diff options
-rw-r--r-- | include/cru/platform/gui/Base.h | 12 | ||||
-rw-r--r-- | include/cru/platform/gui/xcb/Keyboard.h | 8 | ||||
-rw-r--r-- | include/cru/platform/gui/xcb/Window.h | 9 | ||||
-rw-r--r-- | src/platform/gui/xcb/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/platform/gui/xcb/Keyboard.cpp | 9 | ||||
-rw-r--r-- | src/platform/gui/xcb/Window.cpp | 97 |
6 files changed, 107 insertions, 29 deletions
diff --git a/include/cru/platform/gui/Base.h b/include/cru/platform/gui/Base.h index 83d07582..affce4cd 100644 --- a/include/cru/platform/gui/Base.h +++ b/include/cru/platform/gui/Base.h @@ -28,10 +28,16 @@ struct TagMouseButton {}; } // namespace details using MouseButton = Bitmask<details::TagMouseButton>; +struct MouseButtons { + constexpr static MouseButton None = MouseButton::FromOffset(0); + constexpr static MouseButton Left = MouseButton::FromOffset(1); + constexpr static MouseButton Middle = MouseButton::FromOffset(2); + constexpr static MouseButton Right = MouseButton::FromOffset(3); +}; namespace mouse_buttons { -constexpr MouseButton left{0b1}; -constexpr MouseButton middle{0b10}; -constexpr MouseButton right{0b100}; +constexpr MouseButton left{MouseButtons::Left}; +constexpr MouseButton middle{MouseButtons::Middle}; +constexpr MouseButton right{MouseButtons::Right}; } // namespace mouse_buttons } // namespace cru::platform::gui diff --git a/include/cru/platform/gui/xcb/Keyboard.h b/include/cru/platform/gui/xcb/Keyboard.h new file mode 100644 index 00000000..8d25ff7f --- /dev/null +++ b/include/cru/platform/gui/xcb/Keyboard.h @@ -0,0 +1,8 @@ +#pragma once + +#include <cru/platform/gui/Keyboard.h> + +namespace cru::platform::gui::xcb { +struct XcbUiApplication; +KeyModifier GetCurrentKeyModifiers(XcbUiApplication* application); +} // namespace cru::platform::gui::xcb diff --git a/include/cru/platform/gui/xcb/Window.h b/include/cru/platform/gui/xcb/Window.h index 1676dced..016b5717 100644 --- a/include/cru/platform/gui/xcb/Window.h +++ b/include/cru/platform/gui/xcb/Window.h @@ -71,9 +71,9 @@ class XcbWindow : public XcbResource, public virtual INativeWindow { IEvent<MouseEnterLeaveType>* MouseEnterLeaveEvent() override; IEvent<Point>* MouseMoveEvent() override; - virtual IEvent<NativeMouseButtonEventArgs>* MouseDownEvent() = 0; - virtual IEvent<NativeMouseButtonEventArgs>* MouseUpEvent() = 0; - virtual IEvent<NativeMouseWheelEventArgs>* MouseWheelEvent() = 0; + IEvent<NativeMouseButtonEventArgs>* MouseDownEvent() override; + IEvent<NativeMouseButtonEventArgs>* MouseUpEvent() override; + IEvent<NativeMouseWheelEventArgs>* MouseWheelEvent() override; virtual IEvent<NativeKeyEventArgs>* KeyDownEvent() = 0; virtual IEvent<NativeKeyEventArgs>* KeyUpEvent() = 0; @@ -93,5 +93,8 @@ class XcbWindow : public XcbResource, public virtual INativeWindow { Event<MouseEnterLeaveType> mouse_enter_leave_event_; Event<Point> mouse_move_event_; + Event<NativeMouseButtonEventArgs> mouse_down_event_; + Event<NativeMouseButtonEventArgs> mouse_up_event_; + Event<NativeMouseWheelEventArgs> mouse_wheel_event_; }; } // namespace cru::platform::gui::xcb diff --git a/src/platform/gui/xcb/CMakeLists.txt b/src/platform/gui/xcb/CMakeLists.txt index 2ef675a3..8bd64279 100644 --- a/src/platform/gui/xcb/CMakeLists.txt +++ b/src/platform/gui/xcb/CMakeLists.txt @@ -1,6 +1,7 @@ find_library(LIBRARY_CAIRO cairo REQUIRED) find_library(LIBRARY_XCB xcb REQUIRED) add_library(CruPlatformGuiX11 + Keyboard.cpp UiApplication.cpp Window.cpp ) diff --git a/src/platform/gui/xcb/Keyboard.cpp b/src/platform/gui/xcb/Keyboard.cpp new file mode 100644 index 00000000..1a69c3bd --- /dev/null +++ b/src/platform/gui/xcb/Keyboard.cpp @@ -0,0 +1,9 @@ +#include "cru/platform/gui/xcb/Keyboard.h" + +#include "cru/base/Base.h" + +namespace cru::platform::gui::xcb { +KeyModifier GetCurrentKeyModifiers(XcbUiApplication* application) { + NotImplemented(); +} +} // namespace cru::platform::gui::xcb diff --git a/src/platform/gui/xcb/Window.cpp b/src/platform/gui/xcb/Window.cpp index 3494bc7d..9562a390 100644 --- a/src/platform/gui/xcb/Window.cpp +++ b/src/platform/gui/xcb/Window.cpp @@ -1,5 +1,8 @@ #include "cru/platform/gui/xcb/Window.h" +#include "cru/platform/gui/Base.h" +#include "cru/platform/gui/Keyboard.h" #include "cru/platform/gui/Window.h" +#include "cru/platform/gui/xcb/Keyboard.h" #include "cru/platform/gui/xcb/UiApplication.h" #include <xcb/xcb.h> @@ -26,6 +29,43 @@ void print_modifiers(uint32_t mask) { } // namespace namespace cru::platform::gui::xcb { + +namespace { +MouseButton ConvertMouseButton(xcb_button_t button) { + switch (button) { + case 1: + return MouseButtons::Left; + case 2: + return MouseButtons::Middle; + case 3: + return MouseButtons::Right; + default: + return MouseButtons::None; + } +} + +KeyModifier ConvertModifiers(uint32_t mask) { + // const char *MODIFIERS[] = { + // "Shift", "Lock", "Ctrl", "Alt", "Mod2", "Mod3", "Mod4", + // "Mod5", "Button1", "Button2", "Button3", "Button4", "Button5"}; + constexpr KeyModifier MODIFIERS[] = { + KeyModifiers::shift, KeyModifiers::none, KeyModifiers::ctrl, + KeyModifiers::alt, KeyModifiers::none, KeyModifiers::none, + KeyModifiers::none, KeyModifiers::none, KeyModifiers::none, + KeyModifiers::none, KeyModifiers::none, KeyModifiers::none, + KeyModifiers::none, + }; + + KeyModifier result; + for (auto iter = std::begin(MODIFIERS); mask; mask >>= 1, ++iter) { + if (mask & 1) { + result |= *iter; + } + } + return result; +} +} // namespace + XcbWindow::XcbWindow(XcbUiApplication *application) : application_(application) { application->RegisterWindow(this); @@ -39,6 +79,18 @@ IEvent<MouseEnterLeaveType> *XcbWindow::MouseEnterLeaveEvent() { IEvent<Point> *XcbWindow::MouseMoveEvent() { return &mouse_move_event_; } +IEvent<NativeMouseButtonEventArgs> *XcbWindow::MouseDownEvent() { + return &mouse_down_event_; +} + +IEvent<NativeMouseButtonEventArgs> *XcbWindow::MouseUpEvent() { + return &mouse_up_event_; +} + +IEvent<NativeMouseWheelEventArgs> *XcbWindow::MouseWheelEvent() { + return &mouse_wheel_event_; +} + std::optional<xcb_window_t> XcbWindow::GetXcbWindow() { return xcb_window_; } xcb_window_t XcbWindow::DoCreateWindow() { @@ -75,34 +127,33 @@ void XcbWindow::HandleEvent(xcb_generic_event_t *event) { } case XCB_BUTTON_PRESS: { xcb_button_press_event_t *bp = (xcb_button_press_event_t *)event; - print_modifiers(bp->state); - - switch (bp->detail) { - case 4: - printf("Wheel Button up in window %" PRIu32 - ", at coordinates (%" PRIi16 ",%" PRIi16 ")\n", - bp->event, bp->event_x, bp->event_y); - break; - case 5: - printf("Wheel Button down in window %" PRIu32 - ", at coordinates (%" PRIi16 ",%" PRIi16 ")\n", - bp->event, bp->event_x, bp->event_y); - break; - default: - printf("Button %" PRIu8 " pressed in window %" PRIu32 - ", at coordinates (%" PRIi16 ",%" PRIi16 ")\n", - bp->detail, bp->event, bp->event_x, bp->event_y); - break; + + if (bp->detail >= 4 && bp->detail <= 7) { + NativeMouseWheelEventArgs args(30, Point(bp->event_x, bp->event_y), + GetCurrentKeyModifiers(application_), + false); + if (bp->detail == 5 || bp->detail == 7) { + args.delta = -args.delta; + } + if (bp->detail == 6 || bp->detail == 7) { + args.horizontal = true; + } + mouse_wheel_event_.Raise(std::move(args)); + break; } + + NativeMouseButtonEventArgs args(ConvertMouseButton(bp->detail), + Point(bp->event_x, bp->event_y), + GetCurrentKeyModifiers(application_)); + mouse_down_event_.Raise(std::move(args)); break; } case XCB_BUTTON_RELEASE: { xcb_button_release_event_t *br = (xcb_button_release_event_t *)event; - print_modifiers(br->state); - - printf("Button %" PRIu8 " released in window %" PRIu32 - ", at coordinates (%" PRIi16 ",%" PRIi16 ")\n", - br->detail, br->event, br->event_x, br->event_y); + NativeMouseButtonEventArgs args(ConvertMouseButton(br->detail), + Point(br->event_x, br->event_y), + GetCurrentKeyModifiers(application_)); + mouse_up_event_.Raise(std::move(args)); break; } case XCB_MOTION_NOTIFY: { |