diff options
| -rw-r--r-- | editor/create_dialog.cpp | 1 | ||||
| -rw-r--r-- | editor/plugins/canvas_item_editor_plugin.cpp | 44 | ||||
| -rw-r--r-- | editor/plugins/canvas_item_editor_plugin.h | 10 | ||||
| -rw-r--r-- | editor/scene_tree_dock.cpp | 29 | ||||
| -rw-r--r-- | editor/scene_tree_dock.h | 4 | ||||
| -rw-r--r-- | scene/gui/control.cpp | 2 | 
6 files changed, 88 insertions, 2 deletions
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index a9ed1bc2b9..711072f4b2 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -170,6 +170,7 @@ void CreateDialog::_update_search() {  	root->set_text(0, base_type);  	root->set_icon(0, search_options->get_theme_icon(icon_fallback, "EditorIcons"));  	search_options_types[base_type] = root; +	_configure_search_option_item(root, base_type, ClassDB::class_exists(base_type));  	const String search_text = search_box->get_text();  	bool empty_search = search_text == ""; diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 28926d18c2..82ebf48242 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -1021,6 +1021,32 @@ void CanvasItemEditor::_selection_menu_hide() {  	selection_menu->set_size(Vector2(0, 0));  } +void CanvasItemEditor::_add_node_pressed(int p_result) { +	if (p_result == AddNodeOption::ADD_NODE) { +		editor->get_scene_tree_dock()->open_add_child_dialog(); +	} else if (p_result == AddNodeOption::ADD_INSTANCE) { +		editor->get_scene_tree_dock()->open_instance_child_dialog(); +	} +} + +void CanvasItemEditor::_node_created(Node *p_node) { +	if (node_create_position == Point2()) { +		return; +	} + +	CanvasItem *c = Object::cast_to<CanvasItem>(p_node); +	if (c) { +		Transform2D xform = c->get_global_transform_with_canvas().affine_inverse() * c->get_transform(); +		c->_edit_set_position(xform.xform(node_create_position)); +	} + +	call_deferred("_reset_create_position"); // Defer the call in case more than one node is added. +} + +void CanvasItemEditor::_reset_create_position() { +	node_create_position = Point2(); +} +  bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_event) {  	Ref<InputEventMouseButton> b = p_event;  	Ref<InputEventMouseMotion> m = p_event; @@ -2463,6 +2489,14 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {  			}  		} +		if (b.is_valid() && b->is_pressed() && b->get_button_index() == BUTTON_RIGHT && b->get_control()) { +			add_node_menu->set_position(get_global_transform().xform(get_local_mouse_position())); +			add_node_menu->set_size(Vector2(1, 1)); +			add_node_menu->popup(); +			node_create_position = transform.affine_inverse().xform((get_local_mouse_position())); +			return true; +		} +  		if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && b->is_pressed() && tool == TOOL_SELECT) {  			// Single item selection  			Point2 click = transform.affine_inverse().xform(b->get_position()); @@ -5364,6 +5398,7 @@ void CanvasItemEditor::_bind_methods() {  	ClassDB::bind_method("_unhandled_key_input", &CanvasItemEditor::_unhandled_key_input);  	ClassDB::bind_method("_queue_update_bone_list", &CanvasItemEditor::_update_bone_list);  	ClassDB::bind_method("_update_bone_list", &CanvasItemEditor::_update_bone_list); +	ClassDB::bind_method("_reset_create_position", &CanvasItemEditor::_reset_create_position);  	ClassDB::bind_method(D_METHOD("set_state"), &CanvasItemEditor::set_state);  	ClassDB::bind_method(D_METHOD("update_viewport"), &CanvasItemEditor::update_viewport); @@ -5685,6 +5720,9 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {  	editor_selection->connect("selection_changed", callable_mp((CanvasItem *)this, &CanvasItem::update));  	editor_selection->connect("selection_changed", callable_mp(this, &CanvasItemEditor::_selection_changed)); +	editor->get_scene_tree_dock()->connect("node_created", callable_mp(this, &CanvasItemEditor::_node_created)); +	editor->get_scene_tree_dock()->connect("add_node_used", callable_mp(this, &CanvasItemEditor::_reset_create_position)); +  	editor->call_deferred("connect", "play_pressed", Callable(this, "_update_override_camera_button"), make_binds(true));  	editor->call_deferred("connect", "stop_pressed", Callable(this, "_update_override_camera_button"), make_binds(false)); @@ -6106,6 +6144,12 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {  	selection_menu->connect("id_pressed", callable_mp(this, &CanvasItemEditor::_selection_result_pressed));  	selection_menu->connect("popup_hide", callable_mp(this, &CanvasItemEditor::_selection_menu_hide)); +	add_node_menu = memnew(PopupMenu); +	add_child(add_node_menu); +	add_node_menu->add_icon_item(editor->get_scene_tree_dock()->get_theme_icon("Add", "EditorIcons"), TTR("Add Node Here")); +	add_node_menu->add_icon_item(editor->get_scene_tree_dock()->get_theme_icon("Instance", "EditorIcons"), TTR("Instance Scene Here")); +	add_node_menu->connect("id_pressed", callable_mp(this, &CanvasItemEditor::_add_node_pressed)); +  	multiply_grid_step_shortcut = ED_SHORTCUT("canvas_item_editor/multiply_grid_step", TTR("Multiply grid step by 2"), KEY_KP_MULTIPLY);  	divide_grid_step_shortcut = ED_SHORTCUT("canvas_item_editor/divide_grid_step", TTR("Divide grid step by 2"), KEY_KP_DIVIDE);  	pan_view_shortcut = ED_SHORTCUT("canvas_item_editor/pan_view", TTR("Pan View"), KEY_SPACE); diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index 24149a57b0..62a9b1e162 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -79,6 +79,11 @@ public:  		TOOL_MAX  	}; +	enum AddNodeOption { +		ADD_NODE, +		ADD_INSTANCE, +	}; +  private:  	EditorNode *editor; @@ -284,6 +289,7 @@ private:  	bool ruler_tool_active;  	Point2 ruler_tool_origin; +	Point2 node_create_position;  	MenuOption last_option; @@ -376,6 +382,7 @@ private:  	Button *key_auto_insert_button;  	PopupMenu *selection_menu; +	PopupMenu *add_node_menu;  	Control *top_ruler;  	Control *left_ruler; @@ -436,6 +443,9 @@ private:  	void _snap_changed();  	void _selection_result_pressed(int);  	void _selection_menu_hide(); +	void _add_node_pressed(int p_result); +	void _node_created(Node *p_node); +	void _reset_create_position();  	UndoRedo *undo_redo;  	bool _build_bones_list(Node *p_node); diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 0975decefb..16a0576af4 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -219,6 +219,9 @@ void SceneTreeDock::_perform_instance_scenes(const Vector<String> &p_files, Node  	editor_data->get_undo_redo().commit_action();  	editor->push_item(instances[instances.size() - 1]); +	for (int i = 0; i < instances.size(); i++) { +		emit_signal("node_created", instances[i]); +	}  }  void SceneTreeDock::_replace_with_branch_scene(const String &p_file, Node *base) { @@ -347,6 +350,11 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {  				break;  			} +			if (reset_create_dialog) { +				create_dialog->set_base_type("Node"); +				reset_create_dialog = false; +			} +  			// Prefer nodes that inherit from the current scene root.  			Node *current_edited_scene_root = EditorNode::get_singleton()->get_edited_scene();  			if (current_edited_scene_root) { @@ -367,6 +375,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {  			}  			create_dialog->popup_create(true); +			if (!p_confirm_override) { +				emit_signal("add_node_used"); +			}  		} break;  		case TOOL_INSTANCE: {  			if (!profile_allow_editing) { @@ -381,7 +392,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {  			quick_open->popup_dialog("PackedScene", true);  			quick_open->set_title(TTR("Instance Child Scene")); - +			if (!p_confirm_override) { +				emit_signal("add_node_used"); +			}  		} break;  		case TOOL_EXPAND_COLLAPSE: {  			if (!scene_tree->get_selected()) { @@ -2101,6 +2114,8 @@ void SceneTreeDock::_do_create(Node *p_parent) {  		}  		ct->set_size(ms);  	} + +	emit_signal("node_created", c);  }  void SceneTreeDock::_create() { @@ -2790,6 +2805,16 @@ void SceneTreeDock::open_script_dialog(Node *p_for_node, bool p_extend) {  	}  } +void SceneTreeDock::open_add_child_dialog() { +	create_dialog->set_base_type("CanvasItem"); +	_tool_selected(TOOL_NEW, true); +	reset_create_dialog = true; +} + +void SceneTreeDock::open_instance_child_dialog() { +	_tool_selected(TOOL_INSTANCE, true); +} +  void SceneTreeDock::add_remote_tree_editor(Control *p_remote) {  	ERR_FAIL_COND(remote_tree != nullptr);  	add_child(p_remote); @@ -2989,6 +3014,8 @@ void SceneTreeDock::_bind_methods() {  	ClassDB::bind_method(D_METHOD("replace_node"), &SceneTreeDock::replace_node);  	ADD_SIGNAL(MethodInfo("remote_tree_selected")); +	ADD_SIGNAL(MethodInfo("add_node_used")); +	ADD_SIGNAL(MethodInfo("node_created", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node")));  }  SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSelection *p_editor_selection, EditorData &p_editor_data) { diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index 807e922418..aa62c93cb5 100644 --- a/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h @@ -100,6 +100,7 @@ class SceneTreeDock : public VBoxContainer {  	Vector<ObjectID> subresources;  	bool restore_script_editor_on_drag; +	bool reset_create_dialog = false;  	int current_option;  	CreateDialog *create_dialog; @@ -274,6 +275,9 @@ public:  	void attach_script_to_selected(bool p_extend);  	void open_script_dialog(Node *p_for_node, bool p_extend); +	void open_add_child_dialog(); +	void open_instance_child_dialog(); +  	ScriptCreateDialog *get_script_create_dialog() { return script_create_dialog; }  	SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSelection *p_editor_selection, EditorData &p_editor_data); diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 0c104bf318..bff3024e38 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -93,7 +93,7 @@ void Control::_edit_set_state(const Dictionary &p_state) {  void Control::_edit_set_position(const Point2 &p_position) {  #ifdef TOOLS_ENABLED -	set_position(p_position, CanvasItemEditor::get_singleton()->is_anchors_mode_enabled()); +	set_position(p_position, CanvasItemEditor::get_singleton()->is_anchors_mode_enabled() && Object::cast_to<Control>(data.parent));  #else  	// Unlikely to happen. TODO: enclose all _edit_ functions into TOOLS_ENABLED  	set_position(p_position);  |