mirror of
https://github.com/godotengine/godot.git
synced 2025-04-25 01:48:08 +08:00
Merge pull request #28130 from JFonS/add_3d_grouping
Add grouping to 3D editor
This commit is contained in:
commit
db3dd67d47
@ -269,11 +269,21 @@ void SpatialEditorViewport::_select_clicked(bool p_append, bool p_single) {
|
|||||||
if (!clicked)
|
if (!clicked)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Spatial *sp = Object::cast_to<Spatial>(ObjectDB::get_instance(clicked));
|
Node *node = Object::cast_to<Node>(ObjectDB::get_instance(clicked));
|
||||||
if (!sp)
|
Spatial *selected = Object::cast_to<Spatial>(node);
|
||||||
|
if (!selected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_select(sp, clicked_wants_append, true);
|
// Replace the node by the group if grouped
|
||||||
|
while (node && node != editor->get_edited_scene()->get_parent()) {
|
||||||
|
Spatial *selected_tmp = Object::cast_to<Spatial>(node);
|
||||||
|
if (selected_tmp && node->has_meta("_edit_group_")) {
|
||||||
|
selected = selected_tmp;
|
||||||
|
}
|
||||||
|
node = node->get_parent();
|
||||||
|
}
|
||||||
|
|
||||||
|
_select(selected, clicked_wants_append, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpatialEditorViewport::_select(Node *p_node, bool p_append, bool p_single) {
|
void SpatialEditorViewport::_select(Node *p_node, bool p_append, bool p_single) {
|
||||||
@ -511,6 +521,19 @@ void SpatialEditorViewport::_select_region() {
|
|||||||
item = item->get_owner();
|
item = item->get_owner();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Replace the node by the group if grouped
|
||||||
|
if (item->is_class("Spatial")) {
|
||||||
|
Spatial *sel = Object::cast_to<Spatial>(item);
|
||||||
|
while (item && item != editor->get_edited_scene()->get_parent()) {
|
||||||
|
Spatial *selected_tmp = Object::cast_to<Spatial>(item);
|
||||||
|
if (selected_tmp && item->has_meta("_edit_group_")) {
|
||||||
|
sel = selected_tmp;
|
||||||
|
}
|
||||||
|
item = item->get_parent();
|
||||||
|
}
|
||||||
|
item = sel;
|
||||||
|
}
|
||||||
|
|
||||||
if (selected.find(item) != -1) continue;
|
if (selected.find(item) != -1) continue;
|
||||||
|
|
||||||
Ref<EditorSpatialGizmo> seg = sp->get_gizmo();
|
Ref<EditorSpatialGizmo> seg = sp->get_gizmo();
|
||||||
@ -4527,6 +4550,44 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
|
|||||||
emit_signal("item_lock_status_changed");
|
emit_signal("item_lock_status_changed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_refresh_menu_icons();
|
||||||
|
} break;
|
||||||
|
case MENU_GROUP_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_group_", true);
|
||||||
|
emit_signal("item_group_status_changed");
|
||||||
|
}
|
||||||
|
|
||||||
|
_refresh_menu_icons();
|
||||||
|
} break;
|
||||||
|
case MENU_UNGROUP_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_group_", Variant());
|
||||||
|
emit_signal("item_group_status_changed");
|
||||||
|
}
|
||||||
|
|
||||||
_refresh_menu_icons();
|
_refresh_menu_icons();
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
@ -4971,11 +5032,13 @@ bool SpatialEditor::is_any_freelook_active() const {
|
|||||||
void SpatialEditor::_refresh_menu_icons() {
|
void SpatialEditor::_refresh_menu_icons() {
|
||||||
|
|
||||||
bool all_locked = true;
|
bool all_locked = true;
|
||||||
|
bool all_grouped = true;
|
||||||
|
|
||||||
List<Node *> &selection = editor_selection->get_selected_node_list();
|
List<Node *> &selection = editor_selection->get_selected_node_list();
|
||||||
|
|
||||||
if (selection.empty()) {
|
if (selection.empty()) {
|
||||||
all_locked = false;
|
all_locked = false;
|
||||||
|
all_grouped = false;
|
||||||
} else {
|
} else {
|
||||||
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
|
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_")) {
|
if (Object::cast_to<Spatial>(E->get()) && !Object::cast_to<Spatial>(E->get())->has_meta("_edit_lock_")) {
|
||||||
@ -4983,11 +5046,21 @@ void SpatialEditor::_refresh_menu_icons() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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_group_")) {
|
||||||
|
all_grouped = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tool_button[TOOL_LOCK_SELECTED]->set_visible(!all_locked);
|
tool_button[TOOL_LOCK_SELECTED]->set_visible(!all_locked);
|
||||||
tool_button[TOOL_LOCK_SELECTED]->set_disabled(selection.empty());
|
tool_button[TOOL_LOCK_SELECTED]->set_disabled(selection.empty());
|
||||||
tool_button[TOOL_UNLOCK_SELECTED]->set_visible(all_locked);
|
tool_button[TOOL_UNLOCK_SELECTED]->set_visible(all_locked);
|
||||||
|
|
||||||
|
tool_button[TOOL_GROUP_SELECTED]->set_visible(!all_grouped);
|
||||||
|
tool_button[TOOL_GROUP_SELECTED]->set_disabled(selection.empty());
|
||||||
|
tool_button[TOOL_UNGROUP_SELECTED]->set_visible(all_grouped);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -5157,6 +5230,8 @@ void SpatialEditor::_notification(int p_what) {
|
|||||||
tool_button[SpatialEditor::TOOL_MODE_LIST_SELECT]->set_icon(get_icon("ListSelect", "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_LOCK_SELECTED]->set_icon(get_icon("Lock", "EditorIcons"));
|
||||||
tool_button[SpatialEditor::TOOL_UNLOCK_SELECTED]->set_icon(get_icon("Unlock", "EditorIcons"));
|
tool_button[SpatialEditor::TOOL_UNLOCK_SELECTED]->set_icon(get_icon("Unlock", "EditorIcons"));
|
||||||
|
tool_button[SpatialEditor::TOOL_GROUP_SELECTED]->set_icon(get_icon("Group", "EditorIcons"));
|
||||||
|
tool_button[SpatialEditor::TOOL_UNGROUP_SELECTED]->set_icon(get_icon("Ungroup", "EditorIcons"));
|
||||||
|
|
||||||
tool_option_button[SpatialEditor::TOOL_OPT_LOCAL_COORDS]->set_icon(get_icon("Object", "EditorIcons"));
|
tool_option_button[SpatialEditor::TOOL_OPT_LOCAL_COORDS]->set_icon(get_icon("Object", "EditorIcons"));
|
||||||
tool_option_button[SpatialEditor::TOOL_OPT_USE_SNAP]->set_icon(get_icon("Snap", "EditorIcons"));
|
tool_option_button[SpatialEditor::TOOL_OPT_USE_SNAP]->set_icon(get_icon("Snap", "EditorIcons"));
|
||||||
@ -5351,6 +5426,7 @@ void SpatialEditor::_bind_methods() {
|
|||||||
|
|
||||||
ADD_SIGNAL(MethodInfo("transform_key_request"));
|
ADD_SIGNAL(MethodInfo("transform_key_request"));
|
||||||
ADD_SIGNAL(MethodInfo("item_lock_status_changed"));
|
ADD_SIGNAL(MethodInfo("item_lock_status_changed"));
|
||||||
|
ADD_SIGNAL(MethodInfo("item_group_status_changed"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpatialEditor::clear() {
|
void SpatialEditor::clear() {
|
||||||
@ -5464,6 +5540,18 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
|
|||||||
tool_button[TOOL_UNLOCK_SELECTED]->connect("pressed", this, "_menu_item_pressed", button_binds);
|
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)."));
|
tool_button[TOOL_UNLOCK_SELECTED]->set_tooltip(TTR("Unlock the selected object (can be moved)."));
|
||||||
|
|
||||||
|
tool_button[TOOL_GROUP_SELECTED] = memnew(ToolButton);
|
||||||
|
hbc_menu->add_child(tool_button[TOOL_GROUP_SELECTED]);
|
||||||
|
button_binds.write[0] = MENU_GROUP_SELECTED;
|
||||||
|
tool_button[TOOL_GROUP_SELECTED]->connect("pressed", this, "_menu_item_pressed", button_binds);
|
||||||
|
tool_button[TOOL_GROUP_SELECTED]->set_tooltip(TTR("Makes sure the object's children are not selectable."));
|
||||||
|
|
||||||
|
tool_button[TOOL_UNGROUP_SELECTED] = memnew(ToolButton);
|
||||||
|
hbc_menu->add_child(tool_button[TOOL_UNGROUP_SELECTED]);
|
||||||
|
button_binds.write[0] = MENU_UNGROUP_SELECTED;
|
||||||
|
tool_button[TOOL_UNGROUP_SELECTED]->connect("pressed", this, "_menu_item_pressed", button_binds);
|
||||||
|
tool_button[TOOL_UNGROUP_SELECTED]->set_tooltip(TTR("Restores the object's children's ability to be selected."));
|
||||||
|
|
||||||
hbc_menu->add_child(memnew(VSeparator));
|
hbc_menu->add_child(memnew(VSeparator));
|
||||||
|
|
||||||
tool_option_button[TOOL_OPT_LOCAL_COORDS] = memnew(ToolButton);
|
tool_option_button[TOOL_OPT_LOCAL_COORDS] = memnew(ToolButton);
|
||||||
|
@ -485,6 +485,8 @@ public:
|
|||||||
TOOL_MODE_LIST_SELECT,
|
TOOL_MODE_LIST_SELECT,
|
||||||
TOOL_LOCK_SELECTED,
|
TOOL_LOCK_SELECTED,
|
||||||
TOOL_UNLOCK_SELECTED,
|
TOOL_UNLOCK_SELECTED,
|
||||||
|
TOOL_GROUP_SELECTED,
|
||||||
|
TOOL_UNGROUP_SELECTED,
|
||||||
TOOL_MAX
|
TOOL_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -570,6 +572,8 @@ private:
|
|||||||
MENU_VIEW_CAMERA_SETTINGS,
|
MENU_VIEW_CAMERA_SETTINGS,
|
||||||
MENU_LOCK_SELECTED,
|
MENU_LOCK_SELECTED,
|
||||||
MENU_UNLOCK_SELECTED,
|
MENU_UNLOCK_SELECTED,
|
||||||
|
MENU_GROUP_SELECTED,
|
||||||
|
MENU_UNGROUP_SELECTED,
|
||||||
MENU_SNAP_TO_FLOOR
|
MENU_SNAP_TO_FLOOR
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -986,6 +986,7 @@ void SceneTreeDock::_notification(int p_what) {
|
|||||||
|
|
||||||
SpatialEditorPlugin *spatial_editor_plugin = Object::cast_to<SpatialEditorPlugin>(editor_data->get_editor("3D"));
|
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");
|
spatial_editor_plugin->get_spatial_editor()->connect("item_lock_status_changed", scene_tree, "_update_tree");
|
||||||
|
spatial_editor_plugin->get_spatial_editor()->connect("item_group_status_changed", scene_tree, "_update_tree");
|
||||||
|
|
||||||
button_add->set_icon(get_icon("Add", "EditorIcons"));
|
button_add->set_icon(get_icon("Add", "EditorIcons"));
|
||||||
button_instance->set_icon(get_icon("Instance", "EditorIcons"));
|
button_instance->set_icon(get_icon("Instance", "EditorIcons"));
|
||||||
|
@ -102,7 +102,7 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else if (p_id == BUTTON_GROUP) {
|
} else if (p_id == BUTTON_GROUP) {
|
||||||
if (n->is_class("CanvasItem")) {
|
if (n->is_class("CanvasItem") || n->is_class("Spatial")) {
|
||||||
n->set_meta("_edit_group_", Variant());
|
n->set_meta("_edit_group_", Variant());
|
||||||
_update_tree();
|
_update_tree();
|
||||||
emit_signal("node_changed");
|
emit_signal("node_changed");
|
||||||
@ -303,6 +303,10 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
|
|||||||
if (is_locked)
|
if (is_locked)
|
||||||
item->add_button(0, get_icon("Lock", "EditorIcons"), BUTTON_LOCK, false, TTR("Node is locked.\nClick to unlock it."));
|
item->add_button(0, get_icon("Lock", "EditorIcons"), BUTTON_LOCK, false, TTR("Node is locked.\nClick to unlock it."));
|
||||||
|
|
||||||
|
bool is_grouped = p_node->has_meta("_edit_group_");
|
||||||
|
if (is_grouped)
|
||||||
|
item->add_button(0, get_icon("Group", "EditorIcons"), BUTTON_GROUP, false, TTR("Children are not selectable.\nClick to make selectable."));
|
||||||
|
|
||||||
bool v = p_node->call("is_visible");
|
bool v = p_node->call("is_visible");
|
||||||
if (v)
|
if (v)
|
||||||
item->add_button(0, get_icon("GuiVisibilityVisible", "EditorIcons"), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));
|
item->add_button(0, get_icon("GuiVisibilityVisible", "EditorIcons"), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user