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