commit d3c5705122bed1ac4283fbbb9a7631d40dc1fe66
parent 3f3ac855ada80c62ba4f5aed9a0d7593e063dfd2
Author: falkTX <falktx@falktx.com>
Date: Sun, 9 May 2021 00:04:51 +0100
Start to pass events into top-level and subwidgets
Signed-off-by: falkTX <falktx@falktx.com>
Diffstat:
9 files changed, 98 insertions(+), 59 deletions(-)
diff --git a/dgl/src/SubWidget.cpp b/dgl/src/SubWidget.cpp
@@ -100,9 +100,11 @@ void SubWidget::setAbsolutePos(const Point<int>& pos) noexcept
pData->parentWidget->repaint();
}
-
void SubWidget::repaint() noexcept
{
+ if (! isVisible())
+ return;
+
if (TopLevelWidget* const topw = getTopLevelWidget())
topw->repaint(getConstrainedAbsoluteArea());
}
diff --git a/dgl/src/TopLevelWidgetPrivateData.cpp b/dgl/src/TopLevelWidgetPrivateData.cpp
@@ -21,12 +21,6 @@
START_NAMESPACE_DGL
-#define FOR_EACH_WIDGET(it) \
- for (std::list<Widget*>::iterator it = widgets.begin(); it != widgets.end(); ++it)
-
-#define FOR_EACH_WIDGET_INV(rit) \
- for (std::list<Widget*>::reverse_iterator rit = widgets.rbegin(); rit != widgets.rend(); ++rit)
-
// -----------------------------------------------------------------------
TopLevelWidget::PrivateData::PrivateData(TopLevelWidget* const s, Window& w)
@@ -45,13 +39,10 @@ TopLevelWidget::PrivateData::~PrivateData()
void TopLevelWidget::PrivateData::display()
{
- printf("TopLevelWidget::PrivateData::display INIT\n");
-
const Size<uint> size(window.getSize());
const uint width = size.getWidth();
const uint height = size.getHeight();
const double autoScaling = window.pData->autoScaling;
- printf("TopLevelWidget::PrivateData::display %i %i\n", width, height);
// full viewport size
glViewport(0, -(height * autoScaling - height), width * autoScaling, height * autoScaling);
@@ -63,6 +54,26 @@ void TopLevelWidget::PrivateData::display()
selfw->pData->displaySubWidgets(width, height, autoScaling);
}
+void TopLevelWidget::PrivateData::mouseEvent(const Events::MouseEvent& ev)
+{
+ Events::MouseEvent rev = ev;
+
+ const double autoScaling = window.pData->autoScaling;
+
+ if (autoScaling != 1.0)
+ {
+ rev.pos.setX(ev.pos.getX() / autoScaling);
+ rev.pos.setY(ev.pos.getY() / autoScaling);
+ }
+
+ // give top-level widget chance to catch this event first
+ if (self->onMouse(ev))
+ return;
+
+ // propagate event to all subwidgets recursively
+ selfw->pData->giveMouseEventForSubWidgets(rev);
+}
+
// -----------------------------------------------------------------------
END_NAMESPACE_DGL
diff --git a/dgl/src/TopLevelWidgetPrivateData.hpp b/dgl/src/TopLevelWidgetPrivateData.hpp
@@ -33,6 +33,7 @@ struct TopLevelWidget::PrivateData {
explicit PrivateData(TopLevelWidget* const s, Window& w);
~PrivateData();
void display();
+ void mouseEvent(const Events::MouseEvent& ev);
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData)
};
diff --git a/dgl/src/WidgetPrivateData.cpp b/dgl/src/WidgetPrivateData.cpp
@@ -15,10 +15,17 @@
*/
#include "WidgetPrivateData.hpp"
+#include "../SubWidget.hpp"
#include "../TopLevelWidget.hpp"
START_NAMESPACE_DGL
+#define FOR_EACH_SUBWIDGET(it) \
+ for (std::list<SubWidget*>::iterator it = subWidgets.begin(); it != subWidgets.end(); ++it)
+
+#define FOR_EACH_SUBWIDGET_INV(rit) \
+ for (std::list<SubWidget*>::reverse_iterator rit = subWidgets.rbegin(); rit != subWidgets.rend(); ++rit)
+
// -----------------------------------------------------------------------
Widget::PrivateData::PrivateData(Widget* const s, TopLevelWidget* const tlw)
@@ -48,17 +55,40 @@ Widget::PrivateData::~PrivateData()
void Widget::PrivateData::displaySubWidgets(const uint width, const uint height, const double scaling)
{
- printf("Widget::PrivateData::displaySubWidgets INIT | %lu\n", subWidgets.size());
-
if (subWidgets.size() == 0)
return;
for (std::list<SubWidget*>::iterator it = subWidgets.begin(); it != subWidgets.end(); ++it)
{
SubWidget* const subwidget(*it);
- printf("Widget::PrivateData::displaySubWidgets %i %i -> %p\n", width, height, subwidget);
- subwidget->pData->display(width, height, scaling);
+ if (subwidget->isVisible())
+ subwidget->pData->display(width, height, scaling);
+ }
+}
+
+void Widget::PrivateData::giveMouseEventForSubWidgets(Events::MouseEvent& ev)
+{
+ if (! visible)
+ return;
+ if (subWidgets.size() == 0)
+ return;
+
+ const double x = ev.pos.getX();
+ const double y = ev.pos.getY();
+
+ FOR_EACH_SUBWIDGET_INV(rit)
+ {
+ SubWidget* const widget(*rit);
+
+ if (! widget->isVisible())
+ continue;
+
+ ev.pos = Point<double>(x - widget->getAbsoluteX(),
+ y - widget->getAbsoluteY());
+
+ if (widget->onMouse(ev))
+ return;
}
}
@@ -66,8 +96,6 @@ void Widget::PrivateData::displaySubWidgets(const uint width, const uint height,
TopLevelWidget* Widget::PrivateData::findTopLevelWidget(Widget* const w)
{
-// if (TopLevelWidget* const tlw = dynamic_cast<TopLevelWidget*>(w))
-// return tlw;
if (w->pData->topLevelWidget != nullptr)
return w->pData->topLevelWidget;
if (w->pData->parentWidget != nullptr)
diff --git a/dgl/src/WidgetPrivateData.hpp b/dgl/src/WidgetPrivateData.hpp
@@ -41,10 +41,8 @@ struct Widget::PrivateData {
explicit PrivateData(Widget* const s, Widget* const pw);
~PrivateData();
- // NOTE display function is different depending on build type, must call displaySubWidgets at the end
-// void display(uint width, uint height, double autoScaling, bool renderingSubWidget);
-
void displaySubWidgets(uint width, uint height, double autoScaling);
+ void giveMouseEventForSubWidgets(Events::MouseEvent& ev);
static TopLevelWidget* findTopLevelWidget(Widget* const w);
diff --git a/dgl/src/WindowPrivateData.cpp b/dgl/src/WindowPrivateData.cpp
@@ -323,6 +323,19 @@ void Window::PrivateData::onPuglClose()
close();
}
+void Window::PrivateData::onPuglMouse(const Events::MouseEvent& ev)
+{
+ DGL_DBGp("PUGL: onMouse : %i %i %f %f\n", ev.button, ev.press, ev.pos.getX(), ev.pos.getY());
+
+// if (fModal.childFocus != nullptr)
+// return fModal.childFocus->focus();
+
+#ifndef DPF_TEST_WINDOW_CPP
+ if (topLevelWidget != nullptr)
+ topLevelWidget->pData->mouseEvent(ev);
+#endif
+}
+
static int printEvent(const PuglEvent* event, const char* prefix, const bool verbose);
PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const PuglEvent* const event)
@@ -355,6 +368,20 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu
pData->onPuglCreate();
break;
+ case PUGL_BUTTON_PRESS: ///< Mouse button pressed, a #PuglEventButton
+ case PUGL_BUTTON_RELEASE: ///< Mouse button released, a #PuglEventButton
+ {
+ Events::MouseEvent ev;
+ ev.mod = event->button.state;
+ ev.flags = event->button.flags;
+ ev.time = static_cast<uint>(event->button.time * 1000.0 + 0.5);
+ ev.button = event->button.button;
+ ev.press = event->type == PUGL_BUTTON_PRESS;
+ ev.pos = Point<double>(event->button.x, event->button.y);
+ pData->onPuglMouse(ev);
+ break;
+ }
+
// TODO
default:
break;
diff --git a/dgl/src/WindowPrivateData.hpp b/dgl/src/WindowPrivateData.hpp
@@ -18,6 +18,7 @@
#define DGL_WINDOW_PRIVATE_DATA_HPP_INCLUDED
#include "../Window.hpp"
+#include "../Events.hpp"
#include "ApplicationPrivateData.hpp"
#include "pugl.hpp"
@@ -107,6 +108,7 @@ struct Window::PrivateData : IdleCallback {
void onPuglReshape(int width, int height);
void onPuglCreate();
void onPuglClose();
+ void onPuglMouse(const Events::MouseEvent& ev);
// Pugl event handling entry point
static PuglStatus puglEventCallback(PuglView* view, const PuglEvent* event);
diff --git a/tests/Demo.cpp b/tests/Demo.cpp
@@ -80,7 +80,6 @@ protected:
void onDisplay() override
{
const int iconSize = bgIcon.getWidth();
- printf("LEFT SIDE WIDGET onDisplay %i\n", iconSize);
glColor3f(0.027f, 0.027f, 0.027f);
Rectangle<uint>(0, 0, getSize()).draw();
@@ -201,8 +200,8 @@ protected:
void onResize(const ResizeEvent& ev) override
{
- const int width = ev.size.getWidth();
- const int height = ev.size.getHeight();
+ const uint width = ev.size.getWidth();
+ const uint height = ev.size.getHeight();
bgIcon.setWidth(width-4);
bgIcon.setHeight(width-4);
@@ -299,11 +298,6 @@ protected:
void onDisplay() override
{
- static int counter = 0;
- printf("print %i\n", ++counter);
-
- glColor3f(0.471f, 0.971f, 0.171f);
- Rectangle<uint>(0, 0, getSize()).draw();
}
void onReshape(uint width, uint height) override
@@ -341,28 +335,6 @@ private:
};
// --------------------------------------------------------------------------------------------------------------------
-// Testing StandaloneWindow, for custom local widget drawing code
-
-class TestingWidgetStandaloneWindow : public StandaloneWindow
-{
-public:
- static constexpr const char* kExampleWidgetName = "Testing";
-
- TestingWidgetStandaloneWindow(Application& app)
- : StandaloneWindow(app)
- {
- }
-
-protected:
- void onDisplay() override
- {
- glColor3f(0.5f, 0.3f, 0.9f);
- Rectangle<uint>(0, 0, 500, 500).draw();
- // getWidth(), getHeight()
- }
-};
-
-// --------------------------------------------------------------------------------------------------------------------
// Special handy function that runs a StandaloneWindow inside the function scope
template <class ExampleWidgetStandaloneWindow>
@@ -396,8 +368,6 @@ int main(int argc, char* argv[])
createAndShowExampleWidgetStandaloneWindow<ExampleRectanglesStandaloneWindow>(app);
else if (std::strcmp(argv[1], "shapes") == 0)
createAndShowExampleWidgetStandaloneWindow<ExampleShapesStandaloneWindow>(app);
- else if (std::strcmp(argv[1], "testing") == 0)
- createAndShowExampleWidgetStandaloneWindow<TestingWidgetStandaloneWindow>(app);
else
d_stderr2("Invalid demo mode, must be one of: color, rectangles, shapes");
}
diff --git a/tests/widgets/ExampleRectanglesWidget.hpp b/tests/widgets/ExampleRectanglesWidget.hpp
@@ -56,7 +56,7 @@ public:
void init()
{
- this->setSize(300, 300);
+ BaseWidget::setSize(300, 300);
for (int i=0; i<9; ++i)
clicked[i] = false;
@@ -65,8 +65,8 @@ public:
protected:
void onDisplay() override
{
- const uint width = this->getWidth();
- const uint height = this->getHeight();
+ const uint width = BaseWidget::getWidth();
+ const uint height = BaseWidget::getHeight();
Rectangle<double> r;
@@ -115,8 +115,8 @@ protected:
if (ev.button != 1 || ! ev.press)
return false;
- const uint width = this->getWidth();
- const uint height = this->getHeight();
+ const uint width = BaseWidget::getWidth();
+ const uint height = BaseWidget::getHeight();
Rectangle<double> r;
@@ -134,7 +134,7 @@ protected:
if (r.contains(ev.pos))
{
clicked[0+i] = !clicked[0+i];
- this->repaint();
+ BaseWidget::repaint();
break;
}
@@ -144,7 +144,7 @@ protected:
if (r.contains(ev.pos))
{
clicked[3+i] = !clicked[3+i];
- this->repaint();
+ BaseWidget::repaint();
break;
}
@@ -154,7 +154,7 @@ protected:
if (r.contains(ev.pos))
{
clicked[6+i] = !clicked[6+i];
- this->repaint();
+ BaseWidget::repaint();
break;
}
}