You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-04 12:00:25 +00:00
Slider: Add tick position property and tick offset theme item
Allow ticks to be placed at the top, bottom, or center with custom offset.
This commit is contained in:
@@ -23,6 +23,9 @@
|
||||
<member name="ticks_on_borders" type="bool" setter="set_ticks_on_borders" getter="get_ticks_on_borders" default="false">
|
||||
If [code]true[/code], the slider will display ticks for minimum and maximum values.
|
||||
</member>
|
||||
<member name="ticks_position" type="int" setter="set_ticks_position" getter="get_ticks_position" enum="Slider.TickPosition" default="0">
|
||||
Sets the position of the ticks. See [enum TickPosition] for details.
|
||||
</member>
|
||||
</members>
|
||||
<signals>
|
||||
<signal name="drag_ended">
|
||||
@@ -37,6 +40,20 @@
|
||||
</description>
|
||||
</signal>
|
||||
</signals>
|
||||
<constants>
|
||||
<constant name="TICK_POSITION_BOTTOM_RIGHT" value="0" enum="TickPosition">
|
||||
Places the ticks at the bottom of the [HSlider], or right of the [VSlider].
|
||||
</constant>
|
||||
<constant name="TICK_POSITION_TOP_LEFT" value="1" enum="TickPosition">
|
||||
Places the ticks at the top of the [HSlider], or left of the [VSlider].
|
||||
</constant>
|
||||
<constant name="TICK_POSITION_BOTH" value="2" enum="TickPosition">
|
||||
Places the ticks at the both sides of the slider.
|
||||
</constant>
|
||||
<constant name="TICK_POSITION_CENTER" value="3" enum="TickPosition">
|
||||
Places the ticks at the center of the slider.
|
||||
</constant>
|
||||
</constants>
|
||||
<theme_items>
|
||||
<theme_item name="center_grabber" data_type="constant" type="int" default="0">
|
||||
Boolean constant. If [code]1[/code], the grabber texture size will be ignored and it will fit within slider's bounds based only on its center position.
|
||||
@@ -44,6 +61,9 @@
|
||||
<theme_item name="grabber_offset" data_type="constant" type="int" default="0">
|
||||
Vertical or horizontal offset of the grabber.
|
||||
</theme_item>
|
||||
<theme_item name="tick_offset" data_type="constant" type="int" default="0">
|
||||
Vertical or horizontal offset of the ticks. The offset is reversed for top or left ticks.
|
||||
</theme_item>
|
||||
<theme_item name="grabber" data_type="icon" type="Texture2D">
|
||||
The texture for the grabber (the draggable element).
|
||||
</theme_item>
|
||||
|
||||
@@ -308,7 +308,19 @@ void Slider::_notification(int p_what) {
|
||||
continue;
|
||||
}
|
||||
int ofs = (i * areasize / (ticks - 1)) + grabber_offset - grabber_shift;
|
||||
tick->draw(ci, Point2i((size.width - widget_width) / 2, ofs));
|
||||
|
||||
if (ticks_position == TICK_POSITION_BOTTOM_RIGHT || ticks_position == TICK_POSITION_BOTH) {
|
||||
tick->draw(ci, Point2i(widget_width + (size.width - widget_width) / 2 + theme_cache.tick_offset, ofs));
|
||||
}
|
||||
|
||||
if (ticks_position == TICK_POSITION_TOP_LEFT || ticks_position == TICK_POSITION_BOTH) {
|
||||
Point2i pos = Point2i((size.width - widget_width) / 2 - tick->get_width() - theme_cache.tick_offset, ofs);
|
||||
tick->draw_rect(ci, Rect2i(pos, Size2i(-tick->get_width(), tick->get_height())));
|
||||
}
|
||||
|
||||
if (ticks_position == TICK_POSITION_CENTER) {
|
||||
tick->draw(ci, Point2i((size.width - tick->get_width()) / 2 + theme_cache.tick_offset, ofs));
|
||||
}
|
||||
}
|
||||
}
|
||||
grabber->draw(ci, Point2i(size.width / 2 - grabber->get_width() / 2 + theme_cache.grabber_offset, size.height - ratio * areasize - grabber->get_height() + grabber_shift));
|
||||
@@ -333,7 +345,19 @@ void Slider::_notification(int p_what) {
|
||||
continue;
|
||||
}
|
||||
int ofs = (i * areasize / (ticks - 1)) + grabber_offset + grabber_shift;
|
||||
tick->draw(ci, Point2i(ofs, (size.height - widget_height) / 2));
|
||||
|
||||
if (ticks_position == TICK_POSITION_BOTTOM_RIGHT || ticks_position == TICK_POSITION_BOTH) {
|
||||
tick->draw(ci, Point2i(ofs, widget_height + (size.height - widget_height) / 2 + theme_cache.tick_offset));
|
||||
}
|
||||
|
||||
if (ticks_position == TICK_POSITION_TOP_LEFT || ticks_position == TICK_POSITION_BOTH) {
|
||||
Point2i pos = Point2i(ofs, (size.height - widget_height) / 2 - tick->get_height() - theme_cache.tick_offset);
|
||||
tick->draw_rect(ci, Rect2i(pos, Size2i(tick->get_width(), -tick->get_height())));
|
||||
}
|
||||
|
||||
if (ticks_position == TICK_POSITION_CENTER) {
|
||||
tick->draw(ci, Point2i(ofs, (size.height - tick->get_height()) / 2 + theme_cache.tick_offset));
|
||||
}
|
||||
}
|
||||
}
|
||||
grabber->draw(ci, Point2i((rtl ? 1 - ratio : ratio) * areasize + grabber_shift, size.height / 2 - grabber->get_height() / 2 + theme_cache.grabber_offset));
|
||||
@@ -342,6 +366,12 @@ void Slider::_notification(int p_what) {
|
||||
}
|
||||
}
|
||||
|
||||
void Slider::_validate_property(PropertyInfo &p_property) const {
|
||||
if (p_property.name == "ticks_position") {
|
||||
p_property.hint_string = orientation == VERTICAL ? "Right,Left,Both,Center" : "Bottom,Top,Both,Center";
|
||||
}
|
||||
}
|
||||
|
||||
void Slider::set_custom_step(double p_custom_step) {
|
||||
custom_step = p_custom_step;
|
||||
}
|
||||
@@ -367,6 +397,10 @@ bool Slider::get_ticks_on_borders() const {
|
||||
return ticks_on_borders;
|
||||
}
|
||||
|
||||
Slider::TickPosition Slider::get_ticks_position() const {
|
||||
return ticks_position;
|
||||
}
|
||||
|
||||
void Slider::set_ticks_on_borders(bool _tob) {
|
||||
if (ticks_on_borders == _tob) {
|
||||
return;
|
||||
@@ -376,6 +410,15 @@ void Slider::set_ticks_on_borders(bool _tob) {
|
||||
queue_redraw();
|
||||
}
|
||||
|
||||
void Slider::set_ticks_position(TickPosition p_ticks_position) {
|
||||
if (ticks_position == p_ticks_position) {
|
||||
return;
|
||||
}
|
||||
|
||||
ticks_position = p_ticks_position;
|
||||
queue_redraw();
|
||||
}
|
||||
|
||||
void Slider::set_editable(bool p_editable) {
|
||||
if (editable == p_editable) {
|
||||
return;
|
||||
@@ -405,6 +448,9 @@ void Slider::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_ticks_on_borders"), &Slider::get_ticks_on_borders);
|
||||
ClassDB::bind_method(D_METHOD("set_ticks_on_borders", "ticks_on_border"), &Slider::set_ticks_on_borders);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_ticks_position"), &Slider::get_ticks_position);
|
||||
ClassDB::bind_method(D_METHOD("set_ticks_position", "ticks_on_border"), &Slider::set_ticks_position);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_editable", "editable"), &Slider::set_editable);
|
||||
ClassDB::bind_method(D_METHOD("is_editable"), &Slider::is_editable);
|
||||
ClassDB::bind_method(D_METHOD("set_scrollable", "scrollable"), &Slider::set_scrollable);
|
||||
@@ -417,6 +463,12 @@ void Slider::_bind_methods() {
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scrollable"), "set_scrollable", "is_scrollable");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "tick_count", PROPERTY_HINT_RANGE, "0,4096,1"), "set_ticks", "get_ticks");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ticks_on_borders"), "set_ticks_on_borders", "get_ticks_on_borders");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "ticks_position", PROPERTY_HINT_ENUM), "set_ticks_position", "get_ticks_position");
|
||||
|
||||
BIND_ENUM_CONSTANT(TICK_POSITION_BOTTOM_RIGHT);
|
||||
BIND_ENUM_CONSTANT(TICK_POSITION_TOP_LEFT);
|
||||
BIND_ENUM_CONSTANT(TICK_POSITION_BOTH);
|
||||
BIND_ENUM_CONSTANT(TICK_POSITION_CENTER);
|
||||
|
||||
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, Slider, slider_style, "slider");
|
||||
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, Slider, grabber_area_style, "grabber_area");
|
||||
@@ -429,6 +481,7 @@ void Slider::_bind_methods() {
|
||||
|
||||
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Slider, center_grabber);
|
||||
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Slider, grabber_offset);
|
||||
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Slider, tick_offset);
|
||||
}
|
||||
|
||||
Slider::Slider(Orientation p_orientation) {
|
||||
|
||||
@@ -35,6 +35,15 @@
|
||||
class Slider : public Range {
|
||||
GDCLASS(Slider, Range);
|
||||
|
||||
public:
|
||||
enum TickPosition {
|
||||
TICK_POSITION_BOTTOM_RIGHT,
|
||||
TICK_POSITION_TOP_LEFT,
|
||||
TICK_POSITION_BOTH,
|
||||
TICK_POSITION_CENTER,
|
||||
};
|
||||
|
||||
private:
|
||||
struct Grab {
|
||||
int pos = 0;
|
||||
double uvalue = 0.0; // Value at `pos`.
|
||||
@@ -43,6 +52,8 @@ class Slider : public Range {
|
||||
} grab;
|
||||
|
||||
int ticks = 0;
|
||||
TickPosition ticks_position = TICK_POSITION_BOTTOM_RIGHT;
|
||||
|
||||
bool mouse_inside = false;
|
||||
Orientation orientation;
|
||||
double custom_step = -1.0;
|
||||
@@ -65,6 +76,7 @@ class Slider : public Range {
|
||||
|
||||
bool center_grabber = false;
|
||||
int grabber_offset = 0;
|
||||
int tick_offset = 0;
|
||||
} theme_cache;
|
||||
|
||||
protected:
|
||||
@@ -72,6 +84,7 @@ protected:
|
||||
|
||||
virtual void gui_input(const Ref<InputEvent> &p_event) override;
|
||||
void _notification(int p_what);
|
||||
void _validate_property(PropertyInfo &p_property) const;
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
@@ -86,6 +99,9 @@ public:
|
||||
void set_ticks_on_borders(bool);
|
||||
bool get_ticks_on_borders() const;
|
||||
|
||||
void set_ticks_position(TickPosition p_ticks_position);
|
||||
TickPosition get_ticks_position() const;
|
||||
|
||||
void set_editable(bool p_editable);
|
||||
bool is_editable() const;
|
||||
|
||||
@@ -95,6 +111,8 @@ public:
|
||||
Slider(Orientation p_orientation = VERTICAL);
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(Slider::TickPosition);
|
||||
|
||||
class HSlider : public Slider {
|
||||
GDCLASS(HSlider, Slider);
|
||||
|
||||
|
||||
@@ -588,6 +588,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
|
||||
|
||||
theme->set_constant("center_grabber", "HSlider", 0);
|
||||
theme->set_constant("grabber_offset", "HSlider", 0);
|
||||
theme->set_constant("tick_offset", "HSlider", 0);
|
||||
|
||||
// VSlider
|
||||
|
||||
@@ -602,6 +603,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
|
||||
|
||||
theme->set_constant("center_grabber", "VSlider", 0);
|
||||
theme->set_constant("grabber_offset", "VSlider", 0);
|
||||
theme->set_constant("tick_offset", "VSlider", 0);
|
||||
|
||||
// SpinBox
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="4" height="16"><path fill="#fff" fill-opacity=".25" d="M1 0h2v16H1z"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="4" height="8"><path fill="#fff" fill-opacity=".25" d="M1 0h2v16H1z"/></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 124 B After Width: | Height: | Size: 123 B |
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="4"><path fill="#fff" fill-opacity=".25" d="M0 3V1h16v2z"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="4"><path fill="#fff" fill-opacity=".25" d="M0 3V1h16v2z"/></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 124 B After Width: | Height: | Size: 123 B |
Reference in New Issue
Block a user