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