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

Rotate Canvas implementation of KisAbstractInputAction. More...

#include <kis_rotate_canvas_action.h>

+ Inheritance diagram for KisRotateCanvasAction:

Classes

class  Private
 

Public Types

enum  Shortcut {
  RotateModeShortcut , DiscreteRotateModeShortcut , RotateLeftShortcut , RotateRightShortcut ,
  RotateResetShortcut
}
 

Public Member Functions

void activate (int shortcut) override
 
void begin (int shortcut, QEvent *event) override
 
void cursorMovedAbsolute (const QPointF &startPos, const QPointF &pos) override
 
void deactivate (int shortcut) override
 
void end (QEvent *event) override
 
KisInputActionGroup inputActionGroup (int shortcut) const override
 
void inputEvent (QEvent *event) override
 
 KisRotateCanvasAction ()
 
int priority () const override
 
bool supportsHiResInputEvents (int shortcut) const override
 
 ~KisRotateCanvasAction () override
 
- Public Member Functions inherited from KisAbstractInputAction
virtual bool canIgnoreModifiers () const
 
virtual QString description () const
 
virtual QString id () const
 
virtual bool isAvailable () const
 
virtual bool isShortcutRequired (int shortcut) 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

Rotate Canvas implementation of KisAbstractInputAction.

The Rotate Canvas action rotates the canvas.

Definition at line 18 of file kis_rotate_canvas_action.h.

Member Enumeration Documentation

◆ Shortcut

The different behaviours for this action.

Enumerator
RotateModeShortcut 

Toggle Rotate mode.

DiscreteRotateModeShortcut 

Toggle Discrete Rotate mode.

RotateLeftShortcut 

Rotate left by a fixed amount.

RotateRightShortcut 

Rotate right by a fixed amount.

RotateResetShortcut 

Reset the rotation to 0.

Definition at line 25 of file kis_rotate_canvas_action.h.

25 {
31 };
@ RotateLeftShortcut
Rotate left by a fixed amount.
@ RotateResetShortcut
Reset the rotation to 0.
@ DiscreteRotateModeShortcut
Toggle Discrete Rotate mode.
@ RotateRightShortcut
Rotate right by a fixed amount.
@ RotateModeShortcut
Toggle Rotate mode.

Constructor & Destructor Documentation

◆ KisRotateCanvasAction()

KisRotateCanvasAction::KisRotateCanvasAction ( )
explicit

Definition at line 39 of file kis_rotate_canvas_action.cpp.

40 : KisAbstractInputAction("Rotate Canvas")
41 , d(new Private())
42{
43 setName(i18n("Rotate Canvas"));
44 setDescription(i18n("The <i>Rotate Canvas</i> action rotates the canvas."));
45
46 QHash<QString, int> shortcuts;
47 shortcuts.insert(i18n("Rotate Mode"), RotateModeShortcut);
48 shortcuts.insert(i18n("Discrete Rotate Mode"), DiscreteRotateModeShortcut);
49 shortcuts.insert(i18n("Rotate Left"), RotateLeftShortcut);
50 shortcuts.insert(i18n("Rotate Right"), RotateRightShortcut);
51 shortcuts.insert(i18n("Reset Rotation"), RotateResetShortcut);
52 setShortcutIndexes(shortcuts);
53}
KisAbstractInputAction(const QString &id)
void setShortcutIndexes(const QHash< QString, int > &indexes)
void setName(const QString &name)
void setDescription(const QString &description)

References DiscreteRotateModeShortcut, RotateLeftShortcut, RotateModeShortcut, RotateResetShortcut, RotateRightShortcut, KisAbstractInputAction::setDescription(), KisAbstractInputAction::setName(), and KisAbstractInputAction::setShortcutIndexes().

◆ ~KisRotateCanvasAction()

KisRotateCanvasAction::~KisRotateCanvasAction ( )
override

Definition at line 55 of file kis_rotate_canvas_action.cpp.

56{
57 delete d;
58}

References d.

Member Function Documentation

◆ activate()

void KisRotateCanvasAction::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 65 of file kis_rotate_canvas_action.cpp.

66{
67 if (shortcut == DiscreteRotateModeShortcut) {
68 QApplication::setOverrideCursor(KisCursor::rotateCanvasDiscreteCursor());
69 } else /* if (shortcut == SmoothRotateModeShortcut) */ {
70 QApplication::setOverrideCursor(KisCursor::rotateCanvasSmoothCursor());
71 }
72}
static QCursor rotateCanvasDiscreteCursor()
static QCursor rotateCanvasSmoothCursor()

References DiscreteRotateModeShortcut, KisCursor::rotateCanvasDiscreteCursor(), and KisCursor::rotateCanvasSmoothCursor().

◆ begin()

void KisRotateCanvasAction::begin ( int shortcut,
QEvent * event )
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 80 of file kis_rotate_canvas_action.cpp.

