1 module demo.panels;
2 
3 import std.stdio;
4 
5 import window;
6 import rawgfx;
7 
8 import dg2d;
9 
10 import std.random;
11 
12 Font gfx_font;
13 
14 static this()
15 {
16     gfx_font = loadFont(rawfont);
17 }
18 
19 /* ============================================================================ */
20 
21 class GFXPanel : Widget
22 {
23     string getInfo() { return ""; }
24 
25     this(int x,int y, int w, int h)
26     {
27         super(x,y,w,h);
28     }
29 }
30 
31 /* ============================================================================ */
32 
33 RoundRect randomRoundRect(ref Random rnd)
34 {   
35     float x = uniform(120.0f, 680.0f, rnd);
36     float y = uniform(120.0f, 680.0f, rnd);
37     float w = uniform(12.0f, 100.0f, rnd);
38     float h = uniform(12.0f, 100.0f, rnd);
39     float c = uniform(2.0f, ((w<h) ? w : h)/2, rnd);
40     return RoundRect(x-w,y-h,x+w,y+h,c,c);
41 }
42 
43 /* ============================================================================ */
44 
45 Path buildTextPath(Font font, const char[] txt)
46 {
47     Path path;
48     float[] adv;
49     adv.length = txt.length;
50     font.getTextSpacing(txt,adv);
51 
52     int i;
53     int subi = 0;
54     float subx = 50, y = 50;
55     float pos = subx;
56 
57     for (i = 0; i < txt.length; i++)
58     {
59         if ((txt[i] == ' ') || (txt[i] == '\n'))
60         {
61             for (int k = subi; k <= i; k++)
62             {
63                 font.addChar(path, subx, y, txt[k]);
64                 subx += adv[k];
65             }
66             subi = i+1;
67         }
68 
69         if ((pos > 750) || (txt[i] == '\n'))
70         {
71             pos = 50+pos-subx;
72             subx = 50;
73             y += font.lineHeight();
74         }
75 
76         if (y > 750) return path;
77 
78         pos += adv[i];
79     }
80     return path;
81 }
82 
83 /* ============================================================================ */
84 
85 class SolidPanel1 : GFXPanel
86 {
87     
88 	override void onPaint(Canvas canvas)
89   	{
90         auto rnd = Random(1234); 
91         foreach(i; 0..rects.length)
92         {
93             canvas.draw(
94                 rects[i].asPath.append(rects[i].inset(8).asPath.retro),
95                 uniform(0, 0xFFFFFFFF, rnd) | 0xff000000,
96                 WindingRule.NonZero
97                 );
98         }
99     }
100 
101     override void onMouse(MouseMsg msg)
102     {
103     } 
104 
105     this()
106     {
107         super(0,0,800,800);
108         auto rnd = Random(42);
109         foreach(i; 0..rects.length)
110         {
111             retry:
112                 rects[i] = randomRoundRect(rnd);
113                 auto osr = rects[i].outset(8);
114                 foreach(q; 0..i)
115                     if (!intersect(osr,rects[q]).isEmpty) goto retry; 
116         }
117 
118     }
119 
120     override string getInfo()
121     {
122         return "Solid color";
123     }
124 
125     RoundRect[40] rects;
126 }
127 
128 /* ============================================================================ */
129 
130 class SolidPanel2 : GFXPanel
131 {
132     
133 	override void onPaint(Canvas canvas)
134   	{
135         auto rnd = Random(1234); 
136         canvas.draw(
137            path, 0xFFFFFFFF, WindingRule.NonZero
138            );
139     }
140 
141     override void onMouse(MouseMsg msg)
142     {
143     } 
144 
145     this()
146     {
147         super(0,0,800,800);
148         gfx_font.setSize(20);
149         path = buildTextPath(gfx_font, loremIpsum);
150     }
151 
152     override string getInfo()
153     {
154         return "Solid text";
155     }
156 
157     Path path;
158 }
159 
160 /* ============================================================================ */
161 
162 class LinearPanel1 : GFXPanel
163 {
164     
165 	override void onPaint(Canvas canvas)
166   	{
167         canvas.draw(
168             path,
169             LinearGradient(p0.x,p0.y,p1.x,p1.y,grad,RepeatMode.Pad),
170             WindingRule.NonZero
171             );
172     }
173 
174     override void onMouse(MouseMsg msg)
175     {
176         if (msg.left == true)
177         {
178             p0.x = msg.x;
179             p0.y = msg.y;
180             repaint();
181         }
182 
183         if (msg.right == true)
184         {
185             p1.x = msg.x;
186             p1.y = msg.y;
187             repaint();
188         }
189     }   
190 
191     this()
192     {
193         super(0,0,800,800);
194         auto rnd = Random(588);
195         RoundRect[50] rects;
196 
197         foreach(i; 0..rects.length)
198         {
199             retry:
200                 rects[i] = randomRoundRect(rnd);
201                 auto osr = rects[i].outset(6);
202                 foreach(q; 0..i)
203                     if (!intersect(osr,rects[q]).isEmpty) goto retry;
204                 path.append(rects[i].asPath);
205         }
206 
207         grad = new Gradient(256);       
208         grad.initEqualSpaced(0xFFffff00,0xff00ffff,0xFFff00ff,0xFF80ff80);
209     }
210 
211     override string getInfo()
212     {
213         return "Linear gradient";
214     }
215 
216     Point p0 = [300,300];
217     Point p1 = [700,700];
218     Path path;
219     Gradient grad;
220 }
221 
222 /* ============================================================================ */
223 
224 class AngularPanel1 : GFXPanel
225 {
226 	override void onPaint(Canvas canvas)
227   	{
228         canvas.draw(
229             path,
230             AngularGradient(400,400,p0.x,p0.y,p1.x,p1.y,1,grad,RepeatMode.Repeat),
231             WindingRule.EvenOdd
232             );
233     }
234 
235     override void onMouse(MouseMsg msg)
236     {
237         if (msg.left == true)
238         {
239             p0.x = msg.x;
240             p0.y = msg.y;
241             repaint();
242         }
243 
244         if (msg.right == true)
245         {
246             p1.x = msg.x;
247             p1.y = msg.y;
248             repaint();
249         }
250     }   
251 
252     this()
253     {
254         super(0,0,800,800);
255         
256         grad = new Gradient(256);       
257         grad.initEqualSpaced(0xFFff0000,0xff00ff00,0xFF0000ff,0xffffffff);
258 
259         path = Path();
260 
261         path.moveTo(-400,0);
262         foreach(i; 0..33)
263            path.lineTo(Point((i%2) ? 400 : -400, 0).rotate(i*360/66.0))
264            .lineTo(Point((i%2) ? -400 : 400, 0).rotate(i*360/66.0));
265         path.close();
266         path = path.offset(400,400);
267 
268        foreach(i; 1..20)
269             path.append(Circle(400,400,i*20).asPath);
270     }
271 
272     override string getInfo()
273     {
274         return "Angular gradient, even odd, repeat mode = repeat";
275     }
276 
277     Point p0 = [600,400];
278     Point p1 = [400,600];
279     Path path;
280     Gradient grad;
281 }
282 
283 /* ============================================================================ */
284 
285 class RadialPanel1 : GFXPanel
286 {
287 	override void onPaint(Canvas canvas)
288   	{
289         canvas.draw(
290             path,
291             BiradialGradient(focus.x,focus.y,50,400,400,mainrad,grad,RepeatMode.Pad),
292             WindingRule.EvenOdd
293             );
294     }
295 
296     override void onMouse(MouseMsg msg)
297     {
298         if (msg.left == true)
299         {
300             focus.x = msg.x;
301             focus.y = msg.y;
302             repaint();
303         }
304 
305         if (msg.right == true)
306         {
307             import std.math;
308             import dg2d.misc;
309             mainrad = max(60,sqrt(sqr(msg.x-400.0)+sqr(msg.y-400.0)));
310             repaint();
311         }
312     } 
313 
314     this()
315     {
316         super(0,0,800,800);
317         
318         grad = new Gradient(1024);       
319         grad.initEqualSpaced(0xFFffff00,0xff009766,0xFF7b057f);
320         path.append(Rect(0,0,800,800).asPath);
321     }
322 
323     override string getInfo()
324     {
325         return "Biradial gradient, repeat mode = Pad";
326     }
327 
328     Point focus = [300,300];
329     float mainrad = 300;
330     Path path;
331     Gradient grad;
332 }
333 
334 /* ============================================================================ */
335 
336 class RadialPanel2 : GFXPanel
337 {
338 	override void onPaint(Canvas canvas)
339   	{
340         canvas.draw(
341             path,
342             RadialGradient(400,400,p0.x,p0.y,p1.x,p1.y,grad,RepeatMode.Repeat),
343             WindingRule.EvenOdd
344             );
345     }
346 
347     override void onMouse(MouseMsg msg)
348     {
349         if (msg.left == true)
350         {
351             p0.x = msg.x;
352             p0.y = msg.y;
353             repaint();
354         }
355 
356         if (msg.right == true)
357         {
358             p1.x = msg.x;
359             p1.y = msg.y;
360             repaint();
361         }
362     }   
363 
364     this()
365     {
366         super(0,0,800,800);
367         
368         grad = new Gradient;
369         grad.initEqualSpaced(0xFFfF0000,0xff00FF00,0xFF0000FF,0xFFFF0000);      
370         Path tmp;
371         tmp.moveTo(0,0).lineTo(300,20).lineTo(370,0).lineTo(300,-20).close();
372         Path tmp2;
373         tmp2 = Circle(0,0,50).asPath;
374 
375         foreach(i; 0..36)
376         {
377             path.append(tmp.offset(400,400).rotate(400,400,i*10));
378             path.append(tmp2.offset(700,400).rotate(400,400,i*10));
379         }
380     }
381 
382     override string getInfo()
383     {
384         return "Radial gradient, repeat mode = Repeat";
385     }
386 
387     Point p0 = [400,300];
388     Point p1 = [700,300];
389     Path path;
390     Gradient grad;
391 }
392 
393 /* ============================================================================ */
394 
395 class RadialPanel3 : GFXPanel
396 {
397 	override void onPaint(Canvas canvas)
398   	{
399         canvas.draw(
400             path,
401             BiradialGradient(focus.x,focus.y,50,400,400,mainrad,grad,RepeatMode.Mirror),
402             WindingRule.EvenOdd
403             );
404     }
405 
406     override void onMouse(MouseMsg msg)
407     {
408         if (msg.left == true)
409         {
410             focus.x = msg.x;
411             focus.y = msg.y;
412             repaint();
413         }
414 
415         if (msg.right == true)
416         {
417             import std.math;
418             import dg2d.misc;
419             mainrad = max(60,sqrt(sqr(msg.x-400.0)+sqr(msg.y-400.0)));
420             repaint();
421         }
422     }   
423 
424     this()
425     {
426         super(0,0,800,800);
427         
428         grad = new Gradient(8);       
429         grad.initEqualSpaced(0xFFe9b827,0xff8f1e62,0xFFff0000);
430         
431         foreach(i; 0..160)
432         {
433             path.append(Circle(i*3+10,0,i+17).asPath.rotate(i*13).offset(400,400));
434         }
435     }
436 
437     override string getInfo()
438     {
439         return "Biradial gradient, repeat mode = Mirror";
440     }
441 
442     Point focus = [300,300];
443     float mainrad = 300;
444     Path path;
445     Gradient grad;
446 }
447