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.

257 lines
6.6KB

  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 "WidgetPrivateData.hpp"
  17. #include "SubWidgetPrivateData.hpp"
  18. #include "../TopLevelWidget.hpp"
  19. START_NAMESPACE_DGL
  20. #define FOR_EACH_SUBWIDGET(it) \
  21. for (std::list<SubWidget*>::iterator it = subWidgets.begin(); it != subWidgets.end(); ++it)
  22. #define FOR_EACH_SUBWIDGET_INV(rit) \
  23. for (std::list<SubWidget*>::reverse_iterator rit = subWidgets.rbegin(); rit != subWidgets.rend(); ++rit)
  24. // -----------------------------------------------------------------------
  25. Widget::PrivateData::PrivateData(Widget* const s, TopLevelWidget* const tlw)
  26. : self(s),
  27. topLevelWidget(tlw),
  28. parentWidget(nullptr),
  29. id(0),
  30. needsScaling(false),
  31. visible(true),
  32. size(0, 0),
  33. subWidgets() {}
  34. Widget::PrivateData::PrivateData(Widget* const s, Widget* const pw)
  35. : self(s),
  36. topLevelWidget(findTopLevelWidget(pw)),
  37. parentWidget(pw),
  38. id(0),
  39. needsScaling(false),
  40. visible(true),
  41. size(0, 0),
  42. subWidgets() {}
  43. Widget::PrivateData::~PrivateData()
  44. {
  45. subWidgets.clear();
  46. }
  47. void Widget::PrivateData::displaySubWidgets(const uint width, const uint height, const double autoScaleFactor)
  48. {
  49. if (subWidgets.size() == 0)
  50. return;
  51. for (std::list<SubWidget*>::iterator it = subWidgets.begin(); it != subWidgets.end(); ++it)
  52. {
  53. SubWidget* const subwidget(*it);
  54. if (subwidget->isVisible())
  55. subwidget->pData->display(width, height, autoScaleFactor);
  56. }
  57. }
  58. // -----------------------------------------------------------------------
  59. bool Widget::PrivateData::giveKeyboardEventForSubWidgets(const KeyboardEvent& ev)
  60. {
  61. if (! visible)
  62. return false;
  63. if (subWidgets.size() == 0)
  64. return false;
  65. FOR_EACH_SUBWIDGET_INV(rit)
  66. {
  67. SubWidget* const widget(*rit);
  68. if (widget->isVisible() && widget->onKeyboard(ev))
  69. return true;
  70. }
  71. return false;
  72. }
  73. bool Widget::PrivateData::giveSpecialEventForSubWidgets(const SpecialEvent& ev)
  74. {
  75. if (! visible)
  76. return false;
  77. if (subWidgets.size() == 0)
  78. return false;
  79. FOR_EACH_SUBWIDGET_INV(rit)
  80. {
  81. SubWidget* const widget(*rit);
  82. if (widget->isVisible() && widget->onSpecial(ev))
  83. return true;
  84. }
  85. return false;
  86. }
  87. bool Widget::PrivateData::giveCharacterInputEventForSubWidgets(const CharacterInputEvent& ev)
  88. {
  89. if (! visible)
  90. return false;
  91. if (subWidgets.size() == 0)
  92. return false;
  93. FOR_EACH_SUBWIDGET_INV(rit)
  94. {
  95. SubWidget* const widget(*rit);
  96. if (widget->isVisible() && widget->onCharacterInput(ev))
  97. return true;
  98. }
  99. return false;
  100. }
  101. bool Widget::PrivateData::giveMouseEventForSubWidgets(MouseEvent& ev)
  102. {
  103. if (! visible)
  104. return false;
  105. if (subWidgets.size() == 0)
  106. return false;
  107. double x = ev.absolutePos.getX();
  108. double y = ev.absolutePos.getY();
  109. if (SubWidget* const selfw = dynamic_cast<SubWidget*>(self))
  110. {
  111. if (selfw->pData->needsViewportScaling)
  112. {
  113. x -= selfw->getAbsoluteX();
  114. y -= selfw->getAbsoluteY();
  115. ev.absolutePos.setX(x);
  116. ev.absolutePos.setY(y);
  117. }
  118. }
  119. FOR_EACH_SUBWIDGET_INV(rit)
  120. {
  121. SubWidget* const widget(*rit);
  122. if (! widget->isVisible())
  123. continue;
  124. ev.pos = Point<double>(x - widget->getAbsoluteX() + widget->getMargin().getX(),
  125. y - widget->getAbsoluteY() + widget->getMargin().getY());
  126. if (widget->onMouse(ev))
  127. return true;
  128. }
  129. return false;
  130. }
  131. bool Widget::PrivateData::giveMotionEventForSubWidgets(MotionEvent& ev)
  132. {
  133. if (! visible)
  134. return false;
  135. if (subWidgets.size() == 0)
  136. return false;
  137. double x = ev.absolutePos.getX();
  138. double y = ev.absolutePos.getY();
  139. if (SubWidget* const selfw = dynamic_cast<SubWidget*>(self))
  140. {
  141. if (selfw->pData->needsViewportScaling)
  142. {
  143. x -= selfw->getAbsoluteX();
  144. y -= selfw->getAbsoluteY();
  145. ev.absolutePos.setX(x);
  146. ev.absolutePos.setY(y);
  147. }
  148. }
  149. FOR_EACH_SUBWIDGET_INV(rit)
  150. {
  151. SubWidget* const widget(*rit);
  152. if (! widget->isVisible())
  153. continue;
  154. ev.pos = Point<double>(x - widget->getAbsoluteX() + widget->getMargin().getX(),
  155. y - widget->getAbsoluteY() + widget->getMargin().getY());
  156. if (widget->onMotion(ev))
  157. return true;
  158. }
  159. return false;
  160. }
  161. bool Widget::PrivateData::giveScrollEventForSubWidgets(ScrollEvent& ev)
  162. {
  163. if (! visible)
  164. return false;
  165. if (subWidgets.size() == 0)
  166. return false;
  167. double x = ev.absolutePos.getX();
  168. double y = ev.absolutePos.getY();
  169. if (SubWidget* const selfw = dynamic_cast<SubWidget*>(self))
  170. {
  171. if (selfw->pData->needsViewportScaling)
  172. {
  173. x -= selfw->getAbsoluteX();
  174. y -= selfw->getAbsoluteY();
  175. ev.absolutePos.setX(x);
  176. ev.absolutePos.setY(y);
  177. }
  178. }
  179. FOR_EACH_SUBWIDGET_INV(rit)
  180. {
  181. SubWidget* const widget(*rit);
  182. if (! widget->isVisible())
  183. continue;
  184. ev.pos = Point<double>(x - widget->getAbsoluteX() + widget->getMargin().getX(),
  185. y - widget->getAbsoluteY() + widget->getMargin().getY());
  186. if (widget->onScroll(ev))
  187. return true;
  188. }
  189. return false;
  190. }
  191. // -----------------------------------------------------------------------
  192. TopLevelWidget* Widget::PrivateData::findTopLevelWidget(Widget* const pw)
  193. {
  194. if (pw->pData->topLevelWidget != nullptr)
  195. return pw->pData->topLevelWidget;
  196. if (pw->pData->parentWidget != nullptr)
  197. return findTopLevelWidget(pw->pData->parentWidget);
  198. return nullptr;
  199. }
  200. // -----------------------------------------------------------------------
  201. END_NAMESPACE_DGL