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

Zoom Canvas implementation of KisAbstractInputAction. More...

#include <kis_zoom_action.h>

+ Inheritance diagram for KisZoomAction:

Classes

class  Private
 

Public Types

enum  Shortcuts {
  ZoomModeShortcut , DiscreteZoomModeShortcut , ZoomInShortcut , ZoomOutShortcut ,
  Zoom100PctShortcut , FitToViewShortcut , FitToWidthShortcut , RelativeZoomModeShortcut ,
  RelativeDiscreteZoomModeShortcut , FitToHeightShortcut , ZoomInToCursorShortcut , ZoomOutFromCursorShortcut
}
 

Public Member Functions

void activate (int shortcut) override
 
void begin (int shortcut, QEvent *event=0) override
 
void cursorMovedAbsolute (const QPointF &startPos, const QPointF &pos) override
 
void deactivate (int shortcut) override
 
KisInputActionGroup inputActionGroup (int shortcut) const override
 
void inputEvent (QEvent *event) override
 
bool isShortcutRequired (int shortcut) const override
 
 KisZoomAction ()
 
int priority () const override
 
bool supportsHiResInputEvents (int shortcut) const override
 
 ~KisZoomAction () override
 
- Public Member Functions inherited from KisAbstractInputAction
virtual bool canIgnoreModifiers () const
 
virtual QString description () const
 
virtual void end (QEvent *event)
 
virtual QString id () const
 
virtual bool isAvailable () const
 
 KisAbstractInputAction (const QString &id)
 
virtual QString name () const
 
virtual QHash< QString, int > shortcutIndexes () const
 
virtual ~KisAbstractInputAction ()
 

Private Attributes

Private *const d {nullptr}
 

Additional Inherited Members

- Public Attributes inherited from KisAbstractInputAction
QString description
 
QString id
 
QHash< QString, int > indexes
 
QPointF lastCursorPosition
 
QString name
 
QPointF startCursorPosition
 
- Static Public Attributes inherited from KisAbstractInputAction
static KisInputManagerinputManager
 
- Protected Member Functions inherited from KisAbstractInputAction
virtual void cursorMoved (const QPointF &lastPos, const QPointF &pos)
 
QPoint eventPos (const QEvent *event)
 
QPointF eventPosF (const QEvent *event)
 
KisInputManagerinputManager () const
 
void setDescription (const QString &description)
 
void setName (const QString &name)
 
void setShortcutIndexes (const QHash< QString, int > &indexes)
 

Detailed Description

Zoom Canvas implementation of KisAbstractInputAction.

The Zoom Canvas action zooms the canvas.

Definition at line 17 of file kis_zoom_action.h.

Member Enumeration Documentation

◆ Shortcuts

The different behaviours for this action.

Enumerator
ZoomModeShortcut 

Toggle zoom mode.

DiscreteZoomModeShortcut 

Toggle discrete zoom mode.

ZoomInShortcut 

Zoom in by a fixed amount.

ZoomOutShortcut 

Zoom out by a fixed amount.

Zoom100PctShortcut 

Reset zoom to 100%.

FitToViewShortcut 

Zoom fit to page.

FitToWidthShortcut 

Zoom fit to width.

RelativeZoomModeShortcut 

Toggle zoom mode relative to cursor.

RelativeDiscreteZoomModeShortcut 

Toggle discrete zoom mode relative to cursor.

FitToHeightShortcut 

Zoom fit to height.

ZoomInToCursorShortcut 

Zoom in to cursor.

ZoomOutFromCursorShortcut 

Zoom out from cursor.

Definition at line 23 of file kis_zoom_action.h.

23 {
36 };
@ FitToHeightShortcut
Zoom fit to height.
@ ZoomInShortcut
Zoom in by a fixed amount.
@ RelativeDiscreteZoomModeShortcut
Toggle discrete zoom mode relative to cursor.
@ ZoomOutFromCursorShortcut
Zoom out from cursor.
@ ZoomInToCursorShortcut
Zoom in to cursor.
@ ZoomOutShortcut
Zoom out by a fixed amount.
@ DiscreteZoomModeShortcut
Toggle discrete zoom mode.
@ FitToViewShortcut
Zoom fit to page.
@ ZoomModeShortcut
Toggle zoom mode.
@ Zoom100PctShortcut
Reset zoom to 100%.
@ RelativeZoomModeShortcut
Toggle zoom mode relative to cursor.
@ FitToWidthShortcut
Zoom fit to width.

