Signed-off-by: falkTX <falktx@falktx.com>pull/272/head
| @@ -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(); | |||
| @@ -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); | |||
| @@ -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; | |||
| @@ -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); | |||
| @@ -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) | |||
| @@ -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 $*" | |||