Skip to content

Commit afeecad

Browse files
Fix Spinbox display does not round properly when using decimal custom arrow steps
1 parent 76a1359 commit afeecad

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

scene/gui/spin_box.cpp

+32-6
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,11 @@ Size2 SpinBox::get_minimum_size() const {
4141
}
4242

4343
void SpinBox::_update_text(bool p_keep_line_edit) {
44-
String value = String::num(get_value(), Math::range_step_decimals(get_step()));
44+
double step = get_step();
45+
if (use_custom_arrow_step && custom_arrow_step != 0.0) {
46+
step = custom_arrow_step;
47+
}
48+
String value = String::num(get_value(), Math::range_step_decimals(step));
4549
if (is_localizing_numeral_system()) {
4650
value = TS->format_number(value);
4751
}
@@ -75,6 +79,9 @@ void SpinBox::_text_submitted(const String &p_string) {
7579
text = text.trim_prefix(prefix + " ").trim_suffix(" " + suffix);
7680

7781
Error err = expr->parse(text);
82+
83+
use_custom_arrow_step = false;
84+
7885
if (err != OK) {
7986
// If the expression failed try without converting commas to dots - they might have been for parameter separation.
8087
text = p_string;
@@ -114,8 +121,13 @@ void SpinBox::_line_edit_input(const Ref<InputEvent> &p_event) {
114121
void SpinBox::_range_click_timeout() {
115122
if (!drag.enabled && Input::get_singleton()->is_mouse_button_pressed(MouseButton::LEFT)) {
116123
bool up = get_local_mouse_position().y < (get_size().height / 2);
117-
double step = get_custom_arrow_step() != 0.0 ? get_custom_arrow_step() : get_step();
118-
set_value(get_value() + (up ? step : -step));
124+
double step = get_step();
125+
// 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.
126+
double temp_step = get_custom_arrow_step() != 0.0 ? get_custom_arrow_step() : get_step();
127+
_set_step_no_signal(temp_step);
128+
set_value(get_value() + (up ? temp_step : -temp_step));
129+
_set_step_no_signal(step);
130+
use_custom_arrow_step = true;
119131

120132
if (range_click_timer->is_one_shot()) {
121133
range_click_timer->set_wait_time(0.075);
@@ -156,8 +168,7 @@ void SpinBox::gui_input(const Ref<InputEvent> &p_event) {
156168
Ref<InputEventMouseButton> mb = p_event;
157169
Ref<InputEventMouseMotion> mm = p_event;
158170

159-
double step = get_custom_arrow_step() != 0.0 ? get_custom_arrow_step() : get_step();
160-
171+
double step = get_step();
161172
Vector2 mpos;
162173
bool mouse_on_up_button = false;
163174
bool mouse_on_down_button = false;
@@ -177,7 +188,12 @@ void SpinBox::gui_input(const Ref<InputEvent> &p_event) {
177188
line_edit->grab_focus();
178189

179190
if (mouse_on_up_button || mouse_on_down_button) {
180-
set_value(get_value() + (mouse_on_up_button ? step : -step));
191+
// Arrow button is being pressed, so step is being changed temporarily.
192+
double temp_step = get_custom_arrow_step() != 0.0 ? get_custom_arrow_step() : get_step();
193+
_set_step_no_signal(temp_step);
194+
set_value(get_value() + (mouse_on_up_button ? temp_step : -temp_step));
195+
_set_step_no_signal(step);
196+
use_custom_arrow_step = true;
181197
}
182198
state_cache.up_button_pressed = mouse_on_up_button;
183199
state_cache.down_button_pressed = mouse_on_down_button;
@@ -193,17 +209,20 @@ void SpinBox::gui_input(const Ref<InputEvent> &p_event) {
193209
case MouseButton::RIGHT: {
194210
line_edit->grab_focus();
195211
if (mouse_on_up_button || mouse_on_down_button) {
212+
use_custom_arrow_step = false;
196213
set_value(mouse_on_up_button ? get_max() : get_min());
197214
}
198215
} break;
199216
case MouseButton::WHEEL_UP: {
200217
if (line_edit->is_editing()) {
218+
use_custom_arrow_step = false;
201219
set_value(get_value() + step * mb->get_factor());
202220
accept_event();
203221
}
204222
} break;
205223
case MouseButton::WHEEL_DOWN: {
206224
if (line_edit->is_editing()) {
225+
use_custom_arrow_step = false;
207226
set_value(get_value() - step * mb->get_factor());
208227
accept_event();
209228
}
@@ -243,6 +262,7 @@ void SpinBox::gui_input(const Ref<InputEvent> &p_event) {
243262
if (drag.enabled) {
244263
drag.diff_y += mm->get_relative().y;
245264
double diff_y = -0.01 * Math::pow(ABS(drag.diff_y), 1.8) * SIGN(drag.diff_y);
265+
use_custom_arrow_step = false;
246266
set_value(CLAMP(drag.base_val + step * diff_y, get_min(), get_max()));
247267
} else if (drag.allowed && drag.capture_pos.distance_to(mm->get_position()) > 2) {
248268
Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED);
@@ -519,6 +539,12 @@ void SpinBox::_update_buttons_state_for_current_value() {
519539
}
520540
}
521541

542+
void SpinBox::_set_step_no_signal(double p_step) {
543+
set_block_signals(true);
544+
set_step(p_step);
545+
set_block_signals(false);
546+
}
547+
522548
void SpinBox::_bind_methods() {
523549
ClassDB::bind_method(D_METHOD("set_horizontal_alignment", "alignment"), &SpinBox::set_horizontal_alignment);
524550
ClassDB::bind_method(D_METHOD("get_horizontal_alignment"), &SpinBox::get_horizontal_alignment);

scene/gui/spin_box.h

+2
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class SpinBox : public Range {
6666
String suffix;
6767
String last_updated_text;
6868
double custom_arrow_step = 0.0;
69+
bool use_custom_arrow_step = false;
6970

7071
void _line_edit_input(const Ref<InputEvent> &p_event);
7172

@@ -133,6 +134,7 @@ class SpinBox : public Range {
133134

134135
void _mouse_exited();
135136
void _update_buttons_state_for_current_value();
137+
void _set_step_no_signal(double p_step);
136138

137139
protected:
138140
virtual void gui_input(const Ref<InputEvent> &p_event) override;

0 commit comments

Comments
 (0)