Constructor & Destructor Documentation

◆ KisZoomAction()

KisZoomAction::KisZoomAction ( )
explicit

Definition at line 64 of file kis_zoom_action.cpp.

65 : KisAbstractInputAction("Zoom Canvas")
66 , d(new Private(this))
67{
68 setName(i18n("Zoom Canvas"));
69 setDescription(i18n("The <i>Zoom Canvas</i> action zooms the canvas."));
70
71 QHash< QString, int > shortcuts;
72 shortcuts.insert(i18n("Zoom Mode"), ZoomModeShortcut);
73 shortcuts.insert(i18n("Discrete Zoom Mode"), DiscreteZoomModeShortcut);
74 shortcuts.insert(i18n("Relative Zoom Mode"), RelativeZoomModeShortcut);
75 shortcuts.insert(i18n("Relative Discrete Zoom Mode"), RelativeDiscreteZoomModeShortcut);
76 shortcuts.insert(i18n("Zoom In"), ZoomInShortcut);
77 shortcuts.insert(i18n("Zoom Out"), ZoomOutShortcut);
78 shortcuts.insert(i18n("Zoom In To Cursor"), ZoomInToCursorShortcut);
79 shortcuts.insert(i18n("Zoom Out From Cursor"), ZoomOutFromCursorShortcut);
80 shortcuts.insert(i18n("Zoom to 100%"), Zoom100PctShortcut);
81 shortcuts.insert(i18n("Fit to View"), FitToViewShortcut);
82 shortcuts.insert(i18n("Fit to View Width"), FitToWidthShortcut);
83 shortcuts.insert(i18n("Fit to View Height"), FitToHeightShortcut);
84 setShortcutIndexes(shortcuts);
85}
KisAbstractInputAction(const QString &id)
void setShortcutIndexes(const QHash< QString, int > &indexes)
void setName(const QString &name)
void setDescription(const QString &description)
Private *const d

References DiscreteZoomModeShortcut, FitToHeightShortcut, FitToViewShortcut, FitToWidthShortcut, RelativeDiscreteZoomModeShortcut, RelativeZoomModeShortcut, KisAbstractInputAction::setDescription(), KisAbstractInputAction::setName(), KisAbstractInputAction::setShortcutIndexes(), Zoom100PctShortcut, ZoomInShortcut, ZoomInToCursorShortcut, ZoomModeShortcut, ZoomOutFromCursorShortcut, and ZoomOutShortcut.

◆ ~KisZoomAction()

KisZoomAction::~KisZoomAction ( )
override

Definition at line 87 of file kis_zoom_action.cpp.

88{
89 delete d;
90}

References d.

Member Function Documentation

◆ activate()

void KisZoomAction::activate ( int shortcut)
overridevirtual

The method is called when the action is yet to be started, that is, e.g. the user has pressed all the modifiers for the action but hasn't started painting yet. This method is a right place to show the user what is going to happen, e.g. change the cursor.

Reimplemented from KisAbstractInputAction.

Definition at line 97 of file kis_zoom_action.cpp.

98{
99 if (shortcut == DiscreteZoomModeShortcut ||
101 QApplication::setOverrideCursor(KisCursor::zoomDiscreteCursor());
102 } else /* if (shortcut == SmoothZoomModeShortcut) */ {
103 QApplication::setOverrideCursor(KisCursor::zoomSmoothCursor());
104 }
105}
static QCursor zoomSmoothCursor()
static QCursor zoomDiscreteCursor()

References DiscreteZoomModeShortcut, RelativeDiscreteZoomModeShortcut, KisCursor::zoomDiscreteCursor(), and KisCursor::zoomSmoothCursor().

