Browse Source

Platform: implement Sdl2Application::anyEvent(), expose SDL_Event.

pull/308/head
Vladimír Vondruš 7 years ago
parent
commit
20a55b16aa
  1. 3
      doc/changelog.dox
  2. 30
      src/Magnum/Platform/Sdl2Application.cpp
  3. 114
      src/Magnum/Platform/Sdl2Application.h
  4. 8
      src/Magnum/Platform/Test/Sdl2ApplicationTest.cpp

3
doc/changelog.dox

@ -91,6 +91,9 @@ See also:
@ref Platform::GlfwApplication::exitEvent() events for responding to
application window close and possibility to cancel it (for example to
show an exit confirmation dialog)
- New @ref Platform::Sdl2Application::anyEvent() event together with
@ref Platform::Sdl2Application::InputEvent::event() "event()" accessors to
make it possible to access raw `SDL_Event` data
@subsection changelog-latest-changes Changes and improvements

30
src/Magnum/Platform/Sdl2Application.cpp

@ -665,7 +665,7 @@ void Sdl2Application::mainLoopIteration() {
https://github.com/kripken/emscripten/issues/1731 */
CORRADE_ASSERT_UNREACHABLE();
#else
ViewportEvent e{{event.window.data1, event.window.data2}, framebufferSize(), _dpiScaling};
ViewportEvent e{event, {event.window.data1, event.window.data2}, framebufferSize(), _dpiScaling};
/** @todo handle also WM_DPICHANGED events when a window is moved between displays with different DPI */
viewportEvent(e);
_flags |= Flag::Redraw;
@ -678,49 +678,49 @@ void Sdl2Application::mainLoopIteration() {
case SDL_KEYDOWN:
case SDL_KEYUP: {
KeyEvent e(static_cast<KeyEvent::Key>(event.key.keysym.sym), fixedModifiers(event.key.keysym.mod), event.key.repeat != 0);
KeyEvent e{event, static_cast<KeyEvent::Key>(event.key.keysym.sym), fixedModifiers(event.key.keysym.mod), event.key.repeat != 0};
event.type == SDL_KEYDOWN ? keyPressEvent(e) : keyReleaseEvent(e);
} break;
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP: {
MouseEvent e(static_cast<MouseEvent::Button>(event.button.button), {event.button.x, event.button.y}
MouseEvent e{event, static_cast<MouseEvent::Button>(event.button.button), {event.button.x, event.button.y}
#ifndef CORRADE_TARGET_EMSCRIPTEN
, event.button.clicks
#endif
);
};
event.type == SDL_MOUSEBUTTONDOWN ? mousePressEvent(e) : mouseReleaseEvent(e);
} break;
case SDL_MOUSEWHEEL: {
MouseScrollEvent e{{Float(event.wheel.x), Float(event.wheel.y)}};
MouseScrollEvent e{event, {Float(event.wheel.x), Float(event.wheel.y)}};
mouseScrollEvent(e);
} break;
case SDL_MOUSEMOTION: {
MouseMoveEvent e({event.motion.x, event.motion.y}, {event.motion.xrel, event.motion.yrel}, static_cast<MouseMoveEvent::Button>(event.motion.state));
MouseMoveEvent e{event, {event.motion.x, event.motion.y}, {event.motion.xrel, event.motion.yrel}, static_cast<MouseMoveEvent::Button>(event.motion.state)};
mouseMoveEvent(e);
break;
}
case SDL_MULTIGESTURE: {
MultiGestureEvent e({event.mgesture.x, event.mgesture.y}, event.mgesture.dTheta, event.mgesture.dDist, event.mgesture.numFingers);
MultiGestureEvent e{event, {event.mgesture.x, event.mgesture.y}, event.mgesture.dTheta, event.mgesture.dDist, event.mgesture.numFingers};
multiGestureEvent(e);
break;
}
case SDL_TEXTINPUT: {
TextInputEvent e{{event.text.text, std::strlen(event.text.text)}};
TextInputEvent e{event, {event.text.text, std::strlen(event.text.text)}};
textInputEvent(e);
} break;
case SDL_TEXTEDITING: {
TextEditingEvent e{{event.edit.text, std::strlen(event.text.text)}, event.edit.start, event.edit.length};
TextEditingEvent e{event, {event.edit.text, std::strlen(event.text.text)}, event.edit.start, event.edit.length};
textEditingEvent(e);
} break;
case SDL_QUIT: {
ExitEvent e;
ExitEvent e{event};
exitEvent(e);
if(e.isAccepted()) {
#ifndef CORRADE_TARGET_EMSCRIPTEN
@ -731,6 +731,10 @@ void Sdl2Application::mainLoopIteration() {
return;
}
} break;
/* Direct everything else to anyEvent(), so users can implement
event handling for things not present in the Application APIs */
default: if(!(_flags & Flag::NoAnyEvent)) anyEvent(event);
}
}
@ -816,6 +820,12 @@ void Sdl2Application::tickEvent() {
_flags |= Flag::NoTickEvent;
}
void Sdl2Application::anyEvent(SDL_Event&) {
/* If this got called, the any event is not implemented by user and thus
we don't need to call it ever again */
_flags |= Flag::NoAnyEvent;
}
void Sdl2Application::viewportEvent(ViewportEvent& event) {
#ifdef MAGNUM_BUILD_DEPRECATED
CORRADE_IGNORE_DEPRECATED_PUSH

114
src/Magnum/Platform/Sdl2Application.h

@ -57,6 +57,10 @@
#include <wrl.h> /* For the WinMain entrypoint */
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT
union SDL_Event; /* for anyEvent() */
#endif
namespace Magnum { namespace Platform {
namespace Implementation {
@ -949,6 +953,17 @@ class Sdl2Application {
*/
virtual void tickEvent();
/**
* @brief Any event
*
* Called in case a SDL event is not handled by any other event
* functions above.
* @see @ref ViewportEvent::event(), @ref InputEvent::event(),
* @ref MultiGestureEvent::event(), @ref TextInputEvent::event(),
* @ref TextEditingEvent::event(), @ref ExitEvent::event()
*/
virtual void anyEvent(SDL_Event& event);
/*@}*/
private:
@ -956,12 +971,13 @@ class Sdl2Application {
Redraw = 1 << 0,
VSyncEnabled = 1 << 1,
NoTickEvent = 1 << 2,
NoAnyEvent = 1 << 3,
#ifndef CORRADE_TARGET_EMSCRIPTEN
Exit = 1 << 3
Exit = 1 << 4
#endif
#ifdef CORRADE_TARGET_EMSCRIPTEN
TextInputActive = 1 << 4,
Resizable = 1 << 5
TextInputActive = 1 << 5,
Resizable = 1 << 6
#endif
};
@ -1667,11 +1683,20 @@ class Sdl2Application::ExitEvent {
*/
void setAccepted(bool accepted = true) { _accepted = accepted; }
/**
* @brief Underlying SDL event
*
* Of type `SDL_QUIT`.
* @see @ref Sdl2Application::anyEvent()
*/
const SDL_Event& event() const { return _event; }
private:
friend Sdl2Application;
explicit ExitEvent(): _accepted(false) {}
explicit ExitEvent(const SDL_Event& event): _event(event), _accepted(false) {}
const SDL_Event& _event;
bool _accepted;
};
@ -1725,11 +1750,33 @@ class Sdl2Application::ViewportEvent {
*/
Vector2 dpiScaling() const { return _dpiScaling; }
#ifndef CORRADE_TARGET_EMSCRIPTEN
/**
* @brief Underlying SDL event
*
* Of type `SDL_WINDOWEVENT`.
* @note Not available in @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten".
* @see @ref Sdl2Application::anyEvent()
*/
const SDL_Event& event() const { return _event; }
#endif
private:
friend Sdl2Application;
explicit ViewportEvent(const Vector2i& windowSize, const Vector2i& framebufferSize, const Vector2& dpiScaling): _windowSize{windowSize}, _framebufferSize{framebufferSize}, _dpiScaling{dpiScaling} {}
explicit ViewportEvent(
#ifndef CORRADE_TARGET_EMSCRIPTEN
const SDL_Event& event,
#endif
const Vector2i& windowSize, const Vector2i& framebufferSize, const Vector2& dpiScaling):
#ifndef CORRADE_TARGET_EMSCRIPTEN
_event(event),
#endif
_windowSize{windowSize}, _framebufferSize{framebufferSize}, _dpiScaling{dpiScaling} {}
#ifndef CORRADE_TARGET_EMSCRIPTEN
const SDL_Event& _event;
#endif
const Vector2i _windowSize;
const Vector2i _framebufferSize;
const Vector2 _dpiScaling;
@ -1823,14 +1870,26 @@ class Sdl2Application::InputEvent {
*/
void setAccepted(bool accepted = true) { _accepted = accepted; }
/**
* @brief Underlying SDL event
*
* Of type `SDL_KEYDOWN` / `SDL_KEYUP` for @ref KeyEvent,
* `SDL_MOUSEBUTTONUP` / `SDL_MOUSEBUTTONDOWN` for @ref MouseEvent,
* `SDL_MOUSEWHEEL` for @ref MouseScrollEvent and `SDL_MOUSEMOTION` for
* @ref MouseMoveEvent.
* @see @ref Sdl2Application::anyEvent()
*/
const SDL_Event& event() const { return _event; }
#ifndef DOXYGEN_GENERATING_OUTPUT
protected:
explicit InputEvent(): _accepted(false) {}
explicit InputEvent(const SDL_Event& event): _event(event), _accepted(false) {}
~InputEvent() = default;
#endif
private:
const SDL_Event& _event;
bool _accepted;
};
@ -2050,7 +2109,7 @@ class Sdl2Application::KeyEvent: public Sdl2Application::InputEvent {
bool isRepeated() const { return _repeated; }
private:
explicit KeyEvent(Key key, Modifiers modifiers, bool repeated): _key{key}, _modifiers{modifiers}, _repeated{repeated} {}
explicit KeyEvent(const SDL_Event& event, Key key, Modifiers modifiers, bool repeated): InputEvent{event}, _key{key}, _modifiers{modifiers}, _repeated{repeated} {}
const Key _key;
const Modifiers _modifiers;
@ -2107,11 +2166,11 @@ class Sdl2Application::MouseEvent: public Sdl2Application::InputEvent {
Modifiers modifiers();
private:
explicit MouseEvent(Button button, const Vector2i& position
explicit MouseEvent(const SDL_Event& event, Button button, const Vector2i& position
#ifndef CORRADE_TARGET_EMSCRIPTEN
, Int clickCount
#endif
): _button{button}, _position{position},
): InputEvent{event}, _button{button}, _position{position},
#ifndef CORRADE_TARGET_EMSCRIPTEN
_clickCount{clickCount},
#endif
@ -2180,7 +2239,7 @@ class Sdl2Application::MouseMoveEvent: public Sdl2Application::InputEvent {
Modifiers modifiers();
private:
explicit MouseMoveEvent(const Vector2i& position, const Vector2i& relativePosition, Buttons buttons): _position{position}, _relativePosition{relativePosition}, _buttons{buttons}, _modifiersLoaded{false} {}
explicit MouseMoveEvent(const SDL_Event& event, const Vector2i& position, const Vector2i& relativePosition, Buttons buttons): InputEvent{event}, _position{position}, _relativePosition{relativePosition}, _buttons{buttons}, _modifiersLoaded{false} {}
const Vector2i _position, _relativePosition;
const Buttons _buttons;
@ -2215,7 +2274,7 @@ class Sdl2Application::MouseScrollEvent: public Sdl2Application::InputEvent {
Modifiers modifiers();
private:
explicit MouseScrollEvent(const Vector2& offset): _offset{offset}, _positionLoaded{false}, _modifiersLoaded{false} {}
explicit MouseScrollEvent(const SDL_Event& event, const Vector2& offset): InputEvent{event}, _offset{offset}, _positionLoaded{false}, _modifiersLoaded{false} {}
const Vector2 _offset;
bool _positionLoaded;
@ -2283,9 +2342,18 @@ class Sdl2Application::MultiGestureEvent {
*/
Int fingerCount() const { return _fingerCount; }
/**
* @brief Underlying SDL event
*
* Of type `SDL_MULTIGESTURE`.
* @see @ref Sdl2Application::anyEvent()
*/
const SDL_Event& event() const { return _event; }
private:
explicit MultiGestureEvent(const Vector2& center, Float relativeRotation, Float relativeDistance, Int fingerCount): _center{center}, _relativeRotation{relativeRotation}, _relativeDistance{relativeDistance}, _fingerCount{fingerCount}, _accepted{false} {}
explicit MultiGestureEvent(const SDL_Event& event, const Vector2& center, Float relativeRotation, Float relativeDistance, Int fingerCount): _event(event), _center{center}, _relativeRotation{relativeRotation}, _relativeDistance{relativeDistance}, _fingerCount{fingerCount}, _accepted{false} {}
const SDL_Event& _event;
const Vector2 _center;
const Float _relativeRotation;
const Float _relativeDistance;
@ -2330,9 +2398,18 @@ class Sdl2Application::TextInputEvent {
/** @brief Input text in UTF-8 */
Containers::ArrayView<const char> text() const { return _text; }
/**
* @brief Underlying SDL event
*
* Of type `SDL_TEXTINPUT`.
* @see @ref Sdl2Application::anyEvent()
*/
const SDL_Event& event() const { return _event; }
private:
explicit TextInputEvent(Containers::ArrayView<const char> text): _text{text}, _accepted{false} {}
explicit TextInputEvent(const SDL_Event& event, Containers::ArrayView<const char> text): _event(event), _text{text}, _accepted{false} {}
const SDL_Event& _event;
const Containers::ArrayView<const char> _text;
bool _accepted;
};
@ -2380,9 +2457,18 @@ class Sdl2Application::TextEditingEvent {
/** @brief Number of characters to edit from the start point */
Int length() const { return _length; }
/**
* @brief Underlying SDL event
*
* Of type `SDL_TEXTEDITING`.
* @see @ref Sdl2Application::anyEvent()
*/
const SDL_Event& event() const { return _event; }
private:
explicit TextEditingEvent(Containers::ArrayView<const char> text, Int start, Int length): _text{text}, _start{start}, _length{length}, _accepted{false} {}
explicit TextEditingEvent(const SDL_Event& event, Containers::ArrayView<const char> text, Int start, Int length): _event(event), _text{text}, _start{start}, _length{length}, _accepted{false} {}
const SDL_Event& _event;
const Containers::ArrayView<const char> _text;
const Int _start;
const Int _length;

8
src/Magnum/Platform/Test/Sdl2ApplicationTest.cpp

@ -25,6 +25,8 @@
#include "Magnum/Platform/Sdl2Application.h"
#include <SDL_events.h>
namespace Magnum { namespace Platform { namespace Test { namespace {
struct Sdl2ApplicationTest: Platform::Application {
@ -52,6 +54,12 @@ struct Sdl2ApplicationTest: Platform::Application {
void keyPressEvent(KeyEvent& event) override {
Debug{} << event.keyName();
}
/* Should fire on currently not handled events, such as minimize/maximize.
Comment out to verify correct behavior with the override not present. */
void anyEvent(SDL_Event& event) override {
Debug{} << "any event" << event.type;
}
};
}}}}

Loading…
Cancel
Save