瀏覽代碼

Spinbox: Fix incorrect step and decimal text when using custom arrow step

LuoZhihao 1 月之前
父節點
當前提交
81406ff1f4
共有 4 個文件被更改,包括 21 次插入28 次删除
  1. 7 8
      scene/gui/range.cpp
  2. 1 0
      scene/gui/range.h
  3. 13 19
      scene/gui/spin_box.cpp
  4. 0 1
      scene/gui/spin_box.h

+ 7 - 8
scene/gui/range.cpp

@@ -135,8 +135,12 @@ void Range::set_value(double p_val) {
 }
 
 void Range::_set_value_no_signal(double p_val) {
-	if (shared->step > 0) {
-		p_val = Math::round((p_val - shared->min) / shared->step) * shared->step + shared->min;
+	shared->val = _calc_value(p_val, shared->step);
+}
+
+double Range::_calc_value(double p_val, double p_step) const {
+	if (p_step > 0) {
+		p_val = Math::round((p_val - shared->min) / p_step) * p_step + shared->min;
 	}
 
 	if (_rounded_values) {
@@ -150,12 +154,7 @@ void Range::_set_value_no_signal(double p_val) {
 	if (!shared->allow_lesser && p_val < shared->min) {
 		p_val = shared->min;
 	}
-
-	if (shared->val == p_val) {
-		return;
-	}
-
-	shared->val = p_val;
+	return p_val;
 }
 
 void Range::set_value_no_signal(double p_val) {

+ 1 - 0
scene/gui/range.h

@@ -62,6 +62,7 @@ class Range : public Control {
 	void _set_value_no_signal(double p_val);
 
 protected:
+	double _calc_value(double p_val, double p_step) const;
 	virtual void _value_changed(double p_value);
 	void _notify_shared_value_changed() { shared->emit_value_changed(); }
 	void _notification(int p_what);

+ 13 - 19
scene/gui/spin_box.cpp

@@ -86,9 +86,6 @@ Size2 SpinBox::get_minimum_size() const {
 
 void SpinBox::_update_text(bool p_only_update_if_value_changed) {
 	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()) {
 		value = TS->format_number(value);
@@ -195,13 +192,14 @@ void SpinBox::_line_edit_input(const Ref<InputEvent> &p_event) {
 
 void SpinBox::_range_click_timeout() {
 	if (!drag.enabled && Input::get_singleton()->is_mouse_button_pressed(MouseButton::LEFT)) {
-		bool up = get_local_mouse_position().y < (get_size().height / 2);
-		double step = get_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.
+		bool mouse_on_up_button = get_local_mouse_position().y < (get_size().height / 2);
+		// Arrow button is being pressed. Snap the value to next step.
 		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);
+		double new_value = _calc_value(get_value(), temp_step);
+		if ((mouse_on_up_button && new_value <= get_value() + CMP_EPSILON) || (!mouse_on_up_button && new_value >= get_value() - CMP_EPSILON)) {
+			new_value = _calc_value(get_value() + (mouse_on_up_button ? temp_step : -temp_step), temp_step);
+		}
+		set_value(new_value);
 		use_custom_arrow_step = true;
 
 		if (range_click_timer->is_one_shot()) {
@@ -264,11 +262,13 @@ void SpinBox::gui_input(const Ref<InputEvent> &p_event) {
 				line_edit->grab_focus();
 
 				if (mouse_on_up_button || mouse_on_down_button) {
-					// Arrow button is being pressed, so step is being changed temporarily.
+					// Arrow button is being pressed. Snap the value to next step.
 					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);
+					double new_value = _calc_value(get_value(), temp_step);
+					if ((mouse_on_up_button && new_value <= get_value() + CMP_EPSILON) || (!mouse_on_up_button && new_value >= get_value() - CMP_EPSILON)) {
+						new_value = _calc_value(get_value() + (mouse_on_up_button ? temp_step : -temp_step), temp_step);
+					}
+					set_value(new_value);
 					use_custom_arrow_step = true;
 				}
 				state_cache.up_button_pressed = mouse_on_up_button;
@@ -616,12 +616,6 @@ 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::_validate_property(PropertyInfo &p_property) const {
 	if (p_property.name == "exp_edit") {
 		p_property.usage = PROPERTY_USAGE_NONE;

+ 0 - 1
scene/gui/spin_box.h

@@ -144,7 +144,6 @@ class SpinBox : public Range {
 
 	void _mouse_exited();
 	void _update_buttons_state_for_current_value();
-	void _set_step_no_signal(double p_step);
 
 protected:
 	virtual void gui_input(const Ref<InputEvent> &p_event) override;