| @@ -28,6 +28,13 @@ class Window; | |||
| class App | |||
| { | |||
| public: | |||
| class IdleCallback | |||
| { | |||
| public: | |||
| ~IdleCallback() {} | |||
| virtual void idleCallback() = 0; | |||
| }; | |||
| App(); | |||
| ~App(); | |||
| @@ -36,15 +43,18 @@ public: | |||
| void quit(); | |||
| bool isQuiting() const; | |||
| void addIdleCallback(IdleCallback* const callback); | |||
| void removeIdleCallback(IdleCallback* const callback); | |||
| private: | |||
| struct PrivateData; | |||
| PrivateData* const pData; | |||
| friend class Window; | |||
| void addWindow(Window* const window); | |||
| void removeWindow(Window* const window); | |||
| void oneShown(); | |||
| void oneHidden(); | |||
| void _addWindow(Window* const window); | |||
| void _removeWindow(Window* const window); | |||
| void _oneShown(); | |||
| void _oneHidden(); | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| @@ -46,7 +46,6 @@ public: | |||
| void exec(bool lockWait = false); | |||
| void focus(); | |||
| void idle(); | |||
| void repaint(); | |||
| bool isVisible() const noexcept; | |||
| @@ -72,10 +71,12 @@ public: | |||
| private: | |||
| class PrivateData; | |||
| PrivateData* const pData; | |||
| friend class App; | |||
| friend class Widget; | |||
| void addWidget(Widget* const widget); | |||
| void removeWidget(Widget* const widget); | |||
| void _addWidget(Widget* const widget); | |||
| void _removeWidget(Widget* const widget); | |||
| void _idle(); | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| @@ -27,6 +27,7 @@ struct App::PrivateData { | |||
| bool doLoop; | |||
| unsigned visibleWindows; | |||
| std::list<Window*> windows; | |||
| std::list<IdleCallback*> idleCallbacks; | |||
| PrivateData() | |||
| : doLoop(false), | |||
| @@ -43,6 +44,7 @@ App::App() | |||
| App::~App() | |||
| { | |||
| pData->windows.clear(); | |||
| pData->idleCallbacks.clear(); | |||
| delete pData; | |||
| } | |||
| @@ -51,7 +53,13 @@ void App::idle() | |||
| for (std::list<Window*>::iterator it = pData->windows.begin(); it != pData->windows.end(); ++it) | |||
| { | |||
| Window* const window(*it); | |||
| window->idle(); | |||
| window->_idle(); | |||
| } | |||
| for (std::list<IdleCallback*>::iterator it = pData->idleCallbacks.begin(); it != pData->idleCallbacks.end(); ++it) | |||
| { | |||
| IdleCallback* const idleCallback(*it); | |||
| idleCallback->idleCallback(); | |||
| } | |||
| } | |||
| @@ -82,25 +90,39 @@ bool App::isQuiting() const | |||
| // ----------------------------------------------------------------------- | |||
| void App::addWindow(Window* const window) | |||
| void App::addIdleCallback(IdleCallback* const callback) | |||
| { | |||
| if (callback != nullptr) | |||
| pData->idleCallbacks.push_back(callback); | |||
| } | |||
| void App::removeIdleCallback(IdleCallback* const callback) | |||
| { | |||
| if (callback != nullptr) | |||
| pData->idleCallbacks.remove(callback); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| void App::_addWindow(Window* const window) | |||
| { | |||
| if (window != nullptr) | |||
| pData->windows.push_back(window); | |||
| } | |||
| void App::removeWindow(Window* const window) | |||
| void App::_removeWindow(Window* const window) | |||
| { | |||
| if (window != nullptr) | |||
| pData->windows.remove(window); | |||
| } | |||
| void App::oneShown() | |||
| void App::_oneShown() | |||
| { | |||
| if (++pData->visibleWindows == 1) | |||
| pData->doLoop = true; | |||
| } | |||
| void App::oneHidden() | |||
| void App::_oneHidden() | |||
| { | |||
| if (--pData->visibleWindows == 0) | |||
| pData->doLoop = false; | |||
| @@ -29,12 +29,12 @@ Widget::Widget(Window& parent) | |||
| : fParent(parent), | |||
| fVisible(true) | |||
| { | |||
| fParent.addWidget(this); | |||
| fParent._addWidget(this); | |||
| } | |||
| Widget::~Widget() | |||
| { | |||
| fParent.removeWidget(this); | |||
| fParent._removeWidget(this); | |||
| } | |||
| bool Widget::isVisible() const noexcept | |||
| @@ -132,7 +132,7 @@ public: | |||
| init(); | |||
| DBG("Embed window always visible\n"); | |||
| fApp.oneShown(); | |||
| fApp._oneShown(); | |||
| fFirstInit = false; | |||
| } | |||
| @@ -173,7 +173,7 @@ public: | |||
| // process any initial events | |||
| puglProcessEvents(fView); | |||
| fApp.addWindow(fSelf); | |||
| fApp._addWindow(fSelf); | |||
| } | |||
| ~PrivateData() | |||
| @@ -185,7 +185,7 @@ public: | |||
| if (fSelf != nullptr && fView != nullptr) | |||
| { | |||
| fApp.removeWindow(fSelf); | |||
| fApp._removeWindow(fSelf); | |||
| puglDestroy(fView); | |||
| } | |||
| @@ -201,7 +201,7 @@ public: | |||
| if (! fFirstInit) | |||
| { | |||
| fApp.oneHidden(); | |||
| fApp._oneHidden(); | |||
| fFirstInit = true; | |||
| } | |||
| } | |||
| @@ -250,17 +250,9 @@ public: | |||
| #endif | |||
| } | |||
| void idle() | |||
| { | |||
| puglProcessEvents(fView); | |||
| if (fVisible && fModal.enabled && fModal.parent != nullptr) | |||
| fModal.parent->idle(); | |||
| } | |||
| void repaint() | |||
| { | |||
| DBG("Window repaint\n"); | |||
| //DBG("Window repaint\n"); | |||
| puglPostRedisplay(fView); | |||
| } | |||
| @@ -317,7 +309,7 @@ public: | |||
| { | |||
| if (fFirstInit) | |||
| { | |||
| fApp.oneShown(); | |||
| fApp._oneShown(); | |||
| fFirstInit = false; | |||
| } | |||
| } | |||
| @@ -471,6 +463,14 @@ public: | |||
| fWidgets.remove(widget); | |||
| } | |||
| void idle() | |||
| { | |||
| puglProcessEvents(fView); | |||
| if (fVisible && fModal.enabled && fModal.parent != nullptr) | |||
| fModal.parent->idle(); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| void exec_init() | |||
| @@ -522,7 +522,7 @@ public: | |||
| protected: | |||
| void onDisplay() | |||
| { | |||
| DBG("PUGL: onDisplay\n"); | |||
| //DBG("PUGL: onDisplay\n"); | |||
| glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |||
| @@ -783,11 +783,6 @@ void Window::focus() | |||
| pData->focus(); | |||
| } | |||
| void Window::idle() | |||
| { | |||
| pData->idle(); | |||
| } | |||
| void Window::repaint() | |||
| { | |||
| pData->repaint(); | |||
| @@ -860,16 +855,21 @@ intptr_t Window::getWindowId() const | |||
| return pData->getWindowId(); | |||
| } | |||
| void Window::addWidget(Widget* const widget) | |||
| void Window::_addWidget(Widget* const widget) | |||
| { | |||
| pData->addWidget(widget); | |||
| } | |||
| void Window::removeWidget(Widget* const widget) | |||
| void Window::_removeWidget(Widget* const widget) | |||
| { | |||
| pData->removeWidget(widget); | |||
| } | |||
| void Window::_idle() | |||
| { | |||
| pData->idle(); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| END_NAMESPACE_DGL | |||