Gamp v0.0.7-36-g24b1eb6
Gamp: Graphics, Audio, Multimedia and Processing
Loading...
Searching...
No Matches
Window.hpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright Gothel Software e.K.
4 *
5 * SPDX-License-Identifier: MIT
6 *
7 * This Source Code Form is subject to the terms of the MIT License
8 * If a copy of the MIT was not distributed with this file,
9 * you can obtain one at https://opensource.org/license/mit/.
10 */
11#ifndef GAMP_WTWINDOW_HPP_
12#define GAMP_WTWINDOW_HPP_
13
14#include <jau/basic_types.hpp>
15#include <jau/debug.hpp>
16#include <jau/fraction_type.hpp>
17#include <jau/math/vec2i.hpp>
18#include <jau/string_util.hpp>
19
21#include <gamp/wt/Surface.hpp>
26
27namespace gamp::wt {
28
29 /** @defgroup Gamp_WT Gamp Windowing Toolkit
30 * Windowing toolkit functionality.
31 *
32 * @{
33 */
34
35 class Window;
36 typedef std::shared_ptr<Window> WindowRef;
37
38 using namespace jau::fractions_i64_literals;
39 using namespace jau::math;
40 using namespace jau::enums;
41 using namespace gamp::wt::event;
42
43 enum class RenderActions : uint16_t {
44 none = 0,
45 init = 1,
47 };
50
51 class RenderListener : public std::enable_shared_from_this<RenderListener> {
52 private:
54
55 protected:
56 struct Private{ explicit Private() = default; };
57
58 public:
59 /** Private ctor for shared_ptr<RenderListener> instance method w/o public ctor. */
60 constexpr RenderListener(Private) noexcept {}
61
62 virtual ~RenderListener() noexcept = default;
63
64 RenderActions pendingActions() const noexcept { return m_pending_actions; }
65 RenderActions& pendingActions() noexcept { return m_pending_actions; }
66 void setPendingActions(RenderActions v) noexcept { m_pending_actions=v; }
67
68 /** Called by the drawable immediately after the render context is
69 initialized. Can be used to perform one-time renderer
70 initialization per context, such as setup of lights and display lists.<p>
71
72 Note that this method may be called more than once if the underlying
73 render context for the drawable is destroyed and
74 recreated.
75 *
76 * @return true if initialization is completed, false if not initialized yet and init shall be called again
77 */
78 virtual bool init(const WindowRef&, const jau::fraction_timespec& /*when*/) = 0;
79
80 /** Notifies the listener to perform the release of all renderer
81 resources per context, such as memory buffers and shader programs.<P>
82
83 Called by the drawable before the render context is
84 destroyed by an external event.<P>
85
86 Note that this event does not imply the end of life of the application.
87 */
88 virtual void dispose(const WindowRef&, const jau::fraction_timespec& /*when*/) = 0;
89
90 /** Called by the drawable to initiate rendering by the
91 client. After all listener have been notified of a
92 display event, the drawable will swap its buffers. */
93 virtual void display(const WindowRef&, const jau::fraction_timespec& /*when*/) = 0;
94
95 /**
96 * Called by the drawable during the first repaint after the
97 * component has been resized.
98 *
99 * The client can update it's viewport associated data
100 * and view volume of the window/surface appropriately.
101 *
102 * For efficiency the renderer viewport has already been updated,
103 * e.g. via <code>glViewport(x, y, width, height)</code> when this method is called.
104 *
105 * @param drawable the triggering {@link GLAutoDrawable}
106 * @param viewport the viewport in pixel units
107 */
108 virtual void reshape(const WindowRef&, const jau::math::Recti& /*viewport*/, const jau::fraction_timespec& /*when*/) = 0;
109
110 virtual std::string toStringImpl() const noexcept { return "none"; }
111
112 std::string toString() const noexcept {
113 std::string res = "RenderListener[";
114 res.append("pending ").append(to_string(m_pending_actions))
115 .append(", this ").append(jau::to_hexstring(this))
116 .append(", ").append(toStringImpl())
117 .append("]");
118 return res;
119 }
120
121 };
122 typedef std::shared_ptr<RenderListener> RenderListenerRef;
123
124 enum class WindowState : uint16_t {
125 none = 0,
128 };
131
132 class Window : public Surface {
133 private:
134 handle_t m_window_handle;
135
136 /// Window client-area top-left position and size in window units
137 Recti m_window_bounds;
138
139 WindowState m_state;
140
141 WindowEventManager m_win_evt_mngr;
142 KeyEventManager m_key_evt_mngr;
143 PointerEventManager m_ptr_evt_mngr;
144
145 jau::cow_darray<RenderListenerRef> m_render_listener;
146
147 protected:
148 struct Private{ explicit Private() = default; };
149
150 void setWindowBounds(const Recti& r) noexcept { m_window_bounds = r; }
151 void setWindowPos(const Vec2i& sz) noexcept { m_window_bounds.setPosition(sz); }
152 void setWindowSize(const Vec2i& sz) noexcept { m_window_bounds.setSize(sz); }
153 void setFocused(bool v) noexcept { write(m_state, WindowState::focused, v); }
154 void setVisible(bool v) noexcept { write(m_state, WindowState::visible, v); }
155
156 private:
157 class SelfWinListener : public WindowListener {
158 private:
159 Window* m_self;
160 public:
161 SelfWinListener(Window* self) noexcept : m_self(self) {}
162 void windowResized(WindowEvent&, const Vec2i& winSize, const jau::math::Vec2i& surfSize) override {
163 m_self->setWindowSize(winSize);
164 m_self->setSurfaceSize(surfSize);
165 for(const RenderListenerRef& l : *m_self->m_render_listener.snapshot()) {
166 write(l->pendingActions(), RenderActions::reshape, true);
167 }
168 }
169 void windowMoved(WindowEvent&, const Vec2i& winPos) override { m_self->setWindowPos(winPos); }
170 void windowDestroyNotify(WindowEvent&) override {}
171 void windowDestroyed(WindowEvent&) override {}
172 void windowFocusChanged(WindowEvent&, bool focused) override { m_self->setFocused(focused); }
173 void windowRepaint(WindowEvent&) override {}
174 void windowVisibilityChanged(WindowEvent&, bool visible) override { m_self->setVisible(visible); }
175 };
176 WindowListenerRef m_win_selflistener;
177
178 void disposeImpl(handle_t handle) noexcept;
179
180 public:
181 /** Private ctor for single Window::create() method w/o public ctor. */
182 Window(Private, handle_t window_handle, const Recti& window_bounds,
183 handle_t surface_handle, const Vec2i& surface_size)
184 : Surface(Surface::Private(), surface_handle, surface_size),
185 m_window_handle(window_handle),
186 m_window_bounds(window_bounds), m_state(WindowState::none),
187 m_win_selflistener(std::make_shared<SelfWinListener>(this))
188 {
189 write(m_state, WindowState::visible, 0 != window_handle && !window_bounds.is_zero());
190 addWindowListener(m_win_selflistener);
191 }
192
193 /**
194 * Create an new instance, wrapping the native windowing toolkit's handle/resources.
195 *
196 * Must be driven by a native toolkit implementation, see create() below.
197 * @see create()
198 */
199 static WindowRef wrapNative(handle_t window_handle, const Recti& window_bounds,
200 handle_t surface_handle, const Vec2i& surface_size) {
201 return std::make_shared<Window>(Private(), window_handle, window_bounds,
202 surface_handle, surface_size);
203 }
204
205 /**
206 * Create an new instance using a native windowing toolkit.
207 *
208 * @see wrapNative()
209 */
210 static WindowRef create(const char* title, int wwidth, int wheight, bool verbose=false);
211
212 Window(const Window&) = delete;
213 void operator=(const Window&) = delete;
214
215 /**
216 * Releases this instance.
217 */
218 ~Window() noexcept override = default;
219
220 /**
221 * Returns the associated {@link Surface} of this {@link SurfaceHolder}.
222 * <p>
223 * Returns this instance, which <i>is-a</i> {@link Surface}.
224 * </p>
225 */
226 SurfaceRef nativeSurface() { return shared_from_this(); }
228
229 /** Returns the window top-lect position of client-area in window units */
230 constexpr Vec2i windowPos() const noexcept { return m_window_bounds.getPosition(); }
231
232 /** Returns the window size of the client area excluding insets (window decorations) in window units. */
233 constexpr Vec2i windowSize() const noexcept { return m_window_bounds.getSize(); }
234
235 /** Returns the window client-area top-left position and size excluding insets (window decorations) in window units. */
236 constexpr const Recti& windowBounds() const noexcept { return m_window_bounds; }
237
238 /**
239 * Returns <code>true</code> if this window delivers PointerEvent in
240 * OpenGL's coordinate system, <i>origin at bottom left</i>.
241 * Otherwise returns <code>false</code>, i.e. <i>origin at top left</i>.
242 *
243 * Default impl. is isBLOriented(), i.e. <code>true</code> for OpenGL bottom-left coordinate system.
244 *
245 * @see isBLOriented()
246 */
247 constexpr bool isPointerBLOriented() const noexcept { return isBLOriented(); }
248
249 /**
250 * Returns the handle to the surface for this NativeSurface. <P>
251 *
252 * The surface handle should be set/update by {@link #lockSurface()},
253 * where {@link #unlockSurface()} is not allowed to modify it.
254 * After {@link #unlockSurface()} it is no more guaranteed
255 * that the surface handle is still valid.
256 *
257 * The surface handle shall reflect the platform one
258 * for all drawable surface operations, e.g. opengl, swap-buffer. <P>
259 *
260 * On X11 this returns an entity of type Window,
261 * since there is no differentiation of surface and window there. <BR>
262 * On Microsoft Windows this returns an entity of type HDC.
263 */
264 constexpr handle_t windowHandle() const noexcept { return m_window_handle; }
265 bool isValid() const noexcept override { return 0 != surfaceHandle() && 0 != m_window_handle; }
266
267 constexpr WindowState state() const noexcept { return m_state; }
268 constexpr bool hasFocus() const noexcept { return is_set(m_state, WindowState::focused); }
269 constexpr bool isVisible() const noexcept { return is_set(m_state, WindowState::visible); }
270
271 void display(const jau::fraction_timespec& when) noexcept;
272
273 bool surfaceSwap() noexcept override;
274
275 //
276 //
277 //
278 void notifyWindowEvent(uint16_t type, const jau::fraction_timespec& when, bool value=true) noexcept {
279 m_win_evt_mngr.dispatch(type, when, shared(), value);
280 }
282 const jau::math::Vec2i& winSize, const jau::math::Vec2i& surfSize) noexcept {
283 if( m_window_bounds.getSize() != winSize || Surface::surfaceSize() != surfSize ) {
284 m_win_evt_mngr.dispatchResize(when, shared(), winSize, surfSize);
285 }
286 }
288 const jau::math::Vec2i& winPos) noexcept {
289 if( m_window_bounds.getPosition() != winPos ) {
290 m_win_evt_mngr.dispatchMoved(when, shared(), winPos);
291 }
292 }
293
294 void addWindowListener(const WindowListenerRef& l) { m_win_evt_mngr.addListener(l); }
295 size_t removeWindowListener(const WindowListenerRef& l) { return m_win_evt_mngr.removeListener(l); }
296 size_t removeAllWindowListener() { size_t r = m_win_evt_mngr.removeAllListener() - 1; addWindowListener(m_win_selflistener); return r; }
297 size_t windowListenerCount() const noexcept { return m_win_evt_mngr.listenerCount() - 1; }
298
299 //
300 //
301 //
302 const KeyboardTracker& keyTracker() const noexcept { return m_key_evt_mngr; }
303
304 void notifyKeyPressed(const jau::fraction_timespec& when, VKeyCode keySym, InputModifier keySymMods, uint16_t keyChar) noexcept {
305 m_key_evt_mngr.dispatchPressed(when, shared(), keySym, keySymMods, keyChar);
306 }
307 void notifyKeyReleased(const jau::fraction_timespec& when, VKeyCode keySym, InputModifier keySymMods, uint16_t keyChar) noexcept {
308 m_key_evt_mngr.dispatchReleased(when, shared(), keySym, keySymMods, keyChar);
309 }
310 void addKeyListener(const KeyListenerRef& l) { m_key_evt_mngr.addListener(l); }
311 size_t removeKeyListener(const KeyListenerRef& l) { return m_key_evt_mngr.removeListener(l); }
312 size_t removeAllKeyListener() { return m_key_evt_mngr.removeAllListener(); }
313 size_t keyListenerCount() const noexcept { return m_key_evt_mngr.listenerCount(); }
314
315 //
316 //
317 //
318 void notifyPointer(uint16_t type, const jau::fraction_timespec& when,
319 PointerType ptype, uint16_t id,
320 jau::math::Vec2i pos, uint16_t clickCount, InputButton button,
321 jau::math::Vec3f rotation, float rotationScale) noexcept {
322 m_ptr_evt_mngr.dispatch(type, when, shared(), keyTracker().modifier(), ptype, id, pos, clickCount, button, rotation, rotationScale);
323 }
324 void addPointerListener(const PointerListenerRef& l) { m_ptr_evt_mngr.addListener(l); }
325 size_t removePointerListener(const PointerListenerRef& l) { return m_ptr_evt_mngr.removeListener(l); }
326 size_t removeAllPointerListener() { return m_ptr_evt_mngr.removeAllListener(); }
327 size_t pointerListenerCount() const noexcept { return m_ptr_evt_mngr.listenerCount(); }
328
329 //
330 //
331 //
332
333 void addRenderListener(const RenderListenerRef& l) { m_render_listener.push_back(l); }
334
336 return m_render_listener.erase_matching(l, true,
337 [](const RenderListenerRef& a, const RenderListenerRef& b) noexcept -> bool { return a.get() == b.get(); } );
338 }
339
341 const size_t count = m_render_listener.size();
342 m_render_listener.clear(true);
343 return count;
344 }
345
346 size_t renderListenerCount() const noexcept { return m_render_listener.size(); }
347
348 void disposeRenderListener(bool clearRenderListener, const jau::fraction_timespec& when) noexcept;
349
350 void disposedNotify(const jau::fraction_timespec& when) noexcept override {
353 m_window_handle = 0;
354 }
355 void dispose(const jau::fraction_timespec& when) noexcept override {
357 disposeRenderListener(true, when);
358 Surface::dispose(when);
359 if( m_window_handle ) {
360 disposeImpl(m_window_handle);
361 m_window_handle = 0;
362 }
363 }
364
365 //
366 //
367 //
368
369 std::string toString() const noexcept;
370 };
371
372 /**@}*/
373
374} // namespace gamp::wt
375
376#endif /* GAMP_WTWINDOW_HPP_ */
constexpr RenderListener(Private) noexcept
Private ctor for shared_ptr<RenderListener> instance method w/o public ctor.
Definition Window.hpp:60
std::string toString() const noexcept
Definition Window.hpp:112
void setPendingActions(RenderActions v) noexcept
Definition Window.hpp:66
virtual bool init(const WindowRef &, const jau::fraction_timespec &)=0
Called by the drawable immediately after the render context is initialized.
virtual void reshape(const WindowRef &, const jau::math::Recti &, const jau::fraction_timespec &)=0
Called by the drawable during the first repaint after the component has been resized.
virtual void display(const WindowRef &, const jau::fraction_timespec &)=0
Called by the drawable to initiate rendering by the client.
RenderActions & pendingActions() noexcept
Definition Window.hpp:65
RenderActions pendingActions() const noexcept
Definition Window.hpp:64
virtual ~RenderListener() noexcept=default
virtual void dispose(const WindowRef &, const jau::fraction_timespec &)=0
Notifies the listener to perform the release of all renderer resources per context,...
virtual std::string toStringImpl() const noexcept
Definition Window.hpp:110
constexpr handle_t surfaceHandle() const noexcept
Returns the handle to the surface for this NativeSurface.
Definition Surface.hpp:188
void setSurfaceSize(const Vec2i &sz) noexcept
Definition Surface.hpp:72
Surface(Private, handle_t surface_handle, const Vec2i &surface_size)
Private ctor for single Surface::create() method w/o public ctor.
Definition Surface.hpp:79
std::shared_ptr< ChildT > shared_from_base()
Definition Surface.hpp:68
constexpr bool isBLOriented() const noexcept
Returns true if this surface is rendered in OpenGL's coordinate system, origin at bottom left.
Definition Surface.hpp:168
virtual void dispose(const jau::fraction_timespec &) noexcept
Definition Surface.hpp:102
virtual void disposedNotify(const jau::fraction_timespec &) noexcept
Definition Surface.hpp:98
constexpr const Vec2i & surfaceSize() const noexcept
Returns the surface size of the client area excluding insets (window decorations) in pixel units.
Definition Surface.hpp:171
constexpr Vec2i windowPos() const noexcept
Returns the window top-lect position of client-area in window units.
Definition Window.hpp:230
constexpr WindowState state() const noexcept
Definition Window.hpp:267
void display(const jau::fraction_timespec &when) noexcept
Definition gamp_wt.cpp:78
constexpr bool hasFocus() const noexcept
Definition Window.hpp:268
constexpr handle_t windowHandle() const noexcept
Returns the handle to the surface for this NativeSurface.
Definition Window.hpp:264
void addRenderListener(const RenderListenerRef &l)
Definition Window.hpp:333
void notifyKeyReleased(const jau::fraction_timespec &when, VKeyCode keySym, InputModifier keySymMods, uint16_t keyChar) noexcept
Definition Window.hpp:307
size_t renderListenerCount() const noexcept
Definition Window.hpp:346
constexpr bool isVisible() const noexcept
Definition Window.hpp:269
bool isValid() const noexcept override
Definition Window.hpp:265
void notifyWindowEvent(uint16_t type, const jau::fraction_timespec &when, bool value=true) noexcept
Definition Window.hpp:278
void addWindowListener(const WindowListenerRef &l)
Definition Window.hpp:294
constexpr Vec2i windowSize() const noexcept
Returns the window size of the client area excluding insets (window decorations) in window units.
Definition Window.hpp:233
void operator=(const Window &)=delete
size_t removeKeyListener(const KeyListenerRef &l)
Definition Window.hpp:311
void setFocused(bool v) noexcept
Definition Window.hpp:153
size_t windowListenerCount() const noexcept
Definition Window.hpp:297
void notifyWindowResize(const jau::fraction_timespec &when, const jau::math::Vec2i &winSize, const jau::math::Vec2i &surfSize) noexcept
Definition Window.hpp:281
const WindowRef shared()
Definition Window.hpp:227
~Window() noexcept override=default
Releases this instance.
Window(const Window &)=delete
void notifyWindowMoved(const jau::fraction_timespec &when, const jau::math::Vec2i &winPos) noexcept
Definition Window.hpp:287
size_t pointerListenerCount() const noexcept
Definition Window.hpp:327
size_t removeAllRenderListener()
Definition Window.hpp:340
void notifyKeyPressed(const jau::fraction_timespec &when, VKeyCode keySym, InputModifier keySymMods, uint16_t keyChar) noexcept
Definition Window.hpp:304
size_t removeRenderListener(const RenderListenerRef &l)
Definition Window.hpp:335
size_t removePointerListener(const PointerListenerRef &l)
Definition Window.hpp:325
size_t removeAllPointerListener()
Definition Window.hpp:326
void setVisible(bool v) noexcept
Definition Window.hpp:154
size_t removeAllWindowListener()
Definition Window.hpp:296
void notifyPointer(uint16_t type, const jau::fraction_timespec &when, PointerType ptype, uint16_t id, jau::math::Vec2i pos, uint16_t clickCount, InputButton button, jau::math::Vec3f rotation, float rotationScale) noexcept
Definition Window.hpp:318
size_t removeAllKeyListener()
Definition Window.hpp:312
static WindowRef create(const char *title, int wwidth, int wheight, bool verbose=false)
Create an new instance using a native windowing toolkit.
static WindowRef wrapNative(handle_t window_handle, const Recti &window_bounds, handle_t surface_handle, const Vec2i &surface_size)
Create an new instance, wrapping the native windowing toolkit's handle/resources.
Definition Window.hpp:199
void addPointerListener(const PointerListenerRef &l)
Definition Window.hpp:324
void disposedNotify(const jau::fraction_timespec &when) noexcept override
Definition Window.hpp:350
SurfaceRef nativeSurface()
Returns the associated Surface of this SurfaceHolder.
Definition Window.hpp:226
void setWindowPos(const Vec2i &sz) noexcept
Definition Window.hpp:151
const KeyboardTracker & keyTracker() const noexcept
Definition Window.hpp:302
constexpr const Recti & windowBounds() const noexcept
Returns the window client-area top-left position and size excluding insets (window decorations) in wi...
Definition Window.hpp:236
size_t removeWindowListener(const WindowListenerRef &l)
Definition Window.hpp:295
void dispose(const jau::fraction_timespec &when) noexcept override
Definition Window.hpp:355
bool surfaceSwap() noexcept override
Provide a mechanism to utilize custom (pre-) swap surface code.
void setWindowBounds(const Recti &r) noexcept
Definition Window.hpp:150
Window(Private, handle_t window_handle, const Recti &window_bounds, handle_t surface_handle, const Vec2i &surface_size)
Private ctor for single Window::create() method w/o public ctor.
Definition Window.hpp:182
void setWindowSize(const Vec2i &sz) noexcept
Definition Window.hpp:152
std::string toString() const noexcept
Definition gamp_wt.cpp:145
size_t keyListenerCount() const noexcept
Definition Window.hpp:313
constexpr bool isPointerBLOriented() const noexcept
Returns true if this window delivers PointerEvent in OpenGL's coordinate system, origin at bottom lef...
Definition Window.hpp:247
void disposeRenderListener(bool clearRenderListener, const jau::fraction_timespec &when) noexcept
Definition gamp_wt.cpp:129
void addKeyListener(const KeyListenerRef &l)
Definition Window.hpp:310
Listener for multiple WindowEvent.
Definition WinEvent.hpp:79
Implementation of a Copy-On-Write (CoW) using jau::darray as the underlying storage,...
constexpr_atomic storage_ref_t snapshot() const noexcept
Returns the current snapshot of the underlying shared storage by reference.
constexpr bool is_zero() const noexcept
Return true if area is zero.
Definition recti.hpp:125
constexpr bool value(const Bool rhs) noexcept
#define JAU_MAKE_BITFIELD_ENUM_STRING(type,...)
constexpr bool is_set(const E mask, const E bits) noexcept
constexpr E & write(E &store, const E bits, bool set) noexcept
If set==true, sets the bits in store, i.e.
#define JAU_MAKE_ENUM_INFO(type,...)
std::shared_ptr< WindowListener > WindowListenerRef
Definition WinEvent.hpp:113
std::shared_ptr< PointerListener > PointerListenerRef
std::shared_ptr< KeyListener > KeyListenerRef
Definition KeyEvent.hpp:909
VKeyCode
Virtual key code following UTF16 specification.
Definition KeyEvent.hpp:45
static constexpr uint16_t EVENT_WINDOW_DESTROY_NOTIFY
Definition Event.hpp:50
static constexpr uint16_t EVENT_WINDOW_DESTROYED
Definition Event.hpp:53
PointerType
Type of pointer devices.
std::shared_ptr< RenderListener > RenderListenerRef
Definition Window.hpp:122
RenderActions
Definition Window.hpp:43
std::shared_ptr< Window > WindowRef
Definition Event.hpp:36
std::shared_ptr< Surface > SurfaceRef
uintptr_t handle_t
A native handle type, big enough to store a pointer.
Definition GampTypes.hpp:47
Vector2I< int > Vec2i
Definition vec2i.hpp:328
RectI< int > Recti
Definition recti.hpp:139
Vector3F< float > Vec3f
Definition vec3f.hpp:436
std::string to_string(const math_error_t v) noexcept
Returns std::string representation of math_error_t.
std::string to_hexstring(value_type const &v, const bool skipLeading0x=false) noexcept
Produce a lower-case hexadecimal string representation with leading 0x in MSB of the given pointer.
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition backtrace.hpp:32
STL namespace.
Timespec structure using int64_t for its components in analogy to struct timespec_t on 64-bit platfor...