Krita Source Code Documentation
Loading...
Searching...
No Matches
KisCanvasNavigationActionStrategyTouch Class Reference

#include <KisCanvasNavigationActionStrategyTouch.h>

+ Inheritance diagram for KisCanvasNavigationActionStrategyTouch:

Public Member Functions

void inputEvent (QEvent *event) override
 
 KisCanvasNavigationActionStrategyTouch (Flags flags, const QTouchEvent *startEvent, KisCanvas2 *canvas)
 
bool supportsEvent (QEvent *event) const override
 
- Public Member Functions inherited from KisCanvasNavigationActionStrategy
Flags flags () const
 
 KisCanvasNavigationActionStrategy (const Flags &flags)
 
virtual ~KisCanvasNavigationActionStrategy ()=default
 

Private Attributes

KoViewTransformStillPoint m_actionStillPoint
 
KisCanvas2 * m_canvas
 
qreal m_lastDistance {0.0}
 
qreal m_nonRoundedZoom {0.0}
 
SnappedRotationData m_rotationData
 

Additional Inherited Members

- Public Types inherited from KisCanvasNavigationActionStrategy
enum  Flag {
  None = 0x0 , PanEnabled = 0x1 , ZoomEnabled = 0x2 , RotationEnabled = 0x4 ,
  ZoomDescrete = 0x8 , RotationDescrete = 0x10
}
 
- Static Public Member Functions inherited from KisCanvasNavigationActionStrategy
static qreal canvasRotationAngleContinuous (qreal currentRotationOffset, qreal currectCanvasRotation, SnappedRotationData &data)
 
static qreal canvasRotationAngleDescrete (qreal currentRotationOffset, SnappedRotationData &data)
 

Detailed Description

Definition at line 20 of file KisCanvasNavigationActionStrategyTouch.h.

Constructor & Destructor Documentation

◆ KisCanvasNavigationActionStrategyTouch()

KisCanvasNavigationActionStrategyTouch::KisCanvasNavigationActionStrategyTouch ( Flags flags,
const QTouchEvent * startEvent,
KisCanvas2 * canvas )

Definition at line 70 of file KisCanvasNavigationActionStrategyTouch.cpp.

74 , m_canvas(canvas)
75{
77 calculateBasePointFromEvent(startEvent));
78 m_nonRoundedZoom = canvas->viewConverter()->zoom();
79}
KisCoordinatesConverter * coordinatesConverter
const KoViewConverter * viewConverter() const override
KoViewTransformStillPoint makeWidgetStillPoint(const QPointF &viewPoint) const override
Creates a still point that links the viewPoint of the widget to the corresponding point of the image.
virtual void zoom(qreal *zoomX, qreal *zoomY) const

References KisCanvas2::coordinatesConverter, m_actionStillPoint, m_nonRoundedZoom, KisCoordinatesConverter::makeWidgetStillPoint(), KisCanvas2::viewConverter(), and KoViewConverter::zoom().

Member Function Documentation

◆ inputEvent()

void KisCanvasNavigationActionStrategyTouch::inputEvent ( QEvent * event)
overridevirtual

Zoom and Rotate actions will perform pan as part of the post-action recentering stage, so we should track if we really need to perform a separate pan action.

Implements KisCanvasNavigationActionStrategy.

Definition at line 87 of file KisCanvasNavigationActionStrategyTouch.cpp.

