53 icon_widget(Attributes&&... attributes) noexcept : icon_widget()
58 void set_attributes() noexcept {}
60 template<icon_widget_attribute First, icon_widget_attribute... Rest>
61 void set_attributes(First&& first, Rest&&... rest)
noexcept
63 if constexpr (forward_of<First, observer<hi::icon>>) {
65 }
else if constexpr (forward_of<First, observer<hi::alignment>>) {
67 }
else if constexpr (forward_of<First, observer<hi::phrasing>>) {
70 hi_static_no_default();
80 if (_icon_has_modified.exchange(
false)) {
81 _icon_type = icon_type::no;
86 if (
auto const pixmap = std::get_if<hi::pixmap<sfloat_rgba16>>(&
icon)) {
87 _icon_type = icon_type::pixmap;
90 if (not(_pixmap_backing = gfx_pipeline_image::paged_image{surface(), *pixmap})) {
92 _icon_has_modified =
true;
93 ++global_counter<
"icon_widget:no-backing-image:constrain">;
97 }
else if (
auto const g1 = std::get_if<font_glyph_ids>(&
icon)) {
99 auto const icon_style = theme().text_style_set()[{phrasing::regular}];
100 _icon_type = icon_type::glyph;
101 _icon_size = _glyph.front_glyph_metrics().bounding_rectangle.size() *
102 (icon_style.size() * theme().
pixel_density).in(unit::pixels_per_em);
104 }
else if (
auto const g2 = std::get_if<elusive_icon>(&
icon)) {
106 auto const icon_style = theme().text_style_set()[{phrasing::regular}];
107 _icon_type = icon_type::glyph;
108 _icon_size = _glyph.front_glyph_metrics().bounding_rectangle.size() *
109 (icon_style.size() * theme().
pixel_density).in(unit::pixels_per_em);
111 }
else if (
auto const g3 = std::get_if<hikogui_icon>(&
icon)) {
113 auto const icon_style = theme().text_style_set()[{phrasing::regular}];
114 _icon_type = icon_type::glyph;
115 _icon_size = _glyph.front_glyph_metrics().bounding_rectangle.size() *
116 (icon_style.size() * theme().
pixel_density).in(unit::pixels_per_em);
120 auto const resolved_alignment = resolve(*
alignment, os_settings::left_to_right());
121 auto const icon_constraints = box_constraints{
126 theme().margin<
float>()};
129 void set_layout(widget_layout
const& context)
noexcept override
132 if (_icon_type == icon_type::no or not _icon_size) {
133 _icon_rectangle = {};
135 auto const width = std::clamp(context.shape.width(),
minimum->width(),
maximum->width());
136 auto const height = std::clamp(context.shape.height(),
minimum->height(),
maximum->height());
138 auto const icon_scale =
141 auto const resolved_alignment = resolve(*
alignment, os_settings::left_to_right());
142 _icon_rectangle =
align(context.rectangle(), new_icon_size, resolved_alignment);
147 color icon_color() noexcept
149 return theme().text_style_set()[{*
phrasing}].color();
152 void draw(draw_context
const& context)
noexcept override
155 switch (_icon_type) {
159 case icon_type::pixmap:
160 if (not context.draw_image(
layout(), _icon_rectangle, _pixmap_backing)) {
166 case icon_type::glyph:
168 context.draw_glyph(
layout(), _icon_rectangle, _glyph, icon_color());
179 enum class icon_type { no, glyph, pixmap };
181 icon_type _icon_type;
182 font_glyph_ids _glyph;
183 gfx_pipeline_image::paged_image _pixmap_backing;
184 std::atomic<bool> _icon_has_modified =
true;
187 aarectangle _icon_rectangle;
189 callback<void(hi::icon)> _icon_cbt;
191 icon_widget() noexcept : super()
193 _icon_cbt =
icon.subscribe([
this](
auto...) {
194 _icon_has_modified =
true;
195 ++global_counter<
"icon_widget:icon:constrain">;