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
27class GrDirectContext;
28#endif
29
30namespace 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