// Copyright (C) 2022 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef QWASMEVENT_H #define QWASMEVENT_H #include "qwasmplatform.h" #include #include #include #include #include #include QT_BEGIN_NAMESPACE enum class EventType { PointerDown, PointerMove, PointerUp, PointerEnter, PointerLeave, }; enum class PointerType { Mouse, Other, }; enum class WindowArea { NonClient, Client, }; namespace KeyboardModifier { namespace internal { // Check for the existence of shiftKey, ctrlKey, altKey and metaKey in a type. // Based on that, we can safely assume we are dealing with an emscripten event type. template struct IsEmscriptenEvent { template struct SFINAE {}; template static char Test( SFINAE*); template static int Test(...); static const bool value = sizeof(Test(0)) == sizeof(char); }; template struct Helper; template struct Helper::value>> { static QFlags getModifierForEvent(const T& event) { QFlags keyModifier = Qt::NoModifier; if (event.shiftKey) keyModifier |= Qt::ShiftModifier; if (event.ctrlKey) keyModifier |= platform() == Platform::MacOS ? Qt::MetaModifier : Qt::ControlModifier; if (event.altKey) keyModifier |= Qt::AltModifier; if (event.metaKey) keyModifier |= platform() == Platform::MacOS ? Qt::ControlModifier : Qt::MetaModifier; return keyModifier; } }; template<> struct Helper { static QFlags getModifierForEvent(const emscripten::val& event) { QFlags keyModifier = Qt::NoModifier; if (event["shiftKey"].as()) keyModifier |= Qt::ShiftModifier; if (event["ctrlKey"].as()) keyModifier |= platform() == Platform::MacOS ? Qt::MetaModifier : Qt::ControlModifier; if (event["altKey"].as()) keyModifier |= Qt::AltModifier; if (event["metaKey"].as()) keyModifier |= platform() == Platform::MacOS ? Qt::ControlModifier : Qt::MetaModifier; if (event["constructor"]["name"].as() == "KeyboardEvent" && event["location"].as() == DOM_KEY_LOCATION_NUMPAD) { keyModifier |= Qt::KeypadModifier; } return keyModifier; } }; } // namespace internal template QFlags getForEvent(const Event& event) { return internal::Helper::getModifierForEvent(event); } template <> QFlags getForEvent( const EmscriptenKeyboardEvent& event); } // namespace KeyboardModifier struct Q_CORE_EXPORT Event { EventType type; }; struct Q_CORE_EXPORT MouseEvent : public Event { QPoint point; Qt::MouseButton mouseButton; Qt::MouseButtons mouseButtons; QFlags modifiers; static constexpr Qt::MouseButton buttonFromWeb(int webButton) { switch (webButton) { case 0: return Qt::LeftButton; case 1: return Qt::MiddleButton; case 2: return Qt::RightButton; default: return Qt::NoButton; } } static constexpr Qt::MouseButtons buttonsFromWeb(unsigned short webButtons) { // Coincidentally, Qt and web bitfields match. return Qt::MouseButtons::fromInt(webButtons); } static constexpr QEvent::Type mouseEventTypeFromEventType( EventType eventType, WindowArea windowArea) { switch (eventType) { case EventType::PointerDown : return windowArea == WindowArea::Client ? QEvent::MouseButtonPress : QEvent::NonClientAreaMouseButtonPress; case EventType::PointerUp : return windowArea == WindowArea::Client ? QEvent::MouseButtonRelease : QEvent::NonClientAreaMouseButtonRelease; case EventType::PointerMove : return windowArea == WindowArea::Client ? QEvent::MouseMove : QEvent::NonClientAreaMouseMove; default: return QEvent::None; } } }; struct Q_CORE_EXPORT PointerEvent : public MouseEvent { static std::optional fromWeb(emscripten::val webEvent); PointerType pointerType; int pointerId; }; QT_END_NAMESPACE #endif // QWASMEVENT_H