Signed-off-by: falkTX <falktx@falktx.com>pull/272/head
@@ -21,15 +21,46 @@ | |||||
START_NAMESPACE_DGL | 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 | class Window | ||||
{ | { | ||||
public: | public: | ||||
/** | |||||
Constructor for a regular, standalone window. | |||||
*/ | |||||
explicit Window(Application& app); | 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); | explicit Window(Application& app, uintptr_t parentWindowHandle, double scaling, bool resizable); | ||||
/** | |||||
Destructor. | |||||
*/ | |||||
virtual ~Window(); | virtual ~Window(); | ||||
void close(); | void close(); | ||||
@@ -29,9 +29,7 @@ Application::PrivateData::PrivateData(const bool standalone) | |||||
isStandalone(standalone), | isStandalone(standalone), | ||||
isQuitting(false), | isQuitting(false), | ||||
visibleWindows(0), | visibleWindows(0), | ||||
#ifndef DPF_TEST_APPLICATION_CPP | |||||
windows(), | windows(), | ||||
#endif | |||||
idleCallbacks() | idleCallbacks() | ||||
{ | { | ||||
DISTRHO_SAFE_ASSERT_RETURN(world != nullptr,); | DISTRHO_SAFE_ASSERT_RETURN(world != nullptr,); | ||||
@@ -48,9 +46,7 @@ Application::PrivateData::~PrivateData() | |||||
DISTRHO_SAFE_ASSERT(isQuitting); | DISTRHO_SAFE_ASSERT(isQuitting); | ||||
DISTRHO_SAFE_ASSERT(visibleWindows == 0); | DISTRHO_SAFE_ASSERT(visibleWindows == 0); | ||||
#ifndef DPF_TEST_APPLICATION_CPP | |||||
windows.clear(); | windows.clear(); | ||||
#endif | |||||
idleCallbacks.clear(); | idleCallbacks.clear(); | ||||
if (world != nullptr) | if (world != nullptr) | ||||
@@ -87,14 +83,6 @@ void Application::PrivateData::idle(const uint timeoutInMs) | |||||
puglUpdate(world, timeoutInSeconds); | 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) | for (std::list<IdleCallback*>::iterator it = idleCallbacks.begin(), ite = idleCallbacks.end(); it != ite; ++it) | ||||
{ | { | ||||
IdleCallback* const idleCallback(*it); | IdleCallback* const idleCallback(*it); | ||||
@@ -43,10 +43,8 @@ struct Application::PrivateData { | |||||
If 0->1, application is starting. If 1->0, application is quitting/stopping. */ | If 0->1, application is starting. If 1->0, application is quitting/stopping. */ | ||||
uint visibleWindows; | uint visibleWindows; | ||||
#ifndef DPF_TEST_APPLICATION_CPP | |||||
/** List of windows for this application. Used as a way to call each window `idle`. */ | /** List of windows for this application. Used as a way to call each window `idle`. */ | ||||
std::list<Window*> windows; | std::list<Window*> windows; | ||||
#endif | |||||
/** List of idle callbacks for this application. Run after all windows `idle`. */ | /** List of idle callbacks for this application. Run after all windows `idle`. */ | ||||
std::list<IdleCallback*> idleCallbacks; | std::list<IdleCallback*> idleCallbacks; | ||||
@@ -52,8 +52,8 @@ Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* cons | |||||
Window::PrivateData::~PrivateData() | Window::PrivateData::~PrivateData() | ||||
{ | { | ||||
if (self != nullptr) | |||||
appData->windows.remove(self); | |||||
appData->idleCallbacks.remove(this); | |||||
appData->windows.remove(self); | |||||
if (view != nullptr) | if (view != nullptr) | ||||
puglFreeView(view); | puglFreeView(view); | ||||
@@ -63,7 +63,10 @@ Window::PrivateData::~PrivateData() | |||||
void Window::PrivateData::init(const bool resizable) | 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"); | DGL_DBG("Failed!\n"); | ||||
@@ -89,8 +92,6 @@ void Window::PrivateData::init(const bool resizable) | |||||
// puglSetFileSelectedFunc(fView, fileBrowserSelectedCallback); | // puglSetFileSelectedFunc(fView, fileBrowserSelectedCallback); | ||||
// #endif | // #endif | ||||
appData->windows.push_back(self); | |||||
// DGL_DBG("Success!\n"); | // 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) | PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const PuglEvent* const event) | ||||
{ | { | ||||
Window::PrivateData* const pData = (Window::PrivateData*)puglGetHandle(view); | Window::PrivateData* const pData = (Window::PrivateData*)puglGetHandle(view); | ||||
@@ -18,7 +18,7 @@ | |||||
#define DGL_WINDOW_PRIVATE_DATA_HPP_INCLUDED | #define DGL_WINDOW_PRIVATE_DATA_HPP_INCLUDED | ||||
#include "../Window.hpp" | #include "../Window.hpp" | ||||
#include "ApplicationPrivateData.hpp" | |||||
// #include "ApplicationPrivateData.hpp" | |||||
#include "pugl.hpp" | #include "pugl.hpp" | ||||
@@ -28,21 +28,45 @@ class Widget; | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
struct Window::PrivateData { | |||||
struct Window::PrivateData : IdleCallback { | |||||
/** Handy typedef for ... */ | |||||
typedef Application::PrivateData AppData; | 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; | PuglView* const view; | ||||
/** Constructor for a regular, standalone window. */ | |||||
PrivateData(AppData* appData, Window* self); | PrivateData(AppData* appData, Window* self); | ||||
/** Constructor for a regular, standalone window with a transient parent. */ | |||||
PrivateData(AppData* appData, Window* self, Window& transientWindow); | 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(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); | 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 close(); | ||||
void idleCallback() override; | |||||
static PuglStatus puglEventCallback(PuglView* view, const PuglEvent* event); | static PuglStatus puglEventCallback(PuglView* view, const PuglEvent* event); | ||||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData) | DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData) | ||||
@@ -30,9 +30,12 @@ endif | |||||
ifeq ($(HAVE_VULKAN),true) | ifeq ($(HAVE_VULKAN),true) | ||||
WTESTS = Window.vulkan | WTESTS = Window.vulkan | ||||
endif | endif | ||||
TARGETS = $(TESTS:%=../build/tests/%) | TARGETS = $(TESTS:%=../build/tests/%) | ||||
TARGETS += $(WTESTS:Window.%=../build/tests/Window.%) | 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 $*" | @echo "Linking $*" | ||||
$(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(OPENGL_LIBS) -o $@ | $(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(OPENGL_LIBS) -o $@ | ||||
@echo "Running test for $*" | @echo "Running test for $*" | ||||
$(SILENT) | |||||
gdb -ex run $@ | |||||
# $(SILENT) | |||||
$@ | |||||
# gdb -ex run | |||||
../build/tests/%.vulkan: ../build/tests/%.cpp.vulkan.o | ../build/tests/%.vulkan: ../build/tests/%.cpp.vulkan.o | ||||
@echo "Linking $*" | @echo "Linking $*" | ||||