18 enum class Orientation { Landscape, Portrait };
34 Orientation ori = Orientation::Portrait)
47 void Draw(RegionID region,
int value) {
48 int tens = (value / 10) % 10;
49 int ones = value % 10;
51 auto [baseX, baseY] = REGION_OFFSETSS[
static_cast<int>(region)];
52 DrawDigit(baseX, baseY, FONT[tens], region);
53 DrawDigit(baseX + 5, baseY, FONT[ones], region);
65 630.0f - gravity_angle * 180.0f /
static_cast<float>(M_PI), 360.0f);
81 std::this_thread::sleep_for(std::chrono::milliseconds(500));
87 for (
int i = 0; i < 128;) {
88 if (grid_up_.AddNewSand()) {
93 std::this_thread::sleep_for(std::chrono::milliseconds(25));
97 for (
int i = 0; i < 16; i++) {
100 std::this_thread::sleep_for(std::chrono::milliseconds(25));
114 std::this_thread::sleep_for(std::chrono::milliseconds(25));
126 static constexpr std::array<std::array<std::string, 7>, 10> FONT = {{
127 {
"01110",
"10001",
"10011",
"10101",
"11001",
"10001",
"01110"},
128 {
"00100",
"01100",
"00100",
"00100",
"00100",
"00100",
"01110"},
129 {
"01110",
"10001",
"00001",
"00010",
"00100",
"01000",
"11111"},
130 {
"01110",
"10001",
"00001",
"00110",
"00001",
"10001",
"01110"},
131 {
"00010",
"00110",
"01010",
"10010",
"11111",
"00010",
"00010"},
132 {
"11111",
"10000",
"11110",
"00001",
"00001",
"10001",
"01110"},
133 {
"00110",
"01000",
"10000",
"11110",
"10001",
"10001",
"01110"},
134 {
"11111",
"00001",
"00010",
"00100",
"01000",
"01000",
"01000"},
135 {
"01110",
"10001",
"10001",
"01110",
"10001",
"10001",
"01110"},
136 {
"01110",
"10001",
"10001",
"01111",
"00001",
"00010",
"01100"},
140 static constexpr std::array<std::pair<int, int>, 4> REGION_OFFSETSS = {{
154 void DrawDigit(
int leftX,
int topY,
const std::array<std::string, 7>& bitmap,
156 for (
int dy = 0; dy < 7; ++dy) {
157 for (
int dx = 0; dx < 5; ++dx) {
158 if (bitmap[6 - dy][dx] ==
'1') {
173 int row = 0, col = 0;
180 if (region == RegionID::SCREEN_0_PORTRAIT) {
182 }
else if (region == RegionID::SCREEN_1_PORTRAIT) {
190 if (region == RegionID::SCREEN_0_LANDSCAPE) {
192 }
else if (region == RegionID::SCREEN_1_LANDSCAPE) {
197 if (row >= 0 && row < 16 && col >= 0 && col < 32) {
198 display_.DrawPixelMatrix2(row, col, on);
213 Draw(RegionID::SCREEN_0_LANDSCAPE, hour);
214 Draw(RegionID::SCREEN_1_LANDSCAPE, minute);
223 if (seconds % 2 == 1) {
227 Draw(RegionID::SCREEN_0_LANDSCAPE, minutes);
228 Draw(RegionID::SCREEN_1_LANDSCAPE, seconds);
257 Draw(RegionID::SCREEN_0_PORTRAIT, minute);
258 Draw(RegionID::SCREEN_1_PORTRAIT, hour);
268 if (seconds % 2 == 1) {
280 if (seconds % 2 != 1) {
288 Draw(RegionID::SCREEN_0_PORTRAIT, seconds);
289 Draw(RegionID::SCREEN_1_PORTRAIT, minutes);
293 void RenderHumidity(uint8_t humidity) {
294 static constexpr bool ICON[16][16] = {
295 {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
296 {1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
297 {1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
298 {0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0},
299 {0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0},
300 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
301 {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
302 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
303 {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
304 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
305 {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
306 {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
307 {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
308 {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0},
309 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0},
310 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
315 for (
int i = 0; i < 2; i++) {
316 for (
int j = 0; j < 2; j++) {
317 for (
int k = 0; k < 8; k++) {
318 for (
int l = 0; l < 8; l++) {
319 display_.DrawPixel(i * 2 + j + 4, k, l, ICON[k + i * 8][l + j * 8]);
324 Draw(RegionID::SCREEN_0_PORTRAIT, humidity);
328 void RenderTemperature(uint8_t temperature) {
329 static constexpr bool ICON[16][16] = {
330 {0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
331 {0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
332 {1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0},
333 {1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0},
334 {1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0},
335 {0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0},
336 {0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0},
337 {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0},
338 {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0},
339 {0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0},
340 {0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0},
341 {0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0},
342 {0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0},
343 {0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0},
344 {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
345 {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
350 for (
int i = 0; i < 2; i++) {
351 for (
int j = 0; j < 2; j++) {
352 for (
int k = 0; k < 8; k++) {
353 for (
int l = 0; l < 8; l++) {
354 display_.DrawPixel(i * 2 + j + 4, k, l, ICON[k + i * 8][l + j * 8]);
359 Draw(RegionID::SCREEN_0_PORTRAIT, temperature);
366 for (
int i = 0; i < 2; i++) {
367 for (
int j = 0; j < 2; j++) {
368 for (
int k = 0; k < 8; k++) {
369 for (
int l = 0; l < 8; l++) {
370 display_.DrawPixel(i * 2 + j + 4, k, l,
371 up->GetGrid()[k + i * 8][l + j * 8]);
377 for (
int i = 0; i < 2; i++) {
378 for (
int j = 0; j < 2; j++) {
379 for (
int k = 0; k < 8; k++) {
380 for (
int l = 0; l < 8; l++) {
382 down->GetGrid()[k + i * 8][l + j * 8]);
394 std::cout <<
"[CompGuiX::UnitTest] Starting GUI unit test...\n";
400 std::cout <<
"[Test] Draw number 42 in portrait...\n";
401 Draw(RegionID::SCREEN_0_PORTRAIT, 42);
402 std::this_thread::sleep_for(std::chrono::milliseconds(500));
404 std::cout <<
"[Test] Draw time 12:34 in portrait...\n";
406 std::this_thread::sleep_for(std::chrono::milliseconds(500));
408 std::cout <<
"[Test] Draw time 12:34 in landscape...\n";
410 std::this_thread::sleep_for(std::chrono::milliseconds(500));
412 std::cout <<
"[Test] Render humidity icon...\n";
414 std::this_thread::sleep_for(std::chrono::milliseconds(500));
416 std::cout <<
"[Test] Render temperature icon...\n";
417 RenderTemperature(23);
418 std::this_thread::sleep_for(std::chrono::milliseconds(500));
420 std::cout <<
"[Test] Enable sand...\n";
422 std::this_thread::sleep_for(std::chrono::milliseconds(500));
423 std::cout <<
"[Test] Reset sand...\n";
425 std::this_thread::sleep_for(std::chrono::milliseconds(500));
426 std::cout <<
"[Test] Disable sand...\n";
429 std::cout <<
"[CompGuiX::UnitTest] ✅ Test complete.\n";