summaryrefslogtreecommitdiff
path: root/editor/editor_inspector.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/editor_inspector.cpp')
-rw-r--r--editor/editor_inspector.cpp209
1 files changed, 144 insertions, 65 deletions
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index 702e6a12e5..ecb9ea5f35 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -80,6 +80,14 @@ Size2 EditorProperty::get_minimum_size() const {
return ms;
}
+void EditorProperty::emit_changed(const StringName &p_property, const Variant &p_value, const StringName &p_field, bool p_changing) {
+
+ Variant args[4] = { p_property, p_value, p_field, p_changing };
+ const Variant *argptrs[4] = { &args[0], &args[1], &args[2], &args[3] };
+
+ emit_signal("property_changed", (const Variant **)argptrs, 4);
+}
+
void EditorProperty::_notification(int p_what) {
if (p_what == NOTIFICATION_SORT_CHILDREN) {
@@ -203,42 +211,43 @@ void EditorProperty::_notification(int p_what) {
}
int ofs = 0;
+ int text_limit = text_size;
+
if (checkable) {
Ref<Texture> checkbox;
if (checked)
- checkbox = get_icon("checked", "CheckBox");
+ checkbox = get_icon("GuiChecked", "EditorIcons");
else
- checkbox = get_icon("unchecked", "CheckBox");
+ checkbox = get_icon("GuiUnchecked", "EditorIcons");
- Color color(1, 1, 1);
+ Color color2(1, 1, 1);
if (check_hover) {
- color.r *= 1.2;
- color.g *= 1.2;
- color.b *= 1.2;
+ color2.r *= 1.2;
+ color2.g *= 1.2;
+ color2.b *= 1.2;
}
check_rect = Rect2(ofs, ((size.height - checkbox->get_height()) / 2), checkbox->get_width(), checkbox->get_height());
- draw_texture(checkbox, check_rect.position, color);
+ draw_texture(checkbox, check_rect.position, color2);
ofs += get_constant("hseparator", "Tree");
ofs += checkbox->get_width();
+ text_limit -= ofs;
} else {
check_rect = Rect2();
}
- int text_limit = text_size;
-
if (can_revert) {
Ref<Texture> reload_icon = get_icon("ReloadSmall", "EditorIcons");
text_limit -= reload_icon->get_width() + get_constant("hseparator", "Tree") * 2;
revert_rect = Rect2(text_limit + get_constant("hseparator", "Tree"), (size.height - reload_icon->get_height()) / 2, reload_icon->get_width(), reload_icon->get_height());
- Color color(1, 1, 1);
+ Color color2(1, 1, 1);
if (revert_hover) {
- color.r *= 1.2;
- color.g *= 1.2;
- color.b *= 1.2;
+ color2.r *= 1.2;
+ color2.g *= 1.2;
+ color2.b *= 1.2;
}
- draw_texture(reload_icon, revert_rect.position, color);
+ draw_texture(reload_icon, revert_rect.position, color2);
} else {
revert_rect = Rect2();
}
@@ -257,14 +266,14 @@ void EditorProperty::_notification(int p_what) {
ofs = size.width - key->get_width() - get_constant("hseparator", "Tree");
- Color color(1, 1, 1);
+ Color color2(1, 1, 1);
if (keying_hover) {
- color.r *= 1.2;
- color.g *= 1.2;
- color.b *= 1.2;
+ color2.r *= 1.2;
+ color2.g *= 1.2;
+ color2.b *= 1.2;
}
keying_rect = Rect2(ofs, ((size.height - key->get_height()) / 2), key->get_width(), key->get_height());
- draw_texture(key, keying_rect.position, color);
+ draw_texture(key, keying_rect.position, color2);
} else {
keying_rect = Rect2();
}
@@ -425,7 +434,7 @@ bool EditorPropertyRevert::is_node_property_different(Node *p_node, const Varian
float a = p_current;
float b = p_orig;
- return Math::abs(a - b) > CMP_EPSILON; //this must be done because, as some scenes save as text, there might be a tiny difference in floats due to numerical error
+ return !Math::is_equal_approx(a, b); //this must be done because, as some scenes save as text, there might be a tiny difference in floats due to numerical error
}
return bool(Variant::evaluate(Variant::OP_NOT_EQUAL, p_current, p_orig));
@@ -462,10 +471,12 @@ bool EditorPropertyRevert::can_property_revert(Object *p_object, const StringNam
if (!has_revert && !p_object->get_script().is_null()) {
Ref<Script> scr = p_object->get_script();
- Variant orig_value;
- if (scr->get_property_default_value(p_property, orig_value)) {
- if (orig_value != p_object->get(p_property)) {
- has_revert = true;
+ if (scr.is_valid()) {
+ Variant orig_value;
+ if (scr->get_property_default_value(p_property, orig_value)) {
+ if (orig_value != p_object->get(p_property)) {
+ has_revert = true;
+ }
}
}
}
@@ -634,7 +645,7 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) {
emit_signal("property_keyed", property, use_keying_next());
if (use_keying_next()) {
- call_deferred("emit_signal", "property_changed", property, object->get(property).operator int64_t() + 1);
+ call_deferred("emit_changed", property, object->get(property).operator int64_t() + 1, "", false);
call_deferred("update_property");
}
}
@@ -646,31 +657,33 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) {
Node *node = Object::cast_to<Node>(object);
if (node && EditorPropertyRevert::may_node_be_in_instance(node) && EditorPropertyRevert::get_instanced_node_original_property(node, property, vorig)) {
- emit_signal("property_changed", property, vorig.duplicate(true));
+ emit_changed(property, vorig.duplicate(true));
update_property();
return;
}
if (object->call("property_can_revert", property).operator bool()) {
Variant rev = object->call("property_get_revert", property);
- emit_signal("property_changed", property, rev);
+ emit_changed(property, rev);
update_property();
return;
}
if (!object->get_script().is_null()) {
Ref<Script> scr = object->get_script();
- Variant orig_value;
- if (scr->get_property_default_value(property, orig_value)) {
- emit_signal("property_changed", property, orig_value);
- update_property();
- return;
+ if (scr.is_valid()) {
+ Variant orig_value;
+ if (scr->get_property_default_value(property, orig_value)) {
+ emit_changed(property, orig_value);
+ update_property();
+ return;
+ }
}
}
Variant default_value = ClassDB::class_get_default_property_value(object->get_class_name(), property);
if (default_value != Variant()) {
- emit_signal("property_changed", property, default_value);
+ emit_changed(property, default_value);
update_property();
return;
}
@@ -792,6 +805,11 @@ void EditorProperty::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_tooltip_text"), &EditorProperty::get_tooltip_text);
+ ClassDB::bind_method(D_METHOD("add_focusable", "control"), &EditorProperty::add_focusable);
+ ClassDB::bind_method(D_METHOD("set_bottom_editor", "editor"), &EditorProperty::set_bottom_editor);
+
+ ClassDB::bind_method(D_METHOD("emit_changed", "property", "value", "field", "changing"), &EditorProperty::emit_changed, DEFVAL(StringName()), DEFVAL(false));
+
ADD_PROPERTY(PropertyInfo(Variant::STRING, "label"), "set_label", "get_label");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "read_only"), "set_read_only", "is_read_only");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "checkable"), "set_checkable", "is_checkable");
@@ -1226,6 +1244,7 @@ EditorInspectorSection::EditorInspectorSection() {
}
EditorInspectorSection::~EditorInspectorSection() {
+
if (!vbox_added) {
memdelete(vbox);
}
@@ -1287,6 +1306,10 @@ void EditorInspector::remove_inspector_plugin(const Ref<EditorInspectorPlugin> &
for (int i = idx; i < inspector_plugin_count - 1; i++) {
inspector_plugins[i] = inspector_plugins[i + 1];
}
+
+ if (idx == inspector_plugin_count - 1)
+ inspector_plugins[idx] = Ref<EditorInspectorPlugin>();
+
inspector_plugin_count--;
}
@@ -1355,11 +1378,56 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<Edit
ped->added_editors.clear();
}
+bool EditorInspector::_is_property_disabled_by_feature_profile(const StringName &p_property) {
+
+ Ref<EditorFeatureProfile> profile = EditorFeatureProfileManager::get_singleton()->get_current_profile();
+ if (profile.is_null()) {
+ return false;
+ }
+
+ StringName class_name = object->get_class();
+
+ while (class_name != StringName()) {
+
+ if (profile->is_class_property_disabled(class_name, p_property)) {
+ return true;
+ }
+ if (profile->is_class_disabled(class_name)) {
+ //won't see properties of a disabled class
+ return true;
+ }
+ class_name = ClassDB::get_parent_class(class_name);
+ }
+
+ return false;
+}
+
void EditorInspector::update_tree() {
//to update properly if all is refreshed
StringName current_selected = property_selected;
- int current_focusable = property_focusable;
+ int current_focusable = -1;
+
+ if (property_focusable != -1) {
+ //check focusable is really focusable
+ bool restore_focus = false;
+ Control *focused = get_focus_owner();
+ if (focused) {
+ Node *parent = focused->get_parent();
+ while (parent) {
+ EditorInspector *inspector = Object::cast_to<EditorInspector>(parent);
+ if (inspector) {
+ restore_focus = inspector == this; //may be owned by another inspector
+ break; //exit after the first inspector is found, since there may be nested ones
+ }
+ parent = parent->get_parent();
+ }
+ }
+
+ if (restore_focus) {
+ current_focusable = property_focusable;
+ }
+ }
_clear();
@@ -1454,19 +1522,19 @@ void EditorInspector::update_tree() {
category->bg_color = get_color("prop_category", "Editor");
if (use_doc_hints) {
- StringName type = p.name;
- if (!class_descr_cache.has(type)) {
+ StringName type2 = p.name;
+ if (!class_descr_cache.has(type2)) {
String descr;
DocData *dd = EditorHelp::get_doc_data();
- Map<String, DocData::ClassDoc>::Element *E = dd->class_list.find(type);
+ Map<String, DocData::ClassDoc>::Element *E = dd->class_list.find(type2);
if (E) {
descr = E->get().brief_description;
}
- class_descr_cache[type] = descr.word_wrap(80);
+ class_descr_cache[type2] = descr;
}
- category->set_tooltip(p.name + "::" + (class_descr_cache[type] == "" ? "" : class_descr_cache[type]));
+ category->set_tooltip(p.name + "::" + (class_descr_cache[type2] == "" ? "" : class_descr_cache[type2]));
}
for (List<Ref<EditorInspectorPlugin> >::Element *E = valid_plugins.front(); E; E = E->next()) {
@@ -1477,7 +1545,7 @@ void EditorInspector::update_tree() {
continue;
- } else if (!(p.usage & PROPERTY_USAGE_EDITOR))
+ } else if (!(p.usage & PROPERTY_USAGE_EDITOR) || _is_property_disabled_by_feature_profile(p.name))
continue;
if (p.usage & PROPERTY_USAGE_HIGH_END_GFX && VS::get_singleton()->is_low_end())
@@ -1611,16 +1679,16 @@ void EditorInspector::update_tree() {
if (!found) {
DocData *dd = EditorHelp::get_doc_data();
- Map<String, DocData::ClassDoc>::Element *E = dd->class_list.find(classname);
- while (E && descr == String()) {
- for (int i = 0; i < E->get().properties.size(); i++) {
- if (E->get().properties[i].name == propname.operator String()) {
- descr = E->get().properties[i].description.strip_edges().word_wrap(80);
+ Map<String, DocData::ClassDoc>::Element *F = dd->class_list.find(classname);
+ while (F && descr == String()) {
+ for (int i = 0; i < F->get().properties.size(); i++) {
+ if (F->get().properties[i].name == propname.operator String()) {
+ descr = F->get().properties[i].description.strip_edges();
break;
}
}
- if (!E->get().inherits.empty()) {
- E = dd->class_list.find(E->get().inherits);
+ if (!F->get().inherits.empty()) {
+ F = dd->class_list.find(F->get().inherits);
} else {
break;
}
@@ -1871,13 +1939,13 @@ int EditorInspector::get_scroll_offset() const {
return get_v_scroll();
}
-void EditorInspector::set_use_sub_inspector_bg(bool p_enable) {
+void EditorInspector::set_sub_inspector(bool p_enable) {
- use_sub_inspector_bg = p_enable;
+ sub_inspector = p_enable;
if (!is_inside_tree())
return;
- if (use_sub_inspector_bg) {
+ if (sub_inspector) {
add_style_override("bg", get_stylebox("sub_inspector_bg", "Editor"));
} else {
add_style_override("bg", get_stylebox("bg", "Tree"));
@@ -1909,7 +1977,7 @@ void EditorInspector::_edit_set(const String &p_name, const Variant &p_value, bo
}
}
- if (!undo_redo || Object::cast_to<ArrayPropertyEdit>(object) || Object::cast_to<DictionaryPropertyEdit>(object)) { //kind of hacky
+ if (!undo_redo || bool(object->call("_dont_undo_redo"))) {
object->set(p_name, p_value);
if (p_refresh_all)
@@ -1941,10 +2009,6 @@ void EditorInspector::_edit_set(const String &p_name, const Variant &p_value, bo
Resource *r = Object::cast_to<Resource>(object);
if (r) {
- if (!r->is_edited() && String(p_name) != "resource/edited") {
- undo_redo->add_do_method(r, "set_edited", true);
- undo_redo->add_undo_method(r, "set_edited", false);
- }
if (String(p_name) == "resource_local_to_scene") {
bool prev = object->get(p_name);
@@ -1969,14 +2033,14 @@ void EditorInspector::_edit_set(const String &p_name, const Variant &p_value, bo
}
}
-void EditorInspector::_property_changed(const String &p_path, const Variant &p_value, bool changing) {
+void EditorInspector::_property_changed(const String &p_path, const Variant &p_value, const String &p_name, bool changing) {
// The "changing" variable must be true for properties that trigger events as typing occurs,
// like "text_changed" signal. eg: Text property of Label, Button, RichTextLabel, etc.
if (changing)
this->changing++;
- _edit_set(p_path, p_value, false, "");
+ _edit_set(p_path, p_value, false, p_name);
if (changing)
this->changing--;
@@ -1986,7 +2050,7 @@ void EditorInspector::_property_changed(const String &p_path, const Variant &p_v
}
}
-void EditorInspector::_property_changed_update_all(const String &p_path, const Variant &p_value) {
+void EditorInspector::_property_changed_update_all(const String &p_path, const Variant &p_value, const String &p_name, bool p_changing) {
update_tree();
}
@@ -2100,18 +2164,27 @@ void EditorInspector::_node_removed(Node *p_node) {
void EditorInspector::_notification(int p_what) {
+ if (p_what == NOTIFICATION_READY) {
+ EditorFeatureProfileManager::get_singleton()->connect("current_feature_profile_changed", this, "_feature_profile_changed");
+ }
+
if (p_what == NOTIFICATION_ENTER_TREE) {
- get_tree()->connect("node_removed", this, "_node_removed");
- if (use_sub_inspector_bg) {
+ if (sub_inspector) {
add_style_override("bg", get_stylebox("sub_inspector_bg", "Editor"));
- } else if (is_inside_tree()) {
+ } else {
add_style_override("bg", get_stylebox("bg", "Tree"));
+ get_tree()->connect("node_removed", this, "_node_removed");
}
}
+ if (p_what == NOTIFICATION_PREDELETE) {
+ edit(NULL); //just in case
+ }
if (p_what == NOTIFICATION_EXIT_TREE) {
- get_tree()->disconnect("node_removed", this, "_node_removed");
+ if (!sub_inspector) {
+ get_tree()->disconnect("node_removed", this, "_node_removed");
+ }
edit(NULL);
}
@@ -2160,7 +2233,7 @@ void EditorInspector::_notification(int p_what) {
if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
- if (use_sub_inspector_bg) {
+ if (sub_inspector) {
add_style_override("bg", get_stylebox("sub_inspector_bg", "Editor"));
} else if (is_inside_tree()) {
add_style_override("bg", get_stylebox("bg", "Tree"));
@@ -2201,9 +2274,14 @@ String EditorInspector::get_object_class() const {
return object_class;
}
+void EditorInspector::_feature_profile_changed() {
+
+ update_tree();
+}
+
void EditorInspector::_bind_methods() {
- ClassDB::bind_method("_property_changed", &EditorInspector::_property_changed, DEFVAL(false));
+ ClassDB::bind_method("_property_changed", &EditorInspector::_property_changed, DEFVAL(""), DEFVAL(false));
ClassDB::bind_method("_multiple_properties_changed", &EditorInspector::_multiple_properties_changed);
ClassDB::bind_method("_property_changed_update_all", &EditorInspector::_property_changed_update_all);
@@ -2217,6 +2295,7 @@ void EditorInspector::_bind_methods() {
ClassDB::bind_method("_resource_selected", &EditorInspector::_resource_selected);
ClassDB::bind_method("_object_id_selected", &EditorInspector::_object_id_selected);
ClassDB::bind_method("_vscroll_changed", &EditorInspector::_vscroll_changed);
+ ClassDB::bind_method("_feature_profile_changed", &EditorInspector::_feature_profile_changed);
ClassDB::bind_method("refresh", &EditorInspector::refresh);
@@ -2256,7 +2335,7 @@ EditorInspector::EditorInspector() {
_prop_edited = "property_edited";
set_process(true);
property_focusable = -1;
- use_sub_inspector_bg = false;
+ sub_inspector = false;
get_v_scrollbar()->connect("value_changed", this, "_vscroll_changed");
update_scroll_request = -1;