88{
89 if (event->type() != QEvent::TouchUpdate) return;
90
91 QTouchEvent *tevent = dynamic_cast<QTouchEvent *>(event);
92
93#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
94 auto points = tevent->touchPoints();
95#else
96 auto points = tevent->points();
97#endif
98
99 auto point0_it = std::find_if(points.begin(), points.end(), &testIfPointPressed);
100 if (point0_it == points.end())
101 return;
102
103 auto point1_it = std::find_if(std::next(point0_it), points.end(), &testIfPointPressed);
104 if (point1_it == points.end()) {
105 if (flags() & (ZoomEnabled | RotationEnabled)) {
106 return;
107 } else {
108 // we are doing pan-only, this action can be connected to
109 // a single-finger gesture
110 point1_it = point0_it;
111 }
112 }
113
114#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
115 const QPointF p0 = point0_it->pos();
116 const QPointF p1 = point1_it->pos();
117#else
118 const QPointF p0 = point0_it->position();
119 const QPointF p1 = point1_it->position();
120#endif
121
122 const QPointF slope = p1 - p0;
123
124 KisCanvasController *controller = static_cast<KisCanvasController *>(m_canvas->canvasController());
125
127
133 bool needsSeparatePanAction = true;
134
135 if (flags().testFlag(PanEnabled)) {
136 adjustedStillPoint.second = calculateBasePointFromEvent(tevent);
137 }
138
139 if (flags().testFlag(ZoomEnabled)) {
140 const qreal dist = KisAlgebra2D::norm(slope);
141
142 qreal scaleDelta = qFuzzyIsNull(m_lastDistance) ? 1.0 : dist / m_lastDistance;
143
144 // Make sure none of the TouchPoints are too close together, which
145 // throws off the zoom calculations. This also addresses a glitch
146 // where a newly pressed TouchPoint can incorrectly report another
147 // existing TouchPoint's coordinates instead of its own.
148
149 if (dist < 10) {
150 scaleDelta = 1.0;
151 }
152
153 // Workaround: only apply the zoom delta if it's not too
154 // outlandish. TouchPoint coordinates are not always 100% reliable.
155
156 if (qAbs(scaleDelta) < 0.8 || qAbs(scaleDelta) > 1.2) {
157 // just skip the current zoom step
158 scaleDelta = 1.0;
159 }
160
161 const qreal newNonRoundedZoom = m_nonRoundedZoom * scaleDelta;
162
163 if (flags().testFlag(ZoomDescrete)) {
165 if (scaleDelta > 1.0) {
166 const qreal nextExpectedZoom =
167 converter->findNextZoom(converter->zoom(), converter->standardZoomLevels());
168 if (newNonRoundedZoom >= nextExpectedZoom) {
169 controller->setZoom(KoZoomMode::ZOOM_CONSTANT, nextExpectedZoom, adjustedStillPoint);
170 needsSeparatePanAction = false;
171 }
172 } else if (scaleDelta < 1.0) {
173 const qreal prevExpectedZoom =
174 converter->findPrevZoom(converter->zoom(), converter->standardZoomLevels());
175 if (newNonRoundedZoom <= prevExpectedZoom) {
176 controller->setZoom(KoZoomMode::ZOOM_CONSTANT, prevExpectedZoom, adjustedStillPoint);
177 needsSeparatePanAction = false;
178 }
179 }
180
181 } else {
182 controller->setZoom(KoZoomMode::ZOOM_CONSTANT, newNonRoundedZoom, adjustedStillPoint);
183 needsSeparatePanAction = false;
184 }
185
186 m_lastDistance = dist;
187 m_nonRoundedZoom = newNonRoundedZoom;
188 }
189
190 if (flags().testFlag(RotationEnabled)) {
191 const qreal currentAngle = std::atan2(slope.y(), slope.x());
192 qreal rotationAngle = 0.0;
193
194 if (flags().testFlag(RotationDescrete)) {
195 rotationAngle = canvasRotationAngleDescrete(currentAngle, m_rotationData);
196 } else {
197 KisCanvasController *controller = static_cast<KisCanvasController *>(m_canvas->canvasController());
198 rotationAngle = canvasRotationAngleContinuous(currentAngle, controller->rotation(), m_rotationData);
199 }
200
201 if (!qFuzzyIsNull(rotationAngle)) {
202 controller->rotateCanvas(rotationAngle, adjustedStillPoint);
203 needsSeparatePanAction = false;
204 }
205 }
206
207 if (needsSeparatePanAction) {
209 const QPointF currentStillPointViewPosition = converter->documentToWidget(m_actionStillPoint.docPoint());
210 const QPoint canvasOffset((adjustedStillPoint.viewPoint() - currentStillPointViewPosition).toPoint());
211 controller->pan(-canvasOffset);
212 }
213}
QPointF p0
QPointF p1
void rotateCanvas(qreal angle, const std::optional< KoViewTransformStillPoint > &stillPoint, bool isNativeGesture=false)
static qreal canvasRotationAngleContinuous(qreal currentRotationOffset, qreal currectCanvasRotation, SnappedRotationData &data)
static qreal canvasRotationAngleDescrete(qreal currentRotationOffset, SnappedRotationData &data)
static qreal findNextZoom(qreal currentZoom, const QVector< qreal > &zoomLevels)
_Private::Traits< T >::Result documentToWidget(const T &obj) const
QVector< qreal > standardZoomLevels() const
static qreal findPrevZoom(qreal currentZoom, const QVector< qreal > &zoomLevels)
KoCanvasController * canvasController() const
void pan(const QPoint &distance) override
void setZoom(KoZoomMode::Mode mode, qreal zoom) override
void zoom(qreal *zoomX, qreal *zoomY) const override
@ ZOOM_CONSTANT
zoom x %
Definition KoZoomMode.h:24
static bool qFuzzyIsNull(half h)
qreal norm(const T &a)

