-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy patheventfilter.cpp
145 lines (140 loc) · 4.71 KB
/
eventfilter.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// (c) Nathaniel van Diepen 2019 and used with permission.
// https://github.com/Eeems/oxide/blob/master/LICENSE.md
#include "eventfilter.h"
#include <QTimer>
#include <QDebug>
#include <QMouseEvent>
#include <QTabletEvent>
#include <QScreen>
#define DISPLAYWIDTH 1404
#define DISPLAYHEIGHT 1872.0
#define WACOM_X_SCALAR (float(DISPLAYWIDTH) / float(DISPLAYHEIGHT))
#define WACOM_Y_SCALAR (float(DISPLAYHEIGHT) / float(DISPLAYWIDTH))
//#define DEBUG_EVENTS 1
EventFilter::EventFilter(QObject *parent) : QObject(parent), root(nullptr) {}
QPointF swap(QPointF pointF){
return QPointF(pointF.y(), pointF.x());
}
QPointF transpose(QPointF pointF){
pointF = swap(pointF);
// Handle scaling from wacom to screensize
pointF.setX(pointF.x() * WACOM_X_SCALAR);
pointF.setY((DISPLAYWIDTH - pointF.y()) * WACOM_Y_SCALAR);
return pointF;
}
QPointF globalPos(QQuickItem* obj){
qreal x = obj->x();
qreal y = obj->y();
while(obj->parentItem() != nullptr){
obj = obj->parentItem();
x += obj->x();
y += obj->y();
}
return QPointF(x, y);
}
QMouseEvent* toMouseEvent(QEvent::Type type, QEvent* ev){
auto tabletEvent = (QTabletEvent*)ev;
auto button = tabletEvent->pressure() > 0 || type == QMouseEvent::MouseButtonRelease ? Qt::LeftButton : Qt::NoButton;
return new QMouseEvent(
type,
transpose(tabletEvent->posF()),
transpose(tabletEvent->globalPosF()),
transpose(tabletEvent->globalPosF()),
button,
button,
tabletEvent->modifiers()
);
}
bool isAt(QQuickItem* item, QPointF pos){
auto itemPos = globalPos(item);
auto otherItemPos = QPointF(itemPos.x() + item->width(), itemPos.y() + item->height());
return pos.x() >= itemPos.x() && pos.x() <= otherItemPos.x() && pos.y() >= itemPos.y() && pos.y() <= otherItemPos.y();
}
QList<QObject*> widgetsAt(QQuickItem* root, QPointF pos){
QList<QObject*> result;
auto children = root->findChildren<QQuickItem*>();
for(auto child : children){
if(isAt(child, pos)){
if(child->isVisible() && child->isEnabled() && child->acceptedMouseButtons() & Qt::LeftButton){
if(!result.contains(child)){
result.append((QObject*)child);
for(auto item : widgetsAt(child, pos)){
if(!result.contains(item)){
result.append(item);
}
}
}
}
}
}
return result;
}
int parentCount(QQuickItem* obj){
int count = 0;
while(obj->parentItem()){
count++;
obj = obj->parentItem();
}
return count;
}
void postEvent(QEvent::Type type, QEvent* ev, QQuickItem* root){
auto mouseEvent = toMouseEvent(type, ev);
auto pos = mouseEvent->globalPos();
for(auto postWidget : widgetsAt(root, pos)){
if(parentCount((QQuickItem*)postWidget)){
#ifdef DEBUG_EVENTS
qDebug() << "postWidget: " << postWidget;
#endif
auto event = new QMouseEvent(
mouseEvent->type(), mouseEvent->localPos(), mouseEvent->windowPos(),
mouseEvent->screenPos(), mouseEvent->button(), mouseEvent->buttons(),
mouseEvent->modifiers()
);
auto widgetPos = globalPos((QQuickItem*)postWidget);
auto localPos = event->localPos();
localPos.setX(pos.x() - widgetPos.x());
localPos.setY((pos.y()) - widgetPos.y());
event->setLocalPos(localPos);
QGuiApplication::postEvent(postWidget, event);
}
}
delete mouseEvent;
}
bool EventFilter::eventFilter(QObject* obj, QEvent* ev){
auto type = ev->type();
bool filtered = QObject::eventFilter(obj, ev);
if(!filtered){
if(type == QEvent::TabletPress){
#ifdef DEBUG_EVENTS
qDebug() << ev;
#endif
postEvent(QMouseEvent::MouseButtonPress, ev, root);
}else if(type == QEvent::TabletRelease){
#ifdef DEBUG_EVENTS
qDebug() << ev;
#endif
postEvent(QMouseEvent::MouseButtonRelease, ev, root);
}else if(type == QEvent::TabletMove){
#ifdef DEBUG_EVENTS
qDebug() << ev;
#endif
postEvent(QMouseEvent::MouseMove, ev, root);
}
#ifdef DEBUG_EVENTS
else if(
type == QEvent::MouseMove
|| type == QEvent::MouseButtonPress
|| type == QEvent::MouseButtonRelease
){
for(auto widget : widgetsAt(root, ((QMouseEvent*)ev)->globalPos())){
if(parentCount((QQuickItem*)widget)){
qDebug() << "postWidget: " << widget;
}
}
qDebug() << obj;
qDebug() << ev;
}
#endif
}
return filtered;
}