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
9void draw_window(os::Window* window)
10{
11 os::Surface* surface = window->surface();
12 os::SurfaceLock lock(surface);
13 const gfx::Rect rc = surface->bounds();
14
15 os::Paint p;
16 p.color(gfx::rgba(0, 0, 0));
17 p.style(os::Paint::Fill);
18 surface->drawRect(rc, p);
19
20 p.color(gfx::rgba(255, 0, 0)); surface->drawLine(0 , 0, rc.w, rc.h, p);
21 p.color(gfx::rgba(0, 128, 0)); surface->drawLine(rc.w/2, 0, rc.w/2, rc.h, p);
22 p.color(gfx::rgba(0, 0, 255)); surface->drawLine(rc.w , 0, 0, rc.h, p);
23 p.color(gfx::rgba(255, 255, 255));
24 os::draw_text(surface, nullptr, "Hello World", rc.center(),
25 &p, os::TextAlign::Center);
26
27 if (window->isGpuAccelerated())
28 os::draw_text(surface, nullptr, "(GPU)", rc.center()+gfx::Point(0, 24),
29 &p, os::TextAlign::Center);
30
31 // Invalidates the whole window to show it on the screen.
32 if (window->isVisible())
33 window->invalidateRegion(gfx::Region(rc));
34 else
35 window->setVisible(true);
36
37 window->swapBuffers();
38}
39
40int app_main(int argc, char* argv[])
41{
42 os::SystemRef system = os::make_system();
43 system->setAppMode(os::AppMode::GUI);
44 system->setGpuAcceleration(true);
45
46 os::WindowRef window = system->makeWindow(400, 300);
47
48 // Set the title bar caption of the native window.
49 window->setTitle("Hello World");
50
51 // We can change the cursor to use when the mouse is above this
52 // window, this line is not required because by default the native
53 // cursor to be shown in a window is the arrow.
54 window->setCursor(os::NativeCursor::Arrow);
55
56 system->handleWindowResize = draw_window;
57
58 // On macOS: With finishLaunching() we start processing
59 // NSApplicationDelegate events. After calling this we'll start
60 // receiving os::Event::DropFiles events. It's a way to say "ok
61 // we're ready to process messages"
62 system->finishLaunching();
63
64 // On macOS, when we compile the program outside an app bundle, we
65 // must active the app explicitly if we want to put the app on the
66 // front. Remove this if you're planning to distribute your app on a
67 // bundle or enclose it in something like #ifdef _DEBUG/#endif
68 system->activateApp();
69
70 // Wait until a key is pressed or the window is closed
71 os::EventQueue* queue = system->eventQueue();
72 bool running = true;
73 bool redraw = true;
74 while (running) {
75 if (redraw) {
76 redraw = false;
77 draw_window(window.get());
78 }
79 // Wait for an event in the queue, the "true" parameter indicates
80 // that we'll wait for a new event, and the next line will not be
81 // processed until we receive a new event. If we use "false" and
82 // there is no events in the queue, we receive an "ev.type() == Event::None
83 os::Event ev;
84 queue->getEvent(ev);
85
86 switch (ev.type()) {
87
88 case os::Event::CloseApp:
89 case os::Event::CloseWindow:
90 running = false;
91 break;
92
93 case os::Event::KeyDown:
94 switch (ev.scancode()) {
95 case os::kKeyEsc:
96 running = false;
97 break;
98
99 case os::kKeyG:
100 system->setGpuAcceleration(!system->gpuAcceleration());
101 // TODO change window backend immediately
102 redraw = true;
103 break;
104
105 case os::kKey1:
106 case os::kKey2:
107 case os::kKey3:
108 case os::kKey4:
109 case os::kKey5:
110 case os::kKey6:
111 case os::kKey7:
112 case os::kKey8:
113 case os::kKey9:
114 // Set scale
115 window->setScale(1 + (int)(ev.scancode() - os::kKey1));
116 redraw = true;
117 break;
118
119 case os::kKeyF:
120 case os::kKeyF11:
121 window->setFullscreen(!window->isFullscreen());
122 break;
123
124 default:
125 // Do nothing
126 break;
127 }
128 break;
129
130 case os::Event::ResizeWindow:
131 redraw = true;
132 break;
133
134 default:
135 // Do nothing
136 break;
137 }
138 }
139
140 return 0;
141}
142