Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose "editable_instance" to scripting + Update C++ API #46006

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Exposes "editable_instance" of nodes to the scripting interface + mod…
…ifies "set_editable_instance" and "is_editable_instance" to better reflect how they work now
  • Loading branch information
revilo committed Feb 14, 2021
commit 0c7ccf3ed5de110ded5dafe0cc728eb5da53f370
3 changes: 3 additions & 0 deletions doc/classes/Node.xml
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,9 @@
<member name="custom_multiplayer" type="MultiplayerAPI" setter="set_custom_multiplayer" getter="get_custom_multiplayer">
The override to the default [MultiplayerAPI]. Set to [code]null[/code] to use the default [SceneTree] one.
</member>
<member name="editable_instance" type="bool" setter="set_editable_instance" getter="get_editable_instance" default="false">
If the node is an instanced scene, this flag indicates whether it is editable.
</member>
<member name="filename" type="String" setter="set_filename" getter="get_filename">
When a scene is instanced from a file, its topmost node contains the filename from which it was loaded.
</member>
Expand Down
4 changes: 2 additions & 2 deletions editor/editor_folding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ void EditorFolding::_fill_folds(const Node *p_root, const Node *p_node, Array &p
if (!p_node->get_owner()) {
return; //not owned, bye
}
if (p_node->get_owner() != p_root && !p_root->is_editable_instance(p_node)) {
if (p_node->get_owner() != p_root && !p_node->is_editable_instance()) {
return;
}
}
Expand Down Expand Up @@ -284,7 +284,7 @@ void EditorFolding::_do_node_unfolds(Node *p_root, Node *p_node, Set<RES> &resou
if (!p_node->get_owner()) {
return; //not owned, bye
}
if (p_node->get_owner() != p_root && !p_root->is_editable_instance(p_node)) {
if (p_node->get_owner() != p_root && !p_node->is_editable_instance()) {
return;
}
}
Expand Down
2 changes: 1 addition & 1 deletion editor/groups_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ void GroupDialog::_load_nodes(Node *p_current) {
bool keep = true;
Node *root = scene_tree->get_edited_scene_root();
Node *owner = p_current->get_owner();
if (owner != root && p_current != root && !owner && !root->is_editable_instance(owner)) {
if (owner != root && p_current != root && !owner) {
keep = false;
}

Expand Down
2 changes: 1 addition & 1 deletion editor/node_3d_editor_gizmos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ bool EditorNode3DGizmo::is_editable() const {
return true;
}

if (edited_root->is_editable_instance(spatial_node->get_owner())) {
if (spatial_node->get_owner() && spatial_node->get_owner()->is_editable_instance()) {
return true;
}

Expand Down
12 changes: 6 additions & 6 deletions editor/plugins/canvas_item_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,7 @@ void CanvasItemEditor::_get_canvas_items_at_pos(const Point2 &p_pos, Vector<_Sel
Node *node = r_items[i].item;

// Make sure the selected node is in the current scene, or editable
while (node && node != get_tree()->get_edited_scene_root() && node->get_owner() != scene && !scene->is_editable_instance(node->get_owner())) {
while (node && node != get_tree()->get_edited_scene_root() && node->get_owner() != scene && (!node->get_owner() || !node->get_owner()->is_editable_instance())) {
node = node->get_parent();
};

Expand All @@ -655,7 +655,7 @@ void CanvasItemEditor::_get_canvas_items_at_pos(const Point2 &p_pos, Vector<_Sel
}

//Remove the item if invalid
if (!canvas_item || duplicate || (canvas_item != scene && canvas_item->get_owner() != scene && !scene->is_editable_instance(canvas_item->get_owner())) || (!p_allow_locked && _is_node_locked(canvas_item))) {
if (!canvas_item || duplicate || (canvas_item != scene && canvas_item->get_owner() != scene && (!canvas_item->get_owner() || !canvas_item->get_owner()->is_editable_instance())) || (!p_allow_locked && _is_node_locked(canvas_item))) {
r_items.remove(i);
i--;
} else {
Expand Down Expand Up @@ -762,7 +762,7 @@ void CanvasItemEditor::_find_canvas_items_in_rect(const Rect2 &p_rect, Node *p_n
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node);
Node *scene = editor->get_edited_scene();

bool editable = p_node == scene || p_node->get_owner() == scene || scene->is_editable_instance(p_node->get_owner());
bool editable = p_node == scene || p_node->get_owner() == scene || (p_node->get_owner() && p_node->get_owner()->is_editable_instance());
bool lock_children = p_node->has_meta("_edit_group_") && p_node->get_meta("_edit_group_");
bool locked = _is_node_locked(p_node);

Expand Down Expand Up @@ -3743,7 +3743,7 @@ void CanvasItemEditor::_draw_invisible_nodes_positions(Node *p_node, const Trans
ERR_FAIL_COND(!p_node);

Node *scene = editor->get_edited_scene();
if (p_node != scene && p_node->get_owner() != scene && !scene->is_editable_instance(p_node->get_owner())) {
if (p_node != scene && p_node->get_owner() != scene && (!p_node->get_owner() || !p_node->get_owner()->is_editable_instance())) {
return;
}
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node);
Expand Down Expand Up @@ -3813,7 +3813,7 @@ void CanvasItemEditor::_draw_locks_and_groups(Node *p_node, const Transform2D &p
ERR_FAIL_COND(!p_node);

Node *scene = editor->get_edited_scene();
if (p_node != scene && p_node->get_owner() != scene && !scene->is_editable_instance(p_node->get_owner())) {
if (p_node != scene && p_node->get_owner() != scene && (!p_node->get_owner() || !p_node->get_owner()->is_editable_instance())) {
return;
}
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node);
Expand Down Expand Up @@ -3867,7 +3867,7 @@ bool CanvasItemEditor::_build_bones_list(Node *p_node) {

CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node);
Node *scene = editor->get_edited_scene();
if (!canvas_item || !canvas_item->is_visible() || (canvas_item != scene && canvas_item->get_owner() != scene && !scene->is_editable_instance(canvas_item->get_owner()))) {
if (!canvas_item || !canvas_item->is_visible() || (canvas_item != scene && canvas_item->get_owner() != scene && (!canvas_item->get_owner() || !canvas_item->get_owner()->is_editable_instance()))) {
return false;
}

Expand Down
6 changes: 3 additions & 3 deletions editor/plugins/node_3d_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos, bool p_append, b

if (dist < closest_dist) {
item = Object::cast_to<Node>(spat);
while (item->get_owner() && item->get_owner() != edited_scene && !edited_scene->is_editable_instance(item->get_owner())) {
while (item->get_owner() && item->get_owner() != edited_scene && !item->get_owner()->is_editable_instance()) {
item = item->get_owner();
}

Expand Down Expand Up @@ -697,7 +697,7 @@ void Node3DEditorViewport::_select_region() {
}

Node *item = Object::cast_to<Node>(sp);
while (item->get_owner() && item->get_owner() != edited_scene && !edited_scene->is_editable_instance(item->get_owner())) {
while (item->get_owner() && item->get_owner() != edited_scene && !item->get_owner()->is_editable_instance()) {
item = item->get_owner();
}

Expand Down Expand Up @@ -1027,7 +1027,7 @@ void Node3DEditorViewport::_list_select(Ref<InputEventMouseButton> b) {

for (int i = 0; i < selection_results.size(); i++) {
Node3D *item = selection_results[i].item;
if (item != scene && item->get_owner() != scene && !scene->is_editable_instance(item->get_owner())) {
if (item != scene && item->get_owner() != scene && (!item->get_owner() || !item->get_owner()->is_editable_instance())) {
//invalid result
selection_results.remove(i);
i--;
Expand Down
16 changes: 8 additions & 8 deletions editor/scene_tree_dock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
Map<const Node *, Node *> duplimap;
Node *dup = node->duplicate_from_editor(duplimap);

if (EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(node)) {
if (node->is_editable_instance()) {
editable_children.push_back(dup);
}

Expand Down Expand Up @@ -971,7 +971,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (e) {
Node *node = e->get();
if (node) {
bool editable = EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(node);
bool editable = node->is_editable_instance();

if (editable) {
editable_instance_remove_dialog->set_text(TTR("Disabling \"editable_instance\" will cause all properties of the node to be reverted to their default."));
Expand All @@ -992,7 +992,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (e) {
Node *node = e->get();
if (node) {
bool editable = EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(node);
bool editable = node->is_editable_instance();
bool placeholder = node->get_scene_instance_load_placeholder();

// Fire confirmation dialog when children are editable.
Expand All @@ -1005,7 +1005,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
placeholder = !placeholder;

if (placeholder) {
EditorNode::get_singleton()->get_edited_scene()->set_editable_instance(node, false);
node->set_editable_instance(false);
}

node->set_scene_instance_load_placeholder(placeholder);
Expand Down Expand Up @@ -1897,8 +1897,8 @@ void SceneTreeDock::_toggle_placeholder_from_selection() {

void SceneTreeDock::_toggle_editable_children(Node *p_node) {
if (p_node) {
bool editable = !EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(p_node);
EditorNode::get_singleton()->get_edited_scene()->set_editable_instance(p_node, editable);
bool editable = !p_node->is_editable_instance();
p_node->set_editable_instance(editable);
if (editable) {
p_node->set_scene_instance_load_placeholder(false);
}
Expand Down Expand Up @@ -2360,7 +2360,7 @@ static bool _is_node_visible(Node *p_node) {
if (!p_node->get_owner()) {
return false;
}
if (p_node->get_owner() != EditorNode::get_singleton()->get_edited_scene() && !EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(p_node->get_owner())) {
if (p_node->get_owner() != EditorNode::get_singleton()->get_edited_scene() && (!p_node->get_owner() || !p_node->get_owner()->is_editable_instance())) {
return false;
}

Expand Down Expand Up @@ -2642,7 +2642,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->add_icon_item(get_theme_icon("Load", "EditorIcons"), TTR("Open in Editor"), TOOL_SCENE_OPEN_INHERITED);
} else if (!is_top_level) {
menu->add_separator();
bool editable = EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(selection[0]);
bool editable = selection[0]->is_editable_instance();
bool placeholder = selection[0]->get_scene_instance_load_placeholder();
if (profile_allow_editing) {
menu->add_check_item(TTR("Editable Children"), TOOL_SCENE_EDITABLE_CHILDREN);
Expand Down
2 changes: 1 addition & 1 deletion editor/scene_tree_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent, bool p_scroll
bool part_of_subscene = false;

if (!display_foreign && p_node->get_owner() != get_scene_node() && p_node != get_scene_node()) {
if ((show_enabled_subscene || can_open_instance) && p_node->get_owner() && (get_scene_node()->is_editable_instance(p_node->get_owner()))) {
if ((show_enabled_subscene || can_open_instance) && p_node->get_owner() && p_node->get_owner()->is_editable_instance()) {
part_of_subscene = true;
//allow
} else {
Expand Down
20 changes: 9 additions & 11 deletions scene/main/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1909,25 +1909,19 @@ String Node::get_editor_description() const {
}
}

void Node::set_editable_instance(Node *p_node, bool p_editable) {
ERR_FAIL_NULL(p_node);
ERR_FAIL_COND(!is_a_parent_of(p_node));
void Node::set_editable_instance(bool p_editable) {
if (!p_editable) {
p_node->data.editable_instance = false;
data.editable_instance = false;
// Avoid this flag being needlessly saved;
// also give more visual feedback if editable children is re-enabled
set_display_folded(false);
} else {
p_node->data.editable_instance = true;
data.editable_instance = true;
}
}

bool Node::is_editable_instance(const Node *p_node) const {
if (!p_node) {
return false; // Easier, null is never editable. :)
}
ERR_FAIL_COND_V(!is_a_parent_of(p_node), false);
return p_node->data.editable_instance;
bool Node::is_editable_instance() const {
return data.editable_instance;
}

void Node::set_scene_instance_state(const Ref<SceneState> &p_state) {
Expand Down Expand Up @@ -2791,6 +2785,9 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_display_folded", "fold"), &Node::set_display_folded);
ClassDB::bind_method(D_METHOD("is_displayed_folded"), &Node::is_displayed_folded);

ClassDB::bind_method(D_METHOD("set_editable_instance", "editable_instance"), &Node::set_editable_instance);
ClassDB::bind_method(D_METHOD("is_editable_instance"), &Node::is_editable_instance);

ClassDB::bind_method(D_METHOD("set_process_internal", "enable"), &Node::set_process_internal);
ClassDB::bind_method(D_METHOD("is_processing_internal"), &Node::is_processing_internal);

Expand Down Expand Up @@ -2909,6 +2906,7 @@ void Node::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "pause_mode", PROPERTY_HINT_ENUM, "Inherit,Stop,Process"), "set_pause_mode", "get_pause_mode");

ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "name", PROPERTY_HINT_NONE, "", 0), "set_name", "get_name");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editable_instance"), "set_editable_instance", "is_editable_instance");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "filename", PROPERTY_HINT_NONE, "", 0), "set_filename", "get_filename");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "owner", PROPERTY_HINT_RESOURCE_TYPE, "Node", 0), "set_owner", "get_owner");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", 0), "", "get_multiplayer");
Expand Down
4 changes: 2 additions & 2 deletions scene/main/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,8 +322,8 @@ class Node : public Object {
void set_editor_description(const String &p_editor_description);
String get_editor_description() const;

void set_editable_instance(Node *p_node, bool p_editable);
bool is_editable_instance(const Node *p_node) const;
void set_editable_instance(bool p_editable);
bool is_editable_instance() const;

/* NOTIFICATIONS */

Expand Down
8 changes: 4 additions & 4 deletions scene/resources/packed_scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
for (int i = 0; i < editable_instances.size(); i++) {
Node *ei = ret_nodes[0]->get_node_or_null(editable_instances[i]);
if (ei) {
ret_nodes[0]->set_editable_instance(ei, true);
ei->set_editable_instance(true);
}
}

Expand Down Expand Up @@ -372,13 +372,13 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
// document it. if you fail to understand something, please ask!

//discard nodes that do not belong to be processed
if (p_node != p_owner && p_node->get_owner() != p_owner && !p_owner->is_editable_instance(p_node->get_owner())) {
if (p_node != p_owner && p_node->get_owner() != p_owner && (!p_node->get_owner() || !p_node->get_owner()->is_editable_instance())) {
return OK;
}

// save the child instanced scenes that are chosen as editable, so they can be restored
// upon load back
if (p_node != p_owner && p_node->get_filename() != String() && p_owner->is_editable_instance(p_node)) {
if (p_node != p_owner && p_node->get_filename() != String() && p_node->is_editable_instance()) {
editable_instances.push_back(p_owner->get_path_to(p_node));
}

Expand Down Expand Up @@ -661,7 +661,7 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
}

Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName, int> &name_map, HashMap<Variant, int, VariantHasher, VariantComparator> &variant_map, Map<Node *, int> &node_map, Map<Node *, int> &nodepath_map) {
if (p_node != p_owner && p_node->get_owner() && p_node->get_owner() != p_owner && !p_owner->is_editable_instance(p_node->get_owner())) {
if (p_node != p_owner && p_node->get_owner() && p_node->get_owner() != p_owner && (!p_node->get_owner() || !p_node->get_owner()->is_editable_instance())) {
return OK;
}

Expand Down