From 70f3c3cf6f9c1563d95ffb8c25bf8cd2bb7a1ad0 Mon Sep 17 00:00:00 2001 From: hop311 Date: Tue, 30 Jul 2024 00:02:35 +0100 Subject: Search panel + text edit box UI generation --- game/src/Game/GameSession/SearchPanel.gd | 143 +++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 game/src/Game/GameSession/SearchPanel.gd (limited to 'game/src/Game/GameSession/SearchPanel.gd') diff --git a/game/src/Game/GameSession/SearchPanel.gd b/game/src/Game/GameSession/SearchPanel.gd new file mode 100644 index 0000000..5554226 --- /dev/null +++ b/game/src/Game/GameSession/SearchPanel.gd @@ -0,0 +1,143 @@ +extends GUINode + +@export var _map_view : MapView + +var _search_panel : Panel +var _search_line_edit : LineEdit +var _results_list_box : GUIListBox +var _result_buttons : Array[Button] + +var _drag_active : bool = false +var _drag_anchor : Vector2 + +func _ready() -> void: + MenuSingleton.search_cache_changed.connect(_update_results_base) + + add_gui_element("goto", "goto_box") + + remove_node(^"./goto_box/goto") + + _search_panel = get_panel_from_nodepath(^"./goto_box") + + var close_button : Button = get_button_from_nodepath(^"./goto_box/cancel") + if close_button: + close_button.pressed.connect(hide) + + var panel_button : Button = get_button_from_nodepath(^"./goto_box/goto_box") + if panel_button: + panel_button.button_down.connect(_start_drag) + panel_button.button_up.connect(_end_drag) + if _search_panel: + # Move to back so it's not drawn over the results list + _search_panel.move_child(panel_button, 0) + + _search_line_edit = get_line_edit_from_nodepath(^"./goto_box/goto_edit") + if _search_line_edit: + _search_line_edit.text_changed.connect(_search_string_updated) + # Restrict to desired size (by default it's a bit too tall, probably due to font size) + _search_line_edit.set_size(_search_line_edit.get_minimum_size()) + + _results_list_box = get_gui_listbox_from_nodepath(^"./goto_box/provinces") + if _results_list_box: + _results_list_box.scroll_index_changed.connect(_update_results_scroll) + + _results_list_box.set_position(_results_list_box.get_position() - Vector2(4, 0)) + + hide() + + MenuSingleton.generate_search_cache() + +func toggle_visibility() -> void: + if is_visible(): + hide() + else: + show() + if _search_line_edit: + _search_line_edit.grab_focus() + +func _start_drag() -> void: + if _search_panel: + _drag_anchor = _search_panel.get_position() - get_window().get_mouse_position() + _drag_active = true + +func _end_drag() -> void: + _drag_active = false + +func _input(event : InputEvent) -> void: + if _drag_active and event is InputEventMouseMotion: + _search_panel.set_position(_drag_anchor + get_window().get_mouse_position()) + +func _notification(what : int) -> void: + match what: + NOTIFICATION_TRANSLATION_CHANGED: + MenuSingleton.generate_search_cache() + +func _search_string_updated(search_string : String) -> void: + MenuSingleton.update_search_results(search_string) + _update_results_base() + +func _update_results_base() -> void: + if not _results_list_box: + return + + var result_count : int = MenuSingleton.get_search_result_row_count() + + var result_height : float = 0.0 + if result_count > 0 and (_results_list_box.get_child_count() > 0 or _add_result_button()): + result_height = _results_list_box.get_child(0).get_size().y + + _results_list_box.set_fixed(result_count, result_height, false) + _update_results_scroll() + +func _add_result_button() -> bool: + if not _results_list_box: + return false + + var child : Panel = GUINode.generate_gui_element("menubar", "save_game_entry") + if not child: + return false + + var button : Button = GUINode.get_button_from_node(child.get_node(^"./game")) + if not button: + child.queue_free() + return false + + button.pressed.connect(_result_selected.bind(_result_buttons.size())) + + _results_list_box.add_child(child) + _result_buttons.push_back(button) + + return true + +func _update_results_scroll(scroll_index : int = -1) -> void: + if not _results_list_box: + return + + if scroll_index >= 0: + _results_list_box.set_scroll_index(scroll_index, false) + + scroll_index = _results_list_box.get_scroll_index() + + var results : PackedStringArray = MenuSingleton.get_search_result_rows(scroll_index, _results_list_box.get_fixed_visible_items()) + + if results.size() < _result_buttons.size(): + _result_buttons.resize(results.size()) + _results_list_box.clear_children(results.size()) + else: + while _result_buttons.size() < results.size() and _add_result_button(): + pass # Button is added in the loop condition + + for index : int in min(results.size(), _result_buttons.size()): + _result_buttons[index].set_text(results[index]) + +func _result_selected(index : int) -> void: + if _map_view: + _map_view.look_at_map_position(MenuSingleton.get_search_result_position(index)) + else: + push_error("SearchPanel missing MapView reference!") + + if _search_line_edit: + # This triggers a search results update, preventing further get_search_result_position(index) calls + _search_line_edit.clear() + + hide() -- cgit v1.2.3-56-ga3b1