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

Allow multiple contextual editors opened at once #45085

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
133 changes: 98 additions & 35 deletions editor/editor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1888,8 +1888,8 @@ bool EditorNode::item_has_editor(Object *p_object) {
return editor_data.get_subeditors(p_object).size() > 0;
}

void EditorNode::edit_item_resource(RES p_resource) {
edit_item(p_resource.ptr());
void EditorNode::edit_item_resource(RES p_resource, Object *p_owner) {
edit_item(p_resource.ptr(), p_owner);
}

bool EditorNode::_is_class_editor_disabled_by_feature_profile(const StringName &p_class) {
Expand All @@ -1913,7 +1913,7 @@ bool EditorNode::_is_class_editor_disabled_by_feature_profile(const StringName &
return false;
}

void EditorNode::edit_item(Object *p_object) {
void EditorNode::edit_item(Object *p_object, Object *p_owner) {
Vector<EditorPlugin *> sub_plugins;

if (p_object) {
Expand All @@ -1923,11 +1923,22 @@ void EditorNode::edit_item(Object *p_object) {
sub_plugins = editor_data.get_subeditors(p_object);
}

if (!sub_plugins.is_empty()) {
Vector<EditorPluginList::ActiveEditor> sub_editors;
for (int i = 0; i < sub_plugins.size(); i++) {
EditorPluginList::ActiveEditor item;
item.plugin = sub_plugins[i];
item.owner = p_owner->get_instance_id();
sub_editors.append(item);
}

sub_editors.append_array(editor_plugins_over->get_plugins_list());
editor_plugins_over->verify_top_editors(sub_editors);

if (!sub_editors.is_empty()) {
bool same = true;
if (sub_plugins.size() == editor_plugins_over->get_plugins_list().size()) {
for (int i = 0; i < sub_plugins.size(); i++) {
if (sub_plugins[i] != editor_plugins_over->get_plugins_list()[i]) {
if (sub_editors.size() == editor_plugins_over->get_plugins_list().size()) {
for (int i = 0; i < sub_editors.size(); i++) {
if (sub_editors[i].plugin != editor_plugins_over->get_plugins_list()[i].plugin) {
same = false;
}
}
Expand All @@ -1936,12 +1947,12 @@ void EditorNode::edit_item(Object *p_object) {
}
if (!same) {
_display_top_editors(false);
_set_top_editors(sub_plugins);
editor_plugins_over->set_plugins_list(sub_editors);
}
_set_editing_top_editors(p_object);
_display_top_editors(true);
} else {
hide_top_editors();
hide_unused_editors();
}
}

Expand Down Expand Up @@ -1979,20 +1990,20 @@ void EditorNode::_save_default_environment() {
}
}

void EditorNode::hide_top_editors() {
_display_top_editors(false);

editor_plugins_over->clear();
void EditorNode::hide_unused_editors() {
Vector<EditorPluginList::ActiveEditor> prev_editors(editor_plugins_over->get_plugins_list());
editor_plugins_over->verify_top_editors(editor_plugins_over->get_plugins_list());
for (int i = 0; i < prev_editors.size(); i++) {
if (!editor_plugins_over->get_plugins_list().has(prev_editors[i])) {
prev_editors[i].plugin->make_visible(false);
}
}
}

void EditorNode::_display_top_editors(bool p_display) {
editor_plugins_over->make_visible(p_display);
}

void EditorNode::_set_top_editors(Vector<EditorPlugin *> p_editor_plugins_over) {
editor_plugins_over->set_plugins_list(p_editor_plugins_over);
}

void EditorNode::_set_editing_top_editors(Object *p_current_object) {
editor_plugins_over->edit(p_current_object);
}
Expand Down Expand Up @@ -2182,14 +2193,25 @@ void EditorNode::_edit_current() {
sub_plugins = editor_data.get_subeditors(current_obj);
}

if (!sub_plugins.is_empty()) {
Vector<EditorPluginList::ActiveEditor> sub_editors;
for (int i = 0; i < sub_plugins.size(); i++) {
EditorPluginList::ActiveEditor item;
item.plugin = sub_plugins[i];
item.owner = current_obj->get_instance_id();
sub_editors.append(item);
}

sub_editors.append_array(editor_plugins_over->get_plugins_list());
editor_plugins_over->verify_top_editors(sub_editors);

if (!sub_editors.is_empty()) {
_display_top_editors(false);

_set_top_editors(sub_plugins);
editor_plugins_over->set_plugins_list(sub_editors);
_set_editing_top_editors(current_obj);
_display_top_editors(true);
} else if (!editor_plugins_over->get_plugins_list().is_empty()) {
hide_top_editors();
hide_unused_editors();
}
}

Expand Down Expand Up @@ -3085,10 +3107,11 @@ void EditorNode::remove_editor_plugin(EditorPlugin *p_editor, bool p_config_chan
if (p_config_changed) {
p_editor->disable_plugin();
}
singleton->editor_plugins_over->get_plugins_list().erase(p_editor);

singleton->editor_plugins_over->remove_plugin(p_editor, nullptr);
singleton->remove_child(p_editor);
singleton->editor_data.remove_editor_plugin(p_editor);
singleton->get_editor_plugins_force_input_forwarding()->remove_plugin(p_editor);
singleton->get_editor_plugins_force_input_forwarding()->remove_plugin(p_editor, nullptr);
}

void EditorNode::_update_addon_config() {
Expand Down Expand Up @@ -7001,23 +7024,51 @@ EditorNode::~EditorNode() {
* EDITOR PLUGIN LIST
*/

void EditorPluginList::verify_top_editors(Vector<ActiveEditor> &p_editors) {
int i = 0;
while (i < p_editors.size()) {
bool discard = true;
Object *owner = ObjectDB::get_instance(p_editors[i].owner);

if (discard) {
EditorPropertyResource *property = Object::cast_to<EditorPropertyResource>(owner);
if (property) {
discard = !property->is_visible_in_tree() || !property->get_edited_object()->editor_is_section_unfolded(property->get_edited_property());
}
}

if (discard) {
Node *node = Object::cast_to<Node>(owner);
if (node) {
discard = (EditorNode::get_singleton()->get_scene_tree_dock()->get_last_pushed_item() != node);
}
}

if (discard) {
p_editors.remove(i);
} else {
i++;
}
}
}

void EditorPluginList::make_visible(bool p_visible) {
for (int i = 0; i < plugins_list.size(); i++) {
plugins_list[i]->make_visible(p_visible);
plugins_list[i].plugin->make_visible(p_visible);
}
}

void EditorPluginList::edit(Object *p_object) {
for (int i = 0; i < plugins_list.size(); i++) {
plugins_list[i]->edit(p_object);
plugins_list[i].plugin->edit(p_object);
}
}

bool EditorPluginList::forward_gui_input(const Ref<InputEvent> &p_event) {
bool discard = false;

for (int i = 0; i < plugins_list.size(); i++) {
if (plugins_list[i]->forward_canvas_gui_input(p_event)) {
if (plugins_list[i].plugin->forward_canvas_gui_input(p_event)) {
discard = true;
}
}
Expand All @@ -7029,11 +7080,11 @@ bool EditorPluginList::forward_spatial_gui_input(Camera3D *p_camera, const Ref<I
bool discard = false;

for (int i = 0; i < plugins_list.size(); i++) {
if ((!serve_when_force_input_enabled) && plugins_list[i]->is_input_event_forwarding_always_enabled()) {
if ((!serve_when_force_input_enabled) && plugins_list[i].plugin->is_input_event_forwarding_always_enabled()) {
continue;
}

if (plugins_list[i]->forward_spatial_gui_input(p_camera, p_event)) {
if (plugins_list[i].plugin->forward_spatial_gui_input(p_camera, p_event)) {
discard = true;
}
}
Expand All @@ -7043,34 +7094,46 @@ bool EditorPluginList::forward_spatial_gui_input(Camera3D *p_camera, const Ref<I

void EditorPluginList::forward_canvas_draw_over_viewport(Control *p_overlay) {
for (int i = 0; i < plugins_list.size(); i++) {
plugins_list[i]->forward_canvas_draw_over_viewport(p_overlay);
plugins_list[i].plugin->forward_canvas_draw_over_viewport(p_overlay);
}
}

void EditorPluginList::forward_canvas_force_draw_over_viewport(Control *p_overlay) {
for (int i = 0; i < plugins_list.size(); i++) {
plugins_list[i]->forward_canvas_force_draw_over_viewport(p_overlay);
plugins_list[i].plugin->forward_canvas_force_draw_over_viewport(p_overlay);
}
}

void EditorPluginList::forward_spatial_draw_over_viewport(Control *p_overlay) {
for (int i = 0; i < plugins_list.size(); i++) {
plugins_list[i]->forward_spatial_draw_over_viewport(p_overlay);
plugins_list[i].plugin->forward_spatial_draw_over_viewport(p_overlay);
}
}

void EditorPluginList::forward_spatial_force_draw_over_viewport(Control *p_overlay) {
for (int i = 0; i < plugins_list.size(); i++) {
plugins_list[i]->forward_spatial_force_draw_over_viewport(p_overlay);
plugins_list[i].plugin->forward_spatial_force_draw_over_viewport(p_overlay);
}
}

void EditorPluginList::add_plugin(EditorPlugin *p_plugin) {
plugins_list.push_back(p_plugin);
void EditorPluginList::add_plugin(EditorPlugin *p_plugin, Object *p_owner) {
ActiveEditor entry;
entry.plugin = p_plugin;
if (p_owner) {
entry.owner = p_owner->get_instance_id();
}
plugins_list.push_back(entry);
}

void EditorPluginList::remove_plugin(EditorPlugin *p_plugin) {
plugins_list.erase(p_plugin);
void EditorPluginList::remove_plugin(EditorPlugin *p_plugin, Object *p_owner) {
int i = 0;
while (i < plugins_list.size()) {
if (plugins_list[i].plugin == p_plugin && (!p_owner || plugins_list[i].owner == p_owner->get_instance_id())) {
plugins_list.remove(i);
} else {
i++;
}
}
}

bool EditorPluginList::is_empty() {
Expand Down
28 changes: 17 additions & 11 deletions editor/editor_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,6 @@ class EditorNode : public Node {
void _instance_request(const Vector<String> &p_files);

void _display_top_editors(bool p_display);
void _set_top_editors(Vector<EditorPlugin *> p_editor_plugins_over);
void _set_editing_top_editors(Object *p_current_object);

void _quick_opened();
Expand Down Expand Up @@ -726,10 +725,10 @@ class EditorNode : public Node {
static HBoxContainer *get_menu_hb() { return singleton->menu_hb; }

void push_item(Object *p_object, const String &p_property = "", bool p_inspector_only = false);
void edit_item(Object *p_object);
void edit_item_resource(RES p_resource);
void edit_item(Object *p_object, Object *p_owner = nullptr);
void edit_item_resource(RES p_resource, Object *p_owner);
bool item_has_editor(Object *p_object);
void hide_top_editors();
void hide_unused_editors();

void select_editor_by_name(const String &p_name);

Expand Down Expand Up @@ -892,15 +891,19 @@ struct EditorProgress {
};

class EditorPluginList : public Object {
private:
Vector<EditorPlugin *> plugins_list;

public:
void set_plugins_list(Vector<EditorPlugin *> p_plugins_list) {
struct ActiveEditor {
EditorPlugin *plugin;
ObjectID owner;
bool operator==(const ActiveEditor ae) const { return plugin == ae.plugin && owner == ae.owner; }
};
void verify_top_editors(Vector<ActiveEditor> &p_editors);

void set_plugins_list(Vector<ActiveEditor> p_plugins_list) {
plugins_list = p_plugins_list;
}

Vector<EditorPlugin *> &get_plugins_list() {
Vector<ActiveEditor> &get_plugins_list() {
return plugins_list;
}

Expand All @@ -912,13 +915,16 @@ class EditorPluginList : public Object {
bool forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event, bool serve_when_force_input_enabled);
void forward_spatial_draw_over_viewport(Control *p_overlay);
void forward_spatial_force_draw_over_viewport(Control *p_overlay);
void add_plugin(EditorPlugin *p_plugin);
void remove_plugin(EditorPlugin *p_plugin);
void add_plugin(EditorPlugin *p_plugin, Object *p_owner);
void remove_plugin(EditorPlugin *p_plugin, Object *p_owner);
void clear();
bool is_empty();

EditorPluginList();
~EditorPluginList();

private:
Vector<ActiveEditor> plugins_list;
};

struct EditorProgressBG {
Expand Down
4 changes: 2 additions & 2 deletions editor/editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -507,13 +507,13 @@ void EditorPlugin::remove_tool_menu_item(const String &p_name) {
void EditorPlugin::set_input_event_forwarding_always_enabled() {
input_event_forwarding_always_enabled = true;
EditorPluginList *always_input_forwarding_list = EditorNode::get_singleton()->get_editor_plugins_force_input_forwarding();
always_input_forwarding_list->add_plugin(this);
always_input_forwarding_list->add_plugin(this, nullptr);
}

void EditorPlugin::set_force_draw_over_forwarding_enabled() {
force_draw_over_forwarding_enabled = true;
EditorPluginList *always_draw_over_forwarding_list = EditorNode::get_singleton()->get_editor_plugins_force_over();
always_draw_over_forwarding_list->add_plugin(this);
always_draw_over_forwarding_list->add_plugin(this, nullptr);
}

void EditorPlugin::notify_scene_changed(const Node *scn_root) {
Expand Down
16 changes: 10 additions & 6 deletions editor/editor_properties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2828,24 +2828,30 @@ void EditorPropertyResource::_button_input(const Ref<InputEvent> &p_event) {
void EditorPropertyResource::_open_editor_pressed() {
RES res = get_edited_object()->get(get_edited_property());
if (res.is_valid()) {
EditorNode::get_singleton()->call_deferred("edit_item_resource", res); //may clear the editor so do it deferred
EditorNode::get_singleton()->call_deferred("edit_item_resource", res, this); //may clear the editor so do it deferred
}
}

void EditorPropertyResource::_fold_other_editors(Object *p_self) {
if (this == p_self) {
return;
}
EditorPropertyResource *self_prop = Object::cast_to<EditorPropertyResource>(p_self);
if (!self_prop) {
return;
}

RES self_res = self_prop->get_edited_object()->get(self_prop->get_edited_property());
RES res = get_edited_object()->get(get_edited_property());

if (!res.is_valid()) {
return;
}

bool use_editor = false;
for (int i = 0; i < EditorNode::get_editor_data().get_editor_plugin_count(); i++) {
EditorPlugin *ep = EditorNode::get_editor_data().get_editor_plugin(i);
if (ep->handles(res.ptr())) {
if (ep->handles(res.ptr()) && ep->handles(self_res.ptr())) {
use_editor = true;
}
}
Expand Down Expand Up @@ -2962,10 +2968,8 @@ void EditorPropertyResource::update_property() {
memdelete(sub_inspector_vbox);
sub_inspector = nullptr;
sub_inspector_vbox = nullptr;
if (opened_editor) {
EditorNode::get_singleton()->hide_top_editors();
opened_editor = false;
}
opened_editor = false;
EditorNode::get_singleton()->hide_unused_editors();
_update_property_bg();
}
}
Expand Down
Loading