diff options
Diffstat (limited to 'editor')
-rw-r--r-- | editor/editor_help.cpp | 63 | ||||
-rw-r--r-- | editor/editor_properties.cpp | 53 | ||||
-rw-r--r-- | editor/editor_properties.h | 3 | ||||
-rw-r--r-- | editor/filesystem_dock.cpp | 27 | ||||
-rw-r--r-- | editor/plugins/node_3d_editor_plugin.cpp | 37 | ||||
-rw-r--r-- | editor/plugins/skeleton_3d_editor_plugin.cpp | 287 | ||||
-rw-r--r-- | editor/plugins/skeleton_3d_editor_plugin.h | 40 |
7 files changed, 251 insertions, 259 deletions
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index bad2203423..f50ac6d580 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -243,6 +243,9 @@ void EditorHelp::_add_method(const DocData::MethodDoc &p_method, bool p_overview if (p_overview) { class_desc->push_cell(); class_desc->push_align(RichTextLabel::ALIGN_RIGHT); + } else { + static const CharType prefix[3] = { 0x25CF /* filled circle */, ' ', 0 }; + class_desc->add_text(String(prefix)); } _add_type(p_method.return_type, p_method.return_enum); @@ -378,7 +381,6 @@ void EditorHelp::_update_doc() { class_desc->push_color(title_color); class_desc->push_font(doc_font); class_desc->add_text(TTR("Inherits:") + " "); - class_desc->pop(); String inherits = cd.inherits; @@ -393,6 +395,7 @@ void EditorHelp::_update_doc() { } class_desc->pop(); + class_desc->pop(); class_desc->add_newline(); } @@ -401,13 +404,12 @@ void EditorHelp::_update_doc() { bool found = false; bool prev = false; + class_desc->push_font(doc_font); for (Map<String, DocData::ClassDoc>::Element *E = doc->class_list.front(); E; E = E->next()) { if (E->get().inherits == cd.name) { if (!found) { class_desc->push_color(title_color); - class_desc->push_font(doc_font); class_desc->add_text(TTR("Inherited by:") + " "); - class_desc->pop(); found = true; } @@ -419,6 +421,7 @@ void EditorHelp::_update_doc() { prev = true; } } + class_desc->pop(); if (found) { class_desc->pop(); @@ -758,6 +761,8 @@ void EditorHelp::_update_doc() { signal_line[cd.signals[i].name] = class_desc->get_line_count() - 2; //gets overridden if description class_desc->push_font(doc_code_font); // monofont class_desc->push_color(headline_color); + static const CharType prefix[3] = { 0x25CF /* filled circle */, ' ', 0 }; + class_desc->add_text(String(prefix)); _add_text(cd.signals[i].name); class_desc->pop(); class_desc->push_color(symbol_color); @@ -835,10 +840,10 @@ void EditorHelp::_update_doc() { for (Map<String, Vector<DocData::ConstantDoc>>::Element *E = enums.front(); E; E = E->next()) { enum_line[E->key()] = class_desc->get_line_count() - 2; + class_desc->push_font(doc_code_font); class_desc->push_color(title_color); class_desc->add_text("enum "); class_desc->pop(); - class_desc->push_font(doc_code_font); String e = E->key(); if ((e.get_slice_count(".") > 1) && (e.get_slice(".", 0) == edited_class)) { e = e.get_slice(".", 1); @@ -851,6 +856,8 @@ void EditorHelp::_update_doc() { class_desc->push_color(symbol_color); class_desc->add_text(":"); class_desc->pop(); + + class_desc->add_newline(); class_desc->add_newline(); class_desc->push_indent(1); @@ -869,6 +876,8 @@ void EditorHelp::_update_doc() { class_desc->push_font(doc_code_font); class_desc->push_color(headline_color); + static const CharType prefix[3] = { 0x25CF /* filled circle */, ' ', 0 }; + class_desc->add_text(String(prefix)); _add_text(enum_list[i].name); class_desc->pop(); class_desc->push_color(symbol_color); @@ -880,14 +889,15 @@ void EditorHelp::_update_doc() { class_desc->pop(); if (enum_list[i].description != "") { class_desc->push_font(doc_font); - //class_desc->add_text(" "); - class_desc->push_indent(1); class_desc->push_color(comment_color); + static const CharType dash[6] = { ' ', ' ', 0x2013 /* en dash */, ' ', ' ', 0 }; + class_desc->add_text(String(dash)); _add_text(DTR(enum_list[i].description)); class_desc->pop(); class_desc->pop(); - class_desc->pop(); // indent - class_desc->add_newline(); + if (DTR(enum_list[i].description).find("\n") > 0) { + class_desc->add_newline(); + } } class_desc->add_newline(); @@ -931,6 +941,9 @@ void EditorHelp::_update_doc() { class_desc->add_text(String(prefix)); class_desc->pop(); } + } else { + static const CharType prefix[3] = { 0x25CF /* filled circle */, ' ', 0 }; + class_desc->add_text(String(prefix)); } class_desc->push_color(headline_color); @@ -946,13 +959,15 @@ void EditorHelp::_update_doc() { class_desc->pop(); if (constants[i].description != "") { class_desc->push_font(doc_font); - class_desc->push_indent(1); class_desc->push_color(comment_color); + static const CharType dash[6] = { ' ', ' ', 0x2013 /* en dash */, ' ', ' ', 0 }; + class_desc->add_text(String(dash)); _add_text(DTR(constants[i].description)); class_desc->pop(); class_desc->pop(); - class_desc->pop(); // indent - class_desc->add_newline(); + if (DTR(constants[i].description).find("\n") > 0) { + class_desc->add_newline(); + } } class_desc->add_newline(); @@ -987,6 +1002,9 @@ void EditorHelp::_update_doc() { class_desc->push_cell(); class_desc->push_font(doc_code_font); + static const CharType prefix[3] = { 0x25CF /* filled circle */, ' ', 0 }; + class_desc->add_text(String(prefix)); + _add_type(cd.properties[i].type, cd.properties[i].enumeration); class_desc->add_text(" "); class_desc->pop(); // font @@ -1015,6 +1033,11 @@ void EditorHelp::_update_doc() { class_desc->pop(); // font class_desc->pop(); // cell + Map<String, DocData::MethodDoc> method_map; + for (int j = 0; j < methods.size(); j++) { + method_map[methods[j].name] = methods[j]; + } + if (cd.properties[i].setter != "") { class_desc->push_cell(); class_desc->pop(); // cell @@ -1022,7 +1045,14 @@ void EditorHelp::_update_doc() { class_desc->push_cell(); class_desc->push_font(doc_code_font); class_desc->push_color(text_color); - class_desc->add_text(cd.properties[i].setter + TTR("(value)")); + if (method_map[cd.properties[i].setter].arguments.size() > 1) { + // Setters with additional arguments are exposed in the method list, so we link them here for quick access. + class_desc->push_meta("@method " + cd.properties[i].setter); + class_desc->add_text(cd.properties[i].setter + TTR("(value)")); + class_desc->pop(); + } else { + class_desc->add_text(cd.properties[i].setter + TTR("(value)")); + } class_desc->pop(); // color class_desc->push_color(comment_color); class_desc->add_text(" setter"); @@ -1039,7 +1069,14 @@ void EditorHelp::_update_doc() { class_desc->push_cell(); class_desc->push_font(doc_code_font); class_desc->push_color(text_color); - class_desc->add_text(cd.properties[i].getter + "()"); + if (method_map[cd.properties[i].getter].arguments.size() > 0) { + // Getters with additional arguments are exposed in the method list, so we link them here for quick access. + class_desc->push_meta("@method " + cd.properties[i].getter); + class_desc->add_text(cd.properties[i].getter + "()"); + class_desc->pop(); + } else { + class_desc->add_text(cd.properties[i].getter + "()"); + } class_desc->pop(); //color class_desc->push_color(comment_color); class_desc->add_text(" getter"); diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index cfa0c7a063..74267452e6 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -1283,14 +1283,25 @@ void EditorPropertyVector3::_value_changed(double val, const String &p_name) { } void EditorPropertyVector3::update_property() { - Vector3 val = get_edited_object()->get(get_edited_property()); + update_using_vector(get_edited_object()->get(get_edited_property())); +} + +void EditorPropertyVector3::update_using_vector(Vector3 p_vector) { setting = true; - spin[0]->set_value(val.x); - spin[1]->set_value(val.y); - spin[2]->set_value(val.z); + spin[0]->set_value(p_vector.x); + spin[1]->set_value(p_vector.y); + spin[2]->set_value(p_vector.z); setting = false; } +Vector3 EditorPropertyVector3::get_vector() { + Vector3 v3; + v3.x = spin[0]->get_value(); + v3.y = spin[1]->get_value(); + v3.z = spin[2]->get_value(); + return v3; +} + void EditorPropertyVector3::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { Color base = get_theme_color("accent_color", "Editor"); @@ -1434,7 +1445,7 @@ EditorPropertyVector2i::EditorPropertyVector2i(bool p_force_wide) { setting = false; } -///////////////////// RECT2 ///////////////////////// +///////////////////// RECT2i ///////////////////////// void EditorPropertyRect2i::_value_changed(double val, const String &p_name) { if (setting) { @@ -1520,7 +1531,7 @@ EditorPropertyRect2i::EditorPropertyRect2i(bool p_force_wide) { setting = false; } -///////////////////// VECTOR3 ///////////////////////// +///////////////////// VECTOR3i ///////////////////////// void EditorPropertyVector3i::_value_changed(double val, const String &p_name) { if (setting) { @@ -2029,21 +2040,23 @@ void EditorPropertyTransform::_value_changed(double val, const String &p_name) { } void EditorPropertyTransform::update_property() { - Transform val = get_edited_object()->get(get_edited_property()); - setting = true; - spin[0]->set_value(val.basis[0][0]); - spin[1]->set_value(val.basis[1][0]); - spin[2]->set_value(val.basis[2][0]); - spin[3]->set_value(val.basis[0][1]); - spin[4]->set_value(val.basis[1][1]); - spin[5]->set_value(val.basis[2][1]); - spin[6]->set_value(val.basis[0][2]); - spin[7]->set_value(val.basis[1][2]); - spin[8]->set_value(val.basis[2][2]); - spin[9]->set_value(val.origin[0]); - spin[10]->set_value(val.origin[1]); - spin[11]->set_value(val.origin[2]); + update_using_transform(get_edited_object()->get(get_edited_property())); +} +void EditorPropertyTransform::update_using_transform(Transform p_transform) { + setting = true; + spin[0]->set_value(p_transform.basis[0][0]); + spin[1]->set_value(p_transform.basis[1][0]); + spin[2]->set_value(p_transform.basis[2][0]); + spin[3]->set_value(p_transform.basis[0][1]); + spin[4]->set_value(p_transform.basis[1][1]); + spin[5]->set_value(p_transform.basis[2][1]); + spin[6]->set_value(p_transform.basis[0][2]); + spin[7]->set_value(p_transform.basis[1][2]); + spin[8]->set_value(p_transform.basis[2][2]); + spin[9]->set_value(p_transform.origin[0]); + spin[10]->set_value(p_transform.origin[1]); + spin[11]->set_value(p_transform.origin[2]); setting = false; } diff --git a/editor/editor_properties.h b/editor/editor_properties.h index 61c11f4534..35e6c10d90 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -392,6 +392,8 @@ protected: public: virtual void update_property(); + virtual void update_using_vector(Vector3 p_vector); + virtual Vector3 get_vector(); void setup(double p_min, double p_max, double p_step, bool p_no_slider); EditorPropertyVector3(bool p_force_wide = false); }; @@ -536,6 +538,7 @@ protected: public: virtual void update_property(); + virtual void update_using_transform(Transform p_transform); void setup(double p_min, double p_max, double p_step, bool p_no_slider); EditorPropertyTransform(); }; diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 4fdc3dc080..f279f402d9 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -2085,7 +2085,32 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, } } if (!to_move.empty()) { - _move_operation_confirm(to_dir); + if (Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { + for (int i = 0; i < to_move.size(); i++) { + String new_path; + String new_path_base; + + if (to_move[i].is_file) { + new_path = to_dir.plus_file(to_move[i].path.get_file()); + new_path_base = new_path.get_basename() + " (%d)." + new_path.get_extension(); + } else { + PackedStringArray path_split = to_move[i].path.split("/"); + new_path = to_dir.plus_file(path_split[path_split.size() - 2]); + new_path_base = new_path + " (%d)"; + } + + int exist_counter = 1; + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + while (da->file_exists(new_path) || da->dir_exists(new_path)) { + exist_counter++; + new_path = vformat(new_path_base, exist_counter); + } + _try_duplicate_item(to_move[i], new_path); + } + _rescan(); + } else { + _move_operation_confirm(to_dir); + } } } else if (favorite) { // Add the files from favorites. diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 796dd3f8b2..7bf8fd7d26 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -2583,14 +2583,14 @@ void Node3DEditorViewport::_notification(int p_what) { } } -static void draw_indicator_bar(Control &surface, real_t fill, Ref<Texture2D> icon) { +static void draw_indicator_bar(Control &surface, real_t fill, const Ref<Texture2D> icon, const Ref<Font> font, const String &text) { // Adjust bar size from control height - Vector2 surface_size = surface.get_size(); - real_t h = surface_size.y / 2.0; - real_t y = (surface_size.y - h) / 2.0; + const Vector2 surface_size = surface.get_size(); + const real_t h = surface_size.y / 2.0; + const real_t y = (surface_size.y - h) / 2.0; - Rect2 r(10, y, 6, h); - real_t sy = r.size.y * fill; + const Rect2 r(10 * EDSCALE, y, 6 * EDSCALE, h); + const real_t sy = r.size.y * fill; // Note: because this bar appears over the viewport, it has to stay readable for any background color // Draw both neutral dark and bright colors to account this @@ -2598,9 +2598,12 @@ static void draw_indicator_bar(Control &surface, real_t fill, Ref<Texture2D> ico surface.draw_rect(Rect2(r.position.x, r.position.y + r.size.y - sy, r.size.x, sy), Color(1, 1, 1, 0.6)); surface.draw_rect(r.grow(1), Color(0, 0, 0, 0.7), false, Math::round(EDSCALE)); - Vector2 icon_size = icon->get_size(); - Vector2 icon_pos = Vector2(r.position.x - (icon_size.x - r.size.x) / 2, r.position.y + r.size.y + 2); + const Vector2 icon_size = icon->get_size(); + const Vector2 icon_pos = Vector2(r.position.x - (icon_size.x - r.size.x) / 2, r.position.y + r.size.y + 2 * EDSCALE); surface.draw_texture(icon, icon_pos); + + // Draw text below the bar (for speed/zoom information). + surface.draw_string(font, Vector2(icon_pos.x, icon_pos.y + icon_size.y + 16 * EDSCALE), text); } void Node3DEditorViewport::_draw() { @@ -2697,7 +2700,14 @@ void Node3DEditorViewport::_draw() { logscale_t = 0.25 * Math::exp(4.0 * logscale_t - 1.0); } - draw_indicator_bar(*surface, 1.0 - logscale_t, get_theme_icon("ViewportSpeed", "EditorIcons")); + // Display the freelook speed to help the user get a better sense of scale. + const int precision = freelook_speed < 1.0 ? 2 : 1; + draw_indicator_bar( + *surface, + 1.0 - logscale_t, + get_theme_icon("ViewportSpeed", "EditorIcons"), + get_theme_font("font", "Label"), + vformat("%s u/s", String::num(freelook_speed).pad_decimals(precision))); } } else { @@ -2716,7 +2726,14 @@ void Node3DEditorViewport::_draw() { logscale_t = 0.25 * Math::exp(4.0 * logscale_t - 1.0); } - draw_indicator_bar(*surface, logscale_t, get_theme_icon("ViewportZoom", "EditorIcons")); + // Display the zoom center distance to help the user get a better sense of scale. + const int precision = cursor.distance < 1.0 ? 2 : 1; + draw_indicator_bar( + *surface, + logscale_t, + get_theme_icon("ViewportZoom", "EditorIcons"), + get_theme_font("font", "Label"), + vformat("%s u", String::num(cursor.distance).pad_decimals(precision))); } } } diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp index 2586f17fe1..52da8dea19 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.cpp +++ b/editor/plugins/skeleton_3d_editor_plugin.cpp @@ -62,125 +62,56 @@ void BoneTransformEditor::create_editors() { enabled_checkbox->set_visible(toggle_enabled); section->get_vbox()->add_child(enabled_checkbox); - Label *l1 = memnew(Label(TTR("Translation"))); - section->get_vbox()->add_child(l1); - - translation_grid = memnew(GridContainer()); - translation_grid->set_columns(TRANSLATION_COMPONENTS); - section->get_vbox()->add_child(translation_grid); - - Label *l2 = memnew(Label(TTR("Rotation Degrees"))); - section->get_vbox()->add_child(l2); - - rotation_grid = memnew(GridContainer()); - rotation_grid->set_columns(ROTATION_DEGREES_COMPONENTS); - section->get_vbox()->add_child(rotation_grid); - - Label *l3 = memnew(Label(TTR("Scale"))); - section->get_vbox()->add_child(l3); - - scale_grid = memnew(GridContainer()); - scale_grid->set_columns(SCALE_COMPONENTS); - section->get_vbox()->add_child(scale_grid); - - Label *l4 = memnew(Label(TTR("Transform"))); - section->get_vbox()->add_child(l4); - - transform_grid = memnew(GridContainer()); - transform_grid->set_columns(TRANSFORM_CONTROL_COMPONENTS); - section->get_vbox()->add_child(transform_grid); - - static const char *desc[TRANSFORM_COMPONENTS] = { "x", "y", "z", "x", "y", "z", "x", "y", "z", "x", "y", "z" }; - - for (int i = 0; i < TRANSFORM_CONTROL_COMPONENTS; ++i) { - translation_slider[i] = memnew(EditorSpinSlider()); - translation_slider[i]->set_label(desc[i]); - setup_spinner(translation_slider[i], false); - translation_grid->add_child(translation_slider[i]); - - rotation_slider[i] = memnew(EditorSpinSlider()); - rotation_slider[i]->set_label(desc[i]); - setup_spinner(rotation_slider[i], false); - rotation_grid->add_child(rotation_slider[i]); - - scale_slider[i] = memnew(EditorSpinSlider()); - scale_slider[i]->set_label(desc[i]); - setup_spinner(scale_slider[i], false); - scale_grid->add_child(scale_slider[i]); - } - - for (int i = 0; i < TRANSFORM_COMPONENTS; ++i) { - transform_slider[i] = memnew(EditorSpinSlider()); - transform_slider[i]->set_label(desc[i]); - setup_spinner(transform_slider[i], true); - transform_grid->add_child(transform_slider[i]); - } -} - -void BoneTransformEditor::setup_spinner(EditorSpinSlider *spinner, const bool is_transform_spinner) { - spinner->set_flat(true); - spinner->set_min(-10000); - spinner->set_max(10000); - spinner->set_step(0.001f); - spinner->set_hide_slider(true); - spinner->set_allow_greater(true); - spinner->set_allow_lesser(true); - spinner->set_h_size_flags(SIZE_EXPAND_FILL); - - spinner->connect_compat("value_changed", this, "_value_changed", varray(is_transform_spinner)); + // Translation property + translation_property = memnew(EditorPropertyVector3()); + translation_property->setup(-10000, 10000, 0.001f, true); + translation_property->set_label("Translation"); + translation_property->set_use_folding(true); + translation_property->set_read_only(false); + translation_property->connect("property_changed", callable_mp(this, &BoneTransformEditor::_value_changed_vector3)); + section->get_vbox()->add_child(translation_property); + + // Rotation property + rotation_property = memnew(EditorPropertyVector3()); + rotation_property->setup(-10000, 10000, 0.001f, true); + rotation_property->set_label("Rotation Degrees"); + rotation_property->set_use_folding(true); + rotation_property->set_read_only(false); + rotation_property->connect("property_changed", callable_mp(this, &BoneTransformEditor::_value_changed_vector3)); + section->get_vbox()->add_child(rotation_property); + + // Scale property + scale_property = memnew(EditorPropertyVector3()); + scale_property->setup(-10000, 10000, 0.001f, true); + scale_property->set_label("Scale"); + scale_property->set_use_folding(true); + scale_property->set_read_only(false); + scale_property->connect("property_changed", callable_mp(this, &BoneTransformEditor::_value_changed_vector3)); + section->get_vbox()->add_child(scale_property); + + // Transform/Matrix section + transform_section = memnew(EditorInspectorSection); + transform_section->setup("trf_properties_transform", "Matrix", this, section_color, true); + section->get_vbox()->add_child(transform_section); + + // Transform/Matrix property + transform_property = memnew(EditorPropertyTransform()); + transform_property->setup(-10000, 10000, 0.001f, true); + transform_property->set_label("Transform"); + transform_property->set_use_folding(true); + transform_property->set_read_only(false); + transform_property->connect("property_changed", callable_mp(this, &BoneTransformEditor::_value_changed_transform)); + transform_section->get_vbox()->add_child(transform_property); } void BoneTransformEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { create_editors(); - key_button->connect_compat("pressed", this, "_key_button_pressed"); - enabled_checkbox->connect_compat("toggled", this, "_checkbox_toggled"); + key_button->connect("pressed", callable_mp(this, &BoneTransformEditor::_key_button_pressed)); + enabled_checkbox->connect("toggled", callable_mp(this, &BoneTransformEditor::_checkbox_toggled)); [[fallthrough]]; } - case NOTIFICATION_THEME_CHANGED: { - const Color base = get_theme_color("accent_color", "Editor"); - const Color bg_color = get_theme_color("property_color", "Editor"); - const Color bg_lbl_color(bg_color.r, bg_color.g, bg_color.b, 0.5); - - for (int i = 0; i < TRANSLATION_COMPONENTS; i++) { - Color c = base; - c.set_hsv(float(i % TRANSLATION_COMPONENTS) / TRANSLATION_COMPONENTS + 0.05, c.get_s() * 0.75, c.get_v()); - if (!translation_slider[i]) { - continue; - } - translation_slider[i]->set_custom_label_color(true, c); - } - - for (int i = 0; i < ROTATION_DEGREES_COMPONENTS; i++) { - Color c = base; - c.set_hsv(float(i % ROTATION_DEGREES_COMPONENTS) / ROTATION_DEGREES_COMPONENTS + 0.05, c.get_s() * 0.75, c.get_v()); - if (!rotation_slider[i]) { - continue; - } - rotation_slider[i]->set_custom_label_color(true, c); - } - - for (int i = 0; i < SCALE_COMPONENTS; i++) { - Color c = base; - c.set_hsv(float(i % SCALE_COMPONENTS) / SCALE_COMPONENTS + 0.05, c.get_s() * 0.75, c.get_v()); - if (!scale_slider[i]) { - continue; - } - scale_slider[i]->set_custom_label_color(true, c); - } - - for (int i = 0; i < TRANSFORM_COMPONENTS; i++) { - Color c = base; - c.set_hsv(float(i % TRANSFORM_COMPONENTS) / TRANSFORM_COMPONENTS + 0.05, c.get_s() * 0.75, c.get_v()); - if (!transform_slider[i]) { - continue; - } - transform_slider[i]->set_custom_label_color(true, c); - } - - break; - } case NOTIFICATION_SORT_CHILDREN: { const Ref<Font> font = get_theme_font("font", "Tree"); @@ -189,8 +120,8 @@ void BoneTransformEditor::_notification(int p_what) { buffer.y += font->get_height(); buffer.y += get_theme_constant("vseparation", "Tree"); - const float vector_height = translation_grid->get_size().y; - const float transform_height = transform_grid->get_size().y; + const float vector_height = translation_property->get_size().y; + const float transform_height = transform_property->get_size().y; const float button_height = key_button->get_size().y; const float width = get_size().x - get_theme_constant("inspector_margin", "Editor"); @@ -202,10 +133,10 @@ void BoneTransformEditor::_notification(int p_what) { } if (section->get_vbox()->is_visible()) { - input_rects.push_back(Rect2(translation_grid->get_position() + buffer, Size2(width, vector_height))); - input_rects.push_back(Rect2(rotation_grid->get_position() + buffer, Size2(width, vector_height))); - input_rects.push_back(Rect2(scale_grid->get_position() + buffer, Size2(width, vector_height))); - input_rects.push_back(Rect2(transform_grid->get_position() + buffer, Size2(width, transform_height))); + input_rects.push_back(Rect2(translation_property->get_position() + buffer, Size2(width, vector_height))); + input_rects.push_back(Rect2(rotation_property->get_position() + buffer, Size2(width, vector_height))); + input_rects.push_back(Rect2(scale_property->get_position() + buffer, Size2(width, vector_height))); + input_rects.push_back(Rect2(transform_property->get_position() + buffer, Size2(width, transform_height))); } else { const int32_t start = input_rects.size(); const int32_t empty_input_rect_elements = 4; @@ -234,49 +165,53 @@ void BoneTransformEditor::_notification(int p_what) { } } -void BoneTransformEditor::_value_changed(const double p_value, const bool p_from_transform) { +void BoneTransformEditor::_value_changed(const double p_value) { if (updating) return; - if (property.get_slicec('/', 0) == "bones" && property.get_slicec('/', 2) == "custom_pose") { - const Transform tform = compute_transform(p_from_transform); + Transform tform = compute_transform_from_vector3s(); + _change_transform(tform); +} +void BoneTransformEditor::_value_changed_vector3(const String p_property_name, const Vector3 p_vector, const StringName p_edited_property_name, const bool p_boolean) { + if (updating) + return; + Transform tform = compute_transform_from_vector3s(); + _change_transform(tform); +} + +Transform BoneTransformEditor::compute_transform_from_vector3s() const { + // Convert rotation from degrees to radians. + Vector3 prop_rotation = rotation_property->get_vector(); + prop_rotation.x = Math::deg2rad(prop_rotation.x); + prop_rotation.y = Math::deg2rad(prop_rotation.y); + prop_rotation.z = Math::deg2rad(prop_rotation.z); + + return Transform( + Basis(prop_rotation, scale_property->get_vector()), + translation_property->get_vector()); +} + +void BoneTransformEditor::_value_changed_transform(const String p_property_name, const Transform p_transform, const StringName p_edited_property_name, const bool p_boolean) { + if (updating) + return; + _change_transform(p_transform); +} + +void BoneTransformEditor::_change_transform(Transform p_new_transform) { + if (property.get_slicec('/', 0) == "bones" && property.get_slicec('/', 2) == "custom_pose") { undo_redo->create_action(TTR("Set Custom Bone Pose Transform"), UndoRedo::MERGE_ENDS); undo_redo->add_undo_method(skeleton, "set_bone_custom_pose", property.get_slicec('/', 1).to_int(), skeleton->get_bone_custom_pose(property.get_slicec('/', 1).to_int())); - undo_redo->add_do_method(skeleton, "set_bone_custom_pose", property.get_slicec('/', 1).to_int(), tform); + undo_redo->add_do_method(skeleton, "set_bone_custom_pose", property.get_slicec('/', 1).to_int(), p_new_transform); undo_redo->commit_action(); } else if (property.get_slicec('/', 0) == "bones") { - const Transform tform = compute_transform(p_from_transform); - undo_redo->create_action(TTR("Set Bone Transform"), UndoRedo::MERGE_ENDS); undo_redo->add_undo_property(skeleton, property, skeleton->get(property)); - undo_redo->add_do_property(skeleton, property, tform); + undo_redo->add_do_property(skeleton, property, p_new_transform); undo_redo->commit_action(); } } -Transform BoneTransformEditor::compute_transform(const bool p_from_transform) const { - // Last modified was a raw transform column... - if (p_from_transform) { - Transform tform; - - for (int i = 0; i < BASIS_COMPONENTS; ++i) { - tform.basis[i / BASIS_SPLIT_COMPONENTS][i % BASIS_SPLIT_COMPONENTS] = transform_slider[i]->get_value(); - } - - for (int i = 0; i < TRANSLATION_COMPONENTS; ++i) { - tform.origin[i] = transform_slider[i + BASIS_COMPONENTS]->get_value(); - } - - return tform; - } - - return Transform( - Basis(Vector3(Math::deg2rad(rotation_slider[0]->get_value()), Math::deg2rad(rotation_slider[1]->get_value()), Math::deg2rad(rotation_slider[2]->get_value())), - Vector3(scale_slider[0]->get_value(), scale_slider[1]->get_value(), scale_slider[2]->get_value())), - Vector3(translation_slider[0]->get_value(), translation_slider[1]->get_value(), translation_slider[2]->get_value())); -} - void BoneTransformEditor::update_enabled_checkbox() { if (enabled_checkbox) { const String path = "bones/" + property.get_slicec('/', 1) + "/enabled"; @@ -285,12 +220,6 @@ void BoneTransformEditor::update_enabled_checkbox() { } } -void BoneTransformEditor::_bind_methods() { - ClassDB::bind_method(D_METHOD("_value_changed", "value"), &BoneTransformEditor::_value_changed); - ClassDB::bind_method(D_METHOD("_key_button_pressed"), &BoneTransformEditor::_key_button_pressed); - ClassDB::bind_method(D_METHOD("_checkbox_toggled", "toggled"), &BoneTransformEditor::_checkbox_toggled); -} - void BoneTransformEditor::_update_properties() { if (updating) return; @@ -318,47 +247,22 @@ void BoneTransformEditor::_update_custom_pose_properties() { } void BoneTransformEditor::_update_transform_properties(Transform tform) { - Quat rot = tform.get_basis(); - Vector3 rot_rad = rot.get_euler(); - Vector3 rot_degrees = Vector3(Math::rad2deg(rot_rad.x), Math::rad2deg(rot_rad.y), Math::rad2deg(rot_rad.z)); - Vector3 tr = tform.get_origin(); + Basis rotation_basis = tform.get_basis(); + Vector3 rotation_radians = rotation_basis.get_rotation_euler(); + Vector3 rotation_degrees = Vector3(Math::rad2deg(rotation_radians.x), Math::rad2deg(rotation_radians.y), Math::rad2deg(rotation_radians.z)); + Vector3 translation = tform.get_origin(); Vector3 scale = tform.basis.get_scale(); - for (int i = 0; i < TRANSLATION_COMPONENTS; i++) { - translation_slider[i]->set_value(tr[i]); - } - - for (int i = 0; i < ROTATION_DEGREES_COMPONENTS; i++) { - rotation_slider[i]->set_value(rot_degrees[i]); - } - - for (int i = 0; i < SCALE_COMPONENTS; i++) { - scale_slider[i]->set_value(scale[i]); - } - - transform_slider[0]->set_value(tform.get_basis()[Vector3::AXIS_X].x); - transform_slider[1]->set_value(tform.get_basis()[Vector3::AXIS_X].y); - transform_slider[2]->set_value(tform.get_basis()[Vector3::AXIS_X].z); - transform_slider[3]->set_value(tform.get_basis()[Vector3::AXIS_Y].x); - transform_slider[4]->set_value(tform.get_basis()[Vector3::AXIS_Y].y); - transform_slider[5]->set_value(tform.get_basis()[Vector3::AXIS_Y].z); - transform_slider[6]->set_value(tform.get_basis()[Vector3::AXIS_Z].x); - transform_slider[7]->set_value(tform.get_basis()[Vector3::AXIS_Z].y); - transform_slider[8]->set_value(tform.get_basis()[Vector3::AXIS_Z].z); - - for (int i = 0; i < TRANSLATION_COMPONENTS; i++) { - transform_slider[BASIS_COMPONENTS + i]->set_value(tform.get_origin()[i]); - } + translation_property->update_using_vector(translation); + rotation_property->update_using_vector(rotation_degrees); + scale_property->update_using_vector(scale); + transform_property->update_using_transform(tform); update_enabled_checkbox(); updating = false; } BoneTransformEditor::BoneTransformEditor(Skeleton3D *p_skeleton) : - translation_slider(), - rotation_slider(), - scale_slider(), - transform_slider(), skeleton(p_skeleton), key_button(nullptr), enabled_checkbox(nullptr), @@ -397,7 +301,7 @@ void BoneTransformEditor::_key_button_pressed() { return; // Need to normalize the basis before you key it - Transform tform = compute_transform(true); + Transform tform = compute_transform_from_vector3s(); tform.orthonormalize(); AnimationPlayerEditor::singleton->get_track_editor()->insert_transform_key(skeleton, name, tform); } @@ -627,8 +531,7 @@ void Skeleton3DEditor::update_joint_tree() { items.insert(-1, root); const Vector<int> &joint_porder = skeleton->get_bone_process_orders(); - - Ref<Texture> bone_icon = get_theme_icon("Skeleton3D", "EditorIcons"); + Ref<Texture> bone_icon = get_theme_icon("BoneAttachment3D", "EditorIcons"); for (int i = 0; i < joint_porder.size(); ++i) { const int b_idx = joint_porder[i]; @@ -714,11 +617,11 @@ void Skeleton3DEditor::_notification(int p_what) { update_joint_tree(); update_editors(); - get_tree()->connect_compat("node_removed", this, "_node_removed", Vector<Variant>(), Object::CONNECT_ONESHOT); - joint_tree->connect_compat("item_selected", this, "_joint_tree_selection_changed"); - joint_tree->connect_compat("item_rmb_selected", this, "_joint_tree_rmb_select"); + get_tree()->connect("node_removed", callable_mp(this, &Skeleton3DEditor::_node_removed), Vector<Variant>(), Object::CONNECT_ONESHOT); + joint_tree->connect("item_selected", callable_mp(this, &Skeleton3DEditor::_joint_tree_selection_changed)); + joint_tree->connect("item_rmb_selected", callable_mp(this, &Skeleton3DEditor::_joint_tree_rmb_select)); #ifdef TOOLS_ENABLED - skeleton->connect_compat("pose_updated", this, "_update_properties"); + skeleton->connect("pose_updated", callable_mp(this, &Skeleton3DEditor::_update_properties)); #endif // TOOLS_ENABLED break; diff --git a/editor/plugins/skeleton_3d_editor_plugin.h b/editor/plugins/skeleton_3d_editor_plugin.h index 8b0639ed92..a5b8ce80a9 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.h +++ b/editor/plugins/skeleton_3d_editor_plugin.h @@ -41,30 +41,19 @@ class PhysicalBone3D; class Skeleton3DEditorPlugin; class Button; class CheckBox; +class EditorPropertyTransform; +class EditorPropertyVector3; class BoneTransformEditor : public VBoxContainer { GDCLASS(BoneTransformEditor, VBoxContainer); - static const int32_t TRANSLATION_COMPONENTS = 3; - static const int32_t ROTATION_DEGREES_COMPONENTS = 3; - static const int32_t SCALE_COMPONENTS = 3; - static const int32_t BASIS_COMPONENTS = 9; - static const int32_t BASIS_SPLIT_COMPONENTS = 3; - static const int32_t TRANSFORM_COMPONENTS = 12; - static const int32_t TRANSFORM_SPLIT_COMPONENTS = 3; - static const int32_t TRANSFORM_CONTROL_COMPONENTS = 3; - EditorInspectorSection *section; - GridContainer *translation_grid; - GridContainer *rotation_grid; - GridContainer *scale_grid; - GridContainer *transform_grid; - - EditorSpinSlider *translation_slider[TRANSLATION_COMPONENTS]; - EditorSpinSlider *rotation_slider[ROTATION_DEGREES_COMPONENTS]; - EditorSpinSlider *scale_slider[SCALE_COMPONENTS]; - EditorSpinSlider *transform_slider[TRANSFORM_COMPONENTS]; + EditorPropertyVector3 *translation_property; + EditorPropertyVector3 *rotation_property; + EditorPropertyVector3 *scale_property; + EditorInspectorSection *transform_section; + EditorPropertyTransform *transform_property; Rect2 background_rects[5]; @@ -83,17 +72,22 @@ class BoneTransformEditor : public VBoxContainer { String label; void create_editors(); - void setup_spinner(EditorSpinSlider *spinner, const bool is_transform_spinner); - void _value_changed(const double p_value, const bool p_from_transform); - - Transform compute_transform(const bool p_from_transform) const; + // Called when one of the EditorSpinSliders are changed. + void _value_changed(const double p_value); + // Called when the one of the EditorPropertyVector3 are updated. + void _value_changed_vector3(const String p_property_name, const Vector3 p_vector, const StringName p_edited_property_name, const bool p_boolean); + // Called when the transform_property is updated. + void _value_changed_transform(const String p_property_name, const Transform p_transform, const StringName p_edited_property_name, const bool p_boolean); + // Changes the transform to the given transform and updates the UI accordingly. + void _change_transform(Transform p_new_transform); + // Creates a Transform using the EditorPropertyVector3 properties. + Transform compute_transform_from_vector3s() const; void update_enabled_checkbox(); protected: void _notification(int p_what); - static void _bind_methods(); public: BoneTransformEditor(Skeleton3D *p_skeleton); |