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

Add a few buttons in Remote Scene Tree #65118

Merged
merged 1 commit into from
Oct 31, 2022
Merged
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
19 changes: 19 additions & 0 deletions editor/debugger/editor_debugger_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ EditorDebuggerNode::EditorDebuggerNode() {
remote_scene_tree = memnew(EditorDebuggerTree);
remote_scene_tree->connect("object_selected", callable_mp(this, &EditorDebuggerNode::_remote_object_requested));
remote_scene_tree->connect("save_node", callable_mp(this, &EditorDebuggerNode::_save_node_requested));
remote_scene_tree->connect("button_clicked", callable_mp(this, &EditorDebuggerNode::_remote_tree_button_pressed));
SceneTreeDock::get_singleton()->add_remote_tree_editor(remote_scene_tree);
SceneTreeDock::get_singleton()->connect("remote_tree_selected", callable_mp(this, &EditorDebuggerNode::request_remote_tree));

Expand Down Expand Up @@ -573,6 +574,24 @@ void EditorDebuggerNode::_remote_tree_updated(int p_debugger) {
remote_scene_tree->update_scene_tree(get_current_debugger()->get_remote_tree(), p_debugger);
}

void EditorDebuggerNode::_remote_tree_button_pressed(Object *p_item, int p_column, int p_id, MouseButton p_button) {
if (p_button != MouseButton::LEFT) {
return;
}

TreeItem *item = Object::cast_to<TreeItem>(p_item);
ERR_FAIL_COND(!item);

if (p_id == EditorDebuggerTree::BUTTON_SUBSCENE) {
remote_scene_tree->emit_signal(SNAME("open"), item->get_meta("scene_file_path"));
} else if (p_id == EditorDebuggerTree::BUTTON_VISIBILITY) {
ObjectID obj_id = item->get_metadata(0);
ERR_FAIL_COND(obj_id.is_null());
get_current_debugger()->update_remote_object(obj_id, "visible", !item->get_meta("visible"));
get_current_debugger()->request_remote_tree();
}
}

void EditorDebuggerNode::_remote_object_updated(ObjectID p_id, int p_debugger) {
if (p_debugger != tabs->get_current_tab()) {
return;
Expand Down
1 change: 1 addition & 0 deletions editor/debugger/editor_debugger_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ class EditorDebuggerNode : public MarginContainer {
void _debugger_wants_stop(int p_id);
void _debugger_changed(int p_tab);
void _remote_tree_updated(int p_debugger);
void _remote_tree_button_pressed(Object *p_item, int p_column, int p_id, MouseButton p_button);
void _remote_object_updated(ObjectID p_id, int p_debugger);
void _remote_object_property_updated(ObjectID p_id, const String &p_property, int p_debugger);
void _remote_object_requested(ObjectID p_id, int p_debugger);
Expand Down
32 changes: 30 additions & 2 deletions editor/debugger/editor_debugger_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ void EditorDebuggerTree::_notification(int p_what) {
void EditorDebuggerTree::_bind_methods() {
ADD_SIGNAL(MethodInfo("object_selected", PropertyInfo(Variant::INT, "object_id"), PropertyInfo(Variant::INT, "debugger")));
ADD_SIGNAL(MethodInfo("save_node", PropertyInfo(Variant::INT, "object_id"), PropertyInfo(Variant::STRING, "filename"), PropertyInfo(Variant::INT, "debugger")));
ADD_SIGNAL(MethodInfo("open"));
}

void EditorDebuggerTree::_scene_tree_selected() {
Expand Down Expand Up @@ -162,7 +163,7 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int
}
item->set_metadata(0, node.id);

// Set current item as collapsed if necessary (root is never collapsed)
// Set current item as collapsed if necessary (root is never collapsed).
if (parent) {
if (!unfold_cache.has(node.id)) {
item->set_collapsed(true);
Expand All @@ -178,7 +179,7 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int
}
} else { // Must use path
if (last_path == _get_path(item)) {
updating_scene_tree = false; // Force emission of new selection
updating_scene_tree = false; // Force emission of new selection.
item->select(0);
if (filter_changed) {
scroll_item = item;
Expand All @@ -187,6 +188,33 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int
}
}

// Add buttons.
const Color remote_button_color = Color(1, 1, 1, 0.8);
if (!node.scene_file_path.is_empty()) {
String node_scene_file_path = node.scene_file_path;
Ref<Texture2D> button_icon = get_theme_icon(SNAME("InstanceOptions"), SNAME("EditorIcons"));
String tooltip = vformat(TTR("This node has been instantiated from a PackedScene file:\n%s\nClick to open the original file in the Editor."), node_scene_file_path);

item->set_meta("scene_file_path", node_scene_file_path);
item->add_button(0, button_icon, BUTTON_SUBSCENE, false, tooltip);
item->set_button_color(0, item->get_button_count(0) - 1, remote_button_color);
}

if (node.view_flags & SceneDebuggerTree::RemoteNode::VIEW_HAS_VISIBLE_METHOD) {
bool node_visible = node.view_flags & SceneDebuggerTree::RemoteNode::VIEW_VISIBLE;
bool node_visible_in_tree = node.view_flags & SceneDebuggerTree::RemoteNode::VIEW_VISIBLE_IN_TREE;
Ref<Texture2D> button_icon = get_theme_icon(node_visible ? SNAME("GuiVisibilityVisible") : SNAME("GuiVisibilityHidden"), SNAME("EditorIcons"));
String tooltip = TTR("Toggle Visibility");

item->set_meta("visible", node_visible);
item->add_button(0, button_icon, BUTTON_VISIBILITY, false, tooltip);
if (ClassDB::is_parent_class(node.type_name, "CanvasItem") || ClassDB::is_parent_class(node.type_name, "Node3D")) {
item->set_button_color(0, item->get_button_count(0) - 1, node_visible_in_tree ? remote_button_color : Color(1, 1, 1, 0.6));
} else {
item->set_button_color(0, item->get_button_count(0) - 1, remote_button_color);
}
}

// Add in front of the parents stack if children are expected.
if (node.child_count) {
parents.push_front(Pair<TreeItem *, int>(item, node.child_count));
Expand Down
5 changes: 5 additions & 0 deletions editor/debugger/editor_debugger_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ class EditorDebuggerTree : public Tree {
void _notification(int p_what);

public:
enum Button {
BUTTON_SUBSCENE = 0,
BUTTON_VISIBILITY = 1,
};

virtual Variant get_drag_data(const Point2 &p_point) override;

String get_selected_path();
Expand Down
2 changes: 2 additions & 0 deletions editor/scene_tree_dock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1401,6 +1401,7 @@ void SceneTreeDock::_node_replace_owner(Node *p_base, Node *p_node, Node *p_root

void SceneTreeDock::_load_request(const String &p_path) {
EditorNode::get_singleton()->open_request(p_path);
_local_tree_selected();
}

void SceneTreeDock::_script_open_request(const Ref<Script> &p_script) {
Expand Down Expand Up @@ -3218,6 +3219,7 @@ void SceneTreeDock::add_remote_tree_editor(Control *p_remote) {
add_child(p_remote);
remote_tree = p_remote;
remote_tree->hide();
remote_tree->connect("open", callable_mp(this, &SceneTreeDock::_load_request));
}

void SceneTreeDock::show_remote_tree() {
Expand Down
42 changes: 34 additions & 8 deletions scene/debugger/scene_debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -548,14 +548,36 @@ SceneDebuggerTree::SceneDebuggerTree(Node *p_root) {
// Flatten tree into list, depth first, use stack to avoid recursion.
List<Node *> stack;
stack.push_back(p_root);
bool is_root = true;
const StringName &is_visible_sn = SNAME("is_visible");
const StringName &is_visible_in_tree_sn = SNAME("is_visible_in_tree");
while (stack.size()) {
Node *n = stack[0];
stack.pop_front();

int count = n->get_child_count();
nodes.push_back(RemoteNode(count, n->get_name(), n->get_class(), n->get_instance_id()));
for (int i = 0; i < count; i++) {
stack.push_front(n->get_child(count - i - 1));
}

int view_flags = 0;
if (is_root) {
// Prevent root window visibility from being changed.
is_root = false;
} else if (n->has_method(is_visible_sn)) {
const Variant visible = n->call(is_visible_sn);
if (visible.get_type() == Variant::BOOL) {
view_flags = RemoteNode::VIEW_HAS_VISIBLE_METHOD;
view_flags |= uint8_t(visible) * RemoteNode::VIEW_VISIBLE;
}
if (n->has_method(is_visible_in_tree_sn)) {
const Variant visible_in_tree = n->call(is_visible_in_tree_sn);
if (visible_in_tree.get_type() == Variant::BOOL) {
view_flags |= uint8_t(visible_in_tree) * RemoteNode::VIEW_VISIBLE_IN_TREE;
}
}
}
nodes.push_back(RemoteNode(count, n->get_name(), n->get_class(), n->get_instance_id(), n->get_scene_file_path(), view_flags));
}
}

Expand All @@ -565,19 +587,23 @@ void SceneDebuggerTree::serialize(Array &p_arr) {
p_arr.push_back(n.name);
p_arr.push_back(n.type_name);
p_arr.push_back(n.id);
p_arr.push_back(n.scene_file_path);
p_arr.push_back(n.view_flags);
}
}

void SceneDebuggerTree::deserialize(const Array &p_arr) {
int idx = 0;
while (p_arr.size() > idx) {
ERR_FAIL_COND(p_arr.size() < 4);
CHECK_TYPE(p_arr[idx], INT);
CHECK_TYPE(p_arr[idx + 1], STRING);
CHECK_TYPE(p_arr[idx + 2], STRING);
CHECK_TYPE(p_arr[idx + 3], INT);
nodes.push_back(RemoteNode(p_arr[idx], p_arr[idx + 1], p_arr[idx + 2], p_arr[idx + 3]));
idx += 4;
ERR_FAIL_COND(p_arr.size() < 6);
CHECK_TYPE(p_arr[idx], INT); // child_count.
CHECK_TYPE(p_arr[idx + 1], STRING); // name.
CHECK_TYPE(p_arr[idx + 2], STRING); // type_name.
CHECK_TYPE(p_arr[idx + 3], INT); // id.
CHECK_TYPE(p_arr[idx + 4], STRING); // scene_file_path.
CHECK_TYPE(p_arr[idx + 5], INT); // view_flags.
nodes.push_back(RemoteNode(p_arr[idx], p_arr[idx + 1], p_arr[idx + 2], p_arr[idx + 3], p_arr[idx + 4], p_arr[idx + 5]));
idx += 6;
}
}

Expand Down
13 changes: 12 additions & 1 deletion scene/debugger/scene_debugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,23 @@ class SceneDebuggerTree {
String name;
String type_name;
ObjectID id;
String scene_file_path;
uint8_t view_flags = 0;

RemoteNode(int p_child, const String &p_name, const String &p_type, ObjectID p_id) {
enum ViewFlags {
VIEW_HAS_VISIBLE_METHOD = 1 << 1,
VIEW_VISIBLE = 1 << 2,
VIEW_VISIBLE_IN_TREE = 1 << 3,
};

RemoteNode(int p_child, const String &p_name, const String &p_type, ObjectID p_id, const String p_scene_file_path, int p_view_flags) {
child_count = p_child;
name = p_name;
type_name = p_type;
id = p_id;

scene_file_path = p_scene_file_path;
view_flags = p_view_flags;
}

RemoteNode() {}
Expand Down