81{
82 KisAbstractInputAction::begin(shortcut, event);
83 d->allowRotation = false;
84 d->previousAngle = 0;
85 d->snapRotation = 0;
86 d->touchRotation = 0;
87
88 KisCanvasController *canvasController =
90 KIS_SAFE_ASSERT_RECOVER_RETURN(canvasController);
91
92 d->mode = (Shortcut)shortcut;
93
94 switch(shortcut) {
97 // If the canvas has been rotated to an angle that is not an exact multiple of DISCRETE_ANGLE_STEP,
98 // we need to adjust the final discrete rotation by that angle difference.
99 // trunc() is used to round the negative numbers towards zero.
100 const qreal startRotation = inputManager()->canvas()->rotationAngle();
101 d->snapRotation = startRotation - std::trunc(startRotation / DISCRETE_ANGLE_STEP) * DISCRETE_ANGLE_STEP;
102 canvasController->beginCanvasRotation();
104 break;
105 }
107 canvasController->rotateCanvasLeft15();
108 break;
110 canvasController->rotateCanvasRight15();
111 break;
113 canvasController->resetCanvasRotation();
114 break;
115 }
116}
static KisInputManager * inputManager
QPointF eventPosF(const QEvent *event)
virtual void begin(int shortcut, QEvent *event)
qreal rotationAngle() const
canvas rotation in degrees
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
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
constexpr qreal DISCRETE_ANGLE_STEP

References KisRotateCanvasAction::Private::actionStillPoint, KisRotateCanvasAction::Private::allowRotation, KisAbstractInputAction::begin(), KisCanvasController::beginCanvasRotation(), KisInputManager::canvas(), KoCanvasBase::canvasController(), KisCanvas2::coordinatesConverter, d, DISCRETE_ANGLE_STEP, DiscreteRotateModeShortcut, KisAbstractInputAction::eventPosF(), KisAbstractInputAction::inputManager, KIS_SAFE_ASSERT_RECOVER_RETURN, KisCoordinatesConverter::makeWidgetStillPoint(), KisRotateCanvasAction::Private::mode, KisRotateCanvasAction::Private::previousAngle, KisCanvasController::resetCanvasRotation(), KisCanvasController::rotateCanvasLeft15(), KisCanvasController::rotateCanvasRight15(), RotateLeftShortcut, RotateModeShortcut, RotateResetShortcut, RotateRightShortcut, KisCanvas2::rotationAngle(), KisRotateCanvasAction::Private::snapRotation, and KisRotateCanvasAction::Private::touchRotation.

◆ cursorMovedAbsolute()

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

Reimplemented from KisAbstractInputAction.

Definition at line 136 of file kis_rotate_canvas_action.cpp.

137{
138 if (d->mode == RotateResetShortcut) {
139 return;
140 }
141
143 const QPointF centerPoint = converter->flakeToWidget(converter->flakeCenterPoint());
144 const QPointF startPoint = startPos - centerPoint;
145 const QPointF newPoint = pos - centerPoint;
146
147 const qreal oldAngle = atan2(startPoint.y(), startPoint.x());
148 const qreal newAngle = atan2(newPoint.y(), newPoint.x());
149
150 qreal newRotation = (180 / M_PI) * (newAngle - oldAngle);
151
153 // Do not snap unless the user rotated half-way in the desired direction.
154 if (qAbs(newRotation) > 0.5 * DISCRETE_ANGLE_STEP || d->allowRotation) {
155 d->allowRotation = true;
156 newRotation = qRound((newRotation + d->snapRotation) / DISCRETE_ANGLE_STEP) * DISCRETE_ANGLE_STEP - d->snapRotation;
157 } else {
158 newRotation = 0.0;
159 }
160 }
161
162 KisCanvasController *canvasController =
164 KIS_SAFE_ASSERT_RECOVER_RETURN(canvasController);
165 canvasController->rotateCanvas(newRotation);
166}
void rotateCanvas(qreal angle, const std::optional< KoViewTransformStillPoint > &stillPoint, bool isNativeGesture=false)
_Private::Traits< T >::Result flakeToWidget(const T &obj) const
#define M_PI
Definition kis_global.h:111
KRITAIMAGE_EXPORT qreal atan2(qreal y, qreal x)
atan2 replacement

References KisRotateCanvasAction::Private::allowRotation, KisInputManager::canvas(), KoCanvasBase::canvasController(), KisCanvas2::coordinatesConverter, d, DISCRETE_ANGLE_STEP, DiscreteRotateModeShortcut, KisCoordinatesConverter::flakeCenterPoint(), KisCoordinatesConverter::flakeToWidget(), KisAbstractInputAction::inputManager, KIS_SAFE_ASSERT_RECOVER_RETURN, M_PI, KisRotateCanvasAction::Private::mode, KisCanvasController::rotateCanvas(), RotateResetShortcut, and KisRotateCanvasAction::Private::snapRotation.

◆ deactivate()

void KisRotateCanvasAction::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 74 of file kis_rotate_canvas_action.cpp.

75{
76 Q_UNUSED(shortcut);
77 QApplication::restoreOverrideCursor();
78}

◆ end()

void KisRotateCanvasAction::end ( QEvent * event)
overridevirtual

End the action.

Parameters
eventThe mouse event that has finished this action. Is null for keyboard-activated actions.

