Map highlights to selected text near cursor
This commit is contained in:
@@ -12,6 +12,8 @@ var question_highlights := {}
|
|||||||
var stem_plain_text := ""
|
var stem_plain_text := ""
|
||||||
var highlight_mode_enabled := false
|
var highlight_mode_enabled := false
|
||||||
var highlight_drag_started_in_stem := false
|
var highlight_drag_started_in_stem := false
|
||||||
|
var highlight_drag_start_position := Vector2.ZERO
|
||||||
|
var highlight_drag_end_position := Vector2.ZERO
|
||||||
|
|
||||||
var progress_label: Label
|
var progress_label: Label
|
||||||
var timer_label: Label
|
var timer_label: Label
|
||||||
@@ -160,8 +162,10 @@ func _input(event: InputEvent) -> void:
|
|||||||
|
|
||||||
if mouse_event.pressed:
|
if mouse_event.pressed:
|
||||||
highlight_drag_started_in_stem = stem_label.get_global_rect().has_point(mouse_event.global_position)
|
highlight_drag_started_in_stem = stem_label.get_global_rect().has_point(mouse_event.global_position)
|
||||||
|
highlight_drag_start_position = mouse_event.global_position
|
||||||
elif highlight_drag_started_in_stem:
|
elif highlight_drag_started_in_stem:
|
||||||
highlight_drag_started_in_stem = false
|
highlight_drag_started_in_stem = false
|
||||||
|
highlight_drag_end_position = mouse_event.global_position
|
||||||
call_deferred("_commit_current_text_selection")
|
call_deferred("_commit_current_text_selection")
|
||||||
|
|
||||||
|
|
||||||
@@ -311,16 +315,10 @@ func _commit_current_text_selection() -> void:
|
|||||||
if selected_text == "":
|
if selected_text == "":
|
||||||
return
|
return
|
||||||
|
|
||||||
var selection_start := stem_label.get_selection_from()
|
var selected_range := _find_selected_text_range_near_drag(selected_text)
|
||||||
var selection_end := stem_label.get_selection_to()
|
if selected_range.is_empty():
|
||||||
if selection_start == selection_end:
|
|
||||||
return
|
return
|
||||||
if selection_start > selection_end:
|
_highlight_range(int(selected_range["start"]), int(selected_range["end"]))
|
||||||
var previous_start := selection_start
|
|
||||||
selection_start = selection_end
|
|
||||||
selection_end = previous_start
|
|
||||||
|
|
||||||
_highlight_range(selection_start, selection_end)
|
|
||||||
|
|
||||||
|
|
||||||
func _highlight_range(start: int, end: int) -> void:
|
func _highlight_range(start: int, end: int) -> void:
|
||||||
@@ -375,6 +373,35 @@ func _escape_bbcode(value: String) -> String:
|
|||||||
return value.replace("[", "[lb]").replace("]", "[rb]")
|
return value.replace("[", "[lb]").replace("]", "[rb]")
|
||||||
|
|
||||||
|
|
||||||
|
func _find_selected_text_range_near_drag(selected_text: String) -> Dictionary:
|
||||||
|
var matches: Array[Dictionary] = []
|
||||||
|
var search_from := 0
|
||||||
|
while search_from < stem_plain_text.length():
|
||||||
|
var start := stem_plain_text.find(selected_text, search_from)
|
||||||
|
if start == -1:
|
||||||
|
break
|
||||||
|
matches.append({"start": start, "end": start + selected_text.length()})
|
||||||
|
search_from = start + max(1, selected_text.length())
|
||||||
|
|
||||||
|
if matches.is_empty():
|
||||||
|
return {}
|
||||||
|
if matches.size() == 1:
|
||||||
|
return matches[0]
|
||||||
|
|
||||||
|
var local_midpoint := stem_label.get_global_transform().affine_inverse() * ((highlight_drag_start_position + highlight_drag_end_position) * 0.5)
|
||||||
|
var line: int = stem_label.get_line_at_pos(int(local_midpoint.y))
|
||||||
|
var clicked_character: int = stem_label.get_character_line(line)
|
||||||
|
var best_match: Dictionary = matches[0]
|
||||||
|
var best_distance: int = abs(int(best_match["start"]) - clicked_character)
|
||||||
|
for index in range(1, matches.size()):
|
||||||
|
var candidate: Dictionary = matches[index]
|
||||||
|
var distance: int = abs(int(candidate["start"]) - clicked_character)
|
||||||
|
if distance < best_distance:
|
||||||
|
best_distance = distance
|
||||||
|
best_match = candidate
|
||||||
|
return best_match
|
||||||
|
|
||||||
|
|
||||||
func _remove_overlapping_highlights(highlights: Array, start: int, end: int) -> bool:
|
func _remove_overlapping_highlights(highlights: Array, start: int, end: int) -> bool:
|
||||||
var removed := false
|
var removed := false
|
||||||
for index in range(highlights.size() - 1, -1, -1):
|
for index in range(highlights.size() - 1, -1, -1):
|
||||||
|
|||||||
Reference in New Issue
Block a user