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(Qt::KeyboardModifiers horizontalScrollModifiers READ horizontalScrollModifiers WRITE
94 setHorizontalScrollModifiers RESET resetHorizontalScrollModifiers NOTIFY
95 horizontalScrollModifiersChanged FINAL)
96 Q_PROPERTY(bool filterMouseEvents READ filterMouseEvents WRITE setFilterMouseEvents NOTIFY
97 filterMouseEventsChanged FINAL)
98 Q_PROPERTY(bool keyNavigationEnabled READ keyNavigationEnabled WRITE setKeyNavigationEnabled
99 NOTIFY keyNavigationEnabledChanged FINAL)
100 Q_PROPERTY(bool blockTargetWheel MEMBER m_blockTargetWheel NOTIFY blockTargetWheelChanged FINAL)
101 Q_PROPERTY(bool scrollFlickableTarget MEMBER m_scrollFlickableTarget NOTIFY
102 scrollFlickableTargetChanged FINAL)
103 Q_PROPERTY(
104 bool useAnimation READ useAnimation WRITE setUseAnimation NOTIFY useAnimationChanged FINAL)
105
106public:
107 explicit WheelHandler(QObject* parent = nullptr);
108 ~WheelHandler() override;
109
110 QQuickItem* target() const;
111 void setTarget(QQuickItem* target);
112
113 auto active() const -> bool;
114 void setActive(bool);
115 qreal verticalStepSize() const;
116 void setVerticalStepSize(qreal stepSize);
117 void resetVerticalStepSize();
118
119 qreal horizontalStepSize() const;
120 void setHorizontalStepSize(qreal stepSize);
121 void resetHorizontalStepSize();
122
123 Qt::KeyboardModifiers pageScrollModifiers() const;
124 void setPageScrollModifiers(Qt::KeyboardModifiers modifiers);
125 void resetPageScrollModifiers();
126
127 Qt::KeyboardModifiers horizontalScrollModifiers() const;
128 void setHorizontalScrollModifiers(Qt::KeyboardModifiers modifiers);
129 void resetHorizontalScrollModifiers();
130
131 bool filterMouseEvents() const;
132 void setFilterMouseEvents(bool enabled);
133
134 bool keyNavigationEnabled() const;
135 void setKeyNavigationEnabled(bool enabled);
136
137 bool useAnimation() const;
138 void setUseAnimation(bool);
139
140 Q_INVOKABLE bool scrollUp(qreal stepSize = -1);
141 Q_INVOKABLE bool scrollDown(qreal stepSize = -1);
142
143 Q_INVOKABLE bool scrollLeft(qreal stepSize = -1);
144 Q_INVOKABLE bool scrollRight(qreal stepSize = -1);
145
146Q_SIGNALS:
147 void targetChanged();
148 void activeChanged();
149 void verticalStepSizeChanged();
150 void horizontalStepSizeChanged();
151 void pageScrollModifiersChanged();
152 void horizontalScrollModifiersChanged();
153 void filterMouseEventsChanged();
154 void keyNavigationEnabledChanged();
155 void blockTargetWheelChanged();
156 void scrollFlickableTargetChanged();
157 void useAnimationChanged();
158
159 void wheel(KirigamiWheelEvent* wheel);
160 void wheelMoved();
161
162protected:
163 bool eventFilter(QObject* watched, QEvent* event) override;
164
165private Q_SLOTS:
166 void refreshAttach();
167 void attach();
168 void detach();
169 void rebindScrollBarV();
170 void rebindScrollBarH();
171
172private:
173 struct ScrollBar;
174 void rebindScrollBar(ScrollBar& scrollBar);
175 void classBegin() override;
176 void componentComplete() override;
177
178 void setScrolling(bool scrolling);
179 bool scrollFlickable(QPointF pixelDelta, QPointF angleDelta = {},
180 Qt::KeyboardModifiers modifiers = Qt::NoModifier);
181
182 QPointer<QQuickItem> m_target;
183
184 bool m_active;
185 QMetaObject::Connection m_verticalChangedConnection;
186 QMetaObject::Connection m_horizontalChangedConnection;
187
188 qreal m_defaultPixelStepSize = 20 * QGuiApplication::styleHints()->wheelScrollLines();
189 qreal m_verticalStepSize = m_defaultPixelStepSize;
190 qreal m_horizontalStepSize = m_defaultPixelStepSize;
191 bool m_explicitVStepSize = false;
192 bool m_explicitHStepSize = false;
193 bool m_wheelScrolling = false;
194 constexpr static qreal m_wheelScrollingDuration = 400;
195 bool m_filterMouseEvents = false;
196 bool m_keyNavigationEnabled = false;
197 bool m_blockTargetWheel = true;
198 bool m_scrollFlickableTarget = true;
199 constexpr static Qt::KeyboardModifiers m_defaultHorizontalScrollModifiers = Qt::AltModifier;
200 constexpr static Qt::KeyboardModifiers m_defaultPageScrollModifiers =
201 Qt::ControlModifier | Qt::ShiftModifier;
202 Qt::KeyboardModifiers m_pageScrollModifiers = m_defaultPageScrollModifiers;
203 Qt::KeyboardModifiers m_horizontalScrollModifiers = m_defaultHorizontalScrollModifiers;
204 QTimer m_wheelScrollingTimer;
205 KirigamiWheelEvent m_kirigamiWheelEvent;
206
207 QQmlEngine* m_engine = nullptr;
208 bool m_wasTouched = false;
209
210 struct Flickable {
211 QQmlProperty originX, originY;
212 QQmlProperty leftMargin, rightMargin;
213 QQmlProperty topMargin, bottomMargin;
214 QQmlProperty contentX, contentY;
215 QQmlProperty contentHeight, contentWidth;
216 QQmlProperty height, width;
217 QQmlProperty interactive;
218 } m_flickable;
219
220 struct ScrollBar {
221 QQmlProperty scrollBar;
222 QQmlProperty stepSize;
223 QMetaMethod increaseMethod;
224 QMetaMethod decreaseMethod;
225 QQuickItem* item = nullptr;
226 bool valid() const { return item != nullptr; };
227 } m_scrollBarV, m_scrollBarH;
228
229 bool m_useAnimation = false;
230};
231
232} // namespace qml_material
Definition wheel_handler.hpp:32
Handles scrolling for a Flickable and 2 attached ScrollBars.
Definition wheel_handler.hpp:79