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.

374 lines
9.0KB

  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. #include "WindowPrivateData.hpp"
  17. #include "pugl.hpp"
  18. START_NAMESPACE_DGL
  19. // -----------------------------------------------------------------------
  20. // ScopedGraphicsContext
  21. Window::ScopedGraphicsContext::ScopedGraphicsContext(Window& win)
  22. : window(win)
  23. {
  24. puglBackendEnter(window.pData->view);
  25. }
  26. Window::ScopedGraphicsContext::~ScopedGraphicsContext()
  27. {
  28. puglBackendLeave(window.pData->view);
  29. }
  30. // -----------------------------------------------------------------------
  31. // Window
  32. Window::Window(Application& app)
  33. : pData(new PrivateData(app, this))
  34. {
  35. pData->initPost();
  36. }
  37. Window::Window(Application& app, Window& parent)
  38. : pData(new PrivateData(app, this, parent.pData))
  39. {
  40. pData->initPost();
  41. }
  42. Window::Window(Application& app,
  43. const uintptr_t parentWindowHandle,
  44. const double scaleFactor,
  45. const bool resizable)
  46. : pData(new PrivateData(app, this, parentWindowHandle, scaleFactor, resizable))
  47. {
  48. pData->initPost();
  49. }
  50. Window::Window(Application& app,
  51. const uintptr_t parentWindowHandle,
  52. const uint width,
  53. const uint height,
  54. const double scaleFactor,
  55. const bool resizable)
  56. : pData(new PrivateData(app, this, parentWindowHandle, width, height, scaleFactor, resizable))
  57. {
  58. pData->initPost();
  59. }
  60. Window::~Window()
  61. {
  62. delete pData;
  63. }
  64. bool Window::isEmbed() const noexcept
  65. {
  66. return pData->isEmbed;
  67. }
  68. bool Window::isVisible() const noexcept
  69. {
  70. return pData->isVisible;
  71. }
  72. void Window::setVisible(const bool visible)
  73. {
  74. if (visible)
  75. pData->show();
  76. else
  77. pData->hide();
  78. }
  79. void Window::show()
  80. {
  81. pData->show();
  82. }
  83. void Window::hide()
  84. {
  85. pData->hide();
  86. }
  87. void Window::close()
  88. {
  89. pData->close();
  90. }
  91. bool Window::isResizable() const noexcept
  92. {
  93. return puglGetViewHint(pData->view, PUGL_RESIZABLE) == PUGL_TRUE;
  94. }
  95. void Window::setResizable(const bool resizable)
  96. {
  97. pData->setResizable(resizable);
  98. }
  99. uint Window::getWidth() const noexcept
  100. {
  101. const double width = puglGetFrame(pData->view).width;
  102. DISTRHO_SAFE_ASSERT_RETURN(width >= 0.0, 0);
  103. return static_cast<uint>(width + 0.5);
  104. }
  105. uint Window::getHeight() const noexcept
  106. {
  107. const double height = puglGetFrame(pData->view).height;
  108. DISTRHO_SAFE_ASSERT_RETURN(height >= 0.0, 0);
  109. return static_cast<uint>(height + 0.5);
  110. }
  111. Size<uint> Window::getSize() const noexcept
  112. {
  113. const PuglRect rect = puglGetFrame(pData->view);
  114. DISTRHO_SAFE_ASSERT_RETURN(rect.width >= 0.0, Size<uint>());
  115. DISTRHO_SAFE_ASSERT_RETURN(rect.height >= 0.0, Size<uint>());
  116. return Size<uint>(static_cast<uint>(rect.width + 0.5),
  117. static_cast<uint>(rect.height + 0.5));
  118. }
  119. void Window::setWidth(const uint width)
  120. {
  121. setSize(width, getHeight());
  122. }
  123. void Window::setHeight(const uint height)
  124. {
  125. setSize(getWidth(), height);
  126. }
  127. void Window::setSize(uint width, uint height)
  128. {
  129. DISTRHO_SAFE_ASSERT_UINT2_RETURN(width > 1 && height > 1, width, height,);
  130. if (pData->isEmbed)
  131. {
  132. const double scaleFactor = pData->scaleFactor;
  133. const uint minWidth = static_cast<uint>(pData->minWidth * scaleFactor + 0.5);
  134. const uint minHeight = static_cast<uint>(pData->minHeight * scaleFactor + 0.5);
  135. // handle geometry constraints here
  136. if (width < minWidth)
  137. width = minWidth;
  138. if (height < minHeight)
  139. height = minHeight;
  140. if (pData->keepAspectRatio)
  141. {
  142. const double ratio = static_cast<double>(pData->minWidth)
  143. / static_cast<double>(pData->minHeight);
  144. const double reqRatio = static_cast<double>(width)
  145. / static_cast<double>(height);
  146. if (d_isNotEqual(ratio, reqRatio))
  147. {
  148. // fix width
  149. if (reqRatio > ratio)
  150. width = height * ratio;
  151. // fix height
  152. else
  153. height = width / ratio;
  154. }
  155. }
  156. }
  157. puglSetWindowSize(pData->view, width, height);
  158. }
  159. void Window::setSize(const Size<uint>& size)
  160. {
  161. setSize(size.getWidth(), size.getHeight());
  162. }
  163. const char* Window::getTitle() const noexcept
  164. {
  165. return puglGetWindowTitle(pData->view);
  166. }
  167. void Window::setTitle(const char* const title)
  168. {
  169. puglSetWindowTitle(pData->view, title);
  170. }
  171. bool Window::isIgnoringKeyRepeat() const noexcept
  172. {
  173. return puglGetViewHint(pData->view, PUGL_IGNORE_KEY_REPEAT) == PUGL_TRUE;
  174. }
  175. void Window::setIgnoringKeyRepeat(const bool ignore) noexcept
  176. {
  177. puglSetViewHint(pData->view, PUGL_IGNORE_KEY_REPEAT, ignore);
  178. }
  179. bool Window::addIdleCallback(IdleCallback* const callback, const uint timerFrequencyInMs)
  180. {
  181. DISTRHO_SAFE_ASSERT_RETURN(callback != nullptr, false)
  182. return pData->addIdleCallback(callback, timerFrequencyInMs);
  183. }
  184. bool Window::removeIdleCallback(IdleCallback* const callback)
  185. {
  186. DISTRHO_SAFE_ASSERT_RETURN(callback != nullptr, false)
  187. return pData->removeIdleCallback(callback);
  188. }
  189. Application& Window::getApp() const noexcept
  190. {
  191. return pData->app;
  192. }
  193. #ifndef DPF_TEST_WINDOW_CPP
  194. const GraphicsContext& Window::getGraphicsContext() const noexcept
  195. {
  196. return pData->getGraphicsContext();
  197. }
  198. #endif
  199. uintptr_t Window::getNativeWindowHandle() const noexcept
  200. {
  201. return puglGetNativeWindow(pData->view);
  202. }
  203. double Window::getScaleFactor() const noexcept
  204. {
  205. return pData->scaleFactor;
  206. }
  207. void Window::focus()
  208. {
  209. pData->focus();
  210. }
  211. #ifndef DGL_FILE_BROWSER_DISABLED
  212. bool Window::openFileBrowser(const FileBrowserOptions& options)
  213. {
  214. return pData->openFileBrowser(options);
  215. }
  216. #endif
  217. void Window::repaint() noexcept
  218. {
  219. puglPostRedisplay(pData->view);
  220. }
  221. void Window::repaint(const Rectangle<uint>& rect) noexcept
  222. {
  223. PuglRect prect = {
  224. static_cast<double>(rect.getX()),
  225. static_cast<double>(rect.getY()),
  226. static_cast<double>(rect.getWidth()),
  227. static_cast<double>(rect.getHeight()),
  228. };
  229. if (pData->autoScaling)
  230. {
  231. const double autoScaleFactor = pData->autoScaleFactor;
  232. prect.x *= autoScaleFactor;
  233. prect.y *= autoScaleFactor;
  234. prect.width *= autoScaleFactor;
  235. prect.height *= autoScaleFactor;
  236. }
  237. puglPostRedisplayRect(pData->view, prect);
  238. }
  239. void Window::runAsModal(bool blockWait)
  240. {
  241. pData->runAsModal(blockWait);
  242. }
  243. void Window::setGeometryConstraints(const uint minimumWidth,
  244. const uint minimumHeight,
  245. const bool keepAspectRatio,
  246. const bool automaticallyScale)
  247. {
  248. DISTRHO_SAFE_ASSERT_RETURN(minimumWidth > 0,);
  249. DISTRHO_SAFE_ASSERT_RETURN(minimumHeight > 0,);
  250. pData->minWidth = minimumWidth;
  251. pData->minHeight = minimumHeight;
  252. pData->autoScaling = automaticallyScale;
  253. pData->keepAspectRatio = keepAspectRatio;
  254. const double scaleFactor = pData->scaleFactor;
  255. puglSetGeometryConstraints(pData->view,
  256. static_cast<uint>(minimumWidth * scaleFactor + 0.5),
  257. static_cast<uint>(minimumHeight * scaleFactor + 0.5),
  258. keepAspectRatio);
  259. if (scaleFactor != 1.0)
  260. {
  261. const Size<uint> size(getSize());
  262. setSize(static_cast<uint>(size.getWidth() * scaleFactor + 0.5),
  263. static_cast<uint>(size.getHeight() * scaleFactor + 0.5));
  264. }
  265. }
  266. bool Window::onClose()
  267. {
  268. return true;
  269. }
  270. void Window::onFocus(bool, CrossingMode)
  271. {
  272. }
  273. void Window::onReshape(uint, uint)
  274. {
  275. puglFallbackOnResize(pData->view);
  276. }
  277. void Window::onScaleFactorChanged(double)
  278. {
  279. }
  280. #ifndef DGL_FILE_BROWSER_DISABLED
  281. void Window::onFileSelected(const char*)
  282. {
  283. }
  284. #endif
  285. #if 0
  286. void Window::setTransientWinId(const uintptr_t winId)
  287. {
  288. puglSetTransientFor(pData->view, winId);
  289. }
  290. // -----------------------------------------------------------------------
  291. bool Window::handlePluginKeyboard(const bool press, const uint key)
  292. {
  293. // TODO
  294. return false;
  295. // return pData->handlePluginKeyboard(press, key);
  296. }
  297. bool Window::handlePluginSpecial(const bool press, const Key key)
  298. {
  299. // TODO
  300. return false;
  301. // return pData->handlePluginSpecial(press, key);
  302. }
  303. #endif
  304. // -----------------------------------------------------------------------
  305. END_NAMESPACE_DGL