1 module rpui.widgets.checkbox.renderer; 2 3 import rpui.math; 4 import rpui.theme; 5 import rpui.events; 6 import rpui.widget; 7 import rpui.widgets.checkbox.widget; 8 import rpui.render.components; 9 import rpui.render.components_factory; 10 import rpui.render.renderer; 11 import rpui.render.transforms; 12 13 final class CheckboxRenderer : Renderer { 14 private StatefulUiText text; 15 private StatefulTexAtlasTextureQuad checkedBox; 16 private StatefulTexAtlasTextureQuad uncheckedBox; 17 private TexAtlasTextureQuad focusGlow; 18 private QuadTransforms boxTransforms; 19 private QuadTransforms focusGlowTransforms; 20 private UiTextTransforms textTransforms; 21 private Checkbox widget; 22 private Theme theme; 23 private vec2 focusOffsets; 24 25 private inout(State) getTextState() inout { 26 return widget.isEnter ? State.enter : State.leave; 27 } 28 29 private void updateState() { 30 text.state = getTextState(); 31 checkedBox.state = getTextState(); 32 uncheckedBox.state = getTextState(); 33 } 34 35 override void onCreate(Widget widget, in string style) { 36 this.theme = widget.view.theme; 37 this.widget = cast(Checkbox) widget; 38 39 text = createStatefulUiTextFromRdpl( 40 theme, 41 style, 42 "Text", 43 [State.leave, State.enter] 44 ); 45 46 checkedBox = createStatefulTexAtlasTextureQuadFromRdpl( 47 theme, 48 style, 49 "checkedBox", 50 [State.leave, State.enter] 51 ); 52 53 uncheckedBox = createStatefulTexAtlasTextureQuadFromRdpl( 54 theme, 55 style, 56 "uncheckedBox", 57 [State.leave, State.enter] 58 ); 59 60 focusGlow = createTexAtlasTextureQuadFromRdpl( 61 theme, 62 style, 63 "Focus.glow" 64 ); 65 66 focusOffsets = theme.tree.data.getVec2f(style ~ ".Focus.offsets"); 67 } 68 69 override void onRender() { 70 updateState(); 71 renderUiText(theme, text, textTransforms); 72 73 if (widget.checked) { 74 renderTexAtlasQuad(theme, checkedBox, boxTransforms); 75 } else { 76 renderTexAtlasQuad(theme, uncheckedBox, boxTransforms); 77 } 78 79 if (widget.isFocused) { 80 renderTexAtlasQuad(theme, focusGlow, focusGlowTransforms); 81 } 82 } 83 84 override void onProgress(in ProgressEvent event) { 85 updateText(); 86 updateBox(); 87 } 88 89 private void updateText() { 90 UiTextAttributes* textAttrs = &text.attrs[getTextState()]; 91 92 with (textAttrs) { 93 caption = widget.caption; 94 textAlign = widget.textAlign; 95 textVerticalAlign = widget.textVerticalAlign; 96 } 97 98 textTransforms = updateUiTextTransforms( 99 &text.render, 100 &theme.regularFont, 101 textTransforms, 102 *textAttrs, 103 widget.view.cameraView, 104 widget.absolutePosition + widget.innerOffsetStart, 105 widget.size 106 ); 107 108 widget.measure.textWidth = textTransforms.size.x + textAttrs.offset.x; 109 widget.measure.lineHeight = textTransforms.size.y + textAttrs.offset.y; 110 } 111 112 private void updateBox() { 113 boxTransforms = updateQuadTransforms( 114 widget.view.cameraView, 115 widget.absolutePosition, 116 uncheckedBox.texCoords[State.leave].originalTexCoords.size 117 ); 118 119 const focusPos = widget.absolutePosition + focusOffsets; 120 121 focusGlowTransforms = updateQuadTransforms( 122 widget.view.cameraView, 123 focusPos, 124 focusGlow.texCoords.originalTexCoords.size 125 ); 126 } 127 }