References KoCanvasBase::canvasController(), KisCanvasNavigationActionStrategy::canvasRotationAngleContinuous(), KisCanvasNavigationActionStrategy::canvasRotationAngleDescrete(), KisCanvas2::coordinatesConverter, KoViewTransformStillPoint::docPoint(), KisCoordinatesConverter::documentToWidget(), KisCoordinatesConverter::findNextZoom(), KisCoordinatesConverter::findPrevZoom(), KisCanvasNavigationActionStrategy::flags(), m_actionStillPoint, m_canvas, m_lastDistance, m_nonRoundedZoom, m_rotationData, KisAlgebra2D::norm(), p0, p1, KoCanvasControllerWidget::pan(), KisCanvasNavigationActionStrategy::PanEnabled, qFuzzyIsNull(), KisCanvasController::rotateCanvas(), KisCanvasController::rotation(), KisCanvasNavigationActionStrategy::RotationDescrete, KisCanvasNavigationActionStrategy::RotationEnabled, KoCanvasControllerWidget::setZoom(), KisCoordinatesConverter::standardZoomLevels(), KoViewTransformStillPoint::viewPoint(), KoZoomHandler::zoom(), KoZoomMode::ZOOM_CONSTANT, KisCanvasNavigationActionStrategy::ZoomDescrete, and KisCanvasNavigationActionStrategy::ZoomEnabled.

◆ supportsEvent()

bool KisCanvasNavigationActionStrategyTouch::supportsEvent ( QEvent * event) const
overridevirtual

Implements KisCanvasNavigationActionStrategy.

Definition at line 81 of file KisCanvasNavigationActionStrategyTouch.cpp.

82{
83 return event->type() == QEvent::TouchBegin || event->type() == QEvent::TouchUpdate
84 || event->type() == QEvent::TouchEnd;
85}

Member Data Documentation

◆ m_actionStillPoint

KoViewTransformStillPoint KisCanvasNavigationActionStrategyTouch::m_actionStillPoint
private

Definition at line 32 of file KisCanvasNavigationActionStrategyTouch.h.

◆ m_canvas

KisCanvas2* KisCanvasNavigationActionStrategyTouch::m_canvas
private

Definition at line 29 of file KisCanvasNavigationActionStrategyTouch.h.

◆ m_lastDistance

qreal KisCanvasNavigationActionStrategyTouch::m_lastDistance {0.0}
private

Definition at line 35 of file KisCanvasNavigationActionStrategyTouch.h.

35{0.0};

◆ m_nonRoundedZoom

qreal KisCanvasNavigationActionStrategyTouch::m_nonRoundedZoom {0.0}
private

Definition at line 31 of file KisCanvasNavigationActionStrategyTouch.h.

31{0.0};

◆ m_rotationData

SnappedRotationData KisCanvasNavigationActionStrategyTouch::m_rotationData
private

Definition at line 34 of file KisCanvasNavigationActionStrategyTouch.h.


The documentation for this class was generated from the following files: