Skip to content

Commit 1e1e9d8

Browse files
committed
Merge pull request godotengine#108335 from beicause/SpinBox-property-arrow-rounds-value
SpinBox: Add a property to set whether `custom_arrow_step` rounds value
2 parents 5cb2bfc + 7668360 commit 1e1e9d8

File tree

4 files changed

+38
-16
lines changed

4 files changed

+38
-16
lines changed

doc/classes/SpinBox.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@
4949
<member name="alignment" type="int" setter="set_horizontal_alignment" getter="get_horizontal_alignment" enum="HorizontalAlignment" default="0">
5050
Changes the alignment of the underlying [LineEdit].
5151
</member>
52+
<member name="custom_arrow_round" type="bool" setter="set_custom_arrow_round" getter="is_custom_arrow_rounding" default="false">
53+
If [code]true[/code], the value will be rounded to a multiple of [member custom_arrow_step] when interacting with the arrow buttons. Otherwise, increments the value by [member custom_arrow_step] and then rounds it according to [member Range.step].
54+
</member>
5255
<member name="custom_arrow_step" type="float" setter="set_custom_arrow_step" getter="get_custom_arrow_step" default="0.0">
5356
If not [code]0[/code], sets the step when interacting with the arrow buttons of the [SpinBox].
5457
[b]Note:[/b] [member Range.value] will still be rounded to a multiple of [member Range.step].

scene/gui/color_picker.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2170,6 +2170,7 @@ ColorPicker::ColorPicker() {
21702170
intensity_slider->set_step(0.001);
21712171
intensity_value->set_allow_greater(true);
21722172
intensity_value->set_custom_arrow_step(1);
2173+
intensity_value->set_custom_arrow_round(true);
21732174

21742175
hex_hbc = memnew(HBoxContainer);
21752176
hex_hbc->set_alignment(ALIGNMENT_BEGIN);

scene/gui/spin_box.cpp

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
234243
void 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+
617627
void 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);

scene/gui/spin_box.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class SpinBox : public Range {
6767
Timer *range_click_timer = nullptr;
6868
void _range_click_timeout();
6969
void _release_mouse_from_drag_mode();
70+
void _arrow_clicked(bool p_up);
7071

7172
void _update_text(bool p_only_update_if_value_changed = false);
7273
void _text_submitted(const String &p_string);
@@ -76,6 +77,7 @@ class SpinBox : public Range {
7677
String suffix;
7778
String last_text_value;
7879
double custom_arrow_step = 0.0;
80+
bool custom_arrow_round = false;
7981

8082
void _line_edit_input(const Ref<InputEvent> &p_event);
8183

@@ -180,5 +182,8 @@ class SpinBox : public Range {
180182
void set_custom_arrow_step(const double p_custom_arrow_step);
181183
double get_custom_arrow_step() const;
182184

185+
void set_custom_arrow_round(bool p_round);
186+
bool is_custom_arrow_rounding() const;
187+
183188
SpinBox();
184189
};

0 commit comments

Comments
 (0)