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.

222 lines
5.0KB

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