1 module rpui.widgets.text_input.render_system; 2 3 import std.container.array; 4 5 import rpui.widgets.text_input.widget; 6 import rpui.widgets.text_input.transforms_system; 7 import rpui.render.components_factory; 8 import rpui.render.components; 9 import rpui.render.renderer; 10 import rpui.theme; 11 import rpui.math; 12 import rpui.primitives; 13 14 import gapi.texture; 15 16 struct RenderData { 17 StatefulChain background; 18 Chain focusGlow; 19 TexAtlasTextureQuad carriage; 20 StatefulTexAtlasTextureQuad leftArrow; 21 StatefulTexAtlasTextureQuad rightArrow; 22 StatefulUiText text; 23 StatefulUiText prefix; 24 StatefulUiText postfix; 25 Geometry selectRegion; 26 vec4 selectRegionColor; 27 vec4 selectedTextColor; 28 } 29 30 final class TextInputRenderSystem : RenderSystem { 31 private TextInput widget; 32 private Theme theme; 33 private RenderTransforms* transforms; 34 private RenderData* renderData; 35 36 this(TextInput widget, RenderData* renderData, RenderTransforms* transforms) { 37 this.widget = widget; 38 this.theme = widget.view.theme; 39 this.transforms = transforms; 40 this.renderData = renderData; 41 } 42 43 override void onRender() { 44 renderBackground(); 45 renderPrefix(); 46 renderPostfix(); 47 pushScissor(); 48 renderText(); 49 renderSoftPostfix(); 50 renderSelectRegion(); 51 renderSelectedText(); 52 widget.view.popScissor(); 53 renderArrows(); 54 renderCarriage(); 55 } 56 57 private void pushScissor() { 58 with (widget) { 59 Rect scissor; 60 61 const leftMargin = measure.textLeftMargin + widget.measure.prefixWidth; 62 const rightMargin = measure.textRightMargin + widget.measure.postfixWidth; 63 64 scissor.point = vec2( 65 absolutePosition.x + leftMargin, 66 absolutePosition.y 67 ); 68 scissor.size = vec2( 69 size.x - leftMargin - rightMargin, 70 size.y 71 ); 72 73 view.pushScissor(scissor); 74 } 75 } 76 77 private void renderBackground() { 78 renderData.background.state = widget.state; 79 80 renderHorizontalChain( 81 theme, 82 renderData.background, 83 transforms.background, 84 widget.partDraws 85 ); 86 87 if (widget.focusable && widget.isFocused) { 88 renderHorizontalChain( 89 theme, 90 renderData.focusGlow, 91 transforms.focusGlow, 92 widget.partDraws 93 ); 94 } 95 } 96 97 private void renderArrows() { 98 if (!widget.isNumberMode()) 99 return; 100 101 renderTexAtlasQuad( 102 theme, 103 renderData.leftArrow, 104 transforms.leftArrow 105 ); 106 107 renderTexAtlasQuad( 108 theme, 109 renderData.rightArrow, 110 transforms.rightArrow 111 ); 112 } 113 114 private void renderCarriage() { 115 if (!widget.isFocused) 116 return; 117 118 if (widget.editComponent.carriage.visible) { 119 renderTexAtlasQuad( 120 theme, 121 renderData.carriage, 122 transforms.carriage 123 ); 124 } 125 } 126 127 private void renderPrefix() { 128 if (widget.prefix != "") { 129 renderData.prefix.state = widget.state; 130 renderUiText(theme, renderData.prefix, transforms.prefix); 131 } 132 } 133 134 private void renderPostfix() { 135 if (widget.postfix != "" && !widget.softPostfix) { 136 renderData.postfix.state = widget.state; 137 renderUiText(theme, renderData.postfix, transforms.postfix); 138 } 139 } 140 141 private void renderSoftPostfix() { 142 if (widget.postfix != "" && widget.softPostfix) { 143 renderData.postfix.state = widget.state; 144 renderUiText(theme, renderData.postfix, transforms.postfix); 145 } 146 } 147 148 private void renderText() { 149 renderData.text.state = widget.state; 150 renderUiText(theme, renderData.text, transforms.text); 151 } 152 153 private void renderSelectedText() { 154 if (!widget.editComponent.selectRegion.textIsSelected()) 155 return; 156 157 const scissor = Rect( 158 widget.editComponent.selectRegion.absolutePosition, 159 widget.editComponent.selectRegion.size 160 ); 161 162 widget.view.pushScissor(scissor); 163 auto attrs = renderData.text.attrs[widget.state]; 164 attrs.color = renderData.selectedTextColor; 165 166 renderUiText( 167 theme, 168 renderData.text.render, 169 attrs, 170 transforms.text 171 ); 172 173 widget.view.popScissor(); 174 } 175 176 private void renderSelectRegion() { 177 if (!widget.editComponent.selectRegion.textIsSelected()) 178 return; 179 180 renderColorQuad( 181 theme, 182 renderData.selectRegion, 183 renderData.selectRegionColor, 184 transforms.selectRegion 185 ); 186 } 187 }