diff options
Diffstat (limited to 'editor')
-rw-r--r-- | editor/editor_properties.cpp | 264 | ||||
-rw-r--r-- | editor/editor_properties.h | 34 | ||||
-rw-r--r-- | editor/editor_toaster.cpp | 14 | ||||
-rw-r--r-- | editor/icons/Unlinked.svg | 1 | ||||
-rw-r--r-- | editor/plugins/canvas_item_editor_plugin.cpp | 2 | ||||
-rw-r--r-- | editor/plugins/tiles/tile_map_editor.cpp | 134 | ||||
-rw-r--r-- | editor/plugins/tiles/tile_map_editor.h | 10 |
7 files changed, 313 insertions, 146 deletions
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index ddf1974070..a5c02c70d9 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -1597,6 +1597,18 @@ void EditorPropertyVector2::_value_changed(double val, const String &p_name) { return; } + if (linked->is_pressed()) { + setting = true; + if (p_name == "x") { + spin[1]->set_value(spin[0]->get_value() * ratio_yx); + } + + if (p_name == "y") { + spin[0]->set_value(spin[1]->get_value() * ratio_xy); + } + setting = false; + } + Vector2 v2; v2.x = spin[0]->get_value(); v2.y = spin[1]->get_value(); @@ -1609,12 +1621,28 @@ void EditorPropertyVector2::update_property() { spin[0]->set_value(val.x); spin[1]->set_value(val.y); setting = false; + _update_ratio(); +} + +void EditorPropertyVector2::_update_ratio() { + linked->set_modulate(Color(1, 1, 1, linked->is_pressed() ? 1.0 : 0.5)); + + if (spin[0]->get_value() != 0 && spin[1]->get_value() != 0) { + ratio_xy = spin[0]->get_value() / spin[1]->get_value(); + ratio_yx = spin[1]->get_value() / spin[0]->get_value(); + } else { + ratio_xy = 1.0; + ratio_yx = 1.0; + } } void EditorPropertyVector2::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { + linked->set_normal_texture(get_theme_icon(SNAME("Unlinked"), SNAME("EditorIcons"))); + linked->set_pressed_texture(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons"))); + const Color *colors = _get_property_colors(); for (int i = 0; i < 2; i++) { spin[i]->add_theme_color_override("label_color", colors[i]); @@ -1623,10 +1651,7 @@ void EditorPropertyVector2::_notification(int p_what) { } } -void EditorPropertyVector2::_bind_methods() { -} - -void EditorPropertyVector2::setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix) { +void EditorPropertyVector2::setup(double p_min, double p_max, double p_step, bool p_no_slider, bool p_link, const String &p_suffix) { for (int i = 0; i < 2; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); @@ -1636,24 +1661,34 @@ void EditorPropertyVector2::setup(double p_min, double p_max, double p_step, boo spin[i]->set_allow_lesser(true); spin[i]->set_suffix(p_suffix); } + + if (!p_link) { + linked->hide(); + } else { + linked->set_pressed(true); + } } EditorPropertyVector2::EditorPropertyVector2(bool p_force_wide) { bool horizontal = p_force_wide || bool(EDITOR_GET("interface/inspector/horizontal_vector2_editing")); + HBoxContainer *hb = memnew(HBoxContainer); + hb->set_h_size_flags(SIZE_EXPAND_FILL); + BoxContainer *bc; if (p_force_wide) { bc = memnew(HBoxContainer); - add_child(bc); + hb->add_child(bc); } else if (horizontal) { bc = memnew(HBoxContainer); - add_child(bc); - set_bottom_editor(bc); + hb->add_child(bc); + set_bottom_editor(hb); } else { bc = memnew(VBoxContainer); - add_child(bc); + hb->add_child(bc); } + bc->set_h_size_flags(SIZE_EXPAND_FILL); static const char *desc[2] = { "x", "y" }; for (int i = 0; i < 2; i++) { @@ -1668,6 +1703,13 @@ EditorPropertyVector2::EditorPropertyVector2(bool p_force_wide) { } } + linked = memnew(TextureButton); + linked->set_toggle_mode(true); + linked->set_stretch_mode(TextureButton::STRETCH_KEEP_CENTERED); + linked->connect(SNAME("pressed"), callable_mp(this, &EditorPropertyVector2::_update_ratio)); + hb->add_child(linked); + + add_child(hb); if (!horizontal) { set_label_reference(spin[0]); //show text and buttons around this } @@ -1789,6 +1831,25 @@ void EditorPropertyVector3::_value_changed(double val, const String &p_name) { return; } + if (linked->is_pressed()) { + setting = true; + if (p_name == "x") { + spin[1]->set_value(spin[0]->get_value() * ratio_yx); + spin[2]->set_value(spin[0]->get_value() * ratio_zx); + } + + if (p_name == "y") { + spin[0]->set_value(spin[1]->get_value() * ratio_xy); + spin[2]->set_value(spin[1]->get_value() * ratio_zy); + } + + if (p_name == "z") { + spin[0]->set_value(spin[2]->get_value() * ratio_xz); + spin[1]->set_value(spin[2]->get_value() * ratio_yz); + } + setting = false; + } + Vector3 v3; v3.x = spin[0]->get_value(); v3.y = spin[1]->get_value(); @@ -1803,6 +1864,27 @@ void EditorPropertyVector3::_value_changed(double val, const String &p_name) { void EditorPropertyVector3::update_property() { update_using_vector(get_edited_object()->get(get_edited_property())); + _update_ratio(); +} + +void EditorPropertyVector3::_update_ratio() { + linked->set_modulate(Color(1, 1, 1, linked->is_pressed() ? 1.0 : 0.5)); + + if (spin[0]->get_value() != 0 && spin[1]->get_value() != 0) { + ratio_yx = spin[1]->get_value() / spin[0]->get_value(); + ratio_zx = spin[2]->get_value() / spin[0]->get_value(); + ratio_xy = spin[0]->get_value() / spin[1]->get_value(); + ratio_zy = spin[2]->get_value() / spin[1]->get_value(); + ratio_xz = spin[0]->get_value() / spin[2]->get_value(); + ratio_yz = spin[1]->get_value() / spin[2]->get_value(); + } else { + ratio_yx = 1.0; + ratio_zx = 1.0; + ratio_xy = 1.0; + ratio_zy = 1.0; + ratio_xz = 1.0; + ratio_yz = 1.0; + } } void EditorPropertyVector3::update_using_vector(Vector3 p_vector) { @@ -1836,6 +1918,9 @@ void EditorPropertyVector3::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { + linked->set_normal_texture(get_theme_icon(SNAME("Unlinked"), SNAME("EditorIcons"))); + linked->set_pressed_texture(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons"))); + const Color *colors = _get_property_colors(); for (int i = 0; i < 3; i++) { spin[i]->add_theme_color_override("label_color", colors[i]); @@ -1847,7 +1932,7 @@ void EditorPropertyVector3::_notification(int p_what) { void EditorPropertyVector3::_bind_methods() { } -void EditorPropertyVector3::setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix, bool p_angle_in_radians) { +void EditorPropertyVector3::setup(double p_min, double p_max, double p_step, bool p_no_slider, bool p_link, const String &p_suffix, bool p_angle_in_radians) { angle_in_radians = p_angle_in_radians; for (int i = 0; i < 3; i++) { spin[i]->set_min(p_min); @@ -1858,24 +1943,34 @@ void EditorPropertyVector3::setup(double p_min, double p_max, double p_step, boo spin[i]->set_allow_lesser(true); spin[i]->set_suffix(p_suffix); } + + if (!p_link) { + linked->hide(); + } else { + linked->set_pressed(true); + } } EditorPropertyVector3::EditorPropertyVector3(bool p_force_wide) { bool horizontal = p_force_wide || bool(EDITOR_GET("interface/inspector/horizontal_vector_types_editing")); + HBoxContainer *hb = memnew(HBoxContainer); + hb->set_h_size_flags(SIZE_EXPAND_FILL); + BoxContainer *bc; if (p_force_wide) { bc = memnew(HBoxContainer); - add_child(bc); + hb->add_child(bc); } else if (horizontal) { bc = memnew(HBoxContainer); - add_child(bc); - set_bottom_editor(bc); + hb->add_child(bc); + set_bottom_editor(hb); } else { bc = memnew(VBoxContainer); - add_child(bc); + hb->add_child(bc); } + bc->set_h_size_flags(SIZE_EXPAND_FILL); static const char *desc[3] = { "x", "y", "z" }; for (int i = 0; i < 3; i++) { @@ -1890,6 +1985,13 @@ EditorPropertyVector3::EditorPropertyVector3(bool p_force_wide) { } } + linked = memnew(TextureButton); + linked->set_toggle_mode(true); + linked->set_stretch_mode(TextureButton::STRETCH_KEEP_CENTERED); + linked->connect(SNAME("pressed"), callable_mp(this, &EditorPropertyVector3::_update_ratio)); + hb->add_child(linked); + + add_child(hb); if (!horizontal) { set_label_reference(spin[0]); //show text and buttons around this } @@ -1908,6 +2010,18 @@ void EditorPropertyVector2i::_value_changed(double val, const String &p_name) { return; } + if (linked->is_pressed()) { + setting = true; + if (p_name == "x") { + spin[1]->set_value(spin[0]->get_value() * ratio_yx); + } + + if (p_name == "y") { + spin[0]->set_value(spin[1]->get_value() * ratio_xy); + } + setting = false; + } + Vector2i v2; v2.x = spin[0]->get_value(); v2.y = spin[1]->get_value(); @@ -1920,12 +2034,28 @@ void EditorPropertyVector2i::update_property() { spin[0]->set_value(val.x); spin[1]->set_value(val.y); setting = false; + _update_ratio(); +} + +void EditorPropertyVector2i::_update_ratio() { + linked->set_modulate(Color(1, 1, 1, linked->is_pressed() ? 1.0 : 0.5)); + + if (spin[0]->get_value() != 0 && spin[1]->get_value() != 0) { + ratio_xy = spin[0]->get_value() / spin[1]->get_value(); + ratio_yx = spin[1]->get_value() / spin[0]->get_value(); + } else { + ratio_xy = 1.0; + ratio_yx = 1.0; + } } void EditorPropertyVector2i::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { + linked->set_normal_texture(get_theme_icon(SNAME("Unlinked"), SNAME("EditorIcons"))); + linked->set_pressed_texture(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons"))); + const Color *colors = _get_property_colors(); for (int i = 0; i < 2; i++) { spin[i]->add_theme_color_override("label_color", colors[i]); @@ -1934,10 +2064,7 @@ void EditorPropertyVector2i::_notification(int p_what) { } } -void EditorPropertyVector2i::_bind_methods() { -} - -void EditorPropertyVector2i::setup(int p_min, int p_max, bool p_no_slider, const String &p_suffix) { +void EditorPropertyVector2i::setup(int p_min, int p_max, bool p_no_slider, bool p_link, const String &p_suffix) { for (int i = 0; i < 2; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); @@ -1947,24 +2074,34 @@ void EditorPropertyVector2i::setup(int p_min, int p_max, bool p_no_slider, const spin[i]->set_allow_lesser(true); spin[i]->set_suffix(p_suffix); } + + if (!p_link) { + linked->hide(); + } else { + linked->set_pressed(true); + } } EditorPropertyVector2i::EditorPropertyVector2i(bool p_force_wide) { bool horizontal = p_force_wide || bool(EDITOR_GET("interface/inspector/horizontal_vector2_editing")); + HBoxContainer *hb = memnew(HBoxContainer); + hb->set_h_size_flags(SIZE_EXPAND_FILL); + BoxContainer *bc; if (p_force_wide) { bc = memnew(HBoxContainer); - add_child(bc); + hb->add_child(bc); } else if (horizontal) { bc = memnew(HBoxContainer); - add_child(bc); - set_bottom_editor(bc); + hb->add_child(bc); + set_bottom_editor(hb); } else { bc = memnew(VBoxContainer); - add_child(bc); + hb->add_child(bc); } + bc->set_h_size_flags(SIZE_EXPAND_FILL); static const char *desc[2] = { "x", "y" }; for (int i = 0; i < 2; i++) { @@ -1979,6 +2116,13 @@ EditorPropertyVector2i::EditorPropertyVector2i(bool p_force_wide) { } } + linked = memnew(TextureButton); + linked->set_toggle_mode(true); + linked->set_stretch_mode(TextureButton::STRETCH_KEEP_CENTERED); + linked->connect(SNAME("pressed"), callable_mp(this, &EditorPropertyVector2i::_update_ratio)); + hb->add_child(linked); + + add_child(hb); if (!horizontal) { set_label_reference(spin[0]); //show text and buttons around this } @@ -2100,6 +2244,25 @@ void EditorPropertyVector3i::_value_changed(double val, const String &p_name) { return; } + if (linked->is_pressed()) { + setting = true; + if (p_name == "x") { + spin[1]->set_value(spin[0]->get_value() * ratio_yx); + spin[2]->set_value(spin[0]->get_value() * ratio_zx); + } + + if (p_name == "y") { + spin[0]->set_value(spin[1]->get_value() * ratio_xy); + spin[2]->set_value(spin[1]->get_value() * ratio_zy); + } + + if (p_name == "z") { + spin[0]->set_value(spin[2]->get_value() * ratio_xz); + spin[1]->set_value(spin[2]->get_value() * ratio_yz); + } + setting = false; + } + Vector3i v3; v3.x = spin[0]->get_value(); v3.y = spin[1]->get_value(); @@ -2114,12 +2277,36 @@ void EditorPropertyVector3i::update_property() { spin[1]->set_value(val.y); spin[2]->set_value(val.z); setting = false; + _update_ratio(); +} + +void EditorPropertyVector3i::_update_ratio() { + linked->set_modulate(Color(1, 1, 1, linked->is_pressed() ? 1.0 : 0.5)); + + if (spin[0]->get_value() != 0 && spin[1]->get_value() != 0) { + ratio_yx = spin[1]->get_value() / spin[0]->get_value(); + ratio_zx = spin[2]->get_value() / spin[0]->get_value(); + ratio_xy = spin[0]->get_value() / spin[1]->get_value(); + ratio_zy = spin[2]->get_value() / spin[1]->get_value(); + ratio_xz = spin[0]->get_value() / spin[2]->get_value(); + ratio_yz = spin[1]->get_value() / spin[2]->get_value(); + } else { + ratio_yx = 1.0; + ratio_zx = 1.0; + ratio_xy = 1.0; + ratio_zy = 1.0; + ratio_xz = 1.0; + ratio_yz = 1.0; + } } void EditorPropertyVector3i::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { + linked->set_normal_texture(get_theme_icon(SNAME("Unlinked"), SNAME("EditorIcons"))); + linked->set_pressed_texture(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons"))); + const Color *colors = _get_property_colors(); for (int i = 0; i < 3; i++) { spin[i]->add_theme_color_override("label_color", colors[i]); @@ -2131,7 +2318,7 @@ void EditorPropertyVector3i::_notification(int p_what) { void EditorPropertyVector3i::_bind_methods() { } -void EditorPropertyVector3i::setup(int p_min, int p_max, bool p_no_slider, const String &p_suffix) { +void EditorPropertyVector3i::setup(int p_min, int p_max, bool p_no_slider, bool p_link, const String &p_suffix) { for (int i = 0; i < 3; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); @@ -2141,22 +2328,31 @@ void EditorPropertyVector3i::setup(int p_min, int p_max, bool p_no_slider, const spin[i]->set_allow_lesser(true); spin[i]->set_suffix(p_suffix); } + + if (!p_link) { + linked->hide(); + } else { + linked->set_pressed(true); + } } EditorPropertyVector3i::EditorPropertyVector3i(bool p_force_wide) { bool horizontal = p_force_wide || bool(EDITOR_GET("interface/inspector/horizontal_vector_types_editing")); + HBoxContainer *hb = memnew(HBoxContainer); + hb->set_h_size_flags(SIZE_EXPAND_FILL); + BoxContainer *bc; if (p_force_wide) { bc = memnew(HBoxContainer); - add_child(bc); + hb->add_child(bc); } else if (horizontal) { bc = memnew(HBoxContainer); - add_child(bc); - set_bottom_editor(bc); + hb->add_child(bc); + set_bottom_editor(hb); } else { bc = memnew(VBoxContainer); - add_child(bc); + hb->add_child(bc); } static const char *desc[3] = { "x", "y", "z" }; @@ -2171,7 +2367,15 @@ EditorPropertyVector3i::EditorPropertyVector3i(bool p_force_wide) { spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); } } + bc->set_h_size_flags(SIZE_EXPAND_FILL); + + linked = memnew(TextureButton); + linked->set_toggle_mode(true); + linked->set_stretch_mode(TextureButton::STRETCH_KEEP_CENTERED); + linked->connect(SNAME("pressed"), callable_mp(this, &EditorPropertyVector3i::_update_ratio)); + hb->add_child(linked); + add_child(hb); if (!horizontal) { set_label_reference(spin[0]); //show text and buttons around this } @@ -3608,14 +3812,14 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_ EditorPropertyVector2 *editor = memnew(EditorPropertyVector2(p_wide)); EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, default_float_step); - editor->setup(hint.min, hint.max, hint.step, hint.hide_slider, hint.suffix); + editor->setup(hint.min, hint.max, hint.step, hint.hide_slider, p_hint == PROPERTY_HINT_LINK, hint.suffix); return editor; } break; case Variant::VECTOR2I: { EditorPropertyVector2i *editor = memnew(EditorPropertyVector2i(p_wide)); EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, 1); - editor->setup(hint.min, hint.max, hint.hide_slider, hint.suffix); + editor->setup(hint.min, hint.max, hint.hide_slider, p_hint == PROPERTY_HINT_LINK, hint.suffix); return editor; } break; @@ -3635,14 +3839,14 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_ case Variant::VECTOR3: { EditorPropertyVector3 *editor = memnew(EditorPropertyVector3(p_wide)); EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, default_float_step); - editor->setup(hint.min, hint.max, hint.step, hint.hide_slider, hint.suffix, hint.radians); + editor->setup(hint.min, hint.max, hint.step, hint.hide_slider, p_hint == PROPERTY_HINT_LINK, hint.suffix, hint.radians); return editor; } break; case Variant::VECTOR3I: { EditorPropertyVector3i *editor = memnew(EditorPropertyVector3i(p_wide)); EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, 1); - editor->setup(hint.min, hint.max, hint.hide_slider, hint.suffix); + editor->setup(hint.min, hint.max, hint.hide_slider, p_hint == PROPERTY_HINT_LINK, hint.suffix); return editor; } break; diff --git a/editor/editor_properties.h b/editor/editor_properties.h index 6513eb0390..a3b98b7724 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -451,16 +451,19 @@ class EditorPropertyVector2 : public EditorProperty { GDCLASS(EditorPropertyVector2, EditorProperty); EditorSpinSlider *spin[2]; bool setting = false; + double ratio_xy = 1.0; + double ratio_yx = 1.0; + TextureButton *linked = nullptr; + void _update_ratio(); void _value_changed(double p_val, const String &p_name); protected: virtual void _set_read_only(bool p_read_only) override; void _notification(int p_what); - static void _bind_methods(); public: virtual void update_property() override; - void setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix = String()); + void setup(double p_min, double p_max, double p_step, bool p_no_slider, bool p_link = false, const String &p_suffix = String()); EditorPropertyVector2(bool p_force_wide = false); }; @@ -486,6 +489,14 @@ class EditorPropertyVector3 : public EditorProperty { EditorSpinSlider *spin[3]; bool setting = false; bool angle_in_radians = false; + double ratio_yx = 1.0; + double ratio_zx = 1.0; + double ratio_xy = 1.0; + double ratio_zy = 1.0; + double ratio_xz = 1.0; + double ratio_yz = 1.0; + TextureButton *linked = nullptr; + void _update_ratio(); void _value_changed(double p_val, const String &p_name); protected: @@ -497,7 +508,7 @@ public: virtual void update_property() override; 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, const String &p_suffix = String(), bool p_angle_in_radians = false); + void setup(double p_min, double p_max, double p_step, bool p_no_slider, bool p_link = false, const String &p_suffix = String(), bool p_angle_in_radians = false); EditorPropertyVector3(bool p_force_wide = false); }; @@ -505,16 +516,19 @@ class EditorPropertyVector2i : public EditorProperty { GDCLASS(EditorPropertyVector2i, EditorProperty); EditorSpinSlider *spin[2]; bool setting = false; + double ratio_xy = 1.0; + double ratio_yx = 1.0; + TextureButton *linked = nullptr; + void _update_ratio(); void _value_changed(double p_val, const String &p_name); protected: virtual void _set_read_only(bool p_read_only) override; void _notification(int p_what); - static void _bind_methods(); public: virtual void update_property() override; - void setup(int p_min, int p_max, bool p_no_slider, const String &p_suffix = String()); + void setup(int p_min, int p_max, bool p_no_slider, bool p_link = false, const String &p_suffix = String()); EditorPropertyVector2i(bool p_force_wide = false); }; @@ -539,6 +553,14 @@ class EditorPropertyVector3i : public EditorProperty { GDCLASS(EditorPropertyVector3i, EditorProperty); EditorSpinSlider *spin[3]; bool setting = false; + double ratio_yx = 1.0; + double ratio_zx = 1.0; + double ratio_xy = 1.0; + double ratio_zy = 1.0; + double ratio_xz = 1.0; + double ratio_yz = 1.0; + TextureButton *linked = nullptr; + void _update_ratio(); void _value_changed(double p_val, const String &p_name); protected: @@ -548,7 +570,7 @@ protected: public: virtual void update_property() override; - void setup(int p_min, int p_max, bool p_no_slider, const String &p_suffix = String()); + void setup(int p_min, int p_max, bool p_no_slider, bool p_link = false, const String &p_suffix = String()); EditorPropertyVector3i(bool p_force_wide = false); }; diff --git a/editor/editor_toaster.cpp b/editor/editor_toaster.cpp index 7ca88bd2a2..4986bccc35 100644 --- a/editor/editor_toaster.cpp +++ b/editor/editor_toaster.cpp @@ -234,6 +234,16 @@ void EditorToaster::_auto_hide_or_free_toasts() { to_delete[i]->queue_delete(); toasts.erase(to_delete[i]); } + + if (toasts.is_empty()) { + main_button->set_tooltip(TTR("No notifications.")); + main_button->set_modulate(Color(0.5, 0.5, 0.5)); + main_button->set_disabled(true); + } else { + main_button->set_tooltip(TTR("Show notifications.")); + main_button->set_modulate(Color(1, 1, 1)); + main_button->set_disabled(false); + } } void EditorToaster::_draw_button() { @@ -508,6 +518,9 @@ EditorToaster::EditorToaster() { // Main button. main_button = memnew(Button); + main_button->set_tooltip(TTR("No notifications.")); + main_button->set_modulate(Color(0.5, 0.5, 0.5)); + main_button->set_disabled(true); main_button->set_flat(true); main_button->connect("pressed", callable_mp(this, &EditorToaster::_set_notifications_enabled), varray(true)); main_button->connect("pressed", callable_mp(this, &EditorToaster::_repop_old)); @@ -521,6 +534,7 @@ EditorToaster::EditorToaster() { add_child(disable_notifications_panel); disable_notifications_button = memnew(Button); + disable_notifications_button->set_tooltip(TTR("Silence the notifications.")); disable_notifications_button->set_flat(true); disable_notifications_button->connect("pressed", callable_mp(this, &EditorToaster::_set_notifications_enabled), varray(false)); disable_notifications_panel->add_child(disable_notifications_button); diff --git a/editor/icons/Unlinked.svg b/editor/icons/Unlinked.svg new file mode 100644 index 0000000000..6c831eacad --- /dev/null +++ b/editor/icons/Unlinked.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><defs><clipPath id="a"><path d="M0 0h16v16H0z"/></clipPath></defs><g clip-path="url(#a)" fill="#e0e0e0"><path d="M1.136 12.036a3.994 3.994 0 0 1-.137-1.047 4.007 4.007 0 0 1 2.965-3.853 1 1 0 0 1 1.225.707 1 1 0 0 1 .034.25 1 1 0 0 1-.741.975 2 2 0 0 0-1.483 1.926 1.994 1.994 0 0 0 .068.523 2 2 0 0 0 2.45 1.415 2 2 0 0 0 1.484-1.931 2 2 0 0 0-.068-.523 1 1 0 0 1-.034-.25 1 1 0 0 1 .742-.975 1 1 0 0 1 1.225.707 3.991 3.991 0 0 1 .137 1.046 4.007 4.007 0 0 1-2.965 3.852 3.993 3.993 0 0 1-1.035.137 4.006 4.006 0 0 1-3.867-2.959zM9.965 8.863a1 1 0 0 1-.742-.975 1 1 0 0 1 .034-.25 1 1 0 0 1 1.225-.706 2 2 0 0 0 2.449-1.415A1.994 1.994 0 0 0 13 4.994a2 2 0 0 0-1.483-1.926 2 2 0 0 0-2.45 1.414 1 1 0 0 1-1.224.707 1 1 0 0 1-.742-.975 1 1 0 0 1 .034-.25 4 4 0 0 1 4.9-2.829A4.008 4.008 0 0 1 15 4.988a3.993 3.993 0 0 1-.137 1.047 4.006 4.006 0 0 1-3.862 2.966 3.989 3.989 0 0 1-1.036-.138zM5.5 4a.5.5 0 0 1-.5-.5v-2a.5.5 0 0 1 .5-.5.5.5 0 0 1 .5.5v2a.5.5 0 0 1-.5.5zM4.5 5a.5.5 0 0 1-.354-.146l-2-2a.5.5 0 0 1 0-.707.5.5 0 0 1 .707 0l2 2A.5.5 0 0 1 4.5 5zM3.5 6h-2a.5.5 0 0 1-.5-.5.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 .5.5.5.5 0 0 1-.5.5z"/></g></svg> diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 83b0d74dd2..1ea0299d4e 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -1289,7 +1289,7 @@ void CanvasItemEditor::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin, bo zoom_widget->set_zoom_by_increments(-scroll_sign, p_alt); if (!Math::is_equal_approx(ABS(p_scroll_vec.y), (real_t)1.0)) { // Handle high-precision (analog) scrolling. - zoom_widget->set_zoom(zoom * ((zoom_widget->get_zoom() / zoom - 1.f) * p_scroll_vec.y + 1.f)); + zoom_widget->set_zoom(zoom * ((zoom_widget->get_zoom() / zoom - 1.f) * ABS(p_scroll_vec.y) + 1.f)); } _zoom_on_position(zoom_widget->get_zoom(), p_origin); } diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp index 535ed3b700..d2f3eab31c 100644 --- a/editor/plugins/tiles/tile_map_editor.cpp +++ b/editor/plugins/tiles/tile_map_editor.cpp @@ -2028,7 +2028,6 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() { // --- Toolbar --- toolbar = memnew(HBoxContainer); - toolbar->set_h_size_flags(Control::SIZE_EXPAND_FILL); HBoxContainer *tilemap_tiles_tools_buttons = memnew(HBoxContainer); @@ -3423,7 +3422,7 @@ void TileMapEditor::_notification(int p_what) { advanced_menu_button->set_icon(get_theme_icon(SNAME("Tools"), SNAME("EditorIcons"))); toggle_grid_button->set_icon(get_theme_icon(SNAME("Grid"), SNAME("EditorIcons"))); toggle_grid_button->set_pressed(EditorSettings::get_singleton()->get("editors/tiles_editor/display_grid")); - toogle_highlight_selected_layer_button->set_icon(get_theme_icon(SNAME("TileMapHighlightSelected"), SNAME("EditorIcons"))); + toggle_highlight_selected_layer_button->set_icon(get_theme_icon(SNAME("TileMapHighlightSelected"), SNAME("EditorIcons"))); } break; case NOTIFICATION_INTERNAL_PROCESS: { @@ -3458,64 +3457,13 @@ void TileMapEditor::_on_grid_toggled(bool p_pressed) { CanvasItemEditor::get_singleton()->update_viewport(); } -void TileMapEditor::_layers_selection_button_draw() { - if (!has_theme_icon(SNAME("arrow"), SNAME("OptionButton"))) { +void TileMapEditor::_layers_selection_item_selected(int p_index) { + TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id)); + if (!tile_map || tile_map->get_layers_count() <= 0) { return; } - RID ci = layers_selection_button->get_canvas_item(); - Ref<Texture2D> arrow = Control::get_theme_icon(SNAME("arrow"), SNAME("OptionButton")); - - Color clr = Color(1, 1, 1); - if (get_theme_constant(SNAME("modulate_arrow"))) { - switch (layers_selection_button->get_draw_mode()) { - case BaseButton::DRAW_PRESSED: - clr = get_theme_color(SNAME("font_pressed_color")); - break; - case BaseButton::DRAW_HOVER: - clr = get_theme_color(SNAME("font_hover_color")); - break; - case BaseButton::DRAW_DISABLED: - clr = get_theme_color(SNAME("font_disabled_color")); - break; - default: - if (layers_selection_button->has_focus()) { - clr = get_theme_color(SNAME("font_focus_color")); - } else { - clr = get_theme_color(SNAME("font_color")); - } - } - } - - Size2 size = layers_selection_button->get_size(); - - Point2 ofs; - if (is_layout_rtl()) { - ofs = Point2(get_theme_constant(SNAME("arrow_margin"), SNAME("OptionButton")), int(Math::abs((size.height - arrow->get_height()) / 2))); - } else { - ofs = Point2(size.width - arrow->get_width() - get_theme_constant(SNAME("arrow_margin"), SNAME("OptionButton")), int(Math::abs((size.height - arrow->get_height()) / 2))); - } - Rect2 dst_rect = Rect2(ofs, arrow->get_size()); - if (!layers_selection_button->is_pressed()) { - dst_rect.size = -dst_rect.size; - } - arrow->draw_rect(ci, dst_rect, false, clr); -} - -void TileMapEditor::_layers_selection_button_pressed() { - if (!layers_selection_popup->is_visible()) { - Size2 size = layers_selection_popup->get_contents_minimum_size(); - size.x = MAX(size.x, layers_selection_button->get_size().x); - layers_selection_popup->set_position(layers_selection_button->get_screen_position() - Size2(0, size.y * get_global_transform().get_scale().y)); - layers_selection_popup->set_size(size); - layers_selection_popup->popup(); - } else { - layers_selection_popup->hide(); - } -} - -void TileMapEditor::_layers_selection_id_pressed(int p_id) { - tile_map_layer = p_id; + tile_map_layer = p_index; _update_layers_selection(); } @@ -3698,8 +3646,6 @@ void TileMapEditor::_layers_select_next_or_previous(bool p_next) { } void TileMapEditor::_update_layers_selection() { - layers_selection_popup->clear(); - TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id)); if (!tile_map) { return; @@ -3726,32 +3672,23 @@ void TileMapEditor::_update_layers_selection() { } else { tile_map_layer = -1; } - tile_map->set_selected_layer(toogle_highlight_selected_layer_button->is_pressed() ? tile_map_layer : -1); + tile_map->set_selected_layer(toggle_highlight_selected_layer_button->is_pressed() ? tile_map_layer : -1); - // Build the list of layers. - for (int i = 0; i < tile_map->get_layers_count(); i++) { - String name = tile_map->get_layer_name(i); - layers_selection_popup->add_item(name.is_empty() ? vformat(TTR("Layer #%d"), i) : name, i); - layers_selection_popup->set_item_as_radio_checkable(i, true); - layers_selection_popup->set_item_disabled(i, !tile_map->is_layer_enabled(i)); - layers_selection_popup->set_item_checked(i, i == tile_map_layer); - } + layers_selection_button->clear(); + if (tile_map->get_layers_count() > 0) { + // Build the list of layers. + for (int i = 0; i < tile_map->get_layers_count(); i++) { + String name = tile_map->get_layer_name(i); + layers_selection_button->add_item(name.is_empty() ? vformat(TTR("Layer %d"), i) : name, i); + layers_selection_button->set_item_disabled(i, !tile_map->is_layer_enabled(i)); + } - // Update the button label. - if (tile_map_layer >= 0) { - layers_selection_button->set_text(layers_selection_popup->get_item_text(tile_map_layer)); + layers_selection_button->set_disabled(false); + layers_selection_button->select(tile_map_layer); } else { - layers_selection_button->set_text(TTR("Select a layer")); - } - - // Set button minimum width. - Size2 min_button_size = Size2(layers_selection_popup->get_contents_minimum_size().x, 0); - if (has_theme_icon(SNAME("arrow"), SNAME("OptionButton"))) { - Ref<Texture2D> arrow = Control::get_theme_icon(SNAME("arrow"), SNAME("OptionButton")); - min_button_size.x += arrow->get_size().x; + layers_selection_button->set_disabled(true); + layers_selection_button->set_text(TTR("No Layers")); } - layers_selection_button->set_custom_minimum_size(min_button_size); - layers_selection_button->update(); tabs_plugins[tabs_bar->get_current_tab()]->edit(tile_map_id, tile_map_layer); } @@ -4028,7 +3965,6 @@ TileMapEditor::TileMapEditor() { // TabBar. tabs_bar = memnew(TabBar); - tabs_bar->set_tab_alignment(TabBar::ALIGNMENT_CENTER); tabs_bar->set_clip_tabs(false); for (int plugin_index = 0; plugin_index < tile_map_editor_plugins.size(); plugin_index++) { Vector<TileMapEditorPlugin::TabData> tabs_vector = tile_map_editor_plugins[plugin_index]->get_tabs(); @@ -4057,31 +3993,23 @@ TileMapEditor::TileMapEditor() { } // Wide empty separation control. - Control *h_empty_space = memnew(Control); - h_empty_space->set_h_size_flags(SIZE_EXPAND_FILL); - tile_map_toolbar->add_child(h_empty_space); + tile_map_toolbar->add_spacer(); // Layer selector. - layers_selection_popup = memnew(PopupMenu); - layers_selection_popup->connect("id_pressed", callable_mp(this, &TileMapEditor::_layers_selection_id_pressed)); - layers_selection_popup->set_flag(Window::FLAG_POPUP, false); - - layers_selection_button = memnew(Button); - layers_selection_button->set_toggle_mode(true); - layers_selection_button->connect("draw", callable_mp(this, &TileMapEditor::_layers_selection_button_draw)); - layers_selection_button->connect("pressed", callable_mp(this, &TileMapEditor::_layers_selection_button_pressed)); - layers_selection_button->connect("hidden", callable_mp((Window *)layers_selection_popup, &Popup::hide)); - layers_selection_button->set_tooltip(TTR("Tile Map Layer")); - layers_selection_button->add_child(layers_selection_popup); + layers_selection_button = memnew(OptionButton); + layers_selection_button->set_custom_minimum_size(Size2(200, 0)); + layers_selection_button->set_text_overrun_behavior(TextParagraph::OVERRUN_TRIM_ELLIPSIS); + layers_selection_button->set_tooltip(TTR("TileMap Layers")); + layers_selection_button->connect("item_selected", callable_mp(this, &TileMapEditor::_layers_selection_item_selected)); tile_map_toolbar->add_child(layers_selection_button); - toogle_highlight_selected_layer_button = memnew(Button); - toogle_highlight_selected_layer_button->set_flat(true); - toogle_highlight_selected_layer_button->set_toggle_mode(true); - toogle_highlight_selected_layer_button->set_pressed(true); - toogle_highlight_selected_layer_button->connect("pressed", callable_mp(this, &TileMapEditor::_update_layers_selection)); - toogle_highlight_selected_layer_button->set_tooltip(TTR("Highlight Selected TileMap Layer")); - tile_map_toolbar->add_child(toogle_highlight_selected_layer_button); + toggle_highlight_selected_layer_button = memnew(Button); + toggle_highlight_selected_layer_button->set_flat(true); + toggle_highlight_selected_layer_button->set_toggle_mode(true); + toggle_highlight_selected_layer_button->set_pressed(true); + toggle_highlight_selected_layer_button->connect("pressed", callable_mp(this, &TileMapEditor::_update_layers_selection)); + toggle_highlight_selected_layer_button->set_tooltip(TTR("Highlight Selected TileMap Layer")); + tile_map_toolbar->add_child(toggle_highlight_selected_layer_button); tile_map_toolbar->add_child(memnew(VSeparator)); diff --git a/editor/plugins/tiles/tile_map_editor.h b/editor/plugins/tiles/tile_map_editor.h index 4612bd5fa8..ff586ebbfe 100644 --- a/editor/plugins/tiles/tile_map_editor.h +++ b/editor/plugins/tiles/tile_map_editor.h @@ -40,6 +40,7 @@ #include "scene/gui/check_box.h" #include "scene/gui/item_list.h" #include "scene/gui/menu_button.h" +#include "scene/gui/option_button.h" #include "scene/gui/separator.h" #include "scene/gui/spin_box.h" #include "scene/gui/split_container.h" @@ -327,12 +328,9 @@ private: // Toolbar. HBoxContainer *tile_map_toolbar = nullptr; - PopupMenu *layers_selection_popup = nullptr; - Button *layers_selection_button = nullptr; - Button *toogle_highlight_selected_layer_button = nullptr; - void _layers_selection_button_draw(); - void _layers_selection_button_pressed(); - void _layers_selection_id_pressed(int p_id); + OptionButton *layers_selection_button = nullptr; + Button *toggle_highlight_selected_layer_button = nullptr; + void _layers_selection_item_selected(int p_index); Button *toggle_grid_button = nullptr; void _on_grid_toggled(bool p_pressed); |