1// LAF OS Library
2// Copyright (C) 2019-2022 Igara Studio S.A.
3// Copyright (C) 2012-2018 David Capello
4//
5// This file is released under the terms of the MIT license.
6// Read LICENSE.txt for more information.
7
8#ifndef OS_COMMON_SYSTEM_H
9#define OS_COMMON_SYSTEM_H
10#pragma once
11
12#if LAF_WINDOWS
13 #include "os/win/native_dialogs.h"
14#elif LAF_MACOS
15 #include "os/osx/app.h"
16 #include "os/osx/menus.h"
17 #include "os/osx/native_dialogs.h"
18#elif LAF_OS_WITH_GTK
19 #include "os/gtk/native_dialogs.h"
20#else
21 #include "os/native_dialogs.h"
22#endif
23
24#ifdef LAF_FREETYPE
25#include "ft/lib.h"
26#include "os/common/freetype_font.h"
27#endif
28#include "os/common/sprite_sheet_font.h"
29#include "os/event_queue.h"
30#include "os/menus.h"
31#include "os/system.h"
32
33#include <memory>
34
35namespace os {
36
37class CommonSystem : public System {
38public:
39 CommonSystem() { }
40 ~CommonSystem() {
41 // We have to clear the list of all events to clear all possible
42 // living WindowRef (so all window destructors are called at this
43 // point, when the os::System instance is still alive).
44 //
45 // TODO Maybe the event queue should be inside the System instance
46 // (so when the system is deleted, the queue is
47 // deleted). Anyway we should still clear all the events
48 // before set_instance(nullptr), and we're not sure if this
49 // is possible on macOS, as some events are queued before the
50 // System instance is even created (see
51 // EventQueue::instance() comment on laf/os/event_queue.h).
52 eventQueue()->clearEvents();
53
54 set_instance(nullptr);
55 }
56
57 void setAppName(const std::string& appName) override { }
58 void setAppMode(AppMode appMode) override { }
59
60 void markCliFileAsProcessed(const std::string& fn) override { }
61 void finishLaunching() override { }
62 void activateApp() override { }
63
64 void setTabletAPI(TabletAPI api) override {
65 // Do nothing by default
66 }
67
68 TabletAPI tabletAPI() const override {
69 return TabletAPI::Default;
70 }
71
72 Logger* logger() override {
73 return nullptr;
74 }
75
76 Menus* menus() override {
77 return nullptr;
78 }
79
80 NativeDialogs* nativeDialogs() override {
81 if (!m_nativeDialogs) {
82#if LAF_WINDOWS
83 m_nativeDialogs.reset(new NativeDialogsWin);
84#elif LAF_MACOS
85 m_nativeDialogs.reset(new NativeDialogsOSX);
86#elif LAF_OS_WITH_GTK
87 m_nativeDialogs.reset(new NativeDialogsGTK);
88#endif
89 }
90 return m_nativeDialogs.get();
91 }
92
93 EventQueue* eventQueue() override {
94 return EventQueue::instance();
95 }
96
97 FontRef loadSpriteSheetFont(const char* filename, int scale) override {
98 SurfaceRef sheet = loadRgbaSurface(filename);
99 FontRef font = nullptr;
100 if (sheet) {
101 sheet->applyScale(scale);
102 sheet->setImmutable();
103 font = SpriteSheetFont::fromSurface(sheet);
104 }
105 return font;
106 }
107
108 FontRef loadTrueTypeFont(const char* filename, int height) override {
109#ifdef LAF_FREETYPE
110 if (!m_ft)
111 m_ft.reset(new ft::Lib());
112 return FontRef(load_free_type_font(*m_ft.get(), filename, height));
113#else
114 return nullptr;
115#endif
116 }
117
118 KeyModifiers keyModifiers() override {
119 return
120 (KeyModifiers)
121 ((isKeyPressed(kKeyLShift) ||
122 isKeyPressed(kKeyRShift) ? kKeyShiftModifier: 0) |
123 (isKeyPressed(kKeyLControl) ||
124 isKeyPressed(kKeyRControl) ? kKeyCtrlModifier: 0) |
125 (isKeyPressed(kKeyAlt) ? kKeyAltModifier: 0) |
126 (isKeyPressed(kKeyAltGr) ? (kKeyCtrlModifier | kKeyAltModifier): 0) |
127 (isKeyPressed(kKeyCommand) ? kKeyCmdModifier: 0) |
128 (isKeyPressed(kKeySpace) ? kKeySpaceModifier: 0) |
129 (isKeyPressed(kKeyLWin) ||
130 isKeyPressed(kKeyRWin) ? kKeyWinModifier: 0));
131 }
132
133private:
134 Ref<NativeDialogs> m_nativeDialogs;
135#ifdef LAF_FREETYPE
136 std::unique_ptr<ft::Lib> m_ft;
137#endif
138};
139
140} // namespace os
141
142#endif
143