DPF

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

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