diff --git a/doc/classes/EditorSpinSlider.xml b/doc/classes/EditorSpinSlider.xml
index c9762c40ff..c3bb8762c8 100644
--- a/doc/classes/EditorSpinSlider.xml
+++ b/doc/classes/EditorSpinSlider.xml
@@ -13,6 +13,9 @@
The state in which the control used to manipulate the value will be.
+
+ If [code]true[/code], changing via dragging is applied only at the end of the input (for example, when the user releases a mouse button).
+
If [code]true[/code], the [EditorSpinSlider] is considered to be editing an integer value. If [code]false[/code], the [EditorSpinSlider] is considered to be editing a floating-point value. This is used to determine whether a slider should be drawn by default. The slider is only drawn for floats; integers use up-down arrows similar to [SpinBox] instead, unless [member control_state] is set to [constant CONTROL_STATE_PREFER_SLIDER]. It will also use [member EditorSettings.interface/inspector/integer_drag_speed] instead of [member EditorSettings.interface/inspector/float_drag_speed] if the slider is available.
diff --git a/editor/gui/editor_spin_slider.cpp b/editor/gui/editor_spin_slider.cpp
index 0b9206ea36..3c2d903170 100644
--- a/editor/gui/editor_spin_slider.cpp
+++ b/editor/gui/editor_spin_slider.cpp
@@ -91,7 +91,12 @@ void EditorSpinSlider::gui_input(const Ref &p_event) {
}
_grab_start();
} else {
+ bool grabbing = grabbing_spinner;
_grab_end();
+
+ if (deferred_drag_mode && grabbing) {
+ _notify_shared_value_changed(); // Need to be emitted at the end, since the signal doesn't emitted in `set_value_no_signal` method.
+ }
}
} else if (mb->get_button_index() == MouseButton::RIGHT) {
if (mb->is_pressed() && is_grabbing()) {
@@ -132,7 +137,13 @@ void EditorSpinSlider::gui_input(const Ref &p_event) {
const double default_float_step = EDITOR_GET("interface/inspector/default_float_step");
const double drag_step = MAX(get_step(), default_float_step);
const double new_value = pre_grab_value + drag_step * grabbing_spinner_dist_cache;
- set_value((mm->is_command_or_control_pressed() && !editing_integer) ? Math::round(new_value) : new_value);
+
+ double val = (mm->is_command_or_control_pressed() && !editing_integer) ? Math::round(new_value) : new_value;
+ if (deferred_drag_mode) {
+ set_value_no_signal(val);
+ } else {
+ set_value(val);
+ }
}
} else if (updown_offset != -1) {
bool new_hover = (!is_layout_rtl() && mm->get_position().x > updown_offset) || (is_layout_rtl() && mm->get_position().x < updown_offset);
@@ -693,6 +704,14 @@ bool EditorSpinSlider::is_grabbing() const {
return grabbing_grabber || grabbing_spinner;
}
+void EditorSpinSlider::set_deferred_drag_mode_enabled(bool p_enabled) {
+ deferred_drag_mode = p_enabled;
+}
+
+bool EditorSpinSlider::is_deferred_drag_mode_enabled() const {
+ return deferred_drag_mode;
+}
+
void EditorSpinSlider::_focus_entered(bool p_hide_focus) {
if (read_only) {
return;
@@ -731,6 +750,9 @@ void EditorSpinSlider::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_editing_integer", "editing_integer"), &EditorSpinSlider::set_editing_integer);
ClassDB::bind_method(D_METHOD("is_editing_integer"), &EditorSpinSlider::is_editing_integer);
+ ClassDB::bind_method(D_METHOD("set_deferred_drag_mode_enabled", "enabled"), &EditorSpinSlider::set_deferred_drag_mode_enabled, DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("is_deferred_drag_mode_enabled"), &EditorSpinSlider::is_deferred_drag_mode_enabled);
+
ADD_PROPERTY(PropertyInfo(Variant::STRING, "label"), "set_label", "get_label");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "suffix"), "set_suffix", "get_suffix");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "read_only"), "set_read_only", "is_read_only");
@@ -740,6 +762,7 @@ void EditorSpinSlider::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_slider"), "set_hide_slider", "is_hiding_slider");
#endif
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editing_integer"), "set_editing_integer", "is_editing_integer");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deferred_drag_mode"), "set_deferred_drag_mode_enabled", "is_deferred_drag_mode_enabled");
BIND_ENUM_CONSTANT(CONTROL_STATE_DEFAULT);
BIND_ENUM_CONSTANT(CONTROL_STATE_PREFER_SLIDER);
diff --git a/editor/gui/editor_spin_slider.h b/editor/gui/editor_spin_slider.h
index dbb8149f89..c4635362dd 100644
--- a/editor/gui/editor_spin_slider.h
+++ b/editor/gui/editor_spin_slider.h
@@ -66,6 +66,7 @@ class EditorSpinSlider : public Range {
uint64_t value_input_closed_frame = 0;
bool value_input_dirty = false;
bool value_input_focus_visible = false;
+ bool deferred_drag_mode = false;
public:
enum ControlState {
@@ -137,6 +138,8 @@ public:
bool is_flat() const;
bool is_grabbing() const;
+ void set_deferred_drag_mode_enabled(bool p_enabled = true);
+ bool is_deferred_drag_mode_enabled() const;
void setup_and_show() { _focus_entered(); }
LineEdit *get_line_edit();
diff --git a/editor/inspector/editor_inspector.cpp b/editor/inspector/editor_inspector.cpp
index 3daf727d9e..6d77338f25 100644
--- a/editor/inspector/editor_inspector.cpp
+++ b/editor/inspector/editor_inspector.cpp
@@ -1251,6 +1251,7 @@ bool EditorProperty::is_cache_valid() const {
}
return true;
}
+
void EditorProperty::update_cache() {
cache.clear();
if (object && property != StringName()) {
@@ -1261,6 +1262,15 @@ void EditorProperty::update_cache() {
}
}
}
+
+void EditorProperty::set_deferred_drag_mode_enabled(bool p_enabled) {
+ deferred_drag_mode = p_enabled;
+}
+
+bool EditorProperty::is_deferred_drag_mode_enabled() const {
+ return deferred_drag_mode;
+}
+
Variant EditorProperty::get_drag_data(const Point2 &p_point) {
if (property == StringName()) {
return Variant();
diff --git a/editor/inspector/editor_inspector.h b/editor/inspector/editor_inspector.h
index 5e9df77e58..31b80c8a8d 100644
--- a/editor/inspector/editor_inspector.h
+++ b/editor/inspector/editor_inspector.h
@@ -195,6 +195,7 @@ private:
bool selectable = true;
bool selected = false;
int selected_focusable;
+ bool deferred_drag_mode = false;
float split_ratio;
@@ -308,6 +309,9 @@ public:
virtual void update_cache();
virtual bool is_cache_valid() const;
+ virtual void set_deferred_drag_mode_enabled(bool p_enabled = true);
+ bool is_deferred_drag_mode_enabled() const;
+
void set_selectable(bool p_selectable);
bool is_selectable() const;
diff --git a/editor/inspector/editor_properties.cpp b/editor/inspector/editor_properties.cpp
index f02dbf5463..6fd2d82811 100644
--- a/editor/inspector/editor_properties.cpp
+++ b/editor/inspector/editor_properties.cpp
@@ -1561,6 +1561,12 @@ void EditorPropertyInteger::_value_changed(int64_t val) {
emit_changed(get_edited_property(), val);
}
+void EditorPropertyInteger::set_deferred_drag_mode_enabled(bool p_enabled) {
+ EditorProperty::set_deferred_drag_mode_enabled(p_enabled);
+
+ spin->set_deferred_drag_mode_enabled(p_enabled);
+}
+
void EditorPropertyInteger::update_property() {
int64_t val = get_edited_property_display_value();
spin->set_value_no_signal(val);
@@ -1698,6 +1704,12 @@ void EditorPropertyFloat::_value_changed(double val) {
emit_changed(get_edited_property(), val);
}
+void EditorPropertyFloat::set_deferred_drag_mode_enabled(bool p_enabled) {
+ EditorProperty::set_deferred_drag_mode_enabled(p_enabled);
+
+ spin->set_deferred_drag_mode_enabled(p_enabled);
+}
+
void EditorPropertyFloat::update_property() {
double val = get_edited_property_value();
if (radians_as_degrees) {
diff --git a/editor/inspector/editor_properties.h b/editor/inspector/editor_properties.h
index 6cc35a37e5..62c818b1d3 100644
--- a/editor/inspector/editor_properties.h
+++ b/editor/inspector/editor_properties.h
@@ -404,6 +404,7 @@ protected:
virtual void _set_read_only(bool p_read_only) override;
public:
+ virtual void set_deferred_drag_mode_enabled(bool p_enabled = true) override;
virtual void update_property() override;
void setup(const EditorPropertyRangeHint &p_range_hint);
EditorPropertyInteger();
@@ -455,6 +456,7 @@ protected:
virtual void _set_read_only(bool p_read_only) override;
public:
+ virtual void set_deferred_drag_mode_enabled(bool p_enabled = true) override;
virtual void update_property() override;
void setup(const EditorPropertyRangeHint &p_range_hint);
EditorPropertyFloat();
diff --git a/editor/inspector/editor_properties_vector.cpp b/editor/inspector/editor_properties_vector.cpp
index 351a660136..61e8dac055 100644
--- a/editor/inspector/editor_properties_vector.cpp
+++ b/editor/inspector/editor_properties_vector.cpp
@@ -239,6 +239,14 @@ EditorPropertyVectorN::EditorPropertyVectorN(Variant::Type p_type, bool p_force_
}
}
+void EditorPropertyVectorN::set_deferred_drag_mode_enabled(bool p_enabled) {
+ EditorProperty::set_deferred_drag_mode_enabled(p_enabled);
+
+ for (int i = 0; i < component_count; i++) {
+ spin_sliders[i]->set_deferred_drag_mode_enabled(p_enabled);
+ }
+}
+
EditorPropertyVector2::EditorPropertyVector2(bool p_force_wide) :
EditorPropertyVectorN(Variant::VECTOR2, p_force_wide, EDITOR_GET("interface/inspector/horizontal_vector2_editing")) {}
diff --git a/editor/inspector/editor_properties_vector.h b/editor/inspector/editor_properties_vector.h
index 40c55d33f9..63444bd19c 100644
--- a/editor/inspector/editor_properties_vector.h
+++ b/editor/inspector/editor_properties_vector.h
@@ -59,6 +59,7 @@ protected:
void _notification(int p_what);
public:
+ virtual void set_deferred_drag_mode_enabled(bool p_enabled = true) override;
virtual void update_property() override;
void setup(const EditorPropertyRangeHint &p_range_hint, bool p_link = false, bool p_is_int = false);
EditorPropertyVectorN(Variant::Type p_type, bool p_force_wide, bool p_horizontal);
diff --git a/editor/shader/visual_shader_editor_plugin.cpp b/editor/shader/visual_shader_editor_plugin.cpp
index 9c2fbc580a..113e9922d3 100644
--- a/editor/shader/visual_shader_editor_plugin.cpp
+++ b/editor/shader/visual_shader_editor_plugin.cpp
@@ -3405,6 +3405,7 @@ void VisualShaderEditor::_edit_port_default_input(Object *p_button, int p_node,
// TODO: Define these properties with actual PropertyInfo and feed it to the property editor widget.
property_editor = EditorInspector::instantiate_property_editor(edited_property_holder.ptr(), value.get_type(), "edited_property", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE, true);
ERR_FAIL_NULL_MSG(property_editor, "Failed to create property editor for type: " + Variant::get_type_name(value.get_type()));
+ property_editor->set_deferred_drag_mode_enabled();
// Determine the best size for the popup based on the property type.
// This is done here, since the property editors are also used in the inspector where they have different layout requirements, so we can't just change their default minimum size.
@@ -8237,6 +8238,7 @@ Control *VisualShaderNodePluginDefault::create_editor(const Ref &p_par
if (!prop) {
return nullptr;
}
+ prop->set_deferred_drag_mode_enabled();
if (Object::cast_to(prop)) {
Object::cast_to(prop)->set_use_sub_inspector(false);