HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
toolbar_tab_button_widget.hpp
Go to the documentation of this file.
1// Copyright Take Vos 2021-2022.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
9#pragma once
10
12
13namespace hi { inline namespace v1 {
14
46template<fixed_string Name = "">
47class toolbar_tab_button_widget final : public abstract_button_widget<Name / "toolbar-tab-button"> {
48public:
49 using super = abstract_button_widget<Name / "toolbar-tab-button">;
50 using delegate_type = typename super::delegate_type;
51
64 button_widget_attribute auto&&...attributes) noexcept :
66 {
67 this->alignment = alignment::top_center();
68 this->set_attributes<0>(hi_forward(attributes)...);
69 }
70
83 template<
84 different_from<std::shared_ptr<delegate_type>> Value,
85 forward_of<observer<observer_decay_t<Value>>> OnValue,
86 button_widget_attribute... Attributes>
87 toolbar_tab_button_widget(widget *parent, Value&& value, OnValue&& on_value, Attributes&&...attributes) noexcept
88 requires requires { make_default_radio_button_delegate(hi_forward(value), hi_forward(on_value)); }
89 :
91 parent,
93 hi_forward(attributes)...)
94 {
95 }
96
97 void request_redraw() const noexcept override
98 {
99 // A toolbar tab button draws a focus line across the whole toolbar
100 // which is beyond it's own clipping rectangle. The parent is the toolbar
101 // so it will include everything that needs to be redrawn.
102 if (this->parent != nullptr) {
103 this->parent->request_redraw();
104 } else {
106 }
107 }
108
110 [[nodiscard]] box_constraints update_constraints() noexcept override
111 {
112 _label_constraints = super::update_constraints();
113
114 // On left side a check mark, on right side short-cut. Around the label extra margin.
115 hilet extra_size =
116 extent2{theme<super::prefix>.margin_right(this) * 2, theme<super::prefix>.margin_top(this)};
117 return _label_constraints + extra_size;
118 }
119
120 void set_layout(widget_layout const& context) noexcept override
121 {
122 if (compare_store(this->layout, context)) {
123 hilet label_rectangle = aarectangle{
124 theme<super::prefix>.margin_right(this),
125 0.0f,
126 context.width() - theme<super::prefix>.margin_right(this) * 2,
127 context.height() - theme<super::prefix>.margin_top(this)};
128 this->_on_label_shape = this->_off_label_shape = this->_other_label_shape =
129 box_shape{_label_constraints, label_rectangle, theme<super::prefix>.cap_height(this)};
130 }
131 super::set_layout(context);
132 }
133
134 void draw(widget_draw_context& context) noexcept override
135 {
136 if (*this->mode > widget_mode::invisible and overlaps(context, this->layout)) {
137 draw_toolbar_tab_button(context);
138 this->draw_button(context);
139 }
140 }
141 [[nodiscard]] bool accepts_keyboard_focus(keyboard_focus_group group) const noexcept override
142 {
143 return *this->mode >= widget_mode::partial and to_bool(group & hi::keyboard_focus_group::toolbar);
144 }
145
146 [[nodiscard]] bool is_tab_button() const noexcept override
147 {
148 return true;
149 }
151private:
152 box_constraints _label_constraints;
153
154 void draw_toolbar_tab_button(widget_draw_context& context) noexcept
155 {
156 // Draw the outline of the button across the clipping rectangle to clip the
157 // bottom of the outline.
158 hilet offset = theme<super::prefix>.margin_bottom(this) + theme<super::prefix>.border_width(this);
159 hilet outline_rectangle = aarectangle{0.0f, -offset, this->layout.width(), this->layout.height() + offset};
160
161 // The focus line will be drawn by the parent widget (toolbar_widget) at 0.5.
162 hilet button_z = *this->focus ? translate_z(0.6f) : translate_z(0.0f);
163
164 context.draw_box(
165 this->layout,
166 button_z * narrow_cast<aarectangle>(outline_rectangle),
167 theme<super::prefix>.background_color(this),
168 theme<super::prefix>.border_color(this),
169 theme<super::prefix>.border_width(this),
171 theme<super::prefix>.border_radius(this));
172 }
173};
174
175}} // namespace hi::v1
Defines abstract_button_widget.
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
#define hi_forward(x)
Forward a value, based on the decltype of the value.
Definition utility.hpp:29
std::shared_ptr< radio_button_delegate > make_default_radio_button_delegate(auto &&value, auto &&...args) noexcept
Make a shared pointer to a toggle-button delegate.
Definition radio_button_delegate.hpp:113
@ partial
A widget is partially enabled.
@ invisible
The widget is invisible.
DOXYGEN BUG.
Definition algorithm.hpp:13
geometry/margins.hpp
Definition cache.hpp:11
@ inside
The border is drawn inside the edge of a quad.
bool compare_store(T &lhs, U &&rhs) noexcept
Compare then store if there was a change.
Definition utility.hpp:212
Definition widget.hpp:26
virtual void request_redraw() const noexcept
Request the widget to be redrawn on the next frame.
Definition widget.hpp:227
widget * parent
Pointer to the parent widget.
Definition widget.hpp:40
observer< widget_mode > mode
The widget mode.
Definition widget.hpp:49
observer< bool > focus
The widget has keyboard focus.
Definition widget.hpp:61
2D constraints.
Definition box_constraints.hpp:22
Base class for implementing button widgets.
Definition abstract_button_widget.hpp:33
observer< hi::alignment > alignment
The alignment of the button and on/off/other label.
Definition abstract_button_widget.hpp:58
std::shared_ptr< delegate_type > delegate
The delegate that controls the button widget.
Definition abstract_button_widget.hpp:42
A button delegate controls the state of a button widget.
Definition button_delegate.hpp:23
A graphical control element that allows the user to choose only one of a predefined set of mutually e...
Definition toolbar_tab_button_widget.hpp:47
void request_redraw() const noexcept override
Request the widget to be redrawn on the next frame.
Definition toolbar_tab_button_widget.hpp:97
toolbar_tab_button_widget(widget *parent, std::shared_ptr< delegate_type > delegate, button_widget_attribute auto &&...attributes) noexcept
Construct a toolbar tab button widget.
Definition toolbar_tab_button_widget.hpp:61
toolbar_tab_button_widget(widget *parent, Value &&value, OnValue &&on_value, Attributes &&...attributes) noexcept
Construct a toolbar tab button widget with a default button delegate.
Definition toolbar_tab_button_widget.hpp:87
Definition abstract_button_widget.hpp:26
T move(T... args)