diff options
Diffstat (limited to 'scene/gui/spin_box.cpp')
| -rw-r--r-- | scene/gui/spin_box.cpp | 45 |
1 files changed, 34 insertions, 11 deletions
diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index 7cb54f24ea..bd549a6e4a 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -32,6 +32,7 @@ #include "core/input/input.h" #include "core/math/expression.h" +#include "scene/theme/theme_db.h" Size2 SpinBox::get_minimum_size() const { Size2 ms = line_edit->get_combined_minimum_size(); @@ -39,7 +40,7 @@ Size2 SpinBox::get_minimum_size() const { return ms; } -void SpinBox::_update_text() { +void SpinBox::_update_text(bool p_keep_line_edit) { String value = String::num(get_value(), Math::range_step_decimals(get_step())); if (is_localizing_numeral_system()) { value = TS->format_number(value); @@ -54,18 +55,36 @@ void SpinBox::_update_text() { } } + if (p_keep_line_edit && value == last_updated_text && value != line_edit->get_text()) { + return; + } + line_edit->set_text_with_selection(value); + last_updated_text = value; } void SpinBox::_text_submitted(const String &p_string) { Ref<Expression> expr; expr.instantiate(); - String num = TS->parse_number(p_string); + // Convert commas ',' to dots '.' for French/German etc. keyboard layouts. + String text = p_string.replace(",", "."); + text = text.replace(";", ","); + text = TS->parse_number(text); // Ignore the prefix and suffix in the expression. - Error err = expr->parse(num.trim_prefix(prefix + " ").trim_suffix(" " + suffix)); + text = text.trim_prefix(prefix + " ").trim_suffix(" " + suffix); + + Error err = expr->parse(text); if (err != OK) { - return; + // If the expression failed try without converting commas to dots - they might have been for parameter separation. + text = p_string; + text = TS->parse_number(text); + text = text.trim_prefix(prefix + " ").trim_suffix(" " + suffix); + + err = expr->parse(text); + if (err != OK) { + return; + } } Variant value = expr->execute(Array(), nullptr, false, true); @@ -210,6 +229,11 @@ void SpinBox::_line_edit_focus_exit() { if (line_edit->is_menu_visible()) { return; } + // Discontinue because the focus_exit was caused by canceling. + if (Input::get_singleton()->is_action_pressed("ui_cancel")) { + _update_text(); + return; + } _text_submitted(line_edit->get_text()); } @@ -223,16 +247,10 @@ inline void SpinBox::_adjust_width_for_icon(const Ref<Texture2D> &icon) { } } -void SpinBox::_update_theme_item_cache() { - Range::_update_theme_item_cache(); - - theme_cache.updown_icon = get_theme_icon(SNAME("updown")); -} - void SpinBox::_notification(int p_what) { switch (p_what) { case NOTIFICATION_DRAW: { - _update_text(); + _update_text(true); _adjust_width_for_icon(theme_cache.updown_icon); RID ci = get_canvas_item(); @@ -250,6 +268,9 @@ void SpinBox::_notification(int p_what) { _update_text(); } break; + case NOTIFICATION_VISIBILITY_CHANGED: + drag.allowed = false; + [[fallthrough]]; case NOTIFICATION_EXIT_TREE: { _release_mouse(); } break; @@ -374,6 +395,8 @@ void SpinBox::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "suffix"), "set_suffix", "get_suffix"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "custom_arrow_step", PROPERTY_HINT_RANGE, "0,10000,0.0001,or_greater"), "set_custom_arrow_step", "get_custom_arrow_step"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "select_all_on_focus"), "set_select_all_on_focus", "is_select_all_on_focus"); + + BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_ICON, SpinBox, updown_icon, "updown"); } SpinBox::SpinBox() { |
