From b3ae7063832b9088db361d66446fd20ea32781d5 Mon Sep 17 00:00:00 2001 From: Emmanouil Papadeas <35376950+OverloadedOrama@users.noreply.github.com> Date: Fri, 31 Jan 2025 01:51:33 +0200 Subject: [PATCH] Add a Reset layout option for the default layouts in the layouts menu Easy and user friendly way to reset default layouts, similar to Photoshop. This only works for default layouts, currently Default and Tallscreen. --- Translations/Translations.pot | 5 ++++ addons/README.md | 2 +- addons/dockable_container/layout.gd | 16 ++++++++++++ assets/layouts/Default.tres | 1 + assets/layouts/Tallscreen.tres | 1 + src/Main.gd | 9 ++++++- src/UI/Dialogs/ManageLayouts.tscn | 1 + src/UI/TopMenuContainer/TopMenuContainer.gd | 27 ++++++++++++++------- 8 files changed, 51 insertions(+), 11 deletions(-) diff --git a/Translations/Translations.pot b/Translations/Translations.pot index bc11eb007..113531804 100644 --- a/Translations/Translations.pot +++ b/Translations/Translations.pot @@ -311,9 +311,14 @@ msgstr "" msgid "Masking:" msgstr "" +#. Verb, resets something. msgid "Reset" msgstr "" +#. Verb, resets something. +msgid "Reset %s" +msgstr "" + msgid "Use Current Frame" msgstr "" diff --git a/addons/README.md b/addons/README.md index 263765b85..eb9d652c8 100644 --- a/addons/README.md +++ b/addons/README.md @@ -24,7 +24,7 @@ Files extracted from source: ## godot-dockable-container - Upstream: https://github.com/gilzoide/godot-dockable-container -- Version: Based on [e852cbeeb3f06f62c559898b4cf5756858367766](https://github.com/OverloadedOrama/godot-dockable-container/commit/e852cbeeb3f06f62c559898b4cf5756858367766), but with changes in layout.gd that add a `save_on_change` variable and a `save()` method. +- Version: Based on [e852cbeeb3f06f62c559898b4cf5756858367766](https://github.com/OverloadedOrama/godot-dockable-container/commit/e852cbeeb3f06f62c559898b4cf5756858367766), but with changes in layout.gd that add a `save_on_change` and `layout_reset_path` variables, and a `save()`, `copy_from()` and `reset()` methods. - License: [CC0-1.0](https://github.com/gilzoide/godot-dockable-container/blob/main/LICENSE) ## SmartSlicer diff --git a/addons/dockable_container/layout.gd b/addons/dockable_container/layout.gd index 409418185..c37f25e51 100644 --- a/addons/dockable_container/layout.gd +++ b/addons/dockable_container/layout.gd @@ -41,6 +41,8 @@ enum { MARGIN_LEFT, MARGIN_RIGHT, MARGIN_TOP, MARGIN_BOTTOM, MARGIN_CENTER } if changed.is_connected(save): changed.disconnect(save) +## A path to a layout that this layout can be reset to. +@export var layout_reset_path := "" var _changed_signal_queued := false var _first_leaf: DockableLayoutPanel var _hidden_tabs: Dictionary @@ -76,6 +78,20 @@ func clone() -> DockableLayout: return duplicate(true) +func copy_from(other_layout: DockableLayout) -> void: + root = other_layout.root + hidden_tabs = other_layout.hidden_tabs + windows = other_layout.windows + changed.emit() + + +func reset() -> void: + if not layout_reset_path.is_empty(): + var layout_to_reset := load(layout_reset_path) + if is_instance_valid(layout_to_reset) and layout_to_reset is DockableLayout: + copy_from(layout_to_reset.clone()) + + func get_names() -> PackedStringArray: return _root.get_names() diff --git a/assets/layouts/Default.tres b/assets/layouts/Default.tres index 119610248..e858f0d5e 100644 --- a/assets/layouts/Default.tres +++ b/assets/layouts/Default.tres @@ -192,3 +192,4 @@ hidden_tabs = { } windows = {} save_on_change = false +layout_reset_path = "" diff --git a/assets/layouts/Tallscreen.tres b/assets/layouts/Tallscreen.tres index b1d96489b..bb674f15a 100644 --- a/assets/layouts/Tallscreen.tres +++ b/assets/layouts/Tallscreen.tres @@ -162,3 +162,4 @@ hidden_tabs = { } windows = {} save_on_change = false +layout_reset_path = "" diff --git a/src/Main.gd b/src/Main.gd index 1a2b083f1..3dc33ed3d 100644 --- a/src/Main.gd +++ b/src/Main.gd @@ -236,11 +236,18 @@ func _handle_layout_files() -> void: if files.size() == 0: for layout in Global.default_layouts: var file_name := layout.resource_path.get_basename().get_file() + ".tres" - ResourceSaver.save(layout, Global.LAYOUT_DIR.path_join(file_name)) + var new_layout := layout.clone() + new_layout.layout_reset_path = layout.resource_path + ResourceSaver.save(new_layout, Global.LAYOUT_DIR.path_join(file_name)) files = dir.get_files() for file in files: var layout := ResourceLoader.load(Global.LAYOUT_DIR.path_join(file)) if layout is DockableLayout: + if layout.layout_reset_path.is_empty(): + if file == "Default.tres": + layout.layout_reset_path = Global.default_layouts[0].resource_path + elif file == "Tallscreen.tres": + layout.layout_reset_path = Global.default_layouts[1].resource_path Global.layouts.append(layout) # Save the layout every time it changes layout.save_on_change = true diff --git a/src/UI/Dialogs/ManageLayouts.tscn b/src/UI/Dialogs/ManageLayouts.tscn index 55872c4d2..ed0b0680e 100644 --- a/src/UI/Dialogs/ManageLayouts.tscn +++ b/src/UI/Dialogs/ManageLayouts.tscn @@ -18,6 +18,7 @@ root = SubResource("1") hidden_tabs = {} windows = {} save_on_change = false +layout_reset_path = "" [node name="ManageLayouts" type="AcceptDialog"] title = "Manage Layouts" diff --git a/src/UI/TopMenuContainer/TopMenuContainer.gd b/src/UI/TopMenuContainer/TopMenuContainer.gd index a969ab26b..219026037 100644 --- a/src/UI/TopMenuContainer/TopMenuContainer.gd +++ b/src/UI/TopMenuContainer/TopMenuContainer.gd @@ -398,13 +398,12 @@ func _setup_panels_submenu(item: String) -> void: func _setup_layouts_submenu(item: String) -> void: - layouts_submenu.set_name("layouts_submenu") layouts_submenu.hide_on_checkable_item_selection = false populate_layouts_submenu() layouts_submenu.id_pressed.connect(_layouts_submenu_id_pressed) window_menu.add_child(layouts_submenu) - window_menu.add_submenu_item(item, layouts_submenu.get_name()) + window_menu.add_submenu_node_item(item, layouts_submenu) var saved_layout: int = Global.config_cache.get_value("window", "layout", 0) set_layout(saved_layout) @@ -412,10 +411,12 @@ func _setup_layouts_submenu(item: String) -> void: func populate_layouts_submenu() -> void: layouts_submenu.clear() # Does not do anything if it's called for the first time - layouts_submenu.add_item("Manage Layouts", 0) for layout in Global.layouts: var layout_name := layout.resource_path.get_basename().get_file() layouts_submenu.add_radio_check_item(layout_name) + layouts_submenu.add_separator() + layouts_submenu.add_item("Manage Layouts") + layouts_submenu.add_item("Reset Default") func _setup_image_menu() -> void: @@ -847,10 +848,13 @@ func _panels_submenu_id_pressed(id: int) -> void: func _layouts_submenu_id_pressed(id: int) -> void: - if id == 0: + var layout_count := Global.layouts.size() + if id < layout_count: + set_layout(id) + elif id == layout_count + 1: manage_layouts_dialog.popup() - else: - set_layout(id - 1) + elif id == layout_count + 2: + Global.layouts[selected_layout].reset() func set_layout(id: int) -> void: @@ -859,10 +863,15 @@ func set_layout(id: int) -> void: if id >= Global.layouts.size(): id = 0 selected_layout = id - main_ui.layout = Global.layouts[id] + var layout := Global.layouts[id] + main_ui.layout = layout + var layout_name := layout.resource_path.get_basename().get_file() + layouts_submenu.set_item_text(layouts_submenu.item_count - 1, tr("Reset %s") % layout_name) + layouts_submenu.set_item_disabled( + layouts_submenu.item_count - 1, layout.layout_reset_path.is_empty() + ) for i in Global.layouts.size(): - var offset := i + 1 - layouts_submenu.set_item_checked(offset, offset == (id + 1)) + layouts_submenu.set_item_checked(i, i == id) for i in ui_elements.size(): var index := panels_submenu.get_item_index(i)