QmlMaterial 0.1.0
Loading...
Searching...
No Matches
wheel_handler.hpp
1/* SPDX-FileCopyrightText: 2019 Marco Martin <mart@kde.org>
2 * SPDX-FileCopyrightText: 2021 Noah Davis <noahadvs@gmail.com>
3 * SPDX-License-Identifier: LGPL-2.0-or-later
4 *
5 * Adapted from KDE Kirigami; integrated into qml_material.
6 */
7
8#pragma once
9
10#include <QGuiApplication>
11#include <QObject>
12#include <QPoint>
13#include <QPropertyAnimation>
14#include <QQmlParserStatus>
15#include <QQuickItem>
16#include <QStyleHints>
17#include <QTimer>
18#include <QQmlProperty>
19#include <QQmlEngine>
20
21class QWheelEvent;
22class QQmlEngine;
23
24namespace qml_material
25{
26
27class WheelHandler;
28
32class KirigamiWheelEvent : public QObject {
33 Q_OBJECT
34 Q_PROPERTY(qreal x READ x CONSTANT FINAL)
35 Q_PROPERTY(qreal y READ y CONSTANT FINAL)
36 Q_PROPERTY(QPointF angleDelta READ angleDelta CONSTANT FINAL)
37 Q_PROPERTY(QPointF pixelDelta READ pixelDelta CONSTANT FINAL)
38 Q_PROPERTY(int buttons READ buttons CONSTANT FINAL)
39 Q_PROPERTY(int modifiers READ modifiers CONSTANT FINAL)
40 Q_PROPERTY(bool inverted READ inverted CONSTANT FINAL)
41 Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted FINAL)
42
43public:
44 KirigamiWheelEvent(QObject* parent = nullptr);
45 ~KirigamiWheelEvent() override;
46
47 void initializeFromEvent(QWheelEvent* event);
48
49 qreal x() const;
50 qreal y() const;
51 QPointF angleDelta() const;
52 QPointF pixelDelta() const;
53 int buttons() const;
54 int modifiers() const;
55 bool inverted() const;
56 bool isAccepted();
57 void setAccepted(bool accepted);
58
59private:
60 qreal m_x = 0;
61 qreal m_y = 0;
62 QPointF m_angleDelta;
63 QPointF m_pixelDelta;
64 Qt::MouseButtons m_buttons = Qt::NoButton;
65 Qt::KeyboardModifiers m_modifiers = Qt::NoModifier;
66 bool m_inverted = false;
67 bool m_accepted = false;
68};
69
70class WheelFilterItem : public QQuickItem {
71 Q_OBJECT
72public:
73 WheelFilterItem(QQuickItem* parent = nullptr);
74};
75
79class WheelHandler : public QObject, public QQmlParserStatus {
80 Q_OBJECT
81 Q_INTERFACES(QQmlParserStatus)
82 QML_ELEMENT
83
84 Q_PROPERTY(QQuickItem* target READ target WRITE setTarget NOTIFY targetChanged FINAL)
85 Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged FINAL)
86 Q_PROPERTY(qreal verticalStepSize READ verticalStepSize WRITE setVerticalStepSize RESET
87 resetVerticalStepSize NOTIFY verticalStepSizeChanged FINAL)
88 Q_PROPERTY(qreal horizontalStepSize READ horizontalStepSize WRITE setHorizontalStepSize RESET
89 resetHorizontalStepSize NOTIFY horizontalStepSizeChanged FINAL)
90 Q_PROPERTY(Qt::KeyboardModifiers pageScrollModifiers READ pageScrollModifiers WRITE
91 setPageScrollModifiers RESET resetPageScrollModifiers NOTIFY
92 pageScrollModifiersChanged FINAL)
93 Q_PROPERTY(bool filterMouseEvents READ filterMouseEvents WRITE setFilterMouseEvents NOTIFY
94 filterMouseEventsChanged FINAL)
95 Q_PROPERTY(bool keyNavigationEnabled READ keyNavigationEnabled WRITE setKeyNavigationEnabled
96 NOTIFY keyNavigationEnabledChanged FINAL)
97 Q_PROPERTY(bool blockTargetWheel MEMBER m_blockTargetWheel NOTIFY blockTargetWheelChanged FINAL)
98 Q_PROPERTY(bool scrollFlickableTarget MEMBER m_scrollFlickableTarget NOTIFY
99 scrollFlickableTargetChanged FINAL)
100 Q_PROPERTY(
101 bool useAnimation READ useAnimation WRITE setUseAnimation NOTIFY useAnimationChanged FINAL)
102
103public:
104 explicit WheelHandler(QObject* parent = nullptr);
105 ~WheelHandler() override;
106
107 QQuickItem* target() const;
108 void setTarget(QQuickItem* target);
109
110 auto active() const -> bool;
111 void setActive(bool);
112 qreal verticalStepSize() const;
113 void setVerticalStepSize(qreal stepSize);
114 void resetVerticalStepSize();
115
116 qreal horizontalStepSize() const;
117 void setHorizontalStepSize(qreal stepSize);
118 void resetHorizontalStepSize();
119
120 Qt::KeyboardModifiers pageScrollModifiers() const;
121 void setPageScrollModifiers(Qt::KeyboardModifiers modifiers);
122 void resetPageScrollModifiers();
123
124 bool filterMouseEvents() const;
125 void setFilterMouseEvents(bool enabled);
126
127 bool keyNavigationEnabled() const;
128 void setKeyNavigationEnabled(bool enabled);
129
130 bool useAnimation() const;
131 void setUseAnimation(bool);
132
133 Q_INVOKABLE bool scrollUp(qreal stepSize = -1);
134 Q_INVOKABLE bool scrollDown(qreal stepSize = -1);
135
136 Q_INVOKABLE bool scrollLeft(qreal stepSize = -1);
137 Q_INVOKABLE bool scrollRight(qreal stepSize = -1);
138
139Q_SIGNALS:
140 void targetChanged();
141 void activeChanged();
142 void verticalStepSizeChanged();
143 void horizontalStepSizeChanged();
144 void pageScrollModifiersChanged();
145 void filterMouseEventsChanged();
146 void keyNavigationEnabledChanged();
147 void blockTargetWheelChanged();
148 void scrollFlickableTargetChanged();
149 void useAnimationChanged();
150
151 void wheel(KirigamiWheelEvent* wheel);
152 void wheelMoved();
153
154protected:
155 bool eventFilter(QObject* watched, QEvent* event) override;
156
157private Q_SLOTS:
158 void refreshAttach();
159 void attach();
160 void detach();
161 void rebindScrollBarV();
162 void rebindScrollBarH();
163
164private:
165 struct ScrollBar;
166 void rebindScrollBar(ScrollBar& scrollBar);
167 void classBegin() override;
168 void componentComplete() override;
169
170 void setScrolling(bool scrolling);
171 bool scrollFlickable(QPointF pixelDelta, QPointF angleDelta = {},
172 Qt::KeyboardModifiers modifiers = Qt::NoModifier);
173
174 QPointer<QQuickItem> m_target;
175
176 bool m_active;
177 QMetaObject::Connection m_verticalChangedConnection;
178 QMetaObject::Connection m_horizontalChangedConnection;
179
180 qreal m_defaultPixelStepSize = 20 * QGuiApplication::styleHints()->wheelScrollLines();
181 qreal m_verticalStepSize = m_defaultPixelStepSize;
182 qreal m_horizontalStepSize = m_defaultPixelStepSize;
183 bool m_explicitVStepSize = false;
184 bool m_explicitHStepSize = false;
185 bool m_wheelScrolling = false;
186 constexpr static qreal m_wheelScrollingDuration = 400;
187 bool m_filterMouseEvents = false;
188 bool m_keyNavigationEnabled = false;
189 bool m_blockTargetWheel = true;
190 bool m_scrollFlickableTarget = true;
191 constexpr static Qt::KeyboardModifiers m_defaultHorizontalScrollModifiers = Qt::AltModifier;
192 constexpr static Qt::KeyboardModifiers m_defaultPageScrollModifiers =
193 Qt::ControlModifier | Qt::ShiftModifier;
194 Qt::KeyboardModifiers m_pageScrollModifiers = m_defaultPageScrollModifiers;
195 QTimer m_wheelScrollingTimer;
196 KirigamiWheelEvent m_kirigamiWheelEvent;
197
198 QQmlEngine* m_engine = nullptr;
199 bool m_wasTouched = false;
200
201 struct Flickable {
202 QQmlProperty originX, originY;
203 QQmlProperty leftMargin, rightMargin;
204 QQmlProperty topMargin, bottomMargin;
205 QQmlProperty contentX, contentY;
206 QQmlProperty contentHeight, contentWidth;
207 QQmlProperty height, width;
208 QQmlProperty interactive;
209 } m_flickable;
210
211 struct ScrollBar {
212 QQmlProperty scrollBar;
213 QQmlProperty stepSize;
214 QMetaMethod increaseMethod;
215 QMetaMethod decreaseMethod;
216 QQuickItem* item = nullptr;
217 bool valid() const { return item != nullptr; };
218 } m_scrollBarV, m_scrollBarH;
219
220 bool m_useAnimation = false;
221};
222
223} // namespace qml_material
Definition wheel_handler.hpp:32
Handles scrolling for a Flickable and 2 attached ScrollBars.
Definition wheel_handler.hpp:79