HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
label_stencil.hpp
1// Copyright Take Vos 2020.
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
5#pragma once
6
7#include "stencil.hpp"
8#include "text_stencil.hpp"
9#include "image_stencil.hpp"
10#include "../label.hpp"
11#include "../GUI/theme.hpp"
12#include "../GUI/draw_context.hpp"
13#include <string_view>
14
15namespace tt {
16
17class label_stencil : public stencil {
18public:
19 label_stencil(alignment alignment, label label, text_style style) noexcept :
20 stencil(alignment),
21 _style(style),
22 _icon_size(_alignment == horizontal_alignment::center ? theme::global->large_icon_size : theme::global->icon_size)
23 {
24 if (label.has_icon()) {
25 _icon_stencil = stencil::make_unique(alignment::middle_center, label.icon());
26 }
27 if (label.has_text()) {
28 _text_stencil = stencil::make_unique(alignment, label.text(), style);
29 }
30 }
31
32 [[nodiscard]] f32x4 preferred_extent() noexcept override
33 {
34 if (!_text_stencil) {
35 // There is only an icon available.
36 return {_icon_size, _icon_size};
37 }
38
39 if (!_icon_stencil && !_show_icon) {
40 // There is no image, just use the text label.
41 return _text_stencil->preferred_extent();
42 }
43
44 // clang-format off
45 // When center aligned, do not include the icon width. So that the icon may go beyond the margins.
46 ttlet width =
47 _alignment == horizontal_alignment::center ? _text_stencil->preferred_extent().width() :
48 _icon_size + theme::global->margin + _text_stencil->preferred_extent().width();
49
50 // When middle aligned, do not include the icon height. So that the icon may go beyond the margins.
51 ttlet height =
52 _alignment == vertical_alignment::middle ? _text_stencil->preferred_extent().height() :
53 _icon_size + _text_stencil->preferred_extent().height();
54 // clang-format on
55
56 return {width, height};
57 }
58
71 [[nodiscard]] bool show_icon() const noexcept
72 {
73 return _show_icon;
74 }
75
78 void set_show_icon(bool flag) noexcept
79 {
80 if (_show_icon != flag) {
81 _show_icon = flag;
82 _size_is_modified = true;
83 _position_is_modified = true;
84 }
85 }
86
88 aarect const &rectangle,
89 float base_line_position = std::numeric_limits<float>::infinity()) noexcept override
90 {
91 stencil::set_layout_parameters(rectangle, base_line_position);
92
93 // clang-format off
94 ttlet icon_x =
95 _alignment == horizontal_alignment::left ? _rectangle.left() :
96 _alignment == horizontal_alignment::center ? _rectangle.center() - _icon_size * 0.5f :
97 _rectangle.right() - _icon_size;
98
99 ttlet icon_y =
100 _alignment == vertical_alignment::bottom ? _rectangle.bottom() :
101 _alignment == vertical_alignment::middle ? _rectangle.middle() - _icon_size * 0.5f :
102 _rectangle.top() - _icon_size;
103 // clang-format on
104
105
106 if (_icon_stencil) {
107 ttlet icon_rectangle = aarect{icon_x, icon_y, _icon_size, _icon_size};
108 _icon_stencil->set_layout_parameters(icon_rectangle);
109 }
110
111 if (_text_stencil) {
112 // clang-format off
113 ttlet text_width =
114 _alignment == horizontal_alignment::center ? _rectangle.width() :
115 _icon_stencil || _show_icon ? _rectangle.width() - theme::global->margin - _icon_size :
116 _rectangle.width();
117
118 ttlet text_height =
119 _alignment == vertical_alignment::middle ? _rectangle.height() :
120 _icon_stencil || _show_icon ? _rectangle.height() - _icon_size :
121 _rectangle.height();
122
123 ttlet text_x =
124 _alignment == horizontal_alignment::center ? _rectangle.center() - text_width * 0.5f :
125 _alignment == horizontal_alignment::left ? _rectangle.right() - text_width :
126 _rectangle.left();
127
128 ttlet text_y =
129 _alignment == vertical_alignment::middle ? _rectangle.middle() - text_height * 0.5f :
130 _alignment == vertical_alignment::bottom ? _rectangle.top() - text_height :
131 _rectangle.bottom();
132 // clang-format on
133
134 ttlet text_rectangle = aarect{text_x, text_y, text_width, text_height};
135 if (_alignment == horizontal_alignment::center) {
136 _text_stencil->set_layout_parameters(text_rectangle);
137 } else {
138 _text_stencil->set_layout_parameters(text_rectangle, _base_line_position);
139 }
140 }
141 }
142
143 void draw(draw_context context, bool use_context_color = false) noexcept override
144 {
145 if (_text_stencil) {
146 _text_stencil->draw(context, use_context_color);
147 }
148 if (_icon_stencil) {
149 _icon_stencil->draw(context, use_context_color);
150 }
151 }
152
153private:
154 bool _show_icon = false;
155 text_style _style;
156 float _icon_size;
157 std::unique_ptr<image_stencil> _icon_stencil;
158 std::unique_ptr<text_stencil> _text_stencil;
159};
160
161} // namespace tt
Draw context for drawing using the TTauri shaders.
Definition draw_context.hpp:33
A localized text + icon label.
Definition label.hpp:76
Definition label_stencil.hpp:17
void set_show_icon(bool flag) noexcept
Set the show_icon() flag.
Definition label_stencil.hpp:78
bool show_icon() const noexcept
Whether the text in the label will align to an optional icon in the label.
Definition label_stencil.hpp:71
void set_layout_parameters(aarect const &rectangle, float base_line_position=std::numeric_limits< float >::infinity()) noexcept override
Pass layout parameters in local coordinates.
Definition label_stencil.hpp:87
void draw(draw_context context, bool use_context_color=false) noexcept override
Draw the cell.
Definition label_stencil.hpp:143
f32x4 preferred_extent() noexcept override
Return the extent that this cell wants to be drawn as.
Definition label_stencil.hpp:32
Definition stencil.hpp:15
virtual void set_layout_parameters(aarect const &rectangle, float base_line_position=std::numeric_limits< float >::infinity()) noexcept
Pass layout parameters in local coordinates.
Definition stencil.hpp:40
Definition text_style.hpp:16