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:
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). */