Browse Source

Merge pull request #12359 from kubecz3k/spatial-lock

ability to lock spatial nodes transform in editor
Rémi Verschelde 7 years ago
parent
commit
d1831915bf

+ 1 - 1
editor/editor_data.cpp

@@ -913,8 +913,8 @@ void EditorSelection::update() {
 
 	if (!changed)
 		return;
-	emit_signal("selection_changed");
 	changed = false;
+	emit_signal("selection_changed");
 }
 
 List<Node *> &EditorSelection::get_selected_node_list() {

+ 93 - 1
editor/plugins/spatial_editor_plugin.cpp

@@ -1097,7 +1097,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
 
 						if (get_selected_count() == 0)
 							break; //bye
-						//handle rotate
+						//handle scale
 						_edit.mode = TRANSFORM_SCALE;
 						_compute_edit(b->get_position());
 						break;
@@ -1385,6 +1385,10 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
 								continue;
 							}
 
+							if (sp->has_meta("_edit_lock_")) {
+								continue;
+							}
+
 							Transform original = se->original;
 							Transform original_local = se->original_local;
 							Transform base = Transform(Basis(), _edit.center);
@@ -1509,6 +1513,10 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
 								continue;
 							}
 
+							if (sp->has_meta("_edit_lock_")) {
+								continue;
+							}
+
 							Transform original = se->original;
 							Transform t;
 
@@ -1605,6 +1613,10 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
 							if (!se)
 								continue;
 
+							if (sp->has_meta("_edit_lock_")) {
+								continue;
+							}
+
 							Transform t;
 
 							if (local_coords) {
@@ -4094,6 +4106,44 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
 
 			settings_dialog->popup_centered(settings_vbc->get_combined_minimum_size() + Size2(50, 50));
 		} break;
+		case MENU_LOCK_SELECTED: {
+
+			List<Node *> &selection = editor_selection->get_selected_node_list();
+
+			for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+
+				Spatial *spatial = Object::cast_to<Spatial>(E->get());
+				if (!spatial || !spatial->is_visible_in_tree())
+					continue;
+
+				if (spatial->get_viewport() != EditorNode::get_singleton()->get_scene_root())
+					continue;
+
+				spatial->set_meta("_edit_lock_", true);
+				emit_signal("item_lock_status_changed");
+			}
+
+			_refresh_menu_icons();
+		} break;
+		case MENU_UNLOCK_SELECTED: {
+
+			List<Node *> &selection = editor_selection->get_selected_node_list();
+
+			for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+
+				Spatial *spatial = Object::cast_to<Spatial>(E->get());
+				if (!spatial || !spatial->is_visible_in_tree())
+					continue;
+
+				if (spatial->get_viewport() != EditorNode::get_singleton()->get_scene_root())
+					continue;
+
+				spatial->set_meta("_edit_lock_", Variant());
+				emit_signal("item_lock_status_changed");
+			}
+
+			_refresh_menu_icons();
+		} break;
 	}
 }
 
@@ -4477,6 +4527,28 @@ bool SpatialEditor::is_any_freelook_active() const {
 	return false;
 }
 
+void SpatialEditor::_refresh_menu_icons() {
+
+	bool all_locked = true;
+
+	List<Node *> &selection = editor_selection->get_selected_node_list();
+
+	if (selection.empty()) {
+		all_locked = false;
+	} else {
+		for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+			if (Object::cast_to<Spatial>(E->get()) && !Object::cast_to<Spatial>(E->get())->has_meta("_edit_lock_")) {
+				all_locked = false;
+				break;
+			}
+		}
+	}
+
+	tool_button[TOOL_LOCK_SELECTED]->set_visible(!all_locked);
+	tool_button[TOOL_LOCK_SELECTED]->set_disabled(selection.empty());
+	tool_button[TOOL_UNLOCK_SELECTED]->set_visible(all_locked);
+}
+
 void SpatialEditor::_unhandled_key_input(Ref<InputEvent> p_event) {
 
 	if (!is_visible_in_tree() || get_viewport()->gui_has_modal_stack())
@@ -4515,6 +4587,8 @@ void SpatialEditor::_notification(int p_what) {
 		tool_button[SpatialEditor::TOOL_MODE_ROTATE]->set_icon(get_icon("ToolRotate", "EditorIcons"));
 		tool_button[SpatialEditor::TOOL_MODE_SCALE]->set_icon(get_icon("ToolScale", "EditorIcons"));
 		tool_button[SpatialEditor::TOOL_MODE_LIST_SELECT]->set_icon(get_icon("ListSelect", "EditorIcons"));
+		tool_button[SpatialEditor::TOOL_LOCK_SELECTED]->set_icon(get_icon("Lock", "EditorIcons"));
+		tool_button[SpatialEditor::TOOL_UNLOCK_SELECTED]->set_icon(get_icon("Unlock", "EditorIcons"));
 
 		view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), get_icon("Panels1", "EditorIcons"));
 		view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), get_icon("Panels2", "EditorIcons"));
