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.

228 lines
5.1KB

  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. #ifndef DGL_NTK_WINDOW_HPP_INCLUDED
  17. #define DGL_NTK_WINDOW_HPP_INCLUDED
  18. #include "NtkApp.hpp"
  19. #include "../Geometry.hpp"
  20. START_NAMESPACE_DGL
  21. class NtkWidget;
  22. // -----------------------------------------------------------------------
  23. class NtkWindow : public Fl_Double_Window
  24. {
  25. public:
  26. explicit NtkWindow(NtkApp& app)
  27. : Fl_Double_Window(100, 100),
  28. fApp(app),
  29. fIsVisible(false),
  30. fUsingEmbed(false),
  31. fParent(nullptr) {}
  32. explicit NtkWindow(NtkApp& app, NtkWindow& parent)
  33. : Fl_Double_Window(100, 100),
  34. fApp(app),
  35. fIsVisible(false),
  36. fUsingEmbed(false),
  37. fParent(&parent) {}
  38. explicit NtkWindow(NtkApp& app, intptr_t parentId)
  39. : Fl_Double_Window(100, 100),
  40. fApp(app),
  41. fIsVisible(parentId != 0),
  42. fUsingEmbed(parentId != 0),
  43. fParent(nullptr)
  44. {
  45. if (fUsingEmbed)
  46. {
  47. fl_embed(this, (Window)parentId);
  48. Fl_Double_Window::show();
  49. fApp.addWindow(this);
  50. }
  51. }
  52. ~NtkWindow() override
  53. {
  54. if (fUsingEmbed)
  55. {
  56. fApp.removeWindow(this);
  57. Fl_Double_Window::hide();
  58. }
  59. }
  60. void show() override
  61. {
  62. if (fUsingEmbed || fIsVisible)
  63. return;
  64. Fl_Double_Window::show();
  65. fApp.addWindow(this);
  66. fIsVisible = true;
  67. if (fParent != nullptr)
  68. setTransientWinId((intptr_t)fl_xid(fParent));
  69. }
  70. void hide() override
  71. {
  72. if (fUsingEmbed || ! fIsVisible)
  73. return;
  74. fIsVisible = false;
  75. fApp.removeWindow(this);
  76. Fl_Double_Window::hide();
  77. }
  78. void close()
  79. {
  80. hide();
  81. }
  82. bool isVisible() const
  83. {
  84. return visible();
  85. }
  86. void setVisible(bool yesNo)
  87. {
  88. if (yesNo)
  89. show();
  90. else
  91. hide();
  92. }
  93. bool isResizable() const
  94. {
  95. // TODO
  96. return false;
  97. }
  98. void setResizable(bool /*yesNo*/)
  99. {
  100. // TODO
  101. }
  102. int getWidth() const noexcept
  103. {
  104. return w();
  105. }
  106. int getHeight() const noexcept
  107. {
  108. return h();
  109. }
  110. Size<uint> getSize() const noexcept
  111. {
  112. return Size<uint>(w(), h());
  113. }
  114. void setSize(uint width, uint height)
  115. {
  116. resize(x(), y(), width, height);
  117. }
  118. void setSize(Size<uint> size)
  119. {
  120. resize(x(), y(), size.getWidth(), size.getHeight());
  121. }
  122. void setTitle(const char* title)
  123. {
  124. label(title);
  125. }
  126. void setTransientWinId(intptr_t winId)
  127. {
  128. DISTRHO_SAFE_ASSERT_RETURN(winId != 0,);
  129. #ifdef DISTRHO_OS_LINUX
  130. DISTRHO_SAFE_ASSERT_RETURN(fl_display != nullptr,);
  131. const ::Window ourWindow(fl_xid(this));
  132. DISTRHO_SAFE_ASSERT_RETURN(ourWindow != 0,);
  133. XSetTransientForHint(fl_display, ourWindow, winId);
  134. #endif
  135. }
  136. NtkApp& getApp() const noexcept
  137. {
  138. return fApp;
  139. }
  140. intptr_t getWindowId() const
  141. {
  142. return (intptr_t)fl_xid(this);
  143. }
  144. void addIdleCallback(IdleCallback* const callback)
  145. {
  146. DISTRHO_SAFE_ASSERT_RETURN(callback != nullptr,);
  147. if (fIdleCallbacks.size() == 0)
  148. Fl::add_idle(_idleHandler, this);
  149. fIdleCallbacks.push_back(callback);
  150. }
  151. void removeIdleCallback(IdleCallback* const callback)
  152. {
  153. DISTRHO_SAFE_ASSERT_RETURN(callback != nullptr,);
  154. fIdleCallbacks.remove(callback);
  155. if (fIdleCallbacks.size() == 0)
  156. Fl::remove_idle(_idleHandler, this);
  157. }
  158. private:
  159. NtkApp& fApp;
  160. bool fIsVisible;
  161. bool fUsingEmbed;
  162. // transient parent, may be null
  163. NtkWindow* const fParent;
  164. std::list<IdleCallback*> fIdleCallbacks;
  165. friend class NtkWidget;
  166. static void _idleHandler(void* data)
  167. {
  168. NtkWindow* const self((NtkWindow*)data);
  169. for (std::list<IdleCallback*>::iterator it=self->fIdleCallbacks.begin(), ite=self->fIdleCallbacks.end(); it != ite; ++it)
  170. {
  171. IdleCallback* const idleCallback(*it);
  172. idleCallback->idleCallback();
  173. }
  174. }
  175. DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NtkWindow)
  176. };
  177. // -----------------------------------------------------------------------
  178. END_NAMESPACE_DGL
  179. #endif // DGL_NTK_WINDOW_HPP_INCLUDED