From 518d90791495359a26836c90c1d1ac101669e4ee Mon Sep 17 00:00:00 2001 From: Jakub Grzesik Date: Mon, 23 Oct 2017 21:21:15 +0200 Subject: [PATCH] ability to lock spatial nodes transform in editor --- editor/editor_data.cpp | 2 +- editor/plugins/spatial_editor_plugin.cpp | 94 +++++++++++++++++++++++- editor/plugins/spatial_editor_plugin.h | 10 ++- editor/scene_tree_dock.cpp | 4 + editor/scene_tree_editor.cpp | 6 +- 5 files changed, 112 insertions(+), 4 deletions(-) diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index 2cb5340b8bb..443004f820f 100644 --- a/editor/editor_data.cpp +++ b/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 &EditorSelection::get_selected_node_list() { diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index e8714cece6d..7d9958989e7 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -1065,7 +1065,7 @@ void SpatialEditorViewport::_sinput(const Ref &p_event) { if (get_selected_count() == 0) break; //bye - //handle rotate + //handle scale _edit.mode = TRANSFORM_SCALE; _compute_edit(b->get_position()); break; @@ -1327,6 +1327,10 @@ void SpatialEditorViewport::_sinput(const Ref &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); @@ -1452,6 +1456,10 @@ void SpatialEditorViewport::_sinput(const Ref &p_event) { continue; } + if (sp->has_meta("_edit_lock_")) { + continue; + } + Transform original = se->original; Transform t; @@ -1548,6 +1556,10 @@ void SpatialEditorViewport::_sinput(const Ref &p_event) { if (!se) continue; + if (sp->has_meta("_edit_lock_")) { + continue; + } + Transform t; if (local_coords) { @@ -3978,6 +3990,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 &selection = editor_selection->get_selected_node_list(); + + for (List::Element *E = selection.front(); E; E = E->next()) { + + Spatial *spatial = Object::cast_to(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 &selection = editor_selection->get_selected_node_list(); + + for (List::Element *E = selection.front(); E; E = E->next()) { + + Spatial *spatial = Object::cast_to(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; } } @@ -4317,6 +4367,28 @@ bool SpatialEditor::is_any_freelook_active() const { return false; } +void SpatialEditor::_refresh_menu_icons() { + + bool all_locked = true; + + List &selection = editor_selection->get_selected_node_list(); + + if (selection.empty()) { + all_locked = false; + } else { + for (List::Element *E = selection.front(); E; E = E->next()) { + if (Object::cast_to(E->get()) && !Object::cast_to(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 p_event) { if (!is_visible_in_tree() || get_viewport()->gui_has_modal_stack()) @@ -4355,6 +4427,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")); @@ -4365,7 +4439,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) { @@ -4508,8 +4586,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() { @@ -4611,6 +4691,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); diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h index c2b698068f7..64acced01ff 100644 --- a/editor/plugins/spatial_editor_plugin.h +++ b/editor/plugins/spatial_editor_plugin.h @@ -387,6 +387,8 @@ public: TOOL_MODE_ROTATE, TOOL_MODE_SCALE, TOOL_MODE_LIST_SELECT, + TOOL_LOCK_SELECTED, + TOOL_UNLOCK_SELECTED, TOOL_MAX }; @@ -475,7 +477,8 @@ private: MENU_VIEW_ORIGIN, MENU_VIEW_GRID, MENU_VIEW_CAMERA_SETTINGS, - + MENU_LOCK_SELECTED, + MENU_UNLOCK_SELECTED }; Button *tool_button[TOOL_MAX]; @@ -483,6 +486,9 @@ private: MenuButton *transform_menu; MenuButton *view_menu; + ToolButton *lock_button; + ToolButton *unlock_button; + AcceptDialog *accept; ConfirmationDialog *snap_dialog; @@ -539,6 +545,8 @@ private: bool is_any_freelook_active() const; + void _refresh_menu_icons(); + protected: void _notification(int p_what); //void _gui_input(InputEvent p_event); diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 58f70ce11e3..486556b2b73 100644 --- a/editor/scene_tree_dock.cpp +++ b/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(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")); diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index a6e0af05b2f..1bd0858fe83 100644 --- a/editor/scene_tree_editor.cpp +++ b/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"));