Fix highlight selection range calculation
This commit is contained in:
@@ -12,8 +12,6 @@ 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
|
||||||
@@ -162,10 +160,8 @@ 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,14 +307,15 @@ func _finish() -> void:
|
|||||||
func _commit_current_text_selection() -> void:
|
func _commit_current_text_selection() -> void:
|
||||||
if not highlight_mode_enabled or stem_label == null:
|
if not highlight_mode_enabled or stem_label == null:
|
||||||
return
|
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 == "":
|
if selected_text == "":
|
||||||
return
|
return
|
||||||
|
|
||||||
var selected_range := _find_selected_text_range_near_drag(selected_text)
|
var left_trimmed_text := raw_selected_text.strip_edges(true, false)
|
||||||
if selected_range.is_empty():
|
var leading_trim_count := raw_selected_text.length() - left_trimmed_text.length()
|
||||||
return
|
var selection_start := stem_label.get_selection_from() + leading_trim_count
|
||||||
_highlight_range(int(selected_range["start"]), int(selected_range["end"]))
|
_highlight_range(selection_start, selection_start + selected_text.length())
|
||||||
|
|
||||||
|
|
||||||
func _highlight_range(start: int, end: int) -> void:
|
func _highlight_range(start: int, end: int) -> void:
|
||||||
@@ -373,35 +370,6 @@ 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