1// LAF Library
2// Copyright (c) 2019-2022 Igara Studio S.A.
3//
4// This file is released under the terms of the MIT license.
5// Read LICENSE.txt for more information.
6
7#include "os/os.h"
8
9#include <cstdio>
10
11class MyDrawTextDelegate : public os::DrawTextDelegate {
12 gfx::Point m_mousePos;
13public:
14 MyDrawTextDelegate(const gfx::Point& mousePos) : m_mousePos(mousePos) { }
15
16 void preProcessChar(const int index,
17 const int codepoint,
18 gfx::Color& fg,
19 gfx::Color& bg,
20 const gfx::Rect& charBounds) override {
21 if (charBounds.contains(m_mousePos)) {
22 fg = gfx::rgba(0, 0, 0);
23 bg = gfx::rgba(255, 255, 255);
24 }
25 else {
26 fg = gfx::rgba(255, 255, 255);
27 bg = gfx::rgba(0, 0, 0, 0);
28 }
29 }
30};
31
32os::FontRef font = nullptr;
33
34void draw_window(os::Window* window,
35 const gfx::Point& mousePos)
36{
37 os::Surface* surface = window->surface();
38 os::SurfaceLock lock(surface);
39 const gfx::Rect rc = surface->bounds();
40
41 os::SurfaceRef backSurface = os::instance()->makeSurface(rc.w, rc.h);
42 os::SurfaceLock lock2(backSurface.get());
43
44 os::Paint p;
45 p.color(gfx::rgba(0, 0, 0));
46 p.style(os::Paint::Fill);
47 backSurface->drawRect(rc, p);
48
49 p.color(gfx::rgba(255, 255, 255));
50
51 const wchar_t* lines[] = { L"English",
52 L"Русский язык", // Russian
53 L"汉语", // Simplified Chinese
54 L"日本語", // Japanese
55 L"한국어", // Korean
56 L"العَرَبِيَّة‎" }; // Arabic
57
58 MyDrawTextDelegate delegate(mousePos);
59 gfx::Point pos(0, 0);
60 for (auto line : lines) {
61 std::string s = base::to_utf8(line);
62 os::draw_text(
63 backSurface.get(), font.get(), s,
64 gfx::rgba(255, 255, 255), gfx::ColorNone,
65 pos.x, pos.y,
66 &delegate);
67
68 pos.y += font->height() + 4;
69 }
70
71 // Flip the back surface to the window surface
72 surface->drawSurface(backSurface.get(), 0, 0);
73
74 // Invalidates the whole window to show it on the screen.
75 if (window->isVisible())
76 window->invalidateRegion(gfx::Region(rc));
77 else
78 window->setVisible(true);
79}
80
81int app_main(int argc, char* argv[])
82{
83 os::SystemRef system = os::make_system();
84 system->setAppMode(os::AppMode::GUI);
85
86 os::WindowRef window = system->makeWindow(400, 300);
87
88 // TODO use new fonts (SkFont wrappers with system->fontManager())
89 font = os::instance()->loadTrueTypeFont("/Library/Fonts/Arial Unicode.ttf", 32);
90 if (!font) {
91 std::printf("Font not found\n");
92 return 1;
93 }
94
95 window->setTitle("CTL");
96
97 system->finishLaunching();
98 system->activateApp();
99
100 // Wait until a key is pressed or the window is closed
101 os::EventQueue* queue = system->eventQueue();
102 gfx::Point mousePos;
103 bool running = true;
104 bool redraw = true;
105 while (running) {
106 if (redraw) {
107 redraw = false;
108 draw_window(window.get(), mousePos);
109 }
110 // Wait for an event in the queue, the "true" parameter indicates
111 // that we'll wait for a new event, and the next line will not be
112 // processed until we receive a new event. If we use "false" and
113 // there is no events in the queue, we receive an "ev.type() == Event::None
114 os::Event ev;
115 queue->getEvent(ev);
116
117 switch (ev.type()) {
118
119 case os::Event::CloseWindow:
120 running = false;
121 break;
122
123 case os::Event::KeyDown:
124 switch (ev.scancode()) {
125 case os::kKeyEsc:
126 running = false;
127 break;
128 case os::kKey1:
129 case os::kKey2:
130 case os::kKey3:
131 case os::kKey4:
132 case os::kKey5:
133 case os::kKey6:
134 case os::kKey7:
135 case os::kKey8:
136 case os::kKey9:
137 // Set scale
138 window->setScale(1 + (int)(ev.scancode() - os::kKey1));
139 redraw = true;
140 break;
141 default:
142 // Do nothing for other cases
143 break;
144 }
145 break;
146
147 case os::Event::ResizeWindow:
148 redraw = true;
149 break;
150
151 case os::Event::MouseEnter:
152 case os::Event::MouseMove:
153 mousePos = ev.position();
154 redraw = true;
155 break;
156
157 case os::Event::MouseLeave:
158 mousePos = gfx::Point(-1, -1);
159 redraw = true;
160 break;
161
162 default:
163 // Do nothing
164 break;
165 }
166 }
167
168 return 0;
169}
170