Merge pull request #97573 from shahriarlabib000/spinBox

Fix Spinbox display does not round properly when using decimal custom arrow steps
This commit is contained in:
Thaddeus Crews 2024-11-12 09:27:51 -06:00
commit 658b5d4cf8
No known key found for this signature in database
GPG Key ID: 62181B86FE9E5D84
2 changed files with 34 additions and 6 deletions

View File

@ -41,7 +41,11 @@ Size2 SpinBox::get_minimum_size() const {
} }
void SpinBox::_update_text(bool p_keep_line_edit) { void SpinBox::_update_text(bool p_keep_line_edit) {
String value = String::num(get_value(), Math::range_step_decimals(get_step())); double step = get_step();
if (use_custom_arrow_step && custom_arrow_step != 0.0) {
step = custom_arrow_step;
}
String value = String::num(get_value(), Math::range_step_decimals(step));
if (is_localizing_numeral_system()) { if (is_localizing_numeral_system()) {
value = TS->format_number(value); value = TS->format_number(value);
} }
@ -75,6 +79,9 @@ void SpinBox::_text_submitted(const String &p_string) {
text = text.trim_prefix(prefix + " ").trim_suffix(" " + suffix); text = text.trim_prefix(prefix + " ").trim_suffix(" " + suffix);
Error err = expr->parse(text); Error err = expr->parse(text);
use_custom_arrow_step = false;
if (err != OK) { if (err != OK) {
// If the expression failed try without converting commas to dots - they might have been for parameter separation. // If the expression failed try without converting commas to dots - they might have been for parameter separation.
text = p_string; text = p_string;
@ -114,8 +121,13 @@ void SpinBox::_line_edit_input(const Ref<InputEvent> &p_event) {
void SpinBox::_range_click_timeout() { void SpinBox::_range_click_timeout() {
if (!drag.enabled && Input::get_singleton()->is_mouse_button_pressed(MouseButton::LEFT)) { if (!drag.enabled && Input::get_singleton()->is_mouse_button_pressed(MouseButton::LEFT)) {
bool up = get_local_mouse_position().y < (get_size().height / 2); bool up = get_local_mouse_position().y < (get_size().height / 2);
double step = get_custom_arrow_step() != 0.0 ? get_custom_arrow_step() : get_step(); double step = get_step();
set_value(get_value() + (up ? step : -step)); // Arrow button is being pressed, so we also need to set the step to the same value as custom_arrow_step if its not 0.
double temp_step = get_custom_arrow_step() != 0.0 ? get_custom_arrow_step() : get_step();
_set_step_no_signal(temp_step);
set_value(get_value() + (up ? temp_step : -temp_step));
_set_step_no_signal(step);
use_custom_arrow_step = true;
if (range_click_timer->is_one_shot()) { if (range_click_timer->is_one_shot()) {
range_click_timer->set_wait_time(0.075); range_click_timer->set_wait_time(0.075);
@ -156,8 +168,7 @@ void SpinBox::gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event; Ref<InputEventMouseButton> mb = p_event;
Ref<InputEventMouseMotion> mm = p_event; Ref<InputEventMouseMotion> mm = p_event;
double step = get_custom_arrow_step() != 0.0 ? get_custom_arrow_step() : get_step(); double step = get_step();
Vector2 mpos; Vector2 mpos;
bool mouse_on_up_button = false; bool mouse_on_up_button = false;
bool mouse_on_down_button = false; bool mouse_on_down_button = false;
@ -177,7 +188,12 @@ void SpinBox::gui_input(const Ref<InputEvent> &p_event) {
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) {
set_value(get_value() + (mouse_on_up_button ? step : -step)); // Arrow button is being pressed, so step is being changed temporarily.
double temp_step = get_custom_arrow_step() != 0.0 ? get_custom_arrow_step() : get_step();
_set_step_no_signal(temp_step);
set_value(get_value() + (mouse_on_up_button ? temp_step : -temp_step));
_set_step_no_signal(step);
use_custom_arrow_step = true;
} }
state_cache.up_button_pressed = mouse_on_up_button; state_cache.up_button_pressed = mouse_on_up_button;
state_cache.down_button_pressed = mouse_on_down_button; state_cache.down_button_pressed = mouse_on_down_button;
@ -193,17 +209,20 @@ void SpinBox::gui_input(const Ref<InputEvent> &p_event) {
case MouseButton::RIGHT: { case MouseButton::RIGHT: {
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) {
use_custom_arrow_step = false;
set_value(mouse_on_up_button ? get_max() : get_min()); set_value(mouse_on_up_button ? get_max() : get_min());
} }
} break; } break;
case MouseButton::WHEEL_UP: { case MouseButton::WHEEL_UP: {
if (line_edit->is_editing()) { if (line_edit->is_editing()) {
use_custom_arrow_step = false;
set_value(get_value() + step * mb->get_factor()); set_value(get_value() + step * mb->get_factor());
accept_event(); accept_event();
} }
} break; } break;
case MouseButton::WHEEL_DOWN: { case MouseButton::WHEEL_DOWN: {
if (line_edit->is_editing()) { if (line_edit->is_editing()) {
use_custom_arrow_step = false;
set_value(get_value() - step * mb->get_factor()); set_value(get_value() - step * mb->get_factor());
accept_event(); accept_event();
} }
@ -243,6 +262,7 @@ void SpinBox::gui_input(const Ref<InputEvent> &p_event) {
if (drag.enabled) { if (drag.enabled) {
drag.diff_y += mm->get_relative().y; drag.diff_y += mm->get_relative().y;
double diff_y = -0.01 * Math::pow(ABS(drag.diff_y), 1.8) * SIGN(drag.diff_y); double diff_y = -0.01 * Math::pow(ABS(drag.diff_y), 1.8) * SIGN(drag.diff_y);
use_custom_arrow_step = false;
set_value(CLAMP(drag.base_val + step * diff_y, get_min(), get_max())); set_value(CLAMP(drag.base_val + step * diff_y, get_min(), get_max()));
} else if (drag.allowed && drag.capture_pos.distance_to(mm->get_position()) > 2) { } else if (drag.allowed && drag.capture_pos.distance_to(mm->get_position()) > 2) {
Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED); Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED);
@ -519,6 +539,12 @@ void SpinBox::_update_buttons_state_for_current_value() {
} }
} }
void SpinBox::_set_step_no_signal(double p_step) {
set_block_signals(true);
set_step(p_step);
set_block_signals(false);
}
void SpinBox::_bind_methods() { void SpinBox::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_horizontal_alignment", "alignment"), &SpinBox::set_horizontal_alignment); ClassDB::bind_method(D_METHOD("set_horizontal_alignment", "alignment"), &SpinBox::set_horizontal_alignment);
ClassDB::bind_method(D_METHOD("get_horizontal_alignment"), &SpinBox::get_horizontal_alignment); ClassDB::bind_method(D_METHOD("get_horizontal_alignment"), &SpinBox::get_horizontal_alignment);

View File

@ -66,6 +66,7 @@ class SpinBox : public Range {
String suffix; String suffix;
String last_updated_text; String last_updated_text;
double custom_arrow_step = 0.0; double custom_arrow_step = 0.0;
bool use_custom_arrow_step = false;
void _line_edit_input(const Ref<InputEvent> &p_event); void _line_edit_input(const Ref<InputEvent> &p_event);
@ -133,6 +134,7 @@ class SpinBox : public Range {
void _mouse_exited(); void _mouse_exited();
void _update_buttons_state_for_current_value(); void _update_buttons_state_for_current_value();
void _set_step_no_signal(double p_step);
protected: protected:
virtual void gui_input(const Ref<InputEvent> &p_event) override; virtual void gui_input(const Ref<InputEvent> &p_event) override;