@@ -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 | |||