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 $*" | ||||