Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_pan_action.cpp
Go to the documentation of this file.
1/* This file is part of the KDE project
2 * SPDX-FileCopyrightText: 2012 Arjen Hiemstra <ahiemstra@heimr.nl>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7#include "kis_pan_action.h"
8
9#include <kis_debug.h>
10#include <QMouseEvent>
11#include <QApplication>
12#include <QGesture>
13
14#include <klocalizedstring.h>
15
16#include <KoCanvasController.h>
17
18#include <kis_canvas2.h>
19
20#include "kis_input_manager.h"
21
23{
24public:
25 Private() : panDistance(10) { }
26
27 QPointF averagePoint( QTouchEvent* event, int *outCount = nullptr );
28
29 const int panDistance;
30
31 QPointF lastPosition;
34};
35
37 : KisAbstractInputAction("Pan Canvas")
38 , d(new Private)
39{
40 setName(i18n("Pan Canvas"));
41 setDescription(i18n("The <i>Pan Canvas</i> action pans the canvas."));
42
43 QHash<QString, int> shortcuts;
44 shortcuts.insert(i18n("Pan Mode"), PanModeShortcut);
45 shortcuts.insert(i18n("Pan Left"), PanLeftShortcut);
46 shortcuts.insert(i18n("Pan Right"), PanRightShortcut);
47 shortcuts.insert(i18n("Pan Up"), PanUpShortcut);
48 shortcuts.insert(i18n("Pan Down"), PanDownShortcut);
49 setShortcutIndexes(shortcuts);
50}
51
53{
54 delete d;
55}
56
58{
59 return 5;
60}
61
62void KisPanAction::activate(int shortcut)
63{
64 Q_UNUSED(shortcut);
65 QApplication::setOverrideCursor(Qt::OpenHandCursor);
66}
67
68void KisPanAction::deactivate(int shortcut)
69{
70 Q_UNUSED(shortcut);
71 QApplication::restoreOverrideCursor();
72}
73
74void KisPanAction::begin(int shortcut, QEvent *event)
75{
76 KisAbstractInputAction::begin(shortcut, event);
77
78 bool overrideCursor = true;
79
80 switch (shortcut) {
81 case PanModeShortcut: {
82 QTouchEvent *tevent = dynamic_cast<QTouchEvent*>(event);
83 if (tevent) {
85 break;
86 }
87
88 // Some QT wheel events are actually be touch pad pan events. From the QT docs:
89 // "Wheel events are generated for both mouse wheels and trackpad scroll gestures."
90 QWheelEvent *wheelEvent = dynamic_cast<QWheelEvent*>(event);
91 if (wheelEvent) {
92 inputManager()->canvas()->canvasController()->pan(-wheelEvent->pixelDelta());
93 overrideCursor = false;
94 break;
95 }
96
98
99 break;
100 }
101 case PanLeftShortcut:
102 inputManager()->canvas()->canvasController()->pan(QPoint(d->panDistance, 0));
103 break;
104 case PanRightShortcut:
105 inputManager()->canvas()->canvasController()->pan(QPoint(-d->panDistance, 0));
106 break;
107 case PanUpShortcut:
108 inputManager()->canvas()->canvasController()->pan(QPoint(0, d->panDistance));
109 break;
110 case PanDownShortcut:
111 inputManager()->canvas()->canvasController()->pan(QPoint(0, -d->panDistance));
112 break;
113 }
114
115 if (overrideCursor) {
116 QApplication::setOverrideCursor(Qt::ClosedHandCursor);
117 }
118}
119
120void KisPanAction::end(QEvent *event)
121{
122 QApplication::restoreOverrideCursor();
124}
125
126void KisPanAction::inputEvent(QEvent *event)
127{
128 switch (event->type()) {
129 case QEvent::Gesture: {
130 QGestureEvent *gevent = static_cast<QGestureEvent*>(event);
131 if (gevent->activeGestures().at(0)->gestureType() == Qt::PanGesture) {
132 QPanGesture *pan = static_cast<QPanGesture*>(gevent->activeGestures().at(0));
133 inputManager()->canvas()->canvasController()->pan(-pan->delta().toPoint() * 0.2);
134 }
135 return;
136 }
137 case QEvent::TouchUpdate: {
138 QTouchEvent *tevent = static_cast<QTouchEvent*>(event);
139 int newTouchPointsCount;
140 QPointF newPos = d->averagePoint(tevent, &newTouchPointsCount);
141 // When the number of touch points have changed, the average point
142 // of the touch points will produce a huge jump which we don't want
143 // to happen when panning. This can happen when ending a 3-finger
144 // pan gesture. So we only pan the canvas if the number of touch
145 // points have not changed.
146 if (newTouchPointsCount == d->touchPointsCount) {
147 QPointF delta = newPos - d->lastPosition;
148 inputManager()->canvas()->canvasController()->pan(-delta.toPoint());
149 }
150 d->lastPosition = newPos;
151 d->touchPointsCount = newTouchPointsCount;
152 return;
153 }
154 default:
155 break;
156 }
158}
159
160void KisPanAction::cursorMovedAbsolute(const QPointF &startPos, const QPointF &pos)
161{
163}
164
165QPointF KisPanAction::Private::averagePoint( QTouchEvent* event, int *outCount )
166{
167 QPointF result;
168 int count = 0;
169
170 Q_FOREACH ( QTouchEvent::TouchPoint point, event->touchPoints() ) {
171 if( point.state() != Qt::TouchPointReleased ) {
172 result += point.screenPos();
173 count++;
174 }
175 }
176
177 if (outCount) {
178 *outCount = count;
179 }
180
181 if( count > 0 ) {
182 return result / count;
183 } else {
184 return QPointF();
185 }
186}
187
188bool KisPanAction::isShortcutRequired(int shortcut) const
189{
190 return shortcut == PanModeShortcut;
191}
192
194{
195 Q_UNUSED(shortcut);
197}
198
200{
201 Q_UNUSED(shortcut);
202 return true;
203}
KisInputActionGroup
@ ViewTransformActionGroup
Abstract base class for input actions.
virtual void inputEvent(QEvent *event)
static KisInputManager * inputManager
void setShortcutIndexes(const QHash< QString, int > &indexes)
void setName(const QString &name)
virtual void end(QEvent *event)
void setDescription(const QString &description)
virtual void begin(int shortcut, QEvent *event)
KisCanvas2 * canvas() const
QPointF averagePoint(QTouchEvent *event, int *outCount=nullptr)
void inputEvent(QEvent *event) override
void end(QEvent *event) override
void cursorMovedAbsolute(const QPointF &lastPos, const QPointF &pos) override
~KisPanAction() override
bool isShortcutRequired(int shortcut) const override
void activate(int shortcut) override
void begin(int shortcut, QEvent *event) override
bool supportsHiResInputEvents(int shortcut) const override
KisInputActionGroup inputActionGroup(int shortcut) const override
int priority() const override
Private *const d
@ PanRightShortcut
Pan right by a fixed amount.
@ PanModeShortcut
Toggle the pan mode.
@ PanUpShortcut
Pan up by a fixed amount.
@ PanDownShortcut
Pan down by a fixed amount.
@ PanLeftShortcut
Pan left by a fixed amount.
void deactivate(int shortcut) override
KoCanvasController * canvasController() const
virtual QPointF preferredCenter() const =0
Returns the currently set preferred center point in view coordinates (pixels)
virtual void setPreferredCenter(const QPointF &viewPoint)=0
virtual void pan(const QPoint &distance)=0