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.

239 lines
6.3KB

  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::giveCharacterInputEventForSubWidgets(const CharacterInputEvent& 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->onCharacterInput(ev))
  83. return true;
  84. }
  85. return false;
  86. }
  87. bool Widget::PrivateData::giveMouseEventForSubWidgets(MouseEvent& ev)
  88. {
  89. if (! visible)
  90. return false;
  91. if (subWidgets.size() == 0)
  92. return false;
  93. double x = ev.absolutePos.getX();
  94. double y = ev.absolutePos.getY();
  95. if (SubWidget* const selfw = dynamic_cast<SubWidget*>(self))
  96. {
  97. if (selfw->pData->needsViewportScaling)
  98. {
  99. x -= selfw->getAbsoluteX();
  100. y -= selfw->getAbsoluteY();
  101. ev.absolutePos.setX(x);
  102. ev.absolutePos.setY(y);
  103. }
  104. }
  105. FOR_EACH_SUBWIDGET_INV(rit)
  106. {
  107. SubWidget* const widget(*rit);
  108. if (! widget->isVisible())
  109. continue;
  110. ev.pos = Point<double>(x - widget->getAbsoluteX() + widget->getMargin().getX(),
  111. y - widget->getAbsoluteY() + widget->getMargin().getY());
  112. if (widget->onMouse(ev))
  113. return true;
  114. }
  115. return false;
  116. }
  117. bool Widget::PrivateData::giveMotionEventForSubWidgets(MotionEvent& ev)
  118. {
  119. if (! visible)
  120. return false;
  121. if (subWidgets.size() == 0)
  122. return false;
  123. double x = ev.absolutePos.getX();
  124. double y = ev.absolutePos.getY();
  125. if (SubWidget* const selfw = dynamic_cast<SubWidget*>(self))
  126. {
  127. if (selfw->pData->needsViewportScaling)
  128. {
  129. x -= selfw->getAbsoluteX();
  130. y -= selfw->getAbsoluteY();
  131. ev.absolutePos.setX(x);
  132. ev.absolutePos.setY(y);
  133. }
  134. }
  135. FOR_EACH_SUBWIDGET_INV(rit)
  136. {
  137. SubWidget* const widget(*rit);
  138. if (! widget->isVisible())
  139. continue;
  140. ev.pos = Point<double>(x - widget->getAbsoluteX() + widget->getMargin().getX(),
  141. y - widget->getAbsoluteY() + widget->getMargin().getY());
  142. if (widget->onMotion(ev))
  143. return true;
  144. }
  145. return false;
  146. }
  147. bool Widget::PrivateData::giveScrollEventForSubWidgets(ScrollEvent& ev)
  148. {
  149. if (! visible)
  150. return false;
  151. if (subWidgets.size() == 0)
  152. return false;
  153. double x = ev.absolutePos.getX();
  154. double y = ev.absolutePos.getY();
  155. if (SubWidget* const selfw = dynamic_cast<SubWidget*>(self))
  156. {
  157. if (selfw->pData->needsViewportScaling)
  158. {
  159. x -= selfw->getAbsoluteX();
  160. y -= selfw->getAbsoluteY();
  161. ev.absolutePos.setX(x);
  162. ev.absolutePos.setY(y);
  163. }
  164. }
  165. FOR_EACH_SUBWIDGET_INV(rit)
  166. {
  167. SubWidget* const widget(*rit);
  168. if (! widget->isVisible())
  169. continue;
  170. ev.pos = Point<double>(x - widget->getAbsoluteX() + widget->getMargin().getX(),
  171. y - widget->getAbsoluteY() + widget->getMargin().getY());
  172. if (widget->onScroll(ev))
  173. return true;
  174. }
  175. return false;
  176. }
  177. // -----------------------------------------------------------------------
  178. TopLevelWidget* Widget::PrivateData::findTopLevelWidget(Widget* const pw)
  179. {
  180. if (pw->pData->topLevelWidget != nullptr)
  181. return pw->pData->topLevelWidget;
  182. if (pw->pData->parentWidget != nullptr)
  183. return findTopLevelWidget(pw->pData->parentWidget);
  184. return nullptr;
  185. }
  186. // -----------------------------------------------------------------------
  187. END_NAMESPACE_DGL