Browse Source

Platform: added ScreenedApplication class.

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
Vladimír Vondruš 13 years ago
parent
commit
aa5b888bb2
  1. 9
      src/Platform/CMakeLists.txt
  2. 5
      src/Platform/GlutApplication.cpp
  3. 3
      src/Platform/GlutApplication.h
  4. 4
      src/Platform/GlxApplication.cpp
  5. 3
      src/Platform/GlxApplication.h
  6. 4
      src/Platform/NaClApplication.cpp
  7. 3
      src/Platform/NaClApplication.h
  8. 38
      src/Platform/Platform.h
  9. 265
      src/Platform/Screen.h
  10. 199
      src/Platform/ScreenedApplication.h
  11. 133
      src/Platform/ScreenedApplication.hpp
  12. 4
      src/Platform/Sdl2Application.cpp
  13. 3
      src/Platform/Sdl2Application.h
  14. 4
      src/Platform/XEglApplication.cpp
  15. 3
      src/Platform/XEglApplication.h

9
src/Platform/CMakeLists.txt

@ -22,6 +22,15 @@
# DEALINGS IN THE SOFTWARE.
#
# Headers
set(Platform_HEADERS
Platform.h
Screen.h
ScreenedApplication.h
ScreenedApplication.hpp)
install(FILES ${Platform_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Platform)
# GLUT application
if(WITH_GLUTAPPLICATION)
find_package(GLUT)

5
src/Platform/GlutApplication.cpp

@ -26,6 +26,8 @@
#include "Context.h"
#include "Platform/ScreenedApplication.hpp"
namespace Magnum { namespace Platform {
GlutApplication* GlutApplication::instance = nullptr;
@ -117,4 +119,7 @@ void GlutApplication::mouseMoveEvent(MouseMoveEvent&) {}
GlutApplication::Configuration::Configuration(): _title("Magnum GLUT Application"), _size(800, 600), _sampleCount(0) {}
GlutApplication::Configuration::~Configuration() = default;
template class BasicScreen<GlutApplication>;
template class BasicScreenedApplication<GlutApplication>;
}}

3
src/Platform/GlutApplication.h

@ -30,6 +30,7 @@
#include <string>
#include "Platform/Platform.h"
#include "Math/Vector2.h"
#include "Magnum.h"
@ -543,6 +544,8 @@ When no other application header is included this macro is also aliased to
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_APPLICATION_MAIN
typedef GlutApplication Application;
typedef BasicScreen<GlutApplication> Screen;
typedef BasicScreenedApplication<GlutApplication> ScreenedApplication;
#define MAGNUM_APPLICATION_MAIN(className) MAGNUM_GLUTAPPLICATION_MAIN(className)
#else
#undef MAGNUM_APPLICATION_MAIN

4
src/Platform/GlxApplication.cpp

@ -24,6 +24,7 @@
#include "GlxApplication.h"
#include "Platform/ScreenedApplication.hpp"
#include "Platform/Implementation/GlxContextHandler.h"
namespace Magnum { namespace Platform {
@ -32,4 +33,7 @@ GlxApplication::GlxApplication(const Arguments& arguments, const Configuration&
GlxApplication::GlxApplication(const Arguments& arguments, std::nullptr_t): AbstractXApplication(new Implementation::GlxContextHandler, arguments, nullptr) {}
template class BasicScreen<GlxApplication>;
template class BasicScreenedApplication<GlxApplication>;
}}

3
src/Platform/GlxApplication.h

@ -29,6 +29,7 @@
*/
#include "Platform/AbstractXApplication.h"
#include "Platform/Platform.h"
namespace Magnum { namespace Platform {
@ -102,6 +103,8 @@ When no other application header is included this macro is also aliased to
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_APPLICATION_MAIN
typedef GlxApplication Application;
typedef BasicScreen<GlxApplication> Screen;
typedef BasicScreenedApplication<GlxApplication> ScreenedApplication;
#define MAGNUM_APPLICATION_MAIN(className) MAGNUM_GLXAPPLICATION_MAIN(className)
#else
#undef MAGNUM_APPLICATION_MAIN

4
src/Platform/NaClApplication.cpp

@ -30,6 +30,7 @@
#include <Utility/NaClStreamBuffer.h>
#include "Context.h"
#include "Platform/ScreenedApplication.hpp"
namespace Magnum { namespace Platform {
@ -254,4 +255,7 @@ void NaClApplication::mousePressEvent(MouseEvent&) {}
void NaClApplication::mouseReleaseEvent(MouseEvent&) {}
void NaClApplication::mouseMoveEvent(MouseMoveEvent&) {}
template class BasicScreen<NaClApplication>;
template class BasicScreenedApplication<NaClApplication>;
}}

3
src/Platform/NaClApplication.h

@ -37,6 +37,7 @@
#include <ppapi/cpp/graphics_3d_client.h>
#include <ppapi/gles2/gl2ext_ppapi.h>
#include "Platform/Platform.h"
#include "Math/Vector2.h"
#include "Magnum.h"
@ -657,6 +658,8 @@ When no other application header is included this macro is also aliased to
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_APPLICATION_MAIN
typedef NaClApplication Application;
typedef BasicScreen<NaClApplication> Screen;
typedef BasicScreenedApplication<NaClApplication> ScreenedApplication;
#define MAGNUM_APPLICATION_MAIN(className) MAGNUM_NACLAPPLICATION_MAIN(className)
#else
#undef MAGNUM_APPLICATION_MAIN

38
src/Platform/Platform.h

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

265
src/Platform/Screen.h

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

199
src/Platform/ScreenedApplication.h

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

133
src/Platform/ScreenedApplication.hpp

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

4
src/Platform/Sdl2Application.cpp

@ -29,6 +29,7 @@
#endif
#include "Context.h"
#include "Platform/ScreenedApplication.hpp"
namespace Magnum { namespace Platform {
@ -262,4 +263,7 @@ Sdl2Application::InputEvent::Modifiers Sdl2Application::MouseMoveEvent::modifier
return _modifiers = fixedModifiers(SDL_GetModState());
}
template class BasicScreen<Sdl2Application>;
template class BasicScreenedApplication<Sdl2Application>;
}}

3
src/Platform/Sdl2Application.h

@ -30,6 +30,7 @@
#include <Containers/EnumSet.h>
#include "Platform/Platform.h"
#include "Math/Vector2.h"
#include "Magnum.h"
@ -644,6 +645,8 @@ When no other application header is included this macro is also aliased to
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_APPLICATION_MAIN
typedef Sdl2Application Application;
typedef BasicScreen<Sdl2Application> Screen;
typedef BasicScreenedApplication<Sdl2Application> ScreenedApplication;
#define MAGNUM_APPLICATION_MAIN(className) MAGNUM_SDL2APPLICATION_MAIN(className)
#else
#undef MAGNUM_APPLICATION_MAIN

4
src/Platform/XEglApplication.cpp

@ -24,6 +24,7 @@
#include "XEglApplication.h"
#include "Platform/ScreenedApplication.hpp"
#include "Platform/Implementation/EglContextHandler.h"
namespace Magnum { namespace Platform {
@ -32,4 +33,7 @@ XEglApplication::XEglApplication(const Arguments& arguments, const Configuration
XEglApplication::XEglApplication(const Arguments& arguments, std::nullptr_t): AbstractXApplication(new Implementation::EglContextHandler, arguments, nullptr) {}
template class BasicScreen<XEglApplication>;
template class BasicScreenedApplication<XEglApplication>;
}}

3
src/Platform/XEglApplication.h

@ -28,6 +28,7 @@
* @brief Class @ref Magnum::Platform::XEglApplication
*/
#include "Platform/Platform.h"
#include "Platform/AbstractXApplication.h"
namespace Magnum { namespace Platform {
@ -103,6 +104,8 @@ When no other application header is included this macro is also aliased to
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_APPLICATION_MAIN
typedef XEglApplication Application;
typedef BasicScreen<XEglApplication> Screen;
typedef BasicScreenedApplication<XEglApplication> ScreenedApplication;
#define MAGNUM_APPLICATION_MAIN(className) MAGNUM_XEGLAPPLICATION_MAIN(className)
#else
#undef MAGNUM_APPLICATION_MAIN

Loading…
Cancel
Save