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