1 /**
2  * Color demo for dcell.
3  *
4  * Copyright: Copyright 2022 Garrett D'Amore
5  * Authors: Garrett D'Amore
6  * License:
7  *   Distributed under the Boost Software License, Version 1.0.
8  *   (See accompanying file LICENSE or https://www.boost.org/LICENSE_1_0.txt)
9  *   SPDX-License-Identifier: BSL-1.0
10  */
11 module color;
12 
13 import std.stdio;
14 import std.string;
15 import std.concurrency;
16 import std.random;
17 import std.range;
18 import dcell;
19 
20 class ColorBoxes
21 {
22 	import std.random;
23 
24 	int r;
25 	int g;
26 	int b;
27 	int ri;
28 	int gi;
29 	int bi;
30 	Random rng;
31 	enum inc = 8;
32 	int cnt;
33 
34 	bool flip()
35 	{
36 		return (rng.uniform!ubyte() & 0x1) != 0;
37 	}
38 
39 	this()
40 	{
41 		rng = rndGen();
42 		r = rng.uniform!ubyte();
43 		g = rng.uniform!ubyte();
44 		b = rng.uniform!ubyte();
45 		ri = inc;
46 		gi = inc / 4; // humans are very sensitive to green
47 		bi = inc;
48 	}
49 
50 	void makeBox(Screen s)
51 	{
52 		Coord wsz = s.size();
53 		dchar dc = ' ';
54 		Style style;
55 		cnt++;
56 
57 		if (s.colors() == 0)
58 		{
59 			dchar[] glyphs = ['@', '#', '&', '*', '=', '%', 'Z', 'A'];
60 			dc = choice(glyphs, rng);
61 			if (flip())
62 				style.attr |= Attr.reverse;
63 			else
64 				style.attr &= ~Attr.reverse;
65 		}
66 		else
67 		{
68 			r += ri;
69 			g += gi;
70 			b += bi;
71 			if (r >= 256 || r < 0)
72 			{
73 				ri = -ri;
74 				r += ri;
75 			}
76 			if (g >= 256 || g < 0)
77 			{
78 				gi = -gi;
79 				g += gi;
80 			}
81 			if (b >= 256 || b < 0)
82 			{
83 				bi = -bi;
84 				b += bi;
85 			}
86 			if (cnt % (256 / inc) == 0)
87 			{
88 				if (flip())
89 				{
90 					ri = -ri;
91 				}
92 
93 				if (flip())
94 				{
95 					gi = -gi;
96 				}
97 
98 				if (flip())
99 				{
100 					bi = -bi;
101 				}
102 			}
103 			style.bg = fromHex(
104 				int(r) << 15 | int(g) << 8 | int(b));
105 		}
106 
107 		// half the width and half the height
108 		Coord c1 = Coord(wsz.x / 4, wsz.y / 4);
109 		Coord c2 = Coord(c1.x + wsz.x / 2, c1.y + wsz.y / 2);
110 		Coord pos = c1;
111 		Cell cell = Cell(dc, style);
112 		for (pos.y = c1.y; pos.y <= c2.y; pos.y++)
113 		{
114 			for (pos.x = c1.x; pos.x <= c2.x; pos.x++)
115 			{
116 				s[pos] = cell;
117 			}
118 		}
119 		s.show();
120 	}
121 }
122 
123 void main()
124 {
125 	import std.stdio;
126 	import core.time;
127 	import core.stdc.stdlib;
128 
129 	auto s = newScreen();
130 	assert(s !is null);
131 	ColorBoxes cb = new ColorBoxes();
132 
133 	auto now = MonoTime.currTime();
134 
135 	s.start();
136 	bool done = false;
137 	while (!done)
138 	{
139 		cb.makeBox(s);
140 		auto ev = s.receiveEvent(msecs(50));
141 		switch (ev.type)
142 		{
143 		case EventType.key:
144 			switch (ev.key.key)
145 			{
146 			case Key.esc, Key.enter:
147 				done = true;
148 				break;
149 			case Key.ctrlL:
150 				s.resize();
151 				s.sync();
152 				break;
153 			default:
154 
155 			}
156 			break;
157 		case EventType.resize:
158 			s.resize();
159 			break;
160 		case EventType.closed:
161 			done = true;
162 			break;
163 		case EventType.error:
164 			assert(0, "errror received");
165 		default:
166 		}
167 	}
168 	auto end = MonoTime.currTime();
169 	s.stop();
170 	writefln("Drew %d boxes in %s.", cb.cnt, end - now);
171 	writefln("Average per box %s.", (end - now) / cb.cnt);
172 }