mirror of
https://github.com/godotengine/godot.git
synced 2024-11-22 12:12:28 +00:00
Merge pull request #58395 from Geometror/editor-node-data-cleanup
This commit is contained in:
commit
b7850bb1e8
@ -3383,7 +3383,7 @@ Node *AnimationTrackEditor::get_root() const {
|
||||
void AnimationTrackEditor::update_keying() {
|
||||
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) {
|
||||
Object *obj = ObjectDB::get_instance(editor_history->get_path_object(0));
|
||||
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;
|
||||
}
|
||||
|
||||
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++) {
|
||||
String prop = history->get_path_property(i);
|
||||
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) {
|
||||
EditorHistory *history = EditorNode::get_singleton()->get_editor_history();
|
||||
EditorSelectionHistory *history = EditorNode::get_singleton()->get_editor_selection_history();
|
||||
|
||||
ERR_FAIL_COND(!root);
|
||||
// Let's build a node path.
|
||||
|
@ -206,7 +206,7 @@ ObjectID EditorDebuggerInspector::add_object(const Array &p_arr) {
|
||||
void EditorDebuggerInspector::clear_cache() {
|
||||
for (const KeyValue<ObjectID, EditorDebuggerRemoteObject *> &E : remote_objects) {
|
||||
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);
|
||||
}
|
||||
memdelete(E.value);
|
||||
|
@ -181,7 +181,7 @@ void EditorDebuggerNode::_bind_methods() {
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@ -38,12 +38,13 @@
|
||||
#include "editor/plugins/script_editor_plugin.h"
|
||||
#include "scene/resources/packed_scene.h"
|
||||
|
||||
void EditorHistory::cleanup_history() {
|
||||
void EditorSelectionHistory::cleanup_history() {
|
||||
for (int i = 0; i < history.size(); i++) {
|
||||
bool fail = false;
|
||||
|
||||
for (int j = 0; j < history[i].path.size(); j++) {
|
||||
if (!history[i].path[j].ref.is_null()) {
|
||||
// Reference is not null - object still alive.
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -51,21 +52,16 @@ void EditorHistory::cleanup_history() {
|
||||
if (obj) {
|
||||
Node *n = Object::cast_to<Node>(obj);
|
||||
if (n && n->is_inside_tree()) {
|
||||
// Node valid and inside tree - object still alive.
|
||||
continue;
|
||||
}
|
||||
if (!n) { // Possibly still alive
|
||||
if (!n) {
|
||||
// Node possibly still alive.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (j <= history[i].level) {
|
||||
//before or equal level, complete fail
|
||||
fail = true;
|
||||
} else {
|
||||
//after level, clip
|
||||
history.write[i].path.resize(j);
|
||||
}
|
||||
} // Else: object not valid - not alive.
|
||||
|
||||
fail = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -75,16 +71,16 @@ void EditorHistory::cleanup_history() {
|
||||
}
|
||||
}
|
||||
|
||||
if (current >= history.size()) {
|
||||
current = history.size() - 1;
|
||||
if (current_elem_idx >= history.size()) {
|
||||
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);
|
||||
ERR_FAIL_COND(!obj);
|
||||
RefCounted *r = Object::cast_to<RefCounted>(obj);
|
||||
Obj o;
|
||||
_Object o;
|
||||
if (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.inspector_only = p_inspector_only;
|
||||
|
||||
History h;
|
||||
|
||||
bool has_prev = current >= 0 && current < history.size();
|
||||
bool has_prev = current_elem_idx >= 0 && current_elem_idx < history.size();
|
||||
|
||||
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) {
|
||||
//add a sub property
|
||||
History &pr = history.write[current];
|
||||
h = pr;
|
||||
// Add a sub property.
|
||||
HistoryElement &prev_element = history.write[current_elem_idx];
|
||||
h = prev_element;
|
||||
h.path.resize(h.level + 1);
|
||||
h.path.push_back(o);
|
||||
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 {
|
||||
//add a new node
|
||||
// Create a new history item.
|
||||
h.path.push_back(o);
|
||||
h.level = 0;
|
||||
}
|
||||
|
||||
history.push_back(h);
|
||||
current++;
|
||||
current_elem_idx++;
|
||||
}
|
||||
|
||||
void EditorHistory::add_object_inspector_only(ObjectID p_object) {
|
||||
_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() {
|
||||
int EditorSelectionHistory::get_history_len() {
|
||||
return history.size();
|
||||
}
|
||||
|
||||
int EditorHistory::get_history_pos() {
|
||||
return current;
|
||||
int EditorSelectionHistory::get_history_pos() {
|
||||
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(history[p_obj].level, history[p_obj].path.size(), false);
|
||||
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(history[p_obj].level, history[p_obj].path.size(), ObjectID());
|
||||
return history[p_obj].path[history[p_obj].level].object;
|
||||
}
|
||||
|
||||
bool EditorHistory::is_at_beginning() const {
|
||||
return current <= 0;
|
||||
bool EditorSelectionHistory::is_at_beginning() const {
|
||||
return current_elem_idx <= 0;
|
||||
}
|
||||
|
||||
bool EditorHistory::is_at_end() const {
|
||||
return ((current + 1) >= history.size());
|
||||
bool EditorSelectionHistory::is_at_end() const {
|
||||
return ((current_elem_idx + 1) >= history.size());
|
||||
}
|
||||
|
||||
bool EditorHistory::next() {
|
||||
bool EditorSelectionHistory::next() {
|
||||
cleanup_history();
|
||||
|
||||
if ((current + 1) < history.size()) {
|
||||
current++;
|
||||
if ((current_elem_idx + 1) < history.size()) {
|
||||
current_elem_idx++;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@ -179,11 +153,11 @@ bool EditorHistory::next() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EditorHistory::previous() {
|
||||
bool EditorSelectionHistory::previous() {
|
||||
cleanup_history();
|
||||
|
||||
if (current > 0) {
|
||||
current--;
|
||||
if (current_elem_idx > 0) {
|
||||
current_elem_idx--;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@ -191,76 +165,63 @@ bool EditorHistory::previous() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EditorHistory::is_current_inspector_only() const {
|
||||
if (current < 0 || current >= history.size()) {
|
||||
bool EditorSelectionHistory::is_current_inspector_only() const {
|
||||
if (current_elem_idx < 0 || current_elem_idx >= history.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const History &h = history[current];
|
||||
const HistoryElement &h = history[current_elem_idx];
|
||||
return h.path[h.level].inspector_only;
|
||||
}
|
||||
|
||||
ObjectID EditorHistory::get_current() {
|
||||
if (current < 0 || current >= history.size()) {
|
||||
ObjectID EditorSelectionHistory::get_current() {
|
||||
if (current_elem_idx < 0 || current_elem_idx >= history.size()) {
|
||||
return ObjectID();
|
||||
}
|
||||
|
||||
History &h = history.write[current];
|
||||
Object *obj = ObjectDB::get_instance(h.path[h.level].object);
|
||||
if (!obj) {
|
||||
return ObjectID();
|
||||
}
|
||||
|
||||
return obj->get_instance_id();
|
||||
Object *obj = ObjectDB::get_instance(get_history_obj(current_elem_idx));
|
||||
return obj ? obj->get_instance_id() : ObjectID();
|
||||
}
|
||||
|
||||
int EditorHistory::get_path_size() const {
|
||||
if (current < 0 || current >= history.size()) {
|
||||
int EditorSelectionHistory::get_path_size() const {
|
||||
if (current_elem_idx < 0 || current_elem_idx >= history.size()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const History &h = history[current];
|
||||
return h.path.size();
|
||||
return history[current_elem_idx].path.size();
|
||||
}
|
||||
|
||||
ObjectID EditorHistory::get_path_object(int p_index) const {
|
||||
if (current < 0 || current >= history.size()) {
|
||||
ObjectID EditorSelectionHistory::get_path_object(int p_index) const {
|
||||
if (current_elem_idx < 0 || current_elem_idx >= history.size()) {
|
||||
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(h.path[p_index].object);
|
||||
if (!obj) {
|
||||
return ObjectID();
|
||||
}
|
||||
|
||||
return obj->get_instance_id();
|
||||
Object *obj = ObjectDB::get_instance(history[current_elem_idx].path[p_index].object);
|
||||
return obj ? obj->get_instance_id() : ObjectID();
|
||||
}
|
||||
|
||||
String EditorHistory::get_path_property(int p_index) const {
|
||||
if (current < 0 || current >= history.size()) {
|
||||
String EditorSelectionHistory::get_path_property(int p_index) const {
|
||||
if (current_elem_idx < 0 || current_elem_idx >= history.size()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const History &h = history[current];
|
||||
|
||||
ERR_FAIL_INDEX_V(p_index, h.path.size(), "");
|
||||
|
||||
return h.path[p_index].property;
|
||||
ERR_FAIL_INDEX_V(p_index, history[current_elem_idx].path.size(), "");
|
||||
return history[current_elem_idx].path[p_index].property;
|
||||
}
|
||||
|
||||
void EditorHistory::clear() {
|
||||
void EditorSelectionHistory::clear() {
|
||||
history.clear();
|
||||
current = -1;
|
||||
current_elem_idx = -1;
|
||||
}
|
||||
|
||||
EditorHistory::EditorHistory() {
|
||||
current = -1;
|
||||
EditorSelectionHistory::EditorSelectionHistory() {
|
||||
current_elem_idx = -1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
EditorPlugin *EditorData::get_editor(Object *p_object) {
|
||||
// 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.
|
||||
@ -636,14 +597,14 @@ bool EditorData::check_and_update_scene(int p_idx) {
|
||||
|
||||
EditorProgress ep("update_scene", TTR("Updating Scene"), 2);
|
||||
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);
|
||||
ERR_FAIL_COND_V(err != OK, false);
|
||||
ep.step(TTR("Updating scene..."), 1);
|
||||
Node *new_scene = pscene->instantiate(PackedScene::GEN_EDIT_STATE_MAIN);
|
||||
ERR_FAIL_COND_V(!new_scene, false);
|
||||
|
||||
//transfer selection
|
||||
// Transfer selection.
|
||||
List<Node *> new_selection;
|
||||
for (const Node *E : edited_scene.write[p_idx].selection) {
|
||||
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) {
|
||||
ERR_FAIL_INDEX(p_idx, edited_scene.size());
|
||||
current_edited_scene = p_idx;
|
||||
//swap
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
EditedScene &es = edited_scene.write[current_edited_scene];
|
||||
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.editor_states = get_editor_states();
|
||||
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());
|
||||
|
||||
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_selection->clear();
|
||||
@ -1033,12 +993,11 @@ void EditorData::script_class_load_icon_paths() {
|
||||
|
||||
EditorData::EditorData() {
|
||||
current_edited_scene = -1;
|
||||
|
||||
//load_imported_scenes_from_globals();
|
||||
script_class_load_icon_paths();
|
||||
}
|
||||
|
||||
///////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void EditorSelection::_node_removed(Node *p_node) {
|
||||
if (!selection.has(p_node)) {
|
||||
return;
|
||||
@ -1050,7 +1009,7 @@ void EditorSelection::_node_removed(Node *p_node) {
|
||||
}
|
||||
selection.erase(p_node);
|
||||
changed = true;
|
||||
nl_changed = true;
|
||||
node_list_changed = true;
|
||||
}
|
||||
|
||||
void EditorSelection::add_node(Node *p_node) {
|
||||
@ -1061,7 +1020,7 @@ void EditorSelection::add_node(Node *p_node) {
|
||||
}
|
||||
|
||||
changed = true;
|
||||
nl_changed = true;
|
||||
node_list_changed = true;
|
||||
Object *meta = nullptr;
|
||||
for (Object *E : editor_plugins) {
|
||||
meta = E->call("_get_editor_data", p_node);
|
||||
@ -1072,32 +1031,92 @@ void EditorSelection::add_node(Node *p_node) {
|
||||
selection[p_node] = meta;
|
||||
|
||||
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) {
|
||||
ERR_FAIL_NULL(p_node);
|
||||
|
||||
if (!selection.has(p_node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
changed = true;
|
||||
nl_changed = true;
|
||||
node_list_changed = true;
|
||||
Object *meta = selection[p_node];
|
||||
if (meta) {
|
||||
memdelete(meta);
|
||||
}
|
||||
selection.erase(p_node);
|
||||
|
||||
p_node->disconnect("tree_exiting", callable_mp(this, &EditorSelection::_node_removed));
|
||||
//emit_signal(SNAME("selection_changed"));
|
||||
}
|
||||
|
||||
bool EditorSelection::is_selected(Node *p_node) const {
|
||||
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 ret;
|
||||
|
||||
@ -1118,71 +1137,11 @@ TypedArray<Node> EditorSelection::get_selected_nodes() {
|
||||
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() {
|
||||
if (changed) {
|
||||
update();
|
||||
} else {
|
||||
_update_nl();
|
||||
_update_node_list();
|
||||
}
|
||||
return selected_node_list;
|
||||
}
|
||||
@ -1202,7 +1161,7 @@ void EditorSelection::clear() {
|
||||
}
|
||||
|
||||
changed = true;
|
||||
nl_changed = true;
|
||||
node_list_changed = true;
|
||||
}
|
||||
|
||||
EditorSelection::EditorSelection() {
|
||||
|
@ -38,33 +38,32 @@
|
||||
class ConfigFile;
|
||||
class EditorPlugin;
|
||||
|
||||
class EditorHistory {
|
||||
enum {
|
||||
HISTORY_MAX = 64
|
||||
};
|
||||
|
||||
struct Obj {
|
||||
/**
|
||||
* Stores the history of objects which have been selected for editing in the Editor & the Inspector.
|
||||
*
|
||||
* Used in the editor to set & access the currently edited object, as well as the history of objects which have been edited.
|
||||
*/
|
||||
class EditorSelectionHistory {
|
||||
// Stores the object & property (if relevant).
|
||||
struct _Object {
|
||||
REF ref;
|
||||
ObjectID object;
|
||||
String property;
|
||||
bool inspector_only = false;
|
||||
};
|
||||
|
||||
struct History {
|
||||
Vector<Obj> path;
|
||||
// Represents the selection of an object for editing.
|
||||
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;
|
||||
};
|
||||
friend class EditorData;
|
||||
|
||||
Vector<History> history;
|
||||
int current;
|
||||
|
||||
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);
|
||||
Vector<HistoryElement> history;
|
||||
int current_elem_idx; // The current history element being edited.
|
||||
|
||||
public:
|
||||
void cleanup_history();
|
||||
@ -72,13 +71,14 @@ public:
|
||||
bool is_at_beginning() const;
|
||||
bool is_at_end() const;
|
||||
|
||||
void add_object_inspector_only(ObjectID p_object);
|
||||
void add_object(ObjectID p_object);
|
||||
void add_object(ObjectID p_object, const String &p_subprop);
|
||||
void add_object(ObjectID p_object, int p_relevel);
|
||||
// Adds an object to the selection history. A property name can be passed if the target is a subresource of the given 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_property = String(), bool p_inspector_only = false);
|
||||
|
||||
int get_history_len();
|
||||
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;
|
||||
bool is_history_obj_inspector_only(int p_obj) const;
|
||||
|
||||
@ -87,13 +87,16 @@ public:
|
||||
ObjectID get_current();
|
||||
bool is_current_inspector_only() const;
|
||||
|
||||
// Gets the size of the path of the current history item.
|
||||
int get_path_size() const;
|
||||
// Gets the object of the current history item, if valid.
|
||||
ObjectID get_path_object(int p_index) const;
|
||||
// Gets the property of the current history item.
|
||||
String get_path_property(int p_index) const;
|
||||
|
||||
void clear();
|
||||
|
||||
EditorHistory();
|
||||
EditorSelectionHistory();
|
||||
};
|
||||
|
||||
class EditorSelection;
|
||||
@ -112,7 +115,7 @@ public:
|
||||
uint64_t file_modified_time = 0;
|
||||
Dictionary editor_states;
|
||||
List<Node *> selection;
|
||||
Vector<EditorHistory::History> history_stored;
|
||||
Vector<EditorSelectionHistory::HistoryElement> history_stored;
|
||||
int history_current = 0;
|
||||
Dictionary custom_state;
|
||||
uint64_t version = 0;
|
||||
@ -210,8 +213,8 @@ public:
|
||||
void set_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);
|
||||
Dictionary restore_edited_scene_state(EditorSelection *p_selection, EditorHistory *p_history);
|
||||
void save_edited_scene_state(EditorSelection *p_selection, EditorSelectionHistory *p_history, const Dictionary &p_custom);
|
||||
Dictionary restore_edited_scene_state(EditorSelection *p_selection, EditorSelectionHistory *p_history);
|
||||
void notify_edited_scene_changed();
|
||||
void notify_resource_saved(const Ref<Resource> &p_resource);
|
||||
|
||||
@ -233,22 +236,33 @@ public:
|
||||
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 {
|
||||
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;
|
||||
|
||||
// Tracks whether the selection change signal has been emitted.
|
||||
// Prevents multiple signals being called in one frame.
|
||||
bool emitted = false;
|
||||
|
||||
bool changed = false;
|
||||
bool nl_changed = false;
|
||||
bool node_list_changed = false;
|
||||
|
||||
void _node_removed(Node *p_node);
|
||||
|
||||
// Editor plugins which are related to selection.
|
||||
List<Object *> editor_plugins;
|
||||
List<Node *> selected_node_list;
|
||||
|
||||
void _update_nl();
|
||||
void _update_node_list();
|
||||
Array _get_transformable_selected_nodes();
|
||||
void _emit_change();
|
||||
|
||||
@ -256,10 +270,9 @@ protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
TypedArray<Node> get_selected_nodes();
|
||||
void add_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>
|
||||
T *get_node_editor_data(Node *p_node) {
|
||||
@ -269,13 +282,20 @@ public:
|
||||
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 update();
|
||||
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();
|
||||
// Returns all the selected nodes (list version of "get_selected_nodes").
|
||||
List<Node *> get_full_selected_node_list();
|
||||
// Returns the map of selected objects and their metadata.
|
||||
Map<Node *, Object *> &get_selection() { return selection; }
|
||||
|
||||
EditorSelection();
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -112,6 +112,13 @@ public:
|
||||
DOCK_SLOT_MAX
|
||||
};
|
||||
|
||||
enum EditorTable {
|
||||
EDITOR_2D = 0,
|
||||
EDITOR_3D,
|
||||
EDITOR_SCRIPT,
|
||||
EDITOR_ASSETLIB
|
||||
};
|
||||
|
||||
struct ExecuteThreadArgs {
|
||||
String path;
|
||||
List<String> args;
|
||||
@ -123,10 +130,6 @@ public:
|
||||
};
|
||||
|
||||
private:
|
||||
enum {
|
||||
HISTORY_SIZE = 64
|
||||
};
|
||||
|
||||
enum MenuOptions {
|
||||
FILE_NEW_SCENE,
|
||||
FILE_NEW_INHERITED_SCENE,
|
||||
@ -218,13 +221,59 @@ private:
|
||||
TOOL_MENU_BASE = 1000
|
||||
};
|
||||
|
||||
enum {
|
||||
MAX_INIT_CALLBACKS = 128,
|
||||
MAX_BUILD_CALLBACKS = 128
|
||||
};
|
||||
|
||||
enum ScriptNameCasing {
|
||||
SCENE_NAME_CASING_AUTO,
|
||||
SCENE_NAME_CASING_PASCAL_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;
|
||||
Control *theme_base;
|
||||
@ -236,11 +285,8 @@ private:
|
||||
|
||||
int rendering_driver_current;
|
||||
String rendering_driver_request;
|
||||
void _rendering_driver_selected(int);
|
||||
void _update_rendering_driver_color();
|
||||
|
||||
// Split containers
|
||||
|
||||
// Split containers.
|
||||
HSplitContainer *left_l_hsplit;
|
||||
VSplitContainer *left_l_vsplit;
|
||||
HSplitContainer *left_r_hsplit;
|
||||
@ -249,20 +295,17 @@ private:
|
||||
HSplitContainer *right_hsplit;
|
||||
VSplitContainer *right_l_vsplit;
|
||||
VSplitContainer *right_r_vsplit;
|
||||
|
||||
VSplitContainer *center_split;
|
||||
|
||||
// To access those easily by index
|
||||
// To access those easily by index.
|
||||
Vector<VSplitContainer *> vsplits;
|
||||
Vector<HSplitContainer *> hsplits;
|
||||
|
||||
// Main tabs
|
||||
|
||||
// Main tabs.
|
||||
TabBar *scene_tabs;
|
||||
PopupMenu *scene_tabs_context_menu;
|
||||
Panel *tab_preview_panel;
|
||||
TextureRect *tab_preview;
|
||||
int tab_closing;
|
||||
int tab_closing_idx;
|
||||
|
||||
bool exiting = false;
|
||||
bool dimmed = false;
|
||||
@ -304,7 +347,10 @@ private:
|
||||
Ref<Theme> theme;
|
||||
|
||||
PopupMenu *recent_scenes;
|
||||
EditorRunNative *run_native;
|
||||
String _recent_scene;
|
||||
List<String> previous_scenes;
|
||||
String defer_load_scene;
|
||||
Node *_last_instantiated_scene;
|
||||
|
||||
ConfirmationDialog *confirmation;
|
||||
ConfirmationDialog *save_confirmation;
|
||||
@ -325,11 +371,6 @@ private:
|
||||
ConfirmationDialog *install_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;
|
||||
EditorFileDialog *file;
|
||||
ExportTemplateManager *export_template_manager;
|
||||
@ -343,26 +384,16 @@ private:
|
||||
String current_path;
|
||||
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;
|
||||
Vector<Button *> main_editor_buttons;
|
||||
Vector<EditorPlugin *> editor_table;
|
||||
|
||||
AudioStreamPreviewGenerator *preview_gen;
|
||||
AudioStreamPreviewGenerator *audio_preview_gen;
|
||||
ProgressDialog *progress_dialog;
|
||||
BackgroundProgress *progress_hb;
|
||||
|
||||
DependencyErrorDialog *dependency_error;
|
||||
Map<String, Set<String>> dependency_errors;
|
||||
DependencyEditor *dependency_fixer;
|
||||
OrphanResourcesDialog *orphan_resources;
|
||||
ConfirmationDialog *open_imported;
|
||||
@ -371,71 +402,24 @@ private:
|
||||
|
||||
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_tab_move_left;
|
||||
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;
|
||||
bool docks_visible = true;
|
||||
int dock_popup_selected_idx;
|
||||
int dock_select_rect_over_idx;
|
||||
|
||||
HBoxContainer *tabbar_container;
|
||||
Button *distraction_free;
|
||||
Button *scene_tab_add;
|
||||
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;
|
||||
|
||||
PanelContainer *bottom_panel;
|
||||
HBoxContainer *bottom_panel_hb;
|
||||
HBoxContainer *bottom_panel_hb_editors;
|
||||
@ -447,15 +431,81 @@ private:
|
||||
Tree *disk_changed_list;
|
||||
ConfirmationDialog *disk_changed;
|
||||
|
||||
void _bottom_panel_raise_toggled(bool);
|
||||
bool scene_distraction_free = false;
|
||||
bool script_distraction_free = false;
|
||||
|
||||
EditorInterface *editor_interface;
|
||||
|
||||
void _bottom_panel_switch(bool p_enable, int p_idx);
|
||||
|
||||
String external_file;
|
||||
List<String> previous_scenes;
|
||||
bool _playing_edited = false;
|
||||
bool changing_scene = false;
|
||||
bool cmdline_export_mode = false;
|
||||
bool convert_old = false;
|
||||
bool immediate_dialog_confirmed = 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);
|
||||
|
||||
@ -463,7 +513,6 @@ private:
|
||||
void _dialog_display_save_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_confirm_current();
|
||||
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 _dropped_files(const Vector<String> &p_files, int p_screen);
|
||||
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);
|
||||
|
||||
bool convert_old = false;
|
||||
|
||||
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; }
|
||||
|
||||
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_scene(int index, bool p_change_tab = true);
|
||||
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 _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;
|
||||
|
||||
void _update_dock_containers();
|
||||
@ -625,7 +633,6 @@ private:
|
||||
void _update_dock_slots_visibility();
|
||||
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 _load_open_scenes_from_config(Ref<ConfigFile> p_layout, const String &p_section);
|
||||
|
||||
@ -636,35 +643,14 @@ private:
|
||||
|
||||
void _update_addon_config();
|
||||
|
||||
static void _file_access_close_error_notify(const String &p_str);
|
||||
|
||||
void _toggle_distraction_free_mode();
|
||||
|
||||
enum {
|
||||
MAX_INIT_CALLBACKS = 128,
|
||||
MAX_BUILD_CALLBACKS = 128
|
||||
};
|
||||
|
||||
void _inherit_imported(const String &p_action);
|
||||
void _open_imported();
|
||||
|
||||
static int plugin_init_callback_count;
|
||||
static EditorPluginInitializeCallback plugin_init_callbacks[MAX_INIT_CALLBACKS];
|
||||
void _save_default_environment();
|
||||
|
||||
static int build_callback_count;
|
||||
static EditorBuildCallback build_callbacks[MAX_BUILD_CALLBACKS];
|
||||
|
||||
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 _scan_external_changes();
|
||||
void _reload_modified_scenes();
|
||||
@ -677,48 +663,70 @@ private:
|
||||
|
||||
void _pick_main_scene_custom_action(const String &p_custom_action_name);
|
||||
|
||||
bool immediate_dialog_confirmed = false;
|
||||
void _immediate_dialog_confirmed();
|
||||
|
||||
void _select_default_main_screen_plugin();
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
|
||||
static void _bind_methods();
|
||||
void _bottom_panel_switch(bool p_enable, int p_idx);
|
||||
void _bottom_panel_raise_toggled(bool);
|
||||
|
||||
protected:
|
||||
friend class FileSystemDock;
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
void _notification(int p_what);
|
||||
|
||||
int get_current_tab();
|
||||
void set_current_tab(int p_tab);
|
||||
|
||||
public:
|
||||
void set_visible_editor(EditorTable p_table) { _editor_select(p_table); }
|
||||
|
||||
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; }
|
||||
|
||||
EditorPlugin *get_editor_plugin_screen() { return editor_plugin_screen; }
|
||||
EditorPluginList *get_editor_plugins_over() { return editor_plugins_over; }
|
||||
EditorPluginList *get_editor_plugins_force_over() { return editor_plugins_force_over; }
|
||||
EditorPluginList *get_editor_plugins_force_input_forwarding() { return editor_plugins_force_input_forwarding; }
|
||||
static EditorLog *get_log() { return singleton->log; }
|
||||
static EditorData &get_editor_data() { return singleton->editor_data; }
|
||||
static EditorFolding &get_editor_folding() { return singleton->editor_folding; }
|
||||
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 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); }
|
||||
|
||||
@ -743,10 +751,6 @@ public:
|
||||
|
||||
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 edit_item(Object *p_object);
|
||||
void edit_item_resource(RES p_resource);
|
||||
@ -760,15 +764,12 @@ public:
|
||||
|
||||
bool is_changing_scene() const;
|
||||
|
||||
static EditorLog *get_log() { return singleton->log; }
|
||||
Control *get_main_control();
|
||||
SubViewport *get_scene_root() { return scene_root; } // Root of the scene being edited.
|
||||
|
||||
void set_edited_scene(Node *p_scene);
|
||||
|
||||
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);
|
||||
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);
|
||||
@ -779,17 +780,8 @@ public:
|
||||
void set_current_version(uint64_t p_version);
|
||||
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_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; }
|
||||
|
||||
@ -812,22 +804,9 @@ public:
|
||||
|
||||
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_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) {
|
||||
if (p_with_preview) {
|
||||
_save_scene_with_preview(p_file);
|
||||
@ -883,9 +862,6 @@ public:
|
||||
void remove_resource_conversion_plugin(const Ref<EditorResourceConversionPlugin> &p_plugin);
|
||||
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);
|
||||
|
||||
Error run_play_native(int p_idx, int p_platform);
|
||||
@ -895,8 +871,6 @@ public:
|
||||
void run_stop();
|
||||
bool is_run_playing() 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 {
|
||||
|
@ -194,7 +194,7 @@ void EditorPath::_notification(int p_what) {
|
||||
void EditorPath::_bind_methods() {
|
||||
}
|
||||
|
||||
EditorPath::EditorPath(EditorHistory *p_history) {
|
||||
EditorPath::EditorPath(EditorSelectionHistory *p_history) {
|
||||
history = p_history;
|
||||
|
||||
MarginContainer *main_mc = memnew(MarginContainer);
|
||||
|
@ -37,12 +37,12 @@
|
||||
#include "scene/gui/popup_menu.h"
|
||||
#include "scene/gui/texture_rect.h"
|
||||
|
||||
class EditorHistory;
|
||||
class EditorSelectionHistory;
|
||||
|
||||
class EditorPath : public Button {
|
||||
GDCLASS(EditorPath, Button);
|
||||
|
||||
EditorHistory *history;
|
||||
EditorSelectionHistory *history;
|
||||
|
||||
TextureRect *current_object_icon;
|
||||
Label *current_object_label;
|
||||
@ -65,7 +65,7 @@ public:
|
||||
void clear_path();
|
||||
void enable_path();
|
||||
|
||||
EditorPath(EditorHistory *p_history);
|
||||
EditorPath(EditorSelectionHistory *p_history);
|
||||
};
|
||||
|
||||
#endif // EDITOR_PATH_H
|
||||
|
@ -2806,8 +2806,8 @@ void EditorPropertyNodePath::_node_selected(const NodePath &p_path) {
|
||||
|
||||
if (!base_node) {
|
||||
//try a base node within history
|
||||
if (EditorNode::get_singleton()->get_editor_history()->get_path_size() > 0) {
|
||||
Object *base = ObjectDB::get_instance(EditorNode::get_singleton()->get_editor_history()->get_path_object(0));
|
||||
if (EditorNode::get_singleton()->get_editor_selection_history()->get_path_size() > 0) {
|
||||
Object *base = ObjectDB::get_instance(EditorNode::get_singleton()->get_editor_selection_history()->get_path_object(0));
|
||||
if (base) {
|
||||
base_node = Object::cast_to<Node>(base);
|
||||
}
|
||||
|
@ -250,7 +250,7 @@ void InspectorDock::_resource_file_selected(String p_file) {
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
ERR_FAIL_COND(!Object::cast_to<Resource>(current_obj));
|
||||
@ -265,7 +265,7 @@ void InspectorDock::_save_resource(bool save_as) {
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
ERR_FAIL_COND(!Object::cast_to<Resource>(current_obj));
|
||||
@ -276,7 +276,7 @@ void InspectorDock::_unref_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;
|
||||
|
||||
ERR_FAIL_COND(!Object::cast_to<Resource>(current_obj));
|
||||
@ -300,7 +300,7 @@ void InspectorDock::_prepare_resource_extra_popup() {
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@ -352,7 +352,7 @@ void InspectorDock::_prepare_history() {
|
||||
|
||||
void InspectorDock::_select_history(int p_idx) {
|
||||
//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);
|
||||
if (!obj) {
|
||||
return;
|
||||
@ -380,13 +380,13 @@ void InspectorDock::_resource_selected(const RES &p_res, const String &p_propert
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
EditorNode::get_singleton()->edit_current();
|
||||
}
|
||||
@ -476,7 +476,7 @@ void InspectorDock::clear() {
|
||||
}
|
||||
|
||||
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());
|
||||
forward_button->set_disabled(editor_history->is_at_end());
|
||||
|
||||
@ -635,7 +635,7 @@ InspectorDock::InspectorDock(EditorData &p_editor_data) {
|
||||
|
||||
HBoxContainer *subresource_hb = memnew(HBoxContainer);
|
||||
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);
|
||||
subresource_hb->add_child(editor_path);
|
||||
|
||||
|
@ -217,7 +217,7 @@ void ReplicationEditor::update_keying() {
|
||||
/// TODO make keying usable.
|
||||
#if 0
|
||||
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) {
|
||||
Object *obj = ObjectDB::get_instance(editor_history->get_path_object(0));
|
||||
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());
|
||||
Node *root = current->get_node(current->get_root_path());
|
||||
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);
|
||||
Node *node = Object::cast_to<Node>(ObjectDB::get_instance(history->get_path_object(0)));
|
||||
ERR_FAIL_COND(!node);
|
||||
|
@ -6035,8 +6035,8 @@ void VisualShaderNodePortPreview::_shader_changed() {
|
||||
|
||||
//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--) {
|
||||
Object *object = ObjectDB::get_instance(EditorNode::get_singleton()->get_editor_history()->get_path_object(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_selection_history()->get_path_object(i));
|
||||
ShaderMaterial *src_mat;
|
||||
if (!object) {
|
||||
continue;
|
||||
|
@ -2075,8 +2075,8 @@ void SceneTreeDock::_delete_confirm(bool p_cut) {
|
||||
|
||||
_push_item(nullptr);
|
||||
|
||||
// Fixes the EditorHistory from still offering deleted notes
|
||||
EditorHistory *editor_history = EditorNode::get_singleton()->get_editor_history();
|
||||
// Fixes the EditorSelectionHistory from still offering deleted notes
|
||||
EditorSelectionHistory *editor_history = EditorNode::get_singleton()->get_editor_selection_history();
|
||||
editor_history->cleanup_history();
|
||||
InspectorDock::get_singleton()->call("_prepare_history");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user