Reimplemented from KisAbstractInputAction.

Definition at line 118 of file kis_rotate_canvas_action.cpp.

119{
120 Q_UNUSED(event);
121
122 KisCanvasController *canvasController =
124 KIS_SAFE_ASSERT_RECOVER_RETURN(canvasController);
125
126 switch(d->mode) {
129 canvasController->endCanvasRotation();
130 break;
131 default:
132 break;
133 }
134}

References KisInputManager::canvas(), KoCanvasBase::canvasController(), d, DiscreteRotateModeShortcut, KisCanvasController::endCanvasRotation(), KisAbstractInputAction::inputManager, KIS_SAFE_ASSERT_RECOVER_RETURN, KisRotateCanvasAction::Private::mode, and RotateModeShortcut.

◆ inputActionGroup()

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

Reimplemented from KisAbstractInputAction.

Definition at line 247 of file kis_rotate_canvas_action.cpp.

248{
249 Q_UNUSED(shortcut);
251}
@ ViewTransformActionGroup

References ViewTransformActionGroup.

◆ inputEvent()

void KisRotateCanvasAction::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 168 of file kis_rotate_canvas_action.cpp.

169{
170 switch (event->type()) {
171 case QEvent::NativeGesture: {
172 QNativeGestureEvent *gevent = static_cast<QNativeGestureEvent*>(event);
174 KisCanvasController *controller = static_cast<KisCanvasController*>(canvas->canvasController());
175
176 const float angle = gevent->value();
177 QPoint widgetPos = canvas->canvasWidget()->mapFromGlobal(gevent->globalPos());
178
179 KoViewTransformStillPoint adjustedStillPoint = d->actionStillPoint;
180 adjustedStillPoint.second = widgetPos;
181
182 controller->rotateCanvas(angle, adjustedStillPoint, true);
183 return;
184 }
185 case QEvent::TouchUpdate: {
186 QTouchEvent *touchEvent = static_cast<QTouchEvent*>(event);
187
188 if (touchEvent->touchPoints().count() != 2)
189 break;
190
191 QTouchEvent::TouchPoint tp0 = touchEvent->touchPoints().at(0);
192 QTouchEvent::TouchPoint tp1 = touchEvent->touchPoints().at(1);
193
194 if (tp0.state() == Qt::TouchPointReleased ||
195 tp1.state() == Qt::TouchPointReleased)
196 {
197 // Workaround: on some devices, the coordinates of TouchPoints
198 // in state TouchPointReleased are not reliable, and can
199 // "jump" by a significant distance. So we just stop handling
200 // the rotation as soon as the user's finger leaves the tablet.
201 break;
202 }
203
204 QPointF p0 = tp0.pos();
205 QPointF p1 = tp1.pos();
206
207 if ((p0-p1).manhattanLength() < 10)
208 {
209 // The TouchPoints are too close together. Don't update the
210 // rotation as the angle will likely be off. This also deals
211 // with a glitch where a newly pressed TouchPoint incorrectly
212 // reports the existing TouchPoint's coordinates instead of its
213 // own.
214 break;
215 }
216
217 // high school (y2 - y1) / (x2 - x1)
218 QPointF slope = p1 - p0;
219 qreal newAngle = atan2(slope.y(), slope.x());
220
221 // We must have the previous angle measurement to calculate the delta.
222 if (d->allowRotation)
223 {
224 qreal delta = (180 / M_PI) * (newAngle - d->previousAngle);
225
226 // Rotate by the effective angle from the beginning of the action.
227 d->touchRotation += delta;
228
230 KisCanvasController *controller = static_cast<KisCanvasController*>(canvas->canvasController());
231 controller->rotateCanvas(d->touchRotation);
232 }
233 else
234 {
235 d->allowRotation = true;
236 }
237
238 d->previousAngle = newAngle;
239 return;
240 }
241 default:
242 break;
243 }
245}
QPointF p0
QPointF p1
virtual void inputEvent(QEvent *event)
KisAbstractCanvasWidget * canvasWidget
KisCanvas2 * canvas

References KisRotateCanvasAction::Private::actionStillPoint, KisRotateCanvasAction::Private::allowRotation, Private::canvas, KisInputManager::canvas(), KoCanvasBase::canvasController(), KisCanvas2::canvasWidget, d, KisAbstractInputAction::inputEvent(), KisAbstractInputAction::inputManager, M_PI, p0, p1, KisRotateCanvasAction::Private::previousAngle, KisCanvasController::rotateCanvas(), and KisRotateCanvasAction::Private::touchRotation.

◆ priority()

int KisRotateCanvasAction::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 60 of file kis_rotate_canvas_action.cpp.

61{
62 return 3;
63}

◆ supportsHiResInputEvents()

bool KisRotateCanvasAction::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 253 of file kis_rotate_canvas_action.cpp.

254{
255 Q_UNUSED(shortcut);
256 return true;
257}

Member Data Documentation

◆ d

Private* const KisRotateCanvasAction::d {nullptr}
private

Definition at line 49 of file kis_rotate_canvas_action.h.

49{nullptr};

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