diff --git a/src/dev-util/settings_popup.gd b/src/dev-util/settings_popup.gd index 2274090..ece6d11 100644 --- a/src/dev-util/settings_popup.gd +++ b/src/dev-util/settings_popup.gd @@ -1,9 +1,11 @@ class_name SettingsPopup extends PanelContainer -func show_settings(id: int = 0): +func show_settings(id: int = -1): $AnimationPlayer.play("reveal") - $TabContainer.current_tab = id + if not id == -1: + $TabContainer.current_tab = id State.pass_stage_to($TabContainer) func vanish(): $AnimationPlayer.play("vanish") + State.save_settings() diff --git a/src/logic-scenes/main menu/acessability_settings.gd b/src/logic-scenes/main menu/acessability_settings.gd index 0e79931..081be2e 100644 --- a/src/logic-scenes/main menu/acessability_settings.gd +++ b/src/logic-scenes/main menu/acessability_settings.gd @@ -16,7 +16,7 @@ var is_active:bool = false: if not active and is_active: if has_stage: State.leave_stage(self) - leave_stage.emit() + leave_stage.emit() is_active = active if (is_active and not has_stage) and not get_tree().paused: @@ -37,11 +37,11 @@ var is_active:bool = false: func _ready() -> void: if is_in_beginning: - %SaveButton.text = "menu_save_continue" - back_button.text = "" + %SaveButton.hide() + back_button.hide() else: %SaveButton.text = "menu_save" - back_button.hide() + back_button.visible = false update_ui_from_state() @@ -63,11 +63,7 @@ func _ready() -> void: scale_slider.drag_ended.connect(changed.emit) save_button.pressed.connect(_on_save_button_pressed) save_button.pressed.connect(changed.emit) - changed.connect(_on_changed) - -var has_unsaved_changes -func _on_changed(): - has_unsaved_changes = true + back_button.pressed.connect(func(): is_active = false) func _on_scale_slider_dragged(update:bool): if update: @@ -84,9 +80,8 @@ func update_ui_from_state(): scale_slider.value = State.ui_scaling func _on_save_button_pressed() -> void: - is_active = false State.save_settings() - has_unsaved_changes = false + is_active = false func _input(event: InputEvent) -> void: if event.is_action_pressed("ui_cancel") and is_active: diff --git a/src/logic-scenes/main menu/acessability_settings.tscn b/src/logic-scenes/main menu/acessability_settings.tscn index ae12cc7..84a97da 100644 --- a/src/logic-scenes/main menu/acessability_settings.tscn +++ b/src/logic-scenes/main menu/acessability_settings.tscn @@ -43,6 +43,7 @@ text = "menu_a11y_motion" unique_name_in_owner = true layout_mode = 2 size_flags_horizontal = 0 +disabled = true text = "use Screenreader" script = SubResource("GDScript_v567h") @@ -165,17 +166,16 @@ dragger_visibility = 1 unique_name_in_owner = true layout_mode = 2 disabled = true -text = "go back" +text = "menu_back" [node name="SaveButton" type="Button" parent="navbuttons"] unique_name_in_owner = true layout_mode = 2 -text = "save and continue" +text = "menu_save" [node name="card" parent="." instance=ExtResource("2_24dtk")] process_mode = 4 position = Vector2(837, 159) -rotation = 0.105957024 collision_layer = 0 collision_mask = 0 input_pickable = false diff --git a/src/logic-scenes/main menu/audio_settings.gd b/src/logic-scenes/main menu/audio_settings.gd index 6a5bfcf..a406f26 100644 --- a/src/logic-scenes/main menu/audio_settings.gd +++ b/src/logic-scenes/main menu/audio_settings.gd @@ -3,8 +3,6 @@ extends VBoxContainer signal changed signal leave_stage -var has_unsaved_changes:= false - var has_stage:bool = false: set(stage): has_stage = stage diff --git a/src/logic-scenes/main menu/audio_settings.tscn b/src/logic-scenes/main menu/audio_settings.tscn index 1f5e641..f23410a 100644 --- a/src/logic-scenes/main menu/audio_settings.tscn +++ b/src/logic-scenes/main menu/audio_settings.tscn @@ -104,9 +104,9 @@ unique_name_in_owner = true layout_mode = 2 size_flags_horizontal = 3 size_flags_vertical = 4 -max_value = 1.0 +max_value = 1.5 step = 0.05 -value = 0.5 +value = 1.0 ticks_on_borders = true [node name="MusicPreview" type="AudioStreamPlayer" parent="VBoxContainer/GridContainer/MusicSlider"] @@ -131,9 +131,9 @@ unique_name_in_owner = true layout_mode = 2 size_flags_horizontal = 3 size_flags_vertical = 4 -max_value = 1.0 +max_value = 1.5 step = 0.05 -value = 0.5 +value = 1.0 [node name="Label4" type="Label" parent="VBoxContainer/GridContainer"] layout_mode = 2 @@ -144,9 +144,9 @@ unique_name_in_owner = true layout_mode = 2 size_flags_horizontal = 3 size_flags_vertical = 4 -max_value = 1.0 +max_value = 1.5 step = 0.05 -value = 0.5 +value = 1.0 [node name="Label5" type="Label" parent="VBoxContainer/GridContainer"] layout_mode = 2 @@ -157,9 +157,9 @@ unique_name_in_owner = true layout_mode = 2 size_flags_horizontal = 3 size_flags_vertical = 4 -max_value = 1.0 +max_value = 1.5 step = 0.05 -value = 0.5 +value = 1.0 [node name="ForceStereoCheck" type="CheckBox" parent="."] unique_name_in_owner = true diff --git a/src/logic-scenes/main menu/content_settings.gd b/src/logic-scenes/main menu/content_settings.gd index 2f7676b..3e1e85c 100644 --- a/src/logic-scenes/main menu/content_settings.gd +++ b/src/logic-scenes/main menu/content_settings.gd @@ -19,9 +19,9 @@ var current_music_decay:float = 0 func _ready() -> void: if is_in_beginning: - %SaveButton.text = "save and continue" + %SaveButton.hide() else: - %SaveButton.text = "save and exit" + %SaveButton.text = "menu_save_exit" update_ui_from_state() @@ -30,8 +30,6 @@ func _ready() -> void: allow_skip_button.pressed.connect(func(value): State.allow_skipping = value) allow_skip_button.pressed.connect(changed.emit) - changed.connect(func(): has_unsaved_changes = true) - %SaveButton.pressed.connect(_on_exit_button_pressed) %ExpandButton.pressed.connect( func(): @@ -44,9 +42,9 @@ func update_ui_from_state(): allow_skip_button.button_pressed = State.allow_skipping func _on_exit_button_pressed() -> void: - leave_stage.emit() State.save_settings() has_unsaved_changes = false + leave_stage.emit() State.leave_stage(self) func _input(event: InputEvent) -> void: diff --git a/src/logic-scenes/main menu/gameplay_settings.tscn b/src/logic-scenes/main menu/gameplay_settings.tscn index 11bc32e..29eca29 100644 --- a/src/logic-scenes/main menu/gameplay_settings.tscn +++ b/src/logic-scenes/main menu/gameplay_settings.tscn @@ -16,7 +16,7 @@ metadata/_tab_index = 1 [node name="Label" type="Label" parent="."] layout_mode = 2 theme_type_variation = &"HeaderLarge" -text = "Gameplay Settings" +text = "setting_gameplay_title" [node name="Label2" type="Label" parent="."] visible = false @@ -43,6 +43,7 @@ text = "gameplay_invert_y_mouse" unique_name_in_owner = true layout_mode = 2 tooltip_text = "gameplay_simplify_tooltop" +disabled = true text = "gameplay_simplified" [node name="GridContainer" type="GridContainer" parent="VBoxContainer"] @@ -65,7 +66,7 @@ ticks_on_borders = true [node name="Label2" type="Label" parent="VBoxContainer/GridContainer"] layout_mode = 2 -text = "Field of View" +text = "gameplay_fov" [node name="FOVSlider" type="HSlider" parent="VBoxContainer/GridContainer"] unique_name_in_owner = true diff --git a/src/logic-scenes/main menu/main_menu.gd b/src/logic-scenes/main menu/main_menu.gd index bc172a9..b180e6a 100644 --- a/src/logic-scenes/main menu/main_menu.gd +++ b/src/logic-scenes/main menu/main_menu.gd @@ -35,7 +35,6 @@ signal roll_credits @onready var credits_button: Button = $PanelContainer/CreditsButton @onready var quit_button: Button = $PanelContainer/QuitButton @onready var save_game_handle: SaveGameHandle = %SaveGameHandle - @export var save_game_exists: bool = false: set(value): save_game_exists = value @@ -55,6 +54,7 @@ func _ready() -> void: load_game_button.disabled = not save_game_handle.has_existing_saves() settings_button.pressed.connect(settings_popup.show_settings) quit_button.pressed.connect(get_tree().quit) + credits_button.pressed.connect(roll_credits.emit) State.take_stage(self) diff --git a/src/logic-scenes/main menu/video_settings.gd b/src/logic-scenes/main menu/video_settings.gd index 66b43d6..43bf480 100644 --- a/src/logic-scenes/main menu/video_settings.gd +++ b/src/logic-scenes/main menu/video_settings.gd @@ -68,12 +68,6 @@ var fps_enabled: bool: 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 - 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 @@ -107,7 +101,6 @@ func _ready() -> void: upscale_selector.item_selected.connect(func(value): upscale_mode = value) lightning_selector.item_selected.connect(func(value): lighting_quality = value) shadow_selector.item_selected.connect(func(value): shadow_quality = value) - texture_selector.item_selected.connect(func(value): texture_filtering = value) msaa_selector.item_selected.connect(func(value): msaa = value) vsync_selector.item_selected.connect(func(value): vsync_mode = value) @@ -119,6 +112,7 @@ func _ready() -> void: preset_selected = preset_selected + %ConfirmButton.pressed.connect(_on_confirm_button_pressed) %ExitButton.pressed.connect(_on_exit_button_pressed) %ConfirmExit.pressed.connect(_on_exit_confirmed) %ConfirmSave.pressed.connect(_on_confirm_button_pressed) @@ -136,7 +130,8 @@ func load_settings(): var parsed: Dictionary = JSON.parse_string(raw_json) for key in parsed.keys(): - set(key, parsed[key]) + if key in self: + set(key, parsed[key]) else: if Steam.isSteamRunningOnSteamDeck(): @@ -154,7 +149,6 @@ func propagate_settings(): fps_selector.value = max_fps lightning_selector.select(lighting_quality) shadow_selector.select(shadow_quality) - texture_selector.select(texture_filtering) msaa_selector.select(msaa) vsync_selector.select(vsync_mode) @@ -167,7 +161,6 @@ func save_settings(): "max_fps": max_fps, "lighting_quality": lighting_quality, "shadow_quality": shadow_quality, - "texture_filtering": texture_filtering, "msaa": msaa, "vsync_mod": vsync_mode, "preset_selected": preset_selected @@ -199,29 +192,33 @@ func _on_confirm_button_pressed() -> void: ProjectSettings.set_setting("rendering/scaling_3d/mode", upscale_mode) RenderingServer.viewport_set_scaling_3d_scale(get_tree().root.get_viewport_rid(), upscale_mode) ProjectSettings.set_setting("application/run/max_fps", max_fps if fps_enabled else 0) + Engine.max_fps = max_fps if fps_enabled else 0 match lighting_quality: 0: State.ssil_enable = false State.sdfgi_enable = false - ProjectSettings.set_setting("rendering/shading/overrides/force_lambert_over_burley", true) 1: State.ssil_enable = false State.sdfgi_enable = true ProjectSettings.set_setting("rendering/global_illumination/sdfgi/probe_ray_count", 8) - ProjectSettings.set_setting("rendering/shading/overrides/force_lambert_over_burley", true) + RenderingServer.environment_set_sdfgi_ray_count(RenderingServer.ENV_SDFGI_RAY_COUNT_8) 2: State.ssil_enable = false State.sdfgi_enable = true ProjectSettings.set_setting("rendering/global_illumination/sdfgi/probe_ray_count", 16) ProjectSettings.set_setting("rendering/shading/overrides/force_lambert_over_burley", false) + RenderingServer.environment_set_sdfgi_ray_count(RenderingServer.ENV_SDFGI_RAY_COUNT_16) 3: State.ssil_enable = true State.sdfgi_enable = true ProjectSettings.set_setting("rendering/global_illumination/sdfgi/probe_ray_count", 32) ProjectSettings.set_setting("rendering/shading/overrides/force_lambert_over_burley", false) + RenderingServer.environment_set_sdfgi_ray_count(RenderingServer.ENV_SDFGI_RAY_COUNT_32) ProjectSettings.set_setting("rendering/lights_and_shadows/positional_shadow/soft_shadow_filter_quality", shadow_quality) + RenderingServer.directional_soft_shadow_filter_set_quality(shadow_quality*2+1) ProjectSettings.set_setting("rendering/lights_and_shadows/directional_shadow/soft_shadow_filter_quality", shadow_quality) - ProjectSettings.set_setting("rendering/textures/default_filters/anisotropic_filtering_level", texture_filtering) + RenderingServer.positional_soft_shadow_filter_set_quality(shadow_quality*2+1) + ProjectSettings.set_setting("rendering/anti_aliasing/quality/msaa_3d", msaa) ProjectSettings.set_setting("display/window/vsync/vsync_mode", vsync_mode) @@ -236,7 +233,6 @@ func _on_performance_preset_pressed() -> void: fps_enabled = true lighting_quality = 0 shadow_quality = 0 - texture_filtering = 1 msaa = 0 vsync_mode = DisplayServer.VSyncMode.VSYNC_DISABLED @@ -256,7 +252,6 @@ func _on_balanced_preset_pressed() -> void: fps_enabled = true lighting_quality = 2 shadow_quality = 1 - texture_filtering = 3 msaa = 1 vsync_mode = DisplayServer.VSyncMode.VSYNC_ENABLED @@ -276,7 +271,6 @@ func _on_quality_preset_pressed() -> void: fps_enabled = false lighting_quality = 3 shadow_quality = 2 - texture_filtering = 4 msaa = 3 vsync_mode = DisplayServer.VSyncMode.VSYNC_ENABLED diff --git a/src/logic-scenes/main menu/video_settings.tscn b/src/logic-scenes/main menu/video_settings.tscn index bffb817..86be4eb 100644 --- a/src/logic-scenes/main menu/video_settings.tscn +++ b/src/logic-scenes/main menu/video_settings.tscn @@ -260,28 +260,6 @@ popup/item_1/id = 1 popup/item_2/text = "quality" popup/item_2/id = 2 -[node name="FilterLabel" type="Label" parent="GridContainer"] -layout_mode = 2 -text = "Texture Filtering" - -[node name="TextureFiltering" type="OptionButton" parent="GridContainer"] -unique_name_in_owner = true -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)" -popup/item_2/id = 2 -popup/item_3/text = "4x (average)" -popup/item_3/id = 3 -popup/item_4/text = "8x (slow)" -popup/item_4/id = 4 -popup/item_5/text = "16x (slowest)" -popup/item_5/id = 5 - [node name="AlaisingLabel" type="Label" parent="GridContainer"] layout_mode = 2 text = "Anti Aliasing" @@ -318,10 +296,16 @@ popup/item_2/id = 2 popup/item_3/text = "Letterbox" popup/item_3/id = 3 +[node name="HBoxContainer" type="HBoxContainer" parent="GridContainer/vSync"] +visible = false +layout_mode = 0 +offset_right = 40.0 +offset_bottom = 40.0 + [node name="ExitButton" type="Button" parent="GridContainer"] unique_name_in_owner = true layout_mode = 2 -text = "close" +text = "menu_back" [node name="ConfirmButton" type="Button" parent="GridContainer"] unique_name_in_owner = true diff --git a/src/logic-scenes/startup/startup.tscn b/src/logic-scenes/startup/startup.tscn index d4b761b..0220ff7 100644 --- a/src/logic-scenes/startup/startup.tscn +++ b/src/logic-scenes/startup/startup.tscn @@ -1,7 +1,6 @@ [gd_scene load_steps=7 format=3 uid="uid://gldtxysavetf"] [ext_resource type="Texture2D" uid="uid://d0ucjqi8tx6vt" path="res://import/interface-elements/frame.png" id="1_8giso"] -[ext_resource type="Script" uid="uid://0tb763w0vfv7" path="res://tab_container.gd" id="2_lw8rc"] [ext_resource type="PackedScene" uid="uid://b3wlecqvelh22" path="res://logic-scenes/main menu/acessability_settings.tscn" id="3_2p4fc"] [ext_resource type="PackedScene" uid="uid://chal0ioagspx0" path="res://logic-scenes/main menu/content_settings.tscn" id="3_fso6q"] [ext_resource type="Texture2D" uid="uid://bwicl5q0lw06q" path="res://import/interface-elements/bottom.png" id="3_s5ssh"] @@ -107,6 +106,10 @@ func hide(): self.visible = false " +[sub_resource type="GDScript" id="GDScript_l80pk"] +script/source = "extends TabContainer +" + [node name="Startup Menu" type="Panel"] anchors_preset = 15 anchor_right = 1.0 @@ -116,6 +119,7 @@ grow_vertical = 2 script = SubResource("GDScript_a78qq") [node name="Label" type="Label" parent="."] +visible = false layout_mode = 1 anchors_preset = 5 anchor_left = 0.5 @@ -137,74 +141,80 @@ anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 -[node name="PanelContainer" type="PanelContainer" parent="CenterContainer"] +[node name="HSplitContainer" type="VSplitContainer" parent="CenterContainer"] layout_mode = 2 -[node name="StartFrame" type="TextureRect" parent="CenterContainer/PanelContainer"] +[node name="PanelContainer" type="PanelContainer" parent="CenterContainer/HSplitContainer"] +layout_mode = 2 + +[node name="StartFrame" type="TextureRect" parent="CenterContainer/HSplitContainer/PanelContainer"] layout_mode = 2 size_flags_horizontal = 8 texture = ExtResource("1_8giso") expand_mode = 2 stretch_mode = 4 -[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer/PanelContainer"] +[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer/HSplitContainer/PanelContainer"] layout_mode = 2 -[node name="TabContainer" type="TabContainer" parent="CenterContainer/PanelContainer/VBoxContainer"] +[node name="TabContainer" type="TabContainer" parent="CenterContainer/HSplitContainer/PanelContainer/VBoxContainer"] layout_mode = 2 current_tab = 1 tabs_visible = false use_hidden_tabs_for_min_size = true -script = ExtResource("2_lw8rc") +script = SubResource("GDScript_l80pk") -[node name="Accessibility" parent="CenterContainer/PanelContainer/VBoxContainer/TabContainer" instance=ExtResource("3_2p4fc")] +[node name="Accessibility" parent="CenterContainer/HSplitContainer/PanelContainer/VBoxContainer/TabContainer" instance=ExtResource("3_2p4fc")] +unique_name_in_owner = true visible = false layout_mode = 2 is_in_beginning = true -[node name="Content Notes" parent="CenterContainer/PanelContainer/VBoxContainer/TabContainer" instance=ExtResource("3_fso6q")] +[node name="ContentNotes" parent="CenterContainer/HSplitContainer/PanelContainer/VBoxContainer/TabContainer" instance=ExtResource("3_fso6q")] +unique_name_in_owner = true layout_mode = 2 +is_in_beginning = true -[node name="Managing Expectations" type="VBoxContainer" parent="CenterContainer/PanelContainer/VBoxContainer/TabContainer"] +[node name="Managing Expectations" type="VBoxContainer" parent="CenterContainer/HSplitContainer/PanelContainer/VBoxContainer/TabContainer"] visible = false layout_mode = 2 metadata/_tab_index = 2 -[node name="VSeparator" type="VSeparator" parent="CenterContainer/PanelContainer/VBoxContainer/TabContainer/Managing Expectations"] +[node name="VSeparator" type="VSeparator" parent="CenterContainer/HSplitContainer/PanelContainer/VBoxContainer/TabContainer/Managing Expectations"] custom_minimum_size = Vector2(0, 50) layout_mode = 2 -[node name="Label" type="RichTextLabel" parent="CenterContainer/PanelContainer/VBoxContainer/TabContainer/Managing Expectations"] +[node name="Label" type="RichTextLabel" parent="CenterContainer/HSplitContainer/PanelContainer/VBoxContainer/TabContainer/Managing Expectations"] layout_mode = 2 bbcode_enabled = true text = "[center][i]I assure you I did my best, But I am only human and this is just one game.[/i][/center]" fit_content = true -[node name="VSeparator2" type="VSeparator" parent="CenterContainer/PanelContainer/VBoxContainer/TabContainer/Managing Expectations"] +[node name="VSeparator2" type="VSeparator" parent="CenterContainer/HSplitContainer/PanelContainer/VBoxContainer/TabContainer/Managing Expectations"] custom_minimum_size = Vector2(0, 25) layout_mode = 2 -[node name="navbuttons" type="VSplitContainer" parent="CenterContainer/PanelContainer/VBoxContainer/TabContainer/Managing Expectations"] -layout_mode = 2 -size_flags_horizontal = 4 -size_flags_vertical = 10 - -[node name="Next" type="Button" parent="CenterContainer/PanelContainer/VBoxContainer/TabContainer/Managing Expectations/navbuttons"] -layout_mode = 2 -text = "menu_okay" - -[node name="previous" type="Button" parent="CenterContainer/PanelContainer/VBoxContainer/TabContainer/Managing Expectations/navbuttons"] -layout_mode = 2 -text = "menu_back" - -[node name="StartBottom" type="TextureRect" parent="CenterContainer/PanelContainer/VBoxContainer"] +[node name="StartBottom" type="TextureRect" parent="CenterContainer/HSplitContainer/PanelContainer/VBoxContainer"] custom_minimum_size = Vector2(0, 32) layout_mode = 2 texture = ExtResource("3_s5ssh") expand_mode = 2 stretch_mode = 5 +[node name="navbuttons" type="HSplitContainer" parent="CenterContainer/HSplitContainer"] +layout_mode = 2 +size_flags_horizontal = 4 +size_flags_vertical = 6 + +[node name="previous" type="Button" parent="CenterContainer/HSplitContainer/navbuttons"] +layout_mode = 2 +text = "menu_back" + +[node name="Next" type="Button" parent="CenterContainer/HSplitContainer/navbuttons"] +layout_mode = 2 +text = "menu_next" + [node name="continue" type="Button" parent="."] layout_mode = 1 anchors_preset = 7 @@ -237,7 +247,7 @@ grow_horizontal = 2 grow_vertical = 2 text = "I stream this game, please show content notes." -[connection signal="pressed" from="CenterContainer/PanelContainer/VBoxContainer/TabContainer/Managing Expectations/navbuttons/Next" to="." method="hide"] -[connection signal="pressed" from="CenterContainer/PanelContainer/VBoxContainer/TabContainer/Managing Expectations/navbuttons/previous" to="CenterContainer/PanelContainer/VBoxContainer/TabContainer" method="previous"] +[connection signal="pressed" from="CenterContainer/HSplitContainer/navbuttons/previous" to="CenterContainer/HSplitContainer/PanelContainer/VBoxContainer/TabContainer" method="previous"] +[connection signal="pressed" from="CenterContainer/HSplitContainer/navbuttons/Next" to="." method="hide"] [connection signal="pressed" from="continue" to="." method="hide"] [connection signal="toggled" from="continue/CheckBox" to="." method="_on_streaming_notes_toggled"] diff --git a/src/tab_container.gd b/src/tab_container.gd index 0d262fc..98f3bb0 100644 --- a/src/tab_container.gd +++ b/src/tab_container.gd @@ -16,18 +16,11 @@ func _on_tab_changed(tab_id: int): if child.has_stage: child_has_stage = true if child_has_stage: - State.pass_stage_to(get_child(tab_id)) + State.transition_stage_to(get_child(tab_id)) pass_to_actor = get_child(tab_id) func _on_stage_left(): await get_tree().process_frame if not pass_to_actor.has_stage: - var unsaved := false - for child in get_children(): - if child.has_unsaved_changes: - unsaved = true - if unsaved: - get_parent().vanish() - else: - get_parent().ask_confirmation() + get_parent().vanish()