DPF

DISTRHO Plugin Framework
Log | Files | Refs | Submodules | README | LICENSE

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