SubWidget.cpp (5378B)
1 /* 2 * DISTRHO Plugin Framework (DPF) 3 * Copyright (C) 2012-2024 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 "SubWidgetPrivateData.hpp" 18 #include "WidgetPrivateData.hpp" 19 #include "../TopLevelWidget.hpp" 20 21 START_NAMESPACE_DGL 22 23 // -------------------------------------------------------------------------------------------------------------------- 24 25 SubWidget::SubWidget(Widget* const parentWidget) 26 : Widget(parentWidget), 27 pData(new PrivateData(this, parentWidget)) {} 28 29 SubWidget::~SubWidget() 30 { 31 delete pData; 32 } 33 34 template<typename T> 35 bool SubWidget::contains(const T x, const T y) const noexcept 36 { 37 return Rectangle<double>(0, 0, 38 static_cast<double>(getWidth()), 39 static_cast<double>(getHeight())).contains(x, y); 40 } 41 42 template<typename T> 43 bool SubWidget::contains(const Point<T>& pos) const noexcept 44 { 45 return contains(pos.getX(), pos.getY()); 46 } 47 48 int SubWidget::getAbsoluteX() const noexcept 49 { 50 return pData->absolutePos.getX(); 51 } 52 53 int SubWidget::getAbsoluteY() const noexcept 54 { 55 return pData->absolutePos.getY(); 56 } 57 58 Point<int> SubWidget::getAbsolutePos() const noexcept 59 { 60 return pData->absolutePos; 61 } 62 63 Rectangle<int> SubWidget::getAbsoluteArea() const noexcept 64 { 65 return Rectangle<int>(getAbsolutePos(), getSize().toInt()); 66 } 67 68 Rectangle<uint> SubWidget::getConstrainedAbsoluteArea() const noexcept 69 { 70 const int x = getAbsoluteX(); 71 const int y = getAbsoluteY(); 72 73 if (x >= 0 && y >= 0) 74 return Rectangle<uint>(static_cast<uint>(x), static_cast<uint>(y), getSize()); 75 76 const int xOffset = std::min(0, x); 77 const int yOffset = std::min(0, y); 78 const int width = std::max(0, static_cast<int>(getWidth()) + xOffset); 79 const int height = std::max(0, static_cast<int>(getHeight()) + yOffset); 80 81 return Rectangle<uint>(0, 0, static_cast<uint>(width), static_cast<uint>(height)); 82 } 83 84 void SubWidget::setAbsoluteX(const int x) noexcept 85 { 86 setAbsolutePos(Point<int>(x, getAbsoluteY())); 87 } 88 89 void SubWidget::setAbsoluteY(const int y) noexcept 90 { 91 setAbsolutePos(Point<int>(getAbsoluteX(), y)); 92 } 93 94 void SubWidget::setAbsolutePos(const int x, const int y) noexcept 95 { 96 setAbsolutePos(Point<int>(x, y)); 97 } 98 99 void SubWidget::setAbsolutePos(const Point<int>& pos) noexcept 100 { 101 if (pData->absolutePos == pos) 102 return; 103 104 PositionChangedEvent ev; 105 ev.oldPos = pData->absolutePos; 106 ev.pos = pos; 107 108 pData->absolutePos = pos; 109 onPositionChanged(ev); 110 111 repaint(); 112 } 113 114 Point<int> SubWidget::getMargin() const noexcept 115 { 116 return pData->margin; 117 } 118 119 void SubWidget::setMargin(const int x, const int y) noexcept 120 { 121 pData->margin = Point<int>(x, y); 122 } 123 124 void SubWidget::setMargin(const Point<int>& offset) noexcept 125 { 126 pData->margin = offset; 127 } 128 129 Widget* SubWidget::getParentWidget() const noexcept 130 { 131 return pData->parentWidget; 132 } 133 134 void SubWidget::repaint() noexcept 135 { 136 if (! isVisible()) 137 return; 138 139 if (TopLevelWidget* const topw = getTopLevelWidget()) 140 { 141 if (pData->needsFullViewportForDrawing) 142 // repaint is virtual and we want precisely the top-level specific implementation, not any higher level 143 topw->TopLevelWidget::repaint(); 144 else 145 topw->repaint(getConstrainedAbsoluteArea()); 146 } 147 } 148 149 void SubWidget::toBottom() 150 { 151 std::list<SubWidget*>& subwidgets(pData->parentWidget->pData->subWidgets); 152 153 subwidgets.remove(this); 154 subwidgets.insert(subwidgets.begin(), this); 155 } 156 157 void SubWidget::toFront() 158 { 159 std::list<SubWidget*>& subwidgets(pData->parentWidget->pData->subWidgets); 160 161 subwidgets.remove(this); 162 subwidgets.push_back(this); 163 } 164 165 void SubWidget::setNeedsFullViewportDrawing(const bool needsFullViewportForDrawing) 166 { 167 pData->needsFullViewportForDrawing = needsFullViewportForDrawing; 168 } 169 170 void SubWidget::setNeedsViewportScaling(const bool needsViewportScaling, const double autoScaleFactor) 171 { 172 pData->needsViewportScaling = needsViewportScaling; 173 pData->viewportScaleFactor = autoScaleFactor; 174 } 175 176 void SubWidget::setSkipDrawing(const bool skipDrawing) 177 { 178 pData->skipDrawing = skipDrawing; 179 } 180 181 void SubWidget::onPositionChanged(const PositionChangedEvent&) 182 { 183 } 184 185 // -------------------------------------------------------------------------------------------------------------------- 186 // Possible template data types 187 188 template<> 189 bool SubWidget::contains(const Point<double>& pos) const noexcept 190 { 191 return contains(pos.getX(), pos.getY()); 192 } 193 194 // float, int, uint, short, ushort 195 196 // -------------------------------------------------------------------------------------------------------------------- 197 198 END_NAMESPACE_DGL