Refine settings tabs and data folder access

This commit is contained in:
Alexander Sellite 2026-08-16 17:57:08 -04:00
parent 5daf97967a
commit 1aa77180a4
3 changed files with 131 additions and 10 deletions

View file

@ -172,12 +172,97 @@ func _validate_data_settings_navigation() -> void:
root.add_child(panel)
await process_frame
panel.show()
panel.call("_select_page", &"data", false)
for _frame: int in 2:
await process_frame
var data_tab := panel.get_node("%DataTab") as Button
var open_data_folder := panel.get_node("%OpenDataFolder") as Button
var content_panel := panel.get_node("%ContentPanel") as PanelContainer
var tab_overlap: float = (
data_tab.get_global_rect().end.y
- content_panel.get_global_rect().position.y
)
_expect(
is_equal_approx(tab_overlap, data_tab.size.y * 0.5),
"Settings content does not cover the lower half of its organizer tabs.",
)
var open_activation := {"count": 0}
open_data_folder.pressed.connect(func() -> void:
open_activation["count"] = int(open_activation["count"]) + 1
)
data_tab.grab_focus()
var accept_press := InputEventAction.new()
accept_press.action = &"ui_accept"
accept_press.pressed = true
Input.parse_input_event(accept_press)
await process_frame
var accept_release := InputEventAction.new()
accept_release.action = &"ui_accept"
accept_release.pressed = false
Input.parse_input_event(accept_release)
for _frame: int in 2:
await process_frame
_expect(
panel.get_active_page_id() == &"data",
"Selecting the Data tab did not open the Data page.",
)
_expect(
int(open_activation["count"]) == 0,
"Selecting the Data tab also activated Open Data Folder.",
)
_expect(
root.gui_get_focus_owner() == data_tab,
"Selecting the Data tab transferred focus into its actions.",
)
var test_data_root := PlayerDataRoot.new()
root.add_child(test_data_root)
test_data_root.root_path = "/tmp/netfishing-controller-data"
panel.set("_data_root", test_data_root)
open_data_folder.grab_focus()
_expect(
root.gui_get_focus_owner() == open_data_folder,
"Open Data Folder did not accept controller focus.",
)
_expect(
not open_data_folder.disabled,
"Open Data Folder is unexpectedly disabled.",
)
var action_press := InputEventAction.new()
action_press.action = &"ui_accept"
action_press.pressed = true
Input.parse_input_event(action_press)
await process_frame
var action_release := InputEventAction.new()
action_release.action = &"ui_accept"
action_release.pressed = false
Input.parse_input_event(action_release)
for _frame: int in 2:
await process_frame
_expect(
int(open_activation["count"]) == 1,
(
"Explicitly accepting Open Data Folder pressed it %d times."
% int(open_activation["count"])
),
)
var confirmations: Array[Node] = panel.find_children(
"*", "ConfirmationDialog", true, false
)
_expect(
confirmations.size() == 1
and (confirmations.front() as ConfirmationDialog).visible,
"Explicitly accepting Open Data Folder did not request confirmation.",
)
if not confirmations.is_empty():
var confirmation := confirmations.front() as ConfirmationDialog
_expect(
confirmation.gui_get_focus_owner()
== confirmation.get_cancel_button(),
"Open Data Folder confirmation did not default to Cancel.",
)
confirmation.queue_free()
var controls: Array[Control] = [
panel.get_node("%DataTab") as Control,
panel.get_node("%OpenDataFolder") as Control,
data_tab,
open_data_folder,
panel.get_node("%ChangeDataFolder") as Control,
panel.get_node("%CopyPlayerFingerprint") as Control,
panel.get_node("%ExportPlayerIdentity") as Control,
@ -199,6 +284,7 @@ func _validate_data_settings_navigation() -> void:
"Settings children still contain bubble controls.",
)
panel.queue_free()
test_data_root.queue_free()
await process_frame

View file

