summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/dictionary_property_edit.cpp189
-rw-r--r--editor/dictionary_property_edit.h62
-rw-r--r--editor/editor_node.cpp15
-rw-r--r--editor/editor_path.cpp10
-rw-r--r--editor/editor_settings.cpp13
-rw-r--r--editor/editor_settings.h4
-rw-r--r--editor/editor_themes.cpp7
-rw-r--r--editor/filesystem_dock.cpp11
-rw-r--r--editor/filesystem_dock.h1
-rw-r--r--editor/icons/icon_GUI_ellipsis.svg5
-rw-r--r--editor/icons/icon_animation.svg4
-rw-r--r--editor/icons/icon_area.svg4
-rw-r--r--editor/icons/icon_area_2d.svg4
-rw-r--r--editor/icons/icon_array_mesh.svg4
-rw-r--r--editor/icons/icon_editor_handle_add.svg6
-rw-r--r--editor/icons/icon_editor_handle_selected.svg6
-rw-r--r--editor/icons/icon_h_button_array.svg5
-rw-r--r--editor/icons/icon_onion.svg3
-rw-r--r--editor/icons/icon_v_button_array.svg6
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp12
-rw-r--r--editor/plugins/script_editor_plugin.cpp2
-rw-r--r--editor/property_editor.cpp34
-rw-r--r--editor/scene_tree_dock.cpp2
-rw-r--r--editor/script_editor_debugger.cpp199
-rw-r--r--editor/script_editor_debugger.h13
25 files changed, 481 insertions, 140 deletions
diff --git a/editor/dictionary_property_edit.cpp b/editor/dictionary_property_edit.cpp
new file mode 100644
index 0000000000..5b5a7ec9b0
--- /dev/null
+++ b/editor/dictionary_property_edit.cpp
@@ -0,0 +1,189 @@
+/*************************************************************************/
+/* dictionary_property_edit.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#include "dictionary_property_edit.h"
+#include "editor_node.h"
+
+void DictionaryPropertyEdit::_notif_change() {
+ _change_notify();
+}
+
+void DictionaryPropertyEdit::_notif_changev(const String &p_v) {
+ _change_notify(p_v.utf8().get_data());
+}
+
+void DictionaryPropertyEdit::_set_key(const Variant &p_old_key, const Variant &p_new_key) {
+
+ // TODO: Set key of a dictionary is not allowd yet
+ return;
+}
+
+void DictionaryPropertyEdit::_set_value(const Variant &p_key, const Variant &p_value) {
+
+ Dictionary dict = get_dictionary();
+ dict[p_key] = p_value;
+ Object *o = ObjectDB::get_instance(obj);
+ if (!o)
+ return;
+
+ o->set(property, dict);
+}
+
+Variant DictionaryPropertyEdit::get_dictionary() const {
+
+ Object *o = ObjectDB::get_instance(obj);
+ if (!o)
+ return Dictionary();
+ Variant dict = o->get(property);
+ if (dict.get_type() != Variant::DICTIONARY)
+ return Dictionary();
+ return dict;
+}
+
+void DictionaryPropertyEdit::_get_property_list(List<PropertyInfo> *p_list) const {
+
+ Dictionary dict = get_dictionary();
+
+ Array keys = dict.keys();
+ keys.sort();
+
+ for (int i = 0; i < keys.size(); i++) {
+ String index = itos(i);
+
+ const Variant &key = keys[i];
+ PropertyInfo pi(key.get_type(), index + ": key");
+ p_list->push_back(pi);
+
+ const Variant &value = dict[key];
+ pi = PropertyInfo(value.get_type(), index + ": value");
+ p_list->push_back(pi);
+ }
+}
+
+void DictionaryPropertyEdit::edit(Object *p_obj, const StringName &p_prop) {
+
+ property = p_prop;
+ obj = p_obj->get_instance_id();
+}
+
+Node *DictionaryPropertyEdit::get_node() {
+
+ Object *o = ObjectDB::get_instance(obj);
+ if (!o)
+ return NULL;
+
+ return cast_to<Node>(o);
+}
+
+void DictionaryPropertyEdit::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("_set_key"), &DictionaryPropertyEdit::_set_key);
+ ClassDB::bind_method(D_METHOD("_set_value"), &DictionaryPropertyEdit::_set_value);
+ ClassDB::bind_method(D_METHOD("_notif_change"), &DictionaryPropertyEdit::_notif_change);
+ ClassDB::bind_method(D_METHOD("_notif_changev"), &DictionaryPropertyEdit::_notif_changev);
+}
+
+bool DictionaryPropertyEdit::_set(const StringName &p_name, const Variant &p_value) {
+
+ Dictionary dict = get_dictionary();
+ Array keys = dict.keys();
+ keys.sort();
+
+ String pn = p_name;
+ int slash = pn.find(": ");
+ if (slash != -1 && pn.length() > slash) {
+ String type = pn.substr(slash + 2, pn.length());
+ int index = pn.substr(0, slash).to_int();
+ if (type == "key" && index < keys.size()) {
+
+ const Variant &key = keys[index];
+ UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
+
+ ur->create_action(TTR("Change Dictionary Key"));
+ ur->add_do_method(this, "_set_key", key, p_value);
+ ur->add_undo_method(this, "_set_key", p_value, key);
+ ur->add_do_method(this, "_notif_changev", p_name);
+ ur->add_undo_method(this, "_notif_changev", p_name);
+ ur->commit_action();
+
+ return true;
+ } else if (type == "value" && index < keys.size()) {
+ const Variant &key = keys[index];
+ if (dict.has(key)) {
+
+ Variant value = dict[key];
+ UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
+
+ ur->create_action(TTR("Change Dictionary Value"));
+ ur->add_do_method(this, "_set_value", key, p_value);
+ ur->add_undo_method(this, "_set_value", key, value);
+ ur->add_do_method(this, "_notif_changev", p_name);
+ ur->add_undo_method(this, "_notif_changev", p_name);
+ ur->commit_action();
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool DictionaryPropertyEdit::_get(const StringName &p_name, Variant &r_ret) const {
+
+ Dictionary dict = get_dictionary();
+ Array keys = dict.keys();
+ keys.sort();
+
+ String pn = p_name;
+ int slash = pn.find(": ");
+
+ if (slash != -1 && pn.length() > slash) {
+
+ String type = pn.substr(slash + 2, pn.length());
+ int index = pn.substr(0, slash).to_int();
+
+ if (type == "key" && index < keys.size()) {
+ r_ret = keys[index];
+ return true;
+ } else if (type == "value" && index < keys.size()) {
+ const Variant &key = keys[index];
+ if (dict.has(key)) {
+ r_ret = dict[key];
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+DictionaryPropertyEdit::DictionaryPropertyEdit() {
+ obj = 0;
+}
diff --git a/editor/dictionary_property_edit.h b/editor/dictionary_property_edit.h
new file mode 100644
index 0000000000..7a86727fb2
--- /dev/null
+++ b/editor/dictionary_property_edit.h
@@ -0,0 +1,62 @@
+/*************************************************************************/
+/* dictionary_property_edit.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#ifndef DICTIONARY_PROPERTY_EDIT_H
+#define DICTIONARY_PROPERTY_EDIT_H
+
+#include "scene/main/node.h"
+
+class DictionaryPropertyEdit : public Reference {
+ GDCLASS(DictionaryPropertyEdit, Reference);
+
+ ObjectID obj;
+ StringName property;
+
+ void _notif_change();
+ void _notif_changev(const String &p_v);
+ void _set_key(const Variant &p_old_key, const Variant &p_new_key);
+ void _set_value(const Variant &p_key, const Variant &p_value);
+
+ Variant get_dictionary() const;
+
+protected:
+ static void _bind_methods();
+ bool _set(const StringName &p_name, const Variant &p_value);
+ bool _get(const StringName &p_name, Variant &r_ret) const;
+ void _get_property_list(List<PropertyInfo> *p_list) const;
+
+public:
+ void edit(Object *p_obj, const StringName &p_prop);
+
+ Node *get_node();
+
+ DictionaryPropertyEdit();
+};
+
+#endif // DICTIONARY_PROPERTY_EDIT_H
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index c0e2e46f14..109f132d76 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -303,8 +303,7 @@ void EditorNode::_notification(int p_what) {
if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
scene_tabs->set_tab_close_display_policy((bool(EDITOR_DEF("interface/editor/always_show_close_button_in_scene_tabs", false)) ? Tabs::CLOSE_BUTTON_SHOW_ALWAYS : Tabs::CLOSE_BUTTON_SHOW_ACTIVE_ONLY));
- property_editor->set_enable_capitalize_paths(bool(EDITOR_DEF("interface/editor/capitalize_properties", true)));
- Ref<Theme> theme = create_custom_theme(theme_base->get_theme());
+ Ref<Theme> theme = create_editor_theme(theme_base->get_theme());
theme_base->set_theme(theme);
gui_base->set_theme(theme);
@@ -1368,6 +1367,8 @@ void EditorNode::_prepare_history() {
}
} else if (Object::cast_to<Node>(obj)) {
text = Object::cast_to<Node>(obj)->get_name();
+ } else if (obj->is_class("ScriptEditorDebuggerInspectedObject")) {
+ text = obj->call("get_title");
} else {
text = obj->get_class();
}
@@ -1463,6 +1464,7 @@ void EditorNode::_edit_current() {
object_menu->set_disabled(true);
+ bool capitalize = bool(EDITOR_DEF("interface/editor/capitalize_properties", true));
bool is_resource = current_obj->is_class("Resource");
bool is_node = current_obj->is_class("Node");
resource_save_button->set_disabled(!is_resource);
@@ -1516,6 +1518,11 @@ void EditorNode::_edit_current() {
} else {
+ if (current_obj->is_class("ScriptEditorDebuggerInspectedObject")) {
+ editable_warning = TTR("This is a remote object so changes to it will not be kept.\nPlease read the documentation relevant to debugging to better understand this workflow.");
+ capitalize = false;
+ }
+
property_editor->edit(current_obj);
node_dock->set_node(NULL);
}
@@ -1525,6 +1532,10 @@ void EditorNode::_edit_current() {
property_editable_warning_dialog->set_text(editable_warning);
}
+ if (property_editor->is_capitalize_paths_enabled() != capitalize) {
+ property_editor->set_enable_capitalize_paths(capitalize);
+ }
+
/* Take care of PLUGIN EDITOR */
EditorPlugin *main_plugin = editor_data.get_editor(current_obj);
diff --git a/editor/editor_path.cpp b/editor/editor_path.cpp
index 0587939a1a..f0d3c29c11 100644
--- a/editor/editor_path.cpp
+++ b/editor/editor_path.cpp
@@ -149,14 +149,14 @@ void EditorPath::_notification(int p_what) {
if (name == "")
name = r->get_class();
- } else if (Object::cast_to<Node>(obj)) {
-
+ } else if (obj->is_class("ScriptEditorDebuggerInspectedObject"))
+ name = obj->call("get_title");
+ else if (Object::cast_to<Node>(obj))
name = Object::cast_to<Node>(obj)->get_name();
- } else if (Object::cast_to<Resource>(obj) && Object::cast_to<Resource>(obj)->get_name() != "") {
+ else if (Object::cast_to<Resource>(obj) && Object::cast_to<Resource>(obj)->get_name() != "")
name = Object::cast_to<Resource>(obj)->get_name();
- } else {
+ else
name = obj->get_class();
- }
set_tooltip(obj->get_class());
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index d228dd2581..9817ce0047 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -135,7 +135,7 @@ bool EditorSettings::_get(const StringName &p_name, Variant &r_ret) const {
void EditorSettings::_initial_set(const StringName &p_name, const Variant &p_value) {
set(p_name, p_value);
props[p_name].initial = p_value;
- props[p_name].initial_set = true;
+ props[p_name].has_default_value = true;
}
struct _EVCSort {
@@ -221,7 +221,7 @@ bool EditorSettings::has_default_value(const String &p_setting) const {
if (!props.has(p_setting))
return false;
- return props[p_setting].initial_set;
+ return props[p_setting].has_default_value;
}
void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
@@ -424,6 +424,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("editors/2d/bone_ik_color", Color(0.9, 0.9, 0.45, 0.9));
_initial_set("editors/2d/keep_margins_when_changing_anchors", false);
_initial_set("editors/2d/warped_mouse_panning", true);
+ _initial_set("editors/2d/simple_spacebar_panning", false);
_initial_set("editors/2d/scroll_to_pan", false);
_initial_set("editors/2d/pan_speed", 20);
@@ -967,7 +968,7 @@ void EditorSettings::set_initial_value(const StringName &p_setting, const Varian
if (!props.has(p_setting))
return;
props[p_setting].initial = p_value;
- props[p_setting].initial_set = true;
+ props[p_setting].has_default_value = true;
}
Variant _EDITOR_DEF(const String &p_setting, const Variant &p_default) {
@@ -975,10 +976,10 @@ Variant _EDITOR_DEF(const String &p_setting, const Variant &p_default) {
Variant ret = p_default;
if (EditorSettings::get_singleton()->has_setting(p_setting))
ret = EditorSettings::get_singleton()->get(p_setting);
- if (!EditorSettings::get_singleton()->has_default_value(p_setting)) {
- EditorSettings::get_singleton()->set_initial_value(p_setting, p_default);
+ else
EditorSettings::get_singleton()->set(p_setting, p_default);
- }
+ if (!EditorSettings::get_singleton()->has_default_value(p_setting))
+ EditorSettings::get_singleton()->set_initial_value(p_setting, p_default);
return ret;
}
diff --git a/editor/editor_settings.h b/editor/editor_settings.h
index f11f4dfd43..a8c991a6d9 100644
--- a/editor/editor_settings.h
+++ b/editor/editor_settings.h
@@ -66,13 +66,13 @@ private:
int order;
Variant variant;
Variant initial;
- bool initial_set;
+ bool has_default_value;
bool hide_from_editor;
bool save;
VariantContainer() {
order = 0;
hide_from_editor = false;
- initial_set = false;
+ has_default_value = false;
save = false;
}
VariantContainer(const Variant &p_variant, int p_order) {
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 0f9f50095d..ae29b7420e 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -738,6 +738,13 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("button", "Tabs", style_menu);
theme->set_icon("increment", "TabContainer", theme->get_icon("GuiScrollArrowRight", "EditorIcons"));
theme->set_icon("decrement", "TabContainer", theme->get_icon("GuiScrollArrowLeft", "EditorIcons"));
+ theme->set_icon("increment", "Tabs", theme->get_icon("GuiScrollArrowRight", "EditorIcons"));
+ theme->set_icon("decrement", "Tabs", theme->get_icon("GuiScrollArrowLeft", "EditorIcons"));
+ theme->set_icon("increment_highlight", "Tabs", theme->get_icon("GuiScrollArrowRight", "EditorIcons"));
+ theme->set_icon("decrement_highlight", "Tabs", theme->get_icon("GuiScrollArrowLeft", "EditorIcons"));
+ theme->set_icon("increment_highlight", "TabContainer", theme->get_icon("GuiScrollArrowRight", "EditorIcons"));
+ theme->set_icon("decrement_highlight", "TabContainer", theme->get_icon("GuiScrollArrowLeft", "EditorIcons"));
+ theme->set_constant("hseparation", "Tabs", 4 * EDSCALE);
// Content of each tab
Ref<StyleBoxFlat> style_content_panel = style_default->duplicate();
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index eea8177687..9c432323f4 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -1447,6 +1447,15 @@ void FileSystemDock::_files_list_rmb_select(int p_item, const Vector2 &p_pos) {
file_options->popup();
}
+void FileSystemDock::_rmb_pressed(const Vector2 &p_pos) {
+ folder_options->clear();
+ folder_options->set_size(Size2(1, 1));
+
+ folder_options->add_item(TTR("New Folder.."), FOLDER_NEW_FOLDER);
+ folder_options->set_position(files->get_global_position() + p_pos);
+ folder_options->popup();
+}
+
void FileSystemDock::select_file(const String &p_file) {
navigate_to_path(p_file);
@@ -1547,6 +1556,7 @@ void FileSystemDock::_bind_methods() {
ClassDB::bind_method(D_METHOD("_file_selected"), &FileSystemDock::_file_selected);
ClassDB::bind_method(D_METHOD("_file_multi_selected"), &FileSystemDock::_file_multi_selected);
ClassDB::bind_method(D_METHOD("_update_import_dock"), &FileSystemDock::_update_import_dock);
+ ClassDB::bind_method(D_METHOD("_rmb_pressed"), &FileSystemDock::_rmb_pressed);
ADD_SIGNAL(MethodInfo("instance", PropertyInfo(Variant::POOL_STRING_ARRAY, "files")));
ADD_SIGNAL(MethodInfo("open"));
@@ -1665,6 +1675,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
files->connect("item_rmb_selected", this, "_files_list_rmb_select");
files->connect("item_selected", this, "_file_selected");
files->connect("multi_selected", this, "_file_multi_selected");
+ files->connect("rmb_clicked", this, "_rmb_pressed");
files->set_allow_rmb_select(true);
file_list_vb->add_child(files);
diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h
index d100de8b72..f1fd342052 100644
--- a/editor/filesystem_dock.h
+++ b/editor/filesystem_dock.h
@@ -192,6 +192,7 @@ private:
void _dir_rmb_pressed(const Vector2 &p_pos);
void _files_list_rmb_select(int p_item, const Vector2 &p_pos);
+ void _rmb_pressed(const Vector2 &p_pos);
struct FileInfo {
String name;
diff --git a/editor/icons/icon_GUI_ellipsis.svg b/editor/icons/icon_GUI_ellipsis.svg
new file mode 100644
index 0000000000..5565fd2947
--- /dev/null
+++ b/editor/icons/icon_GUI_ellipsis.svg
@@ -0,0 +1,5 @@
+<svg width="14" height="8" version="1.1" viewBox="0 0 14 8" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -1044.4)">
+<path transform="translate(0 1040.4)" d="m3.8594 4c-2.1381 0-3.8594 1.7213-3.8594 3.8594v0.28125c0 2.1381 1.7213 3.8594 3.8594 3.8594h6.2812c2.1381 0 3.8594-1.7213 3.8594-3.8594v-0.28125c0-2.1381-1.7213-3.8594-3.8594-3.8594zm-0.85938 3a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm4 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm4 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1z" fill="#fff" fill-opacity=".39216"/>
+</g>
+</svg>
diff --git a/editor/icons/icon_animation.svg b/editor/icons/icon_animation.svg
index 146403ece5..600faeeddb 100644
--- a/editor/icons/icon_animation.svg
+++ b/editor/icons/icon_animation.svg
@@ -1,5 +1,3 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 2a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 4 -1.5352v1.5352h0.001953a2 2 0 0 0 0.26562 1 2 2 0 0 0 1.7324 1h1v-1-1h-0.5a0.5 0.49999 0 0 1 -0.5 -0.5v-0.5-5a6 6 0 0 0 -6 -6zm0 1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm3.4414 2a1 1 0 0 1 0.88867 0.5 1 1 0 0 1 -0.36523 1.3652 1 1 0 0 1 -1.3672 -0.36523 1 1 0 0 1 0.36719 -1.3652 1 1 0 0 1 0.47656 -0.13477zm-6.9531 0.0019531a1 1 0 0 1 0.54688 0.13281 1 1 0 0 1 0.36719 1.3652 1 1 0 0 1 -1.3672 0.36523 1 1 0 0 1 -0.36523 -1.3652 1 1 0 0 1 0.81836 -0.49805zm0.023438 3.998a1 1 0 0 1 0.89062 0.5 1 1 0 0 1 -0.36719 1.3652 1 1 0 0 1 -1.3652 -0.36523 1 1 0 0 1 0.36523 -1.3652 1 1 0 0 1 0.47656 -0.13477zm6.9043 0.0019531a1 1 0 0 1 0.54883 0.13281 1 1 0 0 1 0.36523 1.3652 1 1 0 0 1 -1.3652 0.36523 1 1 0 0 1 -0.36719 -1.3652 1 1 0 0 1 0.81836 -0.49805zm-3.416 1.998a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1z" fill="#e0e0e0"/>
-</g>
+<path d="m8 2a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 4 -1.5352v1.5352h0.001953a2 2 0 0 0 0.26562 1 2 2 0 0 0 1.7324 1h1v-1-1h-0.5a0.5 0.49999 0 0 1 -0.5 -0.5v-0.5-5a6 6 0 0 0 -6 -6zm0 1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm3.4414 2a1 1 0 0 1 0.88867 0.5 1 1 0 0 1 -0.36523 1.3652 1 1 0 0 1 -1.3672 -0.36523 1 1 0 0 1 0.36719 -1.3652 1 1 0 0 1 0.47656 -0.13477zm-6.9531 0.0019531a1 1 0 0 1 0.54688 0.13281 1 1 0 0 1 0.36719 1.3652 1 1 0 0 1 -1.3672 0.36523 1 1 0 0 1 -0.36523 -1.3652 1 1 0 0 1 0.81836 -0.49805zm0.023438 3.998a1 1 0 0 1 0.89062 0.5 1 1 0 0 1 -0.36719 1.3652 1 1 0 0 1 -1.3652 -0.36523 1 1 0 0 1 0.36523 -1.3652 1 1 0 0 1 0.47656 -0.13477zm6.9043 0.0019531a1 1 0 0 1 0.54883 0.13281 1 1 0 0 1 0.36523 1.3652 1 1 0 0 1 -1.3652 0.36523 1 1 0 0 1 -0.36719 -1.3652 1 1 0 0 1 0.81836 -0.49805zm-3.416 1.998a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1z" fill="#e0e0e0"/>
</svg>
diff --git a/editor/icons/icon_area.svg b/editor/icons/icon_area.svg
index ac673d10fc..5e1a385f58 100644
--- a/editor/icons/icon_area.svg
+++ b/editor/icons/icon_area.svg
@@ -1,5 +1,3 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m1 1v2 2h2v-2h2v-2h-4zm10 0v2h2v2h2v-4h-4zm-7 3v2 4 2h8v-2-6h-8zm2 2h4v4h-4v-4zm-5 5v2 2h2 2v-2h-2v-2h-2zm12 0v2h-2v2h4v-2-2h-2z" fill="#fc9c9c"/>
-</g>
+<path d="m1 1v2 2h2v-2h2v-2h-4zm10 0v2h2v2h2v-4h-4zm-7 3v2 4 2h8v-2-6h-8zm2 2h4v4h-4v-4zm-5 5v2 2h2 2v-2h-2v-2h-2zm12 0v2h-2v2h4v-2-2h-2z" fill="#fc9c9c"/>
</svg>
diff --git a/editor/icons/icon_area_2d.svg b/editor/icons/icon_area_2d.svg
index d6ecb6abe5..28fc4d7804 100644
--- a/editor/icons/icon_area_2d.svg
+++ b/editor/icons/icon_area_2d.svg
@@ -1,5 +1,3 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m1 1v2 2h2v-2h2v-2h-4zm10 0v2h2v2h2v-4h-4zm-7 3v2 4 2h8v-2-6h-8zm2 2h4v4h-4v-4zm-5 5v2 2h2 2v-2h-2v-2h-2zm12 0v2h-2v2h4v-2-2h-2z" fill="#a5b7f3"/>
-</g>
+<path d="m1 1v2 2h2v-2h2v-2h-4zm10 0v2h2v2h2v-4h-4zm-7 3v2 4 2h8v-2-6h-8zm2 2h4v4h-4v-4zm-5 5v2 2h2 2v-2h-2v-2h-2zm12 0v2h-2v2h4v-2-2h-2z" fill="#a5b7f3"/>
</svg>
diff --git a/editor/icons/icon_array_mesh.svg b/editor/icons/icon_array_mesh.svg
index 68890c4366..867fc95b0c 100644
--- a/editor/icons/icon_array_mesh.svg
+++ b/editor/icons/icon_array_mesh.svg
@@ -1,5 +1,3 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm10 0a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm-2 7v3h-3v2h3v3h2v-3h3v-2h-3v-3h-2zm-8 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#ffd684" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
+<path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm10 0a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm-2 7v3h-3v2h3v3h2v-3h3v-2h-3v-3h-2zm-8 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#ffd684" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
</svg>
diff --git a/editor/icons/icon_editor_handle_add.svg b/editor/icons/icon_editor_handle_add.svg
deleted file mode 100644
index 0e7fe7129a..0000000000
--- a/editor/icons/icon_editor_handle_add.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="8" height="8" version="1.1" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
- <g transform="translate(0 -1044.4)">
- <ellipse cx="4" cy="1048.4" rx="4" ry="4" fill="#fff"/>
- <ellipse cx="4" cy="1048.4" rx="2.8572" ry="2.8571" fill="#84ff84"/>
- </g>
-</svg>
diff --git a/editor/icons/icon_editor_handle_selected.svg b/editor/icons/icon_editor_handle_selected.svg
deleted file mode 100644
index 8d338c1fbd..0000000000
--- a/editor/icons/icon_editor_handle_selected.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="8" height="8" version="1.1" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
- <g transform="translate(0 -1044.4)">
- <ellipse cx="4" cy="1048.4" rx="4" ry="4" fill="#fff"/>
- <ellipse cx="4" cy="1048.4" rx="2.8572" ry="2.8571" fill="#8484ff"/>
- </g>
-</svg>
diff --git a/editor/icons/icon_h_button_array.svg b/editor/icons/icon_h_button_array.svg
deleted file mode 100644
index 3f95dbbde1..0000000000
--- a/editor/icons/icon_h_button_array.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m4 1v3.1328l-1.4453-0.96484-1.1094 1.6641 3 2c0.3359 0.2239 0.77347 0.2239 1.1094 0l3-2-1.1094-1.6641-1.4453 0.96484v-3.1328h-2zm8 4v2h-2v2h2v2h2v-2h2v-2h-2v-2h-2zm-8.5 4c-0.831 0-1.5 0.669-1.5 1.5v0.5 1h-1v2h8v-2h-1v-1-0.5c0-0.831-0.669-1.5-1.5-1.5h-3z" fill="#a5efac"/>
-</g>
-</svg>
diff --git a/editor/icons/icon_onion.svg b/editor/icons/icon_onion.svg
new file mode 100644
index 0000000000..5bb2a99423
--- /dev/null
+++ b/editor/icons/icon_onion.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<path d="m8 1c-2 2-7 4-7 8s3 6 7 6c-7-3-6.5995-7.703 0-13-2.2981 3.9516-5.4951 8.9197 0 13 4.8692-4.2391 2.7733-8.1815 1-12 5.5855 4.704 5.3995 8.6488-1 12 4 0 7-2 7-6s-5-6-7-8z" fill="#e0e0e0"/>
+</svg>
diff --git a/editor/icons/icon_v_button_array.svg b/editor/icons/icon_v_button_array.svg
deleted file mode 100644
index ac7ce6064c..0000000000
--- a/editor/icons/icon_v_button_array.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#a5efac">
-<path transform="translate(0 1036.4)" d="m7 1v2.1328l-1.4453-0.96484-1.1094 1.6641 3 2c0.3359 0.2239 0.77347 0.2239 1.1094 0l3-2-1.1094-1.6641-1.4453 0.96484v-2.1328h-2zm-0.5 6c-0.831 0-1.5 0.669-1.5 1.5v0.5h-1v2h2v-2h4v2h2v-2h-1v-0.5c0-0.831-0.669-1.5-1.5-1.5h-3z"/>
-<path d="m7 1046.4v2h-2v2h2v2h2v-2h2v-2h-2v-2z"/>
-</g>
-</svg>
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index b6ba09fb58..6cb4171f5a 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -1858,7 +1858,17 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) {
}
if (drag == DRAG_NONE) {
- if (((m->get_button_mask() & BUTTON_MASK_LEFT) && tool == TOOL_PAN) || (m->get_button_mask() & BUTTON_MASK_MIDDLE) || ((m->get_button_mask() & BUTTON_MASK_LEFT) && Input::get_singleton()->is_key_pressed(KEY_SPACE))) {
+ bool space_pressed = Input::get_singleton()->is_key_pressed(KEY_SPACE);
+ bool simple_panning = EditorSettings::get_singleton()->get("editors/2d/simple_spacebar_panning");
+ int button = m->get_button_mask();
+
+ // Check if any of the panning triggers are activated
+ bool panning_tool = (button & BUTTON_MASK_LEFT) && tool == TOOL_PAN;
+ bool panning_middle_button = button & BUTTON_MASK_MIDDLE;
+ bool panning_spacebar = (button & BUTTON_MASK_LEFT) && space_pressed;
+ bool panning_spacebar_simple = space_pressed && simple_panning;
+
+ if (panning_tool || panning_middle_button || panning_spacebar || panning_spacebar_simple) {
// Pan the viewport
Point2i relative;
if (bool(EditorSettings::get_singleton()->get("editors/2d/warped_mouse_panning"))) {
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 32ec9b2ba9..3c2d52c128 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -2897,7 +2897,7 @@ ScriptEditorPlugin::ScriptEditorPlugin(EditorNode *p_node) {
EDITOR_DEF("text_editor/open_scripts/script_temperature_enabled", true);
EDITOR_DEF("text_editor/open_scripts/highlight_current_script", true);
EDITOR_DEF("text_editor/open_scripts/script_temperature_history_size", 15);
- EDITOR_DEF("text_editor/open_scripts/current_script_background_color", Color(1, 1, 1, 0.5));
+ EDITOR_DEF("text_editor/open_scripts/current_script_background_color", Color(1, 1, 1, 0.3));
EDITOR_DEF("text_editor/open_scripts/group_help_pages", true);
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "text_editor/open_scripts/sort_scripts_by", PROPERTY_HINT_ENUM, "Name,Path"));
EDITOR_DEF("text_editor/open_scripts/sort_scripts_by", 0);
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index 9733f49f42..bc7d8f4b14 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -40,6 +40,7 @@
#include "core/project_settings.h"
#include "editor/array_property_edit.h"
#include "editor/create_dialog.h"
+#include "editor/dictionary_property_edit.h"
#include "editor/editor_export.h"
#include "editor/editor_file_system.h"
#include "editor/editor_help.h"
@@ -1157,7 +1158,8 @@ void CustomPropertyEditor::_node_path_selected(NodePath p_path) {
node = Object::cast_to<Node>(owner);
else if (owner->is_class("ArrayPropertyEdit"))
node = Object::cast_to<ArrayPropertyEdit>(owner)->get_node();
-
+ else if (owner->is_class("DictionaryPropertyEdit"))
+ node = Object::cast_to<DictionaryPropertyEdit>(owner)->get_node();
if (!node) {
v = p_path;
emit_signal("variant_changed");
@@ -3215,9 +3217,14 @@ void PropertyEditor::update_tree() {
} break;
case Variant::DICTIONARY: {
+ Variant v = obj->get(p.name);
+
item->set_cell_mode(1, TreeItem::CELL_MODE_STRING);
- item->set_editable(1, false);
- item->set_text(1, obj->get(p.name).operator String());
+ item->set_text(1, String("Dictionary{") + itos(v.call("size")) + "}");
+ item->add_button(1, get_icon("EditResource", "EditorIcons"));
+
+ if (show_type_icons)
+ item->set_icon(0, get_icon("DictionaryData", "EditorIcons"));
} break;
@@ -3416,7 +3423,9 @@ void PropertyEditor::update_tree() {
type = p.hint_string;
RES res = obj->get(p.name).operator RefPtr();
-
+ if (type.begins_with("RES:") && type != "RES:") { // Remote resources
+ res = ResourceLoader::load(type.substr(4, type.length()));
+ }
Ref<EncodedObjectAsID> encoded = obj->get(p.name); //for debugger and remote tools
if (encoded.is_valid()) {
@@ -3427,6 +3436,7 @@ void PropertyEditor::update_tree() {
item->set_editable(1, true);
} else if (obj->get(p.name).get_type() == Variant::NIL || res.is_null()) {
+
item->set_text(1, "<null>");
item->set_icon(1, Ref<Texture>());
item->set_custom_as_button(1, false);
@@ -3585,7 +3595,7 @@ void PropertyEditor::_edit_set(const String &p_name, const Variant &p_value, boo
}
}
- if (!undo_redo || Object::cast_to<ArrayPropertyEdit>(obj)) { //kind of hacky
+ if (!undo_redo || Object::cast_to<ArrayPropertyEdit>(obj) || Object::cast_to<DictionaryPropertyEdit>(obj)) { //kind of hacky
obj->set(p_name, p_value);
if (p_refresh_all)
@@ -3983,8 +3993,20 @@ void PropertyEditor::_edit_button(Object *p_item, int p_column, int p_button) {
Ref<ArrayPropertyEdit> ape = memnew(ArrayPropertyEdit);
ape->edit(obj, n, ht, Variant::Type(t));
-
EditorNode::get_singleton()->push_item(ape.ptr());
+
+ } else if (t == Variant::DICTIONARY) {
+
+ Variant v = obj->get(n);
+
+ if (v.get_type() != t) {
+ Variant::CallError ce;
+ v = Variant::construct(Variant::Type(t), NULL, 0, ce);
+ }
+
+ Ref<DictionaryPropertyEdit> dpe = memnew(DictionaryPropertyEdit);
+ dpe->edit(obj, n);
+ EditorNode::get_singleton()->push_item(dpe.ptr());
}
}
}
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index e7e57a7079..1d2647badc 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -1853,6 +1853,8 @@ void SceneTreeDock::_local_tree_selected() {
remote_tree->hide();
edit_remote->set_pressed(false);
edit_local->set_pressed(true);
+
+ _node_selected();
}
void SceneTreeDock::_bind_methods() {
diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp
index bc2423fffd..2a3e47b2a6 100644
--- a/editor/script_editor_debugger.cpp
+++ b/editor/script_editor_debugger.cpp
@@ -116,7 +116,7 @@ class ScriptEditorDebuggerInspectedObject : public Object {
protected:
bool _set(const StringName &p_name, const Variant &p_value) {
- if (!prop_values.has(p_name))
+ if (!prop_values.has(p_name) || String(p_name).begins_with("Constants/"))
return false;
emit_signal("value_edited", p_name, p_value);
@@ -132,6 +132,7 @@ protected:
r_ret = prop_values[p_name];
return true;
}
+
void _get_property_list(List<PropertyInfo> *p_list) const {
p_list->clear(); //sorry, no want category
@@ -142,23 +143,52 @@ protected:
static void _bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_title"), &ScriptEditorDebuggerInspectedObject::get_title);
+ ClassDB::bind_method(D_METHOD("get_variant"), &ScriptEditorDebuggerInspectedObject::get_variant);
+ ClassDB::bind_method(D_METHOD("clear"), &ScriptEditorDebuggerInspectedObject::clear);
+ ClassDB::bind_method(D_METHOD("get_remote_object_id"), &ScriptEditorDebuggerInspectedObject::get_remote_object_id);
+
ADD_SIGNAL(MethodInfo("value_edited"));
}
public:
- ObjectID last_edited_id;
+ String type_name;
+ ObjectID remote_object_id;
List<PropertyInfo> prop_list;
Map<StringName, Variant> prop_values;
+ ObjectID get_remote_object_id() {
+ return remote_object_id;
+ }
+
+ String get_title() {
+ if (remote_object_id)
+ return TTR("Remote ") + String(type_name) + ": " + itos(remote_object_id);
+ else
+ return "<null>";
+ }
+ Variant get_variant(const StringName &p_name) {
+
+ Variant var;
+ _get(p_name, var);
+ return var;
+ }
+
+ void clear() {
+
+ prop_list.clear();
+ prop_values.clear();
+ }
void update() {
_change_notify();
}
-
void update_single(const char *p_prop) {
_change_notify(p_prop);
}
- ScriptEditorDebuggerInspectedObject() { last_edited_id = 0; }
+ ScriptEditorDebuggerInspectedObject() {
+ remote_object_id = 0;
+ }
};
void ScriptEditorDebugger::debug_next() {
@@ -297,7 +327,6 @@ Size2 ScriptEditorDebugger::get_minimum_size() const {
void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_data) {
if (p_msg == "debug_enter") {
-
Array msg;
msg.push_back("get_stack_dump");
ppeer->put_var(msg);
@@ -315,12 +344,10 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
if (error != "") {
tabs->set_current_tab(0);
}
-
profiler->set_enabled(false);
-
EditorNode::get_singleton()->get_pause_button()->set_pressed(true);
-
EditorNode::get_singleton()->make_bottom_panel_item_visible(this);
+ _clear_remote_objects();
} else if (p_msg == "debug_exit") {
@@ -337,9 +364,8 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
//tabs->set_current_tab(0);
profiler->set_enabled(true);
profiler->disable_seeking();
-
+ inspector->edit(NULL);
EditorNode::get_singleton()->get_pause_button()->set_pressed(false);
-
} else if (p_msg == "message:click_ctrl") {
clicked_ctrl->set_text(p_data[0]);
@@ -399,55 +425,57 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
le_set->set_disabled(false);
} else if (p_msg == "message:inspect_object") {
+ ScriptEditorDebuggerInspectedObject *debugObj = NULL;
+
ObjectID id = p_data[0];
String type = p_data[1];
- Variant path = p_data[2]; //what to do yet, i don't know
- int prop_count = p_data[3];
-
- int idx = 4;
+ Array properties = p_data[2];
- if (inspected_object->last_edited_id != id) {
- inspected_object->prop_list.clear();
- inspected_object->prop_values.clear();
+ bool is_new_object = false;
+ if (remote_objects.has(id)) {
+ debugObj = remote_objects[id];
+ } else {
+ debugObj = memnew(ScriptEditorDebuggerInspectedObject);
+ debugObj->remote_object_id = id;
+ debugObj->type_name = type;
+ remote_objects[id] = debugObj;
+ is_new_object = true;
+ debugObj->connect("value_edited", this, "_scene_tree_property_value_edited");
}
- for (int i = 0; i < prop_count; i++) {
+ for (int i = 0; i < properties.size(); i++) {
+
+ Array prop = properties[i];
+ if (prop.size() != 6)
+ continue;
PropertyInfo pinfo;
- pinfo.name = p_data[idx++];
- pinfo.type = Variant::Type(int(p_data[idx++]));
- pinfo.hint = PropertyHint(int(p_data[idx++]));
- pinfo.hint_string = p_data[idx++];
- if (pinfo.name.begins_with("*")) {
- pinfo.name = pinfo.name.substr(1, pinfo.name.length());
- pinfo.usage = PROPERTY_USAGE_CATEGORY;
- } else {
- pinfo.usage = PROPERTY_USAGE_EDITOR;
+ pinfo.name = prop[0];
+ pinfo.type = Variant::Type(int(prop[1]));
+ pinfo.hint = PropertyHint(int(prop[2]));
+ pinfo.hint_string = prop[3];
+ pinfo.usage = PropertyUsageFlags(int(prop[4]));
+ Variant var = prop[5];
+
+ String hint_string = pinfo.hint_string;
+ if (hint_string.begins_with("RES:") && hint_string != "RES:") {
+ String path = hint_string.substr(4, hint_string.length());
+ var = ResourceLoader::load(path);
}
- if (inspected_object->last_edited_id != id) {
+ if (is_new_object) {
//don't update.. it's the same, instead refresh
- inspected_object->prop_list.push_back(pinfo);
+ debugObj->prop_list.push_back(pinfo);
}
- inspected_object->prop_values[pinfo.name] = p_data[idx++];
-
- if (inspected_object->last_edited_id == id) {
- //same, just update value, don't rebuild
- inspected_object->update_single(pinfo.name.ascii().get_data());
- }
+ debugObj->prop_values[pinfo.name] = var;
}
- if (inspected_object->last_edited_id != id) {
- //only if different
- inspected_object->update();
+ if (editor->get_editor_history()->get_current() != debugObj->get_instance_id()) {
+ editor->push_item(debugObj, "");
+ } else {
+ debugObj->update();
}
-
- inspected_object->last_edited_id = id;
-
- tabs->set_current_tab(inspect_info->get_index());
- inspect_properties->edit(inspected_object);
-
} else if (p_msg == "message:video_mem") {
vmem_tree->clear();
@@ -502,7 +530,6 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
int ofs = 0;
int mcount = p_data[ofs];
-
ofs++;
for (int i = 0; i < mcount; i++) {
@@ -521,12 +548,34 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
v = s.get_slice(":", 1).to_int();
}
- variables->add_property("members/" + n, v, h, hs);
+ variables->add_property("Locals/" + n, v, h, hs);
}
- ofs += mcount * 2;
+ ofs += mcount * 2;
mcount = p_data[ofs];
+ ofs++;
+ for (int i = 0; i < mcount; i++) {
+
+ String n = p_data[ofs + i * 2 + 0];
+ Variant v = p_data[ofs + i * 2 + 1];
+ PropertyHint h = PROPERTY_HINT_NONE;
+ String hs = String();
+
+ if (n.begins_with("*")) {
+
+ n = n.substr(1, n.length());
+ h = PROPERTY_HINT_OBJECT_ID;
+ String s = v;
+ s = s.replace("[", "");
+ hs = s.get_slice(":", 0);
+ v = s.get_slice(":", 1).to_int();
+ }
+
+ variables->add_property("Members/" + n, v, h, hs);
+ }
+ ofs += mcount * 2;
+ mcount = p_data[ofs];
ofs++;
for (int i = 0; i < mcount; i++) {
@@ -545,7 +594,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
v = s.get_slice(":", 1).to_int();
}
- variables->add_property("locals/" + n, v, h, hs);
+ variables->add_property("Globals/" + n, v, h, hs);
}
variables->update();
@@ -1101,6 +1150,8 @@ void ScriptEditorDebugger::start() {
EditorNode::get_log()->add_message(String("Error listening on port ") + itos(remote_port), true);
return;
}
+
+ EditorNode::get_singleton()->get_scene_tree_dock()->show_remote_tree();
set_process(true);
}
@@ -1133,11 +1184,11 @@ void ScriptEditorDebugger::stop() {
le_set->set_disabled(true);
profiler->set_enabled(true);
- inspect_properties->edit(NULL);
inspect_scene_tree->clear();
EditorNode::get_singleton()->get_pause_button()->set_pressed(false);
EditorNode::get_singleton()->get_pause_button()->set_disabled(true);
+ EditorNode::get_singleton()->get_scene_tree_dock()->hide_remote_tree();
if (hide_on_stop) {
if (is_visible_in_tree())
@@ -1604,6 +1655,24 @@ void ScriptEditorDebugger::_paused() {
}
}
+void ScriptEditorDebugger::_set_remote_object(ObjectID p_id, ScriptEditorDebuggerInspectedObject *p_obj) {
+
+ if (remote_objects.has(p_id))
+ memdelete(remote_objects[p_id]);
+ remote_objects[p_id] = p_obj;
+}
+
+void ScriptEditorDebugger::_clear_remote_objects() {
+
+ for (Map<ObjectID, ScriptEditorDebuggerInspectedObject *>::Element *E = remote_objects.front(); E; E = E->next()) {
+ if (editor->get_editor_history()->get_current() == E->value()->get_instance_id()) {
+ editor->push_item(NULL);
+ }
+ memdelete(E->value());
+ }
+ remote_objects.clear();
+}
+
void ScriptEditorDebugger::_bind_methods() {
ClassDB::bind_method(D_METHOD("_stack_dump_frame_selected"), &ScriptEditorDebugger::_stack_dump_frame_selected);
@@ -1649,6 +1718,7 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
ppeer = Ref<PacketPeerStream>(memnew(PacketPeerStream));
ppeer->set_input_buffer_max_size(1024 * 1024 * 8); //8mb should be enough
editor = p_editor;
+ editor->get_property_editor()->connect("object_id_selected", this, "_scene_tree_property_select_object");
tabs = memnew(TabContainer);
tabs->set_tab_align(TabContainer::ALIGN_LEFT);
@@ -1761,41 +1831,18 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
tabs->add_child(error_split);
}
- { // inquire
-
- inspect_info = memnew(HSplitContainer);
- inspect_info->set_name(TTR("Remote Inspector"));
- tabs->add_child(inspect_info);
-
- VBoxContainer *info_left = memnew(VBoxContainer);
- info_left->set_h_size_flags(SIZE_EXPAND_FILL);
- inspect_info->add_child(info_left);
+ { // remote scene tree
inspect_scene_tree = memnew(Tree);
- info_left->add_margin_child(TTR("Live Scene Tree:"), inspect_scene_tree, true);
+ EditorNode::get_singleton()->get_scene_tree_dock()->add_remote_tree_editor(inspect_scene_tree);
+ inspect_scene_tree->set_v_size_flags(SIZE_EXPAND_FILL);
inspect_scene_tree->connect("cell_selected", this, "_scene_tree_selected");
inspect_scene_tree->connect("item_collapsed", this, "_scene_tree_folded");
- //
-
- VBoxContainer *info_right = memnew(VBoxContainer);
- info_right->set_h_size_flags(SIZE_EXPAND_FILL);
- inspect_info->add_child(info_right);
-
- inspect_properties = memnew(PropertyEditor);
- inspect_properties->hide_top_label();
- inspect_properties->set_show_categories(true);
- inspect_properties->connect("object_id_selected", this, "_scene_tree_property_select_object");
-
- info_right->add_margin_child(TTR("Remote Object Properties: "), inspect_properties, true);
-
inspect_scene_tree_timeout = EDITOR_DEF("debugger/scene_tree_refresh_interval", 1.0);
inspect_edited_object_timeout = EDITOR_DEF("debugger/remote_inspect_refresh_interval", 0.2);
inspected_object_id = 0;
updating_scene_tree = false;
-
- inspected_object = memnew(ScriptEditorDebuggerInspectedObject);
- inspected_object->connect("value_edited", this, "_scene_tree_property_value_edited");
}
{ //profiler
@@ -1952,5 +1999,5 @@ ScriptEditorDebugger::~ScriptEditorDebugger() {
ppeer->set_stream_peer(Ref<StreamPeer>());
server->stop();
- memdelete(inspected_object);
+ _clear_remote_objects();
}
diff --git a/editor/script_editor_debugger.h b/editor/script_editor_debugger.h
index d18a625eef..dc851dd575 100644
--- a/editor/script_editor_debugger.h
+++ b/editor/script_editor_debugger.h
@@ -72,19 +72,18 @@ class ScriptEditorDebugger : public Control {
Button *le_set;
Button *le_clear;
- Tree *inspect_scene_tree;
- HSplitContainer *inspect_info;
- PropertyEditor *inspect_properties;
+ bool updating_scene_tree;
float inspect_scene_tree_timeout;
float inspect_edited_object_timeout;
ObjectID inspected_object_id;
- ScriptEditorDebuggerInspectedObject *inspected_object;
- bool updating_scene_tree;
+ ScriptEditorDebuggerVariables *variables;
+ Map<ObjectID, ScriptEditorDebuggerInspectedObject *> remote_objects;
Set<ObjectID> unfold_cache;
HSplitContainer *error_split;
ItemList *error_list;
ItemList *error_stack;
+ Tree *inspect_scene_tree;
int error_count;
int last_error_count;
@@ -96,7 +95,6 @@ class ScriptEditorDebugger : public Control {
TabContainer *tabs;
Label *reason;
- ScriptEditorDebuggerVariables *variables;
Button *step;
Button *next;
@@ -174,6 +172,9 @@ class ScriptEditorDebugger : public Control {
void _paused();
+ void _set_remote_object(ObjectID p_id, ScriptEditorDebuggerInspectedObject *p_obj);
+ void _clear_remote_objects();
+
protected:
void _notification(int p_what);
static void _bind_methods();