diff --git a/addons/block_code/block_code_plugin.gd b/addons/block_code/block_code_plugin.gd index 99273f21..80991aa0 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(): @@ -112,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. @@ -120,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": @@ -131,14 +131,46 @@ 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 block_code == _selected_block_code: + return + + 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 + + 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_node) + _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: @@ -154,10 +186,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,11 +200,6 @@ static func list_block_code_for_node(node: Node, recursive: bool = false) -> Arr return result -func _on_editor_inspector_property_edited(property: String): - if selected_block_code_node: - _on_editor_inspector_edited_object_changed() - - func _get_plugin_name(): return "Block Code" diff --git a/addons/block_code/ui/main_panel.gd b/addons/block_code/ui/main_panel.gd index d00f3db9..b57ab2c7 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() - var block_code_nodes = BlockCodePlugin.list_block_code_for_node(edited_node) -# + +func _select_block_code_node(edited_node: 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: + _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) 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: