Skip to content

Commit a20ca7b

Browse files
committed
Merge pull request godotengine#110459 from YeldhamDev/let_the_poor_ints_slide
Allow to use sliders for integers in `EditorSpinSlider`
2 parents 2288081 + f16ff82 commit a20ca7b

21 files changed

+188
-96
lines changed

core/config/project_settings.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1699,7 +1699,7 @@ ProjectSettings::ProjectSettings() {
16991699
// installed by the scripts provided in the repository
17001700
// (check `misc/scripts/install_d3d12_sdk_windows.py`).
17011701
// For example, if the script installs 1.613.3, the default value must be 613.
1702-
GLOBAL_DEF_RST(PropertyInfo(Variant::INT, "rendering/rendering_device/d3d12/agility_sdk_version", PROPERTY_HINT_RANGE, "0,10000,1,or_greater,hide_slider"), 613);
1702+
GLOBAL_DEF_RST(PropertyInfo(Variant::INT, "rendering/rendering_device/d3d12/agility_sdk_version", PROPERTY_HINT_RANGE, "0,10000,1,or_greater,hide_control"), 613);
17031703

17041704
GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "rendering/textures/canvas_textures/default_texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,Linear Mipmap,Nearest Mipmap"), 1);
17051705
GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "rendering/textures/canvas_textures/default_texture_repeat", PROPERTY_HINT_ENUM, "Disable,Enable,Mirror"), 0);

core/object/object.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class Ref;
5151

