Highlight exact selected text ranges
This commit is contained in:
@@ -310,25 +310,30 @@ func _commit_current_text_selection() -> void:
|
|||||||
var selected_text := stem_label.get_selected_text().strip_edges()
|
var selected_text := stem_label.get_selected_text().strip_edges()
|
||||||
if selected_text == "":
|
if selected_text == "":
|
||||||
return
|
return
|
||||||
_highlight_text(selected_text)
|
|
||||||
|
|
||||||
|
var selection_start := stem_label.get_selection_from()
|
||||||
func _highlight_text(selected_text: String) -> void:
|
var selection_end := stem_label.get_selection_to()
|
||||||
if selected_text == "":
|
if selection_start == selection_end:
|
||||||
return
|
return
|
||||||
|
if selection_start > selection_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:
|
||||||
var question_id := str(BlockSessionService.get_current_question().get("id", ""))
|
var question_id := str(BlockSessionService.get_current_question().get("id", ""))
|
||||||
if not question_highlights.has(question_id):
|
if not question_highlights.has(question_id):
|
||||||
question_highlights[question_id] = []
|
question_highlights[question_id] = []
|
||||||
|
|
||||||
var highlights: Array = question_highlights[question_id]
|
var highlights: Array = question_highlights[question_id]
|
||||||
var start := _find_available_highlight_start(selected_text, highlights)
|
start = clamp(start, 0, stem_plain_text.length())
|
||||||
if start == -1:
|
end = clamp(end, start, stem_plain_text.length())
|
||||||
start = stem_plain_text.find(selected_text)
|
if start == end:
|
||||||
if start == -1:
|
|
||||||
return
|
return
|
||||||
|
|
||||||
var end := start + selected_text.length()
|
|
||||||
if _remove_overlapping_highlights(highlights, start, end):
|
if _remove_overlapping_highlights(highlights, start, end):
|
||||||
_render_stem()
|
_render_stem()
|
||||||
if stem_label.has_method("deselect"):
|
if stem_label.has_method("deselect"):
|
||||||
@@ -370,24 +375,6 @@ func _escape_bbcode(value: String) -> String:
|
|||||||
return value.replace("[", "[lb]").replace("]", "[rb]")
|
return value.replace("[", "[lb]").replace("]", "[rb]")
|
||||||
|
|
||||||
|
|
||||||
func _find_available_highlight_start(selected_text: String, highlights: Array) -> int:
|
|
||||||
var search_from := 0
|
|
||||||
while search_from < stem_plain_text.length():
|
|
||||||
var start := stem_plain_text.find(selected_text, search_from)
|
|
||||||
if start == -1:
|
|
||||||
return -1
|
|
||||||
var end := start + selected_text.length()
|
|
||||||
var overlaps := false
|
|
||||||
for highlight_range in highlights:
|
|
||||||
if start < int(highlight_range.get("end", 0)) and end > int(highlight_range.get("start", 0)):
|
|
||||||
overlaps = true
|
|
||||||
break
|
|
||||||
if not overlaps:
|
|
||||||
return start
|
|
||||||
search_from = start + 1
|
|
||||||
return -1
|
|
||||||
|
|
||||||
|
|
||||||
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