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 =
extent2i{narrow_cast<int>(pixmap->width()), narrow_cast<int>(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 = narrow_cast<extent2i>(_glyph.get_bounding_rectangle().size() * theme<prefix>.line_height(
this));
89 }
else if (
hilet g2 = std::get_if<elusive_icon>(&
icon.read())) {
91 _icon_type = icon_type::glyph;
92 _icon_size = narrow_cast<extent2i>(_glyph.get_bounding_rectangle().size() * theme<prefix>.line_height(
this));
94 }
else if (
hilet g3 = std::get_if<hikogui_icon>(&
icon.read())) {
96 _icon_type = icon_type::glyph;
97 _icon_size = narrow_cast<extent2i>(_glyph.get_bounding_rectangle().size() * theme<prefix>.line_height(
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 = {};
118 hilet original_icon_size = narrow_cast<extent2>(_icon_size);
120 hilet icon_scale = scale2::uniform(original_icon_size, widget_size);
121 hilet new_icon_size = narrow_cast<extent2i>(icon_scale * original_icon_size);
123 hilet resolved_alignment = resolve(*
alignment, os_settings::left_to_right());
124 _icon_rectangle =
align(context.rectangle(), new_icon_size, resolved_alignment);
129 void draw(widget_draw_context& context)
noexcept override
132 switch (_icon_type) {
136 case icon_type::pixmap:
137 if (not context.draw_image(layout, _icon_rectangle, _pixmap_backing)) {
143 case icon_type::glyph:
145 context.draw_glyph(layout, _icon_rectangle, *_glyph.font, _glyph.glyph, theme<prefix>.fill_color(
this));
156 enum class icon_type { no, glyph, pixmap };
158 icon_type _icon_type;
159 font_book::font_glyph_type _glyph;
160 paged_image _pixmap_backing;
161 decltype(
icon)::callback_token _icon_cbt;
165 aarectanglei _icon_rectangle;
169 _icon_cbt =
icon.subscribe([
this](
auto...) {
170 _icon_has_modified =
true;
171 ++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:223