1 /**
2  * ae.demo.canvas.main
3  *
4  * License:
5  *   This Source Code Form is subject to the terms of
6  *   the Mozilla Public License, v. 2.0. If a copy of
7  *   the MPL was not distributed with this file, You
8  *   can obtain one at http://mozilla.org/MPL/2.0/.
9  *
10  * Authors:
11  *   Vladimir Panteleev <ae@cy.md>
12  */
13 
14 module ae.demo.canvas.main;
15 
16 import std.random;
17 import std.algorithm : min, max;
18 import std.datetime, std.conv;
19 
20 import ae.ui.app.application;
21 import ae.ui.app.posix.main;
22 import ae.ui.shell.shell;
23 import ae.ui.shell.sdl2.shell;
24 import ae.ui.video.video;
25 import ae.ui.video.sdl2.video;
26 import ae.ui.video.renderer;
27 import ae.utils.math;
28 import ae.utils.geometry : TAU;
29 import ae.utils.graphics.draw;
30 import ae.utils.fps;
31 
32 final class MyApplication : Application
33 {
34 	override string getName() { return "Demo/Canvas"; }
35 	override string getCompanyName() { return "CyberShadow"; }
36 
37 	Shell shell;
38 	FPSCounter fps;
39 	bool first = true;
40 
41 	override void render(Renderer s)
42 	{
43 		fps.tick(&shell.setCaption);
44 
45 		auto canvas = s.lock();
46 		scope(exit) s.unlock();
47 
48 		ubyte randByte() { return cast(ubyte)uniform(0, 256); }
49 		BGRX randColor() { return BGRX(randByte(), randByte(), randByte()); }
50 		xy_t randX() { return uniform(0, canvas.w); }
51 		xy_t randY() { return uniform(0, canvas.h); }
52 
53 		enum Shape
54 		{
55 			pixel, hline, vline, line, rect, fillRect, fillRect2, circle, sector, poly,
56 			softCircle, softRing, aaLine,
57 		}
58 
59 		static Shape shape;
60 		if (first)
61 			canvas.whiteNoise(),
62 			shape = cast(Shape) uniform!"(]"(0, Shape.max),
63 			first = false;
64 
65 		final switch (shape)
66 		{
67 			case Shape.pixel:
68 				canvas[randX(), randY()] = randColor();
69 				return;
70 
71 			case Shape.hline:
72 				return canvas.hline(randX(), randX(), randY(), randColor());
73 			case Shape.vline:
74 				return canvas.vline(randX(), randY(), randY(), randColor());
75 			case Shape.line:
76 				return canvas.line(randX(), randY(), randX(), randY(), randColor());
77 
78 			case Shape.rect:
79 				return canvas.rect    (randX(), randY(), randX(), randY(), randColor());
80 			case Shape.fillRect:
81 				return canvas.fillRect(randX(), randY(), randX(), randY(), randColor());
82 			case Shape.fillRect2:
83 				return canvas.fillRect(randX(), randY(), randX(), randY(), randColor(), randColor());
84 
85 			case Shape.circle:
86 			{
87 				int r = uniform(10, 100);
88 				return canvas.fillCircle(uniform(r, canvas.w-r), uniform(r, canvas.h-r), r, randColor());
89 			}
90 			case Shape.sector:
91 			{
92 				int r1 = uniform(10, 100);
93 				int r0 = uniform(0, r1);
94 				return canvas.fillSector(uniform(r1, canvas.w-r1), uniform(r1, canvas.h-r1), r0, r1, uniform(0, TAU), uniform(0, TAU), randColor());
95 			}
96 			case Shape.poly:
97 			{
98 				auto coords = new Coord[uniform(3, 10)];
99 				foreach (ref coord; coords)
100 					coord = Coord(randX(), randY());
101 				return canvas.fillPoly(coords, randColor());
102 			}
103 			case Shape.softCircle:
104 			{
105 				int r1 = uniform(10, 100);
106 				int r0 = uniform(0, r1-5);
107 				return canvas.softCircle(uniform(r1, canvas.w-r1), uniform(r1, canvas.h-r1), r0, r1, randColor());
108 			}
109 			case Shape.softRing:
110 			{
111 				int r2 = uniform(15, 100);
112 				int r0 = uniform(0, r2-10);
113 				int r1 = uniform(r0+5, r2-5);
114 				return canvas.softRing(uniform(r2, canvas.w-r2), uniform(r2, canvas.h-r2), r0, r1, r2, randColor());
115 			}
116 			case Shape.aaLine:
117 				return canvas.aaLine(randX(), randY(), randX(), randY(), randColor());
118 		}
119 	}
120 
121 	override void handleMouseDown(uint x, uint y, MouseButton button)
122 	{
123 		first = true;
124 	}
125 
126 	override void setShellSettings(ShellSettings settings)
127 	{
128 		first = true;
129 		return super.setShellSettings(settings);
130 	}
131 
132 	override int run(string[] args)
133 	{
134 		shell = new SDL2Shell(this);
135 		shell.video = new SDL2SoftwareVideo();
136 		shell.run();
137 		shell.video.shutdown();
138 		return 0;
139 	}
140 
141 	override void handleQuit()
142 	{
143 		shell.quit();
144 	}
145 }
146 
147 shared static this()
148 {
149 	createApplication!MyApplication();
150 }