8#include "../GUI/draw_context.hpp"
9#include "../observable.hpp"
18template<
bool IsVertical>
23 static constexpr bool is_vertical = IsVertical;
25 template<
typename Content,
typename Aperture,
typename Offset>
31 Offset &&offset) noexcept :
33 content(std::forward<Content>(content)),
34 aperture(std::forward<Aperture>(aperture)),
35 offset(std::forward<Offset>(offset))
37 _content_callback = this->content.subscribe([
this](
auto...) {
40 _aperture_callback = this->aperture.subscribe([
this](
auto...) {
43 _offset_callback = this->offset.subscribe([
this](
auto...) {
55 ttlet minimum_length = theme::global->width;
57 if constexpr (is_vertical) {
59 f32x4{theme::global->scroll_bar_thickness, minimum_length},
63 f32x4{minimum_length, theme::global->scroll_bar_thickness},
67 _preferred_base_line = {};
78 need_layout |= std::exchange(_request_relayout,
false);
80 tt_axiom(*content != 0.0f);
83 ttlet slider_offset = *offset * travel_vs_hidden_content_ratio();
85 if constexpr (is_vertical) {
102 draw_slider(context);
109 ttlet lock = std::scoped_lock(gui_system_mutex);
110 ttlet position = _from_window_transform * window_position;
113 return hit_box{weak_from_this(), _draw_layer};
121 ttlet lock = std::scoped_lock(gui_system_mutex);
124 if (event.cause.leftButton) {
127 switch (event.type) {
128 using enum mouse_event::Type;
131 offset_before_drag = *offset;
137 ttlet slider_movement = is_vertical ?
event.delta().y() :
event.delta().x();
138 ttlet content_movement = slider_movement * hidden_content_vs_travel_ratio();
139 offset = offset_before_drag + content_movement;
159 return hidden_content() >= 1.0f;
167 typename decltype(offset)::callback_ptr_type _offset_callback;
168 typename decltype(aperture)::callback_ptr_type _aperture_callback;
169 typename decltype(content)::callback_ptr_type _content_callback;
173 float offset_before_drag;
175 [[nodiscard]]
float rail_length() const noexcept
181 [[nodiscard]]
float slider_length() const noexcept
185 ttlet content_aperture_ratio = *aperture / *content;
186 return std::max(rail_length() * content_aperture_ratio, theme::global->smallSize * 2.0f);
191 [[nodiscard]]
float slider_travel_range() const noexcept
194 return rail_length() - slider_length();
199 [[nodiscard]]
float hidden_content() const noexcept
202 return *content - *aperture;
209 [[nodiscard]]
float hidden_content_vs_travel_ratio() const noexcept
213 ttlet _slider_travel_range = slider_travel_range();
214 return _slider_travel_range != 0.0f ? hidden_content() / _slider_travel_range : 0.0f;
221 [[nodiscard]]
float travel_vs_hidden_content_ratio() const noexcept
225 ttlet _hidden_content = hidden_content();
226 return _hidden_content != 0.0f ? slider_travel_range() / _hidden_content : 0.0f;
229 void draw_rails(draw_context context)
noexcept
233 context.line_color = theme::global->fillColor(_semantic_layer);
234 context.fill_color = theme::global->fillColor(_semantic_layer);
235 if constexpr (is_vertical) {
236 context.corner_shapes = f32x4::broadcast(
rectangle().width() * 0.5f);
238 context.corner_shapes = f32x4::broadcast(
rectangle().height() * 0.5f);
240 context.draw_box_with_border_inside(
rectangle());
243 void draw_slider(draw_context context)
noexcept
247 context.line_color = theme::global->fillColor(_semantic_layer + 1);
248 context.fill_color = theme::global->fillColor(_semantic_layer + 1);
249 context.transform = translate3{0.0f, 0.0f, 0.1f} * context.transform;
250 if constexpr (is_vertical) {
251 context.corner_shapes = f32x4::broadcast(slider_rectangle.width() * 0.5f);
253 context.corner_shapes = f32x4::broadcast(slider_rectangle.height() * 0.5f);
255 context.draw_box_with_border_inside(slider_rectangle);
bool contains(numeric_array< T, 4 > const &rhs) const noexcept
Check if a 2D coordinate is inside the rectangle.
Definition aarect.hpp:300
Draw context for drawing using the TTauri shaders.
Definition draw_context.hpp:33
Definition gui_window.hpp:39
std::atomic< bool > requestLayout
When set to true the widgets will be layed out.
Definition gui_window.hpp:56
Definition hit_box.hpp:15
Definition mouse_event.hpp:13
A 2D vector using interval arithmetic.
Definition interval_vec2.hpp:18
Definition observable.hpp:20
int recurse_lock_count() const noexcept
This function should be used in tt_axiom() to check if the lock is held by current thread.
Definition unfair_recursive_mutex.hpp:60
Definition scroll_bar_widget.hpp:19
bool accepts_keyboard_focus(keyboard_focus_group group) const noexcept override
Check if the widget will accept keyboard focus.
Definition scroll_bar_widget.hpp:148
hit_box hitbox_test(f32x4 window_position) const noexcept override
Find the widget that is under the mouse cursor.
Definition scroll_bar_widget.hpp:107
void draw(draw_context context, hires_utc_clock::time_point display_time_point) noexcept override
Draw the widget.
Definition scroll_bar_widget.hpp:96
bool update_constraints(hires_utc_clock::time_point display_time_point, bool need_reconstrain) noexcept override
Update the constraints of the widget.
Definition scroll_bar_widget.hpp:50
void update_layout(hires_utc_clock::time_point display_time_point, bool need_layout) noexcept override
Update the internal layout of the widget.
Definition scroll_bar_widget.hpp:74
bool visible() const noexcept
Is the scrollbar visible.
Definition scroll_bar_widget.hpp:157
bool handle_event(mouse_event const &event) noexcept
Definition scroll_bar_widget.hpp:119
virtual void update_layout(hires_utc_clock::time_point display_time_point, bool need_layout) noexcept
Update the internal layout of the widget.
widget(gui_window &window, std::shared_ptr< abstract_container_widget > parent) noexcept
virtual bool handle_event(command command) noexcept
Handle command.
gui_window & window
Convenient reference to the Window.
Definition widget.hpp:100
virtual void draw(draw_context context, hires_utc_clock::time_point display_time_point) noexcept
Draw the widget.
Definition widget.hpp:460
virtual bool update_constraints(hires_utc_clock::time_point display_time_point, bool need_reconstrain) noexcept
Update the constraints of the widget.
abstract_container_widget const & parent() const noexcept
Get a reference to the parent.
virtual aarect window_clipping_rectangle() const noexcept
Get the clipping-rectangle in window coordinates.
Definition widget.hpp:320
aarect rectangle() const noexcept
Get the rectangle in local coordinates.
Definition widget.hpp:340