@@ -201,14 +201,7 @@ void SpinBox::_range_click_timeout() {
201201 bool mouse_on_down_button = down_button_rc.has_point (mpos);
202202
203203 if (mouse_on_up_button || mouse_on_down_button) {
204- // Arrow button is being pressed. Snap the value to next step.
205- double temp_step = get_custom_arrow_step () != 0.0 ? get_custom_arrow_step () : get_step ();
206- temp_step = Math::snapped (temp_step, get_step ());
207- double new_value = _calc_value (get_value (), temp_step);
208- if ((mouse_on_up_button && new_value <= get_value () + CMP_EPSILON) || (!mouse_on_up_button && new_value >= get_value () - CMP_EPSILON)) {
209- new_value = _calc_value (get_value () + (mouse_on_up_button ? temp_step : -temp_step), temp_step);
210- }
211- set_value (new_value);
204+ _arrow_clicked (mouse_on_up_button);
212205 }
213206
214207 if (range_click_timer->is_one_shot ()) {
@@ -231,6 +224,22 @@ void SpinBox::_release_mouse_from_drag_mode() {
231224 }
232225}
233226
227+ void SpinBox::_arrow_clicked (bool p_up) {
228+ double arrow_step = get_custom_arrow_step () != 0.0 ? get_custom_arrow_step () : get_step ();
229+ if (custom_arrow_round) {
230+ // Arrow button is being pressed, snap the value to next `arrow_step`.
231+ // `arrow_step` should be a multiple of `step`, otherwise it may not be able to increase/decrease the value.
232+ arrow_step = Math::snapped (arrow_step, get_step ());
233+ double new_value = _calc_value (get_value (), arrow_step);
234+ if ((p_up && new_value <= get_value ()) || (!p_up && new_value >= get_value ())) {
235+ new_value = _calc_value (get_value () + (p_up ? arrow_step : -arrow_step), arrow_step);
236+ }
237+ set_value (new_value);
238+ } else {
239+ set_value (get_value () + (p_up ? arrow_step : -arrow_step));
240+ }
241+ }
242+
234243void SpinBox::_mouse_exited () {
235244 if (state_cache.up_button_hovered || state_cache.down_button_hovered ) {
236245 state_cache.up_button_hovered = false ;
@@ -271,14 +280,7 @@ void SpinBox::gui_input(const Ref<InputEvent> &p_event) {
271280 line_edit->grab_focus (true );
272281
273282 if (mouse_on_up_button || mouse_on_down_button) {
274- // Arrow button is being pressed. Snap the value to next step.
275- double temp_step = get_custom_arrow_step () != 0.0 ? get_custom_arrow_step () : get_step ();
276- temp_step = Math::snapped (temp_step, get_step ());
277- double new_value = _calc_value (get_value (), temp_step);
278- if ((mouse_on_up_button && new_value <= get_value () + CMP_EPSILON) || (!mouse_on_up_button && new_value >= get_value () - CMP_EPSILON)) {
279- new_value = _calc_value (get_value () + (mouse_on_up_button ? temp_step : -temp_step), temp_step);
280- }
281- set_value (new_value);
283+ _arrow_clicked (mouse_on_up_button);
282284 }
283285 state_cache.up_button_pressed = mouse_on_up_button;
284286 state_cache.down_button_pressed = mouse_on_down_button;
@@ -614,6 +616,14 @@ double SpinBox::get_custom_arrow_step() const {
614616 return custom_arrow_step;
615617}
616618
619+ void SpinBox::set_custom_arrow_round (bool p_round) {
620+ custom_arrow_round = p_round;
621+ }
622+
623+ bool SpinBox::is_custom_arrow_rounding () const {
624+ return custom_arrow_round;
625+ }
626+
617627void SpinBox::_value_changed (double p_value) {
618628 _update_buttons_state_for_current_value ();
619629}
@@ -646,6 +656,8 @@ void SpinBox::_bind_methods() {
646656 ClassDB::bind_method (D_METHOD (" set_editable" , " enabled" ), &SpinBox::set_editable);
647657 ClassDB::bind_method (D_METHOD (" set_custom_arrow_step" , " arrow_step" ), &SpinBox::set_custom_arrow_step);
648658 ClassDB::bind_method (D_METHOD (" get_custom_arrow_step" ), &SpinBox::get_custom_arrow_step);
659+ ClassDB::bind_method (D_METHOD (" set_custom_arrow_round" , " round" ), &SpinBox::set_custom_arrow_round);
660+ ClassDB::bind_method (D_METHOD (" is_custom_arrow_rounding" ), &SpinBox::is_custom_arrow_rounding);
649661 ClassDB::bind_method (D_METHOD (" is_editable" ), &SpinBox::is_editable);
650662 ClassDB::bind_method (D_METHOD (" set_update_on_text_changed" , " enabled" ), &SpinBox::set_update_on_text_changed);
651663 ClassDB::bind_method (D_METHOD (" get_update_on_text_changed" ), &SpinBox::get_update_on_text_changed);
@@ -660,6 +672,7 @@ void SpinBox::_bind_methods() {
660672 ADD_PROPERTY (PropertyInfo (Variant::STRING, " prefix" ), " set_prefix" , " get_prefix" );
661673 ADD_PROPERTY (PropertyInfo (Variant::STRING, " suffix" ), " set_suffix" , " get_suffix" );
662674 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" );
675+ ADD_PROPERTY (PropertyInfo (Variant::BOOL, " custom_arrow_round" ), " set_custom_arrow_round" , " is_custom_arrow_rounding" );
663676 ADD_PROPERTY (PropertyInfo (Variant::BOOL, " select_all_on_focus" ), " set_select_all_on_focus" , " is_select_all_on_focus" );
664677
665678 BIND_THEME_ITEM (Theme::DATA_TYPE_CONSTANT, SpinBox, buttons_vertical_separation);
0 commit comments