Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_tool_crop.cc
Go to the documentation of this file.
1/*
2 * kis_tool_crop.cc -- part of Krita
3 *
4 * SPDX-FileCopyrightText: 2004 Boudewijn Rempt <boud@valdyas.org>
5 * SPDX-FileCopyrightText: 2005 Michael Thaler <michael.thaler@physik.tu-muenchen.de>
6 * SPDX-FileCopyrightText: 2006 Cyrille Berger <cberger@cberger.net>
7 * SPDX-FileCopyrightText: 2007 Adrian Page <adrian@pagenet.plus.com>
8 *
9 * SPDX-License-Identifier: GPL-2.0-or-later
10 */
11
12#include "kis_tool_crop.h"
13
14
15#include <QCheckBox>
16#include <QObject>
17#include <QPainter>
18#include <QPen>
19#include <QRect>
20#include <QMenu>
21
22#include <kis_debug.h>
23#include <klocalizedstring.h>
24#include <ksharedconfig.h>
25
26#include <KoCanvasBase.h>
27#include <kis_global.h>
28#include <kis_painter.h>
29#include <kis_cursor.h>
30#include <kis_image.h>
31#include <kis_undo_adapter.h>
32#include <KoPointerEvent.h>
33#include <kis_selection.h>
34#include <kis_layer.h>
35#include <kis_canvas2.h>
36#include <KisViewManager.h>
38#include <kis_group_layer.h>
40
41#include <kundo2command.h>
44
45
62
64{
65 //thirds
70
71 //fifths
80
81 // Passport photo
82 {QPointF(0.0, 0.45/0.35),QPointF(1.0, 0.45/0.35), DecorationLine::Width, DecorationLine::Width, DecorationLine::Width, DecorationLine::Width},
83 {QPointF(0.2, 0.05/0.35),QPointF(0.8, 0.05/0.35), DecorationLine::Width, DecorationLine::Width, DecorationLine::Width, DecorationLine::Width},
84 {QPointF(0.2, 0.40/0.35),QPointF(0.8, 0.40/0.35), DecorationLine::Width, DecorationLine::Width, DecorationLine::Width, DecorationLine::Width},
85 {QPointF(0.25, 0.07/0.35),QPointF(0.75, 0.07/0.35), DecorationLine::Width, DecorationLine::Width, DecorationLine::Width, DecorationLine::Width},
86 {QPointF(0.25, 0.38/0.35),QPointF(0.75, 0.38/0.35), DecorationLine::Width, DecorationLine::Width, DecorationLine::Width, DecorationLine::Width},
87 {QPointF(0.35/0.45, 0.0),QPointF(0.35/0.45, 1.0), DecorationLine::Height, DecorationLine::Height, DecorationLine::Height, DecorationLine::Height},
88
89 //Crosshair
92};
93
94#define DECORATION_COUNT 5
95const int decorsIndex[DECORATION_COUNT] = {0,4,12,18,20};
96
98 : KisTool(canvas, KisCursor::loadWithSize("tool_crop_cursor.svg", 32, 32, 6, 6))
99{
100 setObjectName("tool_crop");
101 m_handleSize = 13;
102 m_haveCropSelection = false;
103 m_cropTypeSelectable = false;
105 m_decoration = 1;
106
107 connect(&m_finalRect, SIGNAL(sigValuesChanged()), SLOT(slotRectChanged()));
108 connect(&m_finalRect, SIGNAL(sigLockValuesChanged()), SLOT(slotRectChanged()));
109
110 // context menu options (mirrors tool options)
111 m_contextMenu.reset(new QMenu());
112 applyCrop = new KisAction(i18n("Crop"));
113
114 centerToggleOption = new KisAction(i18n("Center"));
115 centerToggleOption->setCheckable(true);
116
117 growToggleOption = new KisAction(i18nc("Grow as in crop tool", "Grow"));
118 growToggleOption->setCheckable(true);
119
120 lockWidthToggleOption = new KisAction(i18n("Lock Width"));
121 lockWidthToggleOption->setCheckable(true);
122
123 lockHeightToggleOption = new KisAction(i18n("Lock Height"));
124 lockHeightToggleOption->setCheckable(true);
125
126 lockRatioToggleOption = new KisAction(i18n("Lock Ratio"));
127 lockRatioToggleOption->setCheckable(true);
128
129 KisCanvas2 *kisCanvas =dynamic_cast<KisCanvas2*>(canvas);
130 if (kisCanvas) {
131 connect(kisCanvas->displayColorConverter(), SIGNAL(displayConfigurationChanged()), this, SLOT(updateDecorationColors()));
132 }
134}
135
137{
138 delete applyCrop;
139 delete centerToggleOption;
140 delete growToggleOption;
144}
145
146void KisToolCrop::activate(const QSet<KoShape*> &shapes)
147{
148
149 KisTool::activate(shapes);
150 configGroup = KSharedConfig::openConfig()->group(toolId()); // save settings to kritarc
151
152 KisResourcesSnapshotSP resources =
153 new KisResourcesSnapshot(image(), currentNode(), this->canvas()->resourceManager());
154
155
156 // load settings from configuration
157 setGrowCenter(configGroup.readEntry("growCenter", false));
158 setAllowGrow(configGroup.readEntry("allowGrow", true));
159
160 // Default: thirds decoration
161 setDecoration(configGroup.readEntry("decoration", 1));
162
163 // Default: crop the entire image
164 setCropType(CropToolType(configGroup.readEntry("cropType", 0)));
165
167
168 KisSelectionSP sel = resources->activeSelection();
169 if (sel) {
170 m_haveCropSelection = true;
172 }
173 useCursor(cursor());
174
175 //pixel layer
176 if(resources->currentNode() && resources->currentNode()->paintDevice()) {
178 }
179 //vector layer
180 else {
183 }
185 }
186 connect(&m_finalRect, SIGNAL(sigValuesChanged()), SLOT(showSizeOnCanvas()));
187}
188
195
201
206
211
216
221
222void KisToolCrop::canvasResourceChanged(int key, const QVariant &res)
223{
225
226 //pixel layer
227 if(currentNode() && currentNode()->paintDevice()) {
229 }
230 //vector layer
231 else {
234 }
236 }
237}
238
239void KisToolCrop::paint(QPainter &painter, const KoViewConverter &converter)
240{
241 Q_UNUSED(converter);
243}
244
246{
247 if (m_contextMenu) {
248 // Sync state of context menu toggles with state of Tool Options toggles
249 centerToggleOption->setChecked(growCenter());
250 growToggleOption->setChecked(allowGrow());
251 lockWidthToggleOption->setChecked(lockWidth());
252 lockHeightToggleOption->setChecked(lockHeight());
253 lockRatioToggleOption->setChecked(lockRatio());
254
255 m_contextMenu->clear();
256
257 m_contextMenu->addSection(i18n("Crop Tool Actions"));
258 m_contextMenu->addSeparator();
259
260 if (m_haveCropSelection) { // can't crop if there is no selection
261 m_contextMenu->addAction(applyCrop);
262 m_contextMenu->addSeparator();
263 }
264
267
268 m_contextMenu->addSeparator();
269
273 }
274
275 return m_contextMenu.data();
276}
277
279{
282
283 const QPointF imagePoint = convertToPixelCoord(event);
285
288 QPointF snapDocPoint = image()->pixelToDocument(snapPoint);
289 m_dragOffsetDoc = snapDocPoint - event->point;
290 } else {
291 m_dragOffsetDoc = QPointF();
292 }
293
294 QPointF snappedPoint = convertToPixelCoordAndSnap(event, m_dragOffsetDoc);
295
296 m_dragStart = snappedPoint.toPoint();
297 m_resettingStroke = false;
298
301 const int initialWidth = m_finalRect.widthLocked() ? m_finalRect.rect().width() : 1;
302 const int initialHeight = m_finalRect.heightLocked() ? m_finalRect.rect().height() : 1;
303 const QRect initialRect = QRect(m_dragStart, QSize(initialWidth, initialHeight));
304 m_finalRect.setRectInitial(initialRect);
305 m_initialDragRect = initialRect;
307 m_resettingStroke = true;
308 } else {
310 }
311}
312
322
324{
325 bool result = false;
326
327 const KUndo2Command *lastCommand = image()->undoAdapter()->presentCommand();
328 const KisCropSavedExtraData *data = 0;
329
330 if ((lastCommand = image()->undoAdapter()->presentCommand()) &&
331 (data = dynamic_cast<const KisCropSavedExtraData*>(lastCommand->extraData()))) {
332
333 bool cropImageConsistent =
337
338 bool cropLayerConsistent =
341 currentNode() == data->cropNode();
342
343
344 if (cropImageConsistent || cropLayerConsistent) {
346 image()->waitForDone();
347
349 m_haveCropSelection = true;
350
351 result = true;
352 }
353 }
354
355 return result;
356}
357
359{
362
363 QRectF viewCropRect = pixelToView(m_finalRect.rect());
364 const bool haveValidRect =
365 viewCropRect.width() > m_handleSize &&
366 viewCropRect.height() > m_handleSize;
367
368
369 if (!m_haveCropSelection && !haveValidRect) {
372 m_haveCropSelection = true;
373 }
374 } else if (m_resettingStroke && !haveValidRect) {
376 m_haveCropSelection = false;
377 } else {
378 m_haveCropSelection = true;
379 }
380
382
385}
386
388{
389 QPointF pos = convertToPixelCoordAndSnap(event);
390
391 if (m_haveCropSelection) { //if the crop selection is set
392 //set resize cursor if we are on one of the handles
393 if(mode() == KisTool::PAINT_MODE) {
394 //keep the same cursor as the one we clicked with
396 }else{
397 //hovering
398 qint32 type = mouseOnHandle(pixelToView(pos));
400 }
401 }
402}
403
405{
407
408 // this action will have no continuation
409 event->ignore();
410}
411
412
413#define BORDER_LINE_WIDTH 0
414#define HALF_BORDER_LINE_WIDTH 0
415#define HANDLE_BORDER_LINE_WIDTH 1
416
418{
419 QRectF borderRect = pixelToView(m_finalRect.rect());
420
421 // Draw the border line right next to the crop rectangle perimeter.
423
424 return borderRect;
425}
426
427#define OUTSIDE_CROP_ALPHA 200
428
430{
432 gc.save();
433
434 QRectF wholeImageRect = pixelToView(image()->bounds());
435 QRectF borderRect = borderLineRect();
436
437 QPainterPath path;
438
439 path.addRect(wholeImageRect);
440 path.addRect(borderRect);
441 gc.setPen(Qt::NoPen);
442 gc.setBrush(m_transparentBlack);
443 gc.drawPath(path);
444
445 // Handles
446 QPen pen(Qt::SolidLine);
448 pen.setColor(m_black);
449 pen.setCosmetic(true);
450 gc.setPen(pen);
451 gc.setBrush(m_transparentGrey);
452 gc.drawPath(handlesPath());
453
454 gc.setClipRect(borderRect, Qt::IntersectClip);
455
456 if (m_decoration > 0) {
457 for (int i = decorsIndex[m_decoration-1]; i<decorsIndex[m_decoration]; i++) {
458 drawDecorationLine(&gc, &(decors[i]), borderRect);
459 }
460 }
461 gc.restore();
462 }
463}
464
466{
468 if (m_finalRect.rect().isEmpty()) return;
469
470 const bool imageCrop = m_cropType == ImageCropType || m_cropType == CanvasCropType;
471
472 if (!imageCrop) {
473 //Cropping layer
474 if (!nodeEditable()) {
475 return;
476 }
477 }
478
479 m_haveCropSelection = false;
480 useCursor(cursor());
481
482 QRect cropRect = m_finalRect.rect();
483
484 // The visitor adds the undo steps to the macro
485 if (imageCrop || !currentNode()->paintDevice()) {
486 if (m_cropType == CanvasCropType) {
487 currentImage()->resizeImage(cropRect);
488 } else {
489 currentImage()->cropImage(cropRect);
490 }
491 } else {
493 }
494}
495
497{
499}
500
502{
503 if(m_cropType == cropType)
504 return;
506
507 configGroup.writeEntry("cropType", static_cast<int>(cropType));
508
510}
511
516
518{
519 if(selectable == m_cropTypeSelectable)
520 return;
521 m_cropTypeSelectable = selectable;
523}
524
526{
528}
529
531{
532 return m_decoration;
533}
534
536{
537 // This shouldn't happen, but safety first
538 if(i < 0 || i > DECORATION_COUNT)
539 return;
540 m_decoration = i;
543
544 configGroup.writeEntry("decoration", i);
545}
546
547void KisToolCrop::doCanvasUpdate(const QRect &updateRect)
548{
550 m_lastCanvasUpdateRect = updateRect;
551}
552
554{
556 Q_EMIT cropWidthChanged(cropWidth());
557 Q_EMIT cropXChanged(cropX());
558 Q_EMIT cropYChanged(cropY());
559 Q_EMIT ratioChanged(ratio());
561 Q_EMIT lockWidthChanged(lockWidth());
562 Q_EMIT lockRatioChanged(lockRatio());
563
564 Q_EMIT canGrowChanged(allowGrow());
566
567 doCanvasUpdate(boundingRect().toAlignedRect());
568}
569
571{
572 KisCanvas2 *kisCanvas =dynamic_cast<KisCanvas2*>(canvas());
573 if (!kisCanvas) return;
574
575 KoColor c;
576 c.fromQColor(QColor(Qt::black));
578 c.fromQColor(QColor(0, 0, 0, OUTSIDE_CROP_ALPHA));
580 c.fromQColor(QColor(200, 200, 200, OUTSIDE_CROP_ALPHA));
582}
583
585{
586 if(x == m_finalRect.rect().x())
587 return;
588
589 if (!m_haveCropSelection) {
590 m_haveCropSelection = true;
592 }
593
594 QPoint offset = m_finalRect.rect().topLeft();
595 offset.setX(x);
596 m_finalRect.setOffset(offset);
597}
598
600{
601 return m_finalRect.rect().x();
602}
603
605{
606 if(y == m_finalRect.rect().y())
607 return;
608
609 if (!m_haveCropSelection) {
610 m_haveCropSelection = true;
612 }
613
614 QPoint offset = m_finalRect.rect().topLeft();
615 offset.setY(y);
616 m_finalRect.setOffset(offset);
617}
618
620{
621 return m_finalRect.rect().y();
622}
623
625{
626 if(w == m_finalRect.rect().width())
627 return;
628
629 if (!m_haveCropSelection) {
630 m_haveCropSelection = true;
632 }
633
635}
636
638{
639 return m_finalRect.rect().width();
640}
641
643{
645}
646
648{
649 return m_finalRect.widthLocked();
650}
651
653{
654 if(h == m_finalRect.rect().height())
655 return;
656
657 if (!m_haveCropSelection) {
658 m_haveCropSelection = true;
660 }
661
663}
664
666{
667 return m_finalRect.rect().height();
668}
669
671{
673}
674
676{
677 return m_finalRect.heightLocked();
678}
679
681{
684 configGroup.writeEntry("allowGrow", g);
685
686 // Do a dummy move for the crop area to snap back to the canvas if grow is no longer allowed
687 if (!g) {
689 }
690
691 Q_EMIT canGrowChanged(g);
692}
693
695{
696 return m_finalRect.canGrow();
697}
698
700{
702
703
704 configGroup.writeEntry("growCenter", value);
705
706 Q_EMIT isCenteredChanged(value);
707}
708
710{
711 return m_finalRect.centered();
712}
713
714void KisToolCrop::setRatio(double ratio)
715{
716 if(ratio == m_finalRect.ratio())
717 return;
718
719 if (!m_haveCropSelection) {
720 m_haveCropSelection = true;
722 }
723
725}
726
727double KisToolCrop::ratio() const
728{
729 return m_finalRect.ratio();
730}
731
733{
735}
736
738{
739 return m_finalRect.ratioLocked();
740}
741
743{
744 KisCanvas2 *kisCanvas =dynamic_cast<KisCanvas2*>(canvas());
745 Q_ASSERT(kisCanvas);
746 if(m_mouseOnHandleType == 9) {
747 kisCanvas->viewManager()->showFloatingMessage(i18n("X: %1\nY: %2"
748 , optionsWidget->intX->text(), optionsWidget->intY->text())
749 , QIcon(), 1000, KisFloatingMessage::High, Qt::AlignLeft | Qt::TextWordWrap | Qt::AlignVCenter);
750 }
751 else {
752 kisCanvas->viewManager()->showFloatingMessage(i18n("Width: %1\nHeight: %2"
753 , optionsWidget->intWidth->text(), optionsWidget->intHeight->text())
754 , QIcon(), 1000, KisFloatingMessage::High, Qt::AlignLeft | Qt::TextWordWrap | Qt::AlignVCenter);
755 }
756}
757
759{
761 // See https://bugs.kde.org/show_bug.cgi?id=316896
762 QWidget *specialSpacer = new QWidget(optionsWidget);
763 specialSpacer->setObjectName("SpecialSpacer");
764 specialSpacer->setFixedSize(0, 0);
765 optionsWidget->layout()->addWidget(specialSpacer);
766
767 Q_CHECK_PTR(optionsWidget);
768 optionsWidget->setObjectName(toolId() + " option widget");
769
770 connect(optionsWidget->bnCrop, SIGNAL(clicked()), this, SLOT(crop()));
771
772 connect(optionsWidget, SIGNAL(cropTypeChanged(int)), this, SLOT(setCropTypeLegacy(int)));
773 connect(optionsWidget, SIGNAL(cropXChanged(int)), this, SLOT(setCropX(int)));
774 connect(optionsWidget, SIGNAL(cropYChanged(int)), this, SLOT(setCropY(int)));
775 connect(optionsWidget, SIGNAL(cropHeightChanged(int)), this, SLOT(setCropHeight(int)));
776 connect(optionsWidget, SIGNAL(lockHeightChanged(bool)), this, SLOT(setLockHeight(bool)));
777 connect(optionsWidget, SIGNAL(cropWidthChanged(int)), this, SLOT(setCropWidth(int)));
778 connect(optionsWidget, SIGNAL(lockWidthChanged(bool)), this, SLOT(setLockWidth(bool)));
779 connect(optionsWidget, SIGNAL(ratioChanged(double)), this, SLOT(setRatio(double)));
780 connect(optionsWidget, SIGNAL(lockRatioChanged(bool)), this, SLOT(setLockRatio(bool)));
781 connect(optionsWidget, SIGNAL(decorationChanged(int)), this, SLOT(setDecoration(int)));
782 connect(optionsWidget, SIGNAL(allowGrowChanged(bool)), this, SLOT(setAllowGrow(bool)));
783 connect(optionsWidget, SIGNAL(growCenterChanged(bool)), this, SLOT(setGrowCenter(bool)));
784
785 optionsWidget->setFixedHeight(optionsWidget->sizeHint().height());
786
787 connect(applyCrop, SIGNAL(triggered(bool)), this, SLOT(crop()));
788 connect(centerToggleOption, SIGNAL(triggered(bool)), this, SLOT(setGrowCenter(bool)));
789 connect(growToggleOption, SIGNAL(triggered(bool)), this, SLOT(setAllowGrow(bool)));
790 connect(lockWidthToggleOption, SIGNAL(triggered(bool)), this, SLOT(setLockWidth(bool)));
791 connect(lockHeightToggleOption, SIGNAL(triggered(bool)), this, SLOT(setLockHeight(bool)));
792 connect(lockRatioToggleOption, SIGNAL(triggered(bool)), this, SLOT(setLockRatio(bool)));
793
794 return optionsWidget;
795}
796
797QRectF KisToolCrop::lowerRightHandleRect(QRectF cropBorderRect)
798{
799 return QRectF(cropBorderRect.right() - m_handleSize / 2.0, cropBorderRect.bottom() - m_handleSize / 2.0, m_handleSize, m_handleSize);
800}
801
802QRectF KisToolCrop::upperRightHandleRect(QRectF cropBorderRect)
803{
804 return QRectF(cropBorderRect.right() - m_handleSize / 2.0 , cropBorderRect.top() - m_handleSize / 2.0, m_handleSize, m_handleSize);
805}
806
807QRectF KisToolCrop::lowerLeftHandleRect(QRectF cropBorderRect)
808{
809 return QRectF(cropBorderRect.left() - m_handleSize / 2.0 , cropBorderRect.bottom() - m_handleSize / 2.0, m_handleSize, m_handleSize);
810}
811
812QRectF KisToolCrop::upperLeftHandleRect(QRectF cropBorderRect)
813{
814 return QRectF(cropBorderRect.left() - m_handleSize / 2.0, cropBorderRect.top() - m_handleSize / 2.0, m_handleSize, m_handleSize);
815}
816
817QRectF KisToolCrop::lowerHandleRect(QRectF cropBorderRect)
818{
819 return QRectF(cropBorderRect.left() + (cropBorderRect.width() - m_handleSize) / 2.0 , cropBorderRect.bottom() - m_handleSize / 2.0, m_handleSize, m_handleSize);
820}
821
822QRectF KisToolCrop::rightHandleRect(QRectF cropBorderRect)
823{
824 return QRectF(cropBorderRect.right() - m_handleSize / 2.0 , cropBorderRect.top() + (cropBorderRect.height() - m_handleSize) / 2.0, m_handleSize, m_handleSize);
825}
826
827QRectF KisToolCrop::upperHandleRect(QRectF cropBorderRect)
828{
829 return QRectF(cropBorderRect.left() + (cropBorderRect.width() - m_handleSize) / 2.0 , cropBorderRect.top() - m_handleSize / 2.0, m_handleSize, m_handleSize);
830}
831
832QRectF KisToolCrop::leftHandleRect(QRectF cropBorderRect)
833{
834 return QRectF(cropBorderRect.left() - m_handleSize / 2.0, cropBorderRect.top() + (cropBorderRect.height() - m_handleSize) / 2.0, m_handleSize, m_handleSize);
835}
836
838{
839 QRectF cropBorderRect = borderLineRect();
840 QPainterPath path;
841
842 path.addRect(upperLeftHandleRect(cropBorderRect));
843 path.addRect(upperRightHandleRect(cropBorderRect));
844 path.addRect(lowerLeftHandleRect(cropBorderRect));
845 path.addRect(lowerRightHandleRect(cropBorderRect));
846 path.addRect(upperHandleRect(cropBorderRect));
847 path.addRect(lowerHandleRect(cropBorderRect));
848 path.addRect(leftHandleRect(cropBorderRect));
849 path.addRect(rightHandleRect(cropBorderRect));
850
851 return path;
852}
853
854qint32 KisToolCrop::mouseOnHandle(QPointF currentViewPoint)
855{
856 QRectF borderRect = borderLineRect();
857 qint32 handleType = None;
858
859 if (!m_haveCropSelection) {
860 return None;
861 }
862
863 if (upperLeftHandleRect(borderRect).contains(currentViewPoint)) {
865 } else if (lowerLeftHandleRect(borderRect).contains(currentViewPoint)) {
867 } else if (upperRightHandleRect(borderRect).contains(currentViewPoint)) {
869 } else if (lowerRightHandleRect(borderRect).contains(currentViewPoint)) {
871 } else if (upperHandleRect(borderRect).contains(currentViewPoint)) {
873 } else if (lowerHandleRect(borderRect).contains(currentViewPoint)) {
875 } else if (leftHandleRect(borderRect).contains(currentViewPoint)) {
877 } else if (rightHandleRect(borderRect).contains(currentViewPoint)) {
879 } else if (borderRect.contains(currentViewPoint)) {
881 }
882
883 return handleType;
884}
885
887{
888 QCursor cursorType;
889
890 switch (handle) {
891 case(UpperLeft):
892 case(LowerRight):
893 cursorType = KisCursor::sizeFDiagCursor();
894 break;
895 case(LowerLeft):
896 case(UpperRight):
897 cursorType = KisCursor::sizeBDiagCursor();
898 break;
899 case(Upper):
900 case(Lower):
901 cursorType = KisCursor::sizeVerCursor();
902 break;
903 case(Left):
904 case(Right):
905 cursorType = KisCursor::sizeHorCursor();
906 break;
907 case(Inside):
908 cursorType = KisCursor::sizeAllCursor();
909 break;
910 default:
912 cursorType = KisCursor::arrowCursor();
913 } else {
914 cursorType = cursor();
915 }
916 break;
917 }
918 useCursor(cursorType);
919}
920
927
928void KisToolCrop::drawDecorationLine(QPainter *p, DecorationLine *decorLine, const QRectF rect)
929{
930 QPointF start = rect.topLeft();
931 QPointF end = rect.topLeft();
932 qreal small = qMin(rect.width(), rect.height());
933 qreal large = qMax(rect.width(), rect.height());
934
935 switch (decorLine->startXRelation) {
937 start.setX(start.x() + decorLine->start.x() * rect.width());
938 break;
940 start.setX(start.x() + decorLine->start.x() * rect.height());
941 break;
943 start.setX(start.x() + decorLine->start.x() * small);
944 break;
946 start.setX(start.x() + decorLine->start.x() * large);
947 break;
948 }
949
950 switch (decorLine->startYRelation) {
952 start.setY(start.y() + decorLine->start.y() * rect.width());
953 break;
955 start.setY(start.y() + decorLine->start.y() * rect.height());
956 break;
958 start.setY(start.y() + decorLine->start.y() * small);
959 break;
961 start.setY(start.y() + decorLine->start.y() * large);
962 break;
963 }
964
965 switch (decorLine->endXRelation) {
967 end.setX(end.x() + decorLine->end.x() * rect.width());
968 break;
970 end.setX(end.x() + decorLine->end.x() * rect.height());
971 break;
973 end.setX(end.x() + decorLine->end.x() * small);
974 break;
976 end.setX(end.x() + decorLine->end.x() * large);
977 break;
978 }
979
980 switch (decorLine->endYRelation) {
982 end.setY(end.y() + decorLine->end.y() * rect.width());
983 break;
985 end.setY(end.y() + decorLine->end.y() * rect.height());
986 break;
988 end.setY(end.y() + decorLine->end.y() * small);
989 break;
991 end.setY(end.y() + decorLine->end.y() * large);
992 break;
993 }
994
995 p->drawLine(start, end);
996}
float value(const T *src, size_t ch)
const Params2D p
KUndo2CommandExtraData * extraData() const
KisDisplayColorConverter displayColorConverter
KisViewManager * viewManager() const
void moveHandle(HandleType handle, const QPoint &offset, const QRect &oldRect)
void setRectInitial(const QRect &rect)
QPointF handleSnapPoint(HandleType handle, const QPointF &cursorPos)
void setCropRect(const QRect &cropRect)
void setCentered(bool value)
void setCanGrow(bool value)
void setOffset(const QPoint &offset)
void setHeightLocked(bool value)
void setRatioLocked(bool value)
void setWidthLocked(bool value)
static QCursor sizeBDiagCursor()
Definition kis_cursor.cc:74
static QCursor sizeAllCursor()
Definition kis_cursor.cc:84
static QCursor sizeHorCursor()
Definition kis_cursor.cc:69
static QCursor sizeFDiagCursor()
Definition kis_cursor.cc:79
static QCursor arrowCursor()
Definition kis_cursor.cc:24
static QCursor sizeVerCursor()
Definition kis_cursor.cc:64
QColor convertColorToDisplayColorSpace(const KoColor color, bool applyOcio=false) const
convertColorToDisplayColorSpace This applies displayfiltering to the given KoColor,...
void resizeImage(const QRect &newRect)
start asynchronous operation on resizing the image
Definition kis_image.cc:866
KisUndoAdapter * undoAdapter() const
void waitForDone()
void cropNode(KisNodeSP node, const QRect &newRect, const bool activeFrameOnly=false)
start asynchronous operation on cropping a subtree of nodes starting at node
Definition kis_image.cc:987
QPointF pixelToDocument(const QPointF &pixelCoord) const
void cropImage(const QRect &newRect)
start asynchronous operation on cropping the image
Definition kis_image.cc:871
QRect bounds() const override
The KisResourcesSnapshot class takes a snapshot of the various resources like colors and settings use...
KisSelectionSP activeSelection() const
void requestStrokeCancellation() override
void setAllowGrow(bool g)
KisAction * lockRatioToggleOption
bool m_resettingStroke
void requestUndoDuringStroke() override
void setGrowCenter(bool g)
void cropWidthChanged(int value)
bool tryContinueLastCropAction()
QRectF lowerRightHandleRect(QRectF cropBorderRect)
void requestRedoDuringStroke() override
QWidget * createOptionWidget() override
void paint(QPainter &painter, const KoViewConverter &converter) override
void slotRectChanged()
void requestStrokeEnd() override
QRect m_lastCanvasUpdateRect
bool m_cropTypeSelectable
void setLockHeight(bool lock)
void setCropHeight(int y)
KisAction * centerToggleOption
QRect m_initialDragRect
void decorationChanged(int value)
QRectF upperRightHandleRect(QRectF cropBorderRect)
void setCropX(int x)
QColor m_transparentBlack
KisToolCrop(KoCanvasBase *canvas)
QColor m_transparentGrey
void setCropType(CropToolType cropType)
KisAction * lockHeightToggleOption
void cropTypeChanged(int value)
void ratioChanged(double value)
void beginPrimaryAction(KoPointerEvent *event) override
bool growCenter() const
void setMoveResizeCursor(qint32 handle)
~KisToolCrop() override
void activate(const QSet< KoShape * > &shapes) override
void setCropTypeLegacy(int cropType)
void cropXChanged(int value)
CropToolType m_cropType
QRectF lowerLeftHandleRect(QRectF cropBorderRect)
QRectF upperHandleRect(QRectF cropBorderRect)
void doCanvasUpdate(const QRect &updateRect)
qint32 mouseOnHandle(const QPointF currentViewPoint)
QPoint m_dragStart
QMenu * popupActionsMenu() override
void deactivate() override
void canGrowChanged(bool value)
void canvasResourceChanged(int key, const QVariant &res) override
void updateDecorationColors()
void setDecoration(int i)
void continuePrimaryAction(KoPointerEvent *event) override
qint32 m_handleSize
CropToolType cropType
KisToolCropConfigWidget * optionsWidget
QRectF leftHandleRect(QRectF cropBorderRect)
void mouseMoveEvent(KoPointerEvent *e) override
QRectF boundingRect()
void setRatio(double ratio)
QRectF borderLineRect()
void endPrimaryAction(KoPointerEvent *event) override
void lockRatioChanged(bool value)
qint32 m_mouseOnHandleType
KConfigGroup configGroup
void isCenteredChanged(bool value)
void cancelStroke()
QRectF rightHandleRect(QRectF cropBorderRect)
void drawDecorationLine(QPainter *p, DecorationLine *decorLine, QRectF rect)
void cropYChanged(int value)
void setCropWidth(int x)
bool m_haveCropSelection
QPointF m_dragOffsetDoc
bool cropTypeSelectable
void cropHeightChanged(int value)
void setCropY(int y)
KisAction * applyCrop
QRectF lowerHandleRect(QRectF cropBorderRect)
bool allowGrow() const
KisAction * growToggleOption
QScopedPointer< QMenu > m_contextMenu
KisAction * lockWidthToggleOption
void paintOutlineWithHandles(QPainter &gc)
QPainterPath handlesPath()
void cropTypeSelectableChanged()
void lockHeightChanged(bool value)
QRectF upperLeftHandleRect(QRectF cropBorderRect)
KisConstrainedRect m_finalRect
void showSizeOnCanvas()
void setLockWidth(bool lock)
void lockWidthChanged(bool value)
void setLockRatio(bool lock)
void setCropTypeSelectable(bool selectable)
void beginPrimaryDoubleClickAction(KoPointerEvent *event) override
virtual void undoLastCommand()=0
virtual const KUndo2Command * presentCommand()=0
void showFloatingMessage(const QString &message, const QIcon &icon, int timeout=4500, KisFloatingMessage::Priority priority=KisFloatingMessage::Medium, int alignment=Qt::AlignCenter|Qt::TextWordWrap)
shows a floating message in the top right corner of the canvas
void fromQColor(const QColor &c)
Convenient function for converting from a QColor.
Definition KoColor.cpp:213
Q_INVOKABLE QString toolId() const
void useCursor(const QCursor &cursor)
int decorationThickness() const
decorationThickness The minimum thickness for tool decoration lines, this is derived from the screen ...
#define KIS_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:75
#define bounds(x, a, b)
#define CHECK_MODE_SANITY_OR_RETURN(_mode)
Definition kis_tool.h:27
#define OUTSIDE_CROP_ALPHA
#define DECORATION_COUNT
#define HANDLE_BORDER_LINE_WIDTH
#define HALF_BORDER_LINE_WIDTH
DecorationLine decors[20]
const int decorsIndex[DECORATION_COUNT]
Relation endYRelation
Relation startXRelation
Relation endXRelation
Relation startYRelation
virtual KisPaintDeviceSP paintDevice() const =0
QRect selectedExactRect() const
Slow, but exact way of determining the rectangle that encloses the selection.
QPointF convertToPixelCoord(KoPointerEvent *e)
Definition kis_tool.cc:189
virtual ToolMode mode() const
Definition kis_tool.cc:407
KisImageWSP currentImage()
Definition kis_tool.cc:393
bool nodeEditable()
Checks checks if the current node is editable.
Definition kis_tool.cc:651
QPointF pixelToView(const QPoint &pixelCoord) const
Definition kis_tool.cc:269
KisNodeSP currentNode() const
Definition kis_tool.cc:370
void canvasResourceChanged(int key, const QVariant &res) override
Definition kis_tool.cc:139
void activate(const QSet< KoShape * > &shapes) override
Definition kis_tool.cc:93
void deactivate() override
Definition kis_tool.cc:131
KisImageWSP image() const
Definition kis_tool.cc:332
@ PAINT_MODE
Definition kis_tool.h:300
@ HOVER_MODE
Definition kis_tool.h:299
QPointF convertToPixelCoordAndSnap(KoPointerEvent *e, const QPointF &offset=QPointF(), bool useModifiers=true)
Definition kis_tool.cc:214
void updateCanvasViewRect(const QRectF &viewRect)
Update the canvas for the given rectangle in view coordinates.
Definition kis_tool.cc:327
QCursor cursor
Definition kis_tool.cc:64
virtual void setMode(ToolMode mode)
Definition kis_tool.cc:403
KisCanvas2 * canvas