Add smooth to the changing of properties values in visual shader

This commit is contained in:
Chaosus 2026-02-22 19:50:05 +03:00
parent a3e84cc2af
commit ef933c9235
10 changed files with 69 additions and 1 deletions

View file

@ -13,6 +13,9 @@
<member name="control_state" type="int" setter="set_control_state" getter="get_control_state" enum="EditorSpinSlider.ControlState" default="0">
The state in which the control used to manipulate the value will be.
</member>
<member name="deferred_drag_mode" type="bool" setter="set_deferred_drag_mode_enabled" getter="is_deferred_drag_mode_enabled" default="false">
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).
</member>
<member name="editing_integer" type="bool" setter="set_editing_integer" getter="is_editing_integer" default="false">
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.
</member>

View file

@ -91,7 +91,12 @@ void EditorSpinSlider::gui_input(const Ref<InputEvent> &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<InputEvent> &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);

View file

@ -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();

View file

@ -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();

View file

@ -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;

View file

@ -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) {

View file

@ -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();

View file

@ -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")) {}

View file

@ -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);

View file

@ -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<Resource> &p_par
if (!prop) {
return nullptr;
}
prop->set_deferred_drag_mode_enabled();
if (Object::cast_to<EditorPropertyResource>(prop)) {
Object::cast_to<EditorPropertyResource>(prop)->set_use_sub_inspector(false);