◆ begin()

void KisZoomAction::begin ( int shortcut,
QEvent * event = 0 )
overridevirtual

Begin the action.

Parameters
shortcutThe index of the behaviour to trigger.
eventThe mouse event that has triggered this action. Is null for keyboard-activated actions.

Reimplemented from KisAbstractInputAction.

Definition at line 113 of file kis_zoom_action.cpp.

114{
115 KisAbstractInputAction::begin(shortcut, event);
116
117 d->lastDistance = 0.f;
118
119 switch(shortcut) {
120 case ZoomModeShortcut:
123 d->mode = (Shortcuts)shortcut;
124 d->lastPosition = QPoint();
126 break;
127 }
132 d->mode = (Shortcuts)shortcut;
134 break;
135 case ZoomInShortcut:
136 case ZoomOutShortcut:
139 KoCanvasControllerWidget *controller =
142
143 QPoint pt;
144 if (shortcut == ZoomInToCursorShortcut || shortcut == ZoomOutFromCursorShortcut) {
145 pt = eventPos(event);
146 if (pt.isNull()) {
147 pt = controller->mapFromGlobal(QCursor::pos());
148 }
149 }
150
151 if (shortcut == ZoomInToCursorShortcut || shortcut == ZoomInShortcut) {
152 if (pt.isNull()) {
153 controller->zoomIn();
154 } else {
155 controller->zoomIn(inputManager()->canvas()->coordinatesConverter()->makeWidgetStillPoint(pt));
156 }
157 } else {
158 if (pt.isNull()) {
159 controller->zoomOut();
160 } else {
161 controller->zoomOut(inputManager()->canvas()->coordinatesConverter()->makeWidgetStillPoint(pt));
162 }
163 }
164 break;
165 }
166 case Zoom100PctShortcut: {
167 KoCanvasControllerWidget *controller =
169 controller->setZoom(KoZoomMode::ZOOM_CONSTANT, 1.0);
170 break;
171 }
172 case FitToViewShortcut: {
173 KoCanvasControllerWidget *controller =
175 controller->setZoom(KoZoomMode::ZOOM_PAGE, 1.0);
176 break;
177 }
178 case FitToWidthShortcut: {
179 KoCanvasControllerWidget *controller =
181 controller->setZoom(KoZoomMode::ZOOM_WIDTH, 1.0);
182 break;
183 }
184 case FitToHeightShortcut: {
185 KoCanvasControllerWidget *controller =
187 controller->setZoom(KoZoomMode::ZOOM_HEIGHT, 1.0);
188 break;
189 }
190 }
191}
static KisInputManager * inputManager
QPoint eventPos(const QEvent *event)
QPointF eventPosF(const QEvent *event)
virtual void begin(int shortcut, QEvent *event)
KisCoordinatesConverter * coordinatesConverter
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.
KisCanvas2 * canvas() const
KoViewTransformStillPoint actionStillPoint
KoCanvasController * canvasController() const
void setZoom(KoZoomMode::Mode mode, qreal zoom) override
virtual void zoomIn(const KoViewTransformStillPoint &stillPoint)=0
zooms in keeping stillPoint not moved.
virtual void zoomOut(const KoViewTransformStillPoint &stillPoint)=0
zooms out keeping stillPoint not moved.
void zoom(qreal *zoomX, qreal *zoomY) const override
@ ZOOM_CONSTANT
zoom x %
Definition KoZoomMode.h:24
@ ZOOM_PAGE
zoom page
Definition KoZoomMode.h:25
@ ZOOM_WIDTH
zoom pagewidth
Definition KoZoomMode.h:26
@ ZOOM_HEIGHT
zoom pageheight
Definition KoZoomMode.h:27
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
KisCanvas2 * canvas

