From 43dd08b5d2abf8d33eba83177c6447684c05407e Mon Sep 17 00:00:00 2001 From: Dylan McCall Date: Tue, 9 Jul 2024 13:54:37 -0700 Subject: [PATCH 1/4] Update selection in undo actions When adding a BlockCode node, select the new node as part of the undo / redo action. This is consistent with the behaviour of other actions in Godot. https://phabricator.endlessm.com/T35541 --- addons/block_code/ui/main_panel.gd | 37 ++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/addons/block_code/ui/main_panel.gd b/addons/block_code/ui/main_panel.gd index d00f3db9..e05a1a8d 100644 --- a/addons/block_code/ui/main_panel.gd +++ b/addons/block_code/ui/main_panel.gd @@ -19,7 +19,13 @@ var _current_block_code_node: BlockCode var _block_code_nodes: Array var _collapsed: bool = false -var undo_redo: EditorUndoRedoManager +var undo_redo: EditorUndoRedoManager: + set(value): + if undo_redo: + undo_redo.version_changed.disconnect(_on_undo_redo_version_changed) + undo_redo = value + if undo_redo: + undo_redo.version_changed.connect(_on_undo_redo_version_changed) func _ready(): @@ -28,12 +34,10 @@ func _ready(): _drag_manager.block_dropped.connect(save_script) _drag_manager.block_modified.connect(save_script) - # Setup block scripting environment - undo_redo.version_changed.connect(_on_undo_redo_version_changed) - if not _delete_node_button.icon: _delete_node_button.icon = _icon_delete - _collapse_button.icon = _icon_collapse + if not _collapse_button.icon: + _collapse_button.icon = _icon_collapse func _on_undo_redo_version_changed(): @@ -188,15 +192,13 @@ func _on_node_block_canvas_add_block_code(): undo_redo.add_do_method(edited_node, "add_child", block_code, true) undo_redo.add_do_property(block_code, "owner", scene_root) + undo_redo.add_do_method(self, "_select_block_code_node", edited_node) undo_redo.add_do_reference(block_code) undo_redo.add_undo_method(edited_node, "remove_child", block_code) undo_redo.add_undo_property(block_code, "owner", null) undo_redo.commit_action() - EditorInterface.get_selection().clear() - EditorInterface.get_selection().add_node(block_code) - func _on_node_block_canvas_open_scene(): var edited_node: Node = EditorInterface.get_inspector().get_edited_object() as Node @@ -213,12 +215,27 @@ func _on_node_block_canvas_replace_block_code(): undo_redo.create_action("Replace block code %s" % edited_node.name, UndoRedo.MERGE_DISABLE, scene_root) + # FIXME: When this is undone, the new state is not correctly shown in the + # editor due to an issue in Godot: + # + # Ideally this should fix itself in a future version of Godot. + undo_redo.add_do_method(scene_root, "set_editable_instance", edited_node, true) + undo_redo.add_do_method(self, "_select_block_code_node", edited_node) undo_redo.add_undo_method(scene_root, "set_editable_instance", edited_node, false) undo_redo.commit_action() + +func _select_block_code_node(edited_node: Node): var block_code_nodes = BlockCodePlugin.list_block_code_for_node(edited_node) -# + if block_code_nodes.size() > 0: + _set_selection([block_code_nodes.pop_front()]) + else: + _set_selection([edited_node]) + + +func _set_selection(nodes: Array[Node]): EditorInterface.get_selection().clear() - EditorInterface.get_selection().add_node(block_code_nodes.pop_front() if block_code_nodes.size() > 0 else edited_node) + for node in nodes: + EditorInterface.get_selection().add_node(node) From 88100d544c403b9364d5dbef96b7d78e8d527f28 Mon Sep 17 00:00:00 2001 From: Dylan McCall Date: Tue, 9 Jul 2024 14:20:48 -0700 Subject: [PATCH 2/4] Watch for changes to the selected BlockCode node https://phabricator.endlessm.com/T35541 --- addons/block_code/block_code_plugin.gd | 44 +++++++++++++++------ addons/block_code/ui/main_panel.gd | 2 +- addons/block_code/ui/title_bar/title_bar.gd | 8 ++-- 3 files changed, 36 insertions(+), 18 deletions(-) diff --git a/addons/block_code/block_code_plugin.gd b/addons/block_code/block_code_plugin.gd index 99273f21..2194db78 100644 --- a/addons/block_code/block_code_plugin.gd +++ b/addons/block_code/block_code_plugin.gd @@ -9,7 +9,7 @@ static var block_code_button: Button var editor_inspector: EditorInspector var editor_selection: EditorSelection -var selected_block_code_node: BlockCode +var _selected_block_code: BlockCode var old_feature_profile: String = "" @@ -97,14 +97,12 @@ func _exit_tree(): func _ready(): connect("scene_changed", _on_scene_changed) editor_inspector.connect("edited_object_changed", _on_editor_inspector_edited_object_changed) - editor_inspector.connect("property_edited", _on_editor_inspector_property_edited) _on_scene_changed(EditorInterface.get_edited_scene_root()) _on_editor_inspector_edited_object_changed() func _on_scene_changed(scene_root: Node): main_panel.switch_scene(scene_root) - _on_editor_inspector_edited_object_changed() func _on_editor_inspector_edited_object_changed(): @@ -131,14 +129,29 @@ func _on_editor_inspector_edited_object_changed(): # when we select the parent of a BlockCode node. edited_object = selected_nodes.filter(func(node): return node is BlockCode).pop_front() - # We will edit either the selected node (if it is a BlockCode node) or - # the first BlockCode child of that node. Keep track of the block code node - # being edited so we know to monitor for changes from EditorInspector. - selected_block_code_node = list_block_code_for_node(edited_object as Node).pop_front() - if not is_block_code_editable(selected_block_code_node): - selected_block_code_node = null + var block_code_node = list_block_code_nodes_for_node(edited_object as Node).pop_front() + select_block_code_node(block_code_node) + + +func select_block_code_node(block_code: BlockCode): + if not is_block_code_editable(block_code): + block_code = null + + if _selected_block_code: + _selected_block_code.tree_entered.disconnect(_on_selected_block_code_changed) + _selected_block_code.tree_exited.disconnect(_on_selected_block_code_changed) + _selected_block_code.property_list_changed.disconnect(_on_selected_block_code_changed) + editor_inspector.property_edited.disconnect(_on_editor_inspector_property_edited) + + _selected_block_code = block_code - main_panel.switch_block_code_node(selected_block_code_node) + if _selected_block_code: + _selected_block_code.tree_entered.connect(_on_selected_block_code_changed) + _selected_block_code.tree_exited.connect(_on_selected_block_code_changed) + _selected_block_code.property_list_changed.connect(_on_selected_block_code_changed) + editor_inspector.property_edited.connect(_on_editor_inspector_property_edited) + + main_panel.switch_block_code_node(_selected_block_code) static func is_block_code_editable(block_code: BlockCode) -> bool: @@ -154,10 +167,10 @@ static func is_block_code_editable(block_code: BlockCode) -> bool: static func node_has_block_code(node: Node, recursive: bool = false) -> bool: - return list_block_code_for_node(node, recursive).size() > 0 + return list_block_code_nodes_for_node(node, recursive).size() > 0 -static func list_block_code_for_node(node: Node, recursive: bool = false) -> Array[BlockCode]: +static func list_block_code_nodes_for_node(node: Node, recursive: bool = false) -> Array[BlockCode]: var result: Array[BlockCode] = [] if node is BlockCode: @@ -168,8 +181,13 @@ static func list_block_code_for_node(node: Node, recursive: bool = false) -> Arr return result +func _on_selected_block_code_changed(): + if _selected_block_code: + _on_editor_inspector_edited_object_changed() + + func _on_editor_inspector_property_edited(property: String): - if selected_block_code_node: + if _selected_block_code: _on_editor_inspector_edited_object_changed() diff --git a/addons/block_code/ui/main_panel.gd b/addons/block_code/ui/main_panel.gd index e05a1a8d..b57ab2c7 100644 --- a/addons/block_code/ui/main_panel.gd +++ b/addons/block_code/ui/main_panel.gd @@ -228,7 +228,7 @@ func _on_node_block_canvas_replace_block_code(): func _select_block_code_node(edited_node: Node): - var block_code_nodes = BlockCodePlugin.list_block_code_for_node(edited_node) + var block_code_nodes = BlockCodePlugin.list_block_code_nodes_for_node(edited_node) if block_code_nodes.size() > 0: _set_selection([block_code_nodes.pop_front()]) else: diff --git a/addons/block_code/ui/title_bar/title_bar.gd b/addons/block_code/ui/title_bar/title_bar.gd index c5809fa9..79531122 100644 --- a/addons/block_code/ui/title_bar/title_bar.gd +++ b/addons/block_code/ui/title_bar/title_bar.gd @@ -42,15 +42,15 @@ func _update_node_option_button_items(): if not scene_root: return - for block_code_node in BlockCodePlugin.list_block_code_for_node(scene_root, true): - if not BlockCodePlugin.is_block_code_editable(block_code_node): + for block_code in BlockCodePlugin.list_block_code_nodes_for_node(scene_root, true): + if not BlockCodePlugin.is_block_code_editable(block_code): continue var node_item_index = _node_option_button.item_count - var node_label = "{name} ({type})".format({"name": scene_root.get_path_to(block_code_node).get_concatenated_names(), "type": block_code_node.block_script.script_inherits}) + var node_label = "{name} ({type})".format({"name": scene_root.get_path_to(block_code).get_concatenated_names(), "type": block_code.block_script.script_inherits}) _node_option_button.add_item(node_label) _node_option_button.set_item_icon(node_item_index, _block_code_icon) - _node_option_button.set_item_metadata(node_item_index, block_code_node) + _node_option_button.set_item_metadata(node_item_index, block_code) func _get_index_for_bsd(bsd: BlockScriptData) -> int: From d4103f1037868146c03f7f3c5cf6b1622971d7da Mon Sep 17 00:00:00 2001 From: Dylan McCall Date: Tue, 9 Jul 2024 14:22:27 -0700 Subject: [PATCH 3/4] Do not expand selection if BlockCode is selected a second time https://phabricator.endlessm.com/T35541 --- addons/block_code/block_code_plugin.gd | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/addons/block_code/block_code_plugin.gd b/addons/block_code/block_code_plugin.gd index 2194db78..3a0b8ffa 100644 --- a/addons/block_code/block_code_plugin.gd +++ b/addons/block_code/block_code_plugin.gd @@ -110,7 +110,10 @@ func _on_editor_inspector_edited_object_changed(): #var edited_node = edited_object as Node var selected_nodes = editor_selection.get_selected_nodes() - if edited_object is BlockCode and selected_nodes.has(edited_object): + if edited_object is BlockCode: + make_bottom_panel_item_visible(main_panel) + + if edited_object is BlockCode and selected_nodes.size() == 1 and edited_object.owner and edited_object != _selected_block_code: # If a BlockCode node is being edited, and it was explicitly selected # (as opposed to edited in the Inspector alone), select its parent node # as well. This provides a clearer indication of what is being edited. @@ -118,8 +121,7 @@ func _on_editor_inspector_edited_object_changed(): # so we will return early to avoid duplicate work. var parent_node = edited_object.get_parent() if parent_node: - EditorInterface.get_selection().add_node.call_deferred(parent_node) - make_bottom_panel_item_visible(main_panel) + editor_selection.add_node.call_deferred(parent_node) return if edited_object and edited_object.get_class() == "MultiNodeEdit": From dbd764376d205a66ae339ba2c2d87e7dba39dfad Mon Sep 17 00:00:00 2001 From: Dylan McCall Date: Tue, 9 Jul 2024 15:02:29 -0700 Subject: [PATCH 4/4] Avoid duplicate work when BlockCode changes https://phabricator.endlessm.com/T35541 --- addons/block_code/block_code_plugin.gd | 27 ++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/addons/block_code/block_code_plugin.gd b/addons/block_code/block_code_plugin.gd index 3a0b8ffa..80991aa0 100644 --- a/addons/block_code/block_code_plugin.gd +++ b/addons/block_code/block_code_plugin.gd @@ -136,6 +136,9 @@ func _on_editor_inspector_edited_object_changed(): func select_block_code_node(block_code: BlockCode): + if block_code == _selected_block_code: + return + if not is_block_code_editable(block_code): block_code = null @@ -153,9 +156,23 @@ func select_block_code_node(block_code: BlockCode): _selected_block_code.property_list_changed.connect(_on_selected_block_code_changed) editor_inspector.property_edited.connect(_on_editor_inspector_property_edited) + _refresh_block_code_node() + + +func _refresh_block_code_node(): main_panel.switch_block_code_node(_selected_block_code) +func _on_selected_block_code_changed(): + if _selected_block_code: + _refresh_block_code_node() + + +func _on_editor_inspector_property_edited(property: String): + if _selected_block_code: + _refresh_block_code_node() + + static func is_block_code_editable(block_code: BlockCode) -> bool: if not block_code: return false @@ -183,16 +200,6 @@ static func list_block_code_nodes_for_node(node: Node, recursive: bool = false) return result -func _on_selected_block_code_changed(): - if _selected_block_code: - _on_editor_inspector_edited_object_changed() - - -func _on_editor_inspector_property_edited(property: String): - if _selected_block_code: - _on_editor_inspector_edited_object_changed() - - func _get_plugin_name(): return "Block Code"