summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/editor_help.cpp63
-rw-r--r--editor/editor_properties.cpp53
-rw-r--r--editor/editor_properties.h3
-rw-r--r--editor/filesystem_dock.cpp27
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp37
-rw-r--r--editor/plugins/skeleton_3d_editor_plugin.cpp287
-rw-r--r--editor/plugins/skeleton_3d_editor_plugin.h40
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);