Fix highlight selection range calculation

This commit is contained in:
hz
2026-07-09 21:46:22 -05:00
parent 52f950b28d
commit bb29fcf14c
+6 -38
View File
@@ -12,8 +12,6 @@ var question_highlights := {}
var stem_plain_text := ""
var highlight_mode_enabled := 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 timer_label: Label
@@ -162,10 +160,8 @@ func _input(event: InputEvent) -> void:
if mouse_event.pressed:
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:
highlight_drag_started_in_stem = false
highlight_drag_end_position = mouse_event.global_position
call_deferred("_commit_current_text_selection")
@@ -311,14 +307,15 @@ func _finish() -> void:
func _commit_current_text_selection() -> void:
if not highlight_mode_enabled or stem_label == null:
return
var selected_text := stem_label.get_selected_text().strip_edges()
var raw_selected_text := stem_label.get_selected_text()
var selected_text := raw_selected_text.strip_edges()
if selected_text == "":
return
var selected_range := _find_selected_text_range_near_drag(selected_text)
if selected_range.is_empty():
return
_highlight_range(int(selected_range["start"]), int(selected_range["end"]))
var left_trimmed_text := raw_selected_text.strip_edges(true, false)
var leading_trim_count := raw_selected_text.length() - left_trimmed_text.length()
var selection_start := stem_label.get_selection_from() + leading_trim_count
_highlight_range(selection_start, selection_start + selected_text.length())
func _highlight_range(start: int, end: int) -> void:
@@ -373,35 +370,6 @@ func _escape_bbcode(value: String) -> String:
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:
var removed := false
for index in range(highlights.size() - 1, -1, -1):