diff --git a/krita/data/input/kritadefault.profile b/krita/data/input/kritadefault.profile --- a/krita/data/input/kritadefault.profile +++ b/krita/data/input/kritadefault.profile @@ -24,6 +24,7 @@ 4={2;1;[];0;0;0} 5={3;1;[];0;0;0} 6={4;1;[];0;0;0} +7={0;3;[];0;5;0} [Rotate Canvas] 0={0;2;[1000020,20];1;0;0} @@ -32,6 +33,7 @@ 3={2;1;[34];0;0;0} 4={4;1;[35];0;0;0} 5={3;1;[36];0;0;0} +6={0;4;[];0;0;3} [Select Layer] 0={1;2;[1000020,52];1;0;0} @@ -57,6 +59,7 @@ 10={5;1;[32];0;0;0} 11={0;4;[];0;0;1} 12={8;2;[1000021,1000023];4;0;0} +13={0;4;[];0;0;4} 2={3;1;[2d];0;0;0} 3={2;1;[3d];0;0;0} 4={3;3;[];0;2;0} diff --git a/libs/ui/CMakeLists.txt b/libs/ui/CMakeLists.txt --- a/libs/ui/CMakeLists.txt +++ b/libs/ui/CMakeLists.txt @@ -280,6 +280,7 @@ input/kis_show_palette_action.cpp input/kis_change_primary_setting_action.cpp input/kis_abstract_shortcut.cpp + input/kis_native_gesture_shortcut.cpp input/kis_single_action_shortcut.cpp input/kis_stroke_shortcut.cpp input/kis_shortcut_matcher.cpp diff --git a/libs/ui/canvas/kis_canvas_controller.h b/libs/ui/canvas/kis_canvas_controller.h --- a/libs/ui/canvas/kis_canvas_controller.h +++ b/libs/ui/canvas/kis_canvas_controller.h @@ -51,6 +51,7 @@ public Q_SLOTS: void mirrorCanvas(bool enable); + void rotateCanvas(qreal angle, const QPointF ¢er); void rotateCanvas(qreal angle); void rotateCanvasRight15(); void rotateCanvasLeft15(); diff --git a/libs/ui/canvas/kis_canvas_controller.cpp b/libs/ui/canvas/kis_canvas_controller.cpp --- a/libs/ui/canvas/kis_canvas_controller.cpp +++ b/libs/ui/canvas/kis_canvas_controller.cpp @@ -214,15 +214,20 @@ QIcon(), 500, KisFloatingMessage::Low, Qt::AlignCenter); } -void KisCanvasController::rotateCanvas(qreal angle) +void KisCanvasController::rotateCanvas(qreal angle, const QPointF ¢er) { - QPoint newOffset = m_d->coordinatesConverter->rotate(m_d->coordinatesConverter->widgetCenterPoint(), angle); + QPoint newOffset = m_d->coordinatesConverter->rotate(center, angle); m_d->updateDocumentSizeAfterTransform(); setScrollBarValue(newOffset); m_d->paintOpTransformationConnector->notifyTransformationChanged(); m_d->showRotationValueOnCanvas(); } +void KisCanvasController::rotateCanvas(qreal angle) +{ + rotateCanvas(angle, m_d->coordinatesConverter->widgetCenterPoint()); +} + void KisCanvasController::rotateCanvasRight15() { rotateCanvas(15.0); diff --git a/libs/ui/input/kis_abstract_input_action.cpp b/libs/ui/input/kis_abstract_input_action.cpp --- a/libs/ui/input/kis_abstract_input_action.cpp +++ b/libs/ui/input/kis_abstract_input_action.cpp @@ -176,6 +176,9 @@ case QEvent::Wheel: return static_cast(event)->pos(); + case QEvent::NativeGesture: + return static_cast(event)->pos(); + default: warnInput << "KisAbstractInputAction" << d->name << "tried to process event data from an unhandled event type" << event->type(); return QPoint(); @@ -199,6 +202,9 @@ case QEvent::Wheel: return static_cast(event)->posF(); + case QEvent::NativeGesture: + return QPointF(static_cast(event)->pos()); + default: warnInput << "KisAbstractInputAction" << d->name << "tried to process event data from an unhandled event type" << event->type(); return QPointF(); diff --git a/libs/ui/input/kis_input_manager.h b/libs/ui/input/kis_input_manager.h --- a/libs/ui/input/kis_input_manager.h +++ b/libs/ui/input/kis_input_manager.h @@ -114,6 +114,9 @@ void slotCompressedMoveEvent(); private: + bool startTouch(bool &retval); + void endTouch(); + bool eventFilterImpl(QEvent * event); template bool compressMoveEventCommon(Event *event); diff --git a/libs/ui/input/kis_input_manager.cpp b/libs/ui/input/kis_input_manager.cpp --- a/libs/ui/input/kis_input_manager.cpp +++ b/libs/ui/input/kis_input_manager.cpp @@ -330,6 +330,21 @@ case QEvent::Wheel: { d->debugEvent(event); QWheelEvent *wheelEvent = static_cast(event); + +#ifdef Q_OS_OSX + // Some QT wheel events are actually touch pad pan events. From the QT docs: + // "Wheel events are generated for both mouse wheels and trackpad scroll gestures." + + // We differentiate between touchpad events and real mouse wheels by inspecting the + // event source. + + if (wheelEvent->source() == Qt::MouseEventSource::MouseEventSynthesizedBySystem) { + KisAbstractInputAction::setInputManager(this); + retval = d->matcher.wheelEvent(KisSingleActionShortcut::WheelTrackpad, wheelEvent); + break; + } +#endif + d->accumulatedScrollDelta += wheelEvent->delta(); KisSingleActionShortcut::WheelAction action; @@ -478,13 +493,8 @@ case QEvent::TouchBegin: { - QTouchEvent *tevent = static_cast(event); - d->touchHasBlockedPressEvents = KisConfig().disableTouchOnCanvas(); - // Touch rejection: if touch is disabled on canvas, no need to block mouse press events - if (KisConfig().disableTouchOnCanvas()) d->eatOneMousePress(); - if (d->tryHidePopupPalette()) { - retval = true; - } else { + if (startTouch(retval)) { + QTouchEvent *tevent = static_cast(event); KisAbstractInputAction::setInputManager(this); retval = d->matcher.touchBeginEvent(tevent); event->accept(); @@ -518,12 +528,44 @@ } case QEvent::TouchEnd: { + endTouch(); QTouchEvent *tevent = static_cast(event); - d->touchHasBlockedPressEvents = false; retval = d->matcher.touchEndEvent(tevent); event->accept(); break; } + + case QEvent::NativeGesture: + { + QNativeGestureEvent *gevent = static_cast(event); + switch (gevent->gestureType()) { + case Qt::BeginNativeGesture: + { + if (startTouch(retval)) { + KisAbstractInputAction::setInputManager(this); + retval = d->matcher.nativeGestureBeginEvent(gevent); + event->accept(); + } + break; + } + case Qt::EndNativeGesture: + { + endTouch(); + retval = d->matcher.nativeGestureEndEvent(gevent); + event->accept(); + break; + } + default: + { + KisAbstractInputAction::setInputManager(this); + retval = d->matcher.nativeGestureEvent(gevent); + event->accept(); + break; + } + } + break; + } + default: break; } @@ -531,6 +573,26 @@ return !retval ? d->processUnhandledEvent(event) : true; } +bool KisInputManager::startTouch(bool &retval) +{ + d->touchHasBlockedPressEvents = KisConfig().disableTouchOnCanvas(); + // Touch rejection: if touch is disabled on canvas, no need to block mouse press events + if (KisConfig().disableTouchOnCanvas()) { + d->eatOneMousePress(); + } + if (d->tryHidePopupPalette()) { + retval = true; + return false; + } else { + return true; + } +} + +void KisInputManager::endTouch() +{ + d->touchHasBlockedPressEvents = false; +} + void KisInputManager::slotCompressedMoveEvent() { if (d->compressedMoveEvent) { @@ -601,7 +663,9 @@ d->addWheelShortcut(shortcut->action(), shortcut->mode(), shortcut->keys(), shortcut->wheel()); break; case KisShortcutConfiguration::GestureType: - d->addTouchShortcut(shortcut->action(), shortcut->mode(), shortcut->gesture()); + if (!d->addNativeGestureShortcut(shortcut->action(), shortcut->mode(), shortcut->gesture())) { + d->addTouchShortcut(shortcut->action(), shortcut->mode(), shortcut->gesture()); + } break; default: break; diff --git a/libs/ui/input/kis_input_manager_p.h b/libs/ui/input/kis_input_manager_p.h --- a/libs/ui/input/kis_input_manager_p.h +++ b/libs/ui/input/kis_input_manager_p.h @@ -47,6 +47,7 @@ void addStrokeShortcut(KisAbstractInputAction* action, int index, const QList< Qt::Key >& modifiers, Qt::MouseButtons buttons); void addKeyShortcut(KisAbstractInputAction* action, int index,const QList &keys); void addTouchShortcut( KisAbstractInputAction* action, int index, KisShortcutConfiguration::GestureAction gesture ); + bool addNativeGestureShortcut( KisAbstractInputAction* action, int index, KisShortcutConfiguration::GestureAction gesture ); void addWheelShortcut(KisAbstractInputAction* action, int index, const QList< Qt::Key >& modifiers, KisShortcutConfiguration::MouseWheelMovement wheelAction); bool processUnhandledEvent(QEvent *event); void setupActions(); diff --git a/libs/ui/input/kis_input_manager_p.cpp b/libs/ui/input/kis_input_manager_p.cpp --- a/libs/ui/input/kis_input_manager_p.cpp +++ b/libs/ui/input/kis_input_manager_p.cpp @@ -29,6 +29,7 @@ #include "kis_tool_invocation_action.h" #include "kis_stroke_shortcut.h" #include "kis_touch_shortcut.h" +#include "kis_native_gesture_shortcut.h" #include "kis_input_profile_manager.h" /** @@ -426,6 +427,9 @@ case KisShortcutConfiguration::WheelRight: a = KisSingleActionShortcut::WheelRight; break; + case KisShortcutConfiguration::WheelTrackpad: + a = KisSingleActionShortcut::WheelTrackpad; + break; default: return; } @@ -452,6 +456,34 @@ matcher.addShortcut(shortcut); } +bool KisInputManager::Private::addNativeGestureShortcut(KisAbstractInputAction* action, int index, KisShortcutConfiguration::GestureAction gesture) +{ + // each platform should decide here which gestures are handled via QtNativeGestureEvent. + Qt::NativeGestureType type; + switch (gesture) { +#ifdef Q_OS_OSX + case KisShortcutConfiguration::PinchGesture: + type = Qt::ZoomNativeGesture; + break; + case KisShortcutConfiguration::PanGesture: + type = Qt::PanNativeGesture; + break; + case KisShortcutConfiguration::RotateGesture: + type = Qt::RotateNativeGesture; + break; + case KisShortcutConfiguration::SmartZoomGesture: + type = Qt::SmartZoomNativeGesture; + break; +#endif + default: + return false; + } + + KisNativeGestureShortcut *shortcut = new KisNativeGestureShortcut(action, index, type); + matcher.addShortcut(shortcut); + return true; +} + void KisInputManager::Private::setupActions() { QList actions = KisInputProfileManager::instance()->actions(); diff --git a/libs/ui/input/kis_input_profile_manager.cpp b/libs/ui/input/kis_input_profile_manager.cpp --- a/libs/ui/input/kis_input_profile_manager.cpp +++ b/libs/ui/input/kis_input_profile_manager.cpp @@ -233,6 +233,8 @@ } } + QStringList profilePaths; + Q_FOREACH(const QString & profileName, profileEntries.keys()) { if (profileEntries[profileName].isEmpty()) { @@ -243,6 +245,11 @@ // because that's the most local one. ProfileEntry entry = profileEntries[profileName].first(); + QString path(QFileInfo(entry.fullpath).dir().absolutePath()); + if (!profilePaths.contains(path)) { + profilePaths.append(path); + } + KConfig config(entry.fullpath, KConfig::SimpleConfig); KisInputProfile *newProfile = addProfile(entry.name); @@ -267,6 +274,9 @@ } } + QString profilePathsStr(profilePaths.join("' AND '")); + qDebug() << "input profiles were read from '" << qUtf8Printable(profilePathsStr) << "'."; + KisConfig cfg; QString currentProfile = cfg.currentInputProfile(); if (d->profiles.size() > 0) { diff --git a/libs/ui/input/kis_native_gesture_shortcut.h b/libs/ui/input/kis_native_gesture_shortcut.h new file mode 100644 --- /dev/null +++ b/libs/ui/input/kis_native_gesture_shortcut.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2017 Bernhard Liebl + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef KISNATIVEGESTURESHORTCUT_H +#define KISNATIVEGESTURESHORTCUT_H + +#include "kis_abstract_shortcut.h" + +class QNativeGestureEvent; +class KisNativeGestureShortcut : public KisAbstractShortcut +{ +public: + KisNativeGestureShortcut(KisAbstractInputAction* action, int index, Qt::NativeGestureType type); + ~KisNativeGestureShortcut() override; + + int priority() const override; + + bool match(QNativeGestureEvent* event); + +private: + class Private; + Private * const d; +}; + +#endif // KISNATIVEGESTURESHORTCUT_H diff --git a/libs/ui/input/kis_native_gesture_shortcut.cpp b/libs/ui/input/kis_native_gesture_shortcut.cpp new file mode 100644 --- /dev/null +++ b/libs/ui/input/kis_native_gesture_shortcut.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2017 Bernhard Liebl + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "kis_native_gesture_shortcut.h" + +#include + +class KisNativeGestureShortcut::Private +{ +public: + Private() { } + + Qt::NativeGestureType type; +}; + +KisNativeGestureShortcut::KisNativeGestureShortcut(KisAbstractInputAction* action, int index, Qt::NativeGestureType type) + : KisAbstractShortcut(action, index), d(new Private) +{ + d->type = type; +} + +KisNativeGestureShortcut::~KisNativeGestureShortcut() +{ + delete d; +} + +int KisNativeGestureShortcut::priority() const +{ + return 0; +} + +bool KisNativeGestureShortcut::match(QNativeGestureEvent* event) +{ + //printf("checking NativeGesture against KisNativeGestureShortcut %d %d\n", (int)event->gestureType(), (int)d->type); + return event->gestureType() == d->type; +} diff --git a/libs/ui/input/kis_pan_action.cpp b/libs/ui/input/kis_pan_action.cpp --- a/libs/ui/input/kis_pan_action.cpp +++ b/libs/ui/input/kis_pan_action.cpp @@ -85,11 +85,25 @@ { KisAbstractInputAction::begin(shortcut, event); + bool overrideCursor = true; + switch (shortcut) { case PanModeShortcut: { QTouchEvent *tevent = dynamic_cast(event); - if(tevent) + if (tevent) { d->lastPosition = d->averagePoint(tevent); + break; + } + + // Some QT wheel events are actually be touch pad pan events. From the QT docs: + // "Wheel events are generated for both mouse wheels and trackpad scroll gestures." + QWheelEvent *wheelEvent = dynamic_cast(event); + if (wheelEvent) { + inputManager()->canvas()->canvasController()->pan(-wheelEvent->pixelDelta()); + overrideCursor = false; + break; + } + break; } case PanLeftShortcut: @@ -105,7 +119,10 @@ inputManager()->canvas()->canvasController()->pan(QPoint(0, -d->panDistance)); break; } - QApplication::setOverrideCursor(Qt::ClosedHandCursor); + + if (overrideCursor) { + QApplication::setOverrideCursor(Qt::ClosedHandCursor); + } } void KisPanAction::end(QEvent *event) diff --git a/libs/ui/input/kis_rotate_canvas_action.h b/libs/ui/input/kis_rotate_canvas_action.h --- a/libs/ui/input/kis_rotate_canvas_action.h +++ b/libs/ui/input/kis_rotate_canvas_action.h @@ -50,6 +50,7 @@ void deactivate(int shortcut) override; void begin(int shortcut, QEvent *event) override; void cursorMoved(const QPointF &lastPos, const QPointF &pos) override; + void inputEvent(QEvent* event) override; private: class Private; diff --git a/libs/ui/input/kis_rotate_canvas_action.cpp b/libs/ui/input/kis_rotate_canvas_action.cpp --- a/libs/ui/input/kis_rotate_canvas_action.cpp +++ b/libs/ui/input/kis_rotate_canvas_action.cpp @@ -19,6 +19,7 @@ #include "kis_rotate_canvas_action.h" #include +#include #include #include "kis_cursor.h" @@ -130,3 +131,22 @@ dynamic_cast(inputManager()->canvas()->canvasController()); canvasController->rotateCanvas(angle); } + +void KisRotateCanvasAction::inputEvent(QEvent* event) +{ + switch (event->type()) { + case QEvent::NativeGesture: { + QNativeGestureEvent *gevent = static_cast(event); + KisCanvas2 *canvas = inputManager()->canvas(); + KisCanvasController *controller = static_cast(canvas->canvasController()); + + const float angle = gevent->value(); + QPoint widgetPos = canvas->canvasWidget()->mapFromGlobal(gevent->globalPos()); + controller->rotateCanvas(angle, widgetPos); + return; + } + default: + break; + } + KisAbstractInputAction::inputEvent(event); +} diff --git a/libs/ui/input/kis_shortcut_configuration.h b/libs/ui/input/kis_shortcut_configuration.h --- a/libs/ui/input/kis_shortcut_configuration.h +++ b/libs/ui/input/kis_shortcut_configuration.h @@ -59,6 +59,7 @@ WheelDown, ///< Downwards movement, toward the user. WheelLeft, ///< Left movement. WheelRight, ///< Right movement. + WheelTrackpad, ///< A pan movement on a trackpad. }; /** @@ -68,6 +69,8 @@ NoGesture, ///< No gesture. PinchGesture, ///< Pinch gesture, fingers moving towards or away from each other. PanGesture, ///< Pan gesture, fingers staying together but moving across the screen. + RotateGesture, /// @@ -50,9 +51,11 @@ : runningShortcut(0) , readyShortcut(0) , touchShortcut(0) + , nativeGestureShortcut(0) , suppressAllActions(false) , cursorEntered(false) , usingTouch(false) + , usingNativeGesture(false) {} ~Private() @@ -65,6 +68,7 @@ QList singleActionShortcuts; QList strokeShortcuts; QList touchShortcuts; + QList nativeGestureShortcuts; QSet keys; // Model of currently pressed keys QSet buttons; // Model of currently pressed buttons @@ -74,10 +78,12 @@ QList candidateShortcuts; KisTouchShortcut *touchShortcut; + KisNativeGestureShortcut *nativeGestureShortcut; bool suppressAllActions; bool cursorEntered; bool usingTouch; + bool usingNativeGesture; inline bool actionsSuppressed() const { return suppressAllActions || !cursorEntered; @@ -86,6 +92,10 @@ inline bool actionsSuppressedIgnoreFocus() const { return suppressAllActions; } + + inline bool isUsingTouch() const { + return usingTouch || usingNativeGesture; + } }; KisShortcutMatcher::KisShortcutMatcher() @@ -117,6 +127,10 @@ m_d->touchShortcuts.append(shortcut); } +void KisShortcutMatcher::addShortcut(KisNativeGestureShortcut *shortcut) { + m_d->nativeGestureShortcuts.append(shortcut); +} + bool KisShortcutMatcher::supportsHiResInputEvents() { return @@ -181,7 +195,7 @@ bool retval = false; - if (m_d->usingTouch) { + if (m_d->isUsingTouch()) { return retval; } @@ -208,7 +222,7 @@ bool retval = false; - if (m_d->usingTouch) { + if (m_d->isUsingTouch()) { return retval; } @@ -230,7 +244,7 @@ bool KisShortcutMatcher::wheelEvent(KisSingleActionShortcut::WheelAction wheelAction, QWheelEvent *event) { - if (m_d->runningShortcut || m_d->usingTouch) { + if (m_d->runningShortcut || m_d->isUsingTouch()) { DEBUG_ACTION("Wheel event canceled."); return false; } @@ -240,7 +254,7 @@ bool KisShortcutMatcher::pointerMoved(QEvent *event) { - if (m_d->usingTouch || !m_d->runningShortcut) { + if (m_d->isUsingTouch() || !m_d->runningShortcut) { return false; } @@ -305,6 +319,38 @@ return false; } +bool KisShortcutMatcher::nativeGestureBeginEvent(QNativeGestureEvent *event) +{ + Q_UNUSED(event) + return true; +} + +bool KisShortcutMatcher::nativeGestureEvent(QNativeGestureEvent *event) +{ + bool retval = false; + + if ( m_d->nativeGestureShortcut && !m_d->nativeGestureShortcut->match( event ) ) { + retval = tryEndNativeGestureShortcut( event ); + } + + if ( !m_d->nativeGestureShortcut ) { + retval = tryRunNativeGestureShortcut( event ); + } + else { + m_d->nativeGestureShortcut->action()->inputEvent( event ); + retval = true; + } + + return retval; +} + +bool KisShortcutMatcher::nativeGestureEndEvent(QNativeGestureEvent *event) +{ + Q_UNUSED(event) + m_d->usingNativeGesture = false; + return true; +} + Qt::MouseButtons listToFlags(const QList &list) { Qt::MouseButtons flags; Q_FOREACH (Qt::MouseButton b, list) { @@ -566,3 +612,46 @@ return false; } + +bool KisShortcutMatcher::tryRunNativeGestureShortcut(QNativeGestureEvent* event) +{ + KisNativeGestureShortcut *goodCandidate = 0; + + if (m_d->actionsSuppressed()) + return false; + + Q_FOREACH (KisNativeGestureShortcut* shortcut, m_d->nativeGestureShortcuts) { + if (shortcut->match(event) && (!goodCandidate || shortcut->priority() > goodCandidate->priority())) { + goodCandidate = shortcut; + } + } + + if (goodCandidate) { + goodCandidate->action()->activate(goodCandidate->shortcutIndex()); + goodCandidate->action()->begin(goodCandidate->shortcutIndex(), event); + + m_d->nativeGestureShortcut = goodCandidate; + m_d->usingNativeGesture = true; + + return true; + } + + return false; +} + +bool KisShortcutMatcher::tryEndNativeGestureShortcut(QNativeGestureEvent* event) +{ + if (m_d->nativeGestureShortcut) { + // first reset running shortcut to avoid infinite recursion via end() + KisNativeGestureShortcut *nativeGestureShortcut = m_d->nativeGestureShortcut; + + nativeGestureShortcut->action()->end(event); + nativeGestureShortcut->action()->deactivate(m_d->nativeGestureShortcut->shortcutIndex()); + + m_d->nativeGestureShortcut = 0; // empty it out now that we are done with it + + return true; + } + + return false; +} diff --git a/libs/ui/input/kis_single_action_shortcut.h b/libs/ui/input/kis_single_action_shortcut.h --- a/libs/ui/input/kis_single_action_shortcut.h +++ b/libs/ui/input/kis_single_action_shortcut.h @@ -35,6 +35,7 @@ WheelDown, ///< Mouse wheel moves down. WheelLeft, ///< Mouse wheel moves left. WheelRight, ///< Mouse wheel moves right. + WheelTrackpad, ///< A pan movement on a trackpad. }; KisSingleActionShortcut(KisAbstractInputAction *action, int index); diff --git a/libs/ui/input/kis_zoom_action.cpp b/libs/ui/input/kis_zoom_action.cpp --- a/libs/ui/input/kis_zoom_action.cpp +++ b/libs/ui/input/kis_zoom_action.cpp @@ -19,6 +19,7 @@ #include "kis_zoom_action.h" #include +#include #include @@ -227,6 +228,25 @@ } return; // Don't try to update the cursor during a pinch-zoom } + case QEvent::NativeGesture: { + QNativeGestureEvent *gevent = static_cast(event); + if (gevent->gestureType() == Qt::ZoomNativeGesture) { + KisCanvas2 *canvas = inputManager()->canvas(); + KisCanvasController *controller = static_cast(canvas->canvasController()); + const float delta = 1.0f + gevent->value(); + controller->zoomRelativeToPoint(canvas->canvasWidget()->mapFromGlobal(gevent->globalPos()), delta); + } else if (gevent->gestureType() == Qt::SmartZoomNativeGesture) { + KisCanvas2 *canvas = inputManager()->canvas(); + KoZoomController *controller = canvas->viewManager()->zoomController(); + + if (controller->zoomMode() != KoZoomMode::ZOOM_WIDTH) { + controller->setZoom(KoZoomMode::ZOOM_WIDTH, 1.0); + } else { + controller->setZoom(KoZoomMode::ZOOM_CONSTANT, 1.0); + } + } + return; + } default: break; } diff --git a/libs/widgets/KoZoomController.h b/libs/widgets/KoZoomController.h --- a/libs/widgets/KoZoomController.h +++ b/libs/widgets/KoZoomController.h @@ -87,6 +87,11 @@ void setZoomMode(KoZoomMode::Mode mode); /** + * @return the current zoom mode. + */ + KoZoomMode::Mode zoomMode() const; + + /** * Set the resolution, zoom, the zoom mode for this zoom Controller. * Typically for use just after construction to restore the * persistent data. diff --git a/libs/widgets/KoZoomController.cpp b/libs/widgets/KoZoomController.cpp --- a/libs/widgets/KoZoomController.cpp +++ b/libs/widgets/KoZoomController.cpp @@ -76,6 +76,11 @@ setZoom(mode, 1.0); } +KoZoomMode::Mode KoZoomController::zoomMode() const +{ + return d->zoomHandler->zoomMode(); +} + void KoZoomController::setPageSize(const QSizeF &pageSize) { if(d->pageSize == pageSize) return;