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