commit 9edea25fab9c0e4b02ea3f2e508542f18b7d3f4c
parent 3b1e5d698a3f435e4b508ff3d6d27e7c7ec32f5d
Author: falkTX <falktx@falktx.com>
Date: Sun, 2 May 2021 18:57:11 +0100
Make Window::PrivateData an IdleCallback, add a few comments
Signed-off-by: falkTX <falktx@falktx.com>
Diffstat:
6 files changed, 80 insertions(+), 28 deletions(-)
diff --git a/dgl/Window.hpp b/dgl/Window.hpp
@@ -21,15 +21,46 @@
START_NAMESPACE_DGL
+class Application;
+
// -----------------------------------------------------------------------
-class Application;
+/**
+ DGL Window class.
+
+ This is the where all OS-related events initially happen, before being propagated to any widgets.
+
+ A Window MUST have an Application instance tied to it.
+ It is not possible to swap Application instances from within the lifetime of a Window.
+ But it is possible to completely change the Widgets that a Window contains during its lifetime.
+ Typically the event handling functions as following:
+ Application -> Window -> Top-Level-Widget -> SubWidgets
+
+ ...
+
+ Please note that, unlike many other graphical toolkits out there,
+ DGL makes a clear distinction between a Window and a Widget.
+ You cannot directly draw in a Window, you need to create a Widget for that.
+
+ ...
+ */
class Window
{
public:
+ /**
+ Constructor for a regular, standalone window.
+ */
explicit Window(Application& app);
+
+ /**
+ Constructor for an embed Window, typically used in modules or plugins that run inside another host.
+ */
explicit Window(Application& app, uintptr_t parentWindowHandle, double scaling, bool resizable);
+
+ /**
+ Destructor.
+ */
virtual ~Window();
void close();
diff --git a/dgl/src/ApplicationPrivateData.cpp b/dgl/src/ApplicationPrivateData.cpp
@@ -29,9 +29,7 @@ Application::PrivateData::PrivateData(const bool standalone)
isStandalone(standalone),
isQuitting(false),
visibleWindows(0),
-#ifndef DPF_TEST_APPLICATION_CPP
windows(),
-#endif
idleCallbacks()
{
DISTRHO_SAFE_ASSERT_RETURN(world != nullptr,);
@@ -48,9 +46,7 @@ Application::PrivateData::~PrivateData()
DISTRHO_SAFE_ASSERT(isQuitting);
DISTRHO_SAFE_ASSERT(visibleWindows == 0);
-#ifndef DPF_TEST_APPLICATION_CPP
windows.clear();
-#endif
idleCallbacks.clear();
if (world != nullptr)
@@ -87,14 +83,6 @@ void Application::PrivateData::idle(const uint timeoutInMs)
puglUpdate(world, timeoutInSeconds);
}
-// #ifndef DPF_TEST_APPLICATION_CPP
-// for (std::list<Window*>::iterator it = windows.begin(), ite = windows.end(); it != ite; ++it)
-// {
-// Window* const window(*it);
-// window->_idle();
-// }
-// #endif
-
for (std::list<IdleCallback*>::iterator it = idleCallbacks.begin(), ite = idleCallbacks.end(); it != ite; ++it)
{
IdleCallback* const idleCallback(*it);
diff --git a/dgl/src/ApplicationPrivateData.hpp b/dgl/src/ApplicationPrivateData.hpp
@@ -43,10 +43,8 @@ struct Application::PrivateData {
If 0->1, application is starting. If 1->0, application is quitting/stopping. */
uint visibleWindows;
-#ifndef DPF_TEST_APPLICATION_CPP
/** List of windows for this application. Used as a way to call each window `idle`. */
std::list<Window*> windows;
-#endif
/** List of idle callbacks for this application. Run after all windows `idle`. */
std::list<IdleCallback*> idleCallbacks;
diff --git a/dgl/src/WindowPrivateData.cpp b/dgl/src/WindowPrivateData.cpp
@@ -52,8 +52,8 @@ Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* cons
Window::PrivateData::~PrivateData()
{
- if (self != nullptr)
- appData->windows.remove(self);
+ appData->idleCallbacks.remove(this);
+ appData->windows.remove(self);
if (view != nullptr)
puglFreeView(view);
@@ -63,7 +63,10 @@ Window::PrivateData::~PrivateData()
void Window::PrivateData::init(const bool resizable)
{
- if (self == nullptr || view == nullptr)
+ appData->windows.push_back(self);
+ appData->idleCallbacks.push_back(this);
+
+ if (view == nullptr)
{
/*
DGL_DBG("Failed!\n");
@@ -89,8 +92,6 @@ void Window::PrivateData::init(const bool resizable)
// puglSetFileSelectedFunc(fView, fileBrowserSelectedCallback);
// #endif
- appData->windows.push_back(self);
-
// DGL_DBG("Success!\n");
}
@@ -114,6 +115,12 @@ void Window::PrivateData::close()
// -----------------------------------------------------------------------
+void Window::PrivateData::idleCallback()
+{
+}
+
+// -----------------------------------------------------------------------
+
PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const PuglEvent* const event)
{
Window::PrivateData* const pData = (Window::PrivateData*)puglGetHandle(view);
diff --git a/dgl/src/WindowPrivateData.hpp b/dgl/src/WindowPrivateData.hpp
@@ -18,7 +18,7 @@
#define DGL_WINDOW_PRIVATE_DATA_HPP_INCLUDED
#include "../Window.hpp"
-#include "ApplicationPrivateData.hpp"
+// #include "ApplicationPrivateData.hpp"
#include "pugl.hpp"
@@ -28,21 +28,45 @@ class Widget;
// -----------------------------------------------------------------------
-struct Window::PrivateData {
+struct Window::PrivateData : IdleCallback {
+ /** Handy typedef for ... */
typedef Application::PrivateData AppData;
- AppData* const appData;
- Window* const self;
+ /** Direct access to DGL Application private data where we registers ourselves in. */
+ AppData* const appData;
+
+ /** Pointer to the DGL Window class that this private data belongs to. */
+ Window* const self;
+
+ /** Pugl view instance. */
PuglView* const view;
+ /** Constructor for a regular, standalone window. */
PrivateData(AppData* appData, Window* self);
+
+ /** Constructor for a regular, standalone window with a transient parent. */
PrivateData(AppData* appData, Window* self, Window& transientWindow);
+
+ /** Constructor for an embed Window, with a few extra hints from the host side. */
PrivateData(AppData* appData, Window* self, uintptr_t parentWindowHandle, double scaling, bool resizable);
- ~PrivateData();
+ /** Destructor. */
+ ~PrivateData() override;
+
+ /** Helper initialization function called at the end of all this class constructors. */
void init(bool resizable);
+
+ /** Hide window and notify application of a window close event.
+ * Does nothing if window is embed (that is, not standalone).
+ * The application event-loop will stop if all windows have been closed.
+ *
+ * @note It is possible to hide the window while not stopping event-loop.
+ * A closed window is always hidden, but the reverse is not always true.
+ */
void close();
+ void idleCallback() override;
+
static PuglStatus puglEventCallback(PuglView* view, const PuglEvent* event);
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData)
diff --git a/tests/Makefile b/tests/Makefile
@@ -30,9 +30,12 @@ endif
ifeq ($(HAVE_VULKAN),true)
WTESTS = Window.vulkan
endif
+
TARGETS = $(TESTS:%=../build/tests/%)
TARGETS += $(WTESTS:Window.%=../build/tests/Window.%)
-OBJS = $(TARGETS:%=%.cpp.o)
+
+OBJS = $(TESTS:%=../build/tests/%.cpp.o)
+OBJS += $(WTESTS:Window.%=../build/tests/Window.%.cpp.o)
# ---------------------------------------------------------------------------------------------------------------------
@@ -65,8 +68,9 @@ all: $(TARGETS)
@echo "Linking $*"
$(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(OPENGL_LIBS) -o $@
@echo "Running test for $*"
- $(SILENT)
- gdb -ex run $@
+# $(SILENT)
+ $@
+# gdb -ex run
../build/tests/%.vulkan: ../build/tests/%.cpp.vulkan.o
@echo "Linking $*"