@@ -4525,7 +4599,11 @@ void SpatialEditor::_notification(int p_what) {
 
 		_menu_item_pressed(MENU_VIEW_USE_1_VIEWPORT);
 
+		_refresh_menu_icons();
+
 		get_tree()->connect("node_removed", this, "_node_removed");
+		EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor()->connect("node_changed", this, "_refresh_menu_icons");
+		editor_selection->connect("selection_changed", this, "_refresh_menu_icons");
 	}
 
 	if (p_what == NOTIFICATION_ENTER_TREE) {
@@ -4668,8 +4746,10 @@ void SpatialEditor::_bind_methods() {
 	ClassDB::bind_method("_get_editor_data", &SpatialEditor::_get_editor_data);
 	ClassDB::bind_method("_request_gizmo", &SpatialEditor::_request_gizmo);
 	ClassDB::bind_method("_toggle_maximize_view", &SpatialEditor::_toggle_maximize_view);
+	ClassDB::bind_method("_refresh_menu_icons", &SpatialEditor::_refresh_menu_icons);
 
 	ADD_SIGNAL(MethodInfo("transform_key_request"));
+	ADD_SIGNAL(MethodInfo("item_lock_status_changed"));
 }
 
 void SpatialEditor::clear() {
@@ -4771,6 +4851,18 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
 	tool_button[TOOL_MODE_LIST_SELECT]->connect("pressed", this, "_menu_item_pressed", button_binds);
 	tool_button[TOOL_MODE_LIST_SELECT]->set_tooltip(TTR("Show a list of all objects at the position clicked\n(same as Alt+RMB in select mode)."));
 
+	tool_button[TOOL_LOCK_SELECTED] = memnew(ToolButton);
+	hbc_menu->add_child(tool_button[TOOL_LOCK_SELECTED]);
+	button_binds[0] = MENU_LOCK_SELECTED;
+	tool_button[TOOL_LOCK_SELECTED]->connect("pressed", this, "_menu_item_pressed", button_binds);
+	tool_button[TOOL_LOCK_SELECTED]->set_tooltip(TTR("Lock the selected object in place (can't be moved)."));
+
+	tool_button[TOOL_UNLOCK_SELECTED] = memnew(ToolButton);
+	hbc_menu->add_child(tool_button[TOOL_UNLOCK_SELECTED]);
+	button_binds[0] = MENU_UNLOCK_SELECTED;
+	tool_button[TOOL_UNLOCK_SELECTED]->connect("pressed", this, "_menu_item_pressed", button_binds);
+	tool_button[TOOL_UNLOCK_SELECTED]->set_tooltip(TTR("Unlock the selected object (can be moved)."));
+
 	vs = memnew(VSeparator);
 	hbc_menu->add_child(vs);
 

+ 9 - 1
editor/plugins/spatial_editor_plugin.h

@@ -391,6 +391,8 @@ public:
 		TOOL_MODE_ROTATE,
 		TOOL_MODE_SCALE,
 		TOOL_MODE_LIST_SELECT,
+		TOOL_LOCK_SELECTED,
+		TOOL_UNLOCK_SELECTED,
 		TOOL_MAX
 
 	};
@@ -479,7 +481,8 @@ private:
 		MENU_VIEW_ORIGIN,
 		MENU_VIEW_GRID,
 		MENU_VIEW_CAMERA_SETTINGS,
-
+		MENU_LOCK_SELECTED,
+		MENU_UNLOCK_SELECTED
 	};
 
 	Button *tool_button[TOOL_MAX];
@@ -487,6 +490,9 @@ private:
 	MenuButton *transform_menu;
 	MenuButton *view_menu;
 
+	ToolButton *lock_button;
+	ToolButton *unlock_button;
+
 	AcceptDialog *accept;
 
 	ConfirmationDialog *snap_dialog;
@@ -543,6 +549,8 @@ private:
 
 	bool is_any_freelook_active() const;
 
+	void _refresh_menu_icons();
+
 protected:
 	void _notification(int p_what);
 	//void _gui_input(InputEvent p_event);

+ 4 - 0
editor/scene_tree_dock.cpp

@@ -745,6 +745,10 @@ void SceneTreeDock::_notification(int p_what) {
 				canvas_item_plugin->get_canvas_item_editor()->connect("item_group_status_changed", scene_tree, "_update_tree");
 				scene_tree->connect("node_changed", canvas_item_plugin->get_canvas_item_editor()->get_viewport_control(), "update");
 			}
+
+			SpatialEditorPlugin *spatial_editor_plugin = Object::cast_to<SpatialEditorPlugin>(editor_data->get_editor("3D"));
+			spatial_editor_plugin->get_spatial_editor()->connect("item_lock_status_changed", scene_tree, "_update_tree");
+
 			button_add->set_icon(get_icon("Add", "EditorIcons"));
 			button_instance->set_icon(get_icon("Instance", "EditorIcons"));
 			button_create_script->set_icon(get_icon("ScriptCreate", "EditorIcons"));

+ 5 - 1
editor/scene_tree_editor.cpp

@@ -88,7 +88,7 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i
 
 	} else if (p_id == BUTTON_LOCK) {
 
-		if (n->is_class("CanvasItem")) {
+		if (n->is_class("CanvasItem") || n->is_class("Spatial")) {
 			n->set_meta("_edit_lock_", Variant());
 			_update_tree();
 			emit_signal("node_changed");
@@ -266,6 +266,10 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
 			_update_visibility_color(p_node, item);
 		} else if (p_node->is_class("Spatial")) {
 
+			bool is_locked = p_node->has_meta("_edit_lock_");
+			if (is_locked)
+				item->add_button(0, get_icon("Lock", "EditorIcons"), BUTTON_LOCK, false, TTR("Node is locked.\nClick to unlock"));
+
 			bool v = p_node->call("is_visible");
 			if (v)
 				item->add_button(0, get_icon("Visible", "EditorIcons"), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));