@ -235,7 +235,7 @@ func _connect_controls() -> void:
)
%ControllerMapping.pressed.connect(_open_controller_mapping)
%KeyboardMapping.pressed.connect(_open_keyboard_mouse_mapping)
%OpenDataFolder.pressed.connect(_open_data_folder)
%OpenDataFolder.pressed.connect(_confirm_open_data_folder)
%ChangeDataFolder.pressed.connect(_choose_data_folder)
%ExportPlayerIdentity.pressed.connect(
_choose_identity_export.bind("player")
@ -635,6 +635,32 @@ func _open_data_folder() -> void:
_feedback.text = "could not open the data folder."
func _confirm_open_data_folder() -> void:
if _data_root == null:
_feedback.text = "the data folder is unavailable."
return
var dialog := ConfirmationDialog.new()
dialog.title = "open data folder?"
dialog.ok_button_text = "open folder"
dialog.cancel_button_text = "cancel"
dialog.dialog_text = (
"open this folder outside NETfishing?\n\n" + _data_root.root_path
)
dialog.confirmed.connect(func() -> void:
_open_data_folder()
dialog.queue_free()
)
dialog.canceled.connect(dialog.queue_free)
if _interface_fonts != null:
_interface_fonts.apply_utility_theme(dialog)
add_child(dialog)
dialog.popup_centered(Vector2i(620, 300))
_configure_confirmation_dialog.call_deferred(
dialog,
dialog.get_cancel_button(),
)
func _copy_player_fingerprint() -> void:
var fingerprint: String = (
_player_identity.fingerprint if _player_identity != null else ""

View file

@ -30,9 +30,10 @@ theme_override_constants/margin_bottom = 18
[node name="Layout" type="VBoxContainer" parent="MainPanel/OuterMargin"]
layout_mode = 2
theme_override_constants/separation = 8
theme_override_constants/separation = -26
[node name="Heading" type="Label" parent="MainPanel/OuterMargin/Layout"]
custom_minimum_size = Vector2(0, 66)
layout_mode = 2
theme_override_font_sizes/font_size = 30
text = "settings"
@ -90,7 +91,7 @@ palette_index = 1
[node name="ContentPanel" type="PanelContainer" parent="MainPanel/OuterMargin/Layout"]
unique_name_in_owner = true
custom_minimum_size = Vector2(0, 440)
custom_minimum_size = Vector2(0, 474)
layout_mode = 2
size_flags_vertical = 3
@ -610,7 +611,15 @@ size_flags_horizontal = 3
focus_mode = 2
text = "import host identity"
[node name="SettingsFeedback" type="Label" parent="MainPanel/OuterMargin/Layout"]
[node name="FooterGroup" type="MarginContainer" parent="MainPanel/OuterMargin/Layout"]
layout_mode = 2
theme_override_constants/margin_top = 34
[node name="FooterLayout" type="VBoxContainer" parent="MainPanel/OuterMargin/Layout/FooterGroup"]
layout_mode = 2
theme_override_constants/separation = 8
[node name="SettingsFeedback" type="Label" parent="MainPanel/OuterMargin/Layout/FooterGroup/FooterLayout"]
unique_name_in_owner = true
custom_minimum_size = Vector2(0, 24)
layout_mode = 2
@ -619,19 +628,19 @@ horizontal_alignment = 1
vertical_alignment = 1
text_overrun_behavior = 3
[node name="Footer" type="HBoxContainer" parent="MainPanel/OuterMargin/Layout"]
[node name="Footer" type="HBoxContainer" parent="MainPanel/OuterMargin/Layout/FooterGroup/FooterLayout"]
layout_mode = 2
theme_override_constants/separation = 12
alignment = 2
[node name="ApplySettingsButton" type="Button" parent="MainPanel/OuterMargin/Layout/Footer"]
[node name="ApplySettingsButton" type="Button" parent="MainPanel/OuterMargin/Layout/FooterGroup/FooterLayout/Footer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(180, 44)
layout_mode = 2
focus_mode = 2
text = "apply"
[node name="SettingsBackButton" type="Button" parent="MainPanel/OuterMargin/Layout/Footer"]
[node name="SettingsBackButton" type="Button" parent="MainPanel/OuterMargin/Layout/FooterGroup/FooterLayout/Footer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(180, 44)
layout_mode = 2