1 module rpui.render.components;
2 
3 import std.algorithm;
4 
5 import gapi.geometry;
6 import gapi.geometry_quad;
7 import gapi.texture;
8 import gapi.shader;
9 import gapi.vec;
10 import gapi.transform;
11 import gapi.text;
12 import gapi.font;
13 
14 import rpui.primitives;
15 
16 struct CameraView {
17     mat4 mvpMatrix;
18     float viewportWidth;
19     float viewportHeight;
20     float scaleX;
21     float scaleY;
22 
23     @property inout(float) fontScale() inout { return scaleY; }
24 }
25 
26 struct Geometry {
27     Buffer indicesBuffer;
28     Buffer verticesBuffer;
29     Buffer texCoordsBuffer;
30 
31     VAO vao;
32 }
33 
34 struct LinesGeometry {
35     Buffer indicesBuffer;
36     Buffer verticesBuffer;
37     uint pointsCount;
38 
39     VAO vao;
40 }
41 
42 struct QuadTransforms {
43     Transform2D transform;
44     mat4 modelMatrix;
45     mat4 mvpMatrix;
46 }
47 
48 struct LinesTransforms {
49     Transform2D transform;
50     mat4 modelMatrix;
51     mat4 mvpMatrix;
52 }
53 
54 // TODO(Andrey): Rename to ChainTransforms
55 struct HorizontalChainTransforms {
56     QuadTransforms[ChainPart] quadTransforms;
57 }
58 
59 struct TextureQuad {
60     Geometry geometry;
61     Texture2D texture;
62 }
63 
64 struct TexAtlasTextureQuad {
65     Geometry geometry;
66     Texture2D texture;
67     OriginalWithNormilizedTextureCoords texCoords;
68 }
69 
70 struct StatefulTexAtlasTextureQuad {
71     Geometry geometry;
72     Texture2D texture;
73     OriginalWithNormilizedTextureCoords[State] texCoords;
74     State state;
75 
76     @property inout(OriginalWithNormilizedTextureCoords) currentTexCoords() inout {
77         return texCoords[state];
78     }
79 }
80 
81 struct OriginalWithNormilizedTextureCoords {
82     Texture2DCoords originalTexCoords;
83     Texture2DCoords normilizedTexCoords;
84 }
85 
86 struct StatefulChain {
87     TextureQuad[ChainPart] parts;
88     float[ChainPart] widths;
89     Texture2DCoords[ChainPart][State] texCoords;
90     State state;
91 }
92 
93 struct Chain {
94     TextureQuad[ChainPart] parts;
95     float[ChainPart] widths;
96     float height;
97     Texture2DCoords[ChainPart] texCoords;
98 }
99 
100 struct Block {
101     float[ChainPart][BlockRow] widths;
102     float[BlockRow] heights;
103 
104     Chain topChain;
105     Chain middleChain;
106     Chain bottomChain;
107 }
108 
109 struct BlockTransforms {
110     HorizontalChainTransforms topChain;
111     HorizontalChainTransforms middleChain;
112     HorizontalChainTransforms bottomChain;
113 }
114 
115 struct UiTextRender {
116     Geometry geometry;
117     Text text;
118     Texture2D texture;
119 }
120 
121 struct StatefulUiText {
122     UiTextRender render;
123     UiTextAttributes[State] attrs;
124     State state;
125 }
126 
127 struct UiText {
128     UiTextRender render;
129     UiTextAttributes attrs;
130 }
131 
132 struct UiTextAttributes {
133     vec4 color;
134     vec2 offset;
135     int fontSize;
136     dstring caption;
137     Align textAlign = Align.center;
138     VerticalAlign textVerticalAlign = VerticalAlign.middle;
139     Font font;
140 }
141 
142 struct UiTextTransforms {
143     vec2 size;
144     vec2 relativePosition;
145     mat4 mvpMatrix;
146     dstring cachedString = "";
147 }
148 
149 enum State {
150     leave,
151     enter,
152     click,
153 }
154 
155 enum ChainPart {
156     left,
157     center,
158     right,
159     top,
160     middle,
161     bottom,
162 }
163 
164 enum BlockRow {
165     top,
166     middle,
167     bottom,
168 }
169 
170 immutable horizontalChainParts = [
171     ChainPart.left,
172     ChainPart.center,
173     ChainPart.right,
174 ];
175 
176 immutable verticalChainParts = [
177     ChainPart.top,
178     ChainPart.middle,
179     ChainPart.bottom,
180 ];
181 
182 string getStateRdplName(in State state) {
183     switch (state) {
184         case State.leave:
185             return "Leave";
186 
187         case State.enter:
188             return "Enter";
189 
190         case State.click:
191             return "Click";
192 
193         default:
194             throw new Error("Unknown state");
195     }
196 }
197 
198 string getChainPartRdplName(in ChainPart part) {
199     switch (part) {
200         case ChainPart.left:
201             return "left";
202 
203         case ChainPart.center:
204             return "center";
205 
206         case ChainPart.right:
207             return "right";
208 
209         case ChainPart.top:
210             return "top";
211 
212         case ChainPart.middle:
213             return "middle";
214 
215         case ChainPart.bottom:
216             return "bottom";
217 
218         default:
219             throw new Error("Unknown part");
220     }
221 }