mirror of https://github.com/mosra/magnum.git
Browse Source
Better API for handling more than one application screens (context switching, event propagation etc.). Taken from Push The Box, updated to current coding style and templated.pull/34/head
15 changed files with 680 additions and 0 deletions
@ -0,0 +1,38 @@
|
||||
#ifndef Magnum_Platform_Platform_h |
||||
#define Magnum_Platform_Platform_h |
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
/** @file
|
||||
* @brief Forward declarations for @ref Magnum::Platform namespace |
||||
*/ |
||||
|
||||
namespace Magnum { namespace Platform { |
||||
|
||||
template<class> class BasicScreen; |
||||
template<class> class BasicScreenedApplication; |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,265 @@
|
||||
#ifndef Magnum_Platform_AbstractScreen_h |
||||
#define Magnum_Platform_AbstractScreen_h |
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
/** @file
|
||||
* @brief Class @ref Magnum::Platform::BasicScreen |
||||
*/ |
||||
|
||||
#include <Containers/EnumSet.h> |
||||
|
||||
#include "Platform/ScreenedApplication.h" |
||||
|
||||
namespace Magnum { namespace Platform { |
||||
|
||||
namespace Implementation { |
||||
enum class PropagatedScreenEvent: UnsignedByte { |
||||
Draw = 1 << 0, |
||||
Input = 1 << 1 |
||||
}; |
||||
|
||||
typedef Containers::EnumSet<PropagatedScreenEvent, UnsignedByte> PropagatedScreenEvents; |
||||
CORRADE_ENUMSET_OPERATORS(PropagatedScreenEvents) |
||||
} |
||||
|
||||
/**
|
||||
@brief Base for application screens |
||||
|
||||
See @ref BasicScreenedApplication for more information. |
||||
|
||||
If exactly one application header is included, this class is also aliased to |
||||
`Platform::Screen`. |
||||
|
||||
@section Screen-explicit-specializations Explicit template specializations |
||||
|
||||
The following specialization are explicitly compiled into each particular |
||||
`*Application` library. For other specializations you have to use |
||||
@ref ScreenedApplication.hpp implementation file to avoid linker errors. See |
||||
@ref compilation-speedup-hpp for more information. |
||||
|
||||
- @ref GlutApplication "BasicScreen<GlutApplication>" |
||||
- @ref GlxApplication "BasicScreen<GlxApplication>" |
||||
- @ref NaClApplication "BasicScreen<NaClApplication>" |
||||
- @ref Sdl2Application "BasicScreen<Sdl2Application>" |
||||
- @ref XEglApplication "BasicScreen<XEglApplication>" |
||||
*/ |
||||
template<class Application> class BasicScreen: private Containers::LinkedListItem<BasicScreen<Application>, BasicScreenedApplication<Application>> { |
||||
friend class Containers::LinkedListItem<BasicScreen<Application>, BasicScreenedApplication<Application>>; |
||||
friend class Containers::LinkedList<BasicScreen<Application>>; |
||||
friend class BasicScreenedApplication<Application>; |
||||
|
||||
public: |
||||
#ifdef DOXYGEN_GENERATING_OUTPUT |
||||
/**
|
||||
* @brief Event propagated to given screen |
||||
* |
||||
* @see @ref PropagatedEvents, @ref BasicScreen::setPropagatedEvents() |
||||
*/ |
||||
enum class PropagatedEvent: UnsignedByte { |
||||
/**
|
||||
* Draw event. |
||||
* |
||||
* When enabled, drawEvent() is propagated to this screen. |
||||
*/ |
||||
Draw = 1 << 0, |
||||
|
||||
/**
|
||||
* Input events. |
||||
* |
||||
* When enabled, keyPressEvent(), keyReleaseEvent(), mousePressEvent(), |
||||
* mouseReleaseEvent() and mouseMoveEvent() are propagated to this |
||||
* screen. |
||||
*/ |
||||
Input = 1 << 1 |
||||
}; |
||||
|
||||
/**
|
||||
* @brief Events propagated to given screen |
||||
* |
||||
* @see @ref setPropagatedEvents() |
||||
*/ |
||||
typedef Containers::EnumSet<PropagatedEvent, UnsignedByte> PropagatedEvents; |
||||
#else |
||||
typedef Implementation::PropagatedScreenEvent PropagatedEvent; |
||||
typedef Implementation::PropagatedScreenEvents PropagatedEvents; |
||||
#endif |
||||
|
||||
/** @brief Input event */ |
||||
typedef typename BasicScreenedApplication<Application>::InputEvent InputEvent; |
||||
|
||||
/** @brief Key event */ |
||||
typedef typename BasicScreenedApplication<Application>::KeyEvent KeyEvent; |
||||
|
||||
/** @brief Mouse event */ |
||||
typedef typename BasicScreenedApplication<Application>::MouseEvent MouseEvent; |
||||
|
||||
/** @brief Mouse move event */ |
||||
typedef typename BasicScreenedApplication<Application>::MouseMoveEvent MouseMoveEvent; |
||||
|
||||
explicit BasicScreen(); |
||||
~BasicScreen(); |
||||
|
||||
/** @brief Events propagated to this screen */ |
||||
PropagatedEvents propagatedEvents() const { return _propagatedEvents; } |
||||
|
||||
/**
|
||||
* @brief Set events propagated to this screen |
||||
* |
||||
* For non-propagated events related event functions are not called. |
||||
* No events are propagated by default, call this function in |
||||
* @ref focusEvent() and @ref blurEvent() to reflect focus changes. |
||||
*/ |
||||
void setPropagatedEvents(PropagatedEvents events) { _propagatedEvents = events; } |
||||
|
||||
/** @brief %Application holding this screen */ |
||||
BasicScreenedApplication<Application>* application() { |
||||
return Containers::LinkedListItem<BasicScreen<Application>, BasicScreenedApplication<Application>>::list(); |
||||
} |
||||
/** @overload */ |
||||
const BasicScreenedApplication<Application>* application() const { |
||||
return Containers::LinkedListItem<BasicScreen<Application>, BasicScreenedApplication<Application>>::list(); |
||||
} |
||||
|
||||
/**
|
||||
* @brief Next nearer screen |
||||
* |
||||
* @see @ref BasicScreenedApplication::frontScreen(), |
||||
* @ref BasicScreenedApplication::backScreen() |
||||
*/ |
||||
BasicScreen<Application>* nextNearerScreen() { |
||||
return Containers::LinkedListItem<BasicScreen<Application>, BasicScreenedApplication<Application>>::previous(); |
||||
} |
||||
/** @overload */ |
||||
const BasicScreen<Application>* nextNearerScreen() const { |
||||
return Containers::LinkedListItem<BasicScreen<Application>, BasicScreenedApplication<Application>>::previous(); |
||||
} |
||||
|
||||
/**
|
||||
* @brief Next farther screen |
||||
* |
||||
* @see @ref BasicScreenedApplication::frontScreen(), |
||||
* @ref BasicScreenedApplication::backScreen() |
||||
*/ |
||||
BasicScreen<Application>* nextFartherScreen() { |
||||
return Containers::LinkedListItem<BasicScreen<Application>, BasicScreenedApplication<Application>>::next(); |
||||
} |
||||
/** @overload */ |
||||
const BasicScreen<Application>* nextFartherScreen() const { |
||||
return Containers::LinkedListItem<BasicScreen<Application>, BasicScreenedApplication<Application>>::next(); |
||||
} |
||||
|
||||
protected: |
||||
/** @brief Request redraw */ |
||||
virtual void redraw() { application()->redraw(); } |
||||
|
||||
/**
|
||||
* @brief Focus event |
||||
* |
||||
* Called when screen is focused using @ref BasicScreenedApplication::focusScreen() |
||||
* or @ref BasicScreenedApplication::addScreen(). |
||||
*/ |
||||
virtual void focusEvent() = 0; |
||||
|
||||
/**
|
||||
* @brief Blur event |
||||
* |
||||
* Called when another screen is focused using @ref BasicScreenedApplication::focusScreen(), |
||||
* @ref BasicScreenedApplication::addScreen() or before the screen is |
||||
* removed from application using @ref BasicScreenedApplication::removeScreen(). |
||||
*/ |
||||
virtual void blurEvent() = 0; |
||||
|
||||
/**
|
||||
* @brief Viewport event |
||||
* |
||||
* Called from holder application when viewport size changes. See |
||||
* @ref Sdl2Application::viewportEvent() "*Application::viewportEvent()" |
||||
* for more information. Setting viewport on default framebuffer should |
||||
* be done by the holder application. |
||||
*/ |
||||
virtual void viewportEvent(const Vector2i& size) = 0; |
||||
|
||||
/**
|
||||
* @brief Draw event |
||||
* |
||||
* Called when @ref PropagatedEvent::Draw is enabled and the screen is |
||||
* redrawn. See @ref Sdl2Application::viewportEvent() "*Application::viewportEvent()" |
||||
* for more information. Buffer swapping and clearing of default |
||||
* framebufer should be done by the holder application. |
||||
*/ |
||||
virtual void drawEvent() = 0; |
||||
|
||||
/**
|
||||
* @brief Key press event |
||||
* |
||||
* Called when @ref PropagatedEvent::Input is enabled and an key is |
||||
* pressed. See @ref Sdl2Application::keyPressEvent() "*Application::keyPressEvent()" |
||||
* for more information. |
||||
*/ |
||||
virtual void keyPressEvent(KeyEvent& event); |
||||
|
||||
/**
|
||||
* @brief Key release event |
||||
* |
||||
* Called when @ref PropagatedEvent::Input is enabled and an key is |
||||
* released. See @ref Sdl2Application::keyReleaseEvent() "*Application::keyReleaseEvent()" |
||||
* for more information. |
||||
*/ |
||||
virtual void keyReleaseEvent(KeyEvent& event); |
||||
|
||||
/**
|
||||
* @brief Mouse press event |
||||
* |
||||
* Called when @ref PropagatedEvent::Input is enabled and mouse button |
||||
* is pressed. See @ref Sdl2Application::mousePressEvent() "*Application::mousePressEvent()" |
||||
* for more information. |
||||
*/ |
||||
virtual void mousePressEvent(MouseEvent& event); |
||||
|
||||
/**
|
||||
* @brief Mouse release event |
||||
* |
||||
* Called when @ref PropagatedEvent::Input is enabled and mouse button |
||||
* is released. See @ref Sdl2Application::mouseReleaseEvent() "*Application::mouseReleaseEvent()" |
||||
* for more information. |
||||
*/ |
||||
virtual void mouseReleaseEvent(MouseEvent& event); |
||||
|
||||
/**
|
||||
* @brief Mouse move event |
||||
* |
||||
* Called when @ref PropagatedEvent::Input is enabled and mouse is |
||||
* moved. See @ref Sdl2Application::mouseMoveEvent() "*Application::mouseMoveEvent()" |
||||
* for more information. |
||||
*/ |
||||
virtual void mouseMoveEvent(MouseMoveEvent& event); |
||||
|
||||
private: |
||||
PropagatedEvents _propagatedEvents; |
||||
}; |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,199 @@
|
||||
#ifndef Magnum_Platform_ScreenedApplication_h |
||||
#define Magnum_Platform_ScreenedApplication_h |
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
/** @file
|
||||
* @brief Class @ref Magnum::Platform::BasicScreenedApplication |
||||
*/ |
||||
|
||||
#include <Containers/LinkedList.h> |
||||
#include <Magnum.h> |
||||
|
||||
#include "Platform/Platform.h" |
||||
|
||||
namespace Magnum { namespace Platform { |
||||
|
||||
/**
|
||||
@brief Base for applications with screen management |
||||
|
||||
Manages list of screens and propagates events to them. |
||||
|
||||
If exactly one application header is included, this class is also aliased to |
||||
`Platform::ScreenedApplication`. |
||||
|
||||
Each @ref BasicScreen "Screen" specifies which set of events should be |
||||
propagated to it using @ref BasicScreen::setPropagatedEvents(). When |
||||
application gets an event, they are propagated to the screens: |
||||
|
||||
- @ref Sdl2Application::viewportEvent() "viewportEvent()" is propagated to |
||||
all screens. |
||||
- @ref Sdl2Application::drawEvent() "drawEvent()" is propagated in |
||||
back-to-front order to screens which have @ref BasicScreen::PropagatedEvent::Draw |
||||
enabled. |
||||
- Input events (@ref Sdl2Application::keyPressEvent() "keyPressEvent()", |
||||
@ref Sdl2Application::keyReleaseEvent() "keyReleaseEvent()", |
||||
@ref Sdl2Application::mousePressEvent() "mousePressEvent()", |
||||
@ref Sdl2Application::mouseReleaseEvent() "mouseReleaseEvent()" |
||||
and @ref Sdl2Application::mouseMoveEvent() "mouseMoveEvent()") |
||||
are propagated in front-to-back order to screens which have |
||||
@ref BasicScreen::PropagatedEvent::Input enabled. If any screen sets the |
||||
event as accepted, it is not propagated further. |
||||
|
||||
Traversing through the list of screens is done like following: |
||||
@code |
||||
// front-to-back
|
||||
for(Screen* s = app.frontScreen(); s; s = s->nextFartherScreen()) { |
||||
// ...
|
||||
} |
||||
|
||||
// back-to-front
|
||||
for(Screen* s = app.backScreen(); s; s = s->nextNearerScreen()) { |
||||
// ...
|
||||
} |
||||
@endcode |
||||
|
||||
@section ScreenedApplication-explicit-specializations Explicit template specializations |
||||
|
||||
The following specialization are explicitly compiled into each particular |
||||
`*Application` library. For other specializations you have to use |
||||
@ref ScreenedApplication.hpp implementation file to avoid linker errors. See |
||||
@ref compilation-speedup-hpp for more information. |
||||
|
||||
- @ref GlutApplication "BasicScreenedApplication<GlutApplication>" |
||||
- @ref GlxApplication "BasicScreenedApplication<GlxApplication>" |
||||
- @ref NaClApplication "BasicScreenedApplication<NaClApplication>" |
||||
- @ref Sdl2Application "BasicScreenedApplication<Sdl2Application>" |
||||
- @ref XEglApplication "BasicScreenedApplication<XEglApplication>" |
||||
*/ |
||||
template<class Application> class BasicScreenedApplication: public Application, private Containers::LinkedList<BasicScreen<Application>> { |
||||
friend class Containers::LinkedList<BasicScreen<Application>>; |
||||
friend class Containers::LinkedListItem<BasicScreen<Application>, BasicScreenedApplication<Application>>; |
||||
friend class BasicScreen<Application>; |
||||
|
||||
public: |
||||
/** @copydoc Sdl2Application::Sdl2Application(const Arguments, const Configuration&) */ |
||||
BasicScreenedApplication(const typename Application::Arguments& arguments, const typename Application::Configuration& configuration = Application::Configuration()): Application(arguments, configuration) {} |
||||
|
||||
/** @copydoc Sdl2Application::Sdl2Application(const Arguments&, std::nullptr_t) */ |
||||
BasicScreenedApplication(const typename Application::Arguments& arguments, std::nullptr_t): Application(arguments, nullptr) {} |
||||
|
||||
/**
|
||||
* @brief Add screen to application |
||||
* @return Reference to self (for method chaining) |
||||
* |
||||
* The new screen is added as backmost. If this is the first screen |
||||
* added, @ref BasicScreen::focusEvent() is called. If not, neither |
||||
* @ref BasicScreen::blurEvent() nor @ref BasicScreen::focusEvent() is |
||||
* called (i.e. the screen default state is used). |
||||
*/ |
||||
BasicScreenedApplication<Application>& addScreen(BasicScreen<Application>& screen); |
||||
|
||||
/**
|
||||
* @brief Remove screen from application |
||||
* @return Reference to self (for method chaining) |
||||
* |
||||
* The screen is blurred before removing. Deleting the object is left |
||||
* up to the user. |
||||
* @see @ref BasicScreen::blurEvent() |
||||
*/ |
||||
BasicScreenedApplication<Application>& removeScreen(BasicScreen<Application>& screen); |
||||
|
||||
/**
|
||||
* @brief Focus screen |
||||
* @return Reference to self (for method chaining) |
||||
* |
||||
* Moves the screen to front. Previously focused screen is blurred and |
||||
* this screen is focused. |
||||
* @see @ref BasicScreen::blurEvent(), @ref BasicScreen::focusEvent() |
||||
*/ |
||||
BasicScreenedApplication<Application>& focusScreen(BasicScreen<Application>& screen); |
||||
|
||||
/**
|
||||
* @brief Front screen |
||||
* |
||||
* @see @ref BasicScreen::nextFartherScreen(), @ref BasicScreen::nextNearerScreen() |
||||
*/ |
||||
BasicScreen<Application>* frontScreen() { |
||||
return Containers::LinkedList<BasicScreen<Application>>::first(); |
||||
} |
||||
/** @overload */ |
||||
const BasicScreen<Application>* frontScreen() const { |
||||
return Containers::LinkedList<BasicScreen<Application>>::first(); |
||||
} |
||||
|
||||
/**
|
||||
* @brief Back screen |
||||
* |
||||
* @see @ref BasicScreen::nextFartherScreen(), @ref BasicScreen::nextNearerScreen() |
||||
*/ |
||||
BasicScreen<Application>* backScreen() { |
||||
return Containers::LinkedList<BasicScreen<Application>>::last(); |
||||
} |
||||
/** @overload */ |
||||
const BasicScreen<Application>* backScreen() const { |
||||
return Containers::LinkedList<BasicScreen<Application>>::last(); |
||||
} |
||||
|
||||
protected: |
||||
/**
|
||||
* @brief Global viewport event |
||||
* |
||||
* Called when window size changes, *before* all screens' |
||||
* @ref BasicScreen::viewportEvent() "viewportEvent()". You should at |
||||
* least pass the new size to @ref DefaultFramebuffer::setViewport(). |
||||
* |
||||
* Note that this function might not get called at all if the window |
||||
* size doesn't change. You are responsible for configuring the initial |
||||
* state yourself, viewport of default framebuffer can be retrieved |
||||
* from @ref DefaultFramebuffer::viewport(). |
||||
*/ |
||||
virtual void globalViewportEvent(const Vector2i& size) = 0; |
||||
|
||||
/**
|
||||
* @brief Draw event |
||||
* |
||||
* Called *after* all screens' @ref BasicScreen::drawEvent() "drawEvent()". |
||||
* You should call at least @ref Sdl2Application::swapBuffers() "swapBuffers()". |
||||
* If you want to draw immediately again, call also |
||||
* @ref Sdl2Application::redraw() "redraw()". |
||||
*/ |
||||
virtual void globalDrawEvent() = 0; |
||||
|
||||
private: |
||||
/* The user is supposed to override only globalViewportEvent() and
|
||||
globalDrawEvent(), these implementations are dispatching the events |
||||
to attached screens. */ |
||||
void viewportEvent(const Vector2i& size) override final; |
||||
void drawEvent() override final; |
||||
void keyPressEvent(typename Application::KeyEvent& event) override final; |
||||
void keyReleaseEvent(typename Application::KeyEvent& event) override final; |
||||
void mousePressEvent(typename Application::MouseEvent& event) override final; |
||||
void mouseReleaseEvent(typename Application::MouseEvent& event) override final; |
||||
void mouseMoveEvent(typename Application::MouseMoveEvent& event) override final; |
||||
}; |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,133 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
/** @file
|
||||
* @brief @ref compilation-speedup-hpp "Template implementation" for @ref ScreenedApplication.h and @ref Screen.h |
||||
*/ |
||||
|
||||
#include "ScreenedApplication.h" |
||||
|
||||
#include "Platform/Screen.h" |
||||
|
||||
namespace Magnum { namespace Platform { |
||||
|
||||
template<class Application> BasicScreen<Application>::BasicScreen() = default; |
||||
template<class Application> BasicScreen<Application>::~BasicScreen() = default; |
||||
|
||||
template<class Application> void BasicScreen<Application>::keyPressEvent(KeyEvent&) {} |
||||
template<class Application> void BasicScreen<Application>::keyReleaseEvent(KeyEvent&) {} |
||||
template<class Application> void BasicScreen<Application>::mousePressEvent(MouseEvent&) {} |
||||
template<class Application> void BasicScreen<Application>::mouseReleaseEvent(MouseEvent&) {} |
||||
template<class Application> void BasicScreen<Application>::mouseMoveEvent(MouseMoveEvent&) {} |
||||
|
||||
template<class Application> BasicScreenedApplication<Application>& BasicScreenedApplication<Application>::addScreen(BasicScreen<Application>& screen) { |
||||
Containers::LinkedList<BasicScreen<Application>>::insert(&screen); |
||||
if(frontScreen() == &screen) screen.focusEvent(); |
||||
return *this; |
||||
} |
||||
|
||||
template<class Application> BasicScreenedApplication<Application>& BasicScreenedApplication<Application>::removeScreen(BasicScreen<Application>& screen) { |
||||
screen.blurEvent(); |
||||
Containers::LinkedList<BasicScreen<Application>>::erase(&screen); |
||||
return *this; |
||||
} |
||||
|
||||
template<class Application> BasicScreenedApplication<Application>& BasicScreenedApplication<Application>::focusScreen(BasicScreen<Application>& screen) { |
||||
/* Already focused, nothing to do */ |
||||
if(frontScreen() == &screen) return *this; |
||||
|
||||
frontScreen()->blurEvent(); |
||||
Containers::LinkedList<BasicScreen<Application>>::move(&screen, frontScreen()); |
||||
screen.focusEvent(); |
||||
return *this; |
||||
} |
||||
|
||||
template<class Application> void BasicScreenedApplication<Application>::viewportEvent(const Vector2i& size) { |
||||
/* Call viewport event after all other (because of framebuffer resizing) */ |
||||
globalViewportEvent(size); |
||||
|
||||
for(BasicScreen<Application>* s = Containers::LinkedList<BasicScreen<Application>>::first(); s; s = s->next()) |
||||
s->viewportEvent(size); |
||||
} |
||||
|
||||
template<class Application> void BasicScreenedApplication<Application>::drawEvent() { |
||||
/* Back-to-front rendering */ |
||||
for(BasicScreen<Application>* s = backScreen(); s; s = s->nextNearerScreen()) |
||||
if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Draw) s->drawEvent(); |
||||
|
||||
/* Call global event after all other (because of buffer swapping) */ |
||||
globalDrawEvent(); |
||||
} |
||||
|
||||
template<class Application> void BasicScreenedApplication<Application>::keyPressEvent(typename Application::KeyEvent& event) { |
||||
/* Front-to-back event propagation, stop when the event gets accepted */ |
||||
for(BasicScreen<Application>* s = frontScreen(); s; s = s->nextFartherScreen()) { |
||||
if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Input) { |
||||
s->keyPressEvent(event); |
||||
if(event.isAccepted()) break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
template<class Application> void BasicScreenedApplication<Application>::keyReleaseEvent(typename Application::KeyEvent& event) { |
||||
/* Front-to-back event propagation, stop when the event gets accepted */ |
||||
for(BasicScreen<Application>* s = frontScreen(); s; s = s->nextFartherScreen()) { |
||||
if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Input) { |
||||
s->keyReleaseEvent(event); |
||||
if(event.isAccepted()) break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
template<class Application> void BasicScreenedApplication<Application>::mousePressEvent(typename Application::MouseEvent& event) { |
||||
/* Front-to-back event propagation, stop when the event gets accepted */ |
||||
for(BasicScreen<Application>* s = frontScreen(); s; s = s->nextFartherScreen()) { |
||||
if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Input) { |
||||
s->mousePressEvent(event); |
||||
if(event.isAccepted()) break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
template<class Application> void BasicScreenedApplication<Application>::mouseReleaseEvent(typename Application::MouseEvent& event) { |
||||
/* Front-to-back event propagation, stop when the event gets accepted */ |
||||
for(BasicScreen<Application>* s = frontScreen(); s; s = s->nextFartherScreen()) { |
||||
if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Input) { |
||||
s->mouseReleaseEvent(event); |
||||
if(event.isAccepted()) break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
template<class Application> void BasicScreenedApplication<Application>::mouseMoveEvent(typename Application::MouseMoveEvent& event) { |
||||
/* Front-to-back event propagation, stop when the event gets accepted */ |
||||
for(BasicScreen<Application>* s = frontScreen(); s; s = s->nextFartherScreen()) { |
||||
if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Input) { |
||||
s->mouseMoveEvent(event); |
||||
if(event.isAccepted()) break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
}} |
||||
Loading…
Reference in new issue