1 | // LAF OS Library |
2 | // Copyright (c) 2018-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_WINDOW_H_INCLUDED |
9 | #define OS_WINDOW_H_INCLUDED |
10 | #pragma once |
11 | |
12 | #include "gfx/point.h" |
13 | #include "os/color_space.h" |
14 | #include "os/cursor.h" |
15 | #include "os/native_cursor.h" |
16 | #include "os/ref.h" |
17 | #include "os/screen.h" |
18 | #include "os/surface_list.h" |
19 | |
20 | #include <functional> |
21 | #include <string> |
22 | |
23 | #pragma push_macro("None") |
24 | #undef None // Undefine the X11 None macro |
25 | |
26 | #if LAF_SKIA && SK_SUPPORT_GPU |
27 | class GrDirectContext; |
28 | #endif |
29 | |
30 | namespace os { |
31 | |
32 | class Event; |
33 | class Surface; |
34 | class Window; |
35 | using WindowRef = Ref<Window>; |
36 | |
37 | enum class WindowAction { |
38 | Cancel, |
39 | Move, |
40 | ResizeFromTopLeft, |
41 | ResizeFromTop, |
42 | ResizeFromTopRight, |
43 | ResizeFromLeft, |
44 | ResizeFromRight, |
45 | ResizeFromBottomLeft, |
46 | ResizeFromBottom, |
47 | ResizeFromBottomRight, |
48 | }; |
49 | |
50 | // Possible areas for hit testing. See os::Window::handleHitTest. |
51 | enum class Hit { |
52 | None, |
53 | Content, |
54 | TitleBar, |
55 | TopLeft, |
56 | Top, |
57 | TopRight, |
58 | Left, |
59 | Right, |
60 | BottomLeft, |
61 | Bottom, |
62 | BottomRight, |
63 | MinimizeButton, |
64 | MaximizeButton, |
65 | CloseButton, |
66 | }; |
67 | |
68 | // A window to show graphics. |
69 | class Window : public RefCount { |
70 | public: |
71 | typedef void* NativeHandle; |
72 | |
73 | virtual ~Window() { } |
74 | |
75 | // Real rectangle of this window (including title bar, etc.) in |
76 | // the screen. (The scale is not involved.) |
77 | virtual gfx::Rect frame() const = 0; |
78 | virtual void setFrame(const gfx::Rect& bounds) = 0; |
79 | |
80 | // Rectangle of the content, the origin and the size are specified |
81 | // in real screen pixels. (The scale is not involved.) |
82 | virtual gfx::Rect contentRect() const = 0; |
83 | |
84 | // Returns the frame() when the window wasn't maximized or in |
85 | // full-screen mode. |
86 | virtual gfx::Rect restoredFrame() const = 0; |
87 | |
88 | // Returns the real and current window's size (without scale applied). |
89 | virtual int width() const = 0; |
90 | virtual int height() const = 0; |
91 | gfx::Rect bounds() const; |
92 | |
93 | // Returns the current window scale. Each pixel in the internal |
94 | // window surface, is represented by SCALExSCALE pixels on the |
95 | // screen. |
96 | virtual int scale() const = 0; |
97 | |
98 | // Changes the scale. |
99 | // The available surface size will be (Window::width() / scale, |
100 | // Window::height() / scale) |
101 | // |
102 | // The window size will be a multiple of the scale. |
103 | virtual void setScale(int scale) = 0; |
104 | |
105 | // Returns true if the window is visible in the screen. |
106 | virtual bool isVisible() const = 0; |
107 | |
108 | // Shows or hides the window (doesn't destroy it). |
109 | virtual void setVisible(bool visible) = 0; |
110 | |
111 | // Returns the main surface to draw into this window. |
112 | virtual Surface* surface() = 0; |
113 | |
114 | // Invalidates part of the window to be redraw in the future by |
115 | // the OS painting messages. The region must be in non-scaled |
116 | // coordinates. |
117 | virtual void invalidateRegion(const gfx::Region& rgn) = 0; |
118 | void invalidate(); |
119 | |
120 | // GPU-related functions |
121 | virtual bool isGpuAccelerated() const = 0; |
122 | virtual void swapBuffers() = 0; |
123 | |
124 | // Focus the window to receive the keyboard input by default. |
125 | virtual void activate() = 0; |
126 | virtual void maximize() = 0; |
127 | virtual void minimize() = 0; |
128 | virtual bool isMaximized() const = 0; |
129 | virtual bool isMinimized() const = 0; |
130 | |
131 | // Returns true if this native window is |
132 | // transparent. E.g. WS_EX_LAYERED on Windows, |
133 | // or [NSWindow isOpaque:NO] on macOS. |
134 | virtual bool isTransparent() const = 0; |
135 | |
136 | virtual bool isFullscreen() const = 0; |
137 | virtual void setFullscreen(bool state) = 0; |
138 | |
139 | virtual std::string title() const = 0; |
140 | virtual void setTitle(const std::string& title) = 0; |
141 | |
142 | virtual void setIcons(const SurfaceList& icons) { }; |
143 | |
144 | virtual NativeCursor nativeCursor() = 0; |
145 | virtual bool setCursor(NativeCursor cursor) = 0; |
146 | virtual bool setCursor(const CursorRef& cursor) = 0; |
147 | |
148 | // Sets the mouse position to the given point in surface coordinates. |
149 | virtual void setMousePosition(const gfx::Point& position) = 0; |
150 | |
151 | virtual void captureMouse() = 0; |
152 | virtual void releaseMouse() = 0; |
153 | |
154 | // Convert points between window surface bounds (scaled) <-> screen absolute position |
155 | gfx::Point pointToScreen(const gfx::Point& clientPosition) const; |
156 | gfx::Point pointFromScreen(const gfx::Point& screenPosition) const; |
157 | |
158 | // Queue event for this window (the "ev" window will be set to |
159 | // this window if it's not set). |
160 | void queueEvent(os::Event& ev); |
161 | |
162 | // Performs the user action to move or resize the window. It's |
163 | // useful in case that you want to design your own regions to |
164 | // resize or move/drag the window. |
165 | virtual void performWindowAction(const WindowAction action, |
166 | const Event* event = nullptr) = 0; |
167 | |
168 | // Set/get the specific information to restore the exact same |
169 | // window position (e.g. in the same monitor). |
170 | virtual std::string getLayout() = 0; |
171 | virtual void setLayout(const std::string& layout) = 0; |
172 | |
173 | // For Windows 8/10 only in tablet devices: Set to true if you |
174 | // want to interpret one finger as the mouse movement and two |
175 | // fingers as pan/scroll (true by default). If you want to pan |
176 | // with one finger, call this function with false. |
177 | virtual void setInterpretOneFingerGestureAsMouseMovement(bool state) { } |
178 | |
179 | // Returns the screen where this window belongs. |
180 | virtual os::ScreenRef screen() const = 0; |
181 | |
182 | // Returns the color space of the window where the window is located. |
183 | virtual os::ColorSpaceRef colorSpace() const = 0; |
184 | |
185 | // Changes the color space to use in this window. Can be nullptr |
186 | // if you want to use the current monitor color space. |
187 | virtual void setColorSpace(const os::ColorSpaceRef& colorSpace) = 0; |
188 | |
189 | // Returns the HWND on Windows, X11 Window, or bridged NSWindow pointer. |
190 | virtual NativeHandle nativeHandle() const = 0; |
191 | |
192 | // For Windows platform, function used to handle WM_NCHITTEST for |
193 | // borderless windows (mainly). It's required so some input |
194 | // devices like stylus can be used to move and resize the window. |
195 | std::function<Hit(os::Window*, const gfx::Point& pos)> handleHitTest = nullptr; |
196 | |
197 | template<typename T> |
198 | T* userData() { return reinterpret_cast<T*>(m_userData); } |
199 | |
200 | template<typename T> |
201 | void setUserData(T* data) { m_userData = reinterpret_cast<void*>(data); } |
202 | |
203 | #if LAF_SKIA && SK_SUPPORT_GPU |
204 | virtual GrDirectContext* sk_grCtx() const = 0; |
205 | #endif |
206 | |
207 | protected: |
208 | virtual void onQueueEvent(Event& ev); |
209 | |
210 | private: |
211 | void* m_userData; |
212 | }; |
213 | |
214 | } // namespace os |
215 | |
216 | #pragma pop_macro("None") |
217 | |
218 | #endif |
219 | |