36 constexpr static auto prefix = Name /
"icon";
40 observer<icon>
icon = hi::icon{};
44 observer<alignment>
alignment = hi::alignment::middle_center();
51 void set_attributes() noexcept {}
52 void set_attributes(icon_widget_attribute
auto&& first, icon_widget_attribute
auto&&...rest)
noexcept
54 if constexpr (forward_of<
decltype(first), observer<hi::icon>>) {
56 }
else if constexpr (forward_of<
decltype(first), observer<hi::alignment>>) {
65 [[nodiscard]] box_constraints update_constraints() noexcept
override
67 if (_icon_has_modified.
exchange(
false)) {
68 _icon_type = icon_type::no;
74 _icon_type = icon_type::pixmap;
75 _icon_size =
extent2{narrow_cast<float>(pixmap->width()), narrow_cast<float>(pixmap->height())};
77 if (_pixmap_backing = paged_image{
surface, *pixmap}; not _pixmap_backing) {
79 _icon_has_modified =
true;
80 ++global_counter<
"icon_widget:no-backing-image:constrain">;
84 }
else if (
hilet g1 = std::get_if<font_book::font_glyph_type>(&
icon.read())) {
86 _icon_type = icon_type::glyph;
87 _icon_size = _glyph.get_bounding_rectangle().size() * theme<prefix>.size(
this);
89 }
else if (
hilet g2 = std::get_if<elusive_icon>(&
icon.read())) {
91 _icon_type = icon_type::glyph;
92 _icon_size = _glyph.get_bounding_rectangle().size() * theme<prefix>.size(
this);
94 }
else if (
hilet g3 = std::get_if<hikogui_icon>(&
icon.read())) {
96 _icon_type = icon_type::glyph;
97 _icon_size = _glyph.get_bounding_rectangle().size() * theme<prefix>.size(
this);
101 hilet resolved_alignment = resolve(*
alignment, os_settings::left_to_right());
102 hilet icon_constraints = box_constraints{
107 theme<prefix>.margin(
this)};
111 void set_layout(widget_layout
const& context)
noexcept override
114 if (_icon_type == icon_type::no or not _icon_size) {
115 _icon_rectangle = {};
120 hilet icon_scale = scale2::uniform(_icon_size,
extent2{narrow_cast<float>(width), narrow_cast<float>(height)});
121 hilet new_icon_size = narrow_cast<extent2i>(icon_scale * _icon_size);
122 hilet resolved_alignment = resolve(*
alignment, os_settings::left_to_right());
123 _icon_rectangle =
align(context.rectangle(), new_icon_size, resolved_alignment);
128 void draw(widget_draw_context
const& context)
noexcept override
131 switch (_icon_type) {
135 case icon_type::pixmap:
136 if (not context.draw_image(layout, _icon_rectangle, _pixmap_backing)) {
142 case icon_type::glyph:
144 context.draw_glyph(layout, _icon_rectangle, *_glyph.font, _glyph.glyph, theme<prefix>.fill_color(
this));
155 enum class icon_type { no, glyph, pixmap };
157 icon_type _icon_type;
158 font_book::font_glyph_type _glyph;
159 paged_image _pixmap_backing;
160 decltype(
icon)::callback_token _icon_cbt;
164 aarectanglei _icon_rectangle;
168 _icon_cbt =
icon.subscribe([
this](
auto...) {
169 _icon_has_modified =
true;
170 ++global_counter<
"icon_widget:icon:constrain">;
#define hi_no_default(...)
This part of the code should not be reachable, unless a programming bug.
Definition assert.hpp:279
auto find_glyph(font const &font, grapheme grapheme) noexcept
Find a glyph using the given code-point.
Definition font_book.hpp:234