References KisZoomAction::Private::actionStillPoint, KisAbstractInputAction::begin(), Private::canvas, KisInputManager::canvas(), KoCanvasBase::canvasController(), KisCanvas2::coordinatesConverter, d, DiscreteZoomModeShortcut, KisAbstractInputAction::eventPos(), KisAbstractInputAction::eventPosF(), FitToHeightShortcut, FitToViewShortcut, FitToWidthShortcut, KisAbstractInputAction::inputManager, KIS_SAFE_ASSERT_RECOVER_RETURN, KisZoomAction::Private::lastDiscreteZoomDistance, KisZoomAction::Private::lastDistance, KisZoomAction::Private::lastPosition, KisCoordinatesConverter::makeWidgetStillPoint(), KisZoomAction::Private::mode, RelativeDiscreteZoomModeShortcut, RelativeZoomModeShortcut, KoCanvasControllerWidget::setZoom(), KisZoomAction::Private::startZoom, KoZoomHandler::zoom(), Zoom100PctShortcut, KoZoomMode::ZOOM_CONSTANT, KoZoomMode::ZOOM_HEIGHT, KoZoomMode::ZOOM_PAGE, KoZoomMode::ZOOM_WIDTH, KoCanvasController::zoomIn(), ZoomInShortcut, ZoomInToCursorShortcut, ZoomModeShortcut, KoCanvasController::zoomOut(), ZoomOutFromCursorShortcut, and ZoomOutShortcut.

◆ cursorMovedAbsolute()

void KisZoomAction::cursorMovedAbsolute ( const QPointF & startPos,
const QPointF & pos )
overridevirtual

Reimplemented from KisAbstractInputAction.

Definition at line 293 of file kis_zoom_action.cpp.

294{
295 QPointF diff = -(pos - startPos);
296
297 const int stepCont = 100;
298 const int stepDisc = 50;
299
300 if (d->mode == ZoomModeShortcut ||
302
303 KisConfig cfg(true);
304
305 const qreal logDistance = std::pow(2.0, qreal(cfg.zoomHorizontal() ? -diff.x() : diff.y()) / qreal(stepCont));
306
307 qreal newZoom = 1.0;
308 if (cfg.readEntry<bool>("InvertMiddleClickZoom", false)) {
309 newZoom = d->startZoom / logDistance;
310 } else {
311 newZoom = d->startZoom * logDistance;
312 }
313
314 KoCanvasControllerWidget *controller =
317
318 if (d->mode == ZoomModeShortcut) {
319 controller->setZoom(KoZoomMode::ZOOM_CONSTANT, newZoom);
320 } else {
321 controller->setZoom(KoZoomMode::ZOOM_CONSTANT, newZoom, d->actionStillPoint);
322 }
323
324 } else if (d->mode == DiscreteZoomModeShortcut ||
326
327 KoCanvasControllerWidget *controller =
330
331 KisConfig cfg(true);
332
333 qreal axisDiff = qreal(cfg.zoomHorizontal() ? -diff.x() : diff.y());
334 qreal currentDiff = axisDiff / stepDisc - d->lastDiscreteZoomDistance;
335
336 const bool zoomIn = currentDiff > 0;
337 while (qAbs(currentDiff) > 1.0) {
338 if (zoomIn) {
340 controller->zoomIn(d->actionStillPoint);
341 } else {
342 controller->zoomIn();
343 }
344 } else {
346 controller->zoomOut(d->actionStillPoint);
347 } else {
348 controller->zoomOut();
349 }
350 }
351 d->lastDiscreteZoomDistance += zoomIn ? 1.0 : -1.0;
352 currentDiff = axisDiff / stepDisc - d->lastDiscreteZoomDistance;
353 }
354 }
355}
QAction * zoomIn(const QObject *recvr, const char *slot, QObject *parent)

References KisZoomAction::Private::actionStillPoint, KisInputManager::canvas(), KoCanvasBase::canvasController(), d, DiscreteZoomModeShortcut, KisAbstractInputAction::inputManager, KIS_SAFE_ASSERT_RECOVER_RETURN, KisZoomAction::Private::lastDiscreteZoomDistance, KisZoomAction::Private::mode, KisConfig::readEntry(), RelativeDiscreteZoomModeShortcut, RelativeZoomModeShortcut, KoCanvasControllerWidget::setZoom(), KisZoomAction::Private::startZoom, KoZoomMode::ZOOM_CONSTANT, KisConfig::zoomHorizontal(), KoCanvasController::zoomIn(), ZoomModeShortcut, and KoCanvasController::zoomOut().

