From df97602c6d7335d0a8c83cddefef8716e47c37a0 Mon Sep 17 00:00:00 2001 From: Nemrav <> Date: Tue, 9 May 2023 21:08:41 -0300 Subject: Add UI scaling through menu option --- game/src/Autoload/GuiScale.gd | 65 +++++++++++++++++++++++++++++++++ game/src/GameSession/MapView.gd | 2 +- game/src/OptionMenu/GuiScaleSelector.gd | 65 +++++++++++++++++++++++++++++++++ game/src/OptionMenu/VideoTab.tscn | 18 ++++++++- 4 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 game/src/Autoload/GuiScale.gd create mode 100644 game/src/OptionMenu/GuiScaleSelector.gd (limited to 'game/src') diff --git a/game/src/Autoload/GuiScale.gd b/game/src/Autoload/GuiScale.gd new file mode 100644 index 0000000..d134f5b --- /dev/null +++ b/game/src/Autoload/GuiScale.gd @@ -0,0 +1,65 @@ +extends Node + +#the default value +const error_guiscale : float = 1 + +@export +var minimum_guiscale : float = 0.1 + +const _starting_guiscales : Dictionary = { + float(0.5): &"0.5x", + float(0.75): &"0.75x", + float(1): &"1x", + float(1.5): &"1.5x", + float(2): &"2x", +} + +var _guiscales: Dictionary + +#Similar to Resolution.gd, but we don't bother checking for strings from files +#and we have floats instead of vector2 integers + +func _ready(): + assert(minimum_guiscale > 0, "Minimum gui scale must be positive") + for guiscale_value in _starting_guiscales: + add_guiscale(guiscale_value, _starting_guiscales[guiscale_value]) + assert(not _guiscales.is_empty(), "No valid starting gui scales!") + +func has_guiscale(guiscale_value : float) -> bool: + return guiscale_value in _guiscales + +func add_guiscale(guiscale_value: float, guiscale_name: StringName=&"") -> bool: + if has_guiscale(guiscale_value): return true + var scale_dict := { value = guiscale_value } + var display_name := "%sx" % [guiscale_value] + if not guiscale_name.is_empty(): + scale_dict.name = guiscale_name + #don't need to change the display name + scale_dict.display_name = StringName(display_name) + if guiscale_value < minimum_guiscale: + push_error("GUI scale %s is smaller than the minimum %s" % [scale_dict.display_name,minimum_guiscale]) + return false + _guiscales[guiscale_value] = scale_dict + return true + +#returns floats +func get_guiscale_value_list() -> Array: + var list := _guiscales.keys() + list.sort_custom(func(a, b): return a > b) + return list + +func get_guiscale_display_name(guiscale_value : float) -> StringName: + return _guiscales.get(guiscale_value, {display_name = &"unknown gui scale"}).display_name + +func get_current_guiscale() -> float: + return get_tree().root.content_scale_factor + +func set_guiscale(guiscale:float) -> void: + print("New GUI scale: %f" % guiscale) + if not has_guiscale(guiscale): + push_warning("Setting GUI Scale to non-standard value %sx" % [guiscale]) + get_tree().root.content_scale_factor = guiscale + +func reset_guiscale() -> void: + set_guiscale(get_current_guiscale()) + diff --git a/game/src/GameSession/MapView.gd b/game/src/GameSession/MapView.gd index dc62594..c3b5cbb 100644 --- a/game/src/GameSession/MapView.gd +++ b/game/src/GameSession/MapView.gd @@ -175,7 +175,7 @@ func _movement_process(delta : float) -> void: func _edge_scrolling_vector() -> Vector2: if not _mouse_over_viewport: return Vector2() - var mouse_vector := _mouse_pos_viewport / _viewport_dims - Vector2(0.5, 0.5) + var mouse_vector := _mouse_pos_viewport * GuiScale.get_current_guiscale() / _viewport_dims - Vector2(0.5, 0.5) if abs(mouse_vector.x) < 0.5 - _edge_move_threshold and abs(mouse_vector.y) < 0.5 - _edge_move_threshold: mouse_vector *= 0 return mouse_vector * _edge_move_speed diff --git a/game/src/OptionMenu/GuiScaleSelector.gd b/game/src/OptionMenu/GuiScaleSelector.gd new file mode 100644 index 0000000..ec94269 --- /dev/null +++ b/game/src/OptionMenu/GuiScaleSelector.gd @@ -0,0 +1,65 @@ +extends SettingOptionButton + +@export +var default_value : float = GuiScale.error_guiscale + +func _find_guiscale_index_by_value(value : float) -> int: + for item_index in item_count: + if get_item_metadata(item_index) == value: + return item_index + return -1 + +func _sync_guiscales(to_select:float=GuiScale.get_current_guiscale()) -> void: + clear() + default_selected = -1 + selected = -1 + for guiscale_value in GuiScale.get_guiscale_value_list(): + add_item(GuiScale.get_guiscale_display_name(guiscale_value)) + set_item_metadata(item_count - 1, guiscale_value) + + if guiscale_value == default_value: + default_selected = item_count - 1 + + if guiscale_value == to_select: + selected = item_count - 1 + + if default_selected == -1: + default_selected = item_count - 1 + + if selected == -1: + selected = default_selected + +func _setup_button(): + print("Setup Gui scales Button") + if default_value <= 0: + #TODO: verify this project setting is what we actually want + #print("get default from project settings, default was %f",default_value) + default_value = ProjectSettings.get_setting("display/window/stretch/scale") + GuiScale.add_guiscale(default_value,&"default") + _sync_guiscales() + +func _get_value_for_file(select_value : int): + if _valid_index(select_value): + return get_item_metadata(select_value) + else: + return null + +func _set_value_from_file(load_value): + #no need to match types like resolution does since we don't + #intend on supporting strings + var target_guiscale = load_value + selected = _find_guiscale_index_by_value(target_guiscale) + if selected != -1:return + if GuiScale.add_guiscale(target_guiscale): + _sync_guiscales(target_guiscale) + return + push_error("Setting value '%s' invalid for setting [%s] %s" % [load_value, section_name, setting_name]) + selected = default_selected + +func _on_item_selected(index:int): + if _valid_index(index): + print("Change GUI scale on selector index: %d" % index) + GuiScale.set_guiscale(get_item_metadata(index)) + else: + push_error("Invalid GuiScaleSelector index: %d" % index) + reset_setting() diff --git a/game/src/OptionMenu/VideoTab.tscn b/game/src/OptionMenu/VideoTab.tscn index c92f7f7..8fc8747 100644 --- a/game/src/OptionMenu/VideoTab.tscn +++ b/game/src/OptionMenu/VideoTab.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=7 format=3 uid="uid://bq3awxxjn1tuw"] +[gd_scene load_steps=8 format=3 uid="uid://bq3awxxjn1tuw"] [ext_resource type="Script" path="res://src/OptionMenu/ResolutionSelector.gd" id="1_i8nro"] [ext_resource type="Script" path="res://src/OptionMenu/VideoTab.gd" id="1_jvv62"] [ext_resource type="Script" path="res://src/OptionMenu/ScreenModeSelector.gd" id="2_wa7vw"] +[ext_resource type="Script" path="res://src/OptionMenu/GuiScaleSelector.gd" id="3_pgc5d"] [ext_resource type="Script" path="res://src/OptionMenu/MonitorDisplaySelector.gd" id="3_y6lyb"] [ext_resource type="Script" path="res://src/OptionMenu/RefreshRateSelector.gd" id="4_381mg"] [ext_resource type="Script" path="res://src/OptionMenu/QualityPresetSelector.gd" id="5_srg4v"] @@ -42,6 +43,20 @@ script = ExtResource("1_i8nro") section_name = "video" setting_name = "resolution" +[node name="GuiScaleLabel" type="Label" parent="VBoxContainer/GridContainer"] +layout_mode = 2 +text = "OPTIONS_VIDEO_GUI_SCALE" + +[node name="GuiScaleSelector" type="OptionButton" parent="VBoxContainer/GridContainer"] +editor_description = "UI-19" +layout_mode = 2 +focus_neighbor_bottom = NodePath("../ScreenModeSelector") +item_count = 1 +selected = 0 +popup/item_0/text = "MISSING" +popup/item_0/id = 0 +script = ExtResource("3_pgc5d") + [node name="ScreenModeLabel" type="Label" parent="VBoxContainer/GridContainer"] editor_description = "UI-44" layout_mode = 2 @@ -138,5 +153,6 @@ setting_name = "quality_preset" default_selected = 1 [connection signal="item_selected" from="VBoxContainer/GridContainer/ResolutionSelector" to="VBoxContainer/GridContainer/ResolutionSelector" method="_on_item_selected"] +[connection signal="item_selected" from="VBoxContainer/GridContainer/GuiScaleSelector" to="VBoxContainer/GridContainer/GuiScaleSelector" method="_on_item_selected"] [connection signal="item_selected" from="VBoxContainer/GridContainer/ScreenModeSelector" to="VBoxContainer/GridContainer/ScreenModeSelector" method="_on_item_selected"] [connection signal="item_selected" from="VBoxContainer/GridContainer/MonitorDisplaySelector" to="VBoxContainer/GridContainer/MonitorDisplaySelector" method="_on_item_selected"] -- cgit v1.2.3-56-ga3b1 From 8a59cb15b58f512f27f01a71248feef4777e3a41 Mon Sep 17 00:00:00 2001 From: Hop311 Date: Wed, 10 May 2023 20:52:46 +0100 Subject: GUI scale tweaks --- game/src/Autoload/GuiScale.gd | 21 +++++++++------------ game/src/Autoload/Resolution.gd | 14 +++++++------- game/src/OptionMenu/GuiScaleSelector.gd | 27 +++++++++++++-------------- game/src/OptionMenu/VideoTab.tscn | 4 +++- 4 files changed, 32 insertions(+), 34 deletions(-) (limited to 'game/src') diff --git a/game/src/Autoload/GuiScale.gd b/game/src/Autoload/GuiScale.gd index d134f5b..afd73df 100644 --- a/game/src/Autoload/GuiScale.gd +++ b/game/src/Autoload/GuiScale.gd @@ -1,17 +1,16 @@ extends Node -#the default value -const error_guiscale : float = 1 +const error_guiscale : float = -1.0 @export var minimum_guiscale : float = 0.1 const _starting_guiscales : Dictionary = { - float(0.5): &"0.5x", + float(0.5) : &"0.5x", float(0.75): &"0.75x", - float(1): &"1x", - float(1.5): &"1.5x", - float(2): &"2x", + float(1) : &"1x", + float(1.5) : &"1.5x", + float(2) : &"2x", } var _guiscales: Dictionary @@ -31,13 +30,12 @@ func has_guiscale(guiscale_value : float) -> bool: func add_guiscale(guiscale_value: float, guiscale_name: StringName=&"") -> bool: if has_guiscale(guiscale_value): return true var scale_dict := { value = guiscale_value } - var display_name := "%sx" % [guiscale_value] if not guiscale_name.is_empty(): - scale_dict.name = guiscale_name - #don't need to change the display name - scale_dict.display_name = StringName(display_name) + scale_dict.display_name = guiscale_name + else: + scale_dict.display_name = StringName("%sx" % guiscale_value) if guiscale_value < minimum_guiscale: - push_error("GUI scale %s is smaller than the minimum %s" % [scale_dict.display_name,minimum_guiscale]) + push_error("GUI scale %s is smaller than the minimum %s" % [scale_dict.display_name, minimum_guiscale]) return false _guiscales[guiscale_value] = scale_dict return true @@ -62,4 +60,3 @@ func set_guiscale(guiscale:float) -> void: func reset_guiscale() -> void: set_guiscale(get_current_guiscale()) - diff --git a/game/src/Autoload/Resolution.gd b/game/src/Autoload/Resolution.gd index 35ecbb3..56aa4a5 100644 --- a/game/src/Autoload/Resolution.gd +++ b/game/src/Autoload/Resolution.gd @@ -9,13 +9,13 @@ const _starting_resolutions : Dictionary = { Vector2i(3840,2160): &"4K", Vector2i(2560,1080): &"UW1080p", Vector2i(1920,1080): &"1080p", - Vector2i(1366,768): &"", - Vector2i(1536,864): &"", - Vector2i(1280,720): &"720p", - Vector2i(1440,900): &"", - Vector2i(1600,900): &"", - Vector2i(1024,600): &"", - Vector2i(800,600): &"" + Vector2i(1366,768) : &"", + Vector2i(1536,864) : &"", + Vector2i(1280,720) : &"720p", + Vector2i(1440,900) : &"", + Vector2i(1600,900) : &"", + Vector2i(1024,600) : &"", + Vector2i(800,600) : &"" } var _resolutions : Dictionary diff --git a/game/src/OptionMenu/GuiScaleSelector.gd b/game/src/OptionMenu/GuiScaleSelector.gd index ec94269..6593a07 100644 --- a/game/src/OptionMenu/GuiScaleSelector.gd +++ b/game/src/OptionMenu/GuiScaleSelector.gd @@ -1,5 +1,9 @@ extends SettingOptionButton +# REQUIREMENTS +# * UIFUN-24 +# * UIFUN-31 + @export var default_value : float = GuiScale.error_guiscale @@ -9,7 +13,7 @@ func _find_guiscale_index_by_value(value : float) -> int: return item_index return -1 -func _sync_guiscales(to_select:float=GuiScale.get_current_guiscale()) -> void: +func _sync_guiscales(to_select : float = GuiScale.get_current_guiscale()) -> void: clear() default_selected = -1 selected = -1 @@ -30,12 +34,9 @@ func _sync_guiscales(to_select:float=GuiScale.get_current_guiscale()) -> void: selected = default_selected func _setup_button(): - print("Setup Gui scales Button") if default_value <= 0: - #TODO: verify this project setting is what we actually want - #print("get default from project settings, default was %f",default_value) default_value = ProjectSettings.get_setting("display/window/stretch/scale") - GuiScale.add_guiscale(default_value,&"default") + GuiScale.add_guiscale(default_value, &"default") _sync_guiscales() func _get_value_for_file(select_value : int): @@ -45,20 +46,18 @@ func _get_value_for_file(select_value : int): return null func _set_value_from_file(load_value): - #no need to match types like resolution does since we don't - #intend on supporting strings - var target_guiscale = load_value - selected = _find_guiscale_index_by_value(target_guiscale) - if selected != -1:return - if GuiScale.add_guiscale(target_guiscale): - _sync_guiscales(target_guiscale) - return + if typeof(load_value) == TYPE_FLOAT: + var target_guiscale : float = load_value + selected = _find_guiscale_index_by_value(target_guiscale) + if selected != -1: return + if GuiScale.add_guiscale(target_guiscale): + _sync_guiscales(target_guiscale) + return push_error("Setting value '%s' invalid for setting [%s] %s" % [load_value, section_name, setting_name]) selected = default_selected func _on_item_selected(index:int): if _valid_index(index): - print("Change GUI scale on selector index: %d" % index) GuiScale.set_guiscale(get_item_metadata(index)) else: push_error("Invalid GuiScaleSelector index: %d" % index) diff --git a/game/src/OptionMenu/VideoTab.tscn b/game/src/OptionMenu/VideoTab.tscn index 8fc8747..7c9e2ad 100644 --- a/game/src/OptionMenu/VideoTab.tscn +++ b/game/src/OptionMenu/VideoTab.tscn @@ -48,7 +48,7 @@ layout_mode = 2 text = "OPTIONS_VIDEO_GUI_SCALE" [node name="GuiScaleSelector" type="OptionButton" parent="VBoxContainer/GridContainer"] -editor_description = "UI-19" +editor_description = "UI-23" layout_mode = 2 focus_neighbor_bottom = NodePath("../ScreenModeSelector") item_count = 1 @@ -56,6 +56,8 @@ selected = 0 popup/item_0/text = "MISSING" popup/item_0/id = 0 script = ExtResource("3_pgc5d") +section_name = "video" +setting_name = "gui_scale" [node name="ScreenModeLabel" type="Label" parent="VBoxContainer/GridContainer"] editor_description = "UI-44" -- cgit v1.2.3-56-ga3b1