1 module rpui.widgets.toolbar_item.renderer;
2 
3 import rpui.math;
4 import rpui.primitives;
5 import rpui.theme;
6 import rpui.events;
7 import rpui.widget;
8 import rpui.widgets.toolbar_item.widget;
9 import rpui.render.components;
10 import rpui.render.components_factory;
11 import rpui.render.renderer;
12 import rpui.render.transforms;
13 
14 final class ToolbarItemRenderer : Renderer {
15     private StatefulUiText text;
16     private UiTextTransforms textTransforms;
17     private ToolbarItem widget;
18     private Theme theme;
19     private Geometry iconQuad;
20     private QuadTransforms iconTransforms;
21     private vec2 iconBoxSize;
22     private float[State] iconAlpha;
23 
24     override void onCreate(Widget widget, in string style) {
25         this.theme = widget.view.theme;
26         this.widget = cast(ToolbarItem) widget;
27         this.text = createStatefulUiTextFromRdpl(theme, style, "Text");
28         this.iconQuad = createGeometry();
29         this.iconBoxSize = theme.tree.data.getVec2f(style ~ ".iconBoxSize");
30         this.iconAlpha[State.leave] = theme.tree.data.getNumber(style ~ ".Leave.alpha.0") / 100f;
31         this.iconAlpha[State.enter] = theme.tree.data.getNumber(style ~ ".Enter.alpha.0") / 100f;
32         this.iconAlpha[State.click] = theme.tree.data.getNumber(style ~ ".Click.alpha.0") / 100f;
33     }
34 
35     override void onRender() {
36         auto iconsResources = widget.view.resources.icons;
37         const iconsTexture = iconsResources.getTextureForIcons(widget.iconsGroup);
38         const icon = iconsResources.getIcon(widget.iconsGroup, widget.icon);
39 
40         renderTexAtlasQuad(
41             theme,
42             iconQuad,
43             iconsTexture,
44             icon.texCoord,
45             iconTransforms,
46             iconAlpha[widget.state]
47         );
48 
49         renderUiText(theme, text.render, text.attrs[text.state], textTransforms);
50     }
51 
52     override void onProgress(in ProgressEvent event) {
53         updateText();
54         updateIcon();
55     }
56 
57     private void updateText() {
58         text.state = widget.state;
59 
60         with (text.attrs[text.state]) {
61             caption = widget.caption;
62             textVerticalAlign = VerticalAlign.bottom;
63         }
64 
65         textTransforms = updateUiTextTransforms(
66             &text.render,
67             &theme.regularFont,
68             textTransforms,
69             text.attrs[text.state],
70             widget.view.cameraView,
71             widget.absolutePosition + widget.innerOffsetStart,
72             widget.size
73         );
74     }
75 
76     private void updateIcon() {
77         auto iconsResources = widget.view.resources.icons;
78         const iconSize = iconsResources.getIconsConfig(widget.iconsGroup).size;
79 
80         const iconRelativePosition = vec2(
81             alignBox(Align.center, iconSize.x, iconBoxSize.x),
82             verticalAlignBox(VerticalAlign.middle, iconSize.y, iconBoxSize.y)
83         );
84 
85         iconTransforms = updateQuadTransforms(
86             widget.view.cameraView,
87             widget.absolutePosition + iconRelativePosition,
88             iconSize
89         );
90     }
91 }