◆ deactivate()

void KisZoomAction::deactivate ( int shortcut)
overridevirtual

The method is called when the action is not a candidate for the starting anymore. The action should revert everything that was done in activate() method.

See also
activate()

Reimplemented from KisAbstractInputAction.

Definition at line 107 of file kis_zoom_action.cpp.

108{
109 Q_UNUSED(shortcut);
110 QApplication::restoreOverrideCursor();
111}

◆ inputActionGroup()

KisInputActionGroup KisZoomAction::inputActionGroup ( int shortcut) const
overridevirtual
Returns
the group of the action the specified shortcut belongs to

Reimplemented from KisAbstractInputAction.

Definition at line 368 of file kis_zoom_action.cpp.

369{
370 Q_UNUSED(shortcut);
372}
@ ViewTransformActionGroup

References ViewTransformActionGroup.

◆ inputEvent()

void KisZoomAction::inputEvent ( QEvent * event)
overridevirtual

Process an input event.

By default handles MouseMove events and passes the data to a convenience cursorMoved() method

Parameters
eventAn event to process.

Reimplemented from KisAbstractInputAction.

Definition at line 193 of file kis_zoom_action.cpp.

194{
195 switch (event->type()) {
196 case QEvent::TouchUpdate: {
197 QTouchEvent *tevent = static_cast<QTouchEvent*>(event);
198
199 if (tevent->touchPoints().count() != 2) {
200 // Sanity check. The input state machine should only invoke
201 // this action if there are 2 TouchPoints in the event.
202 return;
203 }
204
205 // First, let's determine if we want to handle this event. Sadly
206 // the coordinates of TouchPoints reported by Qt are not always
207 // dependable. TouchPoints that are just getting released can be
208 // off by a significant amount. So we stop the zoom as soon as the
209 // user lifts a finger.
210
211 QTouchEvent::TouchPoint tp0 = tevent->touchPoints().at(0);
212 QTouchEvent::TouchPoint tp1 = tevent->touchPoints().at(1);
213 if (tp0.state() == Qt::TouchPointReleased ||
214 tp1.state() == Qt::TouchPointReleased) {
215 // Force a recomputation of the position on the next event.
216 d->lastPosition = QPoint();
217 return;
218 }
219
220 QPointF p0 = tp0.pos();
221 QPointF p1 = tp1.pos();
222
223 // Make sure none of the TouchPoints are too close together, which
224 // throws off the zoom calculations. This also addresses a glitch
225 // where a newly pressed TouchPoint can incorrectly report another
226 // existing TouchPoint's coordinates instead of its own.
227
228 if ((p0-p1).manhattanLength() < 10) {
229 d->lastPosition = QPointF();
230 return;
231 }
232
233 // If this is the first valid set of points that we are getting,
234 // then use that as the reference for the zoom.
235
236 if (d->lastPosition.isNull()) {
237 d->lastPosition = p0;
238 d->lastDistance = 0;
239 return;
240 }
241
242 float dist = QLineF(p0, p1).length();
243 float delta = qFuzzyCompare(1.0f, 1.0f + d->lastDistance) ? 1.f : dist / d->lastDistance;
244
245 // Workaround: only apply the zoom delta if it's not too
246 // outlandish. As explained above, TouchPoint coordinates are not
247 // always 100% reliable.
248
249 if(qAbs(delta) < 0.8f || qAbs(delta) > 1.2f) {
250 // TouchPoint coordinates tend to converge toward correct
251 // values over time, so assume that the new position is
252 // likelier to be correct than the last and use that as the new
253 // reference.
254 d->lastPosition = p0;
255 return;
256 }
257
258 KisCanvasController *controller = static_cast<KisCanvasController *>(inputManager()->canvas()->canvasController());
259 const qreal newZoom = controller->canvas()->viewConverter()->zoom() * delta;
260 KoViewTransformStillPoint adjustedStillPoint = d->actionStillPoint;
261 adjustedStillPoint.second = p0;
262 controller->setZoom(KoZoomMode::ZOOM_CONSTANT, newZoom, adjustedStillPoint);
263 d->lastDistance = dist;
264 d->lastPosition = p0;
265 return; // Don't try to update the cursor during a pinch-zoom
266 }
267 case QEvent::NativeGesture: {
268 QNativeGestureEvent *gevent = static_cast<QNativeGestureEvent*>(event);
269 if (gevent->gestureType() == Qt::ZoomNativeGesture) {
271 KisCanvasController *controller = static_cast<KisCanvasController*>(canvas->canvasController());
272 const qreal delta = 1.0f + gevent->value();
273 const qreal newZoom = controller->canvas()->viewConverter()->zoom() * delta;
274 controller->setZoom(KoZoomMode::ZOOM_CONSTANT, newZoom, d->actionStillPoint);
275 } else if (gevent->gestureType() == Qt::SmartZoomNativeGesture) {
278
279 if (controller->zoomState().mode != KoZoomMode::ZOOM_WIDTH) {
280 controller->setZoom(KoZoomMode::ZOOM_WIDTH, 1.0);
281 } else {
282 controller->setZoom(KoZoomMode::ZOOM_CONSTANT, 1.0);
283 }
284 }
285 return;
286 }
287 default:
288 break;
289 }
291}
QPointF p0
QPointF p1
virtual void inputEvent(QEvent *event)
QPointer< KoCanvasBase > canvas
virtual KoZoomState zoomState() const =0
virtual void setZoom(KoZoomMode::Mode mode, qreal zoom)=0
KoZoomMode::Mode mode
Definition KoZoomState.h:24
static bool qFuzzyCompare(half p1, half p2)

References KisZoomAction::Private::actionStillPoint, Private::canvas, KoCanvasControllerWidget::canvas, KisInputManager::canvas(), KoCanvasBase::canvasController(), d, KisAbstractInputAction::inputEvent(), KisAbstractInputAction::inputManager, KisZoomAction::Private::lastDistance, KisZoomAction::Private::lastPosition, KoZoomState::mode, p0, p1, qFuzzyCompare(), KoCanvasControllerWidget::setZoom(), KoCanvasController::setZoom(), KoZoomMode::ZOOM_CONSTANT, KoZoomMode::ZOOM_WIDTH, and KoCanvasController::zoomState().

◆ isShortcutRequired()

bool KisZoomAction::isShortcutRequired ( int shortcut) const
overridevirtual

Return true when the specified shortcut is required for basic user interaction. This is used by the configuration system to prevent basic actions like painting from being removed.

Parameters
shortcutThe shortcut index to check.
Returns
True if the shortcut is required, false if not.

Reimplemented from KisAbstractInputAction.

Definition at line 357 of file kis_zoom_action.cpp.

358{
359 return shortcut == ZoomModeShortcut;
360}

References ZoomModeShortcut.

◆ priority()

int KisZoomAction::priority ( ) const
overridevirtual

The priority for this action.

Priority determines how "important" the action is and is used to resolve conflicts when multiple actions can be activated.

Reimplemented from KisAbstractInputAction.

Definition at line 92 of file kis_zoom_action.cpp.

93{
94 return 4;
95}

◆ supportsHiResInputEvents()

bool KisZoomAction::supportsHiResInputEvents ( int shortcut) const
overridevirtual

Returns true if the action can handle HiRes flow of move events which is generated by the tablet. If the function returns false, some of the events will be dropped or postponed. For most of the actions in Krita (except of real painting) it is perfectly acceptable, so 'false' is the default value.

Reimplemented from KisAbstractInputAction.

Definition at line 362 of file kis_zoom_action.cpp.

363{
364 Q_UNUSED(shortcut);
365 return true;
366}

Member Data Documentation

◆ d

Private* const KisZoomAction::d {nullptr}
private

Definition at line 56 of file kis_zoom_action.h.

56{nullptr};

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