From d1b7e4ded4ff63f8c9ebbaa0600795d744b726ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 1 Aug 2019 21:25:48 +0200 Subject: [PATCH] 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. --- src/Magnum/Platform/Screen.h | 30 +++++++++++-- src/Magnum/Platform/ScreenedApplication.h | 23 +++++++++- src/Magnum/Platform/ScreenedApplication.hpp | 48 +++++++++++++-------- 3 files changed, 78 insertions(+), 23 deletions(-) diff --git a/src/Magnum/Platform/Screen.h b/src/Magnum/Platform/Screen.h index d5b90ce39..6c78a45ab 100644 --- a/src/Magnum/Platform/Screen.h +++ b/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 ScreenKeyEventMixin {}; +template class ScreenKeyEventMixin { + public: + typedef typename BasicScreenedApplication::KeyEvent KeyEvent; + + private: + friend ApplicationKeyEventMixin; + + virtual void keyPressEvent(KeyEvent& event); + virtual void keyReleaseEvent(KeyEvent& event); +}; + template class ScreenMouseScrollEventMixin {}; template class ScreenMouseScrollEventMixin { public: @@ -108,6 +120,7 @@ The following specialization are explicitly compiled into each particular */ template class BasicScreen: private Containers::LinkedListItem, BasicScreenedApplication>, + public Implementation::ScreenKeyEventMixin::value>, public Implementation::ScreenMouseScrollEventMixin::value>, public Implementation::ScreenTextInputEventMixin::value>, public Implementation::ScreenTextEditingEventMixin::value> @@ -156,8 +169,15 @@ template class BasicScreen: /** @brief Input event */ typedef typename BasicScreenedApplication::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::KeyEvent KeyEvent; + #endif /** @brief Mouse event */ typedef typename BasicScreenedApplication::MouseEvent MouseEvent; @@ -305,12 +325,14 @@ template 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 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 /*@}*/ diff --git a/src/Magnum/Platform/ScreenedApplication.h b/src/Magnum/Platform/ScreenedApplication.h index 122001204..32e6c6e98 100644 --- a/src/Magnum/Platform/ScreenedApplication.h +++ b/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 struct ApplicationKeyEventMixin { + typedef int KeyEvent; + virtual void keyPressEvent(KeyEvent&) = 0; + virtual void keyReleaseEvent(KeyEvent&) = 0; + + void callKeyPressEvent(KeyEvent&, Containers::LinkedList>&); + void callKeyReleaseEvent(KeyEvent&, Containers::LinkedList>&); +}; +template struct ApplicationKeyEventMixin { + void callKeyPressEvent(typename Application::KeyEvent& event, Containers::LinkedList>& screens); + void callKeyReleaseEvent(typename Application::KeyEvent& event, Containers::LinkedList>& 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 BasicScreenedApplication: public Application, private Containers::LinkedList>, + private Implementation::ApplicationKeyEventMixin::value>, private Implementation::ApplicationMouseScrollEventMixin::value>, private Implementation::ApplicationTextInputEventMixin::value>, private Implementation::ApplicationTextEditingEventMixin::value> @@ -269,12 +286,14 @@ template 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::KeyEvent& event) override final; + void keyReleaseEvent(typename BasicScreenedApplication::KeyEvent& event) override final; void mouseScrollEvent(typename BasicScreenedApplication::MouseScrollEvent& event) override final; void textInputEvent(typename BasicScreenedApplication::TextInputEvent& event) override final; void textEditingEvent(typename BasicScreenedApplication::TextEditingEvent& event) override final; diff --git a/src/Magnum/Platform/ScreenedApplication.hpp b/src/Magnum/Platform/ScreenedApplication.hpp index 06ff14144..079b4f3ad 100644 --- a/src/Magnum/Platform/ScreenedApplication.hpp +++ b/src/Magnum/Platform/ScreenedApplication.hpp @@ -36,6 +36,28 @@ namespace Magnum { namespace Platform { namespace Implementation { +template void ApplicationKeyEventMixin::callKeyPressEvent(KeyEvent&, Containers::LinkedList>&) {} +template void ApplicationKeyEventMixin::callKeyPressEvent(typename Application::KeyEvent& event, Containers::LinkedList>& screens) { + /* Front-to-back event propagation, stop when the event gets accepted */ + for(BasicScreen* s = screens.first(); s; s = s->nextFartherScreen()) { + if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Input) { + s->keyPressEvent(event); + if(event.isAccepted()) break; + } + } +} + +template void ApplicationKeyEventMixin::callKeyReleaseEvent(KeyEvent&, Containers::LinkedList>&) {} +template void ApplicationKeyEventMixin::callKeyReleaseEvent(typename Application::KeyEvent& event, Containers::LinkedList>& screens) { + /* Front-to-back event propagation, stop when the event gets accepted */ + for(BasicScreen* s = screens.first(); s; s = s->nextFartherScreen()) { + if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Input) { + s->keyReleaseEvent(event); + if(event.isAccepted()) break; + } + } +} + template void ApplicationMouseScrollEventMixin::callMouseScrollEvent(MouseScrollEvent&, Containers::LinkedList>&) {} template void ApplicationMouseScrollEventMixin::callMouseScrollEvent(typename Application::MouseScrollEvent& event, Containers::LinkedList>& screens) { /* Front-to-back event propagation, stop when the event gets accepted */ @@ -70,6 +92,10 @@ true>::callTextEditingEvent(typename Application::TextEditingEvent& event, Conta } } +template void ScreenKeyEventMixin::keyPressEvent(KeyEvent&) {} +template void ScreenKeyEventMixin::keyReleaseEvent(KeyEvent&) {} template void ScreenMouseScrollEventMixin::mouseScrollEvent(MouseScrollEvent&) {} template void ScreenTextInputEventMixin void BasicScreen::viewportEvent(Viewpor template void BasicScreen::viewportEvent(const Vector2i&) {} #endif -template void BasicScreen::keyPressEvent(KeyEvent&) {} -template void BasicScreen::keyReleaseEvent(KeyEvent&) {} template void BasicScreen::mousePressEvent(MouseEvent&) {} template void BasicScreen::mouseReleaseEvent(MouseEvent&) {} template void BasicScreen::mouseMoveEvent(MouseMoveEvent&) {} @@ -155,24 +179,12 @@ template void BasicScreenedApplication::drawEven globalDrawEvent(); } -template void BasicScreenedApplication::keyPressEvent(typename Application::KeyEvent& event) { - /* Front-to-back event propagation, stop when the event gets accepted */ - for(BasicScreen* s = screens().first(); s; s = s->nextFartherScreen()) { - if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Input) { - s->keyPressEvent(event); - if(event.isAccepted()) break; - } - } +template void BasicScreenedApplication::keyPressEvent(typename BasicScreenedApplication::KeyEvent& event) { + this->callKeyPressEvent(event, screens()); } -template void BasicScreenedApplication::keyReleaseEvent(typename Application::KeyEvent& event) { - /* Front-to-back event propagation, stop when the event gets accepted */ - for(BasicScreen* s = screens().first(); s; s = s->nextFartherScreen()) { - if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Input) { - s->keyReleaseEvent(event); - if(event.isAccepted()) break; - } - } +template void BasicScreenedApplication::keyReleaseEvent(typename BasicScreenedApplication::KeyEvent& event) { + this->callKeyReleaseEvent(event, screens()); } template void BasicScreenedApplication::mousePressEvent(typename Application::MouseEvent& event) {