From 88acb31bd43f0e163522837bb1d0dd7da2977c4a Mon Sep 17 00:00:00 2001 From: hop311 Date: Wed, 28 Aug 2024 18:46:30 +0100 Subject: Switch to using custom UI nodes --- .../NationManagementScreen/BudgetMenu.gd | 30 +-- .../NationManagementScreen/DiplomacyMenu.gd | 2 +- .../NationManagementScreen/MilitaryMenu.gd | 2 +- .../NationManagementScreen/PoliticsMenu.gd | 2 +- .../NationManagementScreen/PopulationMenu.gd | 192 ++++++++----------- .../NationManagementScreen/ProductionMenu.gd | 2 +- .../NationManagementScreen/TechnologyMenu.gd | 2 +- .../NationManagementScreen/TradeMenu.gd | 2 +- game/src/Game/GameSession/ProvinceOverviewPanel.gd | 110 ++++++----- game/src/Game/GameSession/SearchPanel.gd | 8 +- game/src/Game/GameSession/Topbar.gd | 209 ++++++++++----------- 11 files changed, 257 insertions(+), 304 deletions(-) (limited to 'game/src') diff --git a/game/src/Game/GameSession/NationManagementScreen/BudgetMenu.gd b/game/src/Game/GameSession/NationManagementScreen/BudgetMenu.gd index 20eb198..ea92beb 100644 --- a/game/src/Game/GameSession/NationManagementScreen/BudgetMenu.gd +++ b/game/src/Game/GameSession/NationManagementScreen/BudgetMenu.gd @@ -35,10 +35,10 @@ var _tariff_val_label : GUILabel var _diplomatic_balance_label : GUILabel var _balance_label : GUILabel -var _lower_class_chart : GFXPieChartTexture -var _middle_class_chart : GFXPieChartTexture -var _upper_class_chart : GFXPieChartTexture -var _debt_chart : GFXPieChartTexture +var _lower_class_chart : GUIPieChart +var _middle_class_chart : GUIPieChart +var _upper_class_chart : GUIPieChart +var _debt_chart : GUIPieChart const _screen : NationManagement.Screen = NationManagement.Screen.BUDGET @@ -49,7 +49,7 @@ func _ready() -> void: add_gui_element("country_budget", "country_budget") - var close_button : Button = get_button_from_nodepath(^"./country_budget/close_button") + var close_button : GUIIconButton = get_gui_icon_button_from_nodepath(^"./country_budget/close_button") if close_button: close_button.pressed.connect(Events.NationManagementScreens.close_nation_management_screen.bind(_screen)) @@ -144,30 +144,30 @@ func _ready() -> void: _tariff_slider.emit_value_changed() # debt buttons - var _tab_takenloans_button : Button = get_button_from_nodepath(^"./country_budget/tab_takenloans") + var _tab_takenloans_button : GUIIconButton = get_gui_icon_button_from_nodepath(^"./country_budget/tab_takenloans") if _tab_takenloans_button: _tab_takenloans_button.pressed.connect(_switch_loans_tab.bind(true)) - var _tab_givenloans_button : Button = get_button_from_nodepath(^"./country_budget/tab_givenloans") + var _tab_givenloans_button : GUIIconButton = get_gui_icon_button_from_nodepath(^"./country_budget/tab_givenloans") if _tab_givenloans_button: _tab_givenloans_button.pressed.connect(_switch_loans_tab.bind(false)) - var _debt_sort_country_button : Button = get_button_from_nodepath(^"./country_budget/debt_sort_country") + var _debt_sort_country_button : GUIIconButton = get_gui_icon_button_from_nodepath(^"./country_budget/debt_sort_country") if _debt_sort_country_button: _debt_sort_country_button.pressed.connect(_sort_loans.bind(true)) - var _debt_sort_amount_button : Button = get_button_from_nodepath(^"./country_budget/debt_sort_amount") + var _debt_sort_amount_button : GUIIconButton = get_gui_icon_button_from_nodepath(^"./country_budget/debt_sort_amount") if _debt_sort_amount_button: _debt_sort_amount_button.pressed.connect(_sort_loans.bind(false)) - var _take_loan_button : Button = get_button_from_nodepath(^"./country_budget/take_loan") + var _take_loan_button : GUIIconButton = get_gui_icon_button_from_nodepath(^"./country_budget/take_loan") if _take_loan_button: _take_loan_button.pressed.connect(_take_loan) - var _repay_loan_button : Button = get_button_from_nodepath(^"./country_budget/repay_loan") + var _repay_loan_button : GUIIconButton = get_gui_icon_button_from_nodepath(^"./country_budget/repay_loan") if _repay_loan_button: _repay_loan_button.pressed.connect(_repay_loan) # charts - _lower_class_chart = get_gfx_pie_chart_texture_from_nodepath(^"./country_budget/chart_0") - _middle_class_chart = get_gfx_pie_chart_texture_from_nodepath(^"./country_budget/chart_1") - _upper_class_chart = get_gfx_pie_chart_texture_from_nodepath(^"./country_budget/chart_2") - _debt_chart = get_gfx_pie_chart_texture_from_nodepath(^"./country_budget/chart_debt") + _lower_class_chart = get_gui_pie_chart_from_nodepath(^"./country_budget/chart_0") + _middle_class_chart = get_gui_pie_chart_from_nodepath(^"./country_budget/chart_1") + _upper_class_chart = get_gui_pie_chart_from_nodepath(^"./country_budget/chart_2") + _debt_chart = get_gui_pie_chart_from_nodepath(^"./country_budget/chart_debt") # TODO - generate strata pop type icons diff --git a/game/src/Game/GameSession/NationManagementScreen/DiplomacyMenu.gd b/game/src/Game/GameSession/NationManagementScreen/DiplomacyMenu.gd index fb11a31..0926fbb 100644 --- a/game/src/Game/GameSession/NationManagementScreen/DiplomacyMenu.gd +++ b/game/src/Game/GameSession/NationManagementScreen/DiplomacyMenu.gd @@ -11,7 +11,7 @@ func _ready() -> void: add_gui_element("country_diplomacy", "country_diplomacy") - var close_button : Button = get_button_from_nodepath(^"./country_diplomacy/close_button") + var close_button : GUIIconButton = get_gui_icon_button_from_nodepath(^"./country_diplomacy/close_button") if close_button: close_button.pressed.connect(Events.NationManagementScreens.close_nation_management_screen.bind(_screen)) diff --git a/game/src/Game/GameSession/NationManagementScreen/MilitaryMenu.gd b/game/src/Game/GameSession/NationManagementScreen/MilitaryMenu.gd index f3cc486..d57f0dd 100644 --- a/game/src/Game/GameSession/NationManagementScreen/MilitaryMenu.gd +++ b/game/src/Game/GameSession/NationManagementScreen/MilitaryMenu.gd @@ -11,7 +11,7 @@ func _ready() -> void: add_gui_element("country_military", "country_military") - var close_button : Button = get_button_from_nodepath(^"./country_military/close_button") + var close_button : GUIIconButton = get_gui_icon_button_from_nodepath(^"./country_military/close_button") if close_button: close_button.pressed.connect(Events.NationManagementScreens.close_nation_management_screen.bind(_screen)) diff --git a/game/src/Game/GameSession/NationManagementScreen/PoliticsMenu.gd b/game/src/Game/GameSession/NationManagementScreen/PoliticsMenu.gd index 7237bf5..b6b18a5 100644 --- a/game/src/Game/GameSession/NationManagementScreen/PoliticsMenu.gd +++ b/game/src/Game/GameSession/NationManagementScreen/PoliticsMenu.gd @@ -11,7 +11,7 @@ func _ready() -> void: add_gui_element("country_politics", "country_politics") - var close_button : Button = get_button_from_nodepath(^"./country_politics/close_button") + var close_button : GUIIconButton = get_gui_icon_button_from_nodepath(^"./country_politics/close_button") if close_button: close_button.pressed.connect(Events.NationManagementScreens.close_nation_management_screen.bind(_screen)) diff --git a/game/src/Game/GameSession/NationManagementScreen/PopulationMenu.gd b/game/src/Game/GameSession/NationManagementScreen/PopulationMenu.gd index e078934..d8af97f 100644 --- a/game/src/Game/GameSession/NationManagementScreen/PopulationMenu.gd +++ b/game/src/Game/GameSession/NationManagementScreen/PopulationMenu.gd @@ -13,20 +13,20 @@ var _province_list_scroll_index : int = 0 var _province_list_types : Array[MenuSingleton.ProvinceListEntry] var _province_list_indices : PackedInt32Array var _province_list_panels : Array[Panel] -var _province_list_button_icons : Array[GFXSpriteTexture] +var _province_list_buttons : Array[GUIIconButton] var _province_list_name_labels : Array[GUILabel] var _province_list_size_labels : Array[GUILabel] -var _province_list_growth_icons : Array[GFXSpriteTexture] -var _province_list_colony_buttons : Array[Button] -var _province_list_national_focus_icons : Array[GFXSpriteTexture] -var _province_list_expand_icons : Array[GFXSpriteTexture] +var _province_list_growth_icons : Array[GUIIcon] +var _province_list_colony_buttons : Array[GUIIconButton] +var _province_list_national_focus_buttons : Array[GUIIconButton] +var _province_list_expand_buttons : Array[GUIIconButton] -var _pop_filter_buttons : Array[Button] +var _pop_filter_buttons : Array[GUIIconButton] var _pop_filter_icons : Array[GFXSpriteTexture] var _pop_filter_selected_icons : Array[GFXButtonStateTexture] var _pop_filter_hover_icons : Array[GFXButtonStateTexture] -var _distribution_charts : Array[GFXPieChartTexture] +var _distribution_charts : Array[GUIPieChart] var _distribution_lists : Array[GUIListBox] var _pop_list_scrollbar : GUIScrollbar @@ -34,30 +34,25 @@ var _pop_list_scroll_index : int = 0 var _pop_list_rows : Array[Panel] var _pop_list_size_labels : Array[GUILabel] -var _pop_list_type_buttons : Array[Button] -var _pop_list_type_icons : Array[GFXSpriteTexture] -var _pop_list_producing_icons : Array[GFXSpriteTexture] +var _pop_list_type_buttons : Array[GUIIconButton] +var _pop_list_producing_icons : Array[GUIIcon] var _pop_list_culture_labels : Array[GUILabel] -var _pop_list_religion_icons : Array[GFXSpriteTexture] +var _pop_list_religion_icons : Array[GUIIcon] var _pop_list_location_labels : Array[GUILabel] var _pop_list_militancy_labels : Array[GUILabel] var _pop_list_consciousness_labels : Array[GUILabel] -var _pop_list_ideology_charts : Array[GFXPieChartTexture] -var _pop_list_issues_charts : Array[GFXPieChartTexture] -var _pop_list_unemployment_progressbars : Array[TextureProgressBar] +var _pop_list_ideology_charts : Array[GUIPieChart] +var _pop_list_issues_charts : Array[GUIPieChart] +var _pop_list_unemployment_progressbars : Array[GUIProgressBar] var _pop_list_cash_labels : Array[GUILabel] -var _pop_list_life_needs_progressbars : Array[TextureProgressBar] -var _pop_list_everyday_needs_progressbars : Array[TextureProgressBar] -var _pop_list_luxury_needs_progressbars : Array[TextureProgressBar] -var _pop_list_rebel_texture_rects : Array[TextureRect] -var _pop_list_rebel_icons : Array[GFXSpriteTexture] -var _pop_list_social_movement_texture_rects : Array[TextureRect] -var _pop_list_social_movement_icons : Array[GFXSpriteTexture] -var _pop_list_political_movement_texture_rects : Array[TextureRect] -var _pop_list_political_movement_icons : Array[GFXSpriteTexture] -var _pop_list_national_movement_texture_rects : Array[TextureRect] -var _pop_list_national_movement_flags : Array[GFXMaskedFlagTexture] -var _pop_list_size_change_icons : Array[GFXSpriteTexture] +var _pop_list_life_needs_progressbars : Array[GUIProgressBar] +var _pop_list_everyday_needs_progressbars : Array[GUIProgressBar] +var _pop_list_luxury_needs_progressbars : Array[GUIProgressBar] +var _pop_list_rebel_icons : Array[GUIIcon] +var _pop_list_social_movement_icons : Array[GUIIcon] +var _pop_list_political_movement_icons : Array[GUIIcon] +var _pop_list_national_movement_flags : Array[GUIMaskedFlag] +var _pop_list_size_change_icons : Array[GUIIcon] var _pop_list_literacy_labels : Array[GUILabel] func _ready() -> void: @@ -72,7 +67,7 @@ func _ready() -> void: add_gui_element(_scene_name, "country_pop") - var close_button : Button = get_button_from_nodepath(^"./country_pop/close_button") + var close_button : GUIIconButton = get_gui_icon_button_from_nodepath(^"./country_pop/close_button") if close_button: close_button.pressed.connect(Events.NationManagementScreens.close_nation_management_screen.bind(_screen)) @@ -91,13 +86,13 @@ func _generate_province_list_row(index : int, type : MenuSingleton.ProvinceListE _province_list_types.push_back(MenuSingleton.LIST_ENTRY_NONE) _province_list_indices.push_back(-1) _province_list_panels.push_back(null) - _province_list_button_icons.push_back(null) + _province_list_buttons.push_back(null) _province_list_name_labels.push_back(null) _province_list_size_labels.push_back(null) _province_list_growth_icons.push_back(null) _province_list_colony_buttons.push_back(null) - _province_list_national_focus_icons.push_back(null) - _province_list_expand_icons.push_back(null) + _province_list_national_focus_buttons.push_back(null) + _province_list_expand_buttons.push_back(null) if _province_list_types[index] == type: return OK @@ -109,13 +104,13 @@ func _generate_province_list_row(index : int, type : MenuSingleton.ProvinceListE _province_list_types[index] = MenuSingleton.LIST_ENTRY_NONE _province_list_indices[index] = -1 _province_list_panels[index] = null - _province_list_button_icons[index] = null + _province_list_buttons[index] = null _province_list_name_labels[index] = null _province_list_size_labels[index] = null _province_list_growth_icons[index] = null _province_list_colony_buttons[index] = null - _province_list_national_focus_icons[index] = null - _province_list_expand_icons[index] = null + _province_list_national_focus_buttons[index] = null + _province_list_expand_buttons[index] = null if type == MenuSingleton.LIST_ENTRY_NONE: return OK @@ -135,33 +130,29 @@ func _generate_province_list_row(index : int, type : MenuSingleton.ProvinceListE _province_list_panels[index] = entry_panel - var base_button : Button = GUINode.get_button_from_node(entry_panel.get_node(^"./poplistbutton")) - if base_button: - base_button.pressed.connect( + _province_list_buttons[index] = GUINode.get_gui_icon_button_from_node(entry_panel.get_node(^"./poplistbutton")) + if _province_list_buttons[index]: + _province_list_buttons[index].pressed.connect( func() -> void: MenuSingleton.population_menu_select_province_list_entry(_province_list_indices[index]) ) - _province_list_button_icons[index] = GUINode.get_gfx_sprite_texture_from_node(base_button) _province_list_name_labels[index] = GUINode.get_gui_label_from_node(entry_panel.get_node(^"./poplist_name")) _province_list_size_labels[index] = GUINode.get_gui_label_from_node(entry_panel.get_node(^"./poplist_numpops")) - _province_list_growth_icons[index] = GUINode.get_gfx_sprite_texture_from_node(entry_panel.get_node(^"./growth_indicator")) + _province_list_growth_icons[index] = GUINode.get_gui_icon_from_node(entry_panel.get_node(^"./growth_indicator")) if type == MenuSingleton.LIST_ENTRY_STATE: - _province_list_colony_buttons[index] = GUINode.get_button_from_node(entry_panel.get_node(^"./colonial_state_icon")) + _province_list_colony_buttons[index] = GUINode.get_gui_icon_button_from_node(entry_panel.get_node(^"./colonial_state_icon")) - var national_focus_button : Button = GUINode.get_button_from_node(entry_panel.get_node(^"./state_focus")) - if national_focus_button: - # TODO - connect national focus button to national focus selection submenu - _province_list_national_focus_icons[index] = GUINode.get_gfx_sprite_texture_from_node(national_focus_button) + # TODO - connect national focus button to national focus selection submenu + _province_list_national_focus_buttons[index] = GUINode.get_gui_icon_button_from_node(entry_panel.get_node(^"./state_focus")) - var expand_button : Button = GUINode.get_button_from_node(entry_panel.get_node(^"./expand")) - if expand_button: - expand_button.pressed.connect( + _province_list_expand_buttons[index] = GUINode.get_gui_icon_button_from_node(entry_panel.get_node(^"./expand")) + if _province_list_expand_buttons[index]: + _province_list_expand_buttons[index].pressed.connect( func() -> void: MenuSingleton.population_menu_toggle_expanded(_province_list_indices[index]) ) - _province_list_expand_icons[index] = GUINode.get_gfx_sprite_texture_from_node(expand_button) _province_listbox.add_child(entry_panel) _province_listbox.move_child(entry_panel, index) @@ -206,7 +197,7 @@ func _setup_sort_buttons() -> void: ] for button_info : Array in sort_button_info: - var sort_button : Button = get_button_from_nodepath(button_info[0]) + var sort_button : GUIIconButton = get_gui_icon_button_from_nodepath(button_info[0]) if sort_button: if button_info[1]: sort_button.set_text("") @@ -223,7 +214,7 @@ func _setup_pop_filter_buttons() -> void: var pop_filter_step : Vector2 = GUINode.get_gui_position(_scene_name, "popfilter_offset") for index : int in pop_filter_sprite_indices.size(): - var pop_filter_button : Button = GUINode.get_button_from_node(GUINode.generate_gui_element(_scene_name, "pop_filter_button")) + var pop_filter_button : GUIIconButton = GUINode.get_gui_icon_button_from_node(GUINode.generate_gui_element(_scene_name, "pop_filter_button")) var pop_filter_icon : GFXSpriteTexture = null var pop_filter_selected_icon : GFXButtonStateTexture = null var pop_filter_hover_icon : GFXButtonStateTexture = null @@ -232,7 +223,7 @@ func _setup_pop_filter_buttons() -> void: _pop_screen_panel.add_child(pop_filter_button) pop_filter_button.set_position(pop_filter_start + pop_filter_step * index) pop_filter_button.pressed.connect(MenuSingleton.population_menu_toggle_pop_filter.bind(index)) - pop_filter_icon = GUINode.get_gfx_sprite_texture_from_node(pop_filter_button) + pop_filter_icon = pop_filter_button.get_gfx_sprite_texture() if pop_filter_icon: pop_filter_icon.set_icon_index(pop_filter_sprite_indices[index]) @@ -244,11 +235,11 @@ func _setup_pop_filter_buttons() -> void: _pop_filter_selected_icons.push_back(pop_filter_selected_icon) _pop_filter_hover_icons.push_back(pop_filter_hover_icon) - var select_all_button : Button = get_button_from_nodepath(^"./country_pop/popfilter_ALL") + var select_all_button : GUIIconButton = get_gui_icon_button_from_nodepath(^"./country_pop/popfilter_ALL") if select_all_button: select_all_button.pressed.connect(MenuSingleton.population_menu_select_all_pop_filters) - var deselect_all_button : Button = get_button_from_nodepath(^"./country_pop/popfilter_DESELECT_ALL") + var deselect_all_button : GUIIconButton = get_gui_icon_button_from_nodepath(^"./country_pop/popfilter_DESELECT_ALL") if deselect_all_button: deselect_all_button.pressed.connect(MenuSingleton.population_menu_deselect_all_pop_filters) @@ -266,7 +257,7 @@ func _setup_distribution_windows() -> void: for index : int in distribution_names.size(): var distribution_panel : Panel = GUINode.generate_gui_element(_scene_name, "distribution_window") - var distribution_chart : GFXPieChartTexture = null + var distribution_chart : GUIPieChart = null var distribution_list : GUIListBox = null if distribution_panel: @@ -277,7 +268,7 @@ func _setup_distribution_windows() -> void: if name_label: name_label.set_text(distribution_names[index]) - distribution_chart = GUINode.get_gfx_pie_chart_texture_from_node(distribution_panel.get_node(^"./chart")) + distribution_chart = GUINode.get_gui_pie_chart_from_node(distribution_panel.get_node(^"./chart")) distribution_list = GUINode.get_gui_listbox_from_node(distribution_panel.get_node(^"./member_names")) _distribution_charts.push_back(distribution_chart) @@ -320,18 +311,16 @@ func _setup_pop_list() -> void: _pop_list_size_labels.push_back(GUINode.get_gui_label_from_node(pop_row_panel.get_node(^"./pop_size"))) - var pop_type_button : Button = GUINode.get_button_from_node(pop_row_panel.get_node(^"./pop_type")) + var pop_type_button : GUIIconButton = GUINode.get_gui_icon_button_from_node(pop_row_panel.get_node(^"./pop_type")) # TODO - open pop details menu on pop type button press _pop_list_type_buttons.push_back(pop_type_button) - _pop_list_type_icons.push_back(GUINode.get_gfx_sprite_texture_from_node(pop_type_button)) - - _pop_list_producing_icons.push_back(GUINode.get_gfx_sprite_texture_from_node(pop_row_panel.get_node(^"./pop_producing_icon"))) + _pop_list_producing_icons.push_back(GUINode.get_gui_icon_from_node(pop_row_panel.get_node(^"./pop_producing_icon"))) var culture_label : GUILabel = GUINode.get_gui_label_from_node(pop_row_panel.get_node(^"./pop_nation")) _pop_list_culture_labels.push_back(culture_label) - _pop_list_religion_icons.push_back(GUINode.get_gfx_sprite_texture_from_node(pop_row_panel.get_node(^"./pop_religion"))) + _pop_list_religion_icons.push_back(GUINode.get_gui_icon_from_node(pop_row_panel.get_node(^"./pop_religion"))) var location_label : GUILabel = GUINode.get_gui_label_from_node(pop_row_panel.get_node(^"./pop_location")) _pop_list_location_labels.push_back(location_label) @@ -340,55 +329,35 @@ func _setup_pop_list() -> void: _pop_list_consciousness_labels.push_back(GUINode.get_gui_label_from_node(pop_row_panel.get_node(^"./pop_con"))) - _pop_list_ideology_charts.push_back(GUINode.get_gfx_pie_chart_texture_from_node(pop_row_panel.get_node(^"./pop_ideology"))) + _pop_list_ideology_charts.push_back(GUINode.get_gui_pie_chart_from_node(pop_row_panel.get_node(^"./pop_ideology"))) - _pop_list_issues_charts.push_back(GUINode.get_gfx_pie_chart_texture_from_node(pop_row_panel.get_node(^"./pop_issues"))) + _pop_list_issues_charts.push_back(GUINode.get_gui_pie_chart_from_node(pop_row_panel.get_node(^"./pop_issues"))) - _pop_list_unemployment_progressbars.push_back(GUINode.get_progress_bar_from_node(pop_row_panel.get_node(^"./pop_unemployment_bar"))) + _pop_list_unemployment_progressbars.push_back(GUINode.get_gui_progress_bar_from_node(pop_row_panel.get_node(^"./pop_unemployment_bar"))) _pop_list_cash_labels.push_back(GUINode.get_gui_label_from_node(pop_row_panel.get_node(^"./pop_cash"))) - var pop_list_life_needs_progressbar : TextureProgressBar = GUINode.get_progress_bar_from_node(pop_row_panel.get_node(^"./lifeneed_progress")) + var pop_list_life_needs_progressbar : GUIProgressBar = GUINode.get_gui_progress_bar_from_node(pop_row_panel.get_node(^"./lifeneed_progress")) if pop_list_life_needs_progressbar: pop_list_life_needs_progressbar.position += Vector2(1, 0) _pop_list_life_needs_progressbars.push_back(pop_list_life_needs_progressbar) - var pop_list_everyday_needs_progressbar : TextureProgressBar = GUINode.get_progress_bar_from_node(pop_row_panel.get_node(^"./eveneed_progress")) + var pop_list_everyday_needs_progressbar : GUIProgressBar = GUINode.get_gui_progress_bar_from_node(pop_row_panel.get_node(^"./eveneed_progress")) if pop_list_everyday_needs_progressbar: pop_list_everyday_needs_progressbar.position += Vector2(1, 0) _pop_list_everyday_needs_progressbars.push_back(pop_list_everyday_needs_progressbar) - _pop_list_luxury_needs_progressbars.push_back(GUINode.get_progress_bar_from_node(pop_row_panel.get_node(^"./luxneed_progress"))) + _pop_list_luxury_needs_progressbars.push_back(GUINode.get_gui_progress_bar_from_node(pop_row_panel.get_node(^"./luxneed_progress"))) - var pop_list_rebel_texture_rect : TextureRect = GUINode.get_texture_rect_from_node(pop_row_panel.get_node(^"./pop_revolt")) - _pop_list_rebel_texture_rects.push_back(pop_list_rebel_texture_rect) - if pop_list_rebel_texture_rect: - _pop_list_rebel_icons.push_back(GUINode.get_gfx_sprite_texture_from_node(pop_list_rebel_texture_rect)) - else: - _pop_list_rebel_icons.push_back(null) + _pop_list_rebel_icons.push_back(GUINode.get_gui_icon_from_node(pop_row_panel.get_node(^"./pop_revolt"))) - var pop_list_social_movement_texture_rect : TextureRect = GUINode.get_texture_rect_from_node(pop_row_panel.get_node(^"./pop_movement_social")) - _pop_list_social_movement_texture_rects.push_back(pop_list_social_movement_texture_rect) - if pop_list_social_movement_texture_rect: - _pop_list_social_movement_icons.push_back(GUINode.get_gfx_sprite_texture_from_node(pop_list_social_movement_texture_rect)) - else: - _pop_list_social_movement_icons.push_back(null) + _pop_list_social_movement_icons.push_back(GUINode.get_gui_icon_from_node(pop_row_panel.get_node(^"./pop_movement_social"))) - var pop_list_political_movement_texture_rect : TextureRect = GUINode.get_texture_rect_from_node(pop_row_panel.get_node(^"./pop_movement_political")) - _pop_list_political_movement_texture_rects.push_back(pop_list_political_movement_texture_rect) - if pop_list_political_movement_texture_rect: - _pop_list_political_movement_icons.push_back(GUINode.get_gfx_sprite_texture_from_node(pop_list_political_movement_texture_rect)) - else: - _pop_list_political_movement_icons.push_back(null) + _pop_list_political_movement_icons.push_back(GUINode.get_gui_icon_from_node(pop_row_panel.get_node(^"./pop_movement_political"))) - var pop_list_national_movement_texture_rect : TextureRect = GUINode.get_texture_rect_from_node(pop_row_panel.get_node(^"./pop_movement_flag")) - _pop_list_national_movement_texture_rects.push_back(pop_list_national_movement_texture_rect) - if pop_list_national_movement_texture_rect: - _pop_list_national_movement_flags.push_back(GUINode.get_gfx_masked_flag_texture_from_node(pop_list_national_movement_texture_rect)) - else: - _pop_list_national_movement_flags.push_back(null) + _pop_list_national_movement_flags.push_back(GUINode.get_gui_masked_flag_from_node(pop_row_panel.get_node(^"./pop_movement_flag"))) - _pop_list_size_change_icons.push_back(GUINode.get_gfx_sprite_texture_from_node(pop_row_panel.get_node(^"./growth_indicator"))) + _pop_list_size_change_icons.push_back(GUINode.get_gui_icon_from_node(pop_row_panel.get_node(^"./growth_indicator"))) _pop_list_literacy_labels.push_back(GUINode.get_gui_label_from_node(pop_row_panel.get_node(^"./pop_literacy"))) @@ -450,8 +419,8 @@ func _update_province_list(scroll_index : int = -1) -> void: _province_list_indices[index] = province_list_info[index_key] - if _province_list_button_icons[index]: - _province_list_button_icons[index].set_icon_index(1 + int(province_list_info[selected_key])) + if _province_list_buttons[index]: + _province_list_buttons[index].set_icon_index(1 + int(province_list_info[selected_key])) if _province_list_name_labels[index]: _province_list_name_labels[index].set_text( @@ -469,10 +438,10 @@ func _update_province_list(scroll_index : int = -1) -> void: if _province_list_colony_buttons[index]: _province_list_colony_buttons[index].set_visible(province_list_info[colony_key]) - if _province_list_expand_icons[index]: - _province_list_expand_icons[index].set_icon_index(1 + int(province_list_info[expanded_key])) + if _province_list_expand_buttons[index]: + _province_list_expand_buttons[index].set_icon_index(1 + int(province_list_info[expanded_key])) - # TODO - set _province_list_national_focus_icons[index] + # TODO - set _province_list_national_focus_buttons[index] # Clear any excess rows for index : int in range(province_list_info_list.size(), _province_list_types.size()): @@ -493,7 +462,7 @@ func _update_pop_filters() -> void: var pop_filter_info : Dictionary = pop_filter_info_list[index] - var pop_filter_button : Button = _pop_filter_buttons[index] + var pop_filter_button : GUIIconButton = _pop_filter_buttons[index] if not pop_filter_button: continue pop_filter_button.disabled = pop_filter_info[pop_filter_count_key] <= 0 @@ -542,9 +511,9 @@ func _update_distributions(): var distribution_row : Dictionary = distribution_info[list_index] - var colour_icon_rect : TextureRect = GUINode.get_texture_rect_from_node(child.get_node(^"./legend_color")) - if colour_icon_rect: - colour_icon_rect.set_modulate(distribution_row[slice_colour_key]) + var colour_icon : GUIIcon = GUINode.get_gui_icon_from_node(child.get_node(^"./legend_color")) + if colour_icon: + colour_icon.set_modulate(distribution_row[slice_colour_key]) var identifier_label : GUILabel = GUINode.get_gui_label_from_node(child.get_node(^"./legend_title")) if identifier_label: @@ -592,8 +561,8 @@ func _update_pop_list() -> void: if _pop_list_size_labels[index]: _pop_list_size_labels[index].set_text(GUINode.int_to_string_suffixed(pop_row[pop_size_key])) - if _pop_list_type_icons[index]: - _pop_list_type_icons[index].set_icon_index(pop_row[pop_type_icon_key]) + if _pop_list_type_buttons[index]: + _pop_list_type_buttons[index].set_icon_index(pop_row[pop_type_icon_key]) if _pop_list_culture_labels[index]: _pop_list_culture_labels[index].set_text(pop_row[pop_culture_key]) if _pop_list_religion_icons[index]: @@ -618,22 +587,21 @@ func _update_pop_list() -> void: _pop_list_everyday_needs_progressbars[index].set_value_no_signal(pop_row[pop_everyday_needs_key]) if _pop_list_luxury_needs_progressbars[index]: _pop_list_luxury_needs_progressbars[index].set_value_no_signal(pop_row[pop_luxury_needs_key]) - if _pop_list_rebel_texture_rects[index]: + if _pop_list_rebel_icons[index]: var rebel_icon : int = pop_row.get(pop_rebel_icon_key, 0) if rebel_icon > 0: - if _pop_list_rebel_icons[index]: - _pop_list_rebel_icons[index].set_icon_index(rebel_icon) - _pop_list_rebel_texture_rects[index].show() + _pop_list_rebel_icons[index].set_icon_index(rebel_icon) + _pop_list_rebel_icons[index].show() else: - _pop_list_rebel_texture_rects[index].hide() + _pop_list_rebel_icons[index].hide() # TODO - handle social/political reform and country rebels - if _pop_list_social_movement_texture_rects[index]: - _pop_list_social_movement_texture_rects[index].hide() - if _pop_list_political_movement_texture_rects[index]: - _pop_list_political_movement_texture_rects[index].hide() - if _pop_list_national_movement_texture_rects[index]: - _pop_list_national_movement_texture_rects[index].hide() + if _pop_list_social_movement_icons[index]: + _pop_list_social_movement_icons[index].hide() + if _pop_list_political_movement_icons[index]: + _pop_list_political_movement_icons[index].hide() + if _pop_list_national_movement_flags[index]: + _pop_list_national_movement_flags[index].hide() if _pop_list_size_change_icons[index]: _pop_list_size_change_icons[index].set_icon_index(get_growth_icon_index(pop_row[pop_size_change_key])) diff --git a/game/src/Game/GameSession/NationManagementScreen/ProductionMenu.gd b/game/src/Game/GameSession/NationManagementScreen/ProductionMenu.gd index 938f8e7..25a60df 100644 --- a/game/src/Game/GameSession/NationManagementScreen/ProductionMenu.gd +++ b/game/src/Game/GameSession/NationManagementScreen/ProductionMenu.gd @@ -11,7 +11,7 @@ func _ready() -> void: add_gui_element("country_production", "country_production") - var close_button : Button = get_button_from_nodepath(^"./country_production/close_button") + var close_button : GUIIconButton = get_gui_icon_button_from_nodepath(^"./country_production/close_button") if close_button: close_button.pressed.connect(Events.NationManagementScreens.close_nation_management_screen.bind(_screen)) diff --git a/game/src/Game/GameSession/NationManagementScreen/TechnologyMenu.gd b/game/src/Game/GameSession/NationManagementScreen/TechnologyMenu.gd index a80ed1e..97c3390 100644 --- a/game/src/Game/GameSession/NationManagementScreen/TechnologyMenu.gd +++ b/game/src/Game/GameSession/NationManagementScreen/TechnologyMenu.gd @@ -11,7 +11,7 @@ func _ready() -> void: add_gui_element("country_technology", "country_technology") - var close_button : Button = get_button_from_nodepath(^"./country_technology/close_button") + var close_button : GUIIconButton = get_gui_icon_button_from_nodepath(^"./country_technology/close_button") if close_button: close_button.pressed.connect(Events.NationManagementScreens.close_nation_management_screen.bind(_screen)) diff --git a/game/src/Game/GameSession/NationManagementScreen/TradeMenu.gd b/game/src/Game/GameSession/NationManagementScreen/TradeMenu.gd index 775f31a..2454b96 100644 --- a/game/src/Game/GameSession/NationManagementScreen/TradeMenu.gd +++ b/game/src/Game/GameSession/NationManagementScreen/TradeMenu.gd @@ -11,7 +11,7 @@ func _ready() -> void: add_gui_element("country_trade", "country_trade") - var close_button : Button = get_button_from_nodepath(^"./country_trade/close_button") + var close_button : GUIIconButton = get_gui_icon_button_from_nodepath(^"./country_trade/close_button") if close_button: close_button.pressed.connect(Events.NationManagementScreens.close_nation_management_screen.bind(_screen)) diff --git a/game/src/Game/GameSession/ProvinceOverviewPanel.gd b/game/src/Game/GameSession/ProvinceOverviewPanel.gd index f2669c0..66fd463 100644 --- a/game/src/Game/GameSession/ProvinceOverviewPanel.gd +++ b/game/src/Game/GameSession/ProvinceOverviewPanel.gd @@ -3,32 +3,31 @@ extends GUINode # Header var _province_name_label : GUILabel var _state_name_label : GUILabel -var _slave_status_icon : TextureRect -var _colony_status_button : Button -var _colony_status_button_texture : GFXSpriteTexture +var _slave_status_icon : GUIIcon +var _colony_status_button : GUIIconButton var _administrative_percentage_label : GUILabel var _owner_percentage_label : GUILabel var _province_modifiers_overlapping_elements_box : GUIOverlappingElementsBox -var _terrain_type_texture : GFXSpriteTexture -var _life_rating_bar : TextureProgressBar -var _controller_flag_texture : GFXMaskedFlagTexture +var _terrain_type_icon : GUIIcon +var _life_rating_bar : GUIProgressBar +var _controller_flag : GUIMaskedFlag # Statistics -var _rgo_icon_texture : GFXSpriteTexture +var _rgo_icon : GUIIcon var _rgo_produced_label : GUILabel var _rgo_income_label : GUILabel -var _rgo_employment_percentage_texture : GFXSpriteTexture +var _rgo_employment_percentage_icon : GUIIcon var _rgo_employment_population_label : GUILabel var _rgo_employment_percentage_label : GUILabel var _crime_name_label : GUILabel -var _crime_icon_texture : GFXSpriteTexture +var _crime_icon : GUIIcon var _crime_fighting_label : GUILabel var _total_population_label : GUILabel var _migration_label : GUILabel var _population_growth_label : GUILabel -var _pop_types_piechart : GFXPieChartTexture -var _pop_ideologies_piechart : GFXPieChartTexture -var _pop_cultures_piechart : GFXPieChartTexture +var _pop_types_piechart : GUIPieChart +var _pop_ideologies_piechart : GUIPieChart +var _pop_cultures_piechart : GUIPieChart var _supply_limit_label : GUILabel var _cores_overlapping_elements_box : GUIOverlappingElementsBox @@ -44,10 +43,10 @@ class BuildingSlot: var _slot_index : int var _slot_node : Control - var _building_icon : GFXSpriteTexture - var _expand_button : Button - var _expanding_icon : TextureRect - var _expanding_progress_bar : TextureProgressBar + var _building_icon : GUIIcon + var _expand_button : GUIIconButton + var _expanding_icon : GUIIcon + var _expanding_progress_bar : GUIProgressBar var _expanding_label : GUILabel func _init(new_slot_index : int, new_slot_node : Control) -> void: @@ -64,18 +63,18 @@ class BuildingSlot: var icon := _slot_node.get_node("build_icon%d" % icon_index) if icon: if icon_index == _slot_index: - _building_icon = GUINode.get_gfx_sprite_texture_from_node(icon) + _building_icon = GUINode.get_gui_icon_from_node(icon) else: icon.hide() var building_name := GUINode.get_gui_label_from_node(_slot_node.get_node(^"./description")) if building_name: building_name.text = MenuSingleton.get_province_building_identifier(_slot_index) - _expand_button = GUINode.get_button_from_node(_slot_node.get_node(^"./expand")) + _expand_button = GUINode.get_gui_icon_button_from_node(_slot_node.get_node(^"./expand")) if _expand_button: _expand_button.pressed.connect(func() -> void: MenuSingleton.expand_selected_province_building(_slot_index)) - _expanding_icon = GUINode.get_texture_rect_from_node(_slot_node.get_node(^"./underconstruction_icon")) - _expanding_progress_bar = GUINode.get_progress_bar_from_node(_slot_node.get_node(^"./building_progress")) + _expanding_icon = GUINode.get_gui_icon_from_node(_slot_node.get_node(^"./underconstruction_icon")) + _expanding_progress_bar = GUINode.get_gui_progress_bar_from_node(_slot_node.get_node(^"./building_progress")) if _expanding_progress_bar: _expanding_progress_bar.max_value = 1.0 _expanding_progress_bar.step = _expanding_progress_bar.max_value / 100 @@ -131,7 +130,7 @@ func _ready() -> void: prov_view.mouse_filter = Control.MOUSE_FILTER_IGNORE set_click_mask_from_nodepaths([^"./province_view/background"]) - var close_button : Button = get_button_from_nodepath(^"./province_view/close_button") + var close_button : GUIIconButton = get_gui_icon_button_from_nodepath(^"./province_view/close_button") if close_button: close_button.pressed.connect(_on_close_button_pressed) @@ -141,41 +140,39 @@ func _ready() -> void: if _state_name_label: # State names are already translated in the MenuSingleton _state_name_label.auto_translate = false - _slave_status_icon = get_texture_rect_from_nodepath(^"./province_view/province_view_header/slave_state_icon") - var slave_status_icon_texture : GFXSpriteTexture = get_gfx_sprite_texture_from_nodepath(^"./province_view/province_view_header/slave_state_icon") - if slave_status_icon_texture: - slave_status_icon_texture.set_icon_index(MenuSingleton.get_slave_pop_icon_index()) - _colony_status_button = get_button_from_nodepath(^"./province_view/province_view_header/colony_button") - _colony_status_button_texture = get_gfx_sprite_texture_from_nodepath(^"./province_view/province_view_header/colony_button") - var admin_icon_texture : GFXSpriteTexture = get_gfx_sprite_texture_from_nodepath(^"./province_view/province_view_header/admin_icon") - if admin_icon_texture: - admin_icon_texture.set_icon_index(MenuSingleton.get_administrative_pop_icon_index()) + _slave_status_icon = get_gui_icon_from_nodepath(^"./province_view/province_view_header/slave_state_icon") + if _slave_status_icon: + _slave_status_icon.set_icon_index(MenuSingleton.get_slave_pop_icon_index()) + _colony_status_button = get_gui_icon_button_from_nodepath(^"./province_view/province_view_header/colony_button") + var admin_icon : GUIIcon = get_gui_icon_from_nodepath(^"./province_view/province_view_header/admin_icon") + if admin_icon: + admin_icon.set_icon_index(MenuSingleton.get_administrative_pop_icon_index()) _administrative_percentage_label = get_gui_label_from_nodepath(^"./province_view/province_view_header/admin_efficiency") _owner_percentage_label = get_gui_label_from_nodepath(^"./province_view/province_view_header/owner_presence") _province_modifiers_overlapping_elements_box = get_gui_overlapping_elements_box_from_nodepath(^"./province_view/province_view_header/province_modifiers") if _province_modifiers_overlapping_elements_box and _province_modifiers_overlapping_elements_box.set_gui_child_element_name("province_interface", "prov_state_modifier") != OK: _province_modifiers_overlapping_elements_box = null # hide province modifiers box since we can't do anything with it - _terrain_type_texture = get_gfx_sprite_texture_from_nodepath(^"./province_view/province_view_header/prov_terrain") - _life_rating_bar = get_progress_bar_from_nodepath(^"./province_view/province_view_header/liferating") - _controller_flag_texture = get_gfx_masked_flag_texture_from_nodepath(^"./province_view/province_view_header/controller_flag") + _terrain_type_icon = get_gui_icon_from_nodepath(^"./province_view/province_view_header/prov_terrain") + _life_rating_bar = get_gui_progress_bar_from_nodepath(^"./province_view/province_view_header/liferating") + _controller_flag = get_gui_masked_flag_from_nodepath(^"./province_view/province_view_header/controller_flag") # Statistics - _rgo_icon_texture = get_gfx_sprite_texture_from_nodepath(^"./province_view/province_statistics/goods_type") + _rgo_icon = get_gui_icon_from_nodepath(^"./province_view/province_statistics/goods_type") _rgo_produced_label = get_gui_label_from_nodepath(^"./province_view/province_statistics/produced") _rgo_income_label = get_gui_label_from_nodepath(^"./province_view/province_statistics/income") - _rgo_employment_percentage_texture = get_gfx_sprite_texture_from_nodepath(^"./province_view/province_statistics/employment_ratio") + _rgo_employment_percentage_icon = get_gui_icon_from_nodepath(^"./province_view/province_statistics/employment_ratio") _rgo_employment_population_label = get_gui_label_from_nodepath(^"./province_view/province_statistics/rgo_population") _rgo_employment_percentage_label = get_gui_label_from_nodepath(^"./province_view/province_statistics/rgo_percent") _crime_name_label = get_gui_label_from_nodepath(^"./province_view/province_statistics/crime_name") - _crime_icon_texture = get_gfx_sprite_texture_from_nodepath(^"./province_view/province_statistics/crime_icon") + _crime_icon = get_gui_icon_from_nodepath(^"./province_view/province_statistics/crime_icon") _crime_fighting_label = get_gui_label_from_nodepath(^"./province_view/province_statistics/crimefight_percent") _total_population_label = get_gui_label_from_nodepath(^"./province_view/province_statistics/total_population") _migration_label = get_gui_label_from_nodepath(^"./province_view/province_statistics/migration") _population_growth_label = get_gui_label_from_nodepath(^"./province_view/province_statistics/growth") - _pop_types_piechart = get_gfx_pie_chart_texture_from_nodepath(^"./province_view/province_statistics/workforce_chart") - _pop_ideologies_piechart = get_gfx_pie_chart_texture_from_nodepath(^"./province_view/province_statistics/ideology_chart") - _pop_cultures_piechart = get_gfx_pie_chart_texture_from_nodepath(^"./province_view/province_statistics/culture_chart") - var population_menu_button : Button = get_button_from_nodepath(^"./province_view/province_statistics/open_popscreen") + _pop_types_piechart = get_gui_pie_chart_from_nodepath(^"./province_view/province_statistics/workforce_chart") + _pop_ideologies_piechart = get_gui_pie_chart_from_nodepath(^"./province_view/province_statistics/ideology_chart") + _pop_cultures_piechart = get_gui_pie_chart_from_nodepath(^"./province_view/province_statistics/culture_chart") + var population_menu_button : GUIIconButton = get_gui_icon_button_from_nodepath(^"./province_view/province_statistics/open_popscreen") if population_menu_button: population_menu_button.pressed.connect( func() -> void: @@ -227,11 +224,11 @@ enum ColonyStatus { STATE, PROTECTORATE, COLONY } # This assumes _cores_overlapping_elements_box is non-null func _set_core_flag(core_index : int, country : String) -> void: - var core_flag_texture : GFXMaskedFlagTexture = GUINode.get_gfx_masked_flag_texture_from_node( + var core_flag_button : GUIMaskedFlagButton = GUINode.get_gui_masked_flag_button_from_node( _cores_overlapping_elements_box.get_child(core_index).get_node(^"./country_flag") ) - if core_flag_texture: - core_flag_texture.set_flag_country_name(country) + if core_flag_button: + core_flag_button.set_flag_country_name(country) func _update_info() -> void: const _province_info_province_key : StringName = &"province" @@ -271,8 +268,7 @@ func _update_info() -> void: if colony_status == ColonyStatus.STATE: _colony_status_button.hide() else: - if _colony_status_button_texture: - _colony_status_button_texture.set_icon_index(colony_status) + _colony_status_button.set_icon_index(colony_status) _colony_status_button.show() if _administrative_percentage_label: @@ -285,28 +281,28 @@ func _update_info() -> void: # TODO - replace example icons with those from the province's list of modifier instances _province_modifiers_overlapping_elements_box.set_child_count(8) for i : int in _province_modifiers_overlapping_elements_box.get_child_count(): - var icon : GFXSpriteTexture = GUINode.get_gfx_sprite_texture_from_node( + var button : GUIIconButton = GUINode.get_gui_icon_button_from_node( _province_modifiers_overlapping_elements_box.get_child(i).get_node(^"./modifier") ) - if icon: - icon.set_icon_index(2 * i + (i & 1) + 1) + if button: + button.set_icon_index(2 * i + (i & 1) + 1) - if _terrain_type_texture: + if _terrain_type_icon: var terrain_type : String = _province_info.get(_province_info_terrain_type_key, "") if terrain_type: const _terrain_type_prefix : String = "GFX_terrainimg_" - if _terrain_type_texture.set_gfx_texture_sprite_name(_terrain_type_prefix + terrain_type) != OK: + if _terrain_type_icon.set_gfx_texture_sprite_name(_terrain_type_prefix + terrain_type) != OK: push_error("Failed to set terrain type texture: ", terrain_type) if _life_rating_bar: _life_rating_bar.value = _province_info.get(_province_info_life_rating_key, 0) / 100.0 - if _controller_flag_texture: - _controller_flag_texture.set_flag_country_name(_province_info.get(_province_info_controller_key, "")) + if _controller_flag: + _controller_flag.set_flag_country_name(_province_info.get(_province_info_controller_key, "")) # Statistics - if _rgo_icon_texture: - _rgo_icon_texture.set_icon_index(_province_info.get(_province_info_rgo_icon_key, -1) + 2) + if _rgo_icon: + _rgo_icon.set_icon_index(_province_info.get(_province_info_rgo_icon_key, -1) + 2) if _rgo_produced_label: # TODO - replace name with amount produced @@ -316,7 +312,7 @@ func _update_info() -> void: # TODO - add £ sign and replace placeholder with actual value _rgo_income_label.text = "%s¤" % GUINode.float_to_string_dp(12.34567, 3) - if _rgo_employment_percentage_texture: + if _rgo_employment_percentage_icon: pass if _rgo_employment_population_label: @@ -329,8 +325,8 @@ func _update_info() -> void: if _crime_name_label: _crime_name_label.text = _province_info.get(_province_info_crime_name_key, "") - if _crime_icon_texture: - _crime_icon_texture.set_icon_index(_province_info.get(_province_info_crime_icon_key, 0) + 1) + if _crime_icon: + _crime_icon.set_icon_index(_province_info.get(_province_info_crime_icon_key, 0) + 1) if _crime_fighting_label: pass diff --git a/game/src/Game/GameSession/SearchPanel.gd b/game/src/Game/GameSession/SearchPanel.gd index c41660f..d13c11f 100644 --- a/game/src/Game/GameSession/SearchPanel.gd +++ b/game/src/Game/GameSession/SearchPanel.gd @@ -5,7 +5,7 @@ extends GUINode var _search_panel : Panel var _search_line_edit : LineEdit var _results_list_box : GUIListBox -var _result_buttons : Array[Button] +var _result_buttons : Array[GUIIconButton] var _drag_active : bool = false var _drag_anchor : Vector2 @@ -19,11 +19,11 @@ func _ready() -> void: _search_panel = get_panel_from_nodepath(^"./goto_box") - var close_button : Button = get_button_from_nodepath(^"./goto_box/cancel") + var close_button : GUIIconButton = get_gui_icon_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") + var panel_button : GUIIconButton = get_gui_icon_button_from_nodepath(^"./goto_box/goto_box") if panel_button: panel_button.button_down.connect(_start_drag) panel_button.button_up.connect(_end_drag) @@ -97,7 +97,7 @@ func _add_result_button() -> bool: if not child: return false - var button : Button = GUINode.get_button_from_node(child.get_node(^"./game")) + var button : GUIIconButton = GUINode.get_gui_icon_button_from_node(child.get_node(^"./game")) if not button: child.queue_free() return false diff --git a/game/src/Game/GameSession/Topbar.gd b/game/src/Game/GameSession/Topbar.gd index d6cc358..62fa322 100644 --- a/game/src/Game/GameSession/Topbar.gd +++ b/game/src/Game/GameSession/Topbar.gd @@ -1,8 +1,8 @@ extends GUINode # Country info -var _country_flag_texture : GFXMaskedFlagTexture -var _country_flag_overlay_texture : GFXSpriteTexture +var _country_flag_button : GUIMaskedFlagButton +var _country_flag_overlay_icon : GUIIcon var _country_name_label : GUILabel var _country_rank_label : GUILabel var _country_prestige_label : GUILabel @@ -14,41 +14,39 @@ var _country_military_power_rank_label : GUILabel var _country_colonial_power_label : GUILabel # Time controls -var _speed_up_button : Button -var _speed_down_button : Button -var _speed_indicator_texture : GFXSpriteTexture +var _speed_up_button : GUIIconButton +var _speed_down_button : GUIIconButton +var _speed_indicator_button : GUIIconButton var _date_label : GUILabel -# NationManagement.Screen-Button +# NationManagement.Screen-GUIIconButton var _nation_management_buttons : Dictionary -# NationManagement.Screen-GFXSpriteTexture -var _nation_management_button_textures : Dictionary # Production -var _production_top_goods_textures : Array[GFXSpriteTexture] -var _production_alert_building_texture : GFXSpriteTexture -var _production_alert_closed_texture : GFXSpriteTexture -var _production_alert_unemployment_texture : GFXSpriteTexture +var _production_top_goods_icons : Array[GUIIcon] +var _production_alert_building_icon : GUIIcon +var _production_alert_closed_icon : GUIIcon +var _production_alert_unemployment_icon : GUIIcon # Budget # TODO - line chart var _budget_funds_label : GUILabel # Technology -var _technology_progress_bar : TextureProgressBar +var _technology_progress_bar : GUIProgressBar var _technology_current_research_label : GUILabel var _technology_literacy_label : GUILabel var _technology_research_points_label : GUILabel # Politics -var _politics_party_icon : TextureRect +var _politics_party_icon : GUIIcon var _politics_party_label : GUILabel var _politics_suppression_points_label : GUILabel var _politics_infamy_label : GUILabel -var _politics_reforms_texture : GFXSpriteTexture -var _politics_decisions_texture : GFXSpriteTexture -var _politics_election_texture : GFXSpriteTexture -var _politics_rebels_texture : GFXSpriteTexture +var _politics_reforms_button : GUIButton +var _politics_decisions_button : GUIIconButton +var _politics_election_icon : GUIIcon +var _politics_rebels_button : GUIIconButton # Population var _population_total_size_label : GUILabel @@ -57,17 +55,17 @@ var _population_militancy_label : GUILabel var _population_consciousness_label : GUILabel # Trade -var _trade_imported_textures : Array[GFXSpriteTexture] -var _trade_exported_textures : Array[GFXSpriteTexture] +var _trade_imported_icons : Array[GUIIcon] +var _trade_exported_icons : Array[GUIIcon] # Diplomacy var _diplomacy_peace_label : GUILabel var _diplomacy_war_enemies_overlapping_elements_box : GUIOverlappingElementsBox var _diplomacy_diplomatic_points_label : GUILabel -var _diplomacy_alert_colony_texture : GFXSpriteTexture -var _diplomacy_alert_crisis_texture : GFXSpriteTexture -var _diplomacy_alert_sphere_texture : GFXSpriteTexture -var _diplomacy_alert_great_power_texture : GFXSpriteTexture +var _diplomacy_alert_colony_button : GUIIconButton +var _diplomacy_alert_crisis_icon : GUIIcon +var _diplomacy_alert_sphere_icon : GUIIcon +var _diplomacy_alert_great_power_icon : GUIIcon # Military var _military_army_size_label : GUILabel @@ -87,21 +85,20 @@ func _ready() -> void: ]) # Disables all consuming invisible panel - var topbar := get_panel_from_nodepath(^"./topbar") + var topbar : Panel = get_panel_from_nodepath(^"./topbar") if topbar: topbar.mouse_filter = Control.MOUSE_FILTER_IGNORE set_click_mask_from_nodepaths([^"./topbar/topbar_bg", ^"./topbar/topbar_paper"]) # Country info - var country_flag_button = get_button_from_nodepath(^"./topbar/player_flag") - if country_flag_button: - country_flag_button.pressed.connect( + _country_flag_button = get_gui_masked_flag_button_from_nodepath(^"./topbar/player_flag") + if _country_flag_button: + _country_flag_button.pressed.connect( func() -> void: # TODO - open the diplomacy menu on the Wars tab Events.NationManagementScreens.open_nation_management_screen(NationManagement.Screen.DIPLOMACY) ) - _country_flag_texture = GUINode.get_gfx_masked_flag_texture_from_node(country_flag_button) - _country_flag_overlay_texture = get_gfx_sprite_texture_from_nodepath(^"./topbar/topbar_flag_overlay") + _country_flag_overlay_icon = get_gui_icon_from_nodepath(^"./topbar/topbar_flag_overlay") _country_name_label = get_gui_label_from_nodepath(^"./topbar/CountryName") _country_rank_label = get_gui_label_from_nodepath(^"./topbar/nation_totalrank") _country_prestige_label = get_gui_label_from_nodepath(^"./topbar/country_prestige") @@ -113,19 +110,18 @@ func _ready() -> void: _country_colonial_power_label = get_gui_label_from_nodepath(^"./topbar/country_colonial_power") # Time controls - _speed_up_button = get_button_from_nodepath(^"./topbar/button_speedup") + _speed_up_button = get_gui_icon_button_from_nodepath(^"./topbar/button_speedup") if _speed_up_button: _speed_up_button.pressed.connect(_on_increase_speed_button_pressed) - _speed_down_button = get_button_from_nodepath(^"./topbar/button_speeddown") + _speed_down_button = get_gui_icon_button_from_nodepath(^"./topbar/button_speeddown") if _speed_down_button: _speed_down_button.pressed.connect(_on_decrease_speed_button_pressed) - var pause_bg_button : Button = get_button_from_nodepath(^"./topbar/pause_bg") + var pause_bg_button : GUIIconButton = get_gui_icon_button_from_nodepath(^"./topbar/pause_bg") if pause_bg_button: pause_bg_button.pressed.connect(_on_play_pause_button_pressed) - var speed_indicator_button = get_button_from_nodepath(^"./topbar/speed_indicator") - if speed_indicator_button: - speed_indicator_button.pressed.connect(_on_play_pause_button_pressed) - _speed_indicator_texture = GUINode.get_gfx_sprite_texture_from_node(speed_indicator_button) + _speed_indicator_button = get_gui_icon_button_from_nodepath(^"./topbar/speed_indicator") + if _speed_indicator_button: + _speed_indicator_button.pressed.connect(_on_play_pause_button_pressed) _date_label = get_gui_label_from_nodepath(^"./topbar/DateText") # Nation management screens @@ -140,40 +136,37 @@ func _ready() -> void: NationManagement.Screen.MILITARY : ^"./topbar/topbarbutton_military" } for screen : NationManagement.Screen in screen_nodepaths: - var button : Button = get_button_from_nodepath(screen_nodepaths[screen]) + var button : GUIIconButton = get_gui_icon_button_from_nodepath(screen_nodepaths[screen]) if button: button.pressed.connect( Events.NationManagementScreens.toggle_nation_management_screen.bind(screen) ) - var icon : GFXSpriteTexture = GUINode.get_gfx_sprite_texture_from_node(button) - if icon: - _nation_management_buttons[screen] = button - _nation_management_button_textures[screen] = icon + _nation_management_buttons[screen] = button Events.NationManagementScreens.update_active_nation_management_screen.connect( _on_update_active_nation_management_screen ) # Production const PRODUCED_GOOD_COUNT : int = 5 - for idx in PRODUCED_GOOD_COUNT: - _production_top_goods_textures.push_back(get_gfx_sprite_texture_from_nodepath("./topbar/topbar_produced%d" % idx)) - _production_alert_building_texture = get_gfx_sprite_texture_from_nodepath(^"./topbar/alert_building_factories") - _production_alert_closed_texture = get_gfx_sprite_texture_from_nodepath(^"./topbar/alert_closed_factories") - _production_alert_unemployment_texture = get_gfx_sprite_texture_from_nodepath(^"./topbar/alert_unemployed_workers") + for idx : int in PRODUCED_GOOD_COUNT: + _production_top_goods_icons.push_back(get_gui_icon_from_nodepath("./topbar/topbar_produced%d" % idx)) + _production_alert_building_icon = get_gui_icon_from_nodepath(^"./topbar/alert_building_factories") + _production_alert_closed_icon = get_gui_icon_from_nodepath(^"./topbar/alert_closed_factories") + _production_alert_unemployment_icon = get_gui_icon_from_nodepath(^"./topbar/alert_unemployed_workers") # Budget _budget_funds_label = get_gui_label_from_nodepath(^"./topbar/budget_funds") # Technology - _technology_progress_bar = get_progress_bar_from_nodepath(^"./topbar/topbar_tech_progress") + _technology_progress_bar = get_gui_progress_bar_from_nodepath(^"./topbar/topbar_tech_progress") _technology_current_research_label = get_gui_label_from_nodepath(^"./topbar/tech_current_research") _technology_literacy_label = get_gui_label_from_nodepath(^"./topbar/tech_literacy_value") _technology_research_points_label = get_gui_label_from_nodepath(^"./topbar/topbar_researchpoints_value") # Politics - _politics_party_icon = get_texture_rect_from_nodepath(^"./topbar/politics_party_icon") + _politics_party_icon = get_gui_icon_from_nodepath(^"./topbar/politics_party_icon") _politics_party_label = get_gui_label_from_nodepath(^"./topbar/politics_ruling_party") - var politics_suppression_button : Button = get_button_from_nodepath(^"./topbar/topbar_supression_icon") + var politics_suppression_button : GUIIconButton = get_gui_icon_button_from_nodepath(^"./topbar/topbar_supression_icon") if politics_suppression_button: politics_suppression_button.pressed.connect( func() -> void: @@ -182,31 +175,28 @@ func _ready() -> void: ) _politics_suppression_points_label = get_gui_label_from_nodepath(^"./topbar/politics_supressionpoints_value") _politics_infamy_label = get_gui_label_from_nodepath(^"./topbar/politics_infamy_value") - var politics_reforms_button : Button = get_button_from_nodepath(^"./topbar/alert_can_do_reforms") - if politics_reforms_button: - politics_reforms_button.pressed.connect( + _politics_reforms_button = get_gui_icon_button_from_nodepath(^"./topbar/alert_can_do_reforms") + if _politics_reforms_button: + _politics_reforms_button.pressed.connect( func() -> void: # TODO - open the politics menu on the Reforms tab Events.NationManagementScreens.toggle_nation_management_screen(NationManagement.Screen.POLITICS) ) - _politics_reforms_texture = GUINode.get_gfx_sprite_texture_from_node(politics_reforms_button) - var politics_decisions_button : Button = get_button_from_nodepath(^"./topbar/alert_can_do_decisions") - if politics_decisions_button: - politics_decisions_button.pressed.connect( + _politics_decisions_button = get_gui_icon_button_from_nodepath(^"./topbar/alert_can_do_decisions") + if _politics_decisions_button: + _politics_decisions_button.pressed.connect( func() -> void: # TODO - open the politics menu on the Decisions tab Events.NationManagementScreens.toggle_nation_management_screen(NationManagement.Screen.POLITICS) ) - _politics_decisions_texture = GUINode.get_gfx_sprite_texture_from_node(politics_decisions_button) - _politics_election_texture = get_gfx_sprite_texture_from_nodepath(^"./topbar/alert_is_in_election") - var politics_rebels_button : Button = get_button_from_nodepath(^"./topbar/alert_have_rebels") - if politics_rebels_button: - politics_rebels_button.pressed.connect( + _politics_election_icon = get_gui_icon_from_nodepath(^"./topbar/alert_is_in_election") + _politics_rebels_button = get_gui_icon_button_from_nodepath(^"./topbar/alert_have_rebels") + if _politics_rebels_button: + _politics_rebels_button.pressed.connect( func() -> void: # TODO - open the politics menu on the Movements tab Events.NationManagementScreens.toggle_nation_management_screen(NationManagement.Screen.POLITICS) ) - _politics_rebels_texture = GUINode.get_gfx_sprite_texture_from_node(politics_rebels_button) # Population _population_total_size_label = get_gui_label_from_nodepath(^"./topbar/population_total_value") @@ -217,24 +207,23 @@ func _ready() -> void: # Trade const TRADE_GOOD_COUNT : int = 3 for idx in TRADE_GOOD_COUNT: - _trade_imported_textures.push_back(get_gfx_sprite_texture_from_nodepath("./topbar/topbar_import%d" % idx)) - _trade_exported_textures.push_back(get_gfx_sprite_texture_from_nodepath("./topbar/topbar_export%d" % idx)) + _trade_imported_icons.push_back(get_gui_icon_from_nodepath("./topbar/topbar_import%d" % idx)) + _trade_exported_icons.push_back(get_gui_icon_from_nodepath("./topbar/topbar_export%d" % idx)) # Diplomacy _diplomacy_peace_label = get_gui_label_from_nodepath(^"./topbar/diplomacy_status") _diplomacy_war_enemies_overlapping_elements_box = get_gui_overlapping_elements_box_from_nodepath(^"./topbar/diplomacy_at_war") _diplomacy_diplomatic_points_label = get_gui_label_from_nodepath(^"./topbar/diplomacy_diplopoints_value") - var diplomacy_alert_colony_button : Button = get_button_from_nodepath(^"./topbar/alert_colony") - if diplomacy_alert_colony_button: - diplomacy_alert_colony_button.pressed.connect( + _diplomacy_alert_colony_button = get_gui_icon_button_from_nodepath(^"./topbar/alert_colony") + if _diplomacy_alert_colony_button: + _diplomacy_alert_colony_button.pressed.connect( func() -> void: # TODO - move to and select province in upgradable colony if any exist Events.NationManagementScreens.open_nation_management_screen(NationManagement.Screen.DIPLOMACY) ) - _diplomacy_alert_colony_texture = GUINode.get_gfx_sprite_texture_from_node(diplomacy_alert_colony_button) - _diplomacy_alert_crisis_texture = get_gfx_sprite_texture_from_nodepath(^"./topbar/alert_crisis") - _diplomacy_alert_sphere_texture = get_gfx_sprite_texture_from_nodepath(^"./topbar/alert_can_increase_opinion") - _diplomacy_alert_great_power_texture = get_gfx_sprite_texture_from_nodepath(^"./topbar/alert_loosing_gp") + _diplomacy_alert_crisis_icon = get_gui_icon_from_nodepath(^"./topbar/alert_crisis") + _diplomacy_alert_sphere_icon = get_gui_icon_from_nodepath(^"./topbar/alert_can_increase_opinion") + _diplomacy_alert_great_power_icon = get_gui_icon_from_nodepath(^"./topbar/alert_loosing_gp") # Military _military_army_size_label = get_gui_label_from_nodepath(^"./topbar/military_army_value") @@ -255,15 +244,15 @@ func _update_info() -> void: const player_country : String = "ENG" ## Country info - if _country_flag_texture: - _country_flag_texture.set_flag_country_name(player_country) + if _country_flag_button: + _country_flag_button.set_flag_country_name(player_country) - if _country_flag_overlay_texture: + if _country_flag_overlay_icon: # 1 - Great Power # 2 - Secondary Power # 3 - Civilised # 4 - Uncivilised - _country_flag_overlay_texture.set_icon_index(1) + _country_flag_overlay_icon.set_icon_index(1) if _country_name_label: _country_name_label.set_text(player_country) @@ -301,18 +290,18 @@ func _update_info() -> void: _date_label.text = MenuSingleton.get_longform_date() ## Production - for idx : int in _production_top_goods_textures.size(): - if _production_top_goods_textures[idx]: - _production_top_goods_textures[idx].set_icon_index(idx + 2) + for idx : int in _production_top_goods_icons.size(): + if _production_top_goods_icons[idx]: + _production_top_goods_icons[idx].set_icon_index(idx + 2) - if _production_alert_building_texture: - _production_alert_building_texture.set_icon_index(2) + if _production_alert_building_icon: + _production_alert_building_icon.set_icon_index(2) - if _production_alert_closed_texture: - _production_alert_closed_texture.set_icon_index(2) + if _production_alert_closed_icon: + _production_alert_closed_icon.set_icon_index(2) - if _production_alert_unemployment_texture: - _production_alert_unemployment_texture.set_icon_index(2) + if _production_alert_unemployment_icon: + _production_alert_unemployment_icon.set_icon_index(2) ## Budget if _budget_funds_label: @@ -351,17 +340,17 @@ func _update_info() -> void: if _politics_infamy_label: _politics_infamy_label.set_text("§Y%s" % GUINode.float_to_string_dp(0.0, 2)) - if _politics_reforms_texture: - _politics_reforms_texture.set_icon_index(2) + if _politics_reforms_button: + _politics_reforms_button.set_icon_index(2) - if _politics_decisions_texture: - _politics_decisions_texture.set_icon_index(2) + if _politics_decisions_button: + _politics_decisions_button.set_icon_index(2) - if _politics_election_texture: - _politics_election_texture.set_icon_index(2) + if _politics_election_icon: + _politics_election_icon.set_icon_index(2) - if _politics_rebels_texture: - _politics_rebels_texture.set_icon_index(2) + if _politics_rebels_button: + _politics_rebels_button.set_icon_index(2) ## Population if _population_total_size_label: @@ -386,13 +375,13 @@ func _update_info() -> void: _population_consciousness_label.set_text("§Y%s" % GUINode.float_to_string_dp(0.05, 2)) ## Trade - for idx : int in _trade_imported_textures.size(): - if _trade_imported_textures[idx]: - _trade_imported_textures[idx].set_icon_index(idx + 2 + _production_top_goods_textures.size()) + for idx : int in _trade_imported_icons.size(): + if _trade_imported_icons[idx]: + _trade_imported_icons[idx].set_icon_index(idx + 2 + _production_top_goods_icons.size()) - for idx : int in _trade_exported_textures.size(): - if _trade_exported_textures[idx]: - _trade_exported_textures[idx].set_icon_index(idx + 2 + _production_top_goods_textures.size() + _trade_imported_textures.size()) + for idx : int in _trade_exported_icons.size(): + if _trade_exported_icons[idx]: + _trade_exported_icons[idx].set_icon_index(idx + 2 + _production_top_goods_icons.size() + _trade_imported_icons.size()) ## Diplomacy if _diplomacy_peace_label: @@ -403,17 +392,17 @@ func _update_info() -> void: if _diplomacy_diplomatic_points_label: _diplomacy_diplomatic_points_label.set_text("§Y%s" % GUINode.float_to_string_dp(7.4, 0)) - if _diplomacy_alert_colony_texture: - _diplomacy_alert_colony_texture.set_icon_index(3) + if _diplomacy_alert_colony_button: + _diplomacy_alert_colony_button.set_icon_index(3) - if _diplomacy_alert_crisis_texture: - _diplomacy_alert_crisis_texture.set_icon_index(3) + if _diplomacy_alert_crisis_icon: + _diplomacy_alert_crisis_icon.set_icon_index(3) - if _diplomacy_alert_sphere_texture: - _diplomacy_alert_sphere_texture.set_icon_index(2) + if _diplomacy_alert_sphere_icon: + _diplomacy_alert_sphere_icon.set_icon_index(2) - if _diplomacy_alert_great_power_texture: - _diplomacy_alert_great_power_texture.set_icon_index(2) + if _diplomacy_alert_great_power_icon: + _diplomacy_alert_great_power_icon.set_icon_index(2) ## Military if _military_army_size_label: @@ -437,11 +426,11 @@ func _update_speed_controls() -> void: #if _speed_down_button: # _speed_down_button.disabled = not MenuSingleton.can_decrease_speed() - if _speed_indicator_texture: + if _speed_indicator_button: var index : int = 1 if not MenuSingleton.is_paused(): index += MenuSingleton.get_speed() + 1 - _speed_indicator_texture.set_icon_index(index) + _speed_indicator_button.set_icon_index(index) # REQUIREMENTS: # * UIFUN-71 @@ -463,4 +452,4 @@ func _on_decrease_speed_button_pressed() -> void: func _on_update_active_nation_management_screen(active_screen : NationManagement.Screen) -> void: for screen : NationManagement.Screen in _nation_management_buttons: - _nation_management_button_textures[screen].set_icon_index(1 + int(screen == active_screen)) + _nation_management_buttons[screen].set_icon_index(1 + int(screen == active_screen)) -- cgit v1.2.3-56-ga3b1 From bdc2ba527bc02e7cdf977f6040f2ca85aa4f9a94 Mon Sep 17 00:00:00 2001 From: hop311 Date: Wed, 28 Aug 2024 23:16:24 +0100 Subject: Add tooltips for buttons, labels, icons, pie charts, sliders, and progress bars --- .../classes/GFXPieChartTexture.cpp | 97 +++++++++-------- .../classes/GFXPieChartTexture.hpp | 13 ++- .../src/openvic-extension/classes/GUIButton.cpp | 12 +- .../src/openvic-extension/classes/GUIButton.hpp | 7 ++ .../openvic-extension/classes/GUIHasTooltip.hpp | 121 +++++++++++++++++++++ .../src/openvic-extension/classes/GUILabel.cpp | 57 +++++++--- .../src/openvic-extension/classes/GUILabel.hpp | 7 ++ .../src/openvic-extension/classes/GUIPieChart.cpp | 80 +++++++++++++- .../src/openvic-extension/classes/GUIPieChart.hpp | 13 ++- .../openvic-extension/classes/GUIProgressBar.cpp | 12 +- .../openvic-extension/classes/GUIProgressBar.hpp | 7 ++ .../src/openvic-extension/classes/GUIScrollbar.cpp | 15 ++- .../src/openvic-extension/classes/GUIScrollbar.hpp | 4 + .../openvic-extension/classes/GUITextureRect.cpp | 12 +- .../openvic-extension/classes/GUITextureRect.hpp | 9 ++ .../openvic-extension/singletons/MenuSingleton.cpp | 33 ++++++ .../openvic-extension/singletons/MenuSingleton.hpp | 14 +++ game/src/Game/GameSession/GameSession.tscn | 8 +- .../NationManagementScreen/BudgetMenu.gd | 21 +++- .../NationManagementScreen/PopulationMenu.gd | 93 +++++++++++++--- game/src/Game/GameSession/Tooltip.gd | 23 ++++ game/src/Game/GameSession/Topbar.gd | 99 +++++++++++++++-- 22 files changed, 661 insertions(+), 96 deletions(-) create mode 100644 extension/src/openvic-extension/classes/GUIHasTooltip.hpp create mode 100644 game/src/Game/GameSession/Tooltip.gd (limited to 'game/src') diff --git a/extension/src/openvic-extension/classes/GFXPieChartTexture.cpp b/extension/src/openvic-extension/classes/GFXPieChartTexture.cpp index 417566d..5d955a3 100644 --- a/extension/src/openvic-extension/classes/GFXPieChartTexture.cpp +++ b/extension/src/openvic-extension/classes/GFXPieChartTexture.cpp @@ -7,6 +7,7 @@ using namespace godot; using namespace OpenVic; +using namespace OpenVic::Utilities::literals; StringName const& GFXPieChartTexture::_slice_identifier_key() { static const StringName slice_identifier_key = "identifier"; @@ -21,7 +22,35 @@ StringName const& GFXPieChartTexture::_slice_weight_key() { return slice_weight_key; } -static constexpr float TWO_PI = 2.0f * std::numbers::pi_v; +GFXPieChartTexture::slice_t const* GFXPieChartTexture::get_slice(Vector2 const& position) const { + if (slices.empty() || position.length_squared() > 1.0_real) { + return nullptr; + } + + static constexpr float TWO_PI = 2.0f * std::numbers::pi_v; + + /* Calculate the anti-clockwise angle between the point and the centre of the image. + * The y coordinate is negated as the image coordinate system's y increases downwards. */ + float theta = atan2(-position.y, position.x); + if (theta < 0.0f) { + theta += TWO_PI; + } + + /* Rescale angle so that total_weight is a full rotation. */ + theta *= total_weight / TWO_PI; + + /* Find the slice theta lies in. */ + for (slice_t const& slice : slices) { + theta -= slice.weight; + + if (theta <= 0.0f) { + return &slice; + } + } + + /* Default to the first slice in case theta never reaches 0 due to floating point inaccuracy. */ + return &slices.front(); +} Error GFXPieChartTexture::_generate_pie_chart_image() { ERR_FAIL_NULL_V(gfx_pie_chart, FAILED); @@ -30,60 +59,37 @@ Error GFXPieChartTexture::_generate_pie_chart_image() { vformat("Invalid GFX::PieChart size for GFXPieChartTexture - %d", gfx_pie_chart->get_size()) ); - const int32_t pie_chart_size = 2 * gfx_pie_chart->get_size(); + const int32_t pie_chart_radius = gfx_pie_chart->get_size(); + const int32_t pie_chart_diameter = 2 * pie_chart_radius; /* Whether we've already set the ImageTexture to an image of the right dimensions, * and so can update it without creating and setting a new image, or not. */ - const bool can_update = pie_chart_image.is_valid() && pie_chart_image->get_width() == pie_chart_size - && pie_chart_image->get_height() == pie_chart_size; + const bool can_update = pie_chart_image.is_valid() && pie_chart_image->get_width() == pie_chart_diameter + && pie_chart_image->get_height() == pie_chart_diameter; if (!can_update) { - pie_chart_image = Image::create(pie_chart_size, pie_chart_size, false, Image::FORMAT_RGBA8); + pie_chart_image = Image::create(pie_chart_diameter, pie_chart_diameter, false, Image::FORMAT_RGBA8); ERR_FAIL_NULL_V(pie_chart_image, FAILED); } static const Color background_colour { 0.0f, 0.0f, 0.0f, 0.0f }; if (!slices.empty()) { - const float pie_chart_radius = gfx_pie_chart->get_size(); - - const Vector2 centre_translation = Vector2 { 0.5f, 0.5f } - static_cast(pie_chart_image->get_size()) * 0.5f; - - for (Vector2i point { 0, 0 }; point.y < pie_chart_image->get_height(); ++point.y) { - - for (point.x = 0; point.x < pie_chart_image->get_width(); ++point.x) { - - const Vector2 offset = centre_translation + point; - - if (offset.length() <= pie_chart_radius) { - - /* Calculate the anti-clockwise angle between the point and the centre of the image. - * The y coordinate is negated as the image coordinate system's y increases downwards. */ - float theta = atan2(-offset.y, offset.x); - if (theta < 0.0f) { - theta += TWO_PI; - } - - /* Rescale angle so that total_weight is a full rotation. */ - theta *= total_weight / TWO_PI; + for (Vector2i point { 0, 0 }; point.y < pie_chart_diameter; ++point.y) { - /* Default to the first colour in case theta never reaches 0 due to floating point inaccuracy. */ - Color colour = slices.front().first; + for (point.x = 0; point.x < pie_chart_diameter; ++point.x) { - /* Find the slice theta lies in. */ - for (slice_t const& slice : slices) { - theta -= slice.second; + Vector2 offset = point; + // Move to the centre of the pixel + offset += Vector2 { 0.5_real, 0.5_real }; + // Normalise to [0, 2] + offset /= pie_chart_radius; + // Translate to [-1, 1] + offset -= Vector2 { 1.0_real, 1.0_real }; - if (theta <= 0.0f) { - colour = slice.first; - break; - } - } + slice_t const* slice = get_slice(offset); - pie_chart_image->set_pixelv(point, colour); - } else { - pie_chart_image->set_pixelv(point, background_colour); - } + pie_chart_image->set_pixelv(point, slice != nullptr ? slice->colour : background_colour); } } } else { @@ -107,12 +113,15 @@ Error GFXPieChartTexture::set_slices_array(godot_pie_chart_data_t const& new_sli for (int32_t i = 0; i < new_slices.size(); ++i) { Dictionary const& slice_dict = new_slices[i]; ERR_CONTINUE_MSG( - !slice_dict.has(_slice_colour_key()) || !slice_dict.has(_slice_weight_key()), + !slice_dict.has(_slice_identifier_key()) || !slice_dict.has(_slice_colour_key()) + || !slice_dict.has(_slice_weight_key()), vformat("Invalid slice keys at index %d", i) ); - const slice_t slice = std::make_pair(slice_dict[_slice_colour_key()], slice_dict[_slice_weight_key()]); - if (slice.second > 0.0f) { - total_weight += slice.second; + const slice_t slice { + slice_dict[_slice_identifier_key()], slice_dict[_slice_colour_key()], slice_dict[_slice_weight_key()] + }; + if (slice.weight > 0.0f) { + total_weight += slice.weight; slices.push_back(slice); } } diff --git a/extension/src/openvic-extension/classes/GFXPieChartTexture.hpp b/extension/src/openvic-extension/classes/GFXPieChartTexture.hpp index 9642f4e..3610efb 100644 --- a/extension/src/openvic-extension/classes/GFXPieChartTexture.hpp +++ b/extension/src/openvic-extension/classes/GFXPieChartTexture.hpp @@ -10,11 +10,17 @@ namespace OpenVic { class GFXPieChartTexture : public godot::ImageTexture { GDCLASS(GFXPieChartTexture, godot::ImageTexture) - using slice_t = std::pair; + public: + struct slice_t { + godot::String name; + godot::Color colour; + float weight; + }; + private: GFX::PieChart const* PROPERTY(gfx_pie_chart); std::vector slices; - float total_weight; + float PROPERTY(total_weight); godot::Ref pie_chart_image; static godot::StringName const& _slice_identifier_key(); @@ -29,6 +35,9 @@ namespace OpenVic { public: GFXPieChartTexture(); + // Position must be centred and normalised so that coords are in [-1, 1]. + slice_t const* get_slice(godot::Vector2 const& position) const; + using godot_pie_chart_data_t = godot::TypedArray; /* Set slices given an Array of Dictionaries, each with the following key-value entries: diff --git a/extension/src/openvic-extension/classes/GUIButton.cpp b/extension/src/openvic-extension/classes/GUIButton.cpp index 323b03c..e35d67a 100644 --- a/extension/src/openvic-extension/classes/GUIButton.cpp +++ b/extension/src/openvic-extension/classes/GUIButton.cpp @@ -10,7 +10,17 @@ using namespace godot; using namespace OpenVic; -void GUIButton::_bind_methods() {} +GUI_TOOLTIP_IMPLEMENTATIONS(GUIButton) + +void GUIButton::_bind_methods() { + GUI_TOOLTIP_BIND_METHODS(GUIButton) +} + +void GUIButton::_notification(int what) { + _tooltip_notification(what); +} + +GUIButton::GUIButton() : tooltip_active { false } {} Error GUIButton::set_gfx_button_state_having_texture(Ref const& texture) { ERR_FAIL_NULL_V(texture, FAILED); diff --git a/extension/src/openvic-extension/classes/GUIButton.hpp b/extension/src/openvic-extension/classes/GUIButton.hpp index 4e53125..3873a4d 100644 --- a/extension/src/openvic-extension/classes/GUIButton.hpp +++ b/extension/src/openvic-extension/classes/GUIButton.hpp @@ -5,17 +5,24 @@ #include #include "openvic-extension/classes/GFXButtonStateTexture.hpp" +#include "openvic-extension/classes/GUIHasTooltip.hpp" namespace OpenVic { class GUIButton : public godot::Button { GDCLASS(GUIButton, godot::Button) + GUI_TOOLTIP_DEFINITIONS + protected: static void _bind_methods(); + void _notification(int what); + godot::Error set_gfx_button_state_having_texture(godot::Ref const& texture); public: + GUIButton(); + godot::Error set_gfx_font(GFX::Font const* gfx_font); }; } diff --git a/extension/src/openvic-extension/classes/GUIHasTooltip.hpp b/extension/src/openvic-extension/classes/GUIHasTooltip.hpp new file mode 100644 index 0000000..22413ec --- /dev/null +++ b/extension/src/openvic-extension/classes/GUIHasTooltip.hpp @@ -0,0 +1,121 @@ +#pragma once + +#include +#include +#include +#include + +#include + +#include "openvic-extension/singletons/MenuSingleton.hpp" +#include "openvic-extension/utility/ClassBindings.hpp" +#include "openvic-extension/utility/Utilities.hpp" + +/* To add tooltip functionality to a class: + * - the class must be derived from Control. + * - add GUI_TOOLTIP_DEFINITIONS to the class definition, bearing in mind that it leaves visibility as private. + * - add GUI_TOOLTIP_IMPLEMENTATIONS(CLASS) to the class' source file. + * - add GUI_TOOLTIP_BIND_METHODS(CLASS) to the class' _bind_methods implementation. + * - call _tooltip_notification from the class' _notification method. + * - initialise tooltip_active to false in the class' constructor. */ + +#define GUI_TOOLTIP_DEFINITIONS \ + public: \ + void set_tooltip_string_and_substitution_dict( \ + godot::String const& new_tooltip_string, godot::Dictionary const& new_tooltip_substitution_dict \ + ); \ + void set_tooltip_string(godot::String const& new_tooltip_string); \ + void set_tooltip_substitution_dict(godot::Dictionary const& new_tooltip_substitution_dict); \ + void clear_tooltip(); \ + private: \ + godot::String PROPERTY(tooltip_string); \ + godot::Dictionary PROPERTY(tooltip_substitution_dict); \ + bool PROPERTY_CUSTOM_PREFIX(tooltip_active, is); \ + void _tooltip_notification(int what); \ + void _set_tooltip_active(bool new_tooltip_active); \ + void _set_tooltip_visibility(bool visible); + +#define GUI_TOOLTIP_IMPLEMENTATIONS(CLASS) \ + void CLASS::set_tooltip_string_and_substitution_dict( \ + String const& new_tooltip_string, Dictionary const& new_tooltip_substitution_dict \ + ) { \ + if (get_mouse_filter() == MOUSE_FILTER_IGNORE) { \ + UtilityFunctions::push_error("Tooltips won't work for \"", get_name(), "\" as it has MOUSE_FILTER_IGNORE"); \ + } \ + if (tooltip_string != new_tooltip_string || tooltip_substitution_dict != new_tooltip_substitution_dict) { \ + tooltip_string = new_tooltip_string; \ + tooltip_substitution_dict = new_tooltip_substitution_dict; \ + if (tooltip_active) { \ + _set_tooltip_visibility(!tooltip_string.is_empty()); \ + } \ + } \ + } \ + void CLASS::set_tooltip_string(String const& new_tooltip_string) { \ + if (get_mouse_filter() == MOUSE_FILTER_IGNORE) { \ + UtilityFunctions::push_error("Tooltips won't work for \"", get_name(), "\" as it has MOUSE_FILTER_IGNORE"); \ + } \ + if (tooltip_string != new_tooltip_string) { \ + tooltip_string = new_tooltip_string; \ + if (tooltip_active) { \ + _set_tooltip_visibility(!tooltip_string.is_empty()); \ + } \ + } \ + } \ + void CLASS::set_tooltip_substitution_dict(Dictionary const& new_tooltip_substitution_dict) { \ + if (get_mouse_filter() == MOUSE_FILTER_IGNORE) { \ + UtilityFunctions::push_error("Tooltips won't work for \"", get_name(), "\" as it has MOUSE_FILTER_IGNORE"); \ + } \ + if (tooltip_substitution_dict != new_tooltip_substitution_dict) { \ + tooltip_substitution_dict = new_tooltip_substitution_dict; \ + if (tooltip_active) { \ + _set_tooltip_visibility(!tooltip_string.is_empty()); \ + } \ + } \ + } \ + void CLASS::clear_tooltip() { \ + set_tooltip_string_and_substitution_dict({}, {}); \ + } \ + void CLASS::_tooltip_notification(int what) { \ + if (what == NOTIFICATION_MOUSE_ENTER_SELF) { \ + _set_tooltip_active(true); \ + } else if (what == NOTIFICATION_MOUSE_EXIT_SELF) { \ + _set_tooltip_active(false); \ + } \ + } \ + void CLASS::_set_tooltip_active(bool new_tooltip_active) { \ + if (tooltip_active != new_tooltip_active) { \ + tooltip_active = new_tooltip_active; \ + if (!tooltip_string.is_empty()) { \ + _set_tooltip_visibility(tooltip_active); \ + } \ + } \ + } \ + void CLASS::_set_tooltip_visibility(bool visible) { \ + MenuSingleton* menu_singleton = MenuSingleton::get_singleton(); \ + ERR_FAIL_NULL(menu_singleton); \ + if (visible) { \ + menu_singleton->show_control_tooltip(tooltip_string, tooltip_substitution_dict, this); \ + } else { \ + menu_singleton->hide_tooltip(); \ + } \ + } + +#define GUI_TOOLTIP_BIND_METHODS(CLASS) \ + OV_BIND_METHOD(CLASS::get_tooltip_string); \ + OV_BIND_METHOD(CLASS::set_tooltip_string, { "new_tooltip_string" }); \ + OV_BIND_METHOD(CLASS::get_tooltip_substitution_dict); \ + OV_BIND_METHOD(CLASS::set_tooltip_substitution_dict, { "new_tooltip_substitution_dict" }); \ + OV_BIND_METHOD( \ + CLASS::set_tooltip_string_and_substitution_dict, { "new_tooltip_string", "new_tooltip_substitution_dict" } \ + ); \ + OV_BIND_METHOD(CLASS::clear_tooltip); \ + OV_BIND_METHOD(CLASS::is_tooltip_active); \ + ADD_PROPERTY( \ + PropertyInfo(Variant::STRING, "tooltip_string", PROPERTY_HINT_MULTILINE_TEXT), \ + "set_tooltip_string", "get_tooltip_string" \ + ); \ + ADD_PROPERTY( \ + PropertyInfo(Variant::DICTIONARY, "tooltip_substitution_dict"), \ + "set_tooltip_substitution_dict", "get_tooltip_substitution_dict" \ + ); \ + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "tooltip_active"), "", "is_tooltip_active"); diff --git a/extension/src/openvic-extension/classes/GUILabel.cpp b/extension/src/openvic-extension/classes/GUILabel.cpp index 9fd6b60..732dec2 100644 --- a/extension/src/openvic-extension/classes/GUILabel.cpp +++ b/extension/src/openvic-extension/classes/GUILabel.cpp @@ -14,7 +14,30 @@ using namespace OpenVic::Utilities::literals; static constexpr int32_t DEFAULT_FONT_SIZE = 16; +GUI_TOOLTIP_IMPLEMENTATIONS(GUILabel) + +String const& GUILabel::get_colour_marker() { + static const String COLOUR_MARKER = String::chr(0xA7); // § + return COLOUR_MARKER; +} + +String const& GUILabel::get_currency_marker() { + static const String CURRENCY_MARKER = String::chr(0xA4); // ¤ + return CURRENCY_MARKER; +} + +String const& GUILabel::get_substitution_marker() { + static const String SUBSTITUTION_MARKER = String::chr(0x24); // $ + return SUBSTITUTION_MARKER; +} + void GUILabel::_bind_methods() { + GUI_TOOLTIP_BIND_METHODS(GUILabel) + + OV_BIND_SMETHOD(get_colour_marker); + OV_BIND_SMETHOD(get_currency_marker); + OV_BIND_SMETHOD(get_substitution_marker); + OV_BIND_METHOD(GUILabel::clear); OV_BIND_METHOD(GUILabel::get_gui_text_name); @@ -80,6 +103,8 @@ void GUILabel::_bind_methods() { } void GUILabel::_notification(int what) { + _tooltip_notification(what); + switch (what) { case NOTIFICATION_RESIZED: case NOTIFICATION_TRANSLATION_CHANGED: { @@ -146,7 +171,8 @@ void GUILabel::_notification(int what) { } GUILabel::GUILabel() - : gui_text { nullptr }, + : tooltip_active { false }, + gui_text { nullptr }, text {}, substitution_dict {}, horizontal_alignment { HORIZONTAL_ALIGNMENT_LEFT }, @@ -454,29 +480,30 @@ void GUILabel::_update_lines() { } String GUILabel::generate_substituted_text(String const& base_text) const { - static const String SUBSTITUTION_MARKER = String::chr(0x24); // $ - String result; int64_t start_pos = 0; int64_t marker_start_pos; - while ((marker_start_pos = base_text.find(SUBSTITUTION_MARKER, start_pos)) != -1) { + while ((marker_start_pos = base_text.find(get_substitution_marker(), start_pos)) != -1) { result += base_text.substr(start_pos, marker_start_pos - start_pos); - int64_t marker_end_pos = base_text.find(SUBSTITUTION_MARKER, marker_start_pos + SUBSTITUTION_MARKER.length()); + int64_t marker_end_pos = base_text.find( + get_substitution_marker(), marker_start_pos + get_substitution_marker().length() + ); if (marker_end_pos == -1) { marker_end_pos = base_text.length(); } String key = base_text.substr( - marker_start_pos + SUBSTITUTION_MARKER.length(), marker_end_pos - marker_start_pos - SUBSTITUTION_MARKER.length() + marker_start_pos + get_substitution_marker().length(), + marker_end_pos - marker_start_pos - get_substitution_marker().length() ); String value = substitution_dict.get(key, String {}); // Use the un-substituted key if no value is found or the value is empty result += value.is_empty() ? key : is_auto_translating() ? tr(value) : value; - start_pos = marker_end_pos + SUBSTITUTION_MARKER.length(); + start_pos = marker_end_pos + get_substitution_marker().length(); } if (start_pos < base_text.length()) { @@ -489,25 +516,23 @@ String GUILabel::generate_substituted_text(String const& base_text) const { std::pair GUILabel::generate_display_text_and_colour_instructions( String const& substituted_text ) const { - static const String COLOUR_MARKER = String::chr(0xA7); // § - String result; colour_instructions_t colour_instructions; int64_t start_pos = 0; int64_t marker_pos; - while ((marker_pos = substituted_text.find(COLOUR_MARKER, start_pos)) != -1) { + while ((marker_pos = substituted_text.find(get_colour_marker(), start_pos)) != -1) { result += substituted_text.substr(start_pos, marker_pos - start_pos); - if (marker_pos + COLOUR_MARKER.length() < substituted_text.length()) { - const char32_t colour_code = substituted_text[marker_pos + COLOUR_MARKER.length()]; + if (marker_pos + get_colour_marker().length() < substituted_text.length()) { + const char32_t colour_code = substituted_text[marker_pos + get_colour_marker().length()]; // Check that the colour code can be safely cast to a char if (colour_code >> sizeof(char) * CHAR_BIT == 0) { colour_instructions.emplace_back(result.length(), static_cast(colour_code)); } - start_pos = marker_pos + COLOUR_MARKER.length() + 1; + start_pos = marker_pos + get_colour_marker().length() + 1; } else { return { std::move(result), std::move(colour_instructions) }; } @@ -588,8 +613,6 @@ void GUILabel::separate_lines( void GUILabel::separate_currency_segments( String const& string, Color const& colour, line_t& line ) const { - static const String CURRENCY_MARKER = String::chr(0xA4); // ¤ - const auto push_string_segment = [this, &string, &colour, &line](int64_t start, int64_t end) -> void { String substring = string.substr(start, end - start); const real_t width = get_string_width(substring); @@ -602,7 +625,7 @@ void GUILabel::separate_currency_segments( const real_t currency_width = currency_texture.is_valid() ? currency_texture->get_width() : 0.0_real; - while ((marker_pos = string.find(CURRENCY_MARKER, start_pos)) != -1) { + while ((marker_pos = string.find(get_currency_marker(), start_pos)) != -1) { if (start_pos < marker_pos) { push_string_segment(start_pos, marker_pos); } @@ -610,7 +633,7 @@ void GUILabel::separate_currency_segments( line.segments.push_back(currency_segment_t {}); line.width += currency_width; - start_pos = marker_pos + CURRENCY_MARKER.length(); + start_pos = marker_pos + get_currency_marker().length(); } if (start_pos < string.length()) { diff --git a/extension/src/openvic-extension/classes/GUILabel.hpp b/extension/src/openvic-extension/classes/GUILabel.hpp index e0982b2..102ad94 100644 --- a/extension/src/openvic-extension/classes/GUILabel.hpp +++ b/extension/src/openvic-extension/classes/GUILabel.hpp @@ -8,11 +8,14 @@ #include #include "openvic-extension/classes/GFXSpriteTexture.hpp" +#include "openvic-extension/classes/GUIHasTooltip.hpp" namespace OpenVic { class GUILabel : public godot::Control { GDCLASS(GUILabel, godot::Control) + GUI_TOOLTIP_DEFINITIONS + using colour_instructions_t = std::vector>; GUI::Text const* PROPERTY(gui_text); @@ -55,6 +58,10 @@ namespace OpenVic { void _notification(int what); public: + static godot::String const& get_colour_marker(); + static godot::String const& get_currency_marker(); + static godot::String const& get_substitution_marker(); + GUILabel(); /* Reset gui_text to nullptr and reset current text. */ diff --git a/extension/src/openvic-extension/classes/GUIPieChart.cpp b/extension/src/openvic-extension/classes/GUIPieChart.cpp index a8ed087..0688dd3 100644 --- a/extension/src/openvic-extension/classes/GUIPieChart.cpp +++ b/extension/src/openvic-extension/classes/GUIPieChart.cpp @@ -1,11 +1,51 @@ #include "GUIPieChart.hpp" +#include + +#include "openvic-extension/classes/GUILabel.hpp" +#include "openvic-extension/singletons/MenuSingleton.hpp" #include "openvic-extension/utility/ClassBindings.hpp" using namespace godot; using namespace OpenVic; using namespace OpenVic::Utilities::literals; +void GUIPieChart::_update_tooltip() { + MenuSingleton* menu_singleton = MenuSingleton::get_singleton(); + ERR_FAIL_NULL(menu_singleton); + + if (gfx_pie_chart_texture.is_valid()) { + GFXPieChartTexture::slice_t const* slice = gfx_pie_chart_texture->get_slice(tooltip_position); + + if (slice != nullptr) { + static const String tooltip_identifier_key = "ID"; + static const String tooltip_percent_key = "PC"; + // "§Y$ID$§!: $PC$%" + static const String tooltip_string = + GUILabel::get_colour_marker() + String { "Y" } + GUILabel::get_substitution_marker() + tooltip_identifier_key + + GUILabel::get_substitution_marker() + GUILabel::get_colour_marker() + "!: " + + GUILabel::get_substitution_marker() + tooltip_percent_key + GUILabel::get_substitution_marker() + "%"; + + Dictionary substitution_dict; + substitution_dict[tooltip_identifier_key] = slice->name; + + float percent = slice->weight * 100.0f; + if (gfx_pie_chart_texture->get_total_weight() > 0.0f) { + percent /= gfx_pie_chart_texture->get_total_weight(); + } + substitution_dict[tooltip_percent_key] = Utilities::float_to_string_dp(percent, 2); + + menu_singleton->show_control_tooltip(tooltip_string, substitution_dict, this); + + tooltip_active = true; + return; + } + } + + menu_singleton->hide_tooltip(); + tooltip_active = false; +} + void GUIPieChart::_bind_methods() { OV_BIND_METHOD(GUIPieChart::get_gfx_pie_chart_texture); OV_BIND_METHOD(GUIPieChart::set_gfx_pie_chart_name, { "gfx_pie_chart_name" }); @@ -13,6 +53,28 @@ void GUIPieChart::_bind_methods() { OV_BIND_METHOD(GUIPieChart::set_slices_array, { "new_slices" }); } +static const Vector2 disabled_tooltip_position { -1.0_real, -1.0_real }; + +void GUIPieChart::_notification(int what) { + if (what == NOTIFICATION_MOUSE_EXIT_SELF) { + tooltip_position = disabled_tooltip_position; + + _update_tooltip(); + } +} + +void GUIPieChart::_gui_input(Ref const& event) { + Ref mm = event; + + if (mm.is_valid()) { + tooltip_position = mm->get_position() * 2.0_real / get_size() - Vector2 { 1.0_real, 1.0_real }; + + _update_tooltip(); + } +} + +GUIPieChart::GUIPieChart() : tooltip_active { false }, tooltip_position { disabled_tooltip_position } {} + Error GUIPieChart::set_gfx_pie_chart(GFX::PieChart const* gfx_pie_chart) { const bool needs_setting = gfx_pie_chart_texture.is_null(); @@ -27,6 +89,10 @@ Error GUIPieChart::set_gfx_pie_chart(GFX::PieChart const* gfx_pie_chart) { set_texture(gfx_pie_chart_texture); } + if (tooltip_active) { + _update_tooltip(); + } + return err; } @@ -50,6 +116,10 @@ Error GUIPieChart::set_gfx_pie_chart_name(String const& gfx_pie_chart_name) { set_texture(gfx_pie_chart_texture); } + if (tooltip_active) { + _update_tooltip(); + } + return err; } @@ -59,8 +129,14 @@ String GUIPieChart::get_gfx_pie_chart_name() const { return gfx_pie_chart_texture->get_gfx_pie_chart_name(); } -Error GUIPieChart::set_slices_array(GFXPieChartTexture::godot_pie_chart_data_t const& new_slices) const { +Error GUIPieChart::set_slices_array(GFXPieChartTexture::godot_pie_chart_data_t const& new_slices) { ERR_FAIL_NULL_V(gfx_pie_chart_texture, FAILED); - return gfx_pie_chart_texture->set_slices_array(new_slices); + const Error err = gfx_pie_chart_texture->set_slices_array(new_slices); + + if (tooltip_active) { + _update_tooltip(); + } + + return err; } diff --git a/extension/src/openvic-extension/classes/GUIPieChart.hpp b/extension/src/openvic-extension/classes/GUIPieChart.hpp index 6b4ac87..3356dba 100644 --- a/extension/src/openvic-extension/classes/GUIPieChart.hpp +++ b/extension/src/openvic-extension/classes/GUIPieChart.hpp @@ -12,10 +12,21 @@ namespace OpenVic { godot::Ref gfx_pie_chart_texture; + bool tooltip_active; + godot::Vector2 tooltip_position; + + void _update_tooltip(); + protected: static void _bind_methods(); + void _notification(int what); + public: + void _gui_input(godot::Ref const& event) override; + + GUIPieChart(); + godot::Error set_gfx_pie_chart(GFX::PieChart const* gfx_pie_chart); godot::Ref get_gfx_pie_chart_texture() const; @@ -24,6 +35,6 @@ namespace OpenVic { godot::String get_gfx_pie_chart_name() const; - godot::Error set_slices_array(GFXPieChartTexture::godot_pie_chart_data_t const& new_slices) const; + godot::Error set_slices_array(GFXPieChartTexture::godot_pie_chart_data_t const& new_slices); }; } diff --git a/extension/src/openvic-extension/classes/GUIProgressBar.cpp b/extension/src/openvic-extension/classes/GUIProgressBar.cpp index 6021746..d13f455 100644 --- a/extension/src/openvic-extension/classes/GUIProgressBar.cpp +++ b/extension/src/openvic-extension/classes/GUIProgressBar.cpp @@ -8,7 +8,17 @@ using namespace godot; using namespace OpenVic; -void GUIProgressBar::_bind_methods() {} +GUI_TOOLTIP_IMPLEMENTATIONS(GUIProgressBar) + +void GUIProgressBar::_bind_methods() { + GUI_TOOLTIP_BIND_METHODS(GUIProgressBar) +} + +void GUIProgressBar::_notification(int what) { + _tooltip_notification(what); +} + +GUIProgressBar::GUIProgressBar() : tooltip_active { false } {} Error GUIProgressBar::set_gfx_progress_bar(GFX::ProgressBar const* progress_bar) { ERR_FAIL_NULL_V(progress_bar, FAILED); diff --git a/extension/src/openvic-extension/classes/GUIProgressBar.hpp b/extension/src/openvic-extension/classes/GUIProgressBar.hpp index 130ac91..11b677a 100644 --- a/extension/src/openvic-extension/classes/GUIProgressBar.hpp +++ b/extension/src/openvic-extension/classes/GUIProgressBar.hpp @@ -3,15 +3,22 @@ #include #include "openvic-simulation/interface/GFXSprite.hpp" +#include "openvic-extension/classes/GUIHasTooltip.hpp" namespace OpenVic { class GUIProgressBar : public godot::TextureProgressBar { GDCLASS(GUIProgressBar, godot::TextureProgressBar) + GUI_TOOLTIP_DEFINITIONS + protected: static void _bind_methods(); + void _notification(int what); + public: + GUIProgressBar(); + godot::Error set_gfx_progress_bar(GFX::ProgressBar const* progress_bar); }; } diff --git a/extension/src/openvic-extension/classes/GUIScrollbar.cpp b/extension/src/openvic-extension/classes/GUIScrollbar.cpp index ddcba7c..6e310d7 100644 --- a/extension/src/openvic-extension/classes/GUIScrollbar.cpp +++ b/extension/src/openvic-extension/classes/GUIScrollbar.cpp @@ -18,7 +18,11 @@ StringName const& GUIScrollbar::signal_value_changed() { return signal_value_changed; } +GUI_TOOLTIP_IMPLEMENTATIONS(GUIScrollbar) + void GUIScrollbar::_bind_methods() { + GUI_TOOLTIP_BIND_METHODS(GUIScrollbar) + OV_BIND_METHOD(GUIScrollbar::emit_value_changed); OV_BIND_METHOD(GUIScrollbar::reset); OV_BIND_METHOD(GUIScrollbar::clear); @@ -49,7 +53,7 @@ void GUIScrollbar::_bind_methods() { ADD_SIGNAL(MethodInfo(signal_value_changed(), PropertyInfo(Variant::INT, "value"))); } -GUIScrollbar::GUIScrollbar() { +GUIScrollbar::GUIScrollbar() : tooltip_active { false } { /* Anything which the constructor might not have default initialised will be set by clear(). */ clear(); } @@ -587,11 +591,16 @@ void GUIScrollbar::_gui_input(Ref const& event) { hover_more = !hover_more; queue_redraw(); } + + _set_tooltip_active(hover_slider || hover_track || hover_less || hover_more); + return; } } void GUIScrollbar::_notification(int what) { + // GUIScrollbar doesn't use _tooltip_notification, as we don't want to show tooltips when hovering over transparent parts. + switch (what) { case NOTIFICATION_VISIBILITY_CHANGED: case NOTIFICATION_MOUSE_EXIT: { @@ -602,6 +611,10 @@ void GUIScrollbar::_notification(int what) { queue_redraw(); } break; + case NOTIFICATION_MOUSE_EXIT_SELF: { + _set_tooltip_active(false); + } break; + /* Pressing (and holding) less and more buttons. */ case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { const double delta = get_physics_process_delta_time(); diff --git a/extension/src/openvic-extension/classes/GUIScrollbar.hpp b/extension/src/openvic-extension/classes/GUIScrollbar.hpp index 16b2e00..d9b22f1 100644 --- a/extension/src/openvic-extension/classes/GUIScrollbar.hpp +++ b/extension/src/openvic-extension/classes/GUIScrollbar.hpp @@ -6,11 +6,14 @@ #include #include "openvic-extension/classes/GFXSpriteTexture.hpp" +#include "openvic-extension/classes/GUIHasTooltip.hpp" namespace OpenVic { class GUIScrollbar : public godot::Control { GDCLASS(GUIScrollbar, godot::Control) + GUI_TOOLTIP_DEFINITIONS + GUI::Scrollbar const* PROPERTY(gui_scrollbar); godot::Ref slider_texture; @@ -74,6 +77,7 @@ namespace OpenVic { protected: static void _bind_methods(); + void _notification(int what); public: diff --git a/extension/src/openvic-extension/classes/GUITextureRect.cpp b/extension/src/openvic-extension/classes/GUITextureRect.cpp index 13fd3bb..fba9b19 100644 --- a/extension/src/openvic-extension/classes/GUITextureRect.cpp +++ b/extension/src/openvic-extension/classes/GUITextureRect.cpp @@ -3,4 +3,14 @@ using namespace godot; using namespace OpenVic; -void GUITextureRect::_bind_methods() {} +GUI_TOOLTIP_IMPLEMENTATIONS(GUITextureRect) + +void GUITextureRect::_bind_methods() { + GUI_TOOLTIP_BIND_METHODS(GUITextureRect) +} + +void GUITextureRect::_notification(int what) { + _tooltip_notification(what); +} + +GUITextureRect::GUITextureRect() : tooltip_active { false } {} diff --git a/extension/src/openvic-extension/classes/GUITextureRect.hpp b/extension/src/openvic-extension/classes/GUITextureRect.hpp index afcf4da..6fc8123 100644 --- a/extension/src/openvic-extension/classes/GUITextureRect.hpp +++ b/extension/src/openvic-extension/classes/GUITextureRect.hpp @@ -2,11 +2,20 @@ #include +#include "openvic-extension/classes/GUIHasTooltip.hpp" + namespace OpenVic { class GUITextureRect : public godot::TextureRect { GDCLASS(GUITextureRect, godot::TextureRect) + GUI_TOOLTIP_DEFINITIONS + protected: static void _bind_methods(); + + void _notification(int what); + + public: + GUITextureRect(); }; } diff --git a/extension/src/openvic-extension/singletons/MenuSingleton.cpp b/extension/src/openvic-extension/singletons/MenuSingleton.cpp index b95bc15..367462b 100644 --- a/extension/src/openvic-extension/singletons/MenuSingleton.cpp +++ b/extension/src/openvic-extension/singletons/MenuSingleton.cpp @@ -30,6 +30,10 @@ StringName const& MenuSingleton::_signal_search_cache_changed() { static const StringName signal_search_cache_changed = "search_cache_changed"; return signal_search_cache_changed; } +StringName const& MenuSingleton::_signal_update_tooltip() { + static const StringName signal_update_tooltip = "update_tooltip"; + return signal_update_tooltip; +} String MenuSingleton::get_state_name(State const& state) const { StateSet const& state_set = state.get_state_set(); @@ -103,6 +107,16 @@ String MenuSingleton::get_country_adjective(CountryInstance const& country) cons } void MenuSingleton::_bind_methods() { + /* TOOLTIP */ + OV_BIND_METHOD(MenuSingleton::show_tooltip, { "text", "substitution_dict", "position" }); + OV_BIND_METHOD(MenuSingleton::show_control_tooltip, { "text", "substitution_dict", "control" }); + OV_BIND_METHOD(MenuSingleton::hide_tooltip); + + ADD_SIGNAL(MethodInfo( + _signal_update_tooltip(), PropertyInfo(Variant::STRING, "text"), + PropertyInfo(Variant::DICTIONARY, "substitution_dict"), PropertyInfo(Variant::VECTOR2, "position") + )); + /* PROVINCE OVERVIEW PANEL */ OV_BIND_METHOD(MenuSingleton::get_province_info_from_index, { "index" }); OV_BIND_METHOD(MenuSingleton::get_province_building_count); @@ -205,6 +219,25 @@ MenuSingleton::~MenuSingleton() { singleton = nullptr; } +/* TOOLTIP */ + +void MenuSingleton::show_tooltip(String const& text, Dictionary const& substitution_dict, Vector2 const& position) { + emit_signal(_signal_update_tooltip(), text, substitution_dict, position); +} + +void MenuSingleton::show_control_tooltip(String const& text, Dictionary const& substitution_dict, Control const* control) { + ERR_FAIL_NULL(control); + + using namespace OpenVic::Utilities::literals; + static const Vector2 offset { 0.0_real, 64.0_real }; + + show_tooltip(text, substitution_dict, control->get_global_position() + offset); +} + +void MenuSingleton::hide_tooltip() { + show_tooltip({}, {}, {}); +} + /* PROVINCE OVERVIEW PANEL */ static TypedArray _make_buildings_dict_array( diff --git a/extension/src/openvic-extension/singletons/MenuSingleton.hpp b/extension/src/openvic-extension/singletons/MenuSingleton.hpp index 190e3ea..022bce5 100644 --- a/extension/src/openvic-extension/singletons/MenuSingleton.hpp +++ b/extension/src/openvic-extension/singletons/MenuSingleton.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -95,6 +96,10 @@ namespace OpenVic { static godot::StringName const& _signal_population_menu_pops_changed(); /* Emitted when the collection of possible search results changes. */ static godot::StringName const& _signal_search_cache_changed(); + /* Emitted when the current tooltip changes. Arguments: text (godot::String), substitution_dict (godot::Dictionary), + * position (godot::Vector2). If text is empty then the tooltip will be hidden, otherwise the text will be shown at + * the given position. */ + static godot::StringName const& _signal_update_tooltip(); godot::String get_state_name(State const& state) const; godot::String get_country_name(CountryInstance const& country) const; @@ -110,6 +115,15 @@ namespace OpenVic { MenuSingleton(); ~MenuSingleton(); + /* TOOLTIP */ + void show_tooltip( + godot::String const& text, godot::Dictionary const& substitution_dict, godot::Vector2 const& position + ); + void show_control_tooltip( + godot::String const& text, godot::Dictionary const& substitution_dict, godot::Control const* control + ); + void hide_tooltip(); + /* PROVINCE OVERVIEW PANEL */ /* Get info to display in Province Overview Panel, packaged in a Dictionary using StringName constants as keys. */ godot::Dictionary get_province_info_from_index(int32_t index) const; diff --git a/game/src/Game/GameSession/GameSession.tscn b/game/src/Game/GameSession/GameSession.tscn index 018aad8..5925f3d 100644 --- a/game/src/Game/GameSession/GameSession.tscn +++ b/game/src/Game/GameSession/GameSession.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=20 format=3 uid="uid://bgnupcshe1m7r"] +[gd_scene load_steps=21 format=3 uid="uid://bgnupcshe1m7r"] [ext_resource type="Script" path="res://src/Game/GameSession/GameSession.gd" id="1_eklvp"] [ext_resource type="PackedScene" uid="uid://cvl76duuym1wq" path="res://src/Game/MusicConductor/MusicPlayer.tscn" id="2_kt6aa"] @@ -19,6 +19,7 @@ [ext_resource type="Script" path="res://src/Game/GameSession/NationManagementScreen/TradeMenu.gd" id="10_mv1r6"] [ext_resource type="Script" path="res://src/Game/GameSession/NationManagementScreen/DiplomacyMenu.gd" id="11_fu7ys"] [ext_resource type="Script" path="res://src/Game/GameSession/NationManagementScreen/MilitaryMenu.gd" id="12_6h6nc"] +[ext_resource type="Script" path="res://src/Game/GameSession/Tooltip.gd" id="20_3306e"] [node name="GameSession" type="Control" node_paths=PackedStringArray("_model_manager", "_game_session_menu")] editor_description = "SS-102, UI-546" @@ -156,6 +157,11 @@ offset_left = -150.0 offset_right = 0.0 grow_horizontal = 0 +[node name="Tooltip" type="GUINode" parent="UICanvasLayer/UI"] +layout_mode = 1 +anchors_preset = 15 +script = ExtResource("20_3306e") + [connection signal="detailed_view_changed" from="MapView" to="ModelManager" method="set_visible"] [connection signal="map_view_camera_changed" from="MapView" to="UICanvasLayer/UI/MapControlPanel" method="_on_map_view_camera_changed"] [connection signal="game_session_menu_button_pressed" from="UICanvasLayer/UI/MapControlPanel" to="." method="_on_game_session_menu_button_pressed"] diff --git a/game/src/Game/GameSession/NationManagementScreen/BudgetMenu.gd b/game/src/Game/GameSession/NationManagementScreen/BudgetMenu.gd index ea92beb..021c9f2 100644 --- a/game/src/Game/GameSession/NationManagementScreen/BudgetMenu.gd +++ b/game/src/Game/GameSession/NationManagementScreen/BudgetMenu.gd @@ -42,6 +42,12 @@ var _debt_chart : GUIPieChart const _screen : NationManagement.Screen = NationManagement.Screen.BUDGET +# TODO - testing function, should be replaced with calls to SIM which trigger UI updates through gamestate_updated +func _on_tax_slider_changed(slider : GUIScrollbar, label : GUILabel, tooltip : String, value : int) -> void: + label.text = "%s¤" % GUINode.float_to_string_dp(value, 3 if abs(value) < 1000 else 1) + slider.set_tooltip_string("%s: §Y%s%%" % [tr(tooltip), GUINode.float_to_string_dp(value, 1)]) + + func _ready() -> void: GameSingleton.gamestate_updated.connect(_update_info) @@ -87,15 +93,24 @@ func _ready() -> void: # income var _lower_class_slider : GUIScrollbar = get_gui_scrollbar_from_nodepath(^"./country_budget/tax_0_slider") if _lower_class_slider and _lower_class_label: - _lower_class_slider.value_changed.connect(func(value : int) -> void: _lower_class_label.text = "%s¤" % GUINode.float_to_string_dp(value, 3 if abs(value) < 1000 else 1)) + _lower_class_slider.value_changed.connect( + func (value : int) -> void: + _on_tax_slider_changed(_lower_class_slider, _lower_class_label, "BUDGET_TAX_POOR", value) + ) _lower_class_slider.emit_value_changed() var _middle_class_slider : GUIScrollbar = get_gui_scrollbar_from_nodepath(^"./country_budget/tax_1_slider") if _middle_class_slider and _middle_class_label: - _middle_class_slider.value_changed.connect(func(value : int) -> void: _middle_class_label.text = "%s¤" % GUINode.float_to_string_dp(value, 3 if abs(value) < 1000 else 1)) + _middle_class_slider.value_changed.connect( + func (value : int) -> void: + _on_tax_slider_changed(_middle_class_slider, _middle_class_label, "BUDGET_TAX_MIDDLE", value) + ) _middle_class_slider.emit_value_changed() var _upper_class_slider : GUIScrollbar = get_gui_scrollbar_from_nodepath(^"./country_budget/tax_2_slider") if _upper_class_slider and _upper_class_label: - _upper_class_slider.value_changed.connect(func(value : int) -> void: _upper_class_label.text = "%s¤" % GUINode.float_to_string_dp(value, 3 if abs(value) < 1000 else 1)) + _upper_class_slider.value_changed.connect( + func (value : int) -> void: + _on_tax_slider_changed(_upper_class_slider, _upper_class_label, "BUDGET_TAX_RICH", value) + ) _upper_class_slider.emit_value_changed() # costs diff --git a/game/src/Game/GameSession/NationManagementScreen/PopulationMenu.gd b/game/src/Game/GameSession/NationManagementScreen/PopulationMenu.gd index d8af97f..eb57387 100644 --- a/game/src/Game/GameSession/NationManagementScreen/PopulationMenu.gd +++ b/game/src/Game/GameSession/NationManagementScreen/PopulationMenu.gd @@ -319,15 +319,28 @@ func _setup_pop_list() -> void: var culture_label : GUILabel = GUINode.get_gui_label_from_node(pop_row_panel.get_node(^"./pop_nation")) _pop_list_culture_labels.push_back(culture_label) + if culture_label: + culture_label.set_mouse_filter(MOUSE_FILTER_PASS) - _pop_list_religion_icons.push_back(GUINode.get_gui_icon_from_node(pop_row_panel.get_node(^"./pop_religion"))) + var religion_icon : GUIIcon = GUINode.get_gui_icon_from_node(pop_row_panel.get_node(^"./pop_religion")) + _pop_list_religion_icons.push_back(religion_icon) + if religion_icon: + religion_icon.set_mouse_filter(MOUSE_FILTER_PASS) var location_label : GUILabel = GUINode.get_gui_label_from_node(pop_row_panel.get_node(^"./pop_location")) _pop_list_location_labels.push_back(location_label) + if location_label: + location_label.set_mouse_filter(MOUSE_FILTER_PASS) - _pop_list_militancy_labels.push_back(GUINode.get_gui_label_from_node(pop_row_panel.get_node(^"./pop_mil"))) + var militancy_label : GUILabel = GUINode.get_gui_label_from_node(pop_row_panel.get_node(^"./pop_mil")) + _pop_list_militancy_labels.push_back(militancy_label) + if militancy_label: + militancy_label.set_mouse_filter(MOUSE_FILTER_PASS) - _pop_list_consciousness_labels.push_back(GUINode.get_gui_label_from_node(pop_row_panel.get_node(^"./pop_con"))) + var consciousness_label : GUILabel = GUINode.get_gui_label_from_node(pop_row_panel.get_node(^"./pop_con")) + _pop_list_consciousness_labels.push_back(consciousness_label) + if consciousness_label: + consciousness_label.set_mouse_filter(MOUSE_FILTER_PASS) _pop_list_ideology_charts.push_back(GUINode.get_gui_pie_chart_from_node(pop_row_panel.get_node(^"./pop_ideology"))) @@ -335,17 +348,20 @@ func _setup_pop_list() -> void: _pop_list_unemployment_progressbars.push_back(GUINode.get_gui_progress_bar_from_node(pop_row_panel.get_node(^"./pop_unemployment_bar"))) - _pop_list_cash_labels.push_back(GUINode.get_gui_label_from_node(pop_row_panel.get_node(^"./pop_cash"))) + var cash_label : GUILabel = GUINode.get_gui_label_from_node(pop_row_panel.get_node(^"./pop_cash")) + _pop_list_cash_labels.push_back(cash_label) + if cash_label: + cash_label.set_mouse_filter(MOUSE_FILTER_PASS) var pop_list_life_needs_progressbar : GUIProgressBar = GUINode.get_gui_progress_bar_from_node(pop_row_panel.get_node(^"./lifeneed_progress")) + _pop_list_life_needs_progressbars.push_back(pop_list_life_needs_progressbar) if pop_list_life_needs_progressbar: pop_list_life_needs_progressbar.position += Vector2(1, 0) - _pop_list_life_needs_progressbars.push_back(pop_list_life_needs_progressbar) var pop_list_everyday_needs_progressbar : GUIProgressBar = GUINode.get_gui_progress_bar_from_node(pop_row_panel.get_node(^"./eveneed_progress")) + _pop_list_everyday_needs_progressbars.push_back(pop_list_everyday_needs_progressbar) if pop_list_everyday_needs_progressbar: pop_list_everyday_needs_progressbar.position += Vector2(1, 0) - _pop_list_everyday_needs_progressbars.push_back(pop_list_everyday_needs_progressbar) _pop_list_luxury_needs_progressbars.push_back(GUINode.get_gui_progress_bar_from_node(pop_row_panel.get_node(^"./luxneed_progress"))) @@ -357,9 +373,15 @@ func _setup_pop_list() -> void: _pop_list_national_movement_flags.push_back(GUINode.get_gui_masked_flag_from_node(pop_row_panel.get_node(^"./pop_movement_flag"))) - _pop_list_size_change_icons.push_back(GUINode.get_gui_icon_from_node(pop_row_panel.get_node(^"./growth_indicator"))) + var size_change_icon : GUIIcon = GUINode.get_gui_icon_from_node(pop_row_panel.get_node(^"./growth_indicator")) + _pop_list_size_change_icons.push_back(size_change_icon) + if size_change_icon: + size_change_icon.set_mouse_filter(MOUSE_FILTER_PASS) - _pop_list_literacy_labels.push_back(GUINode.get_gui_label_from_node(pop_row_panel.get_node(^"./pop_literacy"))) + var literacy_label : GUILabel = GUINode.get_gui_label_from_node(pop_row_panel.get_node(^"./pop_literacy")) + _pop_list_literacy_labels.push_back(literacy_label) + if literacy_label: + literacy_label.set_mouse_filter(MOUSE_FILTER_PASS) func _notification(what : int) -> void: match what: @@ -514,6 +536,10 @@ func _update_distributions(): var colour_icon : GUIIcon = GUINode.get_gui_icon_from_node(child.get_node(^"./legend_color")) if colour_icon: colour_icon.set_modulate(distribution_row[slice_colour_key]) + colour_icon.set_mouse_filter(MOUSE_FILTER_PASS) + colour_icon.set_tooltip_string_and_substitution_dict("§Y$ID$§!: $PC$%", { + "ID": distribution_row[slice_identifier_key], "PC": GUINode.float_to_string_dp(distribution_row[slice_weight_key] * 100.0, 2) + }) var identifier_label : GUILabel = GUINode.get_gui_label_from_node(child.get_node(^"./legend_title")) if identifier_label: @@ -563,30 +589,60 @@ func _update_pop_list() -> void: _pop_list_size_labels[index].set_text(GUINode.int_to_string_suffixed(pop_row[pop_size_key])) if _pop_list_type_buttons[index]: _pop_list_type_buttons[index].set_icon_index(pop_row[pop_type_icon_key]) + # TODO - replace with actual poptype + _pop_list_type_buttons[index].set_tooltip_string("Pop Type #%d" % pop_row[pop_type_icon_key]) if _pop_list_culture_labels[index]: _pop_list_culture_labels[index].set_text(pop_row[pop_culture_key]) + _pop_list_culture_labels[index].set_tooltip_string("NO_ASSIM_NOW") if _pop_list_religion_icons[index]: _pop_list_religion_icons[index].set_icon_index(pop_row[pop_religion_icon_key]) + # TODO - replace with actual religion + _pop_list_religion_icons[index].set_tooltip_string("Religion #%d" % pop_row[pop_religion_icon_key]) if _pop_list_location_labels[index]: - _pop_list_location_labels[index].set_text(GUINode.format_province_name(pop_row.get(pop_location_key, ""))) + var province_name : String = GUINode.format_province_name(pop_row.get(pop_location_key, "")) + _pop_list_location_labels[index].set_text(province_name) + _pop_list_location_labels[index].set_tooltip_string(province_name) if _pop_list_militancy_labels[index]: _pop_list_militancy_labels[index].set_text(GUINode.float_to_string_dp(pop_row[pop_militancy_key], 2)) + # TODO - test tooltip, add monthly change + source breakdown + _pop_list_militancy_labels[index].set_tooltip_string("POP_MIL_TOTAL") if _pop_list_consciousness_labels[index]: _pop_list_consciousness_labels[index].set_text(GUINode.float_to_string_dp(pop_row[pop_consciousness_key], 2)) + # TODO - test tooltip, add monthly change + source breakdown + _pop_list_consciousness_labels[index].set_tooltip_string("POP_CON_TOTAL") if _pop_list_ideology_charts[index]: _pop_list_ideology_charts[index].set_slices_array(pop_row[pop_ideology_key]) if _pop_list_issues_charts[index]: _pop_list_issues_charts[index].set_slices_array(pop_row[pop_issues_key]) if _pop_list_unemployment_progressbars[index]: - _pop_list_unemployment_progressbars[index].set_value_no_signal(pop_row[pop_unemployment_key]) + var unemployment : float = pop_row[pop_unemployment_key] + _pop_list_unemployment_progressbars[index].set_value_no_signal(unemployment) + _pop_list_unemployment_progressbars[index].set_tooltip_string("%s: §Y%s%%" % [ + tr("UNEMPLOYMENT"), GUINode.float_to_string_dp(unemployment * 100.0, 3) + ]) if _pop_list_cash_labels[index]: - _pop_list_cash_labels[index].set_text(GUINode.float_to_string_dp(pop_row[pop_cash_key], 2)) + _pop_list_cash_labels[index].set_text("%s¤" % GUINode.float_to_string_dp(pop_row[pop_cash_key], 2)) + _pop_list_cash_labels[index].set_tooltip_string_and_substitution_dict("POP_DAILY_MONEY", { + "VAL": GUINode.float_to_string_dp(1.23, 2) + }) if _pop_list_life_needs_progressbars[index]: - _pop_list_life_needs_progressbars[index].set_value_no_signal(pop_row[pop_life_needs_key]) + var life_needs : float = pop_row[pop_life_needs_key] + _pop_list_life_needs_progressbars[index].set_value_no_signal(life_needs) + _pop_list_life_needs_progressbars[index].set_tooltip_string_and_substitution_dict("GETTING_NEEDS", { + "NEED": "LIFE_NEEDS", "VAL": GUINode.float_to_string_dp(life_needs * 100.0, 1) + }) if _pop_list_everyday_needs_progressbars[index]: - _pop_list_everyday_needs_progressbars[index].set_value_no_signal(pop_row[pop_everyday_needs_key]) + var everyday_needs : float = pop_row[pop_everyday_needs_key] + _pop_list_everyday_needs_progressbars[index].set_value_no_signal(everyday_needs) + _pop_list_everyday_needs_progressbars[index].set_tooltip_string_and_substitution_dict("GETTING_NEEDS", { + "NEED": "EVERYDAY_NEEDS", "VAL": GUINode.float_to_string_dp(everyday_needs * 100.0, 1) + }) if _pop_list_luxury_needs_progressbars[index]: - _pop_list_luxury_needs_progressbars[index].set_value_no_signal(pop_row[pop_luxury_needs_key]) + var luxury_needs : float = pop_row[pop_luxury_needs_key] + _pop_list_luxury_needs_progressbars[index].set_value_no_signal(luxury_needs) + _pop_list_luxury_needs_progressbars[index].set_tooltip_string_and_substitution_dict("GETTING_NEEDS", { + "NEED": "LUXURY_NEEDS", "VAL": GUINode.float_to_string_dp(luxury_needs * 100.0, 1) + }) if _pop_list_rebel_icons[index]: var rebel_icon : int = pop_row.get(pop_rebel_icon_key, 0) if rebel_icon > 0: @@ -604,9 +660,16 @@ func _update_pop_list() -> void: _pop_list_national_movement_flags[index].hide() if _pop_list_size_change_icons[index]: - _pop_list_size_change_icons[index].set_icon_index(get_growth_icon_index(pop_row[pop_size_change_key])) + var pop_change : int = pop_row[pop_size_change_key] + _pop_list_size_change_icons[index].set_icon_index(get_growth_icon_index(pop_change)) + _pop_list_size_change_icons[index].set_tooltip_string("%s §%s%s" % [ + tr("POPULATION_CHANGED_BY"), "G+" if pop_change > 0 else "Y+" if pop_change == 0 else "R", str(pop_change) + ]) if _pop_list_literacy_labels[index]: _pop_list_literacy_labels[index].set_text("%s%%" % GUINode.float_to_string_dp(pop_row[pop_literacy_key], 2)) + _pop_list_literacy_labels[index].set_tooltip_string("%s: §G%s%%" % [ + tr("LIT_CHANGE"), GUINode.float_to_string_dp(pop_row[pop_literacy_key] / 64.0, 2) + ]) _pop_list_rows[index].show() else: diff --git a/game/src/Game/GameSession/Tooltip.gd b/game/src/Game/GameSession/Tooltip.gd new file mode 100644 index 0000000..c110e2e --- /dev/null +++ b/game/src/Game/GameSession/Tooltip.gd @@ -0,0 +1,23 @@ +extends GUINode + +var _tooltip_label : GUILabel + +func _ready() -> void: + add_gui_element("core", "ToolTip") + + _tooltip_label = get_gui_label_from_nodepath(^"./ToolTip") + if _tooltip_label: + _tooltip_label.set_auto_adjust_to_content_size(true) + + MenuSingleton.update_tooltip.connect(update_tooltip) + + hide() + +func update_tooltip(text : String, substitution_dict : Dictionary, position : Vector2) -> void: + if text: + _tooltip_label.set_text(text) + _tooltip_label.set_substitution_dict(substitution_dict) + _tooltip_label.set_position(position) + show() + else: + hide() diff --git a/game/src/Game/GameSession/Topbar.gd b/game/src/Game/GameSession/Topbar.gd index 62fa322..e3e0809 100644 --- a/game/src/Game/GameSession/Topbar.gd +++ b/game/src/Game/GameSession/Topbar.gd @@ -16,6 +16,7 @@ var _country_colonial_power_label : GUILabel # Time controls var _speed_up_button : GUIIconButton var _speed_down_button : GUIIconButton +var _pause_bg_button : GUIButton var _speed_indicator_button : GUIIconButton var _date_label : GUILabel @@ -101,24 +102,42 @@ func _ready() -> void: _country_flag_overlay_icon = get_gui_icon_from_nodepath(^"./topbar/topbar_flag_overlay") _country_name_label = get_gui_label_from_nodepath(^"./topbar/CountryName") _country_rank_label = get_gui_label_from_nodepath(^"./topbar/nation_totalrank") + if _country_rank_label: + _country_rank_label.set_mouse_filter(MOUSE_FILTER_PASS) _country_prestige_label = get_gui_label_from_nodepath(^"./topbar/country_prestige") + if _country_prestige_label: + _country_prestige_label.set_mouse_filter(MOUSE_FILTER_PASS) _country_prestige_rank_label = get_gui_label_from_nodepath(^"./topbar/selected_prestige_rank") + if _country_prestige_rank_label: + _country_prestige_rank_label.set_mouse_filter(MOUSE_FILTER_PASS) _country_industrial_power_label = get_gui_label_from_nodepath(^"./topbar/country_economic") + if _country_industrial_power_label: + _country_industrial_power_label.set_mouse_filter(MOUSE_FILTER_PASS) _country_industrial_power_rank_label = get_gui_label_from_nodepath(^"./topbar/selected_industry_rank") + if _country_industrial_power_rank_label: + _country_industrial_power_rank_label.set_mouse_filter(MOUSE_FILTER_PASS) _country_military_power_label = get_gui_label_from_nodepath(^"./topbar/country_military") + if _country_military_power_label: + _country_military_power_label.set_mouse_filter(MOUSE_FILTER_PASS) _country_military_power_rank_label = get_gui_label_from_nodepath(^"./topbar/selected_military_rank") + if _country_military_power_rank_label: + _country_military_power_rank_label.set_mouse_filter(MOUSE_FILTER_PASS) _country_colonial_power_label = get_gui_label_from_nodepath(^"./topbar/country_colonial_power") + if _country_colonial_power_label: + _country_colonial_power_label.set_mouse_filter(MOUSE_FILTER_PASS) # Time controls _speed_up_button = get_gui_icon_button_from_nodepath(^"./topbar/button_speedup") if _speed_up_button: _speed_up_button.pressed.connect(_on_increase_speed_button_pressed) + _speed_up_button.set_tooltip_string("TOPBAR_INC_SPEED") _speed_down_button = get_gui_icon_button_from_nodepath(^"./topbar/button_speeddown") if _speed_down_button: _speed_down_button.pressed.connect(_on_decrease_speed_button_pressed) - var pause_bg_button : GUIIconButton = get_gui_icon_button_from_nodepath(^"./topbar/pause_bg") - if pause_bg_button: - pause_bg_button.pressed.connect(_on_play_pause_button_pressed) + _speed_down_button.set_tooltip_string("TOPBAR_DEC_SPEED") + _pause_bg_button = get_gui_icon_button_from_nodepath(^"./topbar/pause_bg") + if _pause_bg_button: + _pause_bg_button.pressed.connect(_on_play_pause_button_pressed) _speed_indicator_button = get_gui_icon_button_from_nodepath(^"./topbar/speed_indicator") if _speed_indicator_button: _speed_indicator_button.pressed.connect(_on_play_pause_button_pressed) @@ -141,6 +160,8 @@ func _ready() -> void: button.pressed.connect( Events.NationManagementScreens.toggle_nation_management_screen.bind(screen) ) + # TODO - test tooltip, replace with actual shortcut strings + button.set_tooltip_string(tr("SHORTCUT") + "F3") _nation_management_buttons[screen] = button Events.NationManagementScreens.update_active_nation_management_screen.connect( _on_update_active_nation_management_screen @@ -158,10 +179,25 @@ func _ready() -> void: _budget_funds_label = get_gui_label_from_nodepath(^"./topbar/budget_funds") # Technology + var tech_button : GUIIconButton = _nation_management_buttons[NationManagement.Screen.TECHNOLOGY] _technology_progress_bar = get_gui_progress_bar_from_nodepath(^"./topbar/topbar_tech_progress") + if _technology_progress_bar and tech_button: + _technology_progress_bar.reparent(tech_button) _technology_current_research_label = get_gui_label_from_nodepath(^"./topbar/tech_current_research") + if _technology_current_research_label: + _technology_current_research_label.set_mouse_filter(MOUSE_FILTER_PASS) + if tech_button: + _technology_current_research_label.reparent(tech_button) _technology_literacy_label = get_gui_label_from_nodepath(^"./topbar/tech_literacy_value") + if _technology_literacy_label: + _technology_literacy_label.set_mouse_filter(MOUSE_FILTER_PASS) + if tech_button: + _technology_literacy_label.reparent(tech_button) _technology_research_points_label = get_gui_label_from_nodepath(^"./topbar/topbar_researchpoints_value") + if _technology_research_points_label: + _technology_research_points_label.set_mouse_filter(MOUSE_FILTER_PASS) + if tech_button: + _technology_research_points_label.reparent(tech_button) # Politics _politics_party_icon = get_gui_icon_from_nodepath(^"./topbar/politics_party_icon") @@ -238,45 +274,66 @@ func _notification(what : int) -> void: match what: NOTIFICATION_TRANSLATION_CHANGED: _update_info() + _update_speed_controls() func _update_info() -> void: # Placeholder data const player_country : String = "ENG" + const player_rank : int = 0 + + const RANK_NAMES : PackedStringArray = [ + "DIPLOMACY_GREATNATION_STATUS", + "DIPLOMACY_COLONIALNATION_STATUS", + "DIPLOMACY_CIVILIZEDNATION_STATUS", + "DIPLOMACY_UNCIVILIZEDNATION_STATUS" + ] ## Country info if _country_flag_button: _country_flag_button.set_flag_country_name(player_country) + _country_flag_button.set_tooltip_string_and_substitution_dict("PLAYER_COUNTRY_TOPBAR_RANK", { + "NAME": player_country, "RANK": RANK_NAMES[player_rank] + }) if _country_flag_overlay_icon: # 1 - Great Power # 2 - Secondary Power # 3 - Civilised # 4 - Uncivilised - _country_flag_overlay_icon.set_icon_index(1) + _country_flag_overlay_icon.set_icon_index(1 + player_rank) if _country_name_label: _country_name_label.set_text(player_country) if _country_rank_label: _country_rank_label.set_text(str(1)) + _country_rank_label.set_tooltip_string_and_substitution_dict("PLAYER_COUNTRY_TOPBAR_RANK", { + "NAME": player_country, "RANK": RANK_NAMES[player_rank] + }) if _country_prestige_label: _country_prestige_label.set_text(str(11)) + _country_military_power_label.set_tooltip_string("RANK_PRESTIGE") if _country_prestige_rank_label: _country_prestige_rank_label.set_text(str(1)) + _country_military_power_label.set_tooltip_string("RANK_PRESTIGE") if _country_industrial_power_label: _country_industrial_power_label.set_text(str(22)) + _country_military_power_label.set_tooltip_string("RANK_INDUSTRY") if _country_industrial_power_rank_label: _country_industrial_power_rank_label.set_text(str(2)) + _country_military_power_label.set_tooltip_string("RANK_INDUSTRY") if _country_military_power_label: _country_military_power_label.set_text(str(33)) + _country_military_power_label.set_tooltip_string("RANK_MILITARY") if _country_military_power_rank_label: _country_military_power_rank_label.set_text(str(3)) + _country_military_power_rank_label.set_tooltip_string("RANK_MILITARY") if _country_colonial_power_label: var available_colonial_power : int = 123 @@ -284,6 +341,7 @@ func _update_info() -> void: _country_colonial_power_label.set_text( "§%s%s§!/%s" % ["W" if available_colonial_power > 0 else "R", available_colonial_power, total_colonial_power] ) + _country_colonial_power_label.set_tooltip_string("COLONIAL_POINTS") ## Time control if _date_label: @@ -320,12 +378,21 @@ func _update_info() -> void: if _technology_current_research_label: # TODO - set current research or "unciv_nation" (in red) if uncivilised _technology_current_research_label.set_text("TB_TECH_NO_CURRENT") + _technology_current_research_label.set_tooltip_string("TECHNOLOGYVIEW_NO_RESEARCH_TOOLTIP") if _technology_literacy_label: - _technology_literacy_label.set_text("§Y%s§W%%" % GUINode.float_to_string_dp(80.0, 1)) + var literacy_float : float = 80.0 + var literacy_string : String = GUINode.float_to_string_dp(80.0, 1) + _technology_literacy_label.set_text("§Y%s§W%%" % literacy_string) + _technology_literacy_label.set_tooltip_string_and_substitution_dict("TOPBAR_AVG_LITERACY", { "AVG": literacy_string }) if _technology_research_points_label: _technology_research_points_label.set_text("§Y%s" % GUINode.float_to_string_dp(10.0, 2)) + # TODO - test tooltip, replace with actual values from the simulation + _technology_research_points_label.set_tooltip_string_and_substitution_dict("TECH_DAILY_RESEARCHPOINTS_TOOLTIP", { + "POPTYPE": "Clergymen", "VALUE": GUINode.float_to_string_dp(1.42, 2), + "FRACTION": GUINode.float_to_string_dp(0.95, 2), "OPTIMAL": GUINode.float_to_string_dp(2, 2) + }) ## Politics if _politics_party_icon: @@ -418,6 +485,9 @@ func _update_info() -> void: _military_leadership_points_label.set_text("§Y%d" % 15) func _update_speed_controls() -> void: + var paused : bool = MenuSingleton.is_paused() + var speed : int = MenuSingleton.get_speed() + # TODO - decide whether to disable these or not # (they don't appear to get disabled in the base game) #if _speed_up_button: @@ -426,10 +496,25 @@ func _update_speed_controls() -> void: #if _speed_down_button: # _speed_down_button.disabled = not MenuSingleton.can_decrease_speed() + if _pause_bg_button: + _pause_bg_button.set_tooltip_string("TOPBAR_DATE_IS_PAUSED" if paused else "TOPBAR_DATE") + if _speed_indicator_button: var index : int = 1 - if not MenuSingleton.is_paused(): - index += MenuSingleton.get_speed() + 1 + if paused: + _speed_indicator_button.set_tooltip_string("TOPBAR_PAUSE_INDICATOR") + else: + index += speed + 1 + const SPEED_NAMES : PackedStringArray = [ + "SLOWEST_SPEED", + "SLOW_SPEED", + "NORMAL_SPEED", + "FAST_SPEED", + "FASTEST_SPEED" + ] + _speed_indicator_button.set_tooltip_string_and_substitution_dict( + "TOPBAR_SPEED_INDICATOR", { "SPEED": SPEED_NAMES[speed] if speed < SPEED_NAMES.size() else str(speed) } + ) _speed_indicator_button.set_icon_index(index) # REQUIREMENTS: -- cgit v1.2.3-56-ga3b1