File indexing completed on 2024-05-19 15:09:23

0001 /*
0002     SPDX-FileCopyrightText: 2015 Eike Hein <hein@kde.org>
0003     SPDX-FileCopyrightText: 2015 Marco Martin <notmart@gmail.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "eventgenerator.h"
0009 
0010 #include <QGuiApplication>
0011 #include <QQuickItem>
0012 #include <QQuickWindow>
0013 
0014 EventGenerator::EventGenerator(QObject *parent)
0015     : QObject(parent)
0016 {
0017 }
0018 
0019 EventGenerator::~EventGenerator()
0020 {
0021 }
0022 
0023 void EventGenerator::sendMouseEvent(QQuickItem *item,
0024                                     EventGenerator::MouseEvent type,
0025                                     int x,
0026                                     int y,
0027                                     int button,
0028                                     Qt::MouseButtons buttons,
0029                                     Qt::KeyboardModifiers modifiers)
0030 {
0031     if (!item) {
0032         return;
0033     }
0034 
0035     QEvent::Type eventType;
0036     switch (type) {
0037     case MouseButtonPress:
0038         eventType = QEvent::MouseButtonPress;
0039         break;
0040     case MouseButtonRelease:
0041         eventType = QEvent::MouseButtonRelease;
0042         break;
0043     case MouseMove:
0044         eventType = QEvent::MouseMove;
0045         break;
0046     default:
0047         return;
0048     }
0049     QMouseEvent ev(eventType, QPointF(x, y), static_cast<Qt::MouseButton>(button), buttons, modifiers);
0050 
0051     QGuiApplication::sendEvent(item, &ev);
0052 }
0053 
0054 void EventGenerator::sendMouseEventRecursive(QQuickItem *parentItem,
0055                                              EventGenerator::MouseEvent type,
0056                                              int x,
0057                                              int y,
0058                                              int button,
0059                                              Qt::MouseButtons buttons,
0060                                              Qt::KeyboardModifiers modifiers)
0061 {
0062     if (!parentItem) {
0063         return;
0064     }
0065 
0066     const QList<QQuickItem *> items = allChildItemsRecursive(parentItem);
0067 
0068     for (QQuickItem *item : items) {
0069         sendMouseEvent(item, type, x, y, button, buttons, modifiers);
0070     }
0071 }
0072 
0073 void EventGenerator::sendWheelEvent(QQuickItem *item,
0074                                     int x,
0075                                     int y,
0076                                     const QPoint &pixelDelta,
0077                                     const QPoint &angleDelta,
0078                                     Qt::MouseButtons buttons,
0079                                     Qt::KeyboardModifiers modifiers)
0080 {
0081     if (!item || !item->window()) {
0082         return;
0083     }
0084 
0085     QPointF pos(x, y);
0086     QPointF globalPos(item->window()->mapToGlobal(item->mapToScene(pos).toPoint()));
0087     QWheelEvent ev(pos, globalPos, pixelDelta, angleDelta, buttons, modifiers, Qt::ScrollUpdate, false /*not inverted*/);
0088     QGuiApplication::sendEvent(item, &ev);
0089 }
0090 
0091 void EventGenerator::sendWheelEventRecursive(QQuickItem *parentItem,
0092                                              int x,
0093                                              int y,
0094                                              const QPoint &pixelDelta,
0095                                              const QPoint &angleDelta,
0096                                              Qt::MouseButtons buttons,
0097                                              Qt::KeyboardModifiers modifiers)
0098 {
0099     if (!parentItem) {
0100         return;
0101     }
0102 
0103     const QList<QQuickItem *> items = allChildItemsRecursive(parentItem);
0104 
0105     for (QQuickItem *item : items) {
0106         sendWheelEvent(item, x, y, pixelDelta, angleDelta, buttons, modifiers);
0107     }
0108 }
0109 
0110 void EventGenerator::sendGrabEvent(QQuickItem *item, EventGenerator::GrabEvent type)
0111 {
0112     if (!item) {
0113         return;
0114     }
0115 
0116     switch (type) {
0117     case GrabMouse:
0118         item->grabMouse();
0119         break;
0120     case UngrabMouse: {
0121         QEvent ev(QEvent::UngrabMouse);
0122         QGuiApplication::sendEvent(item, &ev);
0123         return;
0124     }
0125     default:
0126         return;
0127     }
0128 }
0129 
0130 void EventGenerator::sendGrabEventRecursive(QQuickItem *parentItem, EventGenerator::GrabEvent type)
0131 {
0132     if (!parentItem) {
0133         return;
0134     }
0135 
0136     const QList<QQuickItem *> items = allChildItemsRecursive(parentItem);
0137 
0138     for (QQuickItem *item : items) {
0139         sendGrabEvent(item, type);
0140     }
0141 }
0142 
0143 QList<QQuickItem *> EventGenerator::allChildItemsRecursive(QQuickItem *parentItem)
0144 {
0145     QList<QQuickItem *> itemList;
0146 
0147     const auto childsItems = parentItem->childItems();
0148     itemList.append(childsItems);
0149 
0150     for (QQuickItem *childItem : childsItems) {
0151         itemList.append(allChildItemsRecursive(childItem));
0152     }
0153 
0154     return itemList;
0155 }
0156 
0157 #include "moc_eventgenerator.cpp"