Merge pull request #58395 from Geometror/editor-node-data-cleanup

This commit is contained in:
Rémi Verschelde 2022-03-30 23:41:36 +02:00 committed by GitHub
commit b7850bb1e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 646 additions and 701 deletions

View File

@ -3383,7 +3383,7 @@ Node *AnimationTrackEditor::get_root() const {
void AnimationTrackEditor::update_keying() { void AnimationTrackEditor::update_keying() {
bool keying_enabled = false; bool keying_enabled = false;
EditorHistory *editor_history = EditorNode::get_singleton()->get_editor_history(); EditorSelectionHistory *editor_history = EditorNode::get_singleton()->get_editor_selection_history();
if (is_visible_in_tree() && animation.is_valid() && editor_history->get_path_size() > 0) { if (is_visible_in_tree() && animation.is_valid() && editor_history->get_path_size() > 0) {
Object *obj = ObjectDB::get_instance(editor_history->get_path_object(0)); Object *obj = ObjectDB::get_instance(editor_history->get_path_object(0));
keying_enabled = Object::cast_to<Node>(obj) != nullptr; keying_enabled = Object::cast_to<Node>(obj) != nullptr;
@ -3776,7 +3776,7 @@ void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_p
return; return;
} }
EditorHistory *history = EditorNode::get_singleton()->get_editor_history(); EditorSelectionHistory *history = EditorNode::get_singleton()->get_editor_selection_history();
for (int i = 1; i < history->get_path_size(); i++) { for (int i = 1; i < history->get_path_size(); i++) {
String prop = history->get_path_property(i); String prop = history->get_path_property(i);
ERR_FAIL_COND(prop.is_empty()); ERR_FAIL_COND(prop.is_empty());
@ -3856,7 +3856,7 @@ void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_p
} }
void AnimationTrackEditor::insert_value_key(const String &p_property, const Variant &p_value, bool p_advance) { void AnimationTrackEditor::insert_value_key(const String &p_property, const Variant &p_value, bool p_advance) {
EditorHistory *history = EditorNode::get_singleton()->get_editor_history(); EditorSelectionHistory *history = EditorNode::get_singleton()->get_editor_selection_history();
ERR_FAIL_COND(!root); ERR_FAIL_COND(!root);
// Let's build a node path. // Let's build a node path.

View File

@ -206,7 +206,7 @@ ObjectID EditorDebuggerInspector::add_object(const Array &p_arr) {
void EditorDebuggerInspector::clear_cache() { void EditorDebuggerInspector::clear_cache() {
for (const KeyValue<ObjectID, EditorDebuggerRemoteObject *> &E : remote_objects) { for (const KeyValue<ObjectID, EditorDebuggerRemoteObject *> &E : remote_objects) {
EditorNode *editor = EditorNode::get_singleton(); EditorNode *editor = EditorNode::get_singleton();
if (editor->get_editor_history()->get_current() == E.value->get_instance_id()) { if (editor->get_editor_selection_history()->get_current() == E.value->get_instance_id()) {
editor->push_item(nullptr); editor->push_item(nullptr);
} }
memdelete(E.value); memdelete(E.value);

View File

@ -181,7 +181,7 @@ void EditorDebuggerNode::_bind_methods() {
} }
EditorDebuggerRemoteObject *EditorDebuggerNode::get_inspected_remote_object() { EditorDebuggerRemoteObject *EditorDebuggerNode::get_inspected_remote_object() {
return Object::cast_to<EditorDebuggerRemoteObject>(ObjectDB::get_instance(EditorNode::get_singleton()->get_editor_history()->get_current())); return Object::cast_to<EditorDebuggerRemoteObject>(ObjectDB::get_instance(EditorNode::get_singleton()->get_editor_selection_history()->get_current()));
} }
ScriptEditorDebugger *EditorDebuggerNode::get_debugger(int p_id) const { ScriptEditorDebugger *EditorDebuggerNode::get_debugger(int p_id) const {

View File

@ -38,12 +38,13 @@
#include "editor/plugins/script_editor_plugin.h" #include "editor/plugins/script_editor_plugin.h"
#include "scene/resources/packed_scene.h" #include "scene/resources/packed_scene.h"
void EditorHistory::cleanup_history() { void EditorSelectionHistory::cleanup_history() {
for (int i = 0; i < history.size(); i++) { for (int i = 0; i < history.size(); i++) {
bool fail = false; bool fail = false;
for (int j = 0; j < history[i].path.size(); j++) { for (int j = 0; j < history[i].path.size(); j++) {
if (!history[i].path[j].ref.is_null()) { if (!history[i].path[j].ref.is_null()) {
// Reference is not null - object still alive.
continue; continue;
} }
@ -51,21 +52,16 @@ void EditorHistory::cleanup_history() {
if (obj) { if (obj) {
Node *n = Object::cast_to<Node>(obj); Node *n = Object::cast_to<Node>(obj);
if (n && n->is_inside_tree()) { if (n && n->is_inside_tree()) {
// Node valid and inside tree - object still alive.
continue; continue;
} }
if (!n) { // Possibly still alive if (!n) {
// Node possibly still alive.
continue; continue;
} }
} } // Else: object not valid - not alive.
if (j <= history[i].level) {
//before or equal level, complete fail
fail = true;
} else {
//after level, clip
history.write[i].path.resize(j);
}
fail = true;
break; break;
} }
@ -75,16 +71,16 @@ void EditorHistory::cleanup_history() {
} }
} }
if (current >= history.size()) { if (current_elem_idx >= history.size()) {
current = history.size() - 1; current_elem_idx = history.size() - 1;
} }
} }
void EditorHistory::_add_object(ObjectID p_object, const String &p_property, int p_level_change, bool p_inspector_only) { void EditorSelectionHistory::add_object(ObjectID p_object, const String &p_property, bool p_inspector_only) {
Object *obj = ObjectDB::get_instance(p_object); Object *obj = ObjectDB::get_instance(p_object);
ERR_FAIL_COND(!obj); ERR_FAIL_COND(!obj);
RefCounted *r = Object::cast_to<RefCounted>(obj); RefCounted *r = Object::cast_to<RefCounted>(obj);
Obj o; _Object o;
if (r) { if (r) {
o.ref = REF(r); o.ref = REF(r);
} }
@ -92,86 +88,64 @@ void EditorHistory::_add_object(ObjectID p_object, const String &p_property, int
o.property = p_property; o.property = p_property;
o.inspector_only = p_inspector_only; o.inspector_only = p_inspector_only;
History h; bool has_prev = current_elem_idx >= 0 && current_elem_idx < history.size();
bool has_prev = current >= 0 && current < history.size();
if (has_prev) { if (has_prev) {
history.resize(current + 1); //clip history to next history.resize(current_elem_idx + 1); // Clip history to next.
} }
HistoryElement h;
if (!p_property.is_empty() && has_prev) { if (!p_property.is_empty() && has_prev) {
//add a sub property // Add a sub property.
History &pr = history.write[current]; HistoryElement &prev_element = history.write[current_elem_idx];
h = pr; h = prev_element;
h.path.resize(h.level + 1); h.path.resize(h.level + 1);
h.path.push_back(o); h.path.push_back(o);
h.level++; h.level++;
} else if (p_level_change != -1 && has_prev) {
//add a sub property
History &pr = history.write[current];
h = pr;
ERR_FAIL_INDEX(p_level_change, h.path.size());
h.level = p_level_change;
} else { } else {
//add a new node // Create a new history item.
h.path.push_back(o); h.path.push_back(o);
h.level = 0; h.level = 0;
} }
history.push_back(h); history.push_back(h);
current++; current_elem_idx++;
} }
void EditorHistory::add_object_inspector_only(ObjectID p_object) { int EditorSelectionHistory::get_history_len() {
_add_object(p_object, "", -1, true);
}
void EditorHistory::add_object(ObjectID p_object) {
_add_object(p_object, "", -1);
}
void EditorHistory::add_object(ObjectID p_object, const String &p_subprop) {
_add_object(p_object, p_subprop, -1);
}
void EditorHistory::add_object(ObjectID p_object, int p_relevel) {
_add_object(p_object, "", p_relevel);
}
int EditorHistory::get_history_len() {
return history.size(); return history.size();
} }
int EditorHistory::get_history_pos() { int EditorSelectionHistory::get_history_pos() {
return current; return current_elem_idx;
} }
bool EditorHistory::is_history_obj_inspector_only(int p_obj) const { bool EditorSelectionHistory::is_history_obj_inspector_only(int p_obj) const {
ERR_FAIL_INDEX_V(p_obj, history.size(), false); ERR_FAIL_INDEX_V(p_obj, history.size(), false);
ERR_FAIL_INDEX_V(history[p_obj].level, history[p_obj].path.size(), false); ERR_FAIL_INDEX_V(history[p_obj].level, history[p_obj].path.size(), false);
return history[p_obj].path[history[p_obj].level].inspector_only; return history[p_obj].path[history[p_obj].level].inspector_only;
} }
ObjectID EditorHistory::get_history_obj(int p_obj) const { ObjectID EditorSelectionHistory::get_history_obj(int p_obj) const {
ERR_FAIL_INDEX_V(p_obj, history.size(), ObjectID()); ERR_FAIL_INDEX_V(p_obj, history.size(), ObjectID());
ERR_FAIL_INDEX_V(history[p_obj].level, history[p_obj].path.size(), ObjectID()); ERR_FAIL_INDEX_V(history[p_obj].level, history[p_obj].path.size(), ObjectID());
return history[p_obj].path[history[p_obj].level].object; return history[p_obj].path[history[p_obj].level].object;
} }
bool EditorHistory::is_at_beginning() const { bool EditorSelectionHistory::is_at_beginning() const {
return current <= 0; return current_elem_idx <= 0;
} }
bool EditorHistory::is_at_end() const { bool EditorSelectionHistory::is_at_end() const {
return ((current + 1) >= history.size()); return ((current_elem_idx + 1) >= history.size());
} }
bool EditorHistory::next() { bool EditorSelectionHistory::next() {
cleanup_history(); cleanup_history();
if ((current + 1) < history.size()) { if ((current_elem_idx + 1) < history.size()) {
current++; current_elem_idx++;
} else { } else {
return false; return false;
} }
@ -179,11 +153,11 @@ bool EditorHistory::next() {
return true; return true;
} }
bool EditorHistory::previous() { bool EditorSelectionHistory::previous() {
cleanup_history(); cleanup_history();
if (current > 0) { if (current_elem_idx > 0) {
current--; current_elem_idx--;
} else { } else {
return false; return false;
} }
@ -191,76 +165,63 @@ bool EditorHistory::previous() {
return true; return true;
} }
bool EditorHistory::is_current_inspector_only() const { bool EditorSelectionHistory::is_current_inspector_only() const {
if (current < 0 || current >= history.size()) { if (current_elem_idx < 0 || current_elem_idx >= history.size()) {
return false; return false;
} }
const History &h = history[current]; const HistoryElement &h = history[current_elem_idx];
return h.path[h.level].inspector_only; return h.path[h.level].inspector_only;
} }
ObjectID EditorHistory::get_current() { ObjectID EditorSelectionHistory::get_current() {
if (current < 0 || current >= history.size()) { if (current_elem_idx < 0 || current_elem_idx >= history.size()) {
return ObjectID(); return ObjectID();
} }
History &h = history.write[current]; Object *obj = ObjectDB::get_instance(get_history_obj(current_elem_idx));
Object *obj = ObjectDB::get_instance(h.path[h.level].object); return obj ? obj->get_instance_id() : ObjectID();
if (!obj) {
return ObjectID();
}
return obj->get_instance_id();
} }
int EditorHistory::get_path_size() const { int EditorSelectionHistory::get_path_size() const {
if (current < 0 || current >= history.size()) { if (current_elem_idx < 0 || current_elem_idx >= history.size()) {
return 0; return 0;
} }
const History &h = history[current]; return history[current_elem_idx].path.size();
return h.path.size();
} }
ObjectID EditorHistory::get_path_object(int p_index) const { ObjectID EditorSelectionHistory::get_path_object(int p_index) const {
if (current < 0 || current >= history.size()) { if (current_elem_idx < 0 || current_elem_idx >= history.size()) {
return ObjectID(); return ObjectID();
} }
const History &h = history[current]; ERR_FAIL_INDEX_V(p_index, history[current_elem_idx].path.size(), ObjectID());
ERR_FAIL_INDEX_V(p_index, h.path.size(), ObjectID()); Object *obj = ObjectDB::get_instance(history[current_elem_idx].path[p_index].object);
return obj ? obj->get_instance_id() : ObjectID();
Object *obj = ObjectDB::get_instance(h.path[p_index].object);
if (!obj) {
return ObjectID();
}
return obj->get_instance_id();
} }
String EditorHistory::get_path_property(int p_index) const { String EditorSelectionHistory::get_path_property(int p_index) const {
if (current < 0 || current >= history.size()) { if (current_elem_idx < 0 || current_elem_idx >= history.size()) {
return ""; return "";
} }
const History &h = history[current]; ERR_FAIL_INDEX_V(p_index, history[current_elem_idx].path.size(), "");
return history[current_elem_idx].path[p_index].property;
ERR_FAIL_INDEX_V(p_index, h.path.size(), "");
return h.path[p_index].property;
} }
void EditorHistory::clear() { void EditorSelectionHistory::clear() {
history.clear(); history.clear();
current = -1; current_elem_idx = -1;
} }
EditorHistory::EditorHistory() { EditorSelectionHistory::EditorSelectionHistory() {
current = -1; current_elem_idx = -1;
} }
////////////////////////////////////////////////////////////
EditorPlugin *EditorData::get_editor(Object *p_object) { EditorPlugin *EditorData::get_editor(Object *p_object) {
// We need to iterate backwards so that we can check user-created plugins first. // We need to iterate backwards so that we can check user-created plugins first.
// Otherwise, it would not be possible for plugins to handle CanvasItem and Spatial nodes. // Otherwise, it would not be possible for plugins to handle CanvasItem and Spatial nodes.
@ -636,14 +597,14 @@ bool EditorData::check_and_update_scene(int p_idx) {
EditorProgress ep("update_scene", TTR("Updating Scene"), 2); EditorProgress ep("update_scene", TTR("Updating Scene"), 2);
ep.step(TTR("Storing local changes..."), 0); ep.step(TTR("Storing local changes..."), 0);
//pack first, so it stores diffs to previous version of saved scene // Pack first, so it stores diffs to previous version of saved scene.
Error err = pscene->pack(edited_scene[p_idx].root); Error err = pscene->pack(edited_scene[p_idx].root);
ERR_FAIL_COND_V(err != OK, false); ERR_FAIL_COND_V(err != OK, false);
ep.step(TTR("Updating scene..."), 1); ep.step(TTR("Updating scene..."), 1);
Node *new_scene = pscene->instantiate(PackedScene::GEN_EDIT_STATE_MAIN); Node *new_scene = pscene->instantiate(PackedScene::GEN_EDIT_STATE_MAIN);
ERR_FAIL_COND_V(!new_scene, false); ERR_FAIL_COND_V(!new_scene, false);
//transfer selection // Transfer selection.
List<Node *> new_selection; List<Node *> new_selection;
for (const Node *E : edited_scene.write[p_idx].selection) { for (const Node *E : edited_scene.write[p_idx].selection) {
NodePath p = edited_scene[p_idx].root->get_path_to(E); NodePath p = edited_scene[p_idx].root->get_path_to(E);
@ -675,7 +636,6 @@ int EditorData::get_edited_scene() const {
void EditorData::set_edited_scene(int p_idx) { void EditorData::set_edited_scene(int p_idx) {
ERR_FAIL_INDEX(p_idx, edited_scene.size()); ERR_FAIL_INDEX(p_idx, edited_scene.size());
current_edited_scene = p_idx; current_edited_scene = p_idx;
//swap
} }
Node *EditorData::get_edited_scene_root(int p_idx) { Node *EditorData::get_edited_scene_root(int p_idx) {
@ -850,23 +810,23 @@ NodePath EditorData::get_edited_scene_live_edit_root() {
return edited_scene[current_edited_scene].live_edit_root; return edited_scene[current_edited_scene].live_edit_root;
} }
void EditorData::save_edited_scene_state(EditorSelection *p_selection, EditorHistory *p_history, const Dictionary &p_custom) { void EditorData::save_edited_scene_state(EditorSelection *p_selection, EditorSelectionHistory *p_history, const Dictionary &p_custom) {
ERR_FAIL_INDEX(current_edited_scene, edited_scene.size()); ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
EditedScene &es = edited_scene.write[current_edited_scene]; EditedScene &es = edited_scene.write[current_edited_scene];
es.selection = p_selection->get_full_selected_node_list(); es.selection = p_selection->get_full_selected_node_list();
es.history_current = p_history->current; es.history_current = p_history->current_elem_idx;
es.history_stored = p_history->history; es.history_stored = p_history->history;
es.editor_states = get_editor_states(); es.editor_states = get_editor_states();
es.custom_state = p_custom; es.custom_state = p_custom;
} }
Dictionary EditorData::restore_edited_scene_state(EditorSelection *p_selection, EditorHistory *p_history) { Dictionary EditorData::restore_edited_scene_state(EditorSelection *p_selection, EditorSelectionHistory *p_history) {
ERR_FAIL_INDEX_V(current_edited_scene, edited_scene.size(), Dictionary()); ERR_FAIL_INDEX_V(current_edited_scene, edited_scene.size(), Dictionary());
EditedScene &es = edited_scene.write[current_edited_scene]; EditedScene &es = edited_scene.write[current_edited_scene];
p_history->current = es.history_current; p_history->current_elem_idx = es.history_current;
p_history->history = es.history_stored; p_history->history = es.history_stored;
p_selection->clear(); p_selection->clear();
@ -1033,12 +993,11 @@ void EditorData::script_class_load_icon_paths() {
EditorData::EditorData() { EditorData::EditorData() {
current_edited_scene = -1; current_edited_scene = -1;
//load_imported_scenes_from_globals();
script_class_load_icon_paths(); script_class_load_icon_paths();
} }
/////////// ///////////////////////////////////////////////////////////////////////////////
void EditorSelection::_node_removed(Node *p_node) { void EditorSelection::_node_removed(Node *p_node) {
if (!selection.has(p_node)) { if (!selection.has(p_node)) {
return; return;
@ -1050,7 +1009,7 @@ void EditorSelection::_node_removed(Node *p_node) {
} }
selection.erase(p_node); selection.erase(p_node);
changed = true; changed = true;
nl_changed = true; node_list_changed = true;
} }
void EditorSelection::add_node(Node *p_node) { void EditorSelection::add_node(Node *p_node) {
@ -1061,7 +1020,7 @@ void EditorSelection::add_node(Node *p_node) {
} }
changed = true; changed = true;
nl_changed = true; node_list_changed = true;
Object *meta = nullptr; Object *meta = nullptr;
for (Object *E : editor_plugins) { for (Object *E : editor_plugins) {
meta = E->call("_get_editor_data", p_node); meta = E->call("_get_editor_data", p_node);
@ -1072,32 +1031,92 @@ void EditorSelection::add_node(Node *p_node) {
selection[p_node] = meta; selection[p_node] = meta;
p_node->connect("tree_exiting", callable_mp(this, &EditorSelection::_node_removed), varray(p_node), CONNECT_ONESHOT); p_node->connect("tree_exiting", callable_mp(this, &EditorSelection::_node_removed), varray(p_node), CONNECT_ONESHOT);
//emit_signal(SNAME("selection_changed"));
} }
void EditorSelection::remove_node(Node *p_node) { void EditorSelection::remove_node(Node *p_node) {
ERR_FAIL_NULL(p_node); ERR_FAIL_NULL(p_node);
if (!selection.has(p_node)) { if (!selection.has(p_node)) {
return; return;
} }
changed = true; changed = true;
nl_changed = true; node_list_changed = true;
Object *meta = selection[p_node]; Object *meta = selection[p_node];
if (meta) { if (meta) {
memdelete(meta); memdelete(meta);
} }
selection.erase(p_node); selection.erase(p_node);
p_node->disconnect("tree_exiting", callable_mp(this, &EditorSelection::_node_removed)); p_node->disconnect("tree_exiting", callable_mp(this, &EditorSelection::_node_removed));
//emit_signal(SNAME("selection_changed"));
} }
bool EditorSelection::is_selected(Node *p_node) const { bool EditorSelection::is_selected(Node *p_node) const {
return selection.has(p_node); return selection.has(p_node);
} }
void EditorSelection::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear"), &EditorSelection::clear);
ClassDB::bind_method(D_METHOD("add_node", "node"), &EditorSelection::add_node);
ClassDB::bind_method(D_METHOD("remove_node", "node"), &EditorSelection::remove_node);
ClassDB::bind_method(D_METHOD("get_selected_nodes"), &EditorSelection::get_selected_nodes);
ClassDB::bind_method(D_METHOD("get_transformable_selected_nodes"), &EditorSelection::_get_transformable_selected_nodes);
ClassDB::bind_method(D_METHOD("_emit_change"), &EditorSelection::_emit_change);
ADD_SIGNAL(MethodInfo("selection_changed"));
}
void EditorSelection::add_editor_plugin(Object *p_object) {
editor_plugins.push_back(p_object);
}
void EditorSelection::_update_node_list() {
if (!node_list_changed) {
return;
}
selected_node_list.clear();
// 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;
parent = parent->get_parent();
bool skip = false;
while (parent) {
if (selection.has(parent)) {
skip = true;
break;
}
parent = parent->get_parent();
}
if (skip) {
continue;
}
selected_node_list.push_back(E.key);
}
node_list_changed = true;
}
void EditorSelection::update() {
_update_node_list();
if (!changed) {
return;
}
changed = false;
if (!emitted) {
emitted = true;
call_deferred(SNAME("_emit_change"));
}
}
void EditorSelection::_emit_change() {
emit_signal(SNAME("selection_changed"));
emitted = false;
}
Array EditorSelection::_get_transformable_selected_nodes() { Array EditorSelection::_get_transformable_selected_nodes() {
Array ret; Array ret;
@ -1118,71 +1137,11 @@ TypedArray<Node> EditorSelection::get_selected_nodes() {
return ret; return ret;
} }
void EditorSelection::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear"), &EditorSelection::clear);
ClassDB::bind_method(D_METHOD("add_node", "node"), &EditorSelection::add_node);
ClassDB::bind_method(D_METHOD("remove_node", "node"), &EditorSelection::remove_node);
ClassDB::bind_method(D_METHOD("get_selected_nodes"), &EditorSelection::get_selected_nodes);
ClassDB::bind_method(D_METHOD("get_transformable_selected_nodes"), &EditorSelection::_get_transformable_selected_nodes);
ClassDB::bind_method(D_METHOD("_emit_change"), &EditorSelection::_emit_change);
ADD_SIGNAL(MethodInfo("selection_changed"));
}
void EditorSelection::add_editor_plugin(Object *p_object) {
editor_plugins.push_back(p_object);
}
void EditorSelection::_update_nl() {
if (!nl_changed) {
return;
}
selected_node_list.clear();
for (const KeyValue<Node *, Object *> &E : selection) {
Node *parent = E.key;
parent = parent->get_parent();
bool skip = false;
while (parent) {
if (selection.has(parent)) {
skip = true;
break;
}
parent = parent->get_parent();
}
if (skip) {
continue;
}
selected_node_list.push_back(E.key);
}
nl_changed = true;
}
void EditorSelection::update() {
_update_nl();
if (!changed) {
return;
}
changed = false;
if (!emitted) {
emitted = true;
call_deferred(SNAME("_emit_change"));
}
}
void EditorSelection::_emit_change() {
emit_signal(SNAME("selection_changed"));
emitted = false;
}
List<Node *> &EditorSelection::get_selected_node_list() { List<Node *> &EditorSelection::get_selected_node_list() {
if (changed) { if (changed) {
update(); update();
} else { } else {
_update_nl(); _update_node_list();
} }
return selected_node_list; return selected_node_list;
} }
@ -1202,7 +1161,7 @@ void EditorSelection::clear() {
} }
changed = true; changed = true;
nl_changed = true; node_list_changed = true;
} }
EditorSelection::EditorSelection() { EditorSelection::EditorSelection() {

View File

@ -38,33 +38,32 @@
class ConfigFile; class ConfigFile;
class EditorPlugin; class EditorPlugin;
class EditorHistory { /**
enum { * Stores the history of objects which have been selected for editing in the Editor & the Inspector.
HISTORY_MAX = 64 *
}; * Used in the editor to set & access the currently edited object, as well as the history of objects which have been edited.
*/
struct Obj { class EditorSelectionHistory {
// Stores the object & property (if relevant).
struct _Object {
REF ref; REF ref;
ObjectID object; ObjectID object;
String property; String property;
bool inspector_only = false; bool inspector_only = false;
}; };
struct History { // Represents the selection of an object for editing.
Vector<Obj> path; struct HistoryElement {
// The sub-resources of the parent object (first in the path) that have been edited.
// For example, Node2D -> nested resource -> nested resource, if edited each individually in their own inspector.
Vector<_Object> path;
// The current point in the path. This is always equal to the last item in the path - it is never decremented.
int level = 0; int level = 0;
}; };
friend class EditorData; friend class EditorData;
Vector<History> history; Vector<HistoryElement> history;
int current; int current_elem_idx; // The current history element being edited.
struct PropertyData {
String name;
Variant value;
};
void _add_object(ObjectID p_object, const String &p_property, int p_level_change, bool p_inspector_only = false);
public: public:
void cleanup_history(); void cleanup_history();
@ -72,13 +71,14 @@ public:
bool is_at_beginning() const; bool is_at_beginning() const;
bool is_at_end() const; bool is_at_end() const;
void add_object_inspector_only(ObjectID p_object); // Adds an object to the selection history. A property name can be passed if the target is a subresource of the given object.
void add_object(ObjectID p_object); // If the object should not change the main screen plugin, it can be set as inspector only.
void add_object(ObjectID p_object, const String &p_subprop); void add_object(ObjectID p_object, const String &p_property = String(), bool p_inspector_only = false);
void add_object(ObjectID p_object, int p_relevel);
int get_history_len(); int get_history_len();
int get_history_pos(); int get_history_pos();
// Gets an object from the history. The most recent object would be the object with p_obj = get_history_len() - 1.
ObjectID get_history_obj(int p_obj) const; ObjectID get_history_obj(int p_obj) const;
bool is_history_obj_inspector_only(int p_obj) const; bool is_history_obj_inspector_only(int p_obj) const;
@ -87,13 +87,16 @@ public:
ObjectID get_current(); ObjectID get_current();
bool is_current_inspector_only() const; bool is_current_inspector_only() const;
// Gets the size of the path of the current history item.
int get_path_size() const; int get_path_size() const;
// Gets the object of the current history item, if valid.
ObjectID get_path_object(int p_index) const; ObjectID get_path_object(int p_index) const;
// Gets the property of the current history item.
String get_path_property(int p_index) const; String get_path_property(int p_index) const;
void clear(); void clear();
EditorHistory(); EditorSelectionHistory();
}; };
class EditorSelection; class EditorSelection;
@ -112,7 +115,7 @@ public:
uint64_t file_modified_time = 0; uint64_t file_modified_time = 0;
Dictionary editor_states; Dictionary editor_states;
List<Node *> selection; List<Node *> selection;
Vector<EditorHistory::History> history_stored; Vector<EditorSelectionHistory::HistoryElement> history_stored;
int history_current = 0; int history_current = 0;
Dictionary custom_state; Dictionary custom_state;
uint64_t version = 0; uint64_t version = 0;
@ -210,8 +213,8 @@ public:
void set_plugin_window_layout(Ref<ConfigFile> p_layout); void set_plugin_window_layout(Ref<ConfigFile> p_layout);
void get_plugin_window_layout(Ref<ConfigFile> p_layout); void get_plugin_window_layout(Ref<ConfigFile> p_layout);
void save_edited_scene_state(EditorSelection *p_selection, EditorHistory *p_history, const Dictionary &p_custom); void save_edited_scene_state(EditorSelection *p_selection, EditorSelectionHistory *p_history, const Dictionary &p_custom);
Dictionary restore_edited_scene_state(EditorSelection *p_selection, EditorHistory *p_history); Dictionary restore_edited_scene_state(EditorSelection *p_selection, EditorSelectionHistory *p_history);
void notify_edited_scene_changed(); void notify_edited_scene_changed();
void notify_resource_saved(const Ref<Resource> &p_resource); void notify_resource_saved(const Ref<Resource> &p_resource);
@ -233,22 +236,33 @@ public:
EditorData(); EditorData();
}; };
/**
* Stores and provides access to the nodes currently selected in the editor.
*
* This provides a central location for storing "selected" nodes, as a selection can be triggered from multiple places,
* such as the SceneTreeDock or a main screen editor plugin (e.g. CanvasItemEditor).
*/
class EditorSelection : public Object { class EditorSelection : public Object {
GDCLASS(EditorSelection, Object); GDCLASS(EditorSelection, Object);
private: // Contains the selected nodes and corresponding metadata.
// Metadata objects come from calling _get_editor_data on the editor_plugins, passing the selected node.
Map<Node *, Object *> selection; Map<Node *, Object *> selection;
// Tracks whether the selection change signal has been emitted.
// Prevents multiple signals being called in one frame.
bool emitted = false; bool emitted = false;
bool changed = false; bool changed = false;
bool nl_changed = false; bool node_list_changed = false;
void _node_removed(Node *p_node); void _node_removed(Node *p_node);
// Editor plugins which are related to selection.
List<Object *> editor_plugins; List<Object *> editor_plugins;
List<Node *> selected_node_list; List<Node *> selected_node_list;
void _update_nl(); void _update_node_list();
Array _get_transformable_selected_nodes(); Array _get_transformable_selected_nodes();
void _emit_change(); void _emit_change();
@ -256,10 +270,9 @@ protected:
static void _bind_methods(); static void _bind_methods();
public: public:
TypedArray<Node> get_selected_nodes();
void add_node(Node *p_node); void add_node(Node *p_node);
void remove_node(Node *p_node); void remove_node(Node *p_node);
bool is_selected(Node *) const; bool is_selected(Node *p_node) const;
template <class T> template <class T>
T *get_node_editor_data(Node *p_node) { T *get_node_editor_data(Node *p_node) {
@ -269,13 +282,20 @@ public:
return Object::cast_to<T>(selection[p_node]); return Object::cast_to<T>(selection[p_node]);
} }
// Adds an editor plugin which can provide metadata for selected nodes.
void add_editor_plugin(Object *p_object); void add_editor_plugin(Object *p_object);
void update(); void update();
void clear(); void clear();
// Returns all the selected nodes.
TypedArray<Node> get_selected_nodes();
// 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.
List<Node *> &get_selected_node_list(); List<Node *> &get_selected_node_list();
// Returns all the selected nodes (list version of "get_selected_nodes").
List<Node *> get_full_selected_node_list(); List<Node *> get_full_selected_node_list();
// Returns the map of selected objects and their metadata.
Map<Node *, Object *> &get_selection() { return selection; } Map<Node *, Object *> &get_selection() { return selection; }
EditorSelection(); EditorSelection();

File diff suppressed because it is too large Load Diff

View File

@ -112,6 +112,13 @@ public:
DOCK_SLOT_MAX DOCK_SLOT_MAX
}; };
enum EditorTable {
EDITOR_2D = 0,
EDITOR_3D,
EDITOR_SCRIPT,
EDITOR_ASSETLIB
};
struct ExecuteThreadArgs { struct ExecuteThreadArgs {
String path; String path;
List<String> args; List<String> args;
@ -123,10 +130,6 @@ public:
}; };
private: private:
enum {
HISTORY_SIZE = 64
};
enum MenuOptions { enum MenuOptions {
FILE_NEW_SCENE, FILE_NEW_SCENE,
FILE_NEW_INHERITED_SCENE, FILE_NEW_INHERITED_SCENE,
@ -218,13 +221,59 @@ private:
TOOL_MENU_BASE = 1000 TOOL_MENU_BASE = 1000
}; };
enum {
MAX_INIT_CALLBACKS = 128,
MAX_BUILD_CALLBACKS = 128
};
enum ScriptNameCasing { enum ScriptNameCasing {
SCENE_NAME_CASING_AUTO, SCENE_NAME_CASING_AUTO,
SCENE_NAME_CASING_PASCAL_CASE, SCENE_NAME_CASING_PASCAL_CASE,
SCENE_NAME_CASING_SNAKE_CASE SCENE_NAME_CASING_SNAKE_CASE
}; };
SubViewport *scene_root; // root of the scene being edited struct BottomPanelItem {
String name;
Control *control = nullptr;
Button *button = nullptr;
};
struct ExportDefer {
String preset;
String path;
bool debug = false;
bool pack_only = false;
} export_defer;
static EditorNode *singleton;
EditorData editor_data;
EditorFolding editor_folding;
EditorRun editor_run;
EditorSelectionHistory editor_history;
EditorCommandPalette *command_palette = nullptr;
EditorExport *editor_export = nullptr;
EditorInterface *editor_interface = nullptr;
EditorLog *log = nullptr;
EditorNativeShaderSourceVisualizer *native_shader_source_visualizer = nullptr;
EditorPlugin *editor_plugin_screen = nullptr;
EditorPluginList *editor_plugins_force_input_forwarding = nullptr;
EditorPluginList *editor_plugins_force_over = nullptr;
EditorPluginList *editor_plugins_over = nullptr;
EditorQuickOpen *quick_open = nullptr;
EditorQuickOpen *quick_run = nullptr;
EditorResourcePreview *resource_preview = nullptr;
EditorRunNative *run_native = nullptr;
EditorSelection *editor_selection = nullptr;
EditorSettingsDialog *editor_settings_dialog = nullptr;
ProjectExportDialog *project_export = nullptr;
ProjectSettingsEditor *project_settings_editor = nullptr;
Vector<EditorPlugin *> editor_plugins;
bool _initializing_plugins = false;
Map<String, EditorPlugin *> addon_name_to_plugin;
PanelContainer *scene_root_parent; PanelContainer *scene_root_parent;
Control *theme_base; Control *theme_base;
@ -236,11 +285,8 @@ private:
int rendering_driver_current; int rendering_driver_current;
String rendering_driver_request; String rendering_driver_request;
void _rendering_driver_selected(int);
void _update_rendering_driver_color();
// Split containers
// Split containers.
HSplitContainer *left_l_hsplit; HSplitContainer *left_l_hsplit;
VSplitContainer *left_l_vsplit; VSplitContainer *left_l_vsplit;
HSplitContainer *left_r_hsplit; HSplitContainer *left_r_hsplit;
@ -249,20 +295,17 @@ private:
HSplitContainer *right_hsplit; HSplitContainer *right_hsplit;
VSplitContainer *right_l_vsplit; VSplitContainer *right_l_vsplit;
VSplitContainer *right_r_vsplit; VSplitContainer *right_r_vsplit;
VSplitContainer *center_split; VSplitContainer *center_split;
// To access those easily by index.
// To access those easily by index
Vector<VSplitContainer *> vsplits; Vector<VSplitContainer *> vsplits;
Vector<HSplitContainer *> hsplits; Vector<HSplitContainer *> hsplits;
// Main tabs // Main tabs.
TabBar *scene_tabs; TabBar *scene_tabs;
PopupMenu *scene_tabs_context_menu; PopupMenu *scene_tabs_context_menu;
Panel *tab_preview_panel; Panel *tab_preview_panel;
TextureRect *tab_preview; TextureRect *tab_preview;
int tab_closing; int tab_closing_idx;
bool exiting = false; bool exiting = false;
bool dimmed = false; bool dimmed = false;
@ -304,7 +347,10 @@ private:
Ref<Theme> theme; Ref<Theme> theme;
PopupMenu *recent_scenes; PopupMenu *recent_scenes;
EditorRunNative *run_native; String _recent_scene;
List<String> previous_scenes;
String defer_load_scene;
Node *_last_instantiated_scene;
ConfirmationDialog *confirmation; ConfirmationDialog *confirmation;
ConfirmationDialog *save_confirmation; ConfirmationDialog *save_confirmation;
@ -325,11 +371,6 @@ private:
ConfirmationDialog *install_android_build_template; ConfirmationDialog *install_android_build_template;
ConfirmationDialog *remove_android_build_template; ConfirmationDialog *remove_android_build_template;
EditorSettingsDialog *editor_settings_dialog;
ProjectSettingsEditor *project_settings_editor;
bool settings_changed = true; // make it update settings on first frame
void _update_from_settings();
PopupMenu *vcs_actions_menu; PopupMenu *vcs_actions_menu;
EditorFileDialog *file; EditorFileDialog *file;
ExportTemplateManager *export_template_manager; ExportTemplateManager *export_template_manager;
@ -343,26 +384,16 @@ private:
String current_path; String current_path;
MenuButton *update_spinner; MenuButton *update_spinner;
EditorNativeShaderSourceVisualizer *native_shader_source_visualizer;
String defer_load_scene;
Node *_last_instantiated_scene;
EditorLog *log;
CenterContainer *tabs_center;
EditorQuickOpen *quick_open;
EditorQuickOpen *quick_run;
EditorCommandPalette *command_palette;
HBoxContainer *main_editor_button_vb; HBoxContainer *main_editor_button_vb;
Vector<Button *> main_editor_buttons; Vector<Button *> main_editor_buttons;
Vector<EditorPlugin *> editor_table; Vector<EditorPlugin *> editor_table;
AudioStreamPreviewGenerator *preview_gen; AudioStreamPreviewGenerator *audio_preview_gen;
ProgressDialog *progress_dialog; ProgressDialog *progress_dialog;
BackgroundProgress *progress_hb; BackgroundProgress *progress_hb;
DependencyErrorDialog *dependency_error; DependencyErrorDialog *dependency_error;
Map<String, Set<String>> dependency_errors;
DependencyEditor *dependency_fixer; DependencyEditor *dependency_fixer;
OrphanResourcesDialog *orphan_resources; OrphanResourcesDialog *orphan_resources;
ConfirmationDialog *open_imported; ConfirmationDialog *open_imported;
@ -371,71 +402,24 @@ private:
Vector<Control *> floating_docks; Vector<Control *> floating_docks;
TabContainer *dock_slot[DOCK_SLOT_MAX];
Rect2 dock_select_rect[DOCK_SLOT_MAX];
int dock_select_rect_over;
PopupPanel *dock_select_popup;
Control *dock_select;
Button *dock_float; Button *dock_float;
Button *dock_tab_move_left; Button *dock_tab_move_left;
Button *dock_tab_move_right; Button *dock_tab_move_right;
int dock_popup_selected; Control *dock_select;
PopupPanel *dock_select_popup;
Rect2 dock_select_rect[DOCK_SLOT_MAX];
TabContainer *dock_slot[DOCK_SLOT_MAX];
Timer *dock_drag_timer; Timer *dock_drag_timer;
bool docks_visible = true; bool docks_visible = true;
int dock_popup_selected_idx;
int dock_select_rect_over_idx;
HBoxContainer *tabbar_container; HBoxContainer *tabbar_container;
Button *distraction_free; Button *distraction_free;
Button *scene_tab_add; Button *scene_tab_add;
Control *scene_tab_add_ph; Control *scene_tab_add_ph;
bool scene_distraction = false;
bool script_distraction = false;
String _tmp_import_path;
EditorExport *editor_export;
Object *current;
Ref<Resource> saving_resource;
bool _playing_edited = false;
String run_custom_filename;
bool reference_resource_mem = true;
uint64_t saved_version;
uint64_t last_checked_version;
bool unsaved_cache = true;
String open_navigate;
bool changing_scene = false;
bool waiting_for_first_scan = true;
uint64_t update_spinner_step_msec;
uint64_t update_spinner_step_frame;
int update_spinner_step;
Vector<EditorPlugin *> editor_plugins;
EditorPlugin *editor_plugin_screen;
EditorPluginList *editor_plugins_over;
EditorPluginList *editor_plugins_force_over;
EditorPluginList *editor_plugins_force_input_forwarding;
EditorHistory editor_history;
EditorData editor_data;
EditorRun editor_run;
EditorSelection *editor_selection;
ProjectExportDialog *project_export;
EditorResourcePreview *resource_preview;
EditorFolding editor_folding;
DynamicFontImportSettings *fontdata_import_settings;
SceneImportSettings *scene_import_settings;
struct BottomPanelItem {
String name;
Control *control = nullptr;
Button *button = nullptr;
};
Vector<BottomPanelItem> bottom_panel_items; Vector<BottomPanelItem> bottom_panel_items;
PanelContainer *bottom_panel; PanelContainer *bottom_panel;
HBoxContainer *bottom_panel_hb; HBoxContainer *bottom_panel_hb;
HBoxContainer *bottom_panel_hb_editors; HBoxContainer *bottom_panel_hb_editors;
@ -447,15 +431,81 @@ private:
Tree *disk_changed_list; Tree *disk_changed_list;
ConfirmationDialog *disk_changed; ConfirmationDialog *disk_changed;
void _bottom_panel_raise_toggled(bool); bool scene_distraction_free = false;
bool script_distraction_free = false;
EditorInterface *editor_interface; bool _playing_edited = false;
bool changing_scene = false;
void _bottom_panel_switch(bool p_enable, int p_idx); bool cmdline_export_mode = false;
bool convert_old = false;
String external_file; bool immediate_dialog_confirmed = false;
List<String> previous_scenes;
bool opening_prev = false; bool opening_prev = false;
bool restoring_scenes = false;
bool settings_changed = true; // Make it update settings on first frame.
bool unsaved_cache = true;
bool waiting_for_first_scan = true;
int current_menu_option;
SubViewport *scene_root; // Root of the scene being edited.
Object *current;
Ref<Resource> saving_resource;
uint64_t update_spinner_step_msec;
uint64_t update_spinner_step_frame;
int update_spinner_step;
String _tmp_import_path;
String external_file;
String open_navigate;
String run_custom_filename;
uint64_t saved_version;
uint64_t last_checked_version;
DynamicFontImportSettings *fontdata_import_settings;
SceneImportSettings *scene_import_settings;
String import_reload_fn;
Set<String> textfile_extensions;
Set<FileDialog *> file_dialogs;
Set<EditorFileDialog *> editor_file_dialogs;
Vector<Ref<EditorResourceConversionPlugin>> resource_conversion_plugins;
PrintHandlerList print_handler;
Map<String, Ref<Texture2D>> icon_type_cache;
static EditorBuildCallback build_callbacks[MAX_BUILD_CALLBACKS];
static EditorPluginInitializeCallback plugin_init_callbacks[MAX_INIT_CALLBACKS];
static int build_callback_count;
static int plugin_init_callback_count;
static Vector<EditorNodeInitCallback> _init_callbacks;
static void _dependency_error_report(void *ud, const String &p_path, const String &p_dep, const String &p_type) {
EditorNode *en = (EditorNode *)ud;
if (!en->dependency_errors.has(p_path)) {
en->dependency_errors[p_path] = Set<String>();
}
en->dependency_errors[p_path].insert(p_dep + "::" + p_type);
}
static Ref<Texture2D> _file_dialog_get_icon(const String &p_path);
static void _file_dialog_register(FileDialog *p_dialog);
static void _file_dialog_unregister(FileDialog *p_dialog);
static void _editor_file_dialog_register(EditorFileDialog *p_dialog);
static void _editor_file_dialog_unregister(EditorFileDialog *p_dialog);
static void _load_error_notify(void *p_ud, const String &p_text);
static void _file_access_close_error_notify(const String &p_str);
static void _print_handler(void *p_this, const String &p_string, bool p_error);
static void _resource_saved(RES p_resource, const String &p_path);
static void _resource_loaded(RES p_resource, const String &p_path);
void _build_icon_type_cache();
void _dialog_action(String p_file); void _dialog_action(String p_file);
@ -463,7 +513,6 @@ private:
void _dialog_display_save_error(String p_file, Error p_error); void _dialog_display_save_error(String p_file, Error p_error);
void _dialog_display_load_error(String p_file, Error p_error); void _dialog_display_load_error(String p_file, Error p_error);
int current_option;
void _menu_option(int p_option); void _menu_option(int p_option);
void _menu_confirm_current(); void _menu_confirm_current();
void _menu_option_confirm(int p_option, bool p_confirmed); void _menu_option_confirm(int p_option, bool p_confirmed);
@ -528,36 +577,18 @@ private:
void _global_menu_new_window(const Variant &p_tag); void _global_menu_new_window(const Variant &p_tag);
void _dropped_files(const Vector<String> &p_files, int p_screen); void _dropped_files(const Vector<String> &p_files, int p_screen);
void _add_dropped_files_recursive(const Vector<String> &p_files, String to_path); void _add_dropped_files_recursive(const Vector<String> &p_files, String to_path);
String _recent_scene;
void _update_from_settings();
void _rendering_driver_selected(int);
void _update_rendering_driver_color();
void _exit_editor(int p_exit_code); void _exit_editor(int p_exit_code);
bool convert_old = false;
virtual void unhandled_input(const Ref<InputEvent> &p_event) override; virtual void unhandled_input(const Ref<InputEvent> &p_event) override;
static void _load_error_notify(void *p_ud, const String &p_text);
bool has_main_screen() const { return true; } bool has_main_screen() const { return true; }
String import_reload_fn;
Set<String> textfile_extensions;
Set<FileDialog *> file_dialogs;
Set<EditorFileDialog *> editor_file_dialogs;
Map<String, Ref<Texture2D>> icon_type_cache;
void _build_icon_type_cache();
bool _initializing_addons = false;
Map<String, EditorPlugin *> plugin_addons;
static Ref<Texture2D> _file_dialog_get_icon(const String &p_path);
static void _file_dialog_register(FileDialog *p_dialog);
static void _file_dialog_unregister(FileDialog *p_dialog);
static void _editor_file_dialog_register(EditorFileDialog *p_dialog);
static void _editor_file_dialog_unregister(EditorFileDialog *p_dialog);
void _remove_edited_scene(bool p_change_tab = true); void _remove_edited_scene(bool p_change_tab = true);
void _remove_scene(int index, bool p_change_tab = true); void _remove_scene(int index, bool p_change_tab = true);
bool _find_and_save_resource(RES p_res, Map<RES, bool> &processed, int32_t flags); bool _find_and_save_resource(RES p_res, Map<RES, bool> &processed, int32_t flags);
@ -568,29 +599,6 @@ private:
void _find_node_types(Node *p_node, int &count_2d, int &count_3d); void _find_node_types(Node *p_node, int &count_2d, int &count_3d);
void _save_scene_with_preview(String p_file, int p_idx = -1); void _save_scene_with_preview(String p_file, int p_idx = -1);
Map<String, Set<String>> dependency_errors;
static void _dependency_error_report(void *ud, const String &p_path, const String &p_dep, const String &p_type) {
EditorNode *en = (EditorNode *)ud;
if (!en->dependency_errors.has(p_path)) {
en->dependency_errors[p_path] = Set<String>();
}
en->dependency_errors[p_path].insert(p_dep + "::" + p_type);
}
struct ExportDefer {
String preset;
String path;
bool debug = false;
bool pack_only = false;
} export_defer;
bool cmdline_export_mode = false;
static EditorNode *singleton;
static Vector<EditorNodeInitCallback> _init_callbacks;
bool _find_scene_in_use(Node *p_node, const String &p_path) const; bool _find_scene_in_use(Node *p_node, const String &p_path) const;
void _update_dock_containers(); void _update_dock_containers();
@ -625,7 +633,6 @@ private:
void _update_dock_slots_visibility(); void _update_dock_slots_visibility();
void _dock_tab_changed(int p_tab); void _dock_tab_changed(int p_tab);
bool restoring_scenes = false;
void _save_open_scenes_to_config(Ref<ConfigFile> p_layout, const String &p_section); void _save_open_scenes_to_config(Ref<ConfigFile> p_layout, const String &p_section);
void _load_open_scenes_from_config(Ref<ConfigFile> p_layout, const String &p_section); void _load_open_scenes_from_config(Ref<ConfigFile> p_layout, const String &p_section);
@ -636,35 +643,14 @@ private:
void _update_addon_config(); void _update_addon_config();
static void _file_access_close_error_notify(const String &p_str);
void _toggle_distraction_free_mode(); void _toggle_distraction_free_mode();
enum {
MAX_INIT_CALLBACKS = 128,
MAX_BUILD_CALLBACKS = 128
};
void _inherit_imported(const String &p_action); void _inherit_imported(const String &p_action);
void _open_imported(); void _open_imported();
static int plugin_init_callback_count;
static EditorPluginInitializeCallback plugin_init_callbacks[MAX_INIT_CALLBACKS];
void _save_default_environment(); void _save_default_environment();
static int build_callback_count;
static EditorBuildCallback build_callbacks[MAX_BUILD_CALLBACKS];
void _update_update_spinner(); void _update_update_spinner();
Vector<Ref<EditorResourceConversionPlugin>> resource_conversion_plugins;
PrintHandlerList print_handler;
static void _print_handler(void *p_this, const String &p_string, bool p_error);
static void _resource_saved(RES p_resource, const String &p_path);
static void _resource_loaded(RES p_resource, const String &p_path);
void _resources_changed(const Vector<String> &p_resources); void _resources_changed(const Vector<String> &p_resources);
void _scan_external_changes(); void _scan_external_changes();
void _reload_modified_scenes(); void _reload_modified_scenes();
@ -677,48 +663,70 @@ private:
void _pick_main_scene_custom_action(const String &p_custom_action_name); void _pick_main_scene_custom_action(const String &p_custom_action_name);
bool immediate_dialog_confirmed = false;
void _immediate_dialog_confirmed(); void _immediate_dialog_confirmed();
void _select_default_main_screen_plugin(); void _select_default_main_screen_plugin();
protected: void _bottom_panel_switch(bool p_enable, int p_idx);
void _notification(int p_what); void _bottom_panel_raise_toggled(bool);
static void _bind_methods();
protected: protected:
friend class FileSystemDock; friend class FileSystemDock;
static void _bind_methods();
void _notification(int p_what);
int get_current_tab(); int get_current_tab();
void set_current_tab(int p_tab); void set_current_tab(int p_tab);
public: public:
void set_visible_editor(EditorTable p_table) { _editor_select(p_table); }
bool call_build(); bool call_build();
static void add_plugin_init_callback(EditorPluginInitializeCallback p_callback); static void register_editor_types();
static void unregister_editor_types();
enum EditorTable {
EDITOR_2D = 0,
EDITOR_3D,
EDITOR_SCRIPT,
EDITOR_ASSETLIB
};
void set_visible_editor(EditorTable p_table) { _editor_select(p_table); }
static EditorNode *get_singleton() { return singleton; } static EditorNode *get_singleton() { return singleton; }
EditorPlugin *get_editor_plugin_screen() { return editor_plugin_screen; } static EditorLog *get_log() { return singleton->log; }
EditorPluginList *get_editor_plugins_over() { return editor_plugins_over; } static EditorData &get_editor_data() { return singleton->editor_data; }
EditorPluginList *get_editor_plugins_force_over() { return editor_plugins_force_over; } static EditorFolding &get_editor_folding() { return singleton->editor_folding; }
EditorPluginList *get_editor_plugins_force_input_forwarding() { return editor_plugins_force_input_forwarding; } static UndoRedo *get_undo_redo() { return &singleton->editor_data.get_undo_redo(); }
ProjectSettingsEditor *get_project_settings() { return project_settings_editor; } static HBoxContainer *get_menu_hb() { return singleton->menu_hb; }
static VSplitContainer *get_top_split() { return singleton->top_split; }
static bool has_unsaved_changes() { return singleton->unsaved_cache; }
static void disambiguate_filenames(const Vector<String> p_full_paths, Vector<String> &r_filenames);
static void add_io_error(const String &p_error);
static void progress_add_task(const String &p_task, const String &p_label, int p_steps, bool p_can_cancel = false);
static bool progress_task_step(const String &p_task, const String &p_state, int p_step = -1, bool p_force_refresh = true);
static void progress_end_task(const String &p_task);
static void progress_add_task_bg(const String &p_task, const String &p_label, int p_steps);
static void progress_task_step_bg(const String &p_task, int p_step = -1);
static void progress_end_task_bg(const String &p_task);
static void add_editor_plugin(EditorPlugin *p_editor, bool p_config_changed = false); static void add_editor_plugin(EditorPlugin *p_editor, bool p_config_changed = false);
static void remove_editor_plugin(EditorPlugin *p_editor, bool p_config_changed = false); static void remove_editor_plugin(EditorPlugin *p_editor, bool p_config_changed = false);
static void disambiguate_filenames(const Vector<String> p_full_paths, Vector<String> &r_filenames); static void add_plugin_init_callback(EditorPluginInitializeCallback p_callback);
static void add_init_callback(EditorNodeInitCallback p_callback) { _init_callbacks.push_back(p_callback); }
static void add_build_callback(EditorBuildCallback p_callback);
static bool immediate_confirmation_dialog(const String &p_text, const String &p_ok_text = TTR("Ok"), const String &p_cancel_text = TTR("Cancel"));
EditorPlugin *get_editor_plugin_screen() { return editor_plugin_screen; }
EditorPluginList *get_editor_plugins_force_input_forwarding() { return editor_plugins_force_input_forwarding; }
EditorPluginList *get_editor_plugins_force_over() { return editor_plugins_force_over; }
EditorPluginList *get_editor_plugins_over() { return editor_plugins_over; }
EditorSelection *get_editor_selection() { return editor_selection; }
EditorSelectionHistory *get_editor_selection_history() { return &editor_history; }
ProjectSettingsEditor *get_project_settings() { return project_settings_editor; }
void new_inherited_scene() { _menu_option_confirm(FILE_NEW_INHERITED_SCENE, false); } void new_inherited_scene() { _menu_option_confirm(FILE_NEW_INHERITED_SCENE, false); }
@ -743,10 +751,6 @@ public:
void show_about() { _menu_option_confirm(HELP_ABOUT, false); } void show_about() { _menu_option_confirm(HELP_ABOUT, false); }
static bool has_unsaved_changes() { return singleton->unsaved_cache; }
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 push_item(Object *p_object, const String &p_property = "", bool p_inspector_only = false);
void edit_item(Object *p_object); void edit_item(Object *p_object);
void edit_item_resource(RES p_resource); void edit_item_resource(RES p_resource);
@ -760,15 +764,12 @@ public:
bool is_changing_scene() const; bool is_changing_scene() const;
static EditorLog *get_log() { return singleton->log; }
Control *get_main_control(); Control *get_main_control();
SubViewport *get_scene_root() { return scene_root; } // Root of the scene being edited.
void set_edited_scene(Node *p_scene); void set_edited_scene(Node *p_scene);
Node *get_edited_scene() { return editor_data.get_edited_scene_root(); } Node *get_edited_scene() { return editor_data.get_edited_scene_root(); }
SubViewport *get_scene_root() { return scene_root; } // root of the scene being edited
void fix_dependencies(const String &p_for_file); void fix_dependencies(const String &p_for_file);
int new_scene(); int new_scene();
Error load_scene(const String &p_scene, bool p_ignore_broken_deps = false, bool p_set_inherited = false, bool p_clear_errors = true, bool p_force_open_imported = false, bool p_silent_change_tab = false); Error load_scene(const String &p_scene, bool p_ignore_broken_deps = false, bool p_set_inherited = false, bool p_clear_errors = true, bool p_force_open_imported = false, bool p_silent_change_tab = false);
@ -779,17 +780,8 @@ public:
void set_current_version(uint64_t p_version); void set_current_version(uint64_t p_version);
void set_current_scene(int p_idx); void set_current_scene(int p_idx);
static EditorData &get_editor_data() { return singleton->editor_data; }
static EditorFolding &get_editor_folding() { return singleton->editor_folding; }
EditorHistory *get_editor_history() { return &editor_history; }
static VSplitContainer *get_top_split() { return singleton->top_split; }
void request_instance_scene(const String &p_path); void request_instance_scene(const String &p_path);
void request_instantiate_scenes(const Vector<String> &p_files); void request_instantiate_scenes(const Vector<String> &p_files);
static UndoRedo *get_undo_redo() { return &singleton->editor_data.get_undo_redo(); }
EditorSelection *get_editor_selection() { return editor_selection; }
void set_convert_old_scene(bool p_old) { convert_old = p_old; } void set_convert_old_scene(bool p_old) { convert_old = p_old; }
@ -812,22 +804,9 @@ public:
Error export_preset(const String &p_preset, const String &p_path, bool p_debug, bool p_pack_only); Error export_preset(const String &p_preset, const String &p_path, bool p_debug, bool p_pack_only);
static void register_editor_types();
static void unregister_editor_types();
Control *get_gui_base() { return gui_base; } Control *get_gui_base() { return gui_base; }
Control *get_theme_base() { return gui_base->get_parent_control(); } Control *get_theme_base() { return gui_base->get_parent_control(); }
static void add_io_error(const String &p_error);
static void progress_add_task(const String &p_task, const String &p_label, int p_steps, bool p_can_cancel = false);
static bool progress_task_step(const String &p_task, const String &p_state, int p_step = -1, bool p_force_refresh = true);
static void progress_end_task(const String &p_task);
static void progress_add_task_bg(const String &p_task, const String &p_label, int p_steps);
static void progress_task_step_bg(const String &p_task, int p_step = -1);
static void progress_end_task_bg(const String &p_task);
void save_scene_to_path(String p_file, bool p_with_preview = true) { void save_scene_to_path(String p_file, bool p_with_preview = true) {
if (p_with_preview) { if (p_with_preview) {
_save_scene_with_preview(p_file); _save_scene_with_preview(p_file);
@ -883,9 +862,6 @@ public:
void remove_resource_conversion_plugin(const Ref<EditorResourceConversionPlugin> &p_plugin); void remove_resource_conversion_plugin(const Ref<EditorResourceConversionPlugin> &p_plugin);
Vector<Ref<EditorResourceConversionPlugin>> find_resource_conversion_plugin(const Ref<Resource> &p_for_resource); Vector<Ref<EditorResourceConversionPlugin>> find_resource_conversion_plugin(const Ref<Resource> &p_for_resource);
static void add_init_callback(EditorNodeInitCallback p_callback) { _init_callbacks.push_back(p_callback); }
static void add_build_callback(EditorBuildCallback p_callback);
bool ensure_main_scene(bool p_from_native); bool ensure_main_scene(bool p_from_native);
Error run_play_native(int p_idx, int p_platform); Error run_play_native(int p_idx, int p_platform);
@ -895,8 +871,6 @@ public:
void run_stop(); void run_stop();
bool is_run_playing() const; bool is_run_playing() const;
String get_run_playing_scene() const; String get_run_playing_scene() const;
static bool immediate_confirmation_dialog(const String &p_text, const String &p_ok_text = TTR("Ok"), const String &p_cancel_text = TTR("Cancel"));
}; };
struct EditorProgress { struct EditorProgress {

View File

@ -194,7 +194,7 @@ void EditorPath::_notification(int p_what) {
void EditorPath::_bind_methods() { void EditorPath::_bind_methods() {
} }
EditorPath::EditorPath(EditorHistory *p_history) { EditorPath::EditorPath(EditorSelectionHistory *p_history) {
history = p_history; history = p_history;
MarginContainer *main_mc = memnew(MarginContainer); MarginContainer *main_mc = memnew(MarginContainer);

View File

@ -37,12 +37,12 @@
#include "scene/gui/popup_menu.h" #include "scene/gui/popup_menu.h"
#include "scene/gui/texture_rect.h" #include "scene/gui/texture_rect.h"
class EditorHistory; class EditorSelectionHistory;
class EditorPath : public Button { class EditorPath : public Button {
GDCLASS(EditorPath, Button); GDCLASS(EditorPath, Button);
EditorHistory *history; EditorSelectionHistory *history;
TextureRect *current_object_icon; TextureRect *current_object_icon;
Label *current_object_label; Label *current_object_label;
@ -65,7 +65,7 @@ public:
void clear_path(); void clear_path();
void enable_path(); void enable_path();
EditorPath(EditorHistory *p_history); EditorPath(EditorSelectionHistory *p_history);
}; };
#endif // EDITOR_PATH_H #endif // EDITOR_PATH_H

View File

@ -2806,8 +2806,8 @@ void EditorPropertyNodePath::_node_selected(const NodePath &p_path) {
if (!base_node) { if (!base_node) {
//try a base node within history //try a base node within history
if (EditorNode::get_singleton()->get_editor_history()->get_path_size() > 0) { if (EditorNode::get_singleton()->get_editor_selection_history()->get_path_size() > 0) {
Object *base = ObjectDB::get_instance(EditorNode::get_singleton()->get_editor_history()->get_path_object(0)); Object *base = ObjectDB::get_instance(EditorNode::get_singleton()->get_editor_selection_history()->get_path_object(0));
if (base) { if (base) {
base_node = Object::cast_to<Node>(base); base_node = Object::cast_to<Node>(base);
} }

View File

@ -250,7 +250,7 @@ void InspectorDock::_resource_file_selected(String p_file) {
} }
void InspectorDock::_save_resource(bool save_as) { void InspectorDock::_save_resource(bool save_as) {
ObjectID current = EditorNode::get_singleton()->get_editor_history()->get_current(); ObjectID current = EditorNode::get_singleton()->get_editor_selection_history()->get_current();
Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr; Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr;
ERR_FAIL_COND(!Object::cast_to<Resource>(current_obj)); ERR_FAIL_COND(!Object::cast_to<Resource>(current_obj));
@ -265,7 +265,7 @@ void InspectorDock::_save_resource(bool save_as) {
} }
void InspectorDock::_unref_resource() { void InspectorDock::_unref_resource() {
ObjectID current = EditorNode::get_singleton()->get_editor_history()->get_current(); ObjectID current = EditorNode::get_singleton()->get_editor_selection_history()->get_current();
Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr; Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr;
ERR_FAIL_COND(!Object::cast_to<Resource>(current_obj)); ERR_FAIL_COND(!Object::cast_to<Resource>(current_obj));
@ -276,7 +276,7 @@ void InspectorDock::_unref_resource() {
} }
void InspectorDock::_copy_resource() { void InspectorDock::_copy_resource() {
ObjectID current = EditorNode::get_singleton()->get_editor_history()->get_current(); ObjectID current = EditorNode::get_singleton()->get_editor_selection_history()->get_current();
Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr; Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr;
ERR_FAIL_COND(!Object::cast_to<Resource>(current_obj)); ERR_FAIL_COND(!Object::cast_to<Resource>(current_obj));
@ -300,7 +300,7 @@ void InspectorDock::_prepare_resource_extra_popup() {
} }
void InspectorDock::_prepare_history() { void InspectorDock::_prepare_history() {
EditorHistory *editor_history = EditorNode::get_singleton()->get_editor_history(); EditorSelectionHistory *editor_history = EditorNode::get_singleton()->get_editor_selection_history();
int history_to = MAX(0, editor_history->get_history_len() - 25); int history_to = MAX(0, editor_history->get_history_len() - 25);
@ -352,7 +352,7 @@ void InspectorDock::_prepare_history() {
void InspectorDock::_select_history(int p_idx) { void InspectorDock::_select_history(int p_idx) {
//push it to the top, it is not correct, but it's more useful //push it to the top, it is not correct, but it's more useful
ObjectID id = EditorNode::get_singleton()->get_editor_history()->get_history_obj(p_idx); ObjectID id = EditorNode::get_singleton()->get_editor_selection_history()->get_history_obj(p_idx);
Object *obj = ObjectDB::get_instance(id); Object *obj = ObjectDB::get_instance(id);
if (!obj) { if (!obj) {
return; return;
@ -380,13 +380,13 @@ void InspectorDock::_resource_selected(const RES &p_res, const String &p_propert
} }
void InspectorDock::_edit_forward() { void InspectorDock::_edit_forward() {
if (EditorNode::get_singleton()->get_editor_history()->next()) { if (EditorNode::get_singleton()->get_editor_selection_history()->next()) {
EditorNode::get_singleton()->edit_current(); EditorNode::get_singleton()->edit_current();
} }
} }
void InspectorDock::_edit_back() { void InspectorDock::_edit_back() {
EditorHistory *editor_history = EditorNode::get_singleton()->get_editor_history(); EditorSelectionHistory *editor_history = EditorNode::get_singleton()->get_editor_selection_history();
if ((current && editor_history->previous()) || editor_history->get_path_size() == 1) { if ((current && editor_history->previous()) || editor_history->get_path_size() == 1) {
EditorNode::get_singleton()->edit_current(); EditorNode::get_singleton()->edit_current();
} }
@ -476,7 +476,7 @@ void InspectorDock::clear() {
} }
void InspectorDock::update(Object *p_object) { void InspectorDock::update(Object *p_object) {
EditorHistory *editor_history = EditorNode::get_singleton()->get_editor_history(); EditorSelectionHistory *editor_history = EditorNode::get_singleton()->get_editor_selection_history();
backward_button->set_disabled(editor_history->is_at_beginning()); backward_button->set_disabled(editor_history->is_at_beginning());
forward_button->set_disabled(editor_history->is_at_end()); forward_button->set_disabled(editor_history->is_at_end());
@ -635,7 +635,7 @@ InspectorDock::InspectorDock(EditorData &p_editor_data) {
HBoxContainer *subresource_hb = memnew(HBoxContainer); HBoxContainer *subresource_hb = memnew(HBoxContainer);
add_child(subresource_hb); add_child(subresource_hb);
editor_path = memnew(EditorPath(EditorNode::get_singleton()->get_editor_history())); editor_path = memnew(EditorPath(EditorNode::get_singleton()->get_editor_selection_history()));
editor_path->set_h_size_flags(Control::SIZE_EXPAND_FILL); editor_path->set_h_size_flags(Control::SIZE_EXPAND_FILL);
subresource_hb->add_child(editor_path); subresource_hb->add_child(editor_path);

View File

@ -217,7 +217,7 @@ void ReplicationEditor::update_keying() {
/// TODO make keying usable. /// TODO make keying usable.
#if 0 #if 0
bool keying_enabled = false; bool keying_enabled = false;
EditorHistory *editor_history = EditorNode::get_singleton()->get_editor_history(); EditorSelectionHistory *editor_history = EditorNode::get_singleton()->get_editor_selection_history();
if (is_visible_in_tree() && config.is_valid() && editor_history->get_path_size() > 0) { if (is_visible_in_tree() && config.is_valid() && editor_history->get_path_size() > 0) {
Object *obj = ObjectDB::get_instance(editor_history->get_path_object(0)); Object *obj = ObjectDB::get_instance(editor_history->get_path_object(0));
keying_enabled = Object::cast_to<Node>(obj) != nullptr; keying_enabled = Object::cast_to<Node>(obj) != nullptr;
@ -305,7 +305,7 @@ void ReplicationEditor::property_keyed(const String &p_property) {
ERR_FAIL_COND(!current || config.is_null()); ERR_FAIL_COND(!current || config.is_null());
Node *root = current->get_node(current->get_root_path()); Node *root = current->get_node(current->get_root_path());
ERR_FAIL_COND(!root); ERR_FAIL_COND(!root);
EditorHistory *history = EditorNode::get_singleton()->get_editor_history(); EditorSelectionHistory *history = EditorNode::get_singleton()->get_editor_selection_history();
ERR_FAIL_COND(history->get_path_size() == 0); ERR_FAIL_COND(history->get_path_size() == 0);
Node *node = Object::cast_to<Node>(ObjectDB::get_instance(history->get_path_object(0))); Node *node = Object::cast_to<Node>(ObjectDB::get_instance(history->get_path_object(0)));
ERR_FAIL_COND(!node); ERR_FAIL_COND(!node);

View File

@ -6035,8 +6035,8 @@ void VisualShaderNodePortPreview::_shader_changed() {
//find if a material is also being edited and copy parameters to this one //find if a material is also being edited and copy parameters to this one
for (int i = EditorNode::get_singleton()->get_editor_history()->get_path_size() - 1; i >= 0; i--) { for (int i = EditorNode::get_singleton()->get_editor_selection_history()->get_path_size() - 1; i >= 0; i--) {
Object *object = ObjectDB::get_instance(EditorNode::get_singleton()->get_editor_history()->get_path_object(i)); Object *object = ObjectDB::get_instance(EditorNode::get_singleton()->get_editor_selection_history()->get_path_object(i));
ShaderMaterial *src_mat; ShaderMaterial *src_mat;
if (!object) { if (!object) {
continue; continue;

View File

@ -2075,8 +2075,8 @@ void SceneTreeDock::_delete_confirm(bool p_cut) {
_push_item(nullptr); _push_item(nullptr);
// Fixes the EditorHistory from still offering deleted notes // Fixes the EditorSelectionHistory from still offering deleted notes
EditorHistory *editor_history = EditorNode::get_singleton()->get_editor_history(); EditorSelectionHistory *editor_history = EditorNode::get_singleton()->get_editor_selection_history();
editor_history->cleanup_history(); editor_history->cleanup_history();
InspectorDock::get_singleton()->call("_prepare_history"); InspectorDock::get_singleton()->call("_prepare_history");
} }