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