You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2026-01-06 19:41:11 +00:00
Use ObjectID to store nodes in the editor selection.
This commit is contained in:
@@ -1073,8 +1073,11 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
|
||||
break;
|
||||
}
|
||||
Ref<MultiNodeEdit> mne = memnew(MultiNodeEdit);
|
||||
for (const KeyValue<Node *, Object *> &E : editor_selection->get_selection()) {
|
||||
mne->add_node(root->get_path_to(E.key));
|
||||
for (const KeyValue<ObjectID, Object *> &E : editor_selection->get_selection()) {
|
||||
Node *node = ObjectDB::get_instance<Node>(E.key);
|
||||
if (node) {
|
||||
mne->add_node(root->get_path_to(node));
|
||||
}
|
||||
}
|
||||
|
||||
_push_item(mne.ptr());
|
||||
@@ -2930,7 +2933,10 @@ void SceneTreeDock::_selection_changed() {
|
||||
//automatically turn on multi-edit
|
||||
_tool_selected(TOOL_MULTI_EDIT);
|
||||
} else if (selection_size == 1) {
|
||||
_handle_select(editor_selection->get_selection().begin()->key);
|
||||
Node *node = ObjectDB::get_instance<Node>(editor_selection->get_selection().begin()->key);
|
||||
if (node) {
|
||||
_handle_select(node);
|
||||
}
|
||||
} else if (selection_size == 0) {
|
||||
_push_item(nullptr);
|
||||
}
|
||||
@@ -2940,10 +2946,12 @@ void SceneTreeDock::_selection_changed() {
|
||||
|
||||
// Track script changes in newly selected nodes.
|
||||
node_previous_selection.reserve(editor_selection->get_selection().size());
|
||||
for (const KeyValue<Node *, Object *> &E : editor_selection->get_selection()) {
|
||||
Node *node = E.key;
|
||||
node_previous_selection.push_back(node->get_instance_id());
|
||||
node->connect(CoreStringName(script_changed), callable_mp(this, &SceneTreeDock::_queue_update_script_button));
|
||||
for (const KeyValue<ObjectID, Object *> &E : editor_selection->get_selection()) {
|
||||
Node *node = ObjectDB::get_instance<Node>(E.key);
|
||||
if (node) {
|
||||
node_previous_selection.push_back(E.key);
|
||||
node->connect(CoreStringName(script_changed), callable_mp(this, &SceneTreeDock::_queue_update_script_button));
|
||||
}
|
||||
}
|
||||
_queue_update_script_button();
|
||||
}
|
||||
@@ -3369,12 +3377,12 @@ void SceneTreeDock::set_edited_scene(Node *p_scene) {
|
||||
edited_scene = p_scene;
|
||||
}
|
||||
|
||||
static bool _is_same_selection(const Vector<Node *> &p_first, const HashMap<Node *, Object *> &p_second) {
|
||||
static bool _is_same_selection(const Vector<Node *> &p_first, const HashMap<ObjectID, Object *> &p_second) {
|
||||
if (p_first.size() != p_second.size()) {
|
||||
return false;
|
||||
}
|
||||
for (Node *node : p_first) {
|
||||
if (!p_second.has(node)) {
|
||||
if (!p_second.has(node->get_instance_id())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1214,15 +1214,15 @@ EditorData::~EditorData() {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void EditorSelection::_node_removed(Node *p_node) {
|
||||
if (!selection.has(p_node)) {
|
||||
ERR_FAIL_NULL(p_node);
|
||||
ObjectID nid = p_node->get_instance_id();
|
||||
if (!selection.has(nid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object *meta = selection[p_node];
|
||||
if (meta) {
|
||||
memdelete(meta);
|
||||
}
|
||||
selection.erase(p_node);
|
||||
Object *meta = selection[nid];
|
||||
memdelete_notnull(meta);
|
||||
selection.erase(nid);
|
||||
changed = true;
|
||||
node_list_changed = true;
|
||||
}
|
||||
@@ -1230,7 +1230,8 @@ void EditorSelection::_node_removed(Node *p_node) {
|
||||
void EditorSelection::add_node(Node *p_node) {
|
||||
ERR_FAIL_NULL(p_node);
|
||||
ERR_FAIL_COND(!p_node->is_inside_tree());
|
||||
if (selection.has(p_node)) {
|
||||
ObjectID nid = p_node->get_instance_id();
|
||||
if (selection.has(nid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1243,30 +1244,32 @@ void EditorSelection::add_node(Node *p_node) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
selection[p_node] = meta;
|
||||
selection[nid] = meta;
|
||||
|
||||
p_node->connect(SceneStringName(tree_exiting), callable_mp(this, &EditorSelection::_node_removed).bind(p_node), CONNECT_ONE_SHOT);
|
||||
}
|
||||
|
||||
void EditorSelection::remove_node(Node *p_node) {
|
||||
ERR_FAIL_NULL(p_node);
|
||||
if (!selection.has(p_node)) {
|
||||
ObjectID nid = p_node->get_instance_id();
|
||||
if (!selection.has(nid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
changed = true;
|
||||
node_list_changed = true;
|
||||
Object *meta = selection[p_node];
|
||||
if (meta) {
|
||||
memdelete(meta);
|
||||
}
|
||||
selection.erase(p_node);
|
||||
Object *meta = selection[nid];
|
||||
memdelete_notnull(meta);
|
||||
selection.erase(nid);
|
||||
|
||||
p_node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &EditorSelection::_node_removed));
|
||||
}
|
||||
|
||||
bool EditorSelection::is_selected(Node *p_node) const {
|
||||
return selection.has(p_node);
|
||||
if (!p_node) {
|
||||
return false;
|
||||
}
|
||||
return selection.has(p_node->get_instance_id());
|
||||
}
|
||||
|
||||
void EditorSelection::_bind_methods() {
|
||||
@@ -1295,12 +1298,15 @@ void EditorSelection::_update_node_list() {
|
||||
// If the selection does not have the parent of the selected node, then add the node to the node list.
|
||||
// However, if the parent is already selected, then adding this node is redundant as
|
||||
// it is included with the parent, so skip it.
|
||||
for (const KeyValue<Node *, Object *> &E : selection) {
|
||||
Node *parent = E.key;
|
||||
for (const KeyValue<ObjectID, Object *> &E : selection) {
|
||||
Node *parent = ObjectDB::get_instance<Node>(E.key);
|
||||
if (!parent) {
|
||||
continue;
|
||||
}
|
||||
parent = parent->get_parent();
|
||||
bool skip = false;
|
||||
while (parent) {
|
||||
if (selection.has(parent)) {
|
||||
if (selection.has(parent->get_instance_id())) {
|
||||
skip = true;
|
||||
break;
|
||||
}
|
||||
@@ -1337,8 +1343,11 @@ void EditorSelection::_emit_change() {
|
||||
TypedArray<Node> EditorSelection::get_top_selected_nodes() {
|
||||
TypedArray<Node> ret;
|
||||
|
||||
for (const Node *E : top_selected_node_list) {
|
||||
ret.push_back(E);
|
||||
for (const ObjectID &nid : top_selected_node_list) {
|
||||
Node *node = ObjectDB::get_instance<Node>(nid);
|
||||
if (node) {
|
||||
ret.push_back(node);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -1347,26 +1356,39 @@ TypedArray<Node> EditorSelection::get_top_selected_nodes() {
|
||||
TypedArray<Node> EditorSelection::get_selected_nodes() {
|
||||
TypedArray<Node> ret;
|
||||
|
||||
for (const KeyValue<Node *, Object *> &E : selection) {
|
||||
ret.push_back(E.key);
|
||||
for (const KeyValue<ObjectID, Object *> &E : selection) {
|
||||
Node *node = ObjectDB::get_instance<Node>(E.key);
|
||||
if (node) {
|
||||
ret.push_back(node);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const List<Node *> &EditorSelection::get_top_selected_node_list() {
|
||||
List<Node *> EditorSelection::get_top_selected_node_list() {
|
||||
if (changed) {
|
||||
update();
|
||||
} else {
|
||||
_update_node_list();
|
||||
}
|
||||
return top_selected_node_list;
|
||||
List<Node *> node_list;
|
||||
for (const ObjectID &nid : top_selected_node_list) {
|
||||
Node *node = ObjectDB::get_instance<Node>(nid);
|
||||
if (node) {
|
||||
node_list.push_back(node);
|
||||
}
|
||||
}
|
||||
return node_list;
|
||||
}
|
||||
|
||||
List<Node *> EditorSelection::get_full_selected_node_list() {
|
||||
List<Node *> node_list;
|
||||
for (const KeyValue<Node *, Object *> &E : selection) {
|
||||
node_list.push_back(E.key);
|
||||
for (const KeyValue<ObjectID, Object *> &E : selection) {
|
||||
Node *node = ObjectDB::get_instance<Node>(E.key);
|
||||
if (node) {
|
||||
node_list.push_back(node);
|
||||
}
|
||||
}
|
||||
|
||||
return node_list;
|
||||
@@ -1374,7 +1396,10 @@ List<Node *> EditorSelection::get_full_selected_node_list() {
|
||||
|
||||
void EditorSelection::clear() {
|
||||
while (!selection.is_empty()) {
|
||||
remove_node(selection.begin()->key);
|
||||
Node *node = ObjectDB::get_instance<Node>(selection.begin()->key);
|
||||
if (node) {
|
||||
remove_node(node);
|
||||
}
|
||||
}
|
||||
|
||||
changed = true;
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "core/templates/list.h"
|
||||
#include "scene/main/node.h"
|
||||
#include "scene/resources/texture.h"
|
||||
|
||||
class ConfigFile;
|
||||
@@ -274,7 +275,7 @@ class EditorSelection : public Object {
|
||||
|
||||
// Contains the selected nodes and corresponding metadata.
|
||||
// Metadata objects come from calling _get_editor_data on the editor_plugins, passing the selected node.
|
||||
HashMap<Node *, Object *> selection;
|
||||
HashMap<ObjectID, Object *> selection;
|
||||
|
||||
// Tracks whether the selection change signal has been emitted.
|
||||
// Prevents multiple signals being called in one frame.
|
||||
@@ -287,7 +288,7 @@ class EditorSelection : public Object {
|
||||
|
||||
// Editor plugins which are related to selection.
|
||||
List<Object *> editor_plugins;
|
||||
List<Node *> top_selected_node_list;
|
||||
LocalVector<ObjectID> top_selected_node_list;
|
||||
|
||||
void _update_node_list();
|
||||
void _emit_change();
|
||||
@@ -302,10 +303,14 @@ public:
|
||||
|
||||
template <typename T>
|
||||
T *get_node_editor_data(Node *p_node) {
|
||||
if (!selection.has(p_node)) {
|
||||
if (!p_node) {
|
||||
return nullptr;
|
||||
}
|
||||
return Object::cast_to<T>(selection[p_node]);
|
||||
ObjectID nid = p_node->get_instance_id();
|
||||
if (!selection.has(nid)) {
|
||||
return nullptr;
|
||||
}
|
||||
return Object::cast_to<T>(selection[nid]);
|
||||
}
|
||||
|
||||
// Adds an editor plugin which can provide metadata for selected nodes.
|
||||
@@ -316,7 +321,7 @@ public:
|
||||
|
||||
// Returns only the top level selected nodes.
|
||||
// That is, if the selection includes some node and a child of that node, only the parent is returned.
|
||||
const List<Node *> &get_top_selected_node_list();
|
||||
List<Node *> get_top_selected_node_list();
|
||||
// Same as get_top_selected_node_list but returns a copy in a TypedArray for binding to scripts.
|
||||
TypedArray<Node> get_top_selected_nodes();
|
||||
// Returns all the selected nodes (list version of "get_selected_nodes").
|
||||
@@ -324,7 +329,7 @@ public:
|
||||
// Same as get_full_selected_node_list but returns a copy in a TypedArray for binding to scripts.
|
||||
TypedArray<Node> get_selected_nodes();
|
||||
// Returns the map of selected objects and their metadata.
|
||||
HashMap<Node *, Object *> &get_selection() { return selection; }
|
||||
HashMap<ObjectID, Object *> &get_selection() { return selection; }
|
||||
|
||||
~EditorSelection();
|
||||
};
|
||||
|
||||
@@ -341,12 +341,13 @@ void Particles2DEditorPlugin::_selection_changed() {
|
||||
}
|
||||
|
||||
// Turn gizmos on for nodes that are newly selected.
|
||||
HashSet<const Node *> nodes_in_current_selection;
|
||||
HashSet<ObjectID> nodes_in_current_selection;
|
||||
for (Node *node : current_selection) {
|
||||
nodes_in_current_selection.insert(node);
|
||||
if (!selected_particles.has(node)) {
|
||||
ObjectID nid = node->get_instance_id();
|
||||
nodes_in_current_selection.insert(nid);
|
||||
if (!selected_particles.has(nid)) {
|
||||
_set_show_gizmos(node, true);
|
||||
selected_particles.insert(node);
|
||||
selected_particles.insert(nid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -358,21 +359,24 @@ void Particles2DEditorPlugin::_selection_changed() {
|
||||
direction_img_path_line_edit->set_text("");
|
||||
|
||||
// Turn gizmos off for nodes that are no longer selected.
|
||||
LocalVector<Node *> to_erase;
|
||||
for (Node *node : selected_particles) {
|
||||
if (!nodes_in_current_selection.has(node)) {
|
||||
_set_show_gizmos(node, false);
|
||||
to_erase.push_back(node);
|
||||
LocalVector<ObjectID> to_erase;
|
||||
for (const ObjectID &nid : selected_particles) {
|
||||
if (!nodes_in_current_selection.has(nid)) {
|
||||
Node *node = ObjectDB::get_instance<Node>(nid);
|
||||
if (node) {
|
||||
_set_show_gizmos(node, false);
|
||||
}
|
||||
to_erase.push_back(nid);
|
||||
}
|
||||
}
|
||||
|
||||
for (Node *node : to_erase) {
|
||||
selected_particles.erase(node);
|
||||
for (const ObjectID &nid : to_erase) {
|
||||
selected_particles.erase(nid);
|
||||
}
|
||||
}
|
||||
|
||||
void Particles2DEditorPlugin::_node_removed(Node *p_node) {
|
||||
if (selected_particles.erase(p_node)) {
|
||||
if (p_node && selected_particles.erase(p_node->get_instance_id())) {
|
||||
_set_show_gizmos(p_node, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ protected:
|
||||
MENU_LOAD_EMISSION_MASK = 100,
|
||||
};
|
||||
|
||||
HashSet<Node *> selected_particles;
|
||||
HashSet<ObjectID> selected_particles;
|
||||
|
||||
enum EmissionMode {
|
||||
EMISSION_MODE_SOLID,
|
||||
|
||||
@@ -673,12 +673,12 @@ Transform3D Node3DEditorViewport::to_camera_transform(const Cursor &p_cursor) co
|
||||
}
|
||||
|
||||
int Node3DEditorViewport::get_selected_count() const {
|
||||
const HashMap<Node *, Object *> &selection = editor_selection->get_selection();
|
||||
const HashMap<ObjectID, Object *> &selection = editor_selection->get_selection();
|
||||
|
||||
int count = 0;
|
||||
|
||||
for (const KeyValue<Node *, Object *> &E : selection) {
|
||||
Node3D *sp = Object::cast_to<Node3D>(E.key);
|
||||
for (const KeyValue<ObjectID, Object *> &E : selection) {
|
||||
Node3D *sp = ObjectDB::get_instance<Node3D>(E.key);
|
||||
if (!sp) {
|
||||
continue;
|
||||
}
|
||||
@@ -3341,13 +3341,13 @@ void Node3DEditorViewport::_notification(int p_what) {
|
||||
_update_camera(delta);
|
||||
}
|
||||
|
||||
const HashMap<Node *, Object *> &selection = editor_selection->get_selection();
|
||||
const HashMap<ObjectID, Object *> &selection = editor_selection->get_selection();
|
||||
|
||||
bool changed = false;
|
||||
bool exist = false;
|
||||
|
||||
for (const KeyValue<Node *, Object *> &E : selection) {
|
||||
Node3D *sp = Object::cast_to<Node3D>(E.key);
|
||||
for (const KeyValue<ObjectID, Object *> &E : selection) {
|
||||
Node3D *sp = ObjectDB::get_instance<Node3D>(E.key);
|
||||
if (!sp) {
|
||||
continue;
|
||||
}
|
||||
@@ -8489,10 +8489,10 @@ void Node3DEditor::update_grid() {
|
||||
void Node3DEditor::_selection_changed() {
|
||||
_refresh_menu_icons();
|
||||
|
||||
const HashMap<Node *, Object *> &selection = editor_selection->get_selection();
|
||||
const HashMap<ObjectID, Object *> &selection = editor_selection->get_selection();
|
||||
|
||||
for (const KeyValue<Node *, Object *> &E : selection) {
|
||||
Node3D *sp = Object::cast_to<Node3D>(E.key);
|
||||
for (const KeyValue<ObjectID, Object *> &E : selection) {
|
||||
Node3D *sp = ObjectDB::get_instance<Node3D>(E.key);
|
||||
if (!sp) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -824,8 +824,8 @@ bool CanvasItemEditor::_select_click_on_item(CanvasItem *item, Point2 p_click_po
|
||||
|
||||
List<CanvasItem *> CanvasItemEditor::_get_edited_canvas_items(bool p_retrieve_locked, bool p_remove_canvas_item_if_parent_in_selection, bool *r_has_locked_items) const {
|
||||
List<CanvasItem *> selection;
|
||||
for (const KeyValue<Node *, Object *> &E : editor_selection->get_selection()) {
|
||||
CanvasItem *ci = Object::cast_to<CanvasItem>(E.key);
|
||||
for (const KeyValue<ObjectID, Object *> &E : editor_selection->get_selection()) {
|
||||
CanvasItem *ci = ObjectDB::get_instance<CanvasItem>(E.key);
|
||||
if (ci) {
|
||||
if (ci->is_visible_in_tree() && (p_retrieve_locked || !_is_node_locked(ci))) {
|
||||
Viewport *vp = ci->get_viewport();
|
||||
@@ -4667,7 +4667,7 @@ void CanvasItemEditor::_button_tool_select(int p_index) {
|
||||
}
|
||||
|
||||
void CanvasItemEditor::_insert_animation_keys(bool p_location, bool p_rotation, bool p_scale, bool p_on_existing) {
|
||||
const HashMap<Node *, Object *> &selection = editor_selection->get_selection();
|
||||
const HashMap<ObjectID, Object *> &selection = editor_selection->get_selection();
|
||||
|
||||
AnimationTrackEditor *te = AnimationPlayerEditor::get_singleton()->get_track_editor();
|
||||
ERR_FAIL_COND_MSG(te->get_current_animation().is_null(), "Cannot insert animation key. No animation selected.");
|
||||
@@ -4678,8 +4678,8 @@ void CanvasItemEditor::_insert_animation_keys(bool p_location, bool p_rotation,
|
||||
return;
|
||||
}
|
||||
te->make_insert_queue();
|
||||
for (const KeyValue<Node *, Object *> &E : selection) {
|
||||
CanvasItem *ci = Object::cast_to<CanvasItem>(E.key);
|
||||
for (const KeyValue<ObjectID, Object *> &E : selection) {
|
||||
CanvasItem *ci = ObjectDB::get_instance<CanvasItem>(E.key);
|
||||
if (!ci || !ci->is_visible_in_tree()) {
|
||||
continue;
|
||||
}
|
||||
@@ -4981,10 +4981,10 @@ void CanvasItemEditor::_popup_callback(int p_op) {
|
||||
case ANIM_COPY_POSE: {
|
||||
pose_clipboard.clear();
|
||||
|
||||
const HashMap<Node *, Object *> &selection = editor_selection->get_selection();
|
||||
const HashMap<ObjectID, Object *> &selection = editor_selection->get_selection();
|
||||
|
||||
for (const KeyValue<Node *, Object *> &E : selection) {
|
||||
CanvasItem *ci = Object::cast_to<CanvasItem>(E.key);
|
||||
for (const KeyValue<ObjectID, Object *> &E : selection) {
|
||||
CanvasItem *ci = ObjectDB::get_instance<CanvasItem>(E.key);
|
||||
if (!ci || !ci->is_visible_in_tree()) {
|
||||
continue;
|
||||
}
|
||||
@@ -5023,10 +5023,10 @@ void CanvasItemEditor::_popup_callback(int p_op) {
|
||||
|
||||
} break;
|
||||
case ANIM_CLEAR_POSE: {
|
||||
HashMap<Node *, Object *> &selection = editor_selection->get_selection();
|
||||
HashMap<ObjectID, Object *> &selection = editor_selection->get_selection();
|
||||
|
||||
for (const KeyValue<Node *, Object *> &E : selection) {
|
||||
CanvasItem *ci = Object::cast_to<CanvasItem>(E.key);
|
||||
for (const KeyValue<ObjectID, Object *> &E : selection) {
|
||||
CanvasItem *ci = ObjectDB::get_instance<CanvasItem>(E.key);
|
||||
if (!ci || !ci->is_visible_in_tree()) {
|
||||
continue;
|
||||
}
|
||||
@@ -5089,7 +5089,7 @@ void CanvasItemEditor::_popup_callback(int p_op) {
|
||||
|
||||
} break;
|
||||
case SKELETON_MAKE_BONES: {
|
||||
HashMap<Node *, Object *> &selection = editor_selection->get_selection();
|
||||
HashMap<ObjectID, Object *> &selection = editor_selection->get_selection();
|
||||
Node *editor_root = get_tree()->get_edited_scene_root();
|
||||
|
||||
if (!editor_root || selection.is_empty()) {
|
||||
@@ -5097,8 +5097,8 @@ void CanvasItemEditor::_popup_callback(int p_op) {
|
||||
}
|
||||
|
||||
undo_redo->create_action(TTR("Create Custom Bone2D(s) from Node(s)"));
|
||||
for (const KeyValue<Node *, Object *> &E : selection) {
|
||||
Node2D *n2d = Object::cast_to<Node2D>(E.key);
|
||||
for (const KeyValue<ObjectID, Object *> &E : selection) {
|
||||
Node2D *n2d = ObjectDB::get_instance<Node2D>(E.key);
|
||||
if (!n2d) {
|
||||
continue;
|
||||
}
|
||||
@@ -5144,9 +5144,9 @@ void CanvasItemEditor::_focus_selection(int p_op) {
|
||||
Rect2 rect;
|
||||
int count = 0;
|
||||
|
||||
const HashMap<Node *, Object *> &selection = editor_selection->get_selection();
|
||||
for (const KeyValue<Node *, Object *> &E : selection) {
|
||||
CanvasItem *ci = Object::cast_to<CanvasItem>(E.key);
|
||||
const HashMap<ObjectID, Object *> &selection = editor_selection->get_selection();
|
||||
for (const KeyValue<ObjectID, Object *> &E : selection) {
|
||||
CanvasItem *ci = ObjectDB::get_instance<CanvasItem>(E.key);
|
||||
if (!ci) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -926,8 +926,8 @@ bool ControlEditorToolbar::_is_node_locked(const Node *p_node) {
|
||||
|
||||
List<Control *> ControlEditorToolbar::_get_edited_controls() {
|
||||
List<Control *> selection;
|
||||
for (const KeyValue<Node *, Object *> &E : editor_selection->get_selection()) {
|
||||
Control *control = Object::cast_to<Control>(E.key);
|
||||
for (const KeyValue<ObjectID, Object *> &E : editor_selection->get_selection()) {
|
||||
Control *control = ObjectDB::get_instance<Control>(E.key);
|
||||
if (control && control->is_visible_in_tree() && control->get_viewport() == EditorNode::get_singleton()->get_scene_root() && !_is_node_locked(control)) {
|
||||
selection.push_back(control);
|
||||
}
|
||||
@@ -958,8 +958,8 @@ void ControlEditorToolbar::_selection_changed() {
|
||||
SIZE_EXPAND,
|
||||
};
|
||||
|
||||
for (const KeyValue<Node *, Object *> &E : editor_selection->get_selection()) {
|
||||
Control *control = Object::cast_to<Control>(E.key);
|
||||
for (const KeyValue<ObjectID, Object *> &E : editor_selection->get_selection()) {
|
||||
Control *control = ObjectDB::get_instance<Control>(E.key);
|
||||
if (!control) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user