| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2020 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||
| @@ -21,12 +21,12 @@ | |||
| START_NAMESPACE_DGL | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Forward class names | |||
| class Window; | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| /** | |||
| Base DGL Application class. | |||
| @@ -63,11 +63,12 @@ public: | |||
| idle() is called at regular intervals. | |||
| @note This function is meant for standalones only, *never* call this from plugins. | |||
| */ | |||
| void exec(uint idleTime = 10); | |||
| void exec(uint idleTimeInMs = 10); | |||
| /** | |||
| Quit the application. | |||
| This stops the event-loop and closes all Windows. | |||
| @note This function is meant for standalones only, *never* call this from plugins. | |||
| */ | |||
| void quit(); | |||
| @@ -85,7 +86,7 @@ private: | |||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Application) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| END_NAMESPACE_DGL | |||
| @@ -92,7 +92,7 @@ enum Key { | |||
| /** | |||
| Graphics context, definition depends on build type. | |||
| */ | |||
| struct GraphicsContext; | |||
| struct GraphicsContext {}; | |||
| /** | |||
| Idle callback. | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||
| @@ -26,9 +26,9 @@ START_NAMESPACE_DGL | |||
| // ----------------------------------------------------------------------- | |||
| /** | |||
| Graphics context. | |||
| Cairo Graphics context. | |||
| */ | |||
| struct GraphicsContext | |||
| struct CairoGraphicsContext : GraphicsContext | |||
| { | |||
| cairo_t* cairo; // FIXME proper name.. | |||
| }; | |||
| @@ -24,6 +24,7 @@ BUILD_CXX_FLAGS += -Wno-missing-field-initializers -Wno-extra -Wno-narrowing | |||
| OBJS_common = \ | |||
| ../build/dgl/Application.cpp.o \ | |||
| ../build/dgl/ApplicationPrivateData.cpp.o \ | |||
| ../build/dgl/Color.cpp.o \ | |||
| ../build/dgl/Geometry.cpp.o \ | |||
| ../build/dgl/ImageBase.cpp.o \ | |||
| @@ -108,9 +108,9 @@ START_NAMESPACE_DGL | |||
| // ----------------------------------------------------------------------- | |||
| /** | |||
| Graphics context. | |||
| OpenGL Graphics context. | |||
| */ | |||
| struct GraphicsContext | |||
| struct OpenGLGraphicsContext : GraphicsContext | |||
| { | |||
| }; | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2020 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||
| @@ -18,7 +18,7 @@ | |||
| START_NAMESPACE_DGL | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| Application::Application(const bool isStandalone) | |||
| : pData(new PrivateData(isStandalone)) {} | |||
| @@ -33,14 +33,18 @@ void Application::idle() | |||
| pData->idle(0); | |||
| } | |||
| void Application::exec(const uint idleTime) | |||
| void Application::exec(const uint idleTimeInMs) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(pData->isStandalone,); | |||
| while (! pData->isQuitting) | |||
| pData->idle(idleTime); | |||
| pData->idle(idleTimeInMs); | |||
| } | |||
| void Application::quit() | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(pData->isStandalone,); | |||
| pData->quit(); | |||
| } | |||
| @@ -49,6 +53,6 @@ bool Application::isQuiting() const noexcept | |||
| return pData->isQuitting; | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| END_NAMESPACE_DGL | |||
| @@ -0,0 +1,110 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||
| * permission notice appear in all copies. | |||
| * | |||
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |||
| * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |||
| * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |||
| * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |||
| * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |||
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
| */ | |||
| #include "ApplicationPrivateData.hpp" | |||
| #include "../Window.hpp" | |||
| #include "pugl-upstream/include/pugl/pugl.h" | |||
| START_NAMESPACE_DGL | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| Application::PrivateData::PrivateData(const bool standalone) | |||
| : world(puglNewWorld(standalone ? PUGL_PROGRAM : PUGL_MODULE, | |||
| standalone ? PUGL_WORLD_THREADS : 0x0)), | |||
| isStandalone(standalone), | |||
| isStarting(true), | |||
| isQuitting(false), | |||
| visibleWindows(0), | |||
| windows(), | |||
| idleCallbacks() | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(world != nullptr,); | |||
| puglSetWorldHandle(world, this); | |||
| puglSetClassName(world, DISTRHO_MACRO_AS_STRING(DGL_NAMESPACE)); | |||
| // puglSetLogLevel(world, PUGL_LOG_LEVEL_DEBUG); | |||
| } | |||
| Application::PrivateData::~PrivateData() | |||
| { | |||
| DISTRHO_SAFE_ASSERT(!isStarting); | |||
| DISTRHO_SAFE_ASSERT(isQuitting); | |||
| DISTRHO_SAFE_ASSERT(visibleWindows == 0); | |||
| windows.clear(); | |||
| idleCallbacks.clear(); | |||
| if (world != nullptr) | |||
| puglFreeWorld(world); | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| void Application::PrivateData::oneWindowShown() noexcept | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(isStandalone,); | |||
| if (++visibleWindows == 1) | |||
| { | |||
| isStarting = false; | |||
| isQuitting = false; | |||
| } | |||
| } | |||
| void Application::PrivateData::oneWindowHidden() noexcept | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(isStandalone,); | |||
| DISTRHO_SAFE_ASSERT_RETURN(visibleWindows != 0,); | |||
| if (--visibleWindows == 0) | |||
| isQuitting = true; | |||
| } | |||
| void Application::PrivateData::idle(const uint timeoutInMs) | |||
| { | |||
| puglUpdate(world, timeoutInMs == 0 ? 0.0 : static_cast<double>(timeoutInMs) / 1000.0); | |||
| for (std::list<Window*>::iterator it = windows.begin(), ite = windows.end(); it != ite; ++it) | |||
| { | |||
| Window* const window(*it); | |||
| window->_idle(); | |||
| } | |||
| for (std::list<IdleCallback*>::iterator it = idleCallbacks.begin(), ite = idleCallbacks.end(); it != ite; ++it) | |||
| { | |||
| IdleCallback* const idleCallback(*it); | |||
| idleCallback->idleCallback(); | |||
| } | |||
| } | |||
| void Application::PrivateData::quit() | |||
| { | |||
| isQuitting = true; | |||
| for (std::list<Window*>::reverse_iterator rit = windows.rbegin(), rite = windows.rend(); rit != rite; ++rit) | |||
| { | |||
| Window* const window(*rit); | |||
| window->close(); | |||
| } | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| END_NAMESPACE_DGL | |||
| @@ -18,101 +18,61 @@ | |||
| #define DGL_APP_PRIVATE_DATA_HPP_INCLUDED | |||
| #include "../Application.hpp" | |||
| #include "../Window.hpp" | |||
| #include "pugl-upstream/include/pugl/pugl.h" | |||
| #include <list> | |||
| typedef struct PuglWorldImpl PuglWorld; | |||
| START_NAMESPACE_DGL | |||
| // ----------------------------------------------------------------------- | |||
| class Window; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| struct Application::PrivateData { | |||
| /** Pugl world instance. */ | |||
| PuglWorld* const world; | |||
| /** Whether the application is running as standalone, otherwise it is part of a plugin. */ | |||
| const bool isStandalone; | |||
| /** Whether the applicating is starting up, not yet fully initialized. Defaults to true. */ | |||
| bool isStarting; | |||
| /** Whether the applicating is about to quit, or already stopped. Defaults to false. */ | |||
| bool isQuitting; | |||
| bool isStandalone; | |||
| /** Counter of visible windows, only used in standalone mode. | |||
| If 0->1, application is starting. If 1->0, application is quitting/stopping. */ | |||
| uint visibleWindows; | |||
| /** List of windows for this application. Used as a way to call each window `idle`. */ | |||
| std::list<Window*> windows; | |||
| /** List of idle callbacks for this application. Run after all windows `idle`. */ | |||
| std::list<IdleCallback*> idleCallbacks; | |||
| PuglWorld* const world; | |||
| PrivateData(const bool standalone) | |||
| : isQuitting(false), | |||
| isStandalone(standalone), | |||
| visibleWindows(0), | |||
| windows(), | |||
| idleCallbacks(), | |||
| world(puglNewWorld(isStandalone ? PUGL_PROGRAM : PUGL_MODULE, | |||
| isStandalone ? PUGL_WORLD_THREADS : 0x0)) | |||
| { | |||
| puglSetWorldHandle(world, this); | |||
| // puglSetLogLevel(world, PUGL_LOG_LEVEL_DEBUG); | |||
| // TODO puglSetClassName | |||
| } | |||
| ~PrivateData() | |||
| { | |||
| DISTRHO_SAFE_ASSERT(isQuitting); | |||
| DISTRHO_SAFE_ASSERT(visibleWindows == 0); | |||
| windows.clear(); | |||
| idleCallbacks.clear(); | |||
| d_stdout("calling puglFreeWorld"); | |||
| puglFreeWorld(world); | |||
| } | |||
| void oneWindowShown() noexcept | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(isStandalone,); | |||
| if (++visibleWindows == 1) | |||
| isQuitting = false; | |||
| } | |||
| void oneWindowHidden() noexcept | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(isStandalone,); | |||
| DISTRHO_SAFE_ASSERT_RETURN(visibleWindows > 0,); | |||
| if (--visibleWindows == 0) | |||
| isQuitting = true; | |||
| } | |||
| void idle(const uint timeout) | |||
| { | |||
| puglUpdate(world, timeout == 0 ? 0.0 : (1.0 / static_cast<double>(timeout))); | |||
| for (std::list<Window*>::iterator it = windows.begin(), ite = windows.end(); it != ite; ++it) | |||
| { | |||
| Window* const window(*it); | |||
| window->_idle(); | |||
| } | |||
| for (std::list<IdleCallback*>::iterator it = idleCallbacks.begin(), ite = idleCallbacks.end(); it != ite; ++it) | |||
| { | |||
| IdleCallback* const idleCallback(*it); | |||
| idleCallback->idleCallback(); | |||
| } | |||
| } | |||
| void quit() | |||
| { | |||
| isQuitting = true; | |||
| for (std::list<Window*>::reverse_iterator rit = windows.rbegin(), rite = windows.rend(); rit != rite; ++rit) | |||
| { | |||
| Window* const window(*rit); | |||
| window->close(); | |||
| } | |||
| } | |||
| /** Constructor and destructor */ | |||
| PrivateData(const bool standalone); | |||
| ~PrivateData(); | |||
| /** Flag one window shown or hidden status, which modifies @a visibleWindows. | |||
| For standalone mode only. | |||
| Modifies @a isStarting and @a isQuitting under certain conditions */ | |||
| void oneWindowShown() noexcept; | |||
| void oneWindowHidden() noexcept; | |||
| /** Run Pugl world update for @a timeoutInMs, and then the idle functions for each window and idle callback, | |||
| in order of registration. */ | |||
| void idle(const uint timeoutInMs); | |||
| /** Set flag indicating application is quitting, and closes all windows in reverse order of registration. */ | |||
| void quit(); | |||
| DISTRHO_DECLARE_NON_COPY_STRUCT(PrivateData) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| END_NAMESPACE_DGL | |||
| @@ -77,7 +77,7 @@ void Widget::PrivateData::display(const uint width, | |||
| #endif | |||
| #ifdef DGL_CAIRO | |||
| cairo_t* cr = parent.getGraphicsContext().cairo; | |||
| cairo_t* cr = static_cast<const CairoGraphicsContext&>(parent.getGraphicsContext()).cairo; | |||
| cairo_matrix_t matrix; | |||
| cairo_get_matrix(cr, &matrix); | |||
| cairo_translate(cr, absolutePos.getX(), absolutePos.getY()); | |||
| @@ -50,6 +50,8 @@ inline float round(float __x) | |||
| # define M_PI 3.14159265358979323846 | |||
| #endif | |||
| #define DISTRHO_MACRO_AS_STRING(MACRO) #MACRO | |||
| // ----------------------------------------------------------------------- | |||
| // misc functions | |||