Fix spinbox decimal issues when update_on_text_changed = true

This commit is contained in:
Robert Yevdokimov 2024-12-20 18:50:36 -05:00
parent b15b24b087
commit d8318deb0a
2 changed files with 33 additions and 4 deletions

View file

@ -63,20 +63,39 @@ void SpinBox::_update_text(bool p_only_update_if_value_changed) {
value += " " + suffix; value += " " + suffix;
} }
} }
if (!accepted && update_on_text_changed && !line_edit->get_text().replace(",", ".").contains_char('.')) {
value = String::num(get_value(), 0);
}
line_edit->set_text_with_selection(value); line_edit->set_text_with_selection(value);
} }
void SpinBox::_text_submitted(const String &p_string) { void SpinBox::_text_submitted(const String &p_string) {
if (p_string.is_empty()) { if (p_string.is_empty()) {
_update_text();
return; return;
} }
String text = p_string;
if (update_on_text_changed) {
// Convert commas ',' to dots '.' for French/German etc. keyboard layouts.
text = p_string.replace(",", ".");
if (!text.begins_with(".") && p_string.ends_with(".")) {
return;
}
if (text.begins_with(".")) {
line_edit->set_text("0.");
line_edit->set_caret_column(line_edit->get_text().length());
return;
}
}
Ref<Expression> expr; Ref<Expression> expr;
expr.instantiate(); expr.instantiate();
// Convert commas ',' to dots '.' for French/German etc. keyboard layouts.
String text = p_string.replace(",", ".");
text = text.replace(";", ","); text = text.replace(";", ",");
text = TS->parse_number(text); text = TS->parse_number(text);
// Ignore the prefix and suffix in the expression. // Ignore the prefix and suffix in the expression.
@ -107,12 +126,17 @@ void SpinBox::_text_submitted(const String &p_string) {
} }
void SpinBox::_text_changed(const String &p_string) { void SpinBox::_text_changed(const String &p_string) {
accepted = false;
int cursor_pos = line_edit->get_caret_column(); int cursor_pos = line_edit->get_caret_column();
_text_submitted(p_string); _text_submitted(p_string);
String text = p_string.replace(",", ".");
// Line edit 'set_text' method resets the cursor position so we need to undo that. // Line edit 'set_text' method resets the cursor position so we need to undo that.
line_edit->set_caret_column(cursor_pos); if (update_on_text_changed && !text.begins_with(".")) {
line_edit->set_caret_column(cursor_pos);
}
} }
LineEdit *SpinBox::get_line_edit() { LineEdit *SpinBox::get_line_edit() {
@ -189,6 +213,7 @@ void SpinBox::gui_input(const Ref<InputEvent> &p_event) {
if (mb.is_valid() && mb->is_pressed()) { if (mb.is_valid() && mb->is_pressed()) {
switch (mb->get_button_index()) { switch (mb->get_button_index()) {
case MouseButton::LEFT: { case MouseButton::LEFT: {
accepted = true;
line_edit->grab_focus(); line_edit->grab_focus();
if (mouse_on_up_button || mouse_on_down_button) { if (mouse_on_up_button || mouse_on_down_button) {
@ -288,9 +313,12 @@ void SpinBox::_line_edit_editing_toggled(bool p_toggled_on) {
line_edit->select_all(); line_edit->select_all();
} }
} else { } else {
accepted = true;
if (Input::get_singleton()->is_action_pressed("ui_cancel") || line_edit->get_text().is_empty()) { if (Input::get_singleton()->is_action_pressed("ui_cancel") || line_edit->get_text().is_empty()) {
_update_text(); // Revert text if editing was canceled. _update_text(); // Revert text if editing was canceled.
} else { } else {
line_edit->set_text(line_edit->get_text().trim_suffix(".").trim_suffix(","));
_update_text(true); // Update text in case value was changed this frame (e.g. on `focus_exited`). _update_text(true); // Update text in case value was changed this frame (e.g. on `focus_exited`).
_text_submitted(line_edit->get_text()); _text_submitted(line_edit->get_text());
} }

View file

@ -40,6 +40,7 @@ class SpinBox : public Range {
LineEdit *line_edit = nullptr; LineEdit *line_edit = nullptr;
bool update_on_text_changed = false; bool update_on_text_changed = false;
bool accepted = true;
struct SizingCache { struct SizingCache {
int buttons_block_width = 0; int buttons_block_width = 0;