5252
enum PropertyHint {
5353
PROPERTY_HINT_NONE, ///< no hint provided.
54-
PROPERTY_HINT_RANGE, ///< hint_text = "min,max[,step][,or_greater][,or_less][,hide_slider][,radians_as_degrees][,degrees][,exp][,suffix:<keyword>] range.
54+
PROPERTY_HINT_RANGE, ///< hint_text = "min,max[,step][,or_greater][,or_less][,prefer_slider][,hide_control][,radians_as_degrees][,degrees][,exp][,suffix:<keyword>] range.
5555
PROPERTY_HINT_ENUM, ///< hint_text= "val1,val2,val3,etc"
5656
PROPERTY_HINT_ENUM_SUGGESTION, ///< hint_text= "val1,val2,val3,etc"
5757
PROPERTY_HINT_EXP_EASING, /// exponential easing function (Math::ease) use "attenuation" hint string to revert (flip h), "positive_only" to exclude in-out and out-in. (ie: "attenuation,positive_only")

doc/classes/@GlobalScope.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2771,7 +2771,7 @@
27712771
<constant name="PROPERTY_HINT_RANGE" value="1" enum="PropertyHint">
27722772
Hints that an [int] or [float] property should be within a range specified via the hint string [code]"min,max"[/code] or [code]"min,max,step"[/code]. The hint string can optionally include [code]"or_greater"[/code] and/or [code]"or_less"[/code] to allow manual input going respectively above the max or below the min values.
27732773
[b]Example:[/b] [code]"-360,360,1,or_greater,or_less"[/code].
2774-
Additionally, other keywords can be included: [code]"exp"[/code] for exponential range editing, [code]"radians_as_degrees"[/code] for editing radian angles in degrees (the range values are also in degrees), [code]"degrees"[/code] to hint at an angle and [code]"hide_slider"[/code] to hide the slider.
2774+
Additionally, other keywords can be included: [code]"exp"[/code] for exponential range editing, [code]"radians_as_degrees"[/code] for editing radian angles in degrees (the range values are also in degrees), [code]"degrees"[/code] to hint at an angle, [code]"prefer_slider"[/code] to show the slider for integers, and [code]"hide_control"[/code] to hide the slider or up-down arrows.
27752775
</constant>
27762776
<constant name="PROPERTY_HINT_ENUM" value="2" enum="PropertyHint">
27772777
Hints that an [int] or [String] property is an enumerated value to pick in a list specified via a hint string.

doc/classes/EditorSettings.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,6 +1027,9 @@
10271027
<member name="interface/inspector/horizontal_vector_types_editing" type="bool" setter="" getter="">
10281028
If [code]true[/code], [Vector3], [Vector3i], [Vector4], [Vector4i], [Rect2], [Rect2i], [Plane], and [Quaternion] properties are shown on a single line in the inspector instead of multiple lines. This is overall more compact, but it can be harder to view and edit large values without expanding the inspector horizontally.
10291029
</member>
1030+
<member name="interface/inspector/integer_drag_speed" type="float" setter="" getter="">
1031+
Base speed for increasing/decreasing integer values by dragging them in the inspector.
1032+
</member>
10301033
<member name="interface/inspector/max_array_dictionary_items_per_page" type="int" setter="" getter="">
10311034
The number of [Array] or [Dictionary] items to display on each "page" in the inspector. Higher values allow viewing more values per page, but take more time to load. This increased load time is noticeable when selecting nodes that have array or dictionary properties in the editor.
10321035
</member>

doc/classes/EditorSpinSlider.xml

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,17 @@
1010
<tutorials>
1111
</tutorials>
1212
<members>
13+
<member name="control_state" type="int" setter="set_control_state" getter="get_control_state" enum="EditorSpinSlider.ControlState" default="0">
14+
The state in which the control used to manipulate the value will be.
15+
</member>
1316
<member name="editing_integer" type="bool" setter="set_editing_integer" getter="is_editing_integer" default="false">
14-
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. The slider is only drawn for floats; integers use up-down arrows similar to [SpinBox] instead.
17+
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.
1518
</member>
1619
<member name="flat" type="bool" setter="set_flat" getter="is_flat" default="false">
1720
If [code]true[/code], the slider will not draw background.
1821
</member>
1922
<member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" overrides="Control" enum="Control.FocusMode" default="2" />
20-
<member name="hide_slider" type="bool" setter="set_hide_slider" getter="is_hiding_slider" default="false">
23+
<member name="hide_slider" type="bool" setter="set_hide_slider" getter="is_hiding_slider" default="false" deprecated="Use [member control_state] instead.">
2124
If [code]true[/code], the slider and up/down arrows are hidden.
2225
</member>
2326
<member name="label" type="String" setter="set_label" getter="get_label" default="&quot;&quot;">
@@ -59,6 +62,17 @@
5962
</description>
6063
</signal>
6164
</signals>
65+
<constants>
66+
<constant name="CONTROL_STATE_DEFAULT" value="0" enum="ControlState">
67+
The type of control used will depend on the value of [member editing_integer]. Up-down arrows if [code]true[/code], a slider if [code]false[/code].
68+
</constant>
69+
<constant name="CONTROL_STATE_PREFER_SLIDER" value="1" enum="ControlState">
70+
A slider will always be used, even if [member editing_integer] is enabled.
71+
</constant>
72+
<constant name="CONTROL_STATE_HIDE" value="2" enum="ControlState">
73+
Neither the up-down arrows nor the slider will be shown.
74+
</constant>
75+
</constants>
6276
<theme_items>
6377
<theme_item name="updown" data_type="icon" type="Texture2D">
6478
Single texture representing both the up and down buttons.

editor/animation/animation_track_editor.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2051,7 +2051,7 @@ AnimationTimelineEdit::AnimationTimelineEdit() {
20512051
length->set_step(SECOND_DECIMAL);
20522052
length->set_allow_greater(true);
20532053
length->set_custom_minimum_size(Vector2(70 * EDSCALE, 0));
2054-
length->set_hide_slider(true);
2054+
length->set_control_state(EditorSpinSlider::CONTROL_STATE_HIDE);
20552055
length->set_tooltip_text(TTR("Animation length (seconds)"));
20562056
length->set_accessibility_name(TTRC("Animation length (seconds)"));
20572057
length->connect(SceneStringName(value_changed), callable_mp(this, &AnimationTimelineEdit::_anim_length_changed));
@@ -7970,7 +7970,7 @@ AnimationTrackEditor::AnimationTrackEditor() {
79707970
step->set_min(0);
79717971
step->set_max(1000000);
79727972
step->set_step(SECOND_DECIMAL);
7973-
step->set_hide_slider(true);
7973+
step->set_control_state(EditorSpinSlider::CONTROL_STATE_HIDE);
79747974
step->set_custom_minimum_size(Size2(100, 0) * EDSCALE);
79757975
step->set_tooltip_text(TTR("Animation step value."));
79767976
step->set_accessibility_name(TTRC("Animation step value."));

editor/gui/editor_spin_slider.cpp

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,20 @@
3838
#include "scene/theme/theme_db.h"
3939

4040
String EditorSpinSlider::get_tooltip(const Point2 &p_pos) const {
41+
String value = get_text_value() + suffix;
4142
if (!read_only && grabber->is_visible()) {
43+
String tooltip = value;
4244
Key key = (OS::get_singleton()->has_feature("macos") || OS::get_singleton()->has_feature("web_macos") || OS::get_singleton()->has_feature("web_ios")) ? Key::META : Key::CTRL;
43-
return TS->format_number(rtos(get_value())) + suffix + "\n\n" + vformat(TTR("Hold %s to round to integers.\nHold Shift for more precise changes."), find_keycode_name(key));
45+
if (!editing_integer) {
46+
tooltip += "\n\n" + vformat(TTR("Hold %s to round to integers."), find_keycode_name(key));
47+
}
48+
return tooltip + "\n" + TTR("Hold Shift for more precise changes.");
4449
}
45-
return TS->format_number(rtos(get_value())) + suffix;
50+
return value;
4651
}
4752

4853
String EditorSpinSlider::get_text_value() const {
49-
return TS->format_number(String::num(get_value(), Math::range_step_decimals(get_step())));
54+
return TS->format_number(editing_integer ? itos(get_value()) : rtos(get_value()));
5055
}
5156

5257
void EditorSpinSlider::gui_input(const Ref<InputEvent> &p_event) {
@@ -109,17 +114,8 @@ void EditorSpinSlider::gui_input(const Ref<InputEvent> &p_event) {
109114
pre_grab_value = get_max();
110115
}
111116

112-
if (mm->is_command_or_control_pressed()) {
113-
// If control was just pressed, don't make the value do a huge jump in magnitude.
114-
if (grabbing_spinner_dist_cache != 0) {
115-
pre_grab_value += grabbing_spinner_dist_cache * get_step();
116-
grabbing_spinner_dist_cache = 0;
117-
}
118-
119-
set_value(Math::round(pre_grab_value + get_step() * grabbing_spinner_dist_cache * 10));
120-
} else {
121-
set_value(pre_grab_value + get_step() * grabbing_spinner_dist_cache);
122-
}
117+
double new_value = pre_grab_value + get_step() * grabbing_spinner_dist_cache;
118+
set_value((mm->is_command_or_control_pressed() && !editing_integer) ? Math::round(new_value) : new_value);
123119
}
124120
} else if (updown_offset != -1) {
125121
bool new_hover = (!is_layout_rtl() && mm->get_position().x > updown_offset) || (is_layout_rtl() && mm->get_position().x < updown_offset);
@@ -158,6 +154,7 @@ void EditorSpinSlider::_grab_end() {
158154
if (grabbing_spinner) {
159155
Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
160156
Input::get_singleton()->warp_mouse(grabbing_spinner_mouse_pos);
157+
mouse_over_grabber = true;
161158
queue_redraw();
162159
grabbing_spinner = false;
163160
emit_signal("ungrabbed");
@@ -207,7 +204,12 @@ void EditorSpinSlider::_grabber_gui_input(const Ref<InputEvent> &p_event) {
207204
grab_focus(true);
208205
emit_signal("grabbed");
209206
} else {
210-
grabbing_grabber = false;
207+
if (grabbing_grabber) {
208+
grabbing_grabber = false;
209+
if (!mouse_over_grabber) {
210+
queue_redraw();
211+
}
212+
}
211213
mousewheel_over_grabber = false;
212214
emit_signal("ungrabbed");
213215
}
@@ -377,8 +379,8 @@ void EditorSpinSlider::_draw_spin_slider() {
377379
}
378380
TS->free_rid(num_rid);
379381

380-
if (!hide_slider) {
381-
if (editing_integer) {
382+
if (control_state != CONTROL_STATE_HIDE) {
383+
if (editing_integer && control_state == CONTROL_STATE_DEFAULT) {
382384
Ref<Texture2D> updown2 = read_only ? theme_cache.updown_disabled_icon : theme_cache.updown_icon;
383385
int updown_vofs = (size.height - updown2->get_height()) / 2;
384386
if (rtl) {
@@ -427,7 +429,7 @@ void EditorSpinSlider::_draw_spin_slider() {
427429

428430
if (display_grabber) {
429431
Ref<Texture2D> grabber_tex;
430-
if (mouse_over_grabber) {
432+
if (mouse_over_grabber || grabbing_grabber) {
431433
grabber_tex = get_theme_icon(SNAME("grabber_highlight"), SNAME("HSlider"));
432434
} else {
433435
grabber_tex = get_theme_icon(SNAME("grabber"), SNAME("HSlider"));
@@ -453,7 +455,7 @@ void EditorSpinSlider::_draw_spin_slider() {
453455
void EditorSpinSlider::_notification(int p_what) {
454456
switch (p_what) {
455457
case NOTIFICATION_ENTER_TREE: {
456-
grabbing_spinner_speed = EDITOR_GET("interface/inspector/float_drag_speed");
458+
grabbing_spinner_speed = editing_integer ? EDITOR_GET("interface/inspector/integer_drag_speed") : EDITOR_GET("interface/inspector/float_drag_speed");
457459
_update_value_input_stylebox();
458460
} break;
459461

@@ -523,22 +525,35 @@ Size2 EditorSpinSlider::get_minimum_size() const {
523525
return ms;
524526
}
525527

526-
void EditorSpinSlider::set_hide_slider(bool p_hide) {
527-
hide_slider = p_hide;
528+
void EditorSpinSlider::set_control_state(ControlState p_state) {
529+
control_state = p_state;
528530
queue_redraw();
529531
}
530532

533+
EditorSpinSlider::ControlState EditorSpinSlider::get_control_state() const {
534+
return control_state;
535+
}
536+
537+
#ifndef DISABLE_DEPRECATED
538+
void EditorSpinSlider::set_hide_slider(bool p_hide) {
539+
set_control_state(p_hide ? CONTROL_STATE_HIDE : CONTROL_STATE_DEFAULT);
540+
}
541+
531542
bool EditorSpinSlider::is_hiding_slider() const {
532-
return hide_slider;
543+
return control_state == CONTROL_STATE_HIDE;
533544
}
545+
#endif
534546

535547
void EditorSpinSlider::set_editing_integer(bool p_editing_integer) {
536548
if (p_editing_integer == editing_integer) {
537549
return;
538550
}
539551

540552
editing_integer = p_editing_integer;
541-
queue_redraw();
553+
if (is_inside_tree()) {
554+
grabbing_spinner_speed = editing_integer ? EDITOR_GET("interface/inspector/integer_drag_speed") : EDITOR_GET("interface/inspector/float_drag_speed");
555+
queue_redraw();
556+
}
542557
}
543558

544559
bool EditorSpinSlider::is_editing_integer() const {
@@ -701,8 +716,12 @@ void EditorSpinSlider::_bind_methods() {
701716
ClassDB::bind_method(D_METHOD("set_flat", "flat"), &EditorSpinSlider::set_flat);
702717
ClassDB::bind_method(D_METHOD("is_flat"), &EditorSpinSlider::is_flat);
703718

719+
ClassDB::bind_method(D_METHOD("set_control_state", "state"), &EditorSpinSlider::set_control_state);
720+
ClassDB::bind_method(D_METHOD("get_control_state"), &EditorSpinSlider::get_control_state);
721+
#ifndef DISABLE_DEPRECATED
704722
ClassDB::bind_method(D_METHOD("set_hide_slider", "hide_slider"), &EditorSpinSlider::set_hide_slider);
705723
ClassDB::bind_method(D_METHOD("is_hiding_slider"), &EditorSpinSlider::is_hiding_slider);
724+
#endif
706725

707726
ClassDB::bind_method(D_METHOD("set_editing_integer", "editing_integer"), &EditorSpinSlider::set_editing_integer);
708727
ClassDB::bind_method(D_METHOD("is_editing_integer"), &EditorSpinSlider::is_editing_integer);
@@ -711,9 +730,16 @@ void EditorSpinSlider::_bind_methods() {
711730
ADD_PROPERTY(PropertyInfo(Variant::STRING, "suffix"), "set_suffix", "get_suffix");
712731
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "read_only"), "set_read_only", "is_read_only");
713732
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flat"), "set_flat", "is_flat");
733+
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "control_state"), "set_control_state", "get_control_state");
734+
#ifndef DISABLE_DEPRECATED
714735
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_slider"), "set_hide_slider", "is_hiding_slider");
736+
#endif
715737
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editing_integer"), "set_editing_integer", "is_editing_integer");
716738

739+
BIND_ENUM_CONSTANT(CONTROL_STATE_DEFAULT);
740+
BIND_ENUM_CONSTANT(CONTROL_STATE_PREFER_SLIDER);
741+
BIND_ENUM_CONSTANT(CONTROL_STATE_HIDE);
742+
717743
ADD_SIGNAL(MethodInfo("grabbed"));
718744
ADD_SIGNAL(MethodInfo("ungrabbed"));
719745
ADD_SIGNAL(MethodInfo("updown_pressed"));

editor/gui/editor_spin_slider.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,15 @@ class EditorSpinSlider : public Range {
6868
uint64_t value_input_closed_frame = 0;
6969
bool value_input_dirty = false;
7070

71-
bool hide_slider = false;
71+
public:
72+
enum ControlState {
73+
CONTROL_STATE_DEFAULT,
74+
CONTROL_STATE_PREFER_SLIDER,
75+
CONTROL_STATE_HIDE,
76+
};
77+
78+
private:
79+
ControlState control_state = CONTROL_STATE_DEFAULT;
7280
bool flat = false;
7381
bool editing_integer = false;
7482

@@ -110,8 +118,13 @@ class EditorSpinSlider : public Range {
110118
void set_suffix(const String &p_suffix);
111119
String get_suffix() const;
112120

121+
void set_control_state(ControlState p_type);
122+
ControlState get_control_state() const;
123+
124+
#ifndef DISABLE_DEPRECATED
113125
void set_hide_slider(bool p_hide);
114126
bool is_hiding_slider() const;
127+
#endif
115128

116129
void set_editing_integer(bool p_editing_integer);
117130
bool is_editing_integer() const;
@@ -130,3 +143,5 @@ class EditorSpinSlider : public Range {
130143
virtual Size2 get_minimum_size() const override;
131144
EditorSpinSlider();
132145
};
146+
147+
VARIANT_ENUM_CAST(EditorSpinSlider::ControlState)

0 commit comments

Comments
 (0)