diff --git a/addons/dialogic/Editor/Common/ReferenceManager_AddReplacementPanel.gd b/addons/dialogic/Editor/Common/ReferenceManager_AddReplacementPanel.gd index 06360772f..7d3f355ec 100644 --- a/addons/dialogic/Editor/Common/ReferenceManager_AddReplacementPanel.gd +++ b/addons/dialogic/Editor/Common/ReferenceManager_AddReplacementPanel.gd @@ -52,6 +52,9 @@ func open_existing(_item:TreeItem, info:Dictionary): %Old.text = info.what %New.text = info.forwhat + %MatchCase.button_pressed = info.case_sensitive + %WholeWords.button_pressed = info.whole_words + func _on_type_item_selected(index:int) -> void: match index: 0: diff --git a/addons/dialogic/Editor/Common/reference_manager_window.gd b/addons/dialogic/Editor/Common/reference_manager_window.gd index 7bb42ec72..04bd610da 100644 --- a/addons/dialogic/Editor/Common/reference_manager_window.gd +++ b/addons/dialogic/Editor/Common/reference_manager_window.gd @@ -111,7 +111,9 @@ func add_ref_change(old_name:String, new_name:String, type:Types, where:=Where.T 'category':category_name, 'character_names':character_names, 'texts_only':where == Where.TEXTS_ONLY, - 'type':type + 'type':type, + 'case_sensitive':case_sensitive, + 'whole_words':whole_words, }) update_indicator() diff --git a/addons/dialogic/Editor/TimelineEditor/TextEditor/timeline_editor_text.gd b/addons/dialogic/Editor/TimelineEditor/TextEditor/timeline_editor_text.gd index 3ec26ee85..515c96829 100644 --- a/addons/dialogic/Editor/TimelineEditor/TextEditor/timeline_editor_text.gd +++ b/addons/dialogic/Editor/TimelineEditor/TextEditor/timeline_editor_text.gd @@ -205,12 +205,23 @@ func _on_content_item_clicked(label:String) -> void: return -func _search_timeline(search_text:String) -> bool: +func _search_timeline(search_text:String, match_case := false, whole_words := false) -> bool: + var flags := 0 + if match_case: + flags = flags | SEARCH_MATCH_CASE + if whole_words: + flags = flags | SEARCH_WHOLE_WORDS + set_meta("current_search", search_text) + set_meta("current_search_flags", flags) + set_search_text(search_text) + set_search_flags(flags) queue_redraw() - set_meta("current_search", search_text) - return search(search_text, 0, 0, 0).y != -1 + var result := search(search_text, flags, get_selection_from_line(), get_selection_from_column()) + if result.y != -1: + select.call_deferred(result.y, result.x, result.y, result.x + search_text.length()) + return result.y != -1 func _search_navigate_down() -> void: @@ -222,8 +233,18 @@ func _search_navigate_up() -> void: func search_navigate(navigate_up := false) -> void: - if not has_meta("current_search"): + var pos := get_next_search_position(navigate_up) + if pos.x == -1: return + select(pos.y, pos.x, pos.y, pos.x+len(get_meta("current_search"))) + set_caret_line(pos.y) + center_viewport_to_caret() + queue_redraw() + + +func get_next_search_position(navigate_up := false) -> Vector2i: + if not has_meta("current_search"): + return Vector2i(-1, -1) var pos: Vector2i var search_from_line := 0 var search_from_column := 0 @@ -244,11 +265,56 @@ func search_navigate(navigate_up := false) -> void: search_from_line = get_caret_line() search_from_column = get_caret_column() - pos = search(get_meta("current_search"), 4 if navigate_up else 0, search_from_line, search_from_column) - select(pos.y, pos.x, pos.y, pos.x+len(get_meta("current_search"))) + var flags := get_meta("current_search_flags", 0) + if navigate_up: + flags = flags | SEARCH_BACKWARDS + print() + pos = search(get_meta("current_search"), flags, search_from_line, search_from_column) + return pos + + +func replace(replace_text:String) -> void: + if has_selection(): + set_caret_line(get_selection_from_line()) + set_caret_column(get_selection_from_column()) + + var pos := get_next_search_position() + if pos.x == -1: + return + + if not has_meta("current_search"): + return + + begin_complex_operation() + insert_text("@@", pos.y, pos.x) + if get_meta("current_search_flags") & SEARCH_MATCH_CASE: + text = text.replace("@@"+get_meta("current_search"), replace_text) + else: + text = text.replacen("@@"+get_meta("current_search"), replace_text) + end_complex_operation() + set_caret_line(pos.y) - center_viewport_to_caret() - queue_redraw() + set_caret_column(pos.x) + + timeline_editor.replace_in_timeline() + + +func replace_all(replace_text:String) -> void: + begin_complex_operation() + var next_pos := get_next_search_position() + var counter := 0 + while next_pos.y != -1: + insert_text("@@", next_pos.y, next_pos.x) + if get_meta("current_search_flags") & SEARCH_MATCH_CASE: + text = text.replace("@@"+get_meta("current_search"), replace_text) + else: + text = text.replacen("@@"+get_meta("current_search"), replace_text) + next_pos = get_next_search_position() + set_caret_line(next_pos.y) + set_caret_column(next_pos.x) + end_complex_operation() + + timeline_editor.replace_in_timeline() ################################################################################ diff --git a/addons/dialogic/Editor/TimelineEditor/VisualEditor/timeline_editor_visual.gd b/addons/dialogic/Editor/TimelineEditor/VisualEditor/timeline_editor_visual.gd index 44c731852..55a8cc853 100644 --- a/addons/dialogic/Editor/TimelineEditor/VisualEditor/timeline_editor_visual.gd +++ b/addons/dialogic/Editor/TimelineEditor/VisualEditor/timeline_editor_visual.gd @@ -1228,11 +1228,13 @@ func get_previous_character(double_previous := false) -> DialogicCharacter: ################################################################################ var search_results := {} -func _search_timeline(search_text:String) -> bool: - #for event in search_results: - #if is_instance_valid(search_results[event]): - #search_results[event].set_search_text("") - # +func _search_timeline(search_text:String, match_case := false, whole_words := false) -> bool: + var flags := 0 + if match_case: + flags = flags | TextEdit.SEARCH_MATCH_CASE + if whole_words: + flags = flags | TextEdit.SEARCH_WHOLE_WORDS + search_results.clear() # This checks all text events for whether they contain the text. @@ -1245,13 +1247,15 @@ func _search_timeline(search_text:String) -> bool: text_field.deselect() text_field.set_search_text(search_text) + text_field.set_search_flags(flags) - if text_field.search(search_text, 0, 0, 0).x != -1: + if text_field.search(search_text, flags, 0, 0).x != -1: search_results[block] = text_field text_field.queue_redraw() set_meta("current_search", search_text) + set_meta("current_search_flags", flags) search_navigate(false) @@ -1267,10 +1271,24 @@ func _search_navigate_up() -> void: func search_navigate(navigate_up := false) -> void: + var next_pos := get_next_search_position(navigate_up) + if next_pos: + var event: Node = next_pos[0] + var field: TextEdit = next_pos[1] + var result: Vector2i = next_pos[2] + if not event in selected_items: + select_item(next_pos[0], false) + %TimelineArea.ensure_control_visible(event) + event._on_ToggleBodyVisibility_toggled(true) + field.call_deferred("select", result.y, result.x, result.y, result.x+len(get_meta("current_search"))) + + +func get_next_search_position(navigate_up:= false, include_current := false) -> Array: var search_text: String = get_meta("current_search", "") + var search_flags: int = get_meta("current_search_flags", 0) if search_results.is_empty() or %Timeline.get_child_count() == 0: - return + return [] # We start the search on the selected item, # so these checks make sure something sensible is selected @@ -1294,16 +1312,19 @@ func search_navigate(navigate_up := false) -> void: var event: Node = selected_items[0] var counter := 0 + var first := true while true: counter += 1 var field: TextEdit = search_results[event] field.queue_redraw() # First locates the next result in this field - var result := search_text_field(field, search_text, navigate_up) + var result := search_text_field(field, search_text, search_flags, navigate_up, first and include_current) var current_line := field.get_selection_from_line() if field.has_selection() else -1 var current_column := field.get_selection_from_column() if field.has_selection() else -1 + first = false + # Determines if the found result is valid or navigation should continue into the next event var next_is_in_this_event := false if result.y == -1: @@ -1313,17 +1334,14 @@ func search_navigate(navigate_up := false) -> void: current_line = field.get_line_count()-1 current_column = field.get_line(current_line).length() next_is_in_this_event = result.x < current_column or result.y < current_line + elif include_current: + next_is_in_this_event = true else: next_is_in_this_event = result.x > current_column or result.y > current_line - # If the next result was found, select it and break out of the loop + # If the next result was found return it if next_is_in_this_event: - if not event in selected_items: - select_item(event, false) - %TimelineArea.ensure_control_visible(event) - event._on_ToggleBodyVisibility_toggled(true) - field.call_deferred("select", result.y, result.x, result.y, result.x+len(search_text)) - break + return [event, field, result] # Otherwise deselct this field and continue in the next/previous field.deselect() @@ -1333,9 +1351,10 @@ func search_navigate(navigate_up := false) -> void: if counter > 5: print("[Dialogic] Search failed.") break + return [] -func search_text_field(field:TextEdit, search_text := "", navigate_up:= false) -> Vector2i: +func search_text_field(field:TextEdit, search_text := "", flags:= 0, navigate_up:= false, include_current := false) -> Vector2i: var search_from_line: int = 0 var search_from_column: int = 0 if field.has_selection(): @@ -1347,6 +1366,9 @@ func search_text_field(field:TextEdit, search_text := "", navigate_up:= false) - if search_from_line == -1: return Vector2i(-1, -1) search_from_column = field.get_line(search_from_line).length()-1 + elif include_current: + search_from_line = field.get_selection_from_line() + search_from_column = field.get_selection_from_column() else: search_from_line = field.get_selection_to_line() search_from_column = field.get_selection_to_column() @@ -1355,7 +1377,62 @@ func search_text_field(field:TextEdit, search_text := "", navigate_up:= false) - search_from_line = field.get_line_count()-1 search_from_column = field.get_line(search_from_line).length()-1 - var search := field.search(search_text, 4 if navigate_up else 0, search_from_line, search_from_column) + if navigate_up: + flags = flags | TextEdit.SEARCH_BACKWARDS + + var search := field.search(search_text, flags, search_from_line, search_from_column) return search + +func replace(replace_text:String) -> void: + var next_pos := get_next_search_position(false, true) + var event: Node = next_pos[0] + var field: TextEdit = next_pos[1] + var result: Vector2i = next_pos[2] + + if field.has_selection(): + field.set_caret_column(field.get_selection_from_column()) + field.set_caret_line(field.get_selection_from_line()) + + field.begin_complex_operation() + field.insert_text("@@", result.y, result.x) + if get_meta("current_search_flags") & TextEdit.SEARCH_MATCH_CASE: + field.text = field.text.replace("@@"+get_meta("current_search"), replace_text) + else: + field.text = field.text.replacen("@@"+get_meta("current_search"), replace_text) + field.end_complex_operation() + + timeline_editor.replace_in_timeline() + + +func replace_all(replace_text:String) -> void: + var next_pos := get_next_search_position() + if not next_pos: + return + var event: Node = next_pos[0] + var field: TextEdit = next_pos[1] + var result: Vector2i = next_pos[2] + field.begin_complex_operation() + while next_pos: + event = next_pos[0] + if field != next_pos[1]: + field.end_complex_operation() + field = next_pos[1] + field.begin_complex_operation() + result = next_pos[2] + + if field.has_selection(): + field.set_caret_column(field.get_selection_from_column()) + field.set_caret_line(field.get_selection_from_line()) + + field.insert_text("@@", result.y, result.x) + if get_meta("current_search_flags") & TextEdit.SEARCH_MATCH_CASE: + field.text = field.text.replace("@@"+get_meta("current_search"), replace_text) + else: + field.text = field.text.replacen("@@"+get_meta("current_search"), replace_text) + + next_pos = get_next_search_position() + field.end_complex_operation() + timeline_editor.replace_in_timeline() + #endregion diff --git a/addons/dialogic/Editor/TimelineEditor/shortcut_popup.gd b/addons/dialogic/Editor/TimelineEditor/shortcut_popup.gd index 74c7baa35..5661d09e1 100644 --- a/addons/dialogic/Editor/TimelineEditor/shortcut_popup.gd +++ b/addons/dialogic/Editor/TimelineEditor/shortcut_popup.gd @@ -17,6 +17,7 @@ var shortcuts := [ {"shortcut":"Alt/Opt+Down", "text":"Move selected events/lines down"}, {}, {"shortcut":"Ctrl+F", "text":"Search"}, + {"shortcut":"Ctrl+R", "text":"Replace"}, {}, {"shortcut":"Ctrl+F5", "text":"Play timeline", "platform":"-macOS"}, {"shortcut":"Ctrl+B", "text":"Play timeline", "platform":"macOS"}, diff --git a/addons/dialogic/Editor/TimelineEditor/timeline_editor.gd b/addons/dialogic/Editor/TimelineEditor/timeline_editor.gd index bf904e9ea..bc1828574 100644 --- a/addons/dialogic/Editor/TimelineEditor/timeline_editor.gd +++ b/addons/dialogic/Editor/TimelineEditor/timeline_editor.gd @@ -100,6 +100,10 @@ func _input(event: InputEvent) -> void: if is_ancestor_of(get_viewport().gui_get_focus_owner()): search_timeline() + if event.keycode == KEY_R and event.pressed: + if Input.is_key_pressed(KEY_CTRL): + if is_ancestor_of(get_viewport().gui_get_focus_owner()): + replace_in_timeline(true) ## Method to play the current timeline. Connected to the button in the sidebar. func play_timeline(index := -1) -> void: @@ -193,8 +197,13 @@ func _ready() -> void: %SearchUp.icon = get_theme_icon("MoveUp", "EditorIcons") %SearchDown.icon = get_theme_icon("MoveDown", "EditorIcons") + %ReplaceGlobal.icon = get_theme_icon("ExternalLink", "EditorIcons") + %ProgressSection.hide() + %SearchReplaceSection.hide() + %SearchReplaceSection.add_theme_stylebox_override("panel", get_theme_stylebox("PanelForeground", "EditorStyles")) + func _on_create_timeline_button_pressed() -> void: editors_manager.show_add_resource_dialog( @@ -225,24 +234,25 @@ func get_current_editor() -> Node: #region SEARCH func search_timeline() -> void: + %SearchReplaceSection.show() %SearchSection.show() + %ReplaceSection.hide() if get_viewport().gui_get_focus_owner() is TextEdit: - %Search.text = get_viewport().gui_get_focus_owner().get_selected_text() - _on_search_text_changed(%Search.text) - else: - %Search.text = "" + if get_viewport().gui_get_focus_owner().get_selected_text(): + %Search.text = get_viewport().gui_get_focus_owner().get_selected_text() + _on_search_text_changed(%Search.text) %Search.grab_focus() func _on_close_search_pressed() -> void: - %SearchSection.hide() + %SearchReplaceSection.hide() %Search.text = "" _on_search_text_changed('') func _on_search_text_changed(new_text: String) -> void: var editor: Node = null - var anything_found: bool = get_current_editor()._search_timeline(new_text) + var anything_found: bool = get_current_editor()._search_timeline(new_text, %MatchCase.button_pressed, %WholeWords.button_pressed) if anything_found or new_text.is_empty(): %SearchLabel.hide() %Search.add_theme_color_override("font_color", get_theme_color("font_color", "Editor")) @@ -260,8 +270,44 @@ func _on_search_down_pressed() -> void: func _on_search_up_pressed() -> void: get_current_editor()._search_navigate_up() + +func _on_match_case_toggled(toggled_on: bool) -> void: + _on_search_text_changed(%Search.text) + + +func _on_whole_words_toggled(toggled_on: bool) -> void: + _on_search_text_changed(%Search.text) + + +#endregion + + +#region REPLACE + +func replace_in_timeline(focus_grab:=false) -> void: + search_timeline() + %ReplaceSection.show() + if focus_grab: + %ReplaceText.grab_focus() + %ReplaceText.select_all() + + +func _on_replace_button_pressed() -> void: + get_current_editor().replace(%ReplaceText.text) + + +func _on_replace_all_button_pressed() -> void: + get_current_editor().replace_all(%ReplaceText.text) + + +func _on_replace_global_pressed() -> void: + editors_manager.reference_manager.add_ref_change(%Search.text, %ReplaceText.text, 0, 0, [], + %WholeWords.button_pressed, %MatchCase.button_pressed) + editors_manager.reference_manager.open() + #endregion + #region PROGRESS func set_progress(percentage:float, text := "") -> void: diff --git a/addons/dialogic/Editor/TimelineEditor/timeline_editor.tscn b/addons/dialogic/Editor/TimelineEditor/timeline_editor.tscn index df7fc0368..55040af71 100644 --- a/addons/dialogic/Editor/TimelineEditor/timeline_editor.tscn +++ b/addons/dialogic/Editor/TimelineEditor/timeline_editor.tscn @@ -7,7 +7,7 @@ [ext_resource type="Script" path="res://addons/dialogic/Editor/TimelineEditor/TextEditor/syntax_highlighter.gd" id="4_1t6bf"] [ext_resource type="Script" path="res://addons/dialogic/Editor/TimelineEditor/shortcut_popup.gd" id="6_rfuk0"] -[sub_resource type="Image" id="Image_h7ek6"] +[sub_resource type="Image" id="Image_qhno8"] data = { "data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0), "format": "RGBA8", @@ -16,13 +16,13 @@ data = { "width": 16 } -[sub_resource type="ImageTexture" id="ImageTexture_xe7d2"] -image = SubResource("Image_h7ek6") +[sub_resource type="ImageTexture" id="ImageTexture_g6rcb"] +image = SubResource("Image_qhno8") [sub_resource type="SyntaxHighlighter" id="SyntaxHighlighter_7lpql"] script = ExtResource("4_1t6bf") -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_jujwh"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_emdf0"] content_margin_left = 4.0 content_margin_top = 4.0 content_margin_right = 4.0 @@ -66,7 +66,7 @@ content_margin_left = 20.0 content_margin_top = 20.0 content_margin_right = 20.0 content_margin_bottom = 20.0 -bg_color = Color(0.084, 0.096, 0.116, 1) +bg_color = Color(0, 0, 0, 1) corner_radius_top_left = 20 corner_radius_top_right = 20 corner_radius_bottom_right = 20 @@ -120,7 +120,7 @@ size_flags_horizontal = 10 size_flags_vertical = 4 tooltip_text = "Switch between Text Editor and Visual Editor" text = "Text editor" -icon = SubResource("ImageTexture_xe7d2") +icon = SubResource("ImageTexture_g6rcb") [node name="Shortcuts" type="Button" parent="VBox/HBox"] unique_name_in_owner = true @@ -128,7 +128,7 @@ layout_mode = 2 size_flags_horizontal = 8 size_flags_vertical = 4 tooltip_text = "Shortcuts" -icon = SubResource("ImageTexture_xe7d2") +icon = SubResource("ImageTexture_g6rcb") [node name="VisualEditor" parent="VBox" instance=ExtResource("2_qs7vc")] unique_name_in_owner = true @@ -148,36 +148,83 @@ symbol_lookup_on_click = true line_folding = false gutters_draw_fold_gutter = false -[node name="SearchSection" type="HBoxContainer" parent="VBox"] +[node name="SearchReplaceSection" type="PanelContainer" parent="VBox"] unique_name_in_owner = true visible = false layout_mode = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_emdf0") -[node name="Search" type="LineEdit" parent="VBox/SearchSection"] +[node name="VBox" type="VBoxContainer" parent="VBox/SearchReplaceSection"] +layout_mode = 2 + +[node name="SearchSection" type="HBoxContainer" parent="VBox/SearchReplaceSection/VBox"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="Search" type="LineEdit" parent="VBox/SearchReplaceSection/VBox/SearchSection"] unique_name_in_owner = true layout_mode = 2 size_flags_horizontal = 3 placeholder_text = "Search" -[node name="SearchLabel" type="Label" parent="VBox/SearchSection"] +[node name="SearchLabel" type="Label" parent="VBox/SearchReplaceSection/VBox/SearchSection"] unique_name_in_owner = true visible = false layout_mode = 2 -[node name="SearchUp" type="Button" parent="VBox/SearchSection"] +[node name="SearchUp" type="Button" parent="VBox/SearchReplaceSection/VBox/SearchSection"] +unique_name_in_owner = true +layout_mode = 2 +icon = SubResource("ImageTexture_g6rcb") +flat = true + +[node name="SearchDown" type="Button" parent="VBox/SearchReplaceSection/VBox/SearchSection"] +unique_name_in_owner = true +layout_mode = 2 +icon = SubResource("ImageTexture_g6rcb") +flat = true + +[node name="MatchCase" type="CheckBox" parent="VBox/SearchReplaceSection/VBox/SearchSection"] +unique_name_in_owner = true +layout_mode = 2 +text = "Match Case" + +[node name="WholeWords" type="CheckBox" parent="VBox/SearchReplaceSection/VBox/SearchSection"] +unique_name_in_owner = true +layout_mode = 2 +text = "Whole Words" + +[node name="SearchClose" type="Button" parent="VBox/SearchReplaceSection/VBox/SearchSection"] +unique_name_in_owner = true +layout_mode = 2 +icon = SubResource("ImageTexture_g6rcb") +flat = true + +[node name="ReplaceSection" type="HBoxContainer" parent="VBox/SearchReplaceSection/VBox"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="ReplaceText" type="LineEdit" parent="VBox/SearchReplaceSection/VBox/ReplaceSection"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +placeholder_text = "Replace" + +[node name="ReplaceButton" type="Button" parent="VBox/SearchReplaceSection/VBox/ReplaceSection"] unique_name_in_owner = true layout_mode = 2 -icon = SubResource("ImageTexture_xe7d2") +text = "Replace" -[node name="SearchDown" type="Button" parent="VBox/SearchSection"] +[node name="ReplaceAllButton" type="Button" parent="VBox/SearchReplaceSection/VBox/ReplaceSection"] unique_name_in_owner = true layout_mode = 2 -icon = SubResource("ImageTexture_xe7d2") +text = "Replace All" -[node name="SearchClose" type="Button" parent="VBox/SearchSection"] +[node name="ReplaceGlobal" type="Button" parent="VBox/SearchReplaceSection/VBox/ReplaceSection"] unique_name_in_owner = true layout_mode = 2 -icon = SubResource("ImageTexture_xe7d2") +tooltip_text = "Replace in all timelines" +icon = SubResource("ImageTexture_g6rcb") [node name="ProgressSection" type="HBoxContainer" parent="VBox"] unique_name_in_owner = true @@ -203,7 +250,7 @@ anchor_right = 1.0 anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 -theme_override_styles/panel = SubResource("StyleBoxFlat_jujwh") +theme_override_styles/panel = SubResource("StyleBoxFlat_emdf0") [node name="CenterContainer" type="CenterContainer" parent="NoTimelineScreen"] layout_mode = 2 @@ -250,7 +297,7 @@ text = "Shortcuts " [node name="CloseShortcutPanel" type="Button" parent="ShortcutsPanel/VBoxContainer/HBoxContainer"] unique_name_in_owner = true layout_mode = 2 -icon = SubResource("ImageTexture_xe7d2") +icon = SubResource("ImageTexture_g6rcb") flat = true [node name="ScrollContainer" type="ScrollContainer" parent="ShortcutsPanel/VBoxContainer"] @@ -263,9 +310,14 @@ layout_mode = 2 theme_override_constants/h_separation = 11 columns = 2 -[connection signal="text_changed" from="VBox/SearchSection/Search" to="." method="_on_search_text_changed"] -[connection signal="pressed" from="VBox/SearchSection/SearchUp" to="." method="_on_search_up_pressed"] -[connection signal="pressed" from="VBox/SearchSection/SearchDown" to="." method="_on_search_down_pressed"] -[connection signal="pressed" from="VBox/SearchSection/SearchClose" to="." method="_on_close_search_pressed"] +[connection signal="text_changed" from="VBox/SearchReplaceSection/VBox/SearchSection/Search" to="." method="_on_search_text_changed"] +[connection signal="pressed" from="VBox/SearchReplaceSection/VBox/SearchSection/SearchUp" to="." method="_on_search_up_pressed"] +[connection signal="pressed" from="VBox/SearchReplaceSection/VBox/SearchSection/SearchDown" to="." method="_on_search_down_pressed"] +[connection signal="toggled" from="VBox/SearchReplaceSection/VBox/SearchSection/MatchCase" to="." method="_on_match_case_toggled"] +[connection signal="toggled" from="VBox/SearchReplaceSection/VBox/SearchSection/WholeWords" to="." method="_on_whole_words_toggled"] +[connection signal="pressed" from="VBox/SearchReplaceSection/VBox/SearchSection/SearchClose" to="." method="_on_close_search_pressed"] +[connection signal="pressed" from="VBox/SearchReplaceSection/VBox/ReplaceSection/ReplaceButton" to="." method="_on_replace_button_pressed"] +[connection signal="pressed" from="VBox/SearchReplaceSection/VBox/ReplaceSection/ReplaceAllButton" to="." method="_on_replace_all_button_pressed"] +[connection signal="pressed" from="VBox/SearchReplaceSection/VBox/ReplaceSection/ReplaceGlobal" to="." method="_on_replace_global_pressed"] [connection signal="pressed" from="NoTimelineScreen/CenterContainer/VBoxContainer/CreateTimelineButton" to="." method="_on_create_timeline_button_pressed"] [connection signal="pressed" from="ShortcutsPanel/VBoxContainer/HBoxContainer/CloseShortcutPanel" to="ShortcutsPanel" method="_on_close_shortcut_panel_pressed"]