Browse Source

python: expose viewport and exit event.

And also a possibility to make the window resizable on startup,
otherwise the viewport event gets never triggered.
pull/12/head
Vladimír Vondruš 5 years ago
parent
commit
4d5a9ed456
  1. 5
      doc/python/pages/changelog.rst
  2. 31
      src/python/magnum/platform/application.h
  3. 43
      src/python/magnum/platform/glfw.cpp
  4. 43
      src/python/magnum/platform/sdl2.cpp

5
doc/python/pages/changelog.rst

@ -75,6 +75,11 @@ Changelog
- Fixed :ref:`platform.sdl2.Application.InputEvent.Modifier` and
:ref:`platform.glfw.Application.InputEvent.Modifier` to behave properly
as flags and not just as an enum
- Exposed :ref:`platform.sdl2.Application.viewport_event` and
:ref:`platform.glfw.Application.viewport_event` and a possibility
to make the window resizable on startup
- Exposed :ref:`platform.sdl2.Application.exit_event` and
:ref:`platform.glfw.Application.exit_event`
`2020.06`_
==========

31
src/python/magnum/platform/application.h

@ -34,6 +34,12 @@ namespace magnum { namespace platform {
template<class T, class Trampoline, class Holder> void application(py::class_<T, Trampoline, Holder>& c) {
py::class_<typename T::Configuration> configuration{c, "Configuration", "Configuration"};
py::enum_<typename T::Configuration::WindowFlag> configurationWindowFlags{configuration, "WindowFlag", "WindowFlag"};
configurationWindowFlags
.value("RESIZABLE", T::Configuration::WindowFlag::Resizable);
corrade::enumOperators(configurationWindowFlags);
configuration
.def(py::init())
.def_property("title", &T::Configuration::title,
@ -43,7 +49,14 @@ template<class T, class Trampoline, class Holder> void application(py::class_<T,
.def_property("size", &T::Configuration::size,
[](typename T::Configuration& self, const Vector2i& size) {
self.setSize(size);
}, "Window size");
}, "Window size")
.def_property("window_flags",
[](typename T::Configuration& self) {
return typename T::Configuration::WindowFlag(typename std::underlying_type<typename T::Configuration::WindowFlag>::type(self.windowFlags()));
},
[](typename T::Configuration& self, typename T::Configuration::WindowFlag flags) {
self.setWindowFlags(flags);
}, "Window flags");
/** @todo others */
py::class_<typename T::GLConfiguration> glConfiguration{c, "GLConfiguration", "OpenGL context configuration"};
@ -67,8 +80,9 @@ template<class T, class Trampoline, class Holder> void application(py::class_<T,
.def("redraw", &T::redraw, "Redraw immediately")
.def_property_readonly("window_size", &T::windowSize, "Window size")
.def_property_readonly("framebuffer_size", &T::framebufferSize, "Framebuffer size")
/* Event handlers */
.def("exit_event", &T::exitEvent, "Exit event")
.def("viewport_event", &T::viewportEvent, "Viewport event")
.def("draw_event", &T::drawEvent, "Draw event")
.def("key_press_event", &T::keyPressEvent, "Key press event")
.def("key_release_event", &T::keyReleaseEvent, "Key release event")
@ -76,10 +90,21 @@ template<class T, class Trampoline, class Holder> void application(py::class_<T,
.def("mouse_release_event", &T::mouseReleaseEvent, "Mouse release event")
.def("mouse_move_event", &T::mouseMoveEvent, "Mouse move event")
.def("mouse_scroll_event", &T::mouseScrollEvent, "Mouse scroll event")
/** @todo more */
/** @todo mouse gesture, text input/editing event */
;
}
template<class T, class ...Args> void exitEvent(py::class_<T, Args...>& c) {
c
.def_property("accepted", &T::isAccepted, &T::setAccepted, "Accepted status of the event");
}
template<class T, class ...Args> void viewportEvent(py::class_<T, Args...>& c) {
c
.def_property_readonly("window_size", &T::windowSize, "Window size")
.def_property_readonly("framebuffer_size", &T::framebufferSize, "Framebuffer size")
.def_property_readonly("dpi_scaling", &T::dpiScaling, "DPI scaling");
}
template<class T, class ...Args> void inputEvent(py::class_<T, Args...>& c) {
py::enum_<typename T::Modifier> modifiers{c, "Modifier", "Modifier"};

43
src/python/magnum/platform/glfw.cpp

@ -49,6 +49,12 @@ void glfw(py::module_& m) {
throw py::error_already_set{};
}
void exitEvent(ExitEvent& event) override {
/* The base implementation does this, otherwise the exit event is
always cancelled. It's private so we can't call it directly. */
event.setAccepted();
}
void viewportEvent(ViewportEvent&) override {}
void keyPressEvent(KeyEvent&) override {}
void keyReleaseEvent(KeyEvent&) override {}
void mousePressEvent(MouseEvent&) override {}
@ -64,6 +70,35 @@ void glfw(py::module_& m) {
struct PyApplication: PublicizedApplication {
using PublicizedApplication::PublicizedApplication;
/* PYBIND11_OVERLOAD_NAME() calls object_api::operator() with implicit
template param, which is return_value_policy::automatic_reference.
That later gets changed to return_value_policy::copy in
type_caster_base::cast() and there's no way to override that. */
void exitEvent(ExitEvent& event) override {
PYBIND11_OVERLOAD_NAME(
void,
PublicizedApplication,
"exit_event",
exitEvent,
/* Have to use std::ref() otherwise pybind tries to copy
it and fails */
std::ref(event)
);
}
void viewportEvent(ViewportEvent& event) override {
PYBIND11_OVERLOAD_NAME(
void,
PublicizedApplication,
"viewport_event",
viewportEvent,
/* Have to use std::ref() otherwise pybind tries to copy
it and fails */
std::ref(event)
);
}
void drawEvent() override {
#ifdef __clang__
/* ugh pybind don't tell me I AM THE FIRST ON EARTH to get a
@ -83,10 +118,6 @@ void glfw(py::module_& m) {
#endif
}
/* PYBIND11_OVERLOAD_NAME() calls object_api::operator() with implicit
template param, which is return_value_policy::automatic_reference.
That later gets changed to return_value_policy::copy in
type_caster_base::cast() and there's no way to override that */
void keyPressEvent(KeyEvent& event) override {
PYBIND11_OVERLOAD_NAME(
void,
@ -159,6 +190,8 @@ void glfw(py::module_& m) {
py::class_<PublicizedApplication, PyApplication, ApplicationHolder<PublicizedApplication>> glfwApplication{m, "Application", "GLFW application"};
/** @todo def_property_writeonly for swap_interval */
PyNonDestructibleClass<PublicizedApplication::ExitEvent> exitEvent_{glfwApplication, "ExitEvent", "Exit event"};
PyNonDestructibleClass<PublicizedApplication::ViewportEvent> viewportEvent_{glfwApplication, "ViewportEvent", "Viewport event"};
PyNonDestructibleClass<PublicizedApplication::InputEvent> inputEvent_{glfwApplication, "InputEvent", "Base for input events"};
py::class_<PublicizedApplication::KeyEvent, PublicizedApplication::InputEvent> keyEvent_{glfwApplication, "KeyEvent", "Key event"};
py::class_<PublicizedApplication::MouseEvent, PublicizedApplication::InputEvent> mouseEvent_{glfwApplication, "MouseEvent", "Mouse event"};
@ -166,6 +199,8 @@ void glfw(py::module_& m) {
py::class_<PublicizedApplication::MouseScrollEvent, PublicizedApplication::InputEvent> mouseScrollEvent_{glfwApplication, "MouseScrollEvent", "Mouse scroll event"};
application(glfwApplication);
exitEvent(exitEvent_);
viewportEvent(viewportEvent_);
inputEvent(inputEvent_);
keyEvent(keyEvent_);
mouseEvent(mouseEvent_);

43
src/python/magnum/platform/sdl2.cpp

@ -49,6 +49,12 @@ void sdl2(py::module_& m) {
throw py::error_already_set{};
}
void exitEvent(ExitEvent& event) override {
/* The base implementation does this, otherwise the exit event is
always cancelled. It's private so we can't call it directly. */
event.setAccepted();
}
void viewportEvent(ViewportEvent&) override {}
void keyPressEvent(KeyEvent&) override {}
void keyReleaseEvent(KeyEvent&) override {}
void mousePressEvent(MouseEvent&) override {}
@ -64,6 +70,35 @@ void sdl2(py::module_& m) {
struct PyApplication: PublicizedApplication {
using PublicizedApplication::PublicizedApplication;
/* PYBIND11_OVERLOAD_NAME() calls object_api::operator() with implicit
template param, which is return_value_policy::automatic_reference.
That later gets changed to return_value_policy::copy in
type_caster_base::cast() and there's no way to override that. */
void exitEvent(ExitEvent& event) override {
PYBIND11_OVERLOAD_NAME(
void,
PublicizedApplication,
"exit_event",
exitEvent,
/* Have to use std::ref() otherwise pybind tries to copy
it and fails */
std::ref(event)
);
}
void viewportEvent(ViewportEvent& event) override {
PYBIND11_OVERLOAD_NAME(
void,
PublicizedApplication,
"viewport_event",
viewportEvent,
/* Have to use std::ref() otherwise pybind tries to copy
it and fails */
std::ref(event)
);
}
void drawEvent() override {
#ifdef __clang__
/* ugh pybind don't tell me I AM THE FIRST ON EARTH to get a
@ -83,10 +118,6 @@ void sdl2(py::module_& m) {
#endif
}
/* PYBIND11_OVERLOAD_NAME() calls object_api::operator() with implicit
template param, which is return_value_policy::automatic_reference.
That later gets changed to return_value_policy::copy in
type_caster_base::cast() and there's no way to override that */
void keyPressEvent(KeyEvent& event) override {
PYBIND11_OVERLOAD_NAME(
void,
@ -164,6 +195,8 @@ void sdl2(py::module_& m) {
}, "Swap interval")
.def("main_loop_iteration", &PyApplication::mainLoopIteration, "Run one iteration of application main loop");
PyNonDestructibleClass<PublicizedApplication::ExitEvent> exitEvent_{sdl2application, "ExitEvent", "Exit event"};
PyNonDestructibleClass<PublicizedApplication::ViewportEvent> viewportEvent_{sdl2application, "ViewportEvent", "Viewport event"};
PyNonDestructibleClass<PublicizedApplication::InputEvent> inputEvent_{sdl2application, "InputEvent", "Base for input events"};
py::class_<PublicizedApplication::KeyEvent, PublicizedApplication::InputEvent> keyEvent_{sdl2application, "KeyEvent", "Key event"};
py::class_<PublicizedApplication::MouseEvent, PublicizedApplication::InputEvent> mouseEvent_{sdl2application, "MouseEvent", "Mouse event"};
@ -171,6 +204,8 @@ void sdl2(py::module_& m) {
py::class_<PublicizedApplication::MouseScrollEvent, PublicizedApplication::InputEvent> mouseScrollEvent_{sdl2application, "MouseScrollEvent", "Mouse scroll event"};
application(sdl2application);
exitEvent(exitEvent_);
viewportEvent(viewportEvent_);
inputEvent(inputEvent_);
keyEvent(keyEvent_);
mouseEvent(mouseEvent_);

Loading…
Cancel
Save