File indexing completed on 2024-05-19 15:09:24
0001 /* 0002 SPDX-FileCopyrightText: 2011 Marco Martin <notmart@gmail.com> 0003 SPDX-FileCopyrightText: 2013 Sebastian Kügler <sebas@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #ifndef MOUSEEVENTLISTENER_H 0009 #define MOUSEEVENTLISTENER_H 0010 0011 #include <QQuickItem> 0012 0013 /** 0014 * This item spies on mouse events from all child objects including child MouseAreas regardless 0015 * of whether the child MouseArea propagates events. It does not accept the event. 0016 * 0017 * In addition unlike MouseArea events include the mouse position in global coordinates and provides 0018 * the screen the mouse is in. 0019 */ 0020 0021 class KDeclarativeMouseEvent : public QObject 0022 { 0023 Q_OBJECT 0024 Q_PROPERTY(int x READ x) 0025 Q_PROPERTY(int y READ y) 0026 Q_PROPERTY(int screenX READ screenX) 0027 Q_PROPERTY(int screenY READ screenY) 0028 Q_PROPERTY(int button READ button) 0029 Q_PROPERTY(Qt::MouseButtons buttons READ buttons) 0030 Q_PROPERTY(Qt::KeyboardModifiers modifiers READ modifiers) 0031 Q_PROPERTY(QScreen *screen READ screen CONSTANT) 0032 Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted NOTIFY acceptedChanged) 0033 Q_PROPERTY(int source READ source) 0034 0035 public: 0036 KDeclarativeMouseEvent(int x, 0037 int y, 0038 int screenX, 0039 int screenY, 0040 Qt::MouseButton button, 0041 Qt::MouseButtons buttons, 0042 Qt::KeyboardModifiers modifiers, 0043 QScreen *screen, 0044 Qt::MouseEventSource source) 0045 : m_x(x) 0046 , m_y(y) 0047 , m_screenX(screenX) 0048 , m_screenY(screenY) 0049 , m_button(button) 0050 , m_buttons(buttons) 0051 , m_modifiers(modifiers) 0052 , m_screen(screen) 0053 , m_source(source) 0054 { 0055 } 0056 0057 int x() const 0058 { 0059 return m_x; 0060 } 0061 int y() const 0062 { 0063 return m_y; 0064 } 0065 int screenX() const 0066 { 0067 return m_screenX; 0068 } 0069 int screenY() const 0070 { 0071 return m_screenY; 0072 } 0073 int button() const 0074 { 0075 return m_button; 0076 } 0077 Qt::MouseButtons buttons() const 0078 { 0079 return m_buttons; 0080 } 0081 Qt::KeyboardModifiers modifiers() const 0082 { 0083 return m_modifiers; 0084 } 0085 QScreen *screen() const 0086 { 0087 return m_screen; 0088 } 0089 int source() const 0090 { 0091 return m_source; 0092 } 0093 0094 bool isAccepted() const 0095 { 0096 return m_accepted; 0097 } 0098 void setAccepted(bool accepted) 0099 { 0100 if (m_accepted != accepted) { 0101 m_accepted = accepted; 0102 Q_EMIT acceptedChanged(); 0103 } 0104 } 0105 0106 // only for internal usage 0107 void setX(int x) 0108 { 0109 m_x = x; 0110 } 0111 void setY(int y) 0112 { 0113 m_y = y; 0114 } 0115 0116 Q_SIGNALS: 0117 void acceptedChanged(); 0118 0119 private: 0120 int m_x; 0121 int m_y; 0122 int m_screenX; 0123 int m_screenY; 0124 Qt::MouseButton m_button; 0125 Qt::MouseButtons m_buttons; 0126 Qt::KeyboardModifiers m_modifiers; 0127 QScreen *m_screen; 0128 bool m_accepted = false; 0129 int m_source; 0130 }; 0131 0132 class KDeclarativeWheelEvent : public QObject 0133 { 0134 Q_OBJECT 0135 Q_PROPERTY(int x READ x CONSTANT) 0136 Q_PROPERTY(int y READ y CONSTANT) 0137 Q_PROPERTY(int screenX READ screenX CONSTANT) 0138 Q_PROPERTY(int screenY READ screenY CONSTANT) 0139 Q_PROPERTY(int deltaX READ deltaX CONSTANT) 0140 Q_PROPERTY(int deltaY READ deltaY CONSTANT) 0141 Q_PROPERTY(int delta READ deltaY CONSTANT) // deprecated in favor of deltaY. TODO KF6: remove 0142 Q_PROPERTY(Qt::MouseButtons buttons READ buttons CONSTANT) 0143 Q_PROPERTY(Qt::KeyboardModifiers modifiers READ modifiers CONSTANT) 0144 Q_PROPERTY(Qt::Orientation orientation READ orientation CONSTANT) // deprecated. TODO KF6: remove 0145 0146 public: 0147 KDeclarativeWheelEvent(QPointF pos, 0148 QPoint screenPos, 0149 QPoint angleDelta, 0150 Qt::MouseButtons buttons, 0151 Qt::KeyboardModifiers modifiers, 0152 Qt::Orientation orientation) 0153 : m_x(pos.x()) 0154 , m_y(pos.y()) 0155 , m_screenX(screenPos.x()) 0156 , m_screenY(screenPos.y()) 0157 , m_angleDelta(angleDelta) 0158 , m_buttons(buttons) 0159 , m_modifiers(modifiers) 0160 , m_orientation(orientation) 0161 { 0162 } 0163 0164 int x() const 0165 { 0166 return m_x; 0167 } 0168 int y() const 0169 { 0170 return m_y; 0171 } 0172 int screenX() const 0173 { 0174 return m_screenX; 0175 } 0176 int screenY() const 0177 { 0178 return m_screenY; 0179 } 0180 int deltaX() const 0181 { 0182 return m_angleDelta.x(); 0183 } 0184 int deltaY() const 0185 { 0186 return m_angleDelta.y(); 0187 } 0188 Qt::MouseButtons buttons() const 0189 { 0190 return m_buttons; 0191 } 0192 Qt::KeyboardModifiers modifiers() const 0193 { 0194 return m_modifiers; 0195 } 0196 Qt::Orientation orientation() 0197 { 0198 return m_orientation; 0199 } // TODO KF6: remove 0200 0201 // only for internal usage 0202 void setX(int x) 0203 { 0204 m_x = x; 0205 } 0206 void setY(int y) 0207 { 0208 m_y = y; 0209 } 0210 0211 private: 0212 int m_x; 0213 int m_y; 0214 int m_screenX; 0215 int m_screenY; 0216 QPoint m_angleDelta; 0217 Qt::MouseButtons m_buttons; 0218 Qt::KeyboardModifiers m_modifiers; 0219 Qt::Orientation m_orientation; 0220 }; 0221 0222 class MouseEventListener : public QQuickItem 0223 { 0224 Q_OBJECT 0225 /** 0226 * This property holds whether hover events are handled. 0227 * By default hover events are disabled 0228 */ 0229 Q_PROPERTY(bool hoverEnabled READ hoverEnabled WRITE setHoverEnabled NOTIFY hoverEnabledChanged) 0230 0231 /** 0232 * True if this MouseEventListener or any of its children contains the mouse cursor: 0233 * this property will change only when the mouse button is pressed if hoverEnabled is false. 0234 */ 0235 Q_PROPERTY(bool containsMouse READ containsMouse NOTIFY containsMouseChanged) 0236 0237 Q_PROPERTY(Qt::MouseButtons acceptedButtons READ acceptedButtons WRITE setAcceptedButtons NOTIFY acceptedButtonsChanged) 0238 0239 /** 0240 * This property holds the cursor shape for this mouse area. 0241 * Note that on platforms that do not display a mouse cursor this may have no effect. 0242 */ 0243 Q_PROPERTY(Qt::CursorShape cursorShape READ cursorShape WRITE setCursorShape RESET unsetCursor NOTIFY cursorShapeChanged) 0244 0245 /** 0246 * True if the mouse is pressed in the item or any of its children 0247 */ 0248 Q_PROPERTY(bool pressed READ isPressed NOTIFY pressedChanged) 0249 0250 public: 0251 MouseEventListener(QQuickItem *parent = nullptr); 0252 ~MouseEventListener() override; 0253 0254 bool containsMouse() const; 0255 void setHoverEnabled(bool enable); 0256 bool hoverEnabled() const; 0257 bool isPressed() const; 0258 0259 Qt::MouseButtons acceptedButtons() const; 0260 void setAcceptedButtons(Qt::MouseButtons buttons); 0261 0262 Qt::CursorShape cursorShape() const; 0263 void setCursorShape(Qt::CursorShape shape); 0264 0265 protected: 0266 void hoverEnterEvent(QHoverEvent *event) override; 0267 void hoverLeaveEvent(QHoverEvent *event) override; 0268 void hoverMoveEvent(QHoverEvent *event) override; 0269 void mousePressEvent(QMouseEvent *event) override; 0270 void mouseMoveEvent(QMouseEvent *event) override; 0271 void mouseReleaseEvent(QMouseEvent *event) override; 0272 void wheelEvent(QWheelEvent *event) override; 0273 bool childMouseEventFilter(QQuickItem *item, QEvent *event) override; 0274 void mouseUngrabEvent() override; 0275 void touchUngrabEvent() override; 0276 0277 Q_SIGNALS: 0278 void pressed(KDeclarativeMouseEvent *mouse); 0279 void positionChanged(KDeclarativeMouseEvent *mouse); 0280 void released(KDeclarativeMouseEvent *mouse); 0281 void clicked(KDeclarativeMouseEvent *mouse); 0282 void pressAndHold(KDeclarativeMouseEvent *mouse); 0283 void wheelMoved(KDeclarativeWheelEvent *wheel); 0284 void containsMouseChanged(bool containsMouseChanged); 0285 void hoverEnabledChanged(bool hoverEnabled); 0286 void acceptedButtonsChanged(); 0287 void cursorShapeChanged(); 0288 void pressedChanged(); 0289 void canceled(); 0290 0291 private Q_SLOTS: 0292 void handlePressAndHold(); 0293 void handleUngrab(); 0294 0295 private: 0296 static QScreen *screenForGlobalPos(const QPoint &globalPos); 0297 0298 bool m_pressed; 0299 KDeclarativeMouseEvent *m_pressAndHoldEvent; 0300 QPointF m_buttonDownPos; 0301 // Important: used only for comparison. If you will ever need to access this pointer, make it a QWeakPointer 0302 QEvent *m_lastEvent; 0303 QTimer *m_pressAndHoldTimer; 0304 bool m_containsMouse; 0305 Qt::MouseButtons m_acceptedButtons; 0306 }; 0307 0308 #endif