diff --git a/addons/block_code/block_code_plugin.gd b/addons/block_code/block_code_plugin.gd index dc0c17d0..7e27b7df 100644 --- a/addons/block_code/block_code_plugin.gd +++ b/addons/block_code/block_code_plugin.gd @@ -96,13 +96,19 @@ func _exit_tree(): func _ready(): + connect("scene_changed", _on_scene_changed) editor_inspector.connect("edited_object_changed", _on_editor_inspector_edited_object_changed) + _on_scene_changed(EditorInterface.get_edited_scene_root()) + _on_editor_inspector_edited_object_changed() + + +func _on_scene_changed(scene_root: Node): + BlockCodePlugin.main_panel.switch_scene(scene_root) func _on_editor_inspector_edited_object_changed(): var block_code: BlockCode = editor_inspector.get_edited_object() as BlockCode - if block_code: - BlockCodePlugin.main_panel.switch_script(block_code) + BlockCodePlugin.main_panel.switch_script(block_code) func _has_main_screen(): diff --git a/addons/block_code/ui/block_canvas/block_canvas.gd b/addons/block_code/ui/block_canvas/block_canvas.gd index da872a39..c37667cc 100644 --- a/addons/block_code/ui/block_canvas/block_canvas.gd +++ b/addons/block_code/ui/block_canvas/block_canvas.gd @@ -6,6 +6,8 @@ const EXTEND_MARGIN: float = 800 @onready var _window: Control = %Window @onready var _window_scroll: ScrollContainer = %WindowScroll +@onready var _choose_block_code_label: Label = %ChooseBlockCodeLabel +@onready var _create_block_code_label: Label = %CreateBlockCodeLabel var _block_scenes_by_class = {} @@ -41,10 +43,27 @@ func set_child(n: Node): func bsd_selected(bsd: BlockScriptData): clear_canvas() + _choose_block_code_label.visible = false + _create_block_code_label.visible = false + + if not bsd and scene_has_bsd_nodes(): + _choose_block_code_label.visible = true + return + elif not bsd and not scene_has_bsd_nodes(): + _create_block_code_label.visible = true + return + for tree in bsd.block_trees.array: load_tree(_window, tree) +func scene_has_bsd_nodes() -> bool: + var scene_root = EditorInterface.get_edited_scene_root() + if not scene_root: + return false + return scene_root.find_children("*", "BlockCode").size() > 0 + + func clear_canvas(): for child in _window.get_children(): child.queue_free() diff --git a/addons/block_code/ui/block_canvas/block_canvas.tscn b/addons/block_code/ui/block_canvas/block_canvas.tscn index f6c009fe..29a9a9d7 100644 --- a/addons/block_code/ui/block_canvas/block_canvas.tscn +++ b/addons/block_code/ui/block_canvas/block_canvas.tscn @@ -24,3 +24,17 @@ unique_name_in_owner = true layout_mode = 2 size_flags_horizontal = 3 mouse_filter = 1 + +[node name="ChooseBlockCodeLabel" type="Label" parent="."] +unique_name_in_owner = true +visible = false +layout_mode = 2 +text = "Choose a BlockCode node in the inspector." +horizontal_alignment = 1 + +[node name="CreateBlockCodeLabel" type="Label" parent="."] +unique_name_in_owner = true +visible = false +layout_mode = 2 +text = "First, add a BlockCode node to the scene." +horizontal_alignment = 1 diff --git a/addons/block_code/ui/main_panel.gd b/addons/block_code/ui/main_panel.gd index 79aad6df..26f371d1 100644 --- a/addons/block_code/ui/main_panel.gd +++ b/addons/block_code/ui/main_panel.gd @@ -8,10 +8,13 @@ var eia: EditorInterfaceAccess @onready var _block_canvas: BlockCanvas = %NodeBlockCanvas @onready var _drag_manager: DragManager = %DragManager @onready var _title_bar: TitleBar = %TitleBar +@onready var _editor_inspector: EditorInspector = EditorInterface.get_inspector() var block_code_tab: Button var _current_bsd: BlockScriptData var _current_block_code_node: BlockCode +var _scene_root: Node +var _block_code_nodes: Array var undo_redo: EditorUndoRedoManager @@ -32,17 +35,18 @@ func _on_button_pressed(): _print_generated_script() +func switch_scene(scene_root: Node): + _title_bar.scene_selected(scene_root) + + func switch_script(block_code_node: BlockCode): - var bsd = block_code_node.bsd - if bsd: - _current_bsd = bsd - _current_block_code_node = block_code_node - _picker.bsd_selected(bsd) - _title_bar.bsd_selected(bsd) - _block_canvas.bsd_selected(bsd) - block_code_tab.pressed.emit() - else: - print("No block script attached.") + var bsd = block_code_node.bsd if block_code_node else null + _current_bsd = bsd + _current_block_code_node = block_code_node + _picker.bsd_selected(bsd) + _title_bar.bsd_selected(bsd) + _block_canvas.bsd_selected(bsd) + block_code_tab.pressed.emit() func save_script(): diff --git a/addons/block_code/ui/picker/picker.gd b/addons/block_code/ui/picker/picker.gd index 02c32268..4e79f2f5 100644 --- a/addons/block_code/ui/picker/picker.gd +++ b/addons/block_code/ui/picker/picker.gd @@ -8,6 +8,10 @@ signal block_picked(block: Block) func bsd_selected(bsd: BlockScriptData): + if not bsd: + reset_picker() + return + for class_dict in ProjectSettings.get_global_class_list(): if class_dict.class == bsd.script_inherits: var script = load(class_dict.path) @@ -19,10 +23,14 @@ func bsd_selected(bsd: BlockScriptData): init_picker(CategoryFactory.get_inherited_categories(bsd.script_inherits)) -func init_picker(extra_blocks: Array[BlockCategory] = []): +func reset_picker(): for c in _block_list.get_children(): c.queue_free() + +func init_picker(extra_blocks: Array[BlockCategory] = []): + reset_picker() + var block_categories := CategoryFactory.get_general_categories() if extra_blocks.size() > 0: diff --git a/addons/block_code/ui/title_bar/title_bar.gd b/addons/block_code/ui/title_bar/title_bar.gd index 6bf7d9e1..33c1a066 100644 --- a/addons/block_code/ui/title_bar/title_bar.gd +++ b/addons/block_code/ui/title_bar/title_bar.gd @@ -4,19 +4,65 @@ extends MarginContainer signal node_name_changed(node_name: String) -@onready var _node_name := %NodeName -@onready var _class_name := %ClassName +@onready var _block_code_icon = load("res://addons/block_code/block_code_node/block_code_node.svg") as Texture2D +@onready var _editor_inspector: EditorInspector = EditorInterface.get_inspector() +@onready var _editor_selection: EditorSelection = EditorInterface.get_selection() +@onready var _node_option_button: OptionButton = %NodeOptionButton + + +func _ready(): + _node_option_button.connect("item_selected", _on_node_option_button_item_selected) + + +func scene_selected(scene_root: Node): + _update_node_option_button_options() + var current_block_code = _editor_inspector.get_edited_object() as BlockCode + if not current_block_code: + bsd_selected(null) func bsd_selected(bsd: BlockScriptData): - _class_name.text = bsd.script_inherits + # TODO: We should listen for property changes in all BlockCode nodes and + # their parents. As a workaround for the UI displaying stale data, + # we'll crudely update the list of BlockCode nodes whenever the + # selection changes. + + _update_node_option_button_options() + + var select_index = _get_index_for_bsd(bsd) + if _node_option_button.selected != select_index: + _node_option_button.select(select_index) + + +func _update_node_option_button_options(): + _node_option_button.clear() + + var scene_root = EditorInterface.get_edited_scene_root() + + if not scene_root: + return + + for block_code_node in scene_root.find_children("*", "BlockCode"): + 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.bsd.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) -#func node_selected(node_data: NodeData): -#_node_name.text = node_data.node_name -#_class_name.text = node_data.node_class_name +func _get_index_for_bsd(bsd: BlockScriptData) -> int: + for index in range(_node_option_button.item_count): + var block_code_node = _node_option_button.get_item_metadata(index) + if block_code_node.bsd == bsd: + return index + return -1 -func _on_node_name_text_changed(new_text: String): - #node_name_changed.emit(new_text) - pass +func _on_node_option_button_item_selected(index): + var block_code_node = _node_option_button.get_item_metadata(index) as BlockCode + # FIXME: We should clear the existing selection, but at the moment this + # causes the new node to be deselected due to signal handlers being + # called in the wrong order. + #_editor_selection.clear() + if block_code_node: + EditorInterface.edit_node(block_code_node) diff --git a/addons/block_code/ui/title_bar/title_bar.tscn b/addons/block_code/ui/title_bar/title_bar.tscn index 47a0ed41..9b10be36 100644 --- a/addons/block_code/ui/title_bar/title_bar.tscn +++ b/addons/block_code/ui/title_bar/title_bar.tscn @@ -14,15 +14,7 @@ layout_mode = 2 [node name="HBoxContainer" type="HBoxContainer" parent="."] layout_mode = 2 -[node name="NodeName" type="LineEdit" parent="HBoxContainer"] +[node name="NodeOptionButton" type="OptionButton" parent="HBoxContainer"] unique_name_in_owner = true -custom_minimum_size = Vector2(400, 0) layout_mode = 2 -editable = false - -[node name="ClassName" type="Label" parent="HBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -theme_override_colors/font_color = Color(0.501407, 0.501406, 0.501406, 1) - -[connection signal="text_changed" from="HBoxContainer/NodeName" to="." method="_on_node_name_text_changed"] +size_flags_horizontal = 3