fix infinite recursion and focus management issues in video settings

This commit is contained in:
betalars 2025-03-24 17:17:25 +01:00
parent edc1603fe5
commit 5673f44b2d
2 changed files with 67 additions and 36 deletions

View File

@ -1,47 +1,47 @@
extends VBoxContainer
# This is a hack so values changing to the default to not create a recursion.
signal changed
signal leave_stage
var has_stage:bool = false:
set(stage):
has_stage = stage
preset_selected = preset_selected
match preset_selected:
1: %PerformancePreset.grab_focus()
2: %BalancedPreset.grab_focus()
3: %QualityPreset.grab_focus()
_: %FullscreenMode.grab_focus()
@export_file(".json") var settings_path = "user://video_settings.json"
@export_enum("None", "Performance", "Balanced", "Quality") var preset_selected:int = 2:
set(value):
# this may not call changed!
preset_selected = value
if has_stage:
match preset_selected:
1: %PerformancePreset.grab_focus()
2: %BalancedPreset.grab_focus()
3: %QualityPreset.grab_focus()
_: %FullscreenMode.grab_focus()
@export var window_mode: DisplayServer.WindowMode = DisplayServer.WindowMode.WINDOW_MODE_FULLSCREEN:
set(value):
window_mode = value
changed.emit()
if not ignore_changes: changed.emit()
@onready var fullscreen_selector: OptionButton = %FullscreenMode
@export_range(0.5, 2) var render_scale: float = 1:
set(value):
render_scale = value
changed.emit()
if not ignore_changes: changed.emit()
@onready var scale_selector: SpinBox = %RenderScale
@export var upscale_mode: RenderingServer.ViewportScaling3DMode = RenderingServer.ViewportScaling3DMode.VIEWPORT_SCALING_3D_MODE_BILINEAR :
set(value):
upscale_mode = value
changed.emit()
if not ignore_changes: changed.emit()
@onready var upscale_selector: OptionButton = %SuperResolution
@export_range(30, 144) var max_fps: int = 60:
set(value):
max_fps = value
changed.emit()
if not ignore_changes: changed.emit()
@onready var fps_enabler: CheckBox = %EnableFps
var fps_enabled: bool:
set(value):
@ -52,37 +52,39 @@ var fps_enabled: bool:
@export_enum("low", "medium", "high", "ultra") var lighting_quality: int = 3:
set(value):
lighting_quality = value
changed.emit()
if not ignore_changes: changed.emit()
@onready var lightning_selector: OptionButton = %LightingQuality
@export_enum("low", "medium", "high") var shadow_quality: int = 3:
set(value):
shadow_quality = value
changed.emit()
if not ignore_changes: changed.emit()
@onready var shadow_selector: OptionButton = %ShadowQuality
@export_enum("no", "1x", "2x", "4x", "8x") var texture_filtering:int = 3:
set(value):
texture_filtering = value
changed.emit()
if not ignore_changes: changed.emit()
@onready var texture_selector: OptionButton = %TextureFiltering
@export_enum("no", "1x", "2x", "4x") var msaa = 0:
set(value):
msaa = value
changed.emit()
if not ignore_changes: changed.emit()
@onready var msaa_selector: OptionButton = %AntiAlaising
@export var vsync_mode: DisplayServer.VSyncMode = DisplayServer.VSyncMode.VSYNC_ENABLED:
set(value):
vsync_mode = value
changed.emit()
if not ignore_changes: changed.emit()
@onready var vsync_selector: OptionButton = %vSync
var ignore_changes: bool = false
var has_changed: bool = false:
set(value):
has_changed = value
preset_selected = 0
if not ignore_changes:
preset_selected = 0
if has_changed:
%ExitButton.text = "discard"
else:
@ -106,7 +108,7 @@ func _ready() -> void:
fps_selector.value_changed.connect(func(value): max_fps = value)
fps_enabler.toggled.connect(func(value): fps_enabled = value)
changed.connect(func():has_changed = true)
changed.connect(func(): has_changed = true)
preset_selected = preset_selected
@ -114,6 +116,9 @@ func _ready() -> void:
%ConfirmExit.pressed.connect(_on_exit_confirmed)
%ConfirmSave.pressed.connect(_on_confirm_button_pressed)
%ConfirmAbort.pressed.connect($Popup.hide)
%PerformancePreset.pressed.connect(_on_performance_preset_pressed)
%BalancedPreset.pressed.connect(_on_balanced_preset_pressed)
%QualityPreset.pressed.connect(_on_quality_preset_pressed)
func load_settings():
@ -205,6 +210,9 @@ func _on_confirm_button_pressed() -> void:
save_settings()
func _on_performance_preset_pressed() -> void:
ignore_changes = true
has_changed = true
render_scale = 0.8
max_fps = 60
fps_enabled = true
@ -216,9 +224,15 @@ func _on_performance_preset_pressed() -> void:
propagate_settings()
changed.emit()
ignore_changes = false
preset_selected = 1
func _on_balanced_preset_pressed() -> void:
ignore_changes = true
has_changed = true
render_scale = 1
max_fps = 60
fps_enabled = true
@ -230,9 +244,15 @@ func _on_balanced_preset_pressed() -> void:
propagate_settings()
changed.emit()
ignore_changes = false
preset_selected = 2
func _on_quality_preset_pressed() -> void:
ignore_changes = true
has_changed = true
render_scale = 1
max_fps = 60
fps_enabled = false
@ -243,6 +263,9 @@ func _on_quality_preset_pressed() -> void:
vsync_mode = DisplayServer.VSyncMode.VSYNC_ENABLED
propagate_settings()
changed.emit()
ignore_changes = false
preset_selected = 3

View File

@ -44,37 +44,37 @@ func _ready() -> void:
func _input(event: InputEvent) -> void:
if has_focus():
if Input.is_action_just_pressed(\"ui_accept\"):
print(\"pressed!\")
print(pressed)
if event.is_action_pressed(\"ui_accept\"):
pressed = not pressed
print(pressed)
get_viewport().set_input_as_handled()
if pressed:
if Input.is_action_just_pressed(\"ui_up\") or Input.is_action_just_pressed(\"ui_right\"):
grab_focus()
#
if event.is_action_pressed(\"ui_up\") or event.is_action_pressed(\"ui_right\"):
value += step
get_viewport().set_input_as_handled()
await(get_tree().create_timer(hold_down_delay).timeout)
call_deferred(\"check_input_held\", true)
while Input.is_action_pressed(\"ui_up\") or Input.is_action_pressed(\"ui_right\"):
value += step * repeat_multiplier
await(get_tree().create_timer(repeat_delay).timeout)
elif Input.is_action_just_pressed(\"ui_down\") or Input.is_action_just_pressed(\"ui_left\"):
elif event.is_action_pressed(\"ui_down\", true) or event.is_action_pressed(\"ui_left\", true):
value -= step
get_viewport().set_input_as_handled()
else:
if Input.is_action_just_pressed(\"ui_up\"):
print(focus_neighbor_top)
call_deferred(\"check_input_held\", false)
get_viewport().set_input_as_handled()
func _on_focus_enter():
get_line_edit().add_theme_stylebox_override(\"normal\", focus_stylebox)
func _on_focus_exit():
get_line_edit().remove_theme_stylebox_override(\"normal\")
func check_input_held(upward: bool):
await(get_tree().create_timer(repeat_delay).timeout)
while ((Input.is_action_pressed(\"ui_up\", true) or Input.is_action_pressed(\"ui_right\", true) and upward) or (Input.is_action_pressed(\"ui_down\", true) or Input.is_action_pressed(\"ui_left\", true) and not upward)):
value += step * repeat_multiplier * (1 if upward else -1)
await(get_tree().create_timer(repeat_delay).timeout)
"
[node name="Video Settings" type="VBoxContainer"]
@ -134,6 +134,7 @@ layout_mode = 2
selected = 1
item_count = 3
popup/item_0/text = "Windowed"
popup/item_0/id = 0
popup/item_1/text = "Fullscreen"
popup/item_1/id = 1
popup/item_2/text = "exclusive Fullscreen"
@ -152,6 +153,7 @@ text = "reset"
[node name="RenderScale" type="SpinBox" parent="GridContainer/HBoxContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(120, 0)
layout_mode = 2
focus_mode = 2
min_value = 0.25
@ -174,7 +176,8 @@ layout_mode = 2
selected = 0
item_count = 3
popup/item_0/text = "disabled"
popup/item_1/text = " "
popup/item_0/id = 0
popup/item_1/text = " FSR 1.0"
popup/item_1/id = 1
popup/item_2/text = "FSR 2.2"
popup/item_2/id = 2
@ -214,6 +217,7 @@ layout_mode = 2
selected = 1
item_count = 4
popup/item_0/text = "minimum"
popup/item_0/id = 0
popup/item_1/text = "low (SDF Global Illumination)"
popup/item_1/id = 1
popup/item_2/text = "medium (SDF and Screen Space Global Illumination)"
@ -231,6 +235,7 @@ layout_mode = 2
selected = 1
item_count = 3
popup/item_0/text = "performance"
popup/item_0/id = 0
popup/item_1/text = "balanced"
popup/item_1/id = 1
popup/item_2/text = "quality"
@ -246,6 +251,7 @@ layout_mode = 2
selected = 1
item_count = 6
popup/item_0/text = "disabled"
popup/item_0/id = 0
popup/item_1/text = "1x (very fast)"
popup/item_1/id = 1
popup/item_2/text = "2x (fast)"
@ -267,6 +273,7 @@ layout_mode = 2
selected = 1
item_count = 4
popup/item_0/text = "disabled"
popup/item_0/id = 0
popup/item_1/text = "2x MSAA"
popup/item_1/id = 1
popup/item_2/text = "4x MSAA"
@ -284,6 +291,7 @@ layout_mode = 2
selected = 1
item_count = 4
popup/item_0/text = "disabled"
popup/item_0/id = 0
popup/item_1/text = "enabled"
popup/item_1/id = 1
popup/item_2/text = "adaptive"