Browse Source

Platform: make KeyEvent in the Screen also a mixin.

Because this one is not available in AndroidApplication and due to that
the ScreenedApplication couldn't be used there.
pull/364/head
Vladimír Vondruš 7 years ago
parent
commit
d1b7e4ded4
  1. 30
      src/Magnum/Platform/Screen.h
  2. 23
      src/Magnum/Platform/ScreenedApplication.h
  3. 48
      src/Magnum/Platform/ScreenedApplication.hpp

30
src/Magnum/Platform/Screen.h

@ -49,6 +49,18 @@ CORRADE_ENUMSET_OPERATORS(PropagatedScreenEvents)
are not implemented by all apps. The virtual *Event() function is defined
only if the base Application has it. Calling into those is done through
a corresponding Application*EventMixin defined in ScreenedApplication.h. */
template<class Application, bool> class ScreenKeyEventMixin {};
template<class Application> class ScreenKeyEventMixin<Application, true> {
public:
typedef typename BasicScreenedApplication<Application>::KeyEvent KeyEvent;
private:
friend ApplicationKeyEventMixin<Application, true>;
virtual void keyPressEvent(KeyEvent& event);
virtual void keyReleaseEvent(KeyEvent& event);
};
template<class Application, bool> class ScreenMouseScrollEventMixin {};
template<class Application> class ScreenMouseScrollEventMixin<Application, true> {
public:
@ -108,6 +120,7 @@ The following specialization are explicitly compiled into each particular
*/
template<class Application> class BasicScreen:
private Containers::LinkedListItem<BasicScreen<Application>, BasicScreenedApplication<Application>>,
public Implementation::ScreenKeyEventMixin<Application, Implementation::HasKeyEvent<Application>::value>,
public Implementation::ScreenMouseScrollEventMixin<Application, Implementation::HasMouseScrollEvent<Application>::value>,
public Implementation::ScreenTextInputEventMixin<Application, Implementation::HasTextInputEvent<Application>::value>,
public Implementation::ScreenTextEditingEventMixin<Application, Implementation::HasTextEditingEvent<Application>::value>
@ -156,8 +169,15 @@ template<class Application> class BasicScreen:
/** @brief Input event */
typedef typename BasicScreenedApplication<Application>::InputEvent InputEvent;
/** @brief Key event */
#ifdef DOXYGEN_GENERATING_OUTPUT
/**
* @brief Key event
*
* Defined only if the application has a
* @ref Sdl2Application::KeyEvent "KeyEvent".
*/
typedef typename BasicScreenedApplication<Application>::KeyEvent KeyEvent;
#endif
/** @brief Mouse event */
typedef typename BasicScreenedApplication<Application>::MouseEvent MouseEvent;
@ -305,12 +325,14 @@ template<class Application> class BasicScreen:
/** @{ @name Keyboard handling */
#ifdef DOXYGEN_GENERATING_OUTPUT
/**
* @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.
* for more information. Defined only if the application has a
* @ref Sdl2Application::KeyEvent "KeyEvent".
*/
virtual void keyPressEvent(KeyEvent& event);
@ -319,9 +341,11 @@ template<class Application> class BasicScreen:
*
* Called when @ref PropagatedEvent::Input is enabled and an key is
* released. See @ref Sdl2Application::keyReleaseEvent() "*Application::keyReleaseEvent()"
* for more information.
* for more information. Defined only if the application has a
* @ref Sdl2Application::KeyEvent "KeyEvent".
*/
virtual void keyReleaseEvent(KeyEvent& event);
#endif
/*@}*/

23
src/Magnum/Platform/ScreenedApplication.h

@ -39,10 +39,26 @@ namespace Magnum { namespace Platform {
namespace Implementation {
CORRADE_HAS_TYPE(HasKeyEvent, typename T::KeyEvent);
CORRADE_HAS_TYPE(HasMouseScrollEvent, typename T::MouseScrollEvent);
CORRADE_HAS_TYPE(HasTextInputEvent, typename T::TextInputEvent);
CORRADE_HAS_TYPE(HasTextEditingEvent, typename T::TextEditingEvent);
/* Calls into the screen in case the application has a key*Event(), otherwise
provides a dummy virtual so the application can unconditionally override */
template<class Application, bool> struct ApplicationKeyEventMixin {
typedef int KeyEvent;
virtual void keyPressEvent(KeyEvent&) = 0;
virtual void keyReleaseEvent(KeyEvent&) = 0;
void callKeyPressEvent(KeyEvent&, Containers::LinkedList<BasicScreen<Application>>&);
void callKeyReleaseEvent(KeyEvent&, Containers::LinkedList<BasicScreen<Application>>&);
};
template<class Application> struct ApplicationKeyEventMixin<Application, true> {
void callKeyPressEvent(typename Application::KeyEvent& event, Containers::LinkedList<BasicScreen<Application>>& screens);
void callKeyReleaseEvent(typename Application::KeyEvent& event, Containers::LinkedList<BasicScreen<Application>>& screens);
};
/* Calls into the screen in case the application has a mouseScrollEvent(),
otherwise provides a dummy virtual so the application can unconditionally
override */
@ -148,6 +164,7 @@ The following specialization are explicitly compiled into each particular
template<class Application> class BasicScreenedApplication:
public Application,
private Containers::LinkedList<BasicScreen<Application>>,
private Implementation::ApplicationKeyEventMixin<Application, Implementation::HasKeyEvent<Application>::value>,
private Implementation::ApplicationMouseScrollEventMixin<Application, Implementation::HasMouseScrollEvent<Application>::value>,
private Implementation::ApplicationTextInputEventMixin<Application, Implementation::HasTextInputEvent<Application>::value>,
private Implementation::ApplicationTextEditingEventMixin<Application, Implementation::HasTextEditingEvent<Application>::value>
@ -269,12 +286,14 @@ template<class Application> class BasicScreenedApplication:
to attached screens. */
void viewportEvent(typename Application::ViewportEvent& event) 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;
/* These events are not available in all cases, so if the Application
doesn't have them, they're overriding a mixin dummy */
void keyPressEvent(typename BasicScreenedApplication<Application>::KeyEvent& event) override final;
void keyReleaseEvent(typename BasicScreenedApplication<Application>::KeyEvent& event) override final;
void mouseScrollEvent(typename BasicScreenedApplication<Application>::MouseScrollEvent& event) override final;
void textInputEvent(typename BasicScreenedApplication<Application>::TextInputEvent& event) override final;
void textEditingEvent(typename BasicScreenedApplication<Application>::TextEditingEvent& event) override final;

48
src/Magnum/Platform/ScreenedApplication.hpp

@ -36,6 +36,28 @@ namespace Magnum { namespace Platform {
namespace Implementation {
template<class Application, bool implements> void ApplicationKeyEventMixin<Application, implements>::callKeyPressEvent(KeyEvent&, Containers::LinkedList<BasicScreen<Application>>&) {}
template<class Application> void ApplicationKeyEventMixin<Application, true>::callKeyPressEvent(typename Application::KeyEvent& event, Containers::LinkedList<BasicScreen<Application>>& screens) {
/* Front-to-back event propagation, stop when the event gets accepted */
for(BasicScreen<Application>* s = screens.first(); s; s = s->nextFartherScreen()) {
if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Input) {
s->keyPressEvent(event);
if(event.isAccepted()) break;
}
}
}
template<class Application, bool implements> void ApplicationKeyEventMixin<Application, implements>::callKeyReleaseEvent(KeyEvent&, Containers::LinkedList<BasicScreen<Application>>&) {}
template<class Application> void ApplicationKeyEventMixin<Application, true>::callKeyReleaseEvent(typename Application::KeyEvent& event, Containers::LinkedList<BasicScreen<Application>>& screens) {
/* Front-to-back event propagation, stop when the event gets accepted */
for(BasicScreen<Application>* s = screens.first(); s; s = s->nextFartherScreen()) {
if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Input) {
s->keyReleaseEvent(event);
if(event.isAccepted()) break;
}
}
}
template<class Application, bool implements> void ApplicationMouseScrollEventMixin<Application, implements>::callMouseScrollEvent(MouseScrollEvent&, Containers::LinkedList<BasicScreen<Application>>&) {}
template<class Application> void ApplicationMouseScrollEventMixin<Application, true>::callMouseScrollEvent(typename Application::MouseScrollEvent& event, Containers::LinkedList<BasicScreen<Application>>& screens) {
/* Front-to-back event propagation, stop when the event gets accepted */
@ -70,6 +92,10 @@ true>::callTextEditingEvent(typename Application::TextEditingEvent& event, Conta
}
}
template<class Application> void ScreenKeyEventMixin<Application,
true>::keyPressEvent(KeyEvent&) {}
template<class Application> void ScreenKeyEventMixin<Application,
true>::keyReleaseEvent(KeyEvent&) {}
template<class Application> void ScreenMouseScrollEventMixin<Application,
true>::mouseScrollEvent(MouseScrollEvent&) {}
template<class Application> void ScreenTextInputEventMixin<Application,
@ -96,8 +122,6 @@ template<class Application> void BasicScreen<Application>::viewportEvent(Viewpor
template<class Application> void BasicScreen<Application>::viewportEvent(const Vector2i&) {}
#endif
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&) {}
@ -155,24 +179,12 @@ template<class Application> void BasicScreenedApplication<Application>::drawEven
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 = screens().first(); s; s = s->nextFartherScreen()) {
if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Input) {
s->keyPressEvent(event);
if(event.isAccepted()) break;
}
}
template<class Application> void BasicScreenedApplication<Application>::keyPressEvent(typename BasicScreenedApplication<Application>::KeyEvent& event) {
this->callKeyPressEvent(event, screens());
}
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 = screens().first(); s; s = s->nextFartherScreen()) {
if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Input) {
s->keyReleaseEvent(event);
if(event.isAccepted()) break;
}
}
template<class Application> void BasicScreenedApplication<Application>::keyReleaseEvent(typename BasicScreenedApplication<Application>::KeyEvent& event) {
this->callKeyReleaseEvent(event, screens());
}
template<class Application> void BasicScreenedApplication<Application>::mousePressEvent(typename Application::MouseEvent& event) {

Loading…
Cancel
Save