diff options
Diffstat (limited to 'editor/editor_properties.cpp')
-rw-r--r-- | editor/editor_properties.cpp | 678 |
1 files changed, 583 insertions, 95 deletions
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index f3397d7980..4fae8467b4 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -31,13 +31,26 @@ #include "editor_properties.h" #include "editor/editor_resource_preview.h" #include "editor_node.h" +#include "editor_properties_array_dict.h" #include "scene/main/viewport.h" + +///////////////////// NULL ///////////////////////// + +void EditorPropertyNil::update_property() { +} + +EditorPropertyNil::EditorPropertyNil() { + Label *label = memnew(Label); + label->set_text("[null]"); + add_child(label); +} + ///////////////////// TEXT ///////////////////////// void EditorPropertyText::_text_changed(const String &p_string) { if (updating) return; - emit_signal("property_changed", get_edited_property(), p_string); + emit_signal("property_changed", get_edited_property(), p_string, true); } void EditorPropertyText::update_property() { @@ -65,12 +78,12 @@ EditorPropertyText::EditorPropertyText() { void EditorPropertyMultilineText::_big_text_changed() { text->set_text(big_text->get_text()); - emit_signal("property_changed", get_edited_property(), big_text->get_text()); + emit_signal("property_changed", get_edited_property(), big_text->get_text(), true); } void EditorPropertyMultilineText::_text_changed() { - emit_signal("property_changed", get_edited_property(), text->get_text()); + emit_signal("property_changed", get_edited_property(), text->get_text(), true); } void EditorPropertyMultilineText::_open_big_text() { @@ -118,8 +131,8 @@ void EditorPropertyMultilineText::_bind_methods() { EditorPropertyMultilineText::EditorPropertyMultilineText() { HBoxContainer *hb = memnew(HBoxContainer); - set_label_layout(LABEL_LAYOUT_TOP); add_child(hb); + set_bottom_editor(hb); text = memnew(TextEdit); text->connect("text_changed", this, "_text_changed"); add_focusable(text); @@ -165,6 +178,8 @@ void EditorPropertyTextEnum::_bind_methods() { EditorPropertyTextEnum::EditorPropertyTextEnum() { options = memnew(OptionButton); options->set_clip_text(true); + options->set_flat(true); + add_child(options); add_focusable(options); options->connect("item_selected", this, "_option_selected"); @@ -243,6 +258,51 @@ EditorPropertyPath::EditorPropertyPath() { global = false; } +///////////////////// CLASS NAME ///////////////////////// + +void EditorPropertyClassName::setup(const String &p_base_type, const String &p_selected_type) { + + base_type = p_base_type; + dialog->set_base_type(base_type); + selected_type = p_selected_type; + property->set_text(selected_type); +} + +void EditorPropertyClassName::update_property() { + + String s = get_edited_object()->get(get_edited_property()); + property->set_text(s); + selected_type = s; +} + +void EditorPropertyClassName::_property_selected() { + dialog->popup_create(true); +} + +void EditorPropertyClassName::_dialog_created() { + selected_type = dialog->get_selected_type(); + emit_signal("property_changed", get_edited_property(), selected_type); + update_property(); +} + +void EditorPropertyClassName::_bind_methods() { + ClassDB::bind_method(D_METHOD("_dialog_created"), &EditorPropertyClassName::_dialog_created); + ClassDB::bind_method(D_METHOD("_property_selected"), &EditorPropertyClassName::_property_selected); +} + +EditorPropertyClassName::EditorPropertyClassName() { + property = memnew(Button); + property->set_clip_text(true); + add_child(property); + add_focusable(property); + property->set_text(selected_type); + property->connect("pressed", this, "_property_selected"); + dialog = memnew(CreateDialog); + dialog->set_base_type(base_type); + dialog->connect("create", this, "_dialog_created"); + add_child(dialog); +} + ///////////////////// MEMBER ///////////////////////// void EditorPropertyMember::_property_selected(const String &p_selected) { @@ -377,13 +437,37 @@ EditorPropertyCheck::EditorPropertyCheck() { void EditorPropertyEnum::_option_selected(int p_which) { - emit_signal("property_changed", get_edited_property(), p_which); + String text = options->get_item_text(p_which); + Vector<String> text_split = text.split(":"); + if (text_split.size() == 1) { + emit_signal("property_changed", get_edited_property(), p_which); + return; + } + String name = text_split[1]; + emit_signal("property_changed", get_edited_property(), name.to_int()); } void EditorPropertyEnum::update_property() { int which = get_edited_object()->get(get_edited_property()); - options->select(which); + if (which == 0) { + options->select(which); + return; + } + + for (int i = 0; i < options->get_item_count(); i++) { + String text = options->get_item_text(i); + Vector<String> text_split = text.split(":"); + if (text_split.size() == 1) { + options->select(which); + return; + } + String name = text_split[1]; + if (itos(which) == name) { + options->select(i); + return; + } + } } void EditorPropertyEnum::setup(const Vector<String> &p_options) { @@ -392,6 +476,10 @@ void EditorPropertyEnum::setup(const Vector<String> &p_options) { } } +void EditorPropertyEnum::set_option_button_clip(bool p_enable) { + options->set_clip_text(p_enable); +} + void EditorPropertyEnum::_bind_methods() { ClassDB::bind_method(D_METHOD("_option_selected"), &EditorPropertyEnum::_option_selected); @@ -400,6 +488,7 @@ void EditorPropertyEnum::_bind_methods() { EditorPropertyEnum::EditorPropertyEnum() { options = memnew(OptionButton); options->set_clip_text(true); + options->set_flat(true); add_child(options); add_focusable(options); options->connect("item_selected", this, "_option_selected"); @@ -487,7 +576,7 @@ public: virtual String get_tooltip(const Point2 &p_pos) const { for (int i = 0; i < flag_rects.size(); i++) { - if (flag_rects[i].has_point(p_pos) && i < names.size()) { + if (i < names.size() && flag_rects[i].has_point(p_pos)) { return names[i]; } } @@ -600,9 +689,11 @@ void EditorPropertyLayers::setup(LayerType p_layer_type) { } if (name == "") { - name = "Layer " + itos(i + 1); + name = TTR("Layer") + " " + itos(i + 1); } + name += "\n" + vformat(TTR("Bit %d, value %d"), i, 1 << i); + names.push_back(name); } @@ -622,6 +713,7 @@ void EditorPropertyLayers::_button_pressed() { } Rect2 gp = button->get_global_rect(); + layers->set_as_minsize(); Vector2 popup_pos = gp.position - Vector2(layers->get_combined_minimum_size().x, 0); layers->set_global_position(popup_pos); layers->popup(); @@ -634,6 +726,7 @@ void EditorPropertyLayers::_menu_pressed(int p_menu) { grid->value |= (1 << p_menu); } grid->update(); + layers->set_item_checked(layers->get_item_index(p_menu), grid->value & (1 << p_menu)); _grid_changed(grid->value); } @@ -656,9 +749,10 @@ EditorPropertyLayers::EditorPropertyLayers() { button->set_text(".."); button->connect("pressed", this, "_button_pressed"); hb->add_child(button); - set_label_layout(LABEL_LAYOUT_TOP); + set_bottom_editor(hb); layers = memnew(PopupMenu); add_child(layers); + layers->set_hide_on_checkable_item_selection(false); layers->connect("id_pressed", this, "_menu_pressed"); } ///////////////////// INT ///////////////////////// @@ -691,6 +785,7 @@ void EditorPropertyInteger::setup(int p_min, int p_max, bool p_allow_greater, bo EditorPropertyInteger::EditorPropertyInteger() { spin = memnew(EditorSpinSlider); + spin->set_flat(true); add_child(spin); add_focusable(spin); spin->connect("value_changed", this, "_value_changed"); @@ -777,6 +872,7 @@ void EditorPropertyFloat::setup(double p_min, double p_max, double p_step, bool EditorPropertyFloat::EditorPropertyFloat() { spin = memnew(EditorSpinSlider); + spin->set_flat(true); add_child(spin); add_focusable(spin); spin->connect("value_changed", this, "_value_changed"); @@ -787,6 +883,12 @@ EditorPropertyFloat::EditorPropertyFloat() { void EditorPropertyEasing::_drag_easing(const Ref<InputEvent> &p_ev) { + Ref<InputEventMouseButton> mb = p_ev; + if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) { + preset->set_global_position(easing_draw->get_global_transform().xform(mb->get_position())); + preset->popup(); + } + Ref<InputEventMouseMotion> mm = p_ev; if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_LEFT) { @@ -824,7 +926,7 @@ void EditorPropertyEasing::_draw_easing() { Size2 s = easing_draw->get_size(); Rect2 r(Point2(), s); r = r.grow(3); - get_stylebox("normal", "LineEdit")->draw(ci, r); + //get_stylebox("normal", "LineEdit")->draw(ci, r); int points = 48; @@ -834,6 +936,7 @@ void EditorPropertyEasing::_draw_easing() { Ref<Font> f = get_font("font", "Label"); Color color = get_color("font_color", "Label"); + Vector<Point2> lines; for (int i = 1; i <= points; i++) { float ifl = i / float(points); @@ -846,10 +949,12 @@ void EditorPropertyEasing::_draw_easing() { iflp = 1.0 - iflp; } - VisualServer::get_singleton()->canvas_item_add_line(ci, Point2(iflp * s.width, prev * s.height), Point2(ifl * s.width, h * s.height), color); + lines.push_back(Point2(ifl * s.width, h * s.height)); + lines.push_back(Point2(iflp * s.width, prev * s.height)); prev = h; } + easing_draw->draw_multiline(lines, color, 1.0, true); f->draw(ci, Point2(10, 10 + f->get_ascent()), String::num(exp, 2), color); } @@ -857,29 +962,17 @@ void EditorPropertyEasing::update_property() { easing_draw->update(); } -void EditorPropertyEasing::_set_preset(float p_val) { - emit_signal("property_changed", get_edited_property(), p_val); +void EditorPropertyEasing::_set_preset(int p_preset) { + static const float preset_value[EASING_MAX] = { 0.0, 1.0, 2.0, 0.5, -2.0, -0.5 }; + + emit_signal("property_changed", get_edited_property(), preset_value[p_preset]); easing_draw->update(); } void EditorPropertyEasing::setup(bool p_full, bool p_flip) { flip = p_flip; - if (p_full) { - HBoxContainer *hb2 = memnew(HBoxContainer); - vb->add_child(hb2); - button_out_in = memnew(ToolButton); - button_out_in->set_tooltip(TTR("Out-In")); - button_out_in->set_h_size_flags(SIZE_EXPAND_FILL); - button_out_in->connect("pressed", this, "_set_preset", varray(-0.5)); - hb2->add_child(button_out_in); - - button_in_out = memnew(ToolButton); - button_in_out->set_tooltip(TTR("In")); - button_in_out->set_h_size_flags(SIZE_EXPAND_FILL); - button_in_out->connect("pressed", this, "_set_preset", varray(-2)); - hb2->add_child(button_in_out); - } + full = p_full; } void EditorPropertyEasing::_notification(int p_what) { @@ -887,15 +980,19 @@ void EditorPropertyEasing::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: case NOTIFICATION_ENTER_TREE: { + preset->clear(); + preset->add_icon_item(get_icon("CurveConstant", "EditorIcons"), "Zero", EASING_ZERO); + preset->add_icon_item(get_icon("CurveLinear", "EditorIcons"), "Linear", EASING_LINEAR); + preset->add_icon_item(get_icon("CurveIn", "EditorIcons"), "In", EASING_IN); + preset->add_icon_item(get_icon("CurveOut", "EditorIcons"), "Out", EASING_OUT); + if (full) { + preset->add_icon_item(get_icon("CurveInOut", "EditorIcons"), "In-Out", EASING_IN_OUT); + preset->add_icon_item(get_icon("CurveOutIn", "EditorIcons"), "Out-In", EASING_OUT_IN); + } easing_draw->set_custom_minimum_size(Size2(0, get_font("font", "Label")->get_height() * 2)); - button_linear->set_icon(get_icon("CurveLinear", "EditorIcons")); - button_out->set_icon(get_icon("CurveOut", "EditorIcons")); - button_in->set_icon(get_icon("CurveIn", "EditorIcons")); - button_constant->set_icon(get_icon("CurveConstant", "EditorIcons")); - if (button_out_in) - button_out_in->set_icon(get_icon("CurveOutIn", "EditorIcons")); - if (button_in_out) - button_in_out->set_icon(get_icon("CurveInOut", "EditorIcons")); + } break; + case NOTIFICATION_RESIZED: { + } break; } } @@ -909,47 +1006,18 @@ void EditorPropertyEasing::_bind_methods() { EditorPropertyEasing::EditorPropertyEasing() { - vb = memnew(VBoxContainer); - add_child(vb); - HBoxContainer *hb = memnew(HBoxContainer); - set_label_reference(hb); - - vb->add_child(hb); - - button_linear = memnew(ToolButton); - button_linear->set_tooltip(TTR("Linear")); - button_linear->set_h_size_flags(SIZE_EXPAND_FILL); - button_linear->connect("pressed", this, "_set_preset", varray(1)); - hb->add_child(button_linear); - - button_constant = memnew(ToolButton); - button_constant->set_tooltip(TTR("Linear")); - button_constant->set_h_size_flags(SIZE_EXPAND_FILL); - button_constant->connect("pressed", this, "_set_preset", varray(0)); - hb->add_child(button_constant); - - button_out = memnew(ToolButton); - button_out->set_tooltip(TTR("Out")); - button_out->set_h_size_flags(SIZE_EXPAND_FILL); - button_out->connect("pressed", this, "_set_preset", varray(0.5)); - hb->add_child(button_out); - - button_in = memnew(ToolButton); - button_in->set_tooltip(TTR("In")); - button_in->set_h_size_flags(SIZE_EXPAND_FILL); - button_in->connect("pressed", this, "_set_preset", varray(2)); - hb->add_child(button_in); - - button_in_out = NULL; - button_out_in = NULL; - easing_draw = memnew(Control); easing_draw->connect("draw", this, "_draw_easing"); easing_draw->connect("gui_input", this, "_drag_easing"); easing_draw->set_default_cursor_shape(Control::CURSOR_MOVE); - vb->add_child(easing_draw); + add_child(easing_draw); + + preset = memnew(PopupMenu); + add_child(preset); + preset->connect("id_pressed", this, "_set_preset"); flip = false; + full = false; } ///////////////////// VECTOR2 ///////////////////////// @@ -972,6 +1040,18 @@ void EditorPropertyVector2::update_property() { setting = false; } +void EditorPropertyVector2::_notification(int p_what) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { + Color base = get_color("accent_color", "Editor"); + for (int i = 0; i < 2; i++) { + + Color c = base; + c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v()); + spin[i]->set_custom_label_color(true, c); + } + } +} + void EditorPropertyVector2::_bind_methods() { ClassDB::bind_method(D_METHOD("_value_changed"), &EditorPropertyVector2::_value_changed); @@ -992,6 +1072,7 @@ EditorPropertyVector2::EditorPropertyVector2() { static const char *desc[2] = { "x", "y" }; for (int i = 0; i < 2; i++) { spin[i] = memnew(EditorSpinSlider); + spin[i]->set_flat(true); spin[i]->set_label(desc[i]); vb->add_child(spin[i]); add_focusable(spin[i]); @@ -1009,8 +1090,8 @@ void EditorPropertyRect2::_value_changed(double val) { Rect2 r2; r2.position.x = spin[0]->get_value(); - r2.position.x = spin[1]->get_value(); - r2.size.y = spin[2]->get_value(); + r2.position.y = spin[1]->get_value(); + r2.size.x = spin[2]->get_value(); r2.size.y = spin[3]->get_value(); emit_signal("property_changed", get_edited_property(), r2); } @@ -1024,7 +1105,17 @@ void EditorPropertyRect2::update_property() { spin[3]->set_value(val.size.y); setting = false; } +void EditorPropertyRect2::_notification(int p_what) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { + Color base = get_color("accent_color", "Editor"); + for (int i = 0; i < 4; i++) { + Color c = base; + c.set_hsv(float(i % 2) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v()); + spin[i]->set_custom_label_color(true, c); + } + } +} void EditorPropertyRect2::_bind_methods() { ClassDB::bind_method(D_METHOD("_value_changed"), &EditorPropertyRect2::_value_changed); @@ -1046,6 +1137,8 @@ EditorPropertyRect2::EditorPropertyRect2() { for (int i = 0; i < 4; i++) { spin[i] = memnew(EditorSpinSlider); spin[i]->set_label(desc[i]); + spin[i]->set_flat(true); + vb->add_child(spin[i]); add_focusable(spin[i]); spin[i]->connect("value_changed", this, "_value_changed"); @@ -1074,7 +1167,17 @@ void EditorPropertyVector3::update_property() { spin[2]->set_value(val.z); setting = false; } +void EditorPropertyVector3::_notification(int p_what) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { + Color base = get_color("accent_color", "Editor"); + for (int i = 0; i < 3; i++) { + Color c = base; + c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v()); + spin[i]->set_custom_label_color(true, c); + } + } +} void EditorPropertyVector3::_bind_methods() { ClassDB::bind_method(D_METHOD("_value_changed"), &EditorPropertyVector3::_value_changed); @@ -1096,6 +1199,8 @@ EditorPropertyVector3::EditorPropertyVector3() { for (int i = 0; i < 3; i++) { spin[i] = memnew(EditorSpinSlider); spin[i]->set_label(desc[i]); + spin[i]->set_flat(true); + vb->add_child(spin[i]); add_focusable(spin[i]); spin[i]->connect("value_changed", this, "_value_changed"); @@ -1126,7 +1231,17 @@ void EditorPropertyPlane::update_property() { spin[3]->set_value(val.d); setting = false; } +void EditorPropertyPlane::_notification(int p_what) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { + Color base = get_color("accent_color", "Editor"); + for (int i = 0; i < 3; i++) { + Color c = base; + c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v()); + spin[i]->set_custom_label_color(true, c); + } + } +} void EditorPropertyPlane::_bind_methods() { ClassDB::bind_method(D_METHOD("_value_changed"), &EditorPropertyPlane::_value_changed); @@ -1148,6 +1263,7 @@ EditorPropertyPlane::EditorPropertyPlane() { for (int i = 0; i < 4; i++) { spin[i] = memnew(EditorSpinSlider); spin[i]->set_label(desc[i]); + spin[i]->set_flat(true); vb->add_child(spin[i]); add_focusable(spin[i]); spin[i]->connect("value_changed", this, "_value_changed"); @@ -1179,7 +1295,17 @@ void EditorPropertyQuat::update_property() { spin[3]->set_value(val.w); setting = false; } +void EditorPropertyQuat::_notification(int p_what) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { + Color base = get_color("accent_color", "Editor"); + for (int i = 0; i < 3; i++) { + Color c = base; + c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v()); + spin[i]->set_custom_label_color(true, c); + } + } +} void EditorPropertyQuat::_bind_methods() { ClassDB::bind_method(D_METHOD("_value_changed"), &EditorPropertyQuat::_value_changed); @@ -1201,6 +1327,8 @@ EditorPropertyQuat::EditorPropertyQuat() { for (int i = 0; i < 4; i++) { spin[i] = memnew(EditorSpinSlider); spin[i]->set_label(desc[i]); + spin[i]->set_flat(true); + vb->add_child(spin[i]); add_focusable(spin[i]); spin[i]->connect("value_changed", this, "_value_changed"); @@ -1238,7 +1366,17 @@ void EditorPropertyAABB::update_property() { setting = false; } +void EditorPropertyAABB::_notification(int p_what) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { + Color base = get_color("accent_color", "Editor"); + for (int i = 0; i < 6; i++) { + Color c = base; + c.set_hsv(float(i % 3) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v()); + spin[i]->set_custom_label_color(true, c); + } + } +} void EditorPropertyAABB::_bind_methods() { ClassDB::bind_method(D_METHOD("_value_changed"), &EditorPropertyAABB::_value_changed); @@ -1262,13 +1400,14 @@ EditorPropertyAABB::EditorPropertyAABB() { for (int i = 0; i < 6; i++) { spin[i] = memnew(EditorSpinSlider); spin[i]->set_label(desc[i]); + spin[i]->set_flat(true); + g->add_child(spin[i]); spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); add_focusable(spin[i]); spin[i]->connect("value_changed", this, "_value_changed"); } - set_label_reference(spin[0]); //show text and buttons around this - set_label_layout(LABEL_LAYOUT_TOP); + set_bottom_editor(g); setting = false; } @@ -1301,7 +1440,17 @@ void EditorPropertyTransform2D::update_property() { setting = false; } +void EditorPropertyTransform2D::_notification(int p_what) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { + Color base = get_color("accent_color", "Editor"); + for (int i = 0; i < 6; i++) { + Color c = base; + c.set_hsv(float(i % 2) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v()); + spin[i]->set_custom_label_color(true, c); + } + } +} void EditorPropertyTransform2D::_bind_methods() { ClassDB::bind_method(D_METHOD("_value_changed"), &EditorPropertyTransform2D::_value_changed); @@ -1321,17 +1470,17 @@ EditorPropertyTransform2D::EditorPropertyTransform2D() { g->set_columns(2); add_child(g); - static const char *desc[6] = { "xx", "xy", "yx", "yy", "ox", "oy" }; + static const char *desc[6] = { "x", "y", "x", "y", "x", "y" }; for (int i = 0; i < 6; i++) { spin[i] = memnew(EditorSpinSlider); spin[i]->set_label(desc[i]); + spin[i]->set_flat(true); g->add_child(spin[i]); spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); add_focusable(spin[i]); spin[i]->connect("value_changed", this, "_value_changed"); } - set_label_reference(spin[0]); //show text and buttons around this - set_label_layout(LABEL_LAYOUT_TOP); + set_bottom_editor(g); setting = false; } @@ -1370,7 +1519,17 @@ void EditorPropertyBasis::update_property() { setting = false; } +void EditorPropertyBasis::_notification(int p_what) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { + Color base = get_color("accent_color", "Editor"); + for (int i = 0; i < 9; i++) { + Color c = base; + c.set_hsv(float(i % 3) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v()); + spin[i]->set_custom_label_color(true, c); + } + } +} void EditorPropertyBasis::_bind_methods() { ClassDB::bind_method(D_METHOD("_value_changed"), &EditorPropertyBasis::_value_changed); @@ -1390,17 +1549,17 @@ EditorPropertyBasis::EditorPropertyBasis() { g->set_columns(3); add_child(g); - static const char *desc[9] = { "xx", "xy", "xz", "yx", "yy", "yz", "zx", "zy", "zz" }; + static const char *desc[9] = { "x", "y", "z", "x", "y", "z", "x", "y", "z" }; for (int i = 0; i < 9; i++) { spin[i] = memnew(EditorSpinSlider); spin[i]->set_label(desc[i]); + spin[i]->set_flat(true); g->add_child(spin[i]); spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); add_focusable(spin[i]); spin[i]->connect("value_changed", this, "_value_changed"); } - set_label_reference(spin[0]); //show text and buttons around this - set_label_layout(LABEL_LAYOUT_TOP); + set_bottom_editor(g); setting = false; } @@ -1445,7 +1604,17 @@ void EditorPropertyTransform::update_property() { setting = false; } +void EditorPropertyTransform::_notification(int p_what) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { + Color base = get_color("accent_color", "Editor"); + for (int i = 0; i < 12; i++) { + Color c = base; + c.set_hsv(float(i % 3) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v()); + spin[i]->set_custom_label_color(true, c); + } + } +} void EditorPropertyTransform::_bind_methods() { ClassDB::bind_method(D_METHOD("_value_changed"), &EditorPropertyTransform::_value_changed); @@ -1465,17 +1634,17 @@ EditorPropertyTransform::EditorPropertyTransform() { g->set_columns(3); add_child(g); - static const char *desc[12] = { "xx", "xy", "xz", "yx", "yy", "yz", "zx", "zy", "zz", "ox", "oy", "oz" }; + static const char *desc[12] = { "x", "y", "z", "x", "y", "z", "x", "y", "z", "x", "y", "z" }; for (int i = 0; i < 12; i++) { spin[i] = memnew(EditorSpinSlider); spin[i]->set_label(desc[i]); + spin[i]->set_flat(true); g->add_child(spin[i]); spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); add_focusable(spin[i]); spin[i]->connect("value_changed", this, "_value_changed"); } - set_label_reference(spin[0]); //show text and buttons around this - set_label_layout(LABEL_LAYOUT_TOP); + set_bottom_editor(g); setting = false; } @@ -1512,13 +1681,23 @@ EditorPropertyColor::EditorPropertyColor() { void EditorPropertyNodePath::_node_selected(const NodePath &p_path) { - emit_signal("property_changed", get_edited_property(), p_path); + NodePath path = p_path; + Node *base_node = Object::cast_to<Node>(get_edited_object()); + if (base_node == NULL && get_edited_object()->has_method("get_root_path")) { + base_node = get_edited_object()->call("get_root_path"); + } + if (base_node) { // for AnimationTrackKeyEdit + path = base_node->get_path().rel_path_to(p_path); + } + emit_signal("property_changed", get_edited_property(), path); update_property(); } void EditorPropertyNodePath::_node_assign() { if (!scene_tree) { scene_tree = memnew(SceneTreeDialog); + scene_tree->get_scene_tree()->set_show_enabled_subscene(true); + scene_tree->get_scene_tree()->set_valid_types(valid_types); add_child(scene_tree); scene_tree->connect("selected", this, "_node_selected"); } @@ -1573,9 +1752,10 @@ void EditorPropertyNodePath::update_property() { assign->set_icon(icon); } -void EditorPropertyNodePath::setup(const NodePath &p_base_hint) { +void EditorPropertyNodePath::setup(const NodePath &p_base_hint, Vector<StringName> p_valid_types) { base_hint = p_base_hint; + valid_types = p_valid_types; } void EditorPropertyNodePath::_notification(int p_what) { @@ -1768,6 +1948,7 @@ void EditorPropertyResource::_menu_option(int p_which) { if (!scene_tree) { scene_tree = memnew(SceneTreeDialog); + scene_tree->get_scene_tree()->set_show_enabled_subscene(true); add_child(scene_tree); scene_tree->connect("selected", this, "_viewport_selected"); scene_tree->set_title(TTR("Pick a Viewport")); @@ -1804,7 +1985,19 @@ void EditorPropertyResource::_resource_preview(const String &p_path, const Ref<T RES p = get_edited_object()->get(get_edited_property()); if (p.is_valid() && p->get_instance_id() == p_obj) { if (p_preview.is_valid()) { - assign->set_icon(p_preview); + String type = p->get_class_name(); + preview->set_margin(MARGIN_LEFT, assign->get_icon()->get_width() + assign->get_stylebox("normal")->get_default_margin(MARGIN_LEFT) + get_constant("hseparation", "Button")); + if (type == "GradientTexture") { + preview->set_stretch_mode(TextureRect::STRETCH_SCALE); + assign->set_custom_minimum_size(Size2(1, 1)); + } else { + preview->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED); + int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); + thumbnail_size *= EDSCALE; + assign->set_custom_minimum_size(Size2(1, thumbnail_size)); + } + preview->set_texture(p_preview); + assign->set_text(""); } } } @@ -1952,23 +2145,107 @@ void EditorPropertyResource::_update_menu() { } } - Rect2 gt = get_global_rect(); + Rect2 gt = edit->get_global_rect(); + menu->set_as_minsize(); int ms = menu->get_combined_minimum_size().width; Vector2 popup_pos = gt.position + gt.size - Vector2(ms, 0); - menu->set_position(popup_pos); + menu->set_global_position(popup_pos); menu->popup(); } +void EditorPropertyResource::_sub_inspector_property_keyed(const String &p_property, const Variant &p_value, bool) { + + emit_signal("property_keyed_with_value", String(get_edited_property()) + ":" + p_property, p_value); +} + +void EditorPropertyResource::_sub_inspector_resource_selected(const RES &p_resource, const String &p_property) { + + emit_signal("resource_selected", String(get_edited_property()) + ":" + p_property, p_resource); +} + +void EditorPropertyResource::_sub_inspector_object_id_selected(int p_id) { + + emit_signal("object_id_selected", get_edited_property(), p_id); +} + +void EditorPropertyResource::_open_editor_pressed() { + RES res = get_edited_object()->get(get_edited_property()); + if (res.is_valid()) { + EditorNode::get_singleton()->edit_resource(res.ptr()); + } +} + void EditorPropertyResource::update_property() { RES res = get_edited_object()->get(get_edited_property()); + if (use_sub_inspector) { + + if (res.is_valid() != assign->is_toggle_mode()) { + assign->set_toggle_mode(res.is_valid()); + } +#ifdef TOOLS_ENABLED + if (res.is_valid() && get_edited_object()->editor_is_section_unfolded(get_edited_property())) { + + if (!sub_inspector) { + sub_inspector = memnew(EditorInspector); + sub_inspector->set_enable_v_scroll(false); + + sub_inspector->set_use_sub_inspector_bg(true); + sub_inspector->set_enable_capitalize_paths(true); + + sub_inspector->connect("property_keyed", this, "_sub_inspector_property_keyed"); + sub_inspector->connect("resource_selected", this, "_sub_inspector_resource_selected"); + sub_inspector->connect("object_id_selected", this, "_sub_inspector_object_id_selected"); + sub_inspector->set_keying(is_keying()); + sub_inspector->set_read_only(is_read_only()); + sub_inspector->set_use_folding(is_using_folding()); + + sub_inspector_vbox = memnew(VBoxContainer); + add_child(sub_inspector_vbox); + set_bottom_editor(sub_inspector_vbox); + + sub_inspector_vbox->add_child(sub_inspector); + assign->set_pressed(true); + + bool use_editor = false; + for (int i = 0; i < EditorNode::get_singleton()->get_editor_data().get_editor_plugin_count(); i++) { + EditorPlugin *ep = EditorNode::get_singleton()->get_editor_data().get_editor_plugin(i); + if (ep->handles(res.ptr())) { + use_editor = true; + } + } + + if (use_editor) { + Button *open_in_editor = memnew(Button); + open_in_editor->set_text(TTR("Open Editor")); + open_in_editor->set_icon(get_icon("Edit", "EditorIcons")); + sub_inspector_vbox->add_child(open_in_editor); + open_in_editor->connect("pressed", this, "_open_editor_pressed"); + open_in_editor->set_h_size_flags(SIZE_SHRINK_CENTER); + } + } + + if (res.ptr() != sub_inspector->get_edited_object()) { + sub_inspector->edit(res.ptr()); + } + + } else { + if (sub_inspector) { + set_bottom_editor(NULL); + memdelete(sub_inspector_vbox); + sub_inspector = NULL; + sub_inspector_vbox = NULL; + } + } +#endif + } + + preview->set_texture(Ref<Texture>()); if (res == RES()) { assign->set_icon(Ref<Texture>()); assign->set_text(TTR("[empty]")); - assign->set_disabled(true); } else { - assign->set_disabled(false); Ref<Texture> icon; if (has_icon(res->get_class(), "EditorIcons")) @@ -1999,7 +2276,16 @@ void EditorPropertyResource::update_property() { void EditorPropertyResource::_resource_selected() { RES res = get_edited_object()->get(get_edited_property()); - if (!res.is_null()) { + if (res.is_null()) { + _update_menu(); + return; + } + + if (use_sub_inspector) { + + get_edited_object()->editor_set_section_unfold(get_edited_property(), assign->is_pressed()); + update_property(); + } else { emit_signal("resource_selected", get_edited_property(), res); } @@ -2015,6 +2301,23 @@ void EditorPropertyResource::_notification(int p_what) { Ref<Texture> t = get_icon("select_arrow", "Tree"); edit->set_icon(t); } + + if (p_what == NOTIFICATION_DRAG_BEGIN) { + + if (is_visible_in_tree()) { + if (_is_drop_valid(get_viewport()->gui_get_drag_data())) { + dropping = true; + assign->update(); + } + } + } + + if (p_what == NOTIFICATION_DRAG_END) { + if (dropping) { + dropping = false; + assign->update(); + } + } } void EditorPropertyResource::_viewport_selected(const NodePath &p_path) { @@ -2033,6 +2336,115 @@ void EditorPropertyResource::_viewport_selected(const NodePath &p_path) { emit_signal("property_changed", get_edited_property(), vt); update_property(); } + +void EditorPropertyResource::collapse_all_folding() { + if (sub_inspector) { + sub_inspector->collapse_all_folding(); + } +} + +void EditorPropertyResource::expand_all_folding() { + + if (sub_inspector) { + sub_inspector->expand_all_folding(); + } +} + +void EditorPropertyResource::_button_draw() { + + if (dropping) { + Color color = get_color("accent_color", "Editor"); + assign->draw_rect(Rect2(Point2(), assign->get_size()), color, false); + } +} + +Variant EditorPropertyResource::get_drag_data_fw(const Point2 &p_point, Control *p_from) { + + RES res = get_edited_object()->get(get_edited_property()); + if (res.is_valid()) { + + return EditorNode::get_singleton()->drag_resource(res, p_from); + } + + return Variant(); +} + +bool EditorPropertyResource::_is_drop_valid(const Dictionary &p_drag_data) const { + + String allowed_type = base_type; + + Dictionary drag_data = p_drag_data; + if (drag_data.has("type") && String(drag_data["type"]) == "resource") { + Ref<Resource> res = drag_data["resource"]; + for (int i = 0; i < allowed_type.get_slice_count(","); i++) { + String at = allowed_type.get_slice(",", i).strip_edges(); + if (res.is_valid() && ClassDB::is_parent_class(res->get_class(), at)) { + return true; + } + } + } + + if (drag_data.has("type") && String(drag_data["type"]) == "files") { + + Vector<String> files = drag_data["files"]; + + if (files.size() == 1) { + String file = files[0]; + String ftype = EditorFileSystem::get_singleton()->get_file_type(file); + + if (ftype != "") { + + for (int i = 0; i < allowed_type.get_slice_count(","); i++) { + String at = allowed_type.get_slice(",", i).strip_edges(); + if (ClassDB::is_parent_class(ftype, at)) { + return true; + } + } + } + } + } + + return false; +} + +bool EditorPropertyResource::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const { + + return _is_drop_valid(p_data); +} +void EditorPropertyResource::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { + + ERR_FAIL_COND(!_is_drop_valid(p_data)); + + Dictionary drag_data = p_data; + if (drag_data.has("type") && String(drag_data["type"]) == "resource") { + Ref<Resource> res = drag_data["resource"]; + if (res.is_valid()) { + emit_signal("property_changed", get_edited_property(), res); + update_property(); + return; + } + } + + if (drag_data.has("type") && String(drag_data["type"]) == "files") { + + Vector<String> files = drag_data["files"]; + + if (files.size() == 1) { + String file = files[0]; + RES res = ResourceLoader::load(file); + if (res.is_valid()) { + emit_signal("property_changed", get_edited_property(), res); + update_property(); + return; + } + } + } +} + +void EditorPropertyResource::set_use_sub_inspector(bool p_enable) { + use_sub_inspector = p_enable; +} + void EditorPropertyResource::_bind_methods() { ClassDB::bind_method(D_METHOD("_file_selected"), &EditorPropertyResource::_file_selected); @@ -2041,10 +2453,22 @@ void EditorPropertyResource::_bind_methods() { ClassDB::bind_method(D_METHOD("_resource_preview"), &EditorPropertyResource::_resource_preview); ClassDB::bind_method(D_METHOD("_resource_selected"), &EditorPropertyResource::_resource_selected); ClassDB::bind_method(D_METHOD("_viewport_selected"), &EditorPropertyResource::_viewport_selected); + ClassDB::bind_method(D_METHOD("_sub_inspector_property_keyed"), &EditorPropertyResource::_sub_inspector_property_keyed); + ClassDB::bind_method(D_METHOD("_sub_inspector_resource_selected"), &EditorPropertyResource::_sub_inspector_resource_selected); + ClassDB::bind_method(D_METHOD("_sub_inspector_object_id_selected"), &EditorPropertyResource::_sub_inspector_object_id_selected); + ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &EditorPropertyResource::get_drag_data_fw); + ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &EditorPropertyResource::can_drop_data_fw); + ClassDB::bind_method(D_METHOD("drop_data_fw"), &EditorPropertyResource::drop_data_fw); + ClassDB::bind_method(D_METHOD("_button_draw"), &EditorPropertyResource::_button_draw); + ClassDB::bind_method(D_METHOD("_open_editor_pressed"), &EditorPropertyResource::_open_editor_pressed); } EditorPropertyResource::EditorPropertyResource() { + sub_inspector = NULL; + sub_inspector_vbox = NULL; + use_sub_inspector = bool(EDITOR_GET("interface/inspector/open_resources_in_current_inspector")); + HBoxContainer *hbc = memnew(HBoxContainer); add_child(hbc); assign = memnew(Button); @@ -2052,8 +2476,18 @@ EditorPropertyResource::EditorPropertyResource() { assign->set_h_size_flags(SIZE_EXPAND_FILL); assign->set_clip_text(true); assign->connect("pressed", this, "_resource_selected"); + assign->set_drag_forwarding(this); + assign->connect("draw", this, "_button_draw"); hbc->add_child(assign); + preview = memnew(TextureRect); + preview->set_expand(true); + preview->set_anchors_and_margins_preset(PRESET_WIDE); + preview->set_margin(MARGIN_TOP, 1); + preview->set_margin(MARGIN_BOTTOM, -1); + preview->set_margin(MARGIN_RIGHT, -1); + assign->add_child(preview); + menu = memnew(PopupMenu); add_child(menu); edit = memnew(Button); @@ -2064,6 +2498,7 @@ EditorPropertyResource::EditorPropertyResource() { file = NULL; scene_tree = NULL; + dropping = false; } ////////////// DEFAULT PLUGIN ////////////////////// @@ -2081,6 +2516,10 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ switch (p_type) { // atomic types + case Variant::NIL: { + EditorPropertyNil *editor = memnew(EditorPropertyNil); + add_property_editor(p_path, editor); + } break; case Variant::BOOL: { EditorPropertyCheck *editor = memnew(EditorPropertyCheck); add_property_editor(p_path, editor); @@ -2215,6 +2654,10 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ } else if (p_hint == PROPERTY_HINT_MULTILINE_TEXT) { EditorPropertyMultilineText *editor = memnew(EditorPropertyMultilineText); add_property_editor(p_path, editor); + } else if (p_hint == PROPERTY_HINT_TYPE_STRING) { + EditorPropertyClassName *editor = memnew(EditorPropertyClassName); + editor->setup("Object", p_hint_text); + add_property_editor(p_path, editor); } else if (p_hint == PROPERTY_HINT_DIR || p_hint == PROPERTY_HINT_FILE || p_hint == PROPERTY_HINT_GLOBAL_DIR || p_hint == PROPERTY_HINT_GLOBAL_FILE) { Vector<String> extensions = p_hint_text.split(","); @@ -2425,7 +2868,12 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ EditorPropertyNodePath *editor = memnew(EditorPropertyNodePath); if (p_hint == PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE && p_hint_text != String()) { - editor->setup(p_hint_text); + editor->setup(p_hint_text, Vector<StringName>()); + } + if (p_hint == PROPERTY_HINT_NODE_PATH_VALID_TYPES && p_hint_text != String()) { + Vector<String> types = p_hint_text.split(",", false); + Vector<StringName> sn = Variant(types); //convert via variant + editor->setup(NodePath(), sn); } add_property_editor(p_path, editor); @@ -2435,28 +2883,68 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ case Variant::OBJECT: { EditorPropertyResource *editor = memnew(EditorPropertyResource); editor->setup(p_hint == PROPERTY_HINT_RESOURCE_TYPE ? p_hint_text : "Resource"); + + if (p_hint == PROPERTY_HINT_RESOURCE_TYPE) { + String open_in_new = EDITOR_GET("interface/inspector/resources_types_to_open_in_new_inspector"); + for (int i = 0; i < open_in_new.get_slice_count(","); i++) { + String type = open_in_new.get_slicec(',', i).strip_edges(); + for (int j = 0; j < p_hint_text.get_slice_count(","); j++) { + String inherits = p_hint_text.get_slicec(',', j); + + if (ClassDB::is_parent_class(inherits, type)) { + + editor->set_use_sub_inspector(false); + } + } + } + } + add_property_editor(p_path, editor); } break; case Variant::DICTIONARY: { + EditorPropertyDictionary *editor = memnew(EditorPropertyDictionary); + add_property_editor(p_path, editor); } break; case Variant::ARRAY: { + EditorPropertyArray *editor = memnew(EditorPropertyArray); + editor->setup(Variant::ARRAY); + add_property_editor(p_path, editor); } break; - - // arrays case Variant::POOL_BYTE_ARRAY: { + EditorPropertyArray *editor = memnew(EditorPropertyArray); + editor->setup(Variant::POOL_BYTE_ARRAY); + add_property_editor(p_path, editor); } break; // 20 case Variant::POOL_INT_ARRAY: { + EditorPropertyArray *editor = memnew(EditorPropertyArray); + editor->setup(Variant::POOL_INT_ARRAY); + add_property_editor(p_path, editor); } break; case Variant::POOL_REAL_ARRAY: { + EditorPropertyArray *editor = memnew(EditorPropertyArray); + editor->setup(Variant::POOL_REAL_ARRAY); + add_property_editor(p_path, editor); } break; case Variant::POOL_STRING_ARRAY: { + EditorPropertyArray *editor = memnew(EditorPropertyArray); + editor->setup(Variant::POOL_STRING_ARRAY); + add_property_editor(p_path, editor); } break; case Variant::POOL_VECTOR2_ARRAY: { + EditorPropertyArray *editor = memnew(EditorPropertyArray); + editor->setup(Variant::POOL_VECTOR2_ARRAY); + add_property_editor(p_path, editor); } break; case Variant::POOL_VECTOR3_ARRAY: { + EditorPropertyArray *editor = memnew(EditorPropertyArray); + editor->setup(Variant::POOL_VECTOR3_ARRAY); + add_property_editor(p_path, editor); } break; // 25 case Variant::POOL_COLOR_ARRAY: { + EditorPropertyArray *editor = memnew(EditorPropertyArray); + editor->setup(Variant::POOL_COLOR_ARRAY); + add_property_editor(p_path, editor); } break; default: {} } |