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.

230 lines
6.4KB

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