File indexing completed on 2024-12-22 04:09:14
0001 /* This file is part of the KDE project 0002 0003 SPDX-FileCopyrightText: 2006 Thorsten Zachmann <zachmann@kde.org> 0004 SPDX-FileCopyrightText: 2006 Thomas Zander <zander@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #include "KoShapeRubberSelectStrategy.h" 0010 #include "KoShapeRubberSelectStrategy_p.h" 0011 #include "KoViewConverter.h" 0012 0013 #include <QPainter> 0014 0015 #include "KoShapeManager.h" 0016 #include "KoSelection.h" 0017 #include "KoCanvasBase.h" 0018 0019 KoShapeRubberSelectStrategy::KoShapeRubberSelectStrategy(KoToolBase *tool, const QPointF &clicked, bool useSnapToGrid) 0020 : KoInteractionStrategy(*(new KoShapeRubberSelectStrategyPrivate(tool))) 0021 { 0022 Q_D(KoShapeRubberSelectStrategy); 0023 d->snapGuide->enableSnapStrategies(KoSnapGuide::GridSnapping); 0024 d->snapGuide->enableSnapping(useSnapToGrid); 0025 0026 d->selectRect = QRectF(d->snapGuide->snap(clicked, QFlags<Qt::KeyboardModifier>()), QSizeF(0, 0)); 0027 } 0028 0029 void KoShapeRubberSelectStrategy::paint(QPainter &painter, const KoViewConverter &converter) 0030 { 0031 Q_D(KoShapeRubberSelectStrategy); 0032 painter.setRenderHint(QPainter::Antialiasing, false); 0033 0034 const QColor crossingColor(80,130,8); 0035 const QColor coveringColor(8,60,167); 0036 0037 QColor selectColor( 0038 currentMode() == CrossingSelection ? 0039 crossingColor : coveringColor); 0040 0041 selectColor.setAlphaF(0.8); 0042 QPen select(selectColor, decorationThickness()); 0043 select.setCosmetic(true); 0044 painter.setPen(select); 0045 0046 selectColor.setAlphaF(0.4); 0047 const QBrush fillBrush(selectColor); 0048 painter.setBrush(fillBrush); 0049 0050 QRectF paintRect = converter.documentToView(d->selectedRect()); 0051 paintRect = paintRect.normalized(); 0052 0053 painter.drawRect(paintRect); 0054 } 0055 0056 void KoShapeRubberSelectStrategy::handleMouseMove(const QPointF &p, Qt::KeyboardModifiers modifiers) 0057 { 0058 Q_D(KoShapeRubberSelectStrategy); 0059 QPointF point = d->snapGuide->snap(p, modifiers); 0060 if (modifiers & Qt::ControlModifier) { 0061 const QRectF oldDirtyRect = d->selectedRect(); 0062 d->selectRect.moveTopLeft(d->selectRect.topLeft() - (d->lastPos - point)); 0063 d->lastPos = point; 0064 d->tool->canvas()->updateCanvas(oldDirtyRect | d->selectedRect()); 0065 return; 0066 } 0067 d->lastPos = point; 0068 QPointF old = d->selectRect.bottomRight(); 0069 d->selectRect.setBottomRight(point); 0070 /* 0071 +---------------|--+ 0072 | | | We need to figure out rects A and B based on the two points. BUT 0073 | old | A| we need to do that even if the points are switched places 0074 | \ | | (i.e. the rect got smaller) and even if the rect is mirrored 0075 +---------------+ | in either the horizontal or vertical axis. 0076 | B | 0077 +------------------+ 0078 `- point 0079 */ 0080 QPointF x1 = old; 0081 x1.setY(d->selectRect.topLeft().y()); 0082 qreal h1 = point.y() - x1.y(); 0083 qreal h2 = old.y() - x1.y(); 0084 QRectF A(x1, QSizeF(point.x() - x1.x(), point.y() < d->selectRect.top() ? qMin(h1, h2) : qMax(h1, h2))); 0085 A = A.normalized(); 0086 d->tool->canvas()->updateCanvas(A); 0087 0088 QPointF x2 = old; 0089 x2.setX(d->selectRect.topLeft().x()); 0090 qreal w1 = point.x() - x2.x(); 0091 qreal w2 = old.x() - x2.x(); 0092 QRectF B(x2, QSizeF(point.x() < d->selectRect.left() ? qMin(w1, w2) : qMax(w1, w2), point.y() - x2.y())); 0093 B = B.normalized(); 0094 d->tool->canvas()->updateCanvas(B); 0095 } 0096 0097 KoShapeRubberSelectStrategy::SelectionMode KoShapeRubberSelectStrategy::currentMode() const 0098 { 0099 Q_D(const KoShapeRubberSelectStrategy); 0100 return d->selectRect.left() < d->selectRect.right() ? CoveringSelection : CrossingSelection; 0101 } 0102 0103 KUndo2Command *KoShapeRubberSelectStrategy::createCommand() 0104 { 0105 return 0; 0106 } 0107 0108 QRectF KoShapeRubberSelectStrategy::selectedRectangle() const { 0109 Q_D(const KoShapeRubberSelectStrategy); 0110 return d->selectedRect(); 0111 }