diff --git a/krita/ui/canvas/kis_infinity_manager.cpp b/krita/ui/canvas/kis_infinity_manager.cpp index 471032e8c9..92b1a0b8ed 100644 --- a/krita/ui/canvas/kis_infinity_manager.cpp +++ b/krita/ui/canvas/kis_infinity_manager.cpp @@ -1,242 +1,250 @@ /* * Copyright (c) 2013 Dmitry Kazakov * * 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_infinity_manager.h" #include #include #include #include #include #include #include #include #include #include #include #include #include KisInfinityManager::KisInfinityManager(QPointerview, KisCanvas2 *canvas) : KisCanvasDecoration(INFINITY_DECORATION_ID, view), m_filteringEnabled(false), m_cursorSwitched(false), m_sideRects(NSides), m_canvas(canvas) { connect(canvas, SIGNAL(documentOffsetUpdateFinished()), SLOT(imagePositionChanged())); } inline void KisInfinityManager::addDecoration(const QRect &areaRect, const QPointF &handlePoint, qreal angle, Side side) { QTransform t; t.rotate(angle); t = t * QTransform::fromTranslate(handlePoint.x(), handlePoint.y()); m_handleTransform << t; m_decorationPath.addRect(areaRect); m_sideRects[side] = areaRect; } void KisInfinityManager::imagePositionChanged() { - QRect imageRect = m_canvas->coordinatesConverter()->imageRectInWidgetPixels().toAlignedRect(); - QRect widgetRect = m_canvas->canvasWidget()->rect(); + const QRect imageRect = m_canvas->coordinatesConverter()->imageRectInWidgetPixels().toAlignedRect(); + const QRect widgetRect = m_canvas->canvasWidget()->rect(); KisConfig cfg; qreal vastScrolling = cfg.vastScrolling(); int xReserve = vastScrolling * widgetRect.width(); int yReserve = vastScrolling * widgetRect.height(); int xThreshold = imageRect.width() - 0.4 * xReserve; int yThreshold = imageRect.height() - 0.4 * yReserve; const int stripeWidth = 48; int xCut = widgetRect.width() - stripeWidth; int yCut = widgetRect.height() - stripeWidth; m_decorationPath = QPainterPath(); m_decorationPath.setFillRule(Qt::WindingFill); m_handleTransform.clear(); m_sideRects.clear(); m_sideRects.resize(NSides); bool visible = false; if (imageRect.x() <= -xThreshold) { QRect areaRect(widgetRect.adjusted(xCut, 0, 0, 0)); QPointF pt = areaRect.center() + QPointF(-0.1 * stripeWidth, 0); addDecoration(areaRect, pt, 0, Right); visible = true; } if (imageRect.y() <= -yThreshold) { QRect areaRect(widgetRect.adjusted(0, yCut, 0, 0)); QPointF pt = areaRect.center() + QPointF(0, -0.1 * stripeWidth); addDecoration(areaRect, pt, 90, Bottom); visible = true; } if (imageRect.right() > widgetRect.width() + xThreshold) { QRect areaRect(widgetRect.adjusted(0, 0, -xCut, 0)); QPointF pt = areaRect.center() + QPointF(0.1 * stripeWidth, 0); addDecoration(areaRect, pt, 180, Left); visible = true; } if (imageRect.bottom() > widgetRect.height() + yThreshold) { QRect areaRect(widgetRect.adjusted(0, 0, 0, -yCut)); QPointF pt = areaRect.center() + QPointF(0, 0.1 * stripeWidth); addDecoration(areaRect, pt, 270, Top); visible = true; } if (!m_filteringEnabled && visible && this->visible()) { KisInputManager *inputManager = m_canvas->globalInputManager(); if (inputManager) { inputManager->attachPriorityEventFilter(this); } m_filteringEnabled = true; } if (m_filteringEnabled && (!visible || !this->visible())) { KisInputManager *inputManager = m_canvas->globalInputManager(); if (inputManager) { inputManager->detachPriorityEventFilter(this); } m_filteringEnabled = false; } } void KisInfinityManager::drawDecoration(QPainter& gc, const QRectF& updateArea, const KisCoordinatesConverter *converter, KisCanvas2 *canvas) { Q_UNUSED(updateArea); Q_UNUSED(converter); Q_UNUSED(canvas); if (!m_filteringEnabled) return; gc.save(); gc.setTransform(QTransform(), false); KisConfig cfg; QColor color = cfg.canvasBorderColor(); gc.fillPath(m_decorationPath, color.darker(115)); QPainterPath p = KisAlgebra2D::smallArrow(); foreach (const QTransform &t, m_handleTransform) { gc.fillPath(t.map(p), color); } gc.restore(); } inline int expandLeft(int x0, int x1, int maxExpand) { return qMax(x0 - maxExpand, qMin(x0, x1)); } inline int expandRight(int x0, int x1, int maxExpand) { return qMin(x0 + maxExpand, qMax(x0, x1)); } bool KisInfinityManager::eventFilter(QObject *obj, QEvent *event) { + /** + * We connect our event filter to the global InputManager which is + * shared among all the canvases. Ideally we should disconnect our + * event filter whin this canvas is not active, but for now we can + * just check the destination of the event, if it is correct. + */ + if (obj != m_canvas->canvasWidget()) return false; + KIS_ASSERT_RECOVER_NOOP(m_filteringEnabled); bool retval = false; switch (event->type()) { case QEvent::Enter: case QEvent::Leave: case QEvent::MouseMove: { QMouseEvent *mouseEvent = static_cast(event); if (m_decorationPath.contains(mouseEvent->pos())) { if (!m_cursorSwitched) { m_oldCursor = m_canvas->canvasWidget()->cursor(); m_cursorSwitched = true; } m_canvas->canvasWidget()->setCursor(Qt::PointingHandCursor); retval = true; } else if (m_cursorSwitched) { m_canvas->canvasWidget()->setCursor(m_oldCursor); m_cursorSwitched = false; } break; } case QEvent::MouseButtonPress: { QMouseEvent *mouseEvent = static_cast(event); retval = mouseEvent->button() == Qt::LeftButton && m_cursorSwitched; if (mouseEvent->button() == Qt::RightButton) { imagePositionChanged(); } break; } case QEvent::MouseButtonRelease: { QMouseEvent *mouseEvent = static_cast(event); retval = mouseEvent->button() == Qt::LeftButton && m_cursorSwitched; if (retval) { QPoint pos = mouseEvent->pos(); const KisCoordinatesConverter *converter = m_canvas->coordinatesConverter(); QRect widgetRect = converter->widgetToImage(m_canvas->canvasWidget()->rect()).toAlignedRect(); KisImageWSP image = view()->image(); QRect cropRect = image->bounds(); const int hLimit = cropRect.width(); const int vLimit = cropRect.height(); if (m_sideRects[Right].contains(pos)) { cropRect.setRight(expandRight(cropRect.right(), widgetRect.right(), hLimit)); } if (m_sideRects[Bottom].contains(pos)) { cropRect.setBottom(expandRight(cropRect.bottom(), widgetRect.bottom(), vLimit)); } if (m_sideRects[Left].contains(pos)) { cropRect.setLeft(expandLeft(cropRect.left(), widgetRect.left(), hLimit)); } if (m_sideRects[Top].contains(pos)) { cropRect.setTop(expandLeft(cropRect.top(), widgetRect.top(), vLimit)); } image->resizeImage(cropRect); } break; } default: break; } return !retval ? KisCanvasDecoration::eventFilter(obj, event) : true; }