Mercurial > hg > pub > prymula > com
comparison DPF-Prymula-audioplugins/dpf/dgl/Window.hpp @ 3:84e66ea83026
DPF-Prymula-audioplugins-0.231015-2
author | prymula <prymula76@outlook.com> |
---|---|
date | Mon, 16 Oct 2023 21:53:34 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
2:cf2cb71d31dd | 3:84e66ea83026 |
---|---|
1 /* | |
2 * DISTRHO Plugin Framework (DPF) | |
3 * Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com> | |
4 * | |
5 * Permission to use, copy, modify, and/or distribute this software for any purpose with | |
6 * or without fee is hereby granted, provided that the above copyright notice and this | |
7 * permission notice appear in all copies. | |
8 * | |
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |
10 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |
11 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |
12 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |
13 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
15 */ | |
16 | |
17 #ifndef DGL_WINDOW_HPP_INCLUDED | |
18 #define DGL_WINDOW_HPP_INCLUDED | |
19 | |
20 #include "Geometry.hpp" | |
21 | |
22 #ifndef DGL_FILE_BROWSER_DISABLED | |
23 # include "FileBrowserDialog.hpp" | |
24 #endif | |
25 | |
26 #include <vector> | |
27 | |
28 #ifdef DISTRHO_NAMESPACE | |
29 START_NAMESPACE_DISTRHO | |
30 class PluginWindow; | |
31 END_NAMESPACE_DISTRHO | |
32 #endif | |
33 | |
34 START_NAMESPACE_DGL | |
35 | |
36 class Application; | |
37 class TopLevelWidget; | |
38 | |
39 // ----------------------------------------------------------------------- | |
40 | |
41 /** | |
42 DGL Window class. | |
43 | |
44 This is the where all OS-related events initially happen, before being propagated to any widgets. | |
45 | |
46 A Window MUST have an Application instance tied to it. | |
47 It is not possible to swap Application instances from within the lifetime of a Window. | |
48 But it is possible to completely change the Widgets that a Window contains during its lifetime. | |
49 | |
50 Typically the event handling functions as following: | |
51 Application -> Window -> Top-Level-Widget -> SubWidgets | |
52 | |
53 Please note that, unlike many other graphical toolkits out there, | |
54 DGL makes a clear distinction between a Window and a Widget. | |
55 You cannot directly draw in a Window, you need to create a Widget for that. | |
56 | |
57 Also, a Window MUST have a single top-level Widget. | |
58 The Window will take care of global screen positioning and resizing, everything else is sent for widgets to handle. | |
59 | |
60 ... | |
61 */ | |
62 class DISTRHO_API Window | |
63 { | |
64 struct PrivateData; | |
65 | |
66 public: | |
67 /** | |
68 Window graphics context as a scoped struct. | |
69 This class gives graphics context drawing time to a window's widgets. | |
70 Typically used for allowing OpenGL drawing operations during a window + widget constructor. | |
71 | |
72 Unless you are subclassing the Window or StandaloneWindow classes, you do not need to care. | |
73 In such cases you will need to use this struct as a way to get a valid OpenGL context. | |
74 For example in a standalone application: | |
75 ``` | |
76 int main() | |
77 { | |
78 Application app; | |
79 Window win(app); | |
80 ScopedPointer<MyCustomTopLevelWidget> widget; | |
81 { | |
82 const Window::ScopedGraphicsContext sgc(win); | |
83 widget = new MyCustomTopLevelWidget(win); | |
84 } | |
85 app.exec(); | |
86 return 0; | |
87 } | |
88 ``` | |
89 | |
90 This struct is necessary because we cannot automatically make the window leave the OpenGL context in custom code. | |
91 And we must always cleanly enter and leave the OpenGL context. | |
92 So in order to avoid messing up the global host context, this class is used around widget creation. | |
93 */ | |
94 struct ScopedGraphicsContext | |
95 { | |
96 /** Constructor that will make the @a window graphics context the current one */ | |
97 explicit ScopedGraphicsContext(Window& window); | |
98 | |
99 /** Overloaded constructor, gives back context to its transient parent when done */ | |
100 explicit ScopedGraphicsContext(Window& window, Window& transientParentWindow); | |
101 | |
102 /** Desstructor for clearing current context, if not done yet */ | |
103 ~ScopedGraphicsContext(); | |
104 | |
105 /** Early context clearing, useful for standalone windows not created by you. */ | |
106 void done(); | |
107 | |
108 /** Get a valid context back again. */ | |
109 void reinit(); | |
110 | |
111 DISTRHO_DECLARE_NON_COPYABLE(ScopedGraphicsContext) | |
112 DISTRHO_PREVENT_HEAP_ALLOCATION | |
113 | |
114 private: | |
115 Window& window; | |
116 Window::PrivateData* const ppData; | |
117 bool active; | |
118 bool reenter; | |
119 }; | |
120 | |
121 /** | |
122 Constructor for a regular, standalone window. | |
123 */ | |
124 explicit Window(Application& app); | |
125 | |
126 /** | |
127 Constructor for a modal window, by having another window as its transient parent. | |
128 The Application instance must be the same between the 2 windows. | |
129 */ | |
130 explicit Window(Application& app, Window& transientParentWindow); | |
131 | |
132 /** | |
133 Constructor for an embed Window without known size, | |
134 typically used in modules or plugins that run inside another host. | |
135 */ | |
136 explicit Window(Application& app, | |
137 uintptr_t parentWindowHandle, | |
138 double scaleFactor, | |
139 bool resizable); | |
140 | |
141 /** | |
142 Constructor for an embed Window with known size, | |
143 typically used in modules or plugins that run inside another host. | |
144 */ | |
145 explicit Window(Application& app, | |
146 uintptr_t parentWindowHandle, | |
147 uint width, | |
148 uint height, | |
149 double scaleFactor, | |
150 bool resizable); | |
151 | |
152 /** | |
153 Destructor. | |
154 */ | |
155 virtual ~Window(); | |
156 | |
157 /** | |
158 Whether this Window is embed into another (usually not DGL-controlled) Window. | |
159 */ | |
160 bool isEmbed() const noexcept; | |
161 | |
162 /** | |
163 Check if this window is visible / mapped. | |
164 Invisible windows do not receive events except resize. | |
165 @see setVisible(bool) | |
166 */ | |
167 bool isVisible() const noexcept; | |
168 | |
169 /** | |
170 Set window visible (or not) according to @a visible. | |
171 Only valid for standalones, embed windows are always visible. | |
172 @see isVisible(), hide(), show() | |
173 */ | |
174 void setVisible(bool visible); | |
175 | |
176 /** | |
177 Show window. | |
178 This is the same as calling setVisible(true). | |
179 @see isVisible(), setVisible(bool) | |
180 */ | |
181 void show(); | |
182 | |
183 /** | |
184 Hide window. | |
185 This is the same as calling setVisible(false). | |
186 @see isVisible(), setVisible(bool) | |
187 */ | |
188 void hide(); | |
189 | |
190 /** | |
191 Hide window and notify application of a window close event. | |
192 The application event-loop will stop when all windows have been closed. | |
193 For standalone windows only, has no effect if window is embed. | |
194 @see isEmbed() | |
195 | |
196 @note It is possible to hide the window while not stopping the event-loop. | |
197 A closed window is always hidden, but the reverse is not always true. | |
198 */ | |
199 void close(); | |
200 | |
201 /** | |
202 Check if this window is resizable (by the user or window manager). | |
203 @see setResizable | |
204 */ | |
205 bool isResizable() const noexcept; | |
206 | |
207 /** | |
208 Set window as resizable (by the user or window manager). | |
209 It is always possible to resize a window programmatically, which is not the same as the user being allowed to it. | |
210 @note This function does nothing for plugins, where the resizable state is set via macro. | |
211 @see DISTRHO_UI_USER_RESIZABLE | |
212 */ | |
213 void setResizable(bool resizable); | |
214 | |
215 /** | |
216 Get X offset, typically 0. | |
217 */ | |
218 int getOffsetX() const noexcept; | |
219 | |
220 /** | |
221 Get Y offset, typically 0. | |
222 */ | |
223 int getOffsetY() const noexcept; | |
224 | |
225 /** | |
226 Get offset. | |
227 */ | |
228 Point<int> getOffset() const noexcept; | |
229 | |
230 /** | |
231 Set X offset. | |
232 */ | |
233 void setOffsetX(int x); | |
234 | |
235 /** | |
236 Set Y offset. | |
237 */ | |
238 void setOffsetY(int y); | |
239 | |
240 /** | |
241 Set offset using @a x and @a y values. | |
242 */ | |
243 void setOffset(int x, int y); | |
244 | |
245 /** | |
246 Set offset. | |
247 */ | |
248 void setOffset(const Point<int>& offset); | |
249 | |
250 /** | |
251 Get width. | |
252 */ | |
253 uint getWidth() const noexcept; | |
254 | |
255 /** | |
256 Get height. | |
257 */ | |
258 uint getHeight() const noexcept; | |
259 | |
260 /** | |
261 Get size. | |
262 */ | |
263 Size<uint> getSize() const noexcept; | |
264 | |
265 /** | |
266 Set width. | |
267 */ | |
268 void setWidth(uint width); | |
269 | |
270 /** | |
271 Set height. | |
272 */ | |
273 void setHeight(uint height); | |
274 | |
275 /** | |
276 Set size using @a width and @a height values. | |
277 */ | |
278 void setSize(uint width, uint height); | |
279 | |
280 /** | |
281 Set size. | |
282 */ | |
283 void setSize(const Size<uint>& size); | |
284 | |
285 /** | |
286 Get the title of the window previously set with setTitle(). | |
287 */ | |
288 const char* getTitle() const noexcept; | |
289 | |
290 /** | |
291 Set the title of the window, typically displayed in the title bar or in window switchers. | |
292 | |
293 This only makes sense for non-embedded windows. | |
294 */ | |
295 void setTitle(const char* title); | |
296 | |
297 /** | |
298 Check if key repeat events are ignored. | |
299 */ | |
300 bool isIgnoringKeyRepeat() const noexcept; | |
301 | |
302 /** | |
303 Set to ignore (or not) key repeat events according to @a ignore. | |
304 */ | |
305 void setIgnoringKeyRepeat(bool ignore) noexcept; | |
306 | |
307 /** | |
308 Get the clipboard contents. | |
309 | |
310 This gets the system clipboard contents, | |
311 which may have been set with setClipboard() or copied from another application. | |
312 | |
313 Returns the clipboard contents, or null. | |
314 | |
315 @note By default only "text/plain" mimetype is supported and returned. | |
316 Override onClipboardDataOffer for supporting other types. | |
317 */ | |
318 const void* getClipboard(size_t& dataSize); | |
319 | |
320 /** | |
321 Set the clipboard contents. | |
322 | |
323 This sets the system clipboard contents, | |
324 which can be retrieved with getClipboard() or pasted into other applications. | |
325 | |
326 If using a string, the use of a null terminator is required (and must be part of dataSize).@n | |
327 The MIME type of the data "text/plain" is assumed if null is used. | |
328 */ | |
329 bool setClipboard(const char* mimeType, const void* data, size_t dataSize); | |
330 | |
331 /** | |
332 Set the mouse cursor. | |
333 | |
334 This changes the system cursor that is displayed when the pointer is inside the window. | |
335 May fail if setting the cursor is not supported on this system, | |
336 for example if compiled on X11 without Xcursor support. | |
337 */ | |
338 bool setCursor(MouseCursor cursor); | |
339 | |
340 /** | |
341 Add a callback function to be triggered on every idle cycle or on a specific timer frequency. | |
342 You can add more than one, and remove them at anytime with removeIdleCallback(). | |
343 This can be used to perform some action at a regular interval with relatively low frequency. | |
344 | |
345 If providing a timer frequency, there are a few things to note: | |
346 1. There is a platform-specific limit to the number of supported timers, and overhead associated with each, | |
347 so you should create only a few timers and perform several tasks in one if necessary. | |
348 2. This timer frequency is not guaranteed to have a resolution better than 10ms | |
349 (the maximum timer resolution on Windows) and may be rounded up if it is too short. | |
350 On X11 and MacOS, a resolution of about 1ms can usually be relied on. | |
351 */ | |
352 bool addIdleCallback(IdleCallback* callback, uint timerFrequencyInMs = 0); | |
353 | |
354 /** | |
355 Remove an idle callback previously added via addIdleCallback(). | |
356 */ | |
357 bool removeIdleCallback(IdleCallback* callback); | |
358 | |
359 /** | |
360 Get the application associated with this window. | |
361 */ | |
362 Application& getApp() const noexcept; | |
363 | |
364 /** | |
365 Get the graphics context associated with this window. | |
366 GraphicsContext is an empty struct and needs to be casted into a different type in order to be usable, | |
367 for example GraphicsContext. | |
368 @see CairoSubWidget, CairoTopLevelWidget | |
369 */ | |
370 const GraphicsContext& getGraphicsContext() const noexcept; | |
371 | |
372 /** | |
373 Get the "native" window handle. | |
374 Returned value depends on the platform: | |
375 - HaikuOS: This is a pointer to a `BView`. | |
376 - MacOS: This is a pointer to an `NSView*`. | |
377 - Windows: This is a `HWND`. | |
378 - Everything else: This is an [X11] `Window`. | |
379 */ | |
380 uintptr_t getNativeWindowHandle() const noexcept; | |
381 | |
382 /** | |
383 Get the scale factor requested for this window. | |
384 This is purely informational, and up to developers to choose what to do with it. | |
385 | |
386 If you do not want to deal with this yourself, | |
387 consider using setGeometryConstraints() where you can specify to automatically scale the window contents. | |
388 @see setGeometryConstraints | |
389 */ | |
390 double getScaleFactor() const noexcept; | |
391 | |
392 /** | |
393 Grab the keyboard input focus. | |
394 */ | |
395 void focus(); | |
396 | |
397 #ifndef DGL_FILE_BROWSER_DISABLED | |
398 /** | |
399 Open a file browser dialog with this window as transient parent. | |
400 A few options can be specified to setup the dialog. | |
401 | |
402 If a path is selected, onFileSelected() will be called with the user chosen path. | |
403 If the user cancels or does not pick a file, onFileSelected() will be called with nullptr as filename. | |
404 | |
405 This function does not block the event loop. | |
406 */ | |
407 bool openFileBrowser(const DGL_NAMESPACE::FileBrowserOptions& options = FileBrowserOptions()); | |
408 #endif | |
409 | |
410 /** | |
411 Request repaint of this window, for the entire area. | |
412 */ | |
413 void repaint() noexcept; | |
414 | |
415 /** | |
416 Request partial repaint of this window, with bounds according to @a rect. | |
417 */ | |
418 void repaint(const Rectangle<uint>& rect) noexcept; | |
419 | |
420 /** | |
421 Render this window's content into a picture file, specified by @a filename. | |
422 Window must be visible and on screen. | |
423 Written picture format is PPM. | |
424 */ | |
425 void renderToPicture(const char* filename); | |
426 | |
427 /** | |
428 Run this window as a modal, blocking input events from the parent. | |
429 Only valid for windows that have been created with another window as parent (as passed in the constructor). | |
430 Can optionally block-wait, but such option is only available if the application is running as standalone. | |
431 */ | |
432 void runAsModal(bool blockWait = false); | |
433 | |
434 /** | |
435 Get the geometry constraints set for the Window. | |
436 @see setGeometryConstraints | |
437 */ | |
438 Size<uint> getGeometryConstraints(bool& keepAspectRatio); | |
439 | |
440 /** | |
441 Set geometry constraints for the Window when resized by the user, and optionally scale contents automatically. | |
442 */ | |
443 void setGeometryConstraints(uint minimumWidth, | |
444 uint minimumHeight, | |
445 bool keepAspectRatio = false, | |
446 bool automaticallyScale = false, | |
447 bool resizeNowIfAutoScaling = true); | |
448 | |
449 /** | |
450 Set the transient parent of the window. | |
451 | |
452 Set this for transient children like dialogs, to have them properly associated with their parent window. | |
453 This should be not be called for embed windows, or after making the window visible. | |
454 */ | |
455 void setTransientParent(uintptr_t transientParentWindowHandle); | |
456 | |
457 /** DEPRECATED Use isIgnoringKeyRepeat(). */ | |
458 DISTRHO_DEPRECATED_BY("isIgnoringKeyRepeat()") | |
459 inline bool getIgnoringKeyRepeat() const noexcept { return isIgnoringKeyRepeat(); } | |
460 | |
461 /** DEPRECATED Use getScaleFactor(). */ | |
462 DISTRHO_DEPRECATED_BY("getScaleFactor()") | |
463 inline double getScaling() const noexcept { return getScaleFactor(); } | |
464 | |
465 /** DEPRECATED Use runAsModal(bool). */ | |
466 DISTRHO_DEPRECATED_BY("runAsModal(bool)") | |
467 inline void exec(bool blockWait = false) { runAsModal(blockWait); } | |
468 | |
469 protected: | |
470 /** | |
471 Get the types available for the data in a clipboard. | |
472 Must only be called within the context of onClipboardDataOffer. | |
473 */ | |
474 std::vector<ClipboardDataOffer> getClipboardDataOfferTypes(); | |
475 | |
476 /** | |
477 A function called when clipboard has data present, possibly with several datatypes. | |
478 While handling this event, the data types can be investigated with getClipboardDataOfferTypes() to decide whether to accept the offer. | |
479 | |
480 Reimplement and return a non-zero id to accept the clipboard data offer for a particular type. | |
481 Applications must ignore any type they do not recognize. | |
482 | |
483 The default implementation accepts the "text/plain" mimetype. | |
484 */ | |
485 virtual uint32_t onClipboardDataOffer(); | |
486 | |
487 /** | |
488 A function called when the window is attempted to be closed. | |
489 Returning true closes the window, which is the default behaviour. | |
490 Override this method and return false to prevent the window from being closed by the user. | |
491 | |
492 This method is not used for embed windows, and not even made available in DISTRHO_NAMESPACE::UI. | |
493 For embed windows, closing is handled by the host/parent process and we have no control over it. | |
494 As such, a close action on embed windows will always succeed and cannot be cancelled. | |
495 | |
496 NOTE: This currently does not work under macOS. | |
497 */ | |
498 virtual bool onClose(); | |
499 | |
500 /** | |
501 A function called when the window gains or loses the keyboard focus. | |
502 The default implementation does nothing. | |
503 */ | |
504 virtual void onFocus(bool focus, CrossingMode mode); | |
505 | |
506 /** | |
507 A function called when the window is resized. | |
508 If there is a top-level widget associated with this window, its size will be set right after this function. | |
509 The default implementation sets up drawing context where necessary. | |
510 */ | |
511 virtual void onReshape(uint width, uint height); | |
512 | |
513 /** | |
514 A function called when scale factor requested for this window changes. | |
515 The default implementation does nothing. | |
516 WARNING function needs a proper name | |
517 */ | |
518 virtual void onScaleFactorChanged(double scaleFactor); | |
519 | |
520 #ifndef DGL_FILE_BROWSER_DISABLED | |
521 /** | |
522 A function called when a path is selected by the user, as triggered by openFileBrowser(). | |
523 This action happens after the user confirms the action, so the file browser dialog will be closed at this point. | |
524 The default implementation does nothing. | |
525 */ | |
526 virtual void onFileSelected(const char* filename); | |
527 | |
528 /** DEPRECATED Use onFileSelected(). */ | |
529 DISTRHO_DEPRECATED_BY("onFileSelected(const char*)") | |
530 inline virtual void fileBrowserSelected(const char* filename) { return onFileSelected(filename); } | |
531 #endif | |
532 | |
533 private: | |
534 PrivateData* const pData; | |
535 friend class Application; | |
536 friend class TopLevelWidget; | |
537 #ifdef DISTRHO_NAMESPACE | |
538 friend class DISTRHO_NAMESPACE::PluginWindow; | |
539 #endif | |
540 | |
541 /** @internal */ | |
542 explicit Window(Application& app, | |
543 uintptr_t parentWindowHandle, | |
544 uint width, | |
545 uint height, | |
546 double scaleFactor, | |
547 bool resizable, | |
548 bool usesSizeRequest, | |
549 bool doPostInit); | |
550 | |
551 DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Window) | |
552 }; | |
553 | |
554 // ----------------------------------------------------------------------- | |
555 | |
556 END_NAMESPACE_DGL | |
557 | |
558 #endif // DGL_WINDOW_HPP_INCLUDED |