DISTRHO Plugin Framework
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

310 lines
9.5KB

  1. /*
  2. * DISTRHO Plugin Framework (DPF)
  3. * Copyright (C) 2012-2021 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. #ifndef DGL_WINDOW_PRIVATE_DATA_HPP_INCLUDED
  17. #define DGL_WINDOW_PRIVATE_DATA_HPP_INCLUDED
  18. #include "../Window.hpp"
  19. #include "../Widget.hpp"
  20. #include "ApplicationPrivateData.hpp"
  21. #include "pugl.hpp"
  22. #include <list>
  23. START_NAMESPACE_DGL
  24. class TopLevelWidget;
  25. // -----------------------------------------------------------------------
  26. struct Window::PrivateData : IdleCallback {
  27. /** Reference to the DGL Application class this (private data) window associates with. */
  28. Application& app;
  29. /** Direct access to the DGL Application private data where we registers ourselves in. */
  30. Application::PrivateData* const appData;
  31. /** Pointer to the the DGL Window class that this private data belongs to. */
  32. Window* const self;
  33. /** Pugl view instance. */
  34. PuglView* const view;
  35. /** Pugl view instance of the transient parent window. */
  36. PuglView* const transientParentView;
  37. /** Reserved space for graphics context. */
  38. mutable uint8_t graphicsContext[sizeof(void*)];
  39. /** The top-level widgets associated with this Window. */
  40. std::list<TopLevelWidget*> topLevelWidgets;
  41. /** Whether this Window is closed (not visible or counted in the Application it is tied to).
  42. Defaults to true unless embed (embed windows are never closed). */
  43. bool isClosed;
  44. /** Whether this Window is currently visible/mapped. Defaults to false. */
  45. bool isVisible;
  46. /** Whether this Window is embed into another (usually not DGL-controlled) Window. */
  47. const bool isEmbed;
  48. /** Scale factor to report to widgets on request, purely informational. */
  49. double scaleFactor;
  50. /** Automatic scaling to apply on widgets, implemented internally. */
  51. bool autoScaling;
  52. double autoScaleFactor;
  53. /** Pugl geometry constraints access. */
  54. uint minWidth, minHeight;
  55. bool keepAspectRatio;
  56. #ifdef DISTRHO_OS_WINDOWS
  57. /** Selected file for openFileBrowser on windows, stored for fake async operation. */
  58. const char* win32SelectedFile;
  59. #endif
  60. /** Modal window setup. */
  61. struct Modal {
  62. PrivateData* parent; // parent of this window (so we can become modal)
  63. PrivateData* child; // child window to give focus to when modal mode is enabled
  64. bool enabled; // wherever modal mode is enabled (only possible if parent != null)
  65. /** Constructor for a non-modal window. */
  66. Modal() noexcept
  67. : parent(nullptr),
  68. child(nullptr),
  69. enabled(false) {}
  70. /** Constructor for a modal window (with a parent). */
  71. Modal(PrivateData* const p) noexcept
  72. : parent(p),
  73. child(nullptr),
  74. enabled(false) {}
  75. /** Destructor. */
  76. ~Modal() noexcept
  77. {
  78. DISTRHO_SAFE_ASSERT(! enabled);
  79. }
  80. DISTRHO_DECLARE_NON_COPYABLE(Modal)
  81. DISTRHO_PREVENT_HEAP_ALLOCATION
  82. } modal;
  83. /** Constructor for a regular, standalone window. */
  84. explicit PrivateData(Application& app, Window* self);
  85. /** Constructor for a modal window. */
  86. explicit PrivateData(Application& app, Window* self, PrivateData* ppData);
  87. /** Constructor for an embed Window, with a few extra hints from the host side. */
  88. explicit PrivateData(Application& app, Window* self, uintptr_t parentWindowHandle, double scaling, bool resizable);
  89. /** Constructor for an embed Window, with a few extra hints from the host side. */
  90. explicit PrivateData(Application& app, Window* self, uintptr_t parentWindowHandle,
  91. uint width, uint height, double scaling, bool resizable);
  92. /** Destructor. */
  93. ~PrivateData() override;
  94. /** Helper initialization function called at the end of all this class constructors. */
  95. void initPre(uint width, uint height, bool resizable);
  96. /** Helper initialization function called on the Window constructor after we are done. */
  97. void initPost();
  98. /** Hide window and notify application of a window close event.
  99. * Does nothing if window is embed (that is, not standalone).
  100. * The application event-loop will stop when all windows have been closed.
  101. *
  102. * @note It is possible to hide the window while not stopping the event-loop.
  103. * A closed window is always hidden, but the reverse is not always true.
  104. */
  105. void close();
  106. void show();
  107. void hide();
  108. void focus();
  109. void setResizable(bool resizable);
  110. const GraphicsContext& getGraphicsContext() const noexcept;
  111. // idle callback stuff
  112. void idleCallback() override;
  113. bool addIdleCallback(IdleCallback* callback, uint timerFrequencyInMs);
  114. bool removeIdleCallback(IdleCallback* callback);
  115. #ifndef DGL_FILE_BROWSER_DISABLED
  116. // file handling
  117. bool openFileBrowser(const Window::FileBrowserOptions& options);
  118. # ifdef DISTRHO_OS_MAC
  119. static void openPanelCallback(PuglView* view, const char* path);
  120. # endif
  121. #endif
  122. // modal handling
  123. void startModal();
  124. void stopModal();
  125. void runAsModal(bool blockWait);
  126. // pugl events
  127. void onPuglConfigure(double width, double height);
  128. void onPuglExpose();
  129. void onPuglClose();
  130. void onPuglFocus(bool focus, CrossingMode mode);
  131. void onPuglKey(const Widget::KeyboardEvent& ev);
  132. void onPuglSpecial(const Widget::SpecialEvent& ev);
  133. void onPuglText(const Widget::CharacterInputEvent& ev);
  134. void onPuglMouse(const Widget::MouseEvent& ev);
  135. void onPuglMotion(const Widget::MotionEvent& ev);
  136. void onPuglScroll(const Widget::ScrollEvent& ev);
  137. // Pugl event handling entry point
  138. static PuglStatus puglEventCallback(PuglView* view, const PuglEvent* event);
  139. DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData)
  140. };
  141. // -----------------------------------------------------------------------
  142. END_NAMESPACE_DGL
  143. #if 0
  144. // #if defined(DISTRHO_OS_HAIKU)
  145. // BApplication* bApplication;
  146. // BView* bView;
  147. // BWindow* bWindow;
  148. #if defined(DISTRHO_OS_MAC)
  149. // NSView<PuglGenericView>* mView;
  150. // id mWindow;
  151. // id mParentWindow;
  152. # ifndef DGL_FILE_BROWSER_DISABLED
  153. NSOpenPanel* fOpenFilePanel;
  154. id fFilePanelDelegate;
  155. # endif
  156. #elif defined(DISTRHO_OS_WINDOWS)
  157. // HWND hwnd;
  158. // HWND hwndParent;
  159. # ifndef DGL_FILE_BROWSER_DISABLED
  160. String fSelectedFile;
  161. # endif
  162. #endif
  163. #endif
  164. #if 0
  165. // -----------------------------------------------------------------------
  166. // Window Private
  167. struct Window::PrivateData {
  168. // -------------------------------------------------------------------
  169. bool handlePluginSpecial(const bool press, const Key key)
  170. {
  171. DBGp("PUGL: handlePluginSpecial : %i %i\n", press, key);
  172. if (fModal.childFocus != nullptr)
  173. {
  174. fModal.childFocus->focus();
  175. return true;
  176. }
  177. int mods = 0x0;
  178. switch (key)
  179. {
  180. case kKeyShift:
  181. mods |= kModifierShift;
  182. break;
  183. case kKeyControl:
  184. mods |= kModifierControl;
  185. break;
  186. case kKeyAlt:
  187. mods |= kModifierAlt;
  188. break;
  189. default:
  190. break;
  191. }
  192. if (mods != 0x0)
  193. {
  194. if (press)
  195. fView->mods |= mods;
  196. else
  197. fView->mods &= ~(mods);
  198. }
  199. Widget::SpecialEvent ev;
  200. ev.press = press;
  201. ev.key = key;
  202. ev.mod = static_cast<Modifier>(fView->mods);
  203. ev.time = 0;
  204. FOR_EACH_WIDGET_INV(rit)
  205. {
  206. Widget* const widget(*rit);
  207. if (widget->isVisible() && widget->onSpecial(ev))
  208. return true;
  209. }
  210. return false;
  211. }
  212. #if defined(DISTRHO_OS_MAC) && !defined(DGL_FILE_BROWSER_DISABLED)
  213. static void openPanelDidEnd(NSOpenPanel* panel, int returnCode, void *userData)
  214. {
  215. PrivateData* pData = (PrivateData*)userData;
  216. if (returnCode == NSOKButton)
  217. {
  218. NSArray* urls = [panel URLs];
  219. NSURL* fileUrl = nullptr;
  220. for (NSUInteger i = 0, n = [urls count]; i < n && !fileUrl; ++i)
  221. {
  222. NSURL* url = (NSURL*)[urls objectAtIndex:i];
  223. if ([url isFileURL])
  224. fileUrl = url;
  225. }
  226. if (fileUrl)
  227. {
  228. PuglView* view = pData->fView;
  229. if (view->fileSelectedFunc)
  230. {
  231. const char* fileName = [fileUrl.path UTF8String];
  232. view->fileSelectedFunc(view, fileName);
  233. }
  234. }
  235. }
  236. [pData->fOpenFilePanel release];
  237. pData->fOpenFilePanel = nullptr;
  238. }
  239. #endif
  240. // -------------------------------------------------------------------
  241. DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData)
  242. };
  243. #endif
  244. #endif // DGL_WINDOW_PRIVATE_DATA_HPP_INCLUDED