DPF

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

commit 919f18973ac4ec270bb2f4028517336ae2ec0ce8
parent 57817027713af9e3b4bea411106c47c668478980
Author: falkTX <falktx@falktx.com>
Date:   Fri, 28 May 2021 12:05:02 +0100

Allow one Window to have many top level widgets

Signed-off-by: falkTX <falktx@falktx.com>

Diffstat:
Mdgl/src/TopLevelWidgetPrivateData.cpp | 5++---
Mdgl/src/WindowPrivateData.cpp | 85++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
Mdgl/src/WindowPrivateData.hpp | 6++++--
3 files changed, 71 insertions(+), 25 deletions(-)

diff --git a/dgl/src/TopLevelWidgetPrivateData.cpp b/dgl/src/TopLevelWidgetPrivateData.cpp @@ -28,13 +28,12 @@ TopLevelWidget::PrivateData::PrivateData(TopLevelWidget* const s, Window& w) selfw(s), window(w) { - window.pData->topLevelWidget = self; + window.pData->topLevelWidgets.push_back(self); } TopLevelWidget::PrivateData::~PrivateData() { - // FIXME? - window.pData->topLevelWidget = nullptr; + window.pData->topLevelWidgets.remove(self); } bool TopLevelWidget::PrivateData::keyboardEvent(const KeyboardEvent& ev) diff --git a/dgl/src/WindowPrivateData.cpp b/dgl/src/WindowPrivateData.cpp @@ -51,6 +51,12 @@ START_NAMESPACE_DGL #define DEFAULT_WIDTH 640 #define DEFAULT_HEIGHT 480 +#define FOR_EACH_TOP_LEVEL_WIDGET(it) \ + for (std::list<TopLevelWidget*>::iterator it = topLevelWidgets.begin(); it != topLevelWidgets.end(); ++it) + +#define FOR_EACH_TOP_LEVEL_WIDGET_INV(rit) \ + for (std::list<TopLevelWidget*>::reverse_iterator rit = topLevelWidgets.rbegin(); rit != topLevelWidgets.rend(); ++rit) + // ----------------------------------------------------------------------- #ifdef DISTRHO_OS_WINDOWS @@ -73,7 +79,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s) appData(a.pData), self(s), view(puglNewView(appData->world)), - topLevelWidget(nullptr), + topLevelWidgets(), isClosed(true), isVisible(false), isEmbed(false), @@ -95,7 +101,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, PrivateData* c appData(a.pData), self(s), view(puglNewView(appData->world)), - topLevelWidget(nullptr), + topLevelWidgets(), isClosed(true), isVisible(false), isEmbed(false), @@ -121,7 +127,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, appData(a.pData), self(s), view(puglNewView(appData->world)), - topLevelWidget(nullptr), + topLevelWidgets(), isClosed(parentWindowHandle == 0), isVisible(parentWindowHandle != 0), isEmbed(parentWindowHandle != 0), @@ -152,7 +158,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, appData(a.pData), self(s), view(puglNewView(appData->world)), - topLevelWidget(nullptr), + topLevelWidgets(), isClosed(parentWindowHandle == 0), isVisible(parentWindowHandle != 0), isEmbed(parentWindowHandle != 0), @@ -642,8 +648,12 @@ void Window::PrivateData::onPuglConfigure(const double width, const double heigh self->onReshape(uwidth, uheight); #ifndef DPF_TEST_WINDOW_CPP - if (topLevelWidget != nullptr) - topLevelWidget->setSize(uwidth, uheight); + FOR_EACH_TOP_LEVEL_WIDGET(it) + { + TopLevelWidget* const widget(*it); + + widget->setSize(uwidth, uheight); + } #endif // always repaint after a resize @@ -657,8 +667,13 @@ void Window::PrivateData::onPuglExpose() puglOnDisplayPrepare(view); #ifndef DPF_TEST_WINDOW_CPP - if (topLevelWidget != nullptr) - topLevelWidget->pData->display(); + FOR_EACH_TOP_LEVEL_WIDGET(it) + { + TopLevelWidget* const widget(*it); + + if (widget->isVisible()) + widget->pData->display(); + } #endif } @@ -711,8 +726,13 @@ void Window::PrivateData::onPuglKey(const Widget::KeyboardEvent& ev) return modal.child->focus(); #ifndef DPF_TEST_WINDOW_CPP - if (topLevelWidget != nullptr) - topLevelWidget->pData->keyboardEvent(ev); + FOR_EACH_TOP_LEVEL_WIDGET_INV(rit) + { + TopLevelWidget* const widget(*rit); + + if (widget->isVisible() && widget->pData->keyboardEvent(ev)) + break; + } #endif } @@ -724,8 +744,13 @@ void Window::PrivateData::onPuglSpecial(const Widget::SpecialEvent& ev) return modal.child->focus(); #ifndef DPF_TEST_WINDOW_CPP - if (topLevelWidget != nullptr) - topLevelWidget->pData->specialEvent(ev); + FOR_EACH_TOP_LEVEL_WIDGET_INV(rit) + { + TopLevelWidget* const widget(*rit); + + if (widget->isVisible() && widget->pData->specialEvent(ev)) + break; + } #endif } @@ -737,8 +762,13 @@ void Window::PrivateData::onPuglText(const Widget::CharacterInputEvent& ev) return modal.child->focus(); #ifndef DPF_TEST_WINDOW_CPP - if (topLevelWidget != nullptr) - topLevelWidget->pData->characterInputEvent(ev); + FOR_EACH_TOP_LEVEL_WIDGET_INV(rit) + { + TopLevelWidget* const widget(*rit); + + if (widget->isVisible() && widget->pData->characterInputEvent(ev)) + break; + } #endif } @@ -750,8 +780,13 @@ void Window::PrivateData::onPuglMouse(const Widget::MouseEvent& ev) return modal.child->focus(); #ifndef DPF_TEST_WINDOW_CPP - if (topLevelWidget != nullptr) - topLevelWidget->pData->mouseEvent(ev); + FOR_EACH_TOP_LEVEL_WIDGET_INV(rit) + { + TopLevelWidget* const widget(*rit); + + if (widget->isVisible() && widget->pData->mouseEvent(ev)) + break; + } #endif } @@ -763,8 +798,13 @@ void Window::PrivateData::onPuglMotion(const Widget::MotionEvent& ev) return modal.child->focus(); #ifndef DPF_TEST_WINDOW_CPP - if (topLevelWidget != nullptr) - topLevelWidget->pData->motionEvent(ev); + FOR_EACH_TOP_LEVEL_WIDGET_INV(rit) + { + TopLevelWidget* const widget(*rit); + + if (widget->isVisible() && widget->pData->motionEvent(ev)) + break; + } #endif } @@ -776,8 +816,13 @@ void Window::PrivateData::onPuglScroll(const Widget::ScrollEvent& ev) return modal.child->focus(); #ifndef DPF_TEST_WINDOW_CPP - if (topLevelWidget != nullptr) - topLevelWidget->pData->scrollEvent(ev); + FOR_EACH_TOP_LEVEL_WIDGET_INV(rit) + { + TopLevelWidget* const widget(*rit); + + if (widget->isVisible() && widget->pData->scrollEvent(ev)) + break; + } #endif } diff --git a/dgl/src/WindowPrivateData.hpp b/dgl/src/WindowPrivateData.hpp @@ -23,6 +23,8 @@ #include "pugl.hpp" +#include <list> + START_NAMESPACE_DGL class TopLevelWidget; @@ -45,8 +47,8 @@ struct Window::PrivateData : IdleCallback { /** Reserved space for graphics context. */ mutable uint8_t graphicsContext[sizeof(void*)]; - /** The top-level widget associated with this Window. */ - TopLevelWidget* topLevelWidget; + /** The top-level widgets associated with this Window. */ + std::list<TopLevelWidget*> topLevelWidgets; /** Whether this Window is closed (not visible or counted in the Application it is tied to). Defaults to true unless embed (embed windows are never closed). */