Audio plugin host https://kx.studio/carla
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.

947 lines
22KB

  1. /*
  2. * DISTRHO Plugin Framework (DPF)
  3. * Copyright (C) 2012-2014 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 "../App.hpp"
  17. #include "../Widget.hpp"
  18. #include "../Window.hpp"
  19. #include <cassert>
  20. #include <cstdio>
  21. #include <list>
  22. #include "pugl/pugl.h"
  23. #if defined(DISTRHO_OS_WINDOWS)
  24. # include "pugl/pugl_win.cpp"
  25. #elif defined(DISTRHO_OS_MAC)
  26. # include "pugl/pugl_osx_extended.h"
  27. extern "C" {
  28. struct PuglViewImpl {
  29. int width;
  30. int height;
  31. };}
  32. #elif defined(DISTRHO_OS_LINUX)
  33. # include <sys/types.h>
  34. # include <unistd.h>
  35. extern "C" {
  36. # include "pugl/pugl_x11.c"
  37. }
  38. #else
  39. # error Unsupported platform
  40. #endif
  41. #define FOR_EACH_WIDGET(it) \
  42. for (std::list<Widget*>::iterator it = fWidgets.begin(); it != fWidgets.end(); ++it)
  43. #define FOR_EACH_WIDGET_INV(rit) \
  44. for (std::list<Widget*>::reverse_iterator rit = fWidgets.rbegin(); rit != fWidgets.rend(); ++rit)
  45. #ifdef DEBUG
  46. # define DBG(msg) std::fprintf(stderr, "%s", msg);
  47. # define DBGp(...) std::fprintf(stderr, __VA_ARGS__);
  48. # define DBGF std::fflush(stderr);
  49. #else
  50. # define DBG(msg)
  51. # define DBGp(...)
  52. # define DBGF
  53. #endif
  54. START_NAMESPACE_DGL
  55. Window* dgl_lastUiParent = nullptr;
  56. // -----------------------------------------------------------------------
  57. // Window Private
  58. class Window::PrivateData
  59. {
  60. public:
  61. PrivateData(App& app, Window* const self)
  62. : fApp(app),
  63. fSelf(self),
  64. fView(puglCreate(0, "Window", 100, 100, true, false)),
  65. fFirstInit(true),
  66. fVisible(false),
  67. fResizable(true),
  68. fUsingEmbed(false),
  69. #if defined(DISTRHO_OS_WINDOWS)
  70. hwnd(0)
  71. #elif defined(DISTRHO_OS_LINUX)
  72. xDisplay(nullptr),
  73. xWindow(0)
  74. #elif defined(DISTRHO_OS_MAC)
  75. fNeedsIdle(true)
  76. #else
  77. _dummy('\0')
  78. #endif
  79. {
  80. DBG("Creating window without parent..."); DBGF;
  81. init();
  82. }
  83. PrivateData(App& app, Window* const self, Window& parent)
  84. : fApp(app),
  85. fSelf(self),
  86. fView(puglCreate(0, "Window", 100, 100, true, false)),
  87. fFirstInit(true),
  88. fVisible(false),
  89. fResizable(true),
  90. fUsingEmbed(false),
  91. fModal(parent.pData),
  92. #if defined(DISTRHO_OS_WINDOWS)
  93. hwnd(0)
  94. #elif defined(DISTRHO_OS_LINUX)
  95. xDisplay(nullptr),
  96. xWindow(0)
  97. #elif defined(DISTRHO_OS_MAC)
  98. fNeedsIdle(false)
  99. #else
  100. _dummy('\0')
  101. #endif
  102. {
  103. DBG("Creating window with parent..."); DBGF;
  104. init();
  105. #ifdef DISTRHO_OS_LINUX
  106. const PuglInternals* const parentImpl(parent.pData->fView->impl);
  107. XSetTransientForHint(xDisplay, xWindow, parentImpl->win);
  108. #endif
  109. }
  110. PrivateData(App& app, Window* const self, const intptr_t parentId)
  111. : fApp(app),
  112. fSelf(self),
  113. fView(puglCreate(parentId, "Window", 100, 100, (parentId == 0), (parentId != 0))),
  114. fFirstInit(true),
  115. fVisible(parentId != 0),
  116. fResizable(parentId == 0),
  117. fUsingEmbed(parentId != 0),
  118. #if defined(DISTRHO_OS_WINDOWS)
  119. hwnd(0)
  120. #elif defined(DISTRHO_OS_LINUX)
  121. xDisplay(nullptr),
  122. xWindow(0)
  123. #elif defined(DISTRHO_OS_MAC)
  124. fNeedsIdle(false)
  125. #else
  126. _dummy('\0')
  127. #endif
  128. {
  129. if (parentId != 0) {
  130. DBG("Creating embedded window..."); DBGF;
  131. } else {
  132. DBG("Creating window without parent..."); DBGF;
  133. }
  134. init();
  135. if (parentId != 0)
  136. {
  137. DBG("NOTE: Embed window is always visible and non-resizable\n");
  138. fApp._oneShown();
  139. fFirstInit = false;
  140. }
  141. }
  142. void init()
  143. {
  144. if (fSelf == nullptr || fView == nullptr)
  145. {
  146. DBG("Failed!\n");
  147. dgl_lastUiParent = nullptr;
  148. return;
  149. }
  150. dgl_lastUiParent = fSelf;
  151. puglSetHandle(fView, this);
  152. puglSetDisplayFunc(fView, onDisplayCallback);
  153. puglSetKeyboardFunc(fView, onKeyboardCallback);
  154. puglSetMotionFunc(fView, onMotionCallback);
  155. puglSetMouseFunc(fView, onMouseCallback);
  156. puglSetScrollFunc(fView, onScrollCallback);
  157. puglSetSpecialFunc(fView, onSpecialCallback);
  158. puglSetReshapeFunc(fView, onReshapeCallback);
  159. puglSetCloseFunc(fView, onCloseCallback);
  160. #if defined(DISTRHO_OS_WINDOWS)
  161. PuglInternals* impl = fView->impl;
  162. hwnd = impl->hwnd;
  163. assert(hwnd != 0);
  164. #elif defined(DISTRHO_OS_LINUX)
  165. PuglInternals* impl = fView->impl;
  166. xDisplay = impl->display;
  167. xWindow = impl->win;
  168. assert(xWindow != 0);
  169. if (! fUsingEmbed)
  170. {
  171. pid_t pid = getpid();
  172. Atom _nwp = XInternAtom(xDisplay, "_NET_WM_PID", True);
  173. XChangeProperty(xDisplay, xWindow, _nwp, XA_CARDINAL, 32, PropModeReplace, (const unsigned char*)&pid, 1);
  174. }
  175. #endif
  176. DBG("Success!\n");
  177. #if 0
  178. // process any initial events
  179. puglProcessEvents(fView);
  180. #endif
  181. fApp._addWindow(fSelf);
  182. }
  183. ~PrivateData()
  184. {
  185. DBG("Destroying window..."); DBGF;
  186. //fOnModal = false;
  187. fWidgets.clear();
  188. if (fSelf != nullptr)
  189. {
  190. fApp._removeWindow(fSelf);
  191. fSelf = nullptr;
  192. }
  193. if (fView != nullptr)
  194. {
  195. puglDestroy(fView);
  196. fView = nullptr;
  197. }
  198. #if defined(DISTRHO_OS_WINDOWS)
  199. hwnd = 0;
  200. #elif defined(DISTRHO_OS_LINUX)
  201. xDisplay = nullptr;
  202. xWindow = 0;
  203. #endif
  204. DBG("Success!\n");
  205. }
  206. // -------------------------------------------------------------------
  207. void close()
  208. {
  209. DBG("Window close\n");
  210. setVisible(false);
  211. if (! fFirstInit)
  212. {
  213. fApp._oneHidden();
  214. fFirstInit = true;
  215. }
  216. }
  217. void exec(const bool lockWait)
  218. {
  219. DBG("Window exec\n");
  220. exec_init();
  221. if (lockWait)
  222. {
  223. for (; fVisible && fModal.enabled;)
  224. {
  225. idle();
  226. d_msleep(10);
  227. }
  228. exec_fini();
  229. }
  230. else
  231. {
  232. idle();
  233. }
  234. }
  235. // -------------------------------------------------------------------
  236. void focus()
  237. {
  238. DBG("Window focus\n");
  239. #if defined(DISTRHO_OS_WINDOWS)
  240. SetForegroundWindow(hwnd);
  241. SetActiveWindow(hwnd);
  242. SetFocus(hwnd);
  243. #elif defined(DISTRHO_OS_MAC)
  244. puglImplFocus(fView);
  245. #elif defined(DISTRHO_OS_LINUX)
  246. XRaiseWindow(xDisplay, xWindow);
  247. XSetInputFocus(xDisplay, xWindow, RevertToPointerRoot, CurrentTime);
  248. XFlush(xDisplay);
  249. #endif
  250. }
  251. void repaint()
  252. {
  253. //DBG("Window repaint\n");
  254. puglPostRedisplay(fView);
  255. }
  256. // -------------------------------------------------------------------
  257. bool isVisible() const noexcept
  258. {
  259. return fVisible;
  260. }
  261. void setVisible(const bool yesNo)
  262. {
  263. if (fVisible == yesNo)
  264. {
  265. DBG("Window setVisible matches current state, ignoring request\n");
  266. return;
  267. }
  268. if (fUsingEmbed)
  269. {
  270. DBG("Window setVisible cannot be called when embedded\n");
  271. return;
  272. }
  273. DBG("Window setVisible called\n");
  274. fVisible = yesNo;
  275. if (yesNo && fFirstInit)
  276. setSize(static_cast<unsigned int>(fView->width), static_cast<unsigned int>(fView->height), true);
  277. #if defined(DISTRHO_OS_WINDOWS)
  278. if (yesNo)
  279. ShowWindow(hwnd, fFirstInit ? SW_SHOWNORMAL : SW_RESTORE);
  280. else
  281. ShowWindow(hwnd, SW_HIDE);
  282. UpdateWindow(hwnd);
  283. #elif defined(DISTRHO_OS_MAC)
  284. puglImplSetVisible(fView, yesNo);
  285. #elif defined(DISTRHO_OS_LINUX)
  286. if (yesNo)
  287. XMapRaised(xDisplay, xWindow);
  288. else
  289. XUnmapWindow(xDisplay, xWindow);
  290. XFlush(xDisplay);
  291. #endif
  292. if (yesNo)
  293. {
  294. if (fFirstInit)
  295. {
  296. fApp._oneShown();
  297. fFirstInit = false;
  298. }
  299. }
  300. else if (fModal.enabled)
  301. exec_fini();
  302. }
  303. // -------------------------------------------------------------------
  304. bool isResizable() const noexcept
  305. {
  306. return fResizable;
  307. }
  308. void setResizable(const bool yesNo)
  309. {
  310. if (fResizable == yesNo)
  311. {
  312. DBG("Window setResizable matches current state, ignoring request\n");
  313. return;
  314. }
  315. if (fUsingEmbed)
  316. {
  317. DBG("Window setResizable cannot be called when embedded\n");
  318. return;
  319. }
  320. DBG("Window setResizable called\n");
  321. fResizable = yesNo;
  322. setSize(static_cast<unsigned int>(fView->width), static_cast<unsigned int>(fView->height), true);
  323. }
  324. // -------------------------------------------------------------------
  325. int getWidth() const noexcept
  326. {
  327. return fView->width;
  328. }
  329. int getHeight() const noexcept
  330. {
  331. return fView->height;
  332. }
  333. Size<int> getSize() const noexcept
  334. {
  335. return Size<int>(fView->width, fView->height);
  336. }
  337. void setSize(unsigned int width, unsigned int height, const bool forced = false)
  338. {
  339. if (width == 0 || height == 0)
  340. {
  341. DBGp("Window setSize called with invalid value(s) %i %i, ignoring request\n", width, height);
  342. return;
  343. }
  344. if (fView->width == static_cast<int>(width) && fView->height == static_cast<int>(height) && ! forced)
  345. {
  346. DBGp("Window setSize matches current size, ignoring request (%i %i)\n", width, height);
  347. return;
  348. }
  349. fView->width = static_cast<int>(width);
  350. fView->height = static_cast<int>(height);
  351. DBGp("Window setSize called %s, size %i %i\n", forced ? "(forced)" : "(not forced)", width, height);
  352. #if defined(DISTRHO_OS_WINDOWS)
  353. int winFlags = WS_POPUPWINDOW | WS_CAPTION;
  354. if (fResizable)
  355. winFlags |= WS_SIZEBOX;
  356. RECT wr = { 0, 0, static_cast<long>(width), static_cast<long>(height) };
  357. AdjustWindowRectEx(&wr, winFlags, FALSE, WS_EX_TOPMOST);
  358. SetWindowPos(hwnd, 0, 0, 0, wr.right-wr.left, wr.bottom-wr.top, SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOZORDER);
  359. if (! forced)
  360. UpdateWindow(hwnd);
  361. #elif defined(DISTRHO_OS_MAC)
  362. puglImplSetSize(fView, width, height, forced);
  363. #elif defined(DISTRHO_OS_LINUX)
  364. XResizeWindow(xDisplay, xWindow, width, height);
  365. if (! fResizable)
  366. {
  367. XSizeHints sizeHints;
  368. memset(&sizeHints, 0, sizeof(sizeHints));
  369. sizeHints.flags = PSize|PMinSize|PMaxSize;
  370. sizeHints.width = static_cast<int>(width);
  371. sizeHints.height = static_cast<int>(height);
  372. sizeHints.min_width = static_cast<int>(width);
  373. sizeHints.min_height = static_cast<int>(height);
  374. sizeHints.max_width = static_cast<int>(width);
  375. sizeHints.max_height = static_cast<int>(height);
  376. XSetNormalHints(xDisplay, xWindow, &sizeHints);
  377. }
  378. if (! forced)
  379. XFlush(xDisplay);
  380. #endif
  381. repaint();
  382. }
  383. // -------------------------------------------------------------------
  384. void setTitle(const char* const title)
  385. {
  386. DBGp("Window setTitle \"%s\"\n", title);
  387. #if defined(DISTRHO_OS_WINDOWS)
  388. SetWindowTextA(hwnd, title);
  389. #elif defined(DISTRHO_OS_MAC)
  390. puglImplSetTitle(fView, title);
  391. #elif defined(DISTRHO_OS_LINUX)
  392. XStoreName(xDisplay, xWindow, title);
  393. #endif
  394. }
  395. void setTransientWinId(const intptr_t winId)
  396. {
  397. #if defined(DISTRHO_OS_LINUX)
  398. XSetTransientForHint(xDisplay, xWindow, static_cast< ::Window>(winId));
  399. #else
  400. return;
  401. // unused
  402. (void)winId;
  403. #endif
  404. }
  405. // -------------------------------------------------------------------
  406. App& getApp() const noexcept
  407. {
  408. return fApp;
  409. }
  410. int getModifiers() const
  411. {
  412. return puglGetModifiers(fView);
  413. }
  414. uint32_t getEventTimestamp() const
  415. {
  416. return puglGetEventTimestamp(fView);
  417. }
  418. intptr_t getWindowId() const
  419. {
  420. return puglGetNativeWindow(fView);
  421. }
  422. // -------------------------------------------------------------------
  423. void addWidget(Widget* const widget)
  424. {
  425. fWidgets.push_back(widget);
  426. }
  427. void removeWidget(Widget* const widget)
  428. {
  429. fWidgets.remove(widget);
  430. }
  431. void idle()
  432. {
  433. puglProcessEvents(fView);
  434. #ifdef DISTRHO_OS_MAC
  435. if (fNeedsIdle)
  436. puglImplIdle(fView);
  437. #endif
  438. if (fModal.enabled && fModal.parent != nullptr)
  439. fModal.parent->idle();
  440. }
  441. // -------------------------------------------------------------------
  442. void exec_init()
  443. {
  444. DBG("Window modal loop starting..."); DBGF;
  445. assert(fModal.parent != nullptr);
  446. if (fModal.parent == nullptr)
  447. {
  448. DBG("Failed, there's no modal parent!\n");
  449. return setVisible(true);
  450. }
  451. fModal.enabled = true;
  452. fModal.parent->fModal.childFocus = this;
  453. #ifdef DISTRHO_OS_WINDOWS
  454. // Center this window
  455. PuglInternals* const parentImpl = fModal.parent->fView->impl;
  456. RECT curRect;
  457. RECT parentRect;
  458. GetWindowRect(hwnd, &curRect);
  459. GetWindowRect(parentImpl->hwnd, &parentRect);
  460. int x = parentRect.left+(parentRect.right-curRect.right)/2;
  461. int y = parentRect.top +(parentRect.bottom-curRect.bottom)/2;
  462. SetWindowPos(hwnd, 0, x, y, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
  463. UpdateWindow(hwnd);
  464. #endif
  465. fModal.parent->setVisible(true);
  466. setVisible(true);
  467. DBG("Ok\n");
  468. }
  469. void exec_fini()
  470. {
  471. DBG("Window modal loop stopping..."); DBGF;
  472. fModal.enabled = false;
  473. if (fModal.parent != nullptr)
  474. fModal.parent->fModal.childFocus = nullptr;
  475. DBG("Ok\n");
  476. }
  477. // -------------------------------------------------------------------
  478. protected:
  479. void onDisplay()
  480. {
  481. //DBG("PUGL: onDisplay\n");
  482. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  483. glLoadIdentity();
  484. FOR_EACH_WIDGET(it)
  485. {
  486. Widget* const widget(*it);
  487. if (widget->isVisible())
  488. widget->onDisplay();
  489. }
  490. }
  491. void onKeyboard(const bool press, const uint32_t key)
  492. {
  493. DBGp("PUGL: onKeyboard : %i %i\n", press, key);
  494. if (fModal.childFocus != nullptr)
  495. return fModal.childFocus->focus();
  496. FOR_EACH_WIDGET_INV(rit)
  497. {
  498. Widget* const widget(*rit);
  499. if (widget->isVisible() && widget->onKeyboard(press, key))
  500. break;
  501. }
  502. }
  503. void onMouse(const int button, const bool press, const int x, const int y)
  504. {
  505. DBGp("PUGL: onMouse : %i %i %i %i\n", button, press, x, y);
  506. if (fModal.childFocus != nullptr)
  507. return fModal.childFocus->focus();
  508. FOR_EACH_WIDGET_INV(rit)
  509. {
  510. Widget* const widget(*rit);
  511. if (widget->isVisible() && widget->onMouse(button, press, x, y))
  512. break;
  513. }
  514. }
  515. void onMotion(const int x, const int y)
  516. {
  517. DBGp("PUGL: onMotion : %i %i\n", x, y);
  518. if (fModal.childFocus != nullptr)
  519. return;
  520. FOR_EACH_WIDGET_INV(rit)
  521. {
  522. Widget* const widget(*rit);
  523. if (widget->isVisible() && widget->onMotion(x, y))
  524. break;
  525. }
  526. }
  527. void onScroll(const int x, const int y, const float dx, const float dy)
  528. {
  529. DBGp("PUGL: onScroll : %i %i %f %f\n", x, y, dx, dy);
  530. if (fModal.childFocus != nullptr)
  531. return;
  532. FOR_EACH_WIDGET_INV(rit)
  533. {
  534. Widget* const widget(*rit);
  535. if (widget->isVisible() && widget->onScroll(x, y, dx, dy))
  536. break;
  537. }
  538. }
  539. void onSpecial(const bool press, const Key key)
  540. {
  541. DBGp("PUGL: onSpecial : %i %i\n", press, key);
  542. if (fModal.childFocus != nullptr)
  543. return;
  544. FOR_EACH_WIDGET_INV(rit)
  545. {
  546. Widget* const widget(*rit);
  547. if (widget->isVisible() && widget->onSpecial(press, key))
  548. break;
  549. }
  550. }
  551. void onReshape(const int width, const int height)
  552. {
  553. DBGp("PUGL: onReshape : %i %i\n", width, height);
  554. FOR_EACH_WIDGET(it)
  555. {
  556. Widget* const widget(*it);
  557. widget->onReshape(width, height);
  558. }
  559. }
  560. void onClose()
  561. {
  562. DBG("PUGL: onClose\n");
  563. if (fModal.enabled && fModal.parent != nullptr)
  564. exec_fini();
  565. if (fModal.childFocus != nullptr)
  566. fModal.childFocus->onClose();
  567. FOR_EACH_WIDGET(it)
  568. {
  569. Widget* const widget(*it);
  570. widget->onClose();
  571. }
  572. close();
  573. }
  574. // -------------------------------------------------------------------
  575. private:
  576. App& fApp;
  577. Window* fSelf;
  578. PuglView* fView;
  579. bool fFirstInit;
  580. bool fVisible;
  581. bool fResizable;
  582. bool fUsingEmbed;
  583. std::list<Widget*> fWidgets;
  584. struct Modal {
  585. bool enabled;
  586. PrivateData* parent;
  587. PrivateData* childFocus;
  588. Modal()
  589. : enabled(false),
  590. parent(nullptr),
  591. childFocus(nullptr) {}
  592. Modal(PrivateData* const p)
  593. : enabled(false),
  594. parent(p),
  595. childFocus(nullptr) {}
  596. ~Modal()
  597. {
  598. assert(! enabled);
  599. assert(childFocus == nullptr);
  600. }
  601. } fModal;
  602. #if defined(DISTRHO_OS_WINDOWS)
  603. HWND hwnd;
  604. #elif defined(DISTRHO_OS_LINUX)
  605. Display* xDisplay;
  606. ::Window xWindow;
  607. #elif defined(DISTRHO_OS_MAC)
  608. bool fNeedsIdle;
  609. #else
  610. char _dummy;
  611. #endif
  612. // -------------------------------------------------------------------
  613. // Callbacks
  614. #define handlePtr ((PrivateData*)puglGetHandle(view))
  615. static void onDisplayCallback(PuglView* view)
  616. {
  617. handlePtr->onDisplay();
  618. }
  619. static void onKeyboardCallback(PuglView* view, bool press, uint32_t key)
  620. {
  621. handlePtr->onKeyboard(press, key);
  622. }
  623. static void onMouseCallback(PuglView* view, int button, bool press, int x, int y)
  624. {
  625. handlePtr->onMouse(button, press, x, y);
  626. }
  627. static void onMotionCallback(PuglView* view, int x, int y)
  628. {
  629. handlePtr->onMotion(x, y);
  630. }
  631. static void onScrollCallback(PuglView* view, int x, int y, float dx, float dy)
  632. {
  633. handlePtr->onScroll(x, y, dx, dy);
  634. }
  635. static void onSpecialCallback(PuglView* view, bool press, PuglKey key)
  636. {
  637. handlePtr->onSpecial(press, static_cast<Key>(key));
  638. }
  639. static void onReshapeCallback(PuglView* view, int width, int height)
  640. {
  641. handlePtr->onReshape(width, height);
  642. }
  643. static void onCloseCallback(PuglView* view)
  644. {
  645. handlePtr->onClose();
  646. }
  647. #undef handlePtr
  648. };
  649. // -----------------------------------------------------------------------
  650. // Window
  651. Window::Window(App& app)
  652. : pData(new PrivateData(app, this))
  653. {
  654. }
  655. Window::Window(App& app, Window& parent)
  656. : pData(new PrivateData(app, this, parent))
  657. {
  658. }
  659. Window::Window(App& app, intptr_t parentId)
  660. : pData(new PrivateData(app, this, parentId))
  661. {
  662. }
  663. Window::~Window()
  664. {
  665. delete pData;
  666. }
  667. void Window::show()
  668. {
  669. pData->setVisible(true);
  670. }
  671. void Window::hide()
  672. {
  673. pData->setVisible(false);
  674. }
  675. void Window::close()
  676. {
  677. pData->close();
  678. }
  679. void Window::exec(bool lockWait)
  680. {
  681. pData->exec(lockWait);
  682. }
  683. void Window::focus()
  684. {
  685. pData->focus();
  686. }
  687. void Window::repaint()
  688. {
  689. pData->repaint();
  690. }
  691. bool Window::isVisible() const noexcept
  692. {
  693. return pData->isVisible();
  694. }
  695. void Window::setVisible(bool yesNo)
  696. {
  697. pData->setVisible(yesNo);
  698. }
  699. bool Window::isResizable() const noexcept
  700. {
  701. return pData->isResizable();
  702. }
  703. void Window::setResizable(bool yesNo)
  704. {
  705. pData->setResizable(yesNo);
  706. }
  707. int Window::getWidth() const noexcept
  708. {
  709. return pData->getWidth();
  710. }
  711. int Window::getHeight() const noexcept
  712. {
  713. return pData->getHeight();
  714. }
  715. Size<int> Window::getSize() const noexcept
  716. {
  717. return pData->getSize();
  718. }
  719. void Window::setSize(unsigned int width, unsigned int height)
  720. {
  721. pData->setSize(width, height);
  722. }
  723. void Window::setTitle(const char* title)
  724. {
  725. pData->setTitle(title);
  726. }
  727. void Window::setTransientWinId(intptr_t winId)
  728. {
  729. pData->setTransientWinId(winId);
  730. }
  731. App& Window::getApp() const noexcept
  732. {
  733. return pData->getApp();
  734. }
  735. int Window::getModifiers() const
  736. {
  737. return pData->getModifiers();
  738. }
  739. uint32_t Window::getEventTimestamp() const
  740. {
  741. return pData->getEventTimestamp();
  742. }
  743. intptr_t Window::getWindowId() const
  744. {
  745. return pData->getWindowId();
  746. }
  747. void Window::_addWidget(Widget* const widget)
  748. {
  749. pData->addWidget(widget);
  750. }
  751. void Window::_removeWidget(Widget* const widget)
  752. {
  753. pData->removeWidget(widget);
  754. }
  755. void Window::_idle()
  756. {
  757. pData->idle();
  758. }
  759. // -----------------------------------------------------------------------
  760. END_NAMESPACE_DGL
  761. #undef DBG
  762. #undef DBGF