summaryrefslogtreecommitdiffstats
path: root/krita/plugins/tools/tool_crop/kis_tool_crop.cc
diff options
context:
space:
mode:
Diffstat (limited to 'krita/plugins/tools/tool_crop/kis_tool_crop.cc')
-rw-r--r--krita/plugins/tools/tool_crop/kis_tool_crop.cc925
1 files changed, 925 insertions, 0 deletions
diff --git a/krita/plugins/tools/tool_crop/kis_tool_crop.cc b/krita/plugins/tools/tool_crop/kis_tool_crop.cc
new file mode 100644
index 00000000..fd83e204
--- /dev/null
+++ b/krita/plugins/tools/tool_crop/kis_tool_crop.cc
@@ -0,0 +1,925 @@
+/*
+ * kis_tool_crop.cc -- part of Krita
+ *
+ * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
+ * Copyright (c) 2005 Michael Thaler <michael.thaler@physik.tu-muenchen.de>
+ * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net>
+ *
+ * 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 <qcheckbox.h>
+#include <qcombobox.h>
+#include <qobject.h>
+#include <qpainter.h>
+#include <qpen.h>
+#include <qpushbutton.h>
+#include <qrect.h>
+
+#include <kdebug.h>
+#include <kaction.h>
+#include <kcommand.h>
+#include <klocale.h>
+#include <knuminput.h>
+#include <kdebug.h>
+
+#include <kis_global.h>
+#include <kis_painter.h>
+#include <kis_canvas_controller.h>
+#include <kis_canvas_subject.h>
+#include <kis_cursor.h>
+#include <kis_image.h>
+#include <kis_undo_adapter.h>
+#include <kis_button_press_event.h>
+#include <kis_button_release_event.h>
+#include <kis_move_event.h>
+#include <kis_selected_transaction.h>
+#include <kis_selection.h>
+#include <kis_layer.h>
+#include <kis_crop_visitor.h>
+
+#include "kis_tool_crop.h"
+#include "wdg_tool_crop.h"
+
+#include "kis_canvas.h"
+#include "kis_canvas_painter.h"
+
+
+
+KisToolCrop::KisToolCrop()
+ : super(i18n("Crop"))
+{
+ setName("tool_crop");
+ m_cropCursor = KisCursor::load("tool_crop_cursor.png", 6, 6);
+ setCursor(m_cropCursor);
+ m_subject = 0;
+ m_selecting = false;
+ m_rectCrop = QRect(0, 0, 0, 0);
+ m_handleSize = 13;
+ m_haveCropSelection = false;
+ m_optWidget = 0;
+}
+
+KisToolCrop::~KisToolCrop()
+{
+}
+
+void KisToolCrop::update(KisCanvasSubject *subject)
+{
+ m_subject = subject;
+ super::update(m_subject);
+}
+
+void KisToolCrop::activate()
+{
+ super::activate();
+
+ // No current crop rectangle, try to use the selection of the device to make a rectangle
+ if (m_subject && m_subject->currentImg() && m_subject->currentImg()->activeDevice()) {
+ KisPaintDeviceSP device = m_subject->currentImg()->activeDevice();
+ if (!device->hasSelection()) {
+ //m_rectCrop = m_subject->currentImg()->bounds();
+ //validateSelection();
+ m_haveCropSelection = false;
+ m_selecting = false;
+ }
+ else {
+
+ m_rectCrop = device->selection()->selectedRect();
+ validateSelection();
+ crop();
+ }
+ }
+}
+
+void KisToolCrop::deactivate()
+{
+ clearRect();
+}
+
+
+void KisToolCrop::paint(KisCanvasPainter& gc)
+{
+ paintOutlineWithHandles(gc, QRect());
+}
+
+void KisToolCrop::paint(KisCanvasPainter& gc, const QRect& rc)
+{
+ paintOutlineWithHandles(gc, rc);
+}
+
+void KisToolCrop::clearRect()
+{
+ kdDebug() << "Clearing\n";
+ if (m_subject) {
+
+ KisCanvasController *controller = m_subject->canvasController();
+ KisImageSP img = m_subject->currentImg();
+
+ Q_ASSERT(controller);
+
+ controller->kiscanvas()->update();
+
+ m_rectCrop = QRect(0,0,0,0);
+
+ updateWidgetValues();
+ m_selecting = false;
+ }
+}
+
+void KisToolCrop::buttonPress(KisButtonPressEvent *e)
+{
+ if (m_subject) {
+ KisImageSP img = m_subject->currentImg();
+
+ if (img && img->activeDevice() && e->button() == LeftButton) {
+
+ QPoint pos = e->pos().floorQPoint();
+ QRect b = img->bounds();
+
+ if (pos.x() < b.x())
+ pos.setX(b.x());
+ else if (pos.x() > b.x() + b.width())
+ pos.setX(b.x() + b.width());
+
+ if (pos.y() < b.y())
+ pos.setY(b.y());
+ else if (pos.y() > b.y() + b.height())
+ pos.setY(b.y() + b.height());
+
+ m_selecting = true;
+
+ if( !m_haveCropSelection ) //if the selection is not set
+ {
+ m_rectCrop = QRect( pos.x(), pos.y(), 0, 0);
+ paintOutlineWithHandles();
+ }
+ else
+ {
+ KisCanvasController *controller = m_subject->canvasController();
+ m_mouseOnHandleType = mouseOnHandle(controller ->windowToView(pos));
+ m_dragStart = pos;
+ }
+
+ updateWidgetValues();
+ }
+ }
+}
+
+void KisToolCrop::move(KisMoveEvent *e)
+{
+ if ( m_subject && m_subject->currentImg())
+ {
+ if( m_selecting ) //if the user selects
+ {
+ if( !m_haveCropSelection ) //if the cropSelection is not yet set
+ {
+ paintOutlineWithHandles();
+
+ m_rectCrop.setBottomRight( e->pos().floorQPoint());
+
+ KisImageSP image = m_subject->currentImg();
+
+ m_rectCrop.setRight( QMIN(m_rectCrop.right(), image->width()));
+ m_rectCrop.setBottom( QMIN(m_rectCrop.bottom(), image->width()));
+ m_rectCrop = m_rectCrop.normalize();
+
+ paintOutlineWithHandles();
+ }
+ else //if the crop selection is set
+ {
+ m_dragStop = e->pos().floorQPoint();
+ if (m_mouseOnHandleType != None && m_dragStart != m_dragStop ) {
+
+
+ Q_INT32 imageWidth = m_subject->currentImg()->width();
+ Q_INT32 imageHeight = m_subject->currentImg()->height();
+
+ paintOutlineWithHandles();
+
+ QPoint pos = e->pos().floorQPoint();
+ if( m_mouseOnHandleType == Inside )
+ {
+ m_rectCrop.moveBy( ( m_dragStop.x() - m_dragStart.x() ), ( m_dragStop.y() - m_dragStart.y() ) );
+ if( m_rectCrop.left() < 0 )
+ {
+ m_rectCrop.moveLeft( 0 );
+ }
+ if( m_rectCrop.right() > imageWidth )
+ {
+ m_rectCrop.moveRight( imageWidth );
+ }
+ if( m_rectCrop.top() < 0 )
+ {
+ m_rectCrop.moveTop( 0 );
+ }
+ if( m_rectCrop.bottom() > imageHeight )
+ {
+ m_rectCrop.moveBottom( imageHeight );
+ }
+ } else if(m_optWidget->boolRatio->isChecked())
+ {
+ QPoint drag = m_dragStop - m_dragStart;
+ if( ! m_optWidget->boolWidth->isChecked() && !m_optWidget->boolHeight->isChecked() )
+ {
+ switch (m_mouseOnHandleType)
+ {
+ case (UpperLeft):
+ {
+ Q_INT32 dep = (drag.x() + drag.y()) / 2;
+ m_rectCrop.setTop( m_rectCrop.top() + dep );
+ m_rectCrop.setLeft( (int) ( m_rectCrop.right() - m_optWidget->doubleRatio->value() * m_rectCrop.height() ) );
+ }
+ break;
+ case (LowerRight):
+ {
+ Q_INT32 dep = (drag.x() + drag.y()) / 2;
+ m_rectCrop.setBottom( m_rectCrop.bottom() + dep );
+ m_rectCrop.setWidth( (int) ( m_optWidget->doubleRatio->value() * m_rectCrop.height() ) );
+ break;
+ }
+ case (UpperRight):
+ {
+ Q_INT32 dep = (drag.x() - drag.y()) / 2;
+ m_rectCrop.setTop( m_rectCrop.top() - dep );
+ m_rectCrop.setWidth( (int) ( m_optWidget->doubleRatio->value() * m_rectCrop.height() ) );
+ break;
+ }
+ case (LowerLeft):
+ {
+ Q_INT32 dep = (drag.x() - drag.y()) / 2;
+ m_rectCrop.setBottom( m_rectCrop.bottom() - dep );
+ m_rectCrop.setLeft( (int) ( m_rectCrop.right() - m_optWidget->doubleRatio->value() * m_rectCrop.height() ) );
+ break;
+ }
+ case (Upper):
+ m_rectCrop.setTop( pos.y() + m_dy );
+ m_rectCrop.setWidth( (int) (m_rectCrop.height() * m_optWidget->doubleRatio->value()) );
+ break;
+ case (Lower):
+ m_rectCrop.setBottom( pos.y() + m_dy );
+ m_rectCrop.setWidth( (int) (m_rectCrop.height() * m_optWidget->doubleRatio->value()) );
+ break;
+ case (Left):
+ m_rectCrop.setLeft( pos.x() + m_dx );
+ m_rectCrop.setHeight( (int) (m_rectCrop.width() / m_optWidget->doubleRatio->value()) );
+ break;
+ case (Right):
+ m_rectCrop.setRight( pos.x() + m_dx );
+ m_rectCrop.setHeight( (int) (m_rectCrop.width() / m_optWidget->doubleRatio->value()) );
+ break;
+ case (Inside): // never happen
+ break;
+ }
+ }
+ } else {
+ if( m_optWidget->boolWidth->isChecked() )
+ {
+ m_rectCrop.setWidth( m_optWidget->intWidth->value() + 1 );
+ } else {
+ switch (m_mouseOnHandleType)
+ {
+ case (LowerLeft):
+ case (Left):
+ case (UpperLeft):
+ m_rectCrop.setLeft( pos.x() + m_dx );
+ break;
+ case (Right):
+ case (UpperRight):
+ case (LowerRight):
+ m_rectCrop.setRight( pos.x() + m_dx );
+ break;
+ default:
+ break;
+ }
+ }
+ if( m_optWidget->boolHeight->isChecked() )
+ {
+ m_rectCrop.setHeight( m_optWidget->intHeight->value() + 1 );
+ } else {
+ switch (m_mouseOnHandleType)
+ {
+ case (UpperLeft):
+ case (Upper):
+ case (UpperRight):
+ m_rectCrop.setTop( pos.y() + m_dy );
+ break;
+ case (LowerRight):
+ case (LowerLeft):
+ case (Lower):
+ m_rectCrop.setBottom( pos.y() + m_dy );
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ if( m_rectCrop.height() < 0)
+ {
+ if( m_mouseOnHandleType == Lower)
+ m_mouseOnHandleType = Upper;
+ else if( m_mouseOnHandleType == LowerLeft)
+ m_mouseOnHandleType = UpperLeft;
+ else if( m_mouseOnHandleType == LowerRight)
+ m_mouseOnHandleType = UpperRight;
+ else if( m_mouseOnHandleType == Upper)
+ m_mouseOnHandleType = Lower;
+ else if( m_mouseOnHandleType == UpperLeft)
+ m_mouseOnHandleType = LowerLeft;
+ else if( m_mouseOnHandleType == UpperRight)
+ m_mouseOnHandleType = LowerRight;
+ }
+ if( m_rectCrop.width() < 0)
+ {
+ if( m_mouseOnHandleType == Right)
+ m_mouseOnHandleType = Left;
+ else if( m_mouseOnHandleType == UpperRight)
+ m_mouseOnHandleType = UpperLeft;
+ else if( m_mouseOnHandleType == LowerRight)
+ m_mouseOnHandleType = LowerLeft;
+ else if( m_mouseOnHandleType == Left)
+ m_mouseOnHandleType = Right;
+ else if( m_mouseOnHandleType == UpperLeft)
+ m_mouseOnHandleType = UpperRight;
+ else if( m_mouseOnHandleType == LowerLeft)
+ m_mouseOnHandleType = LowerRight;
+ }
+
+ m_rectCrop = m_rectCrop.normalize();
+ m_rectCrop = m_rectCrop.intersect( QRect(0,0, imageWidth + 1, imageHeight + 1 ) );
+ m_dragStart = e->pos().floorQPoint();
+ paintOutlineWithHandles();
+ }
+ }
+ updateWidgetValues();
+ }
+ else //if we are not selecting
+ {
+ if ( m_haveCropSelection ) //if the crop selection is set
+ {
+ KisCanvasController *controller = m_subject->canvasController();
+ Q_INT32 type = mouseOnHandle(controller->windowToView(e->pos().floorQPoint()));
+ //set resize cursor if we are on one of the handles
+ setMoveResizeCursor(type);
+ }
+ }
+ }
+}
+
+void KisToolCrop::updateWidgetValues(bool updateratio)
+{
+ QRect r = realRectCrop();
+ setOptionWidgetX(r.x());
+ setOptionWidgetY(r.y());
+ setOptionWidgetWidth(r.width() );
+ setOptionWidgetHeight(r.height() );
+ if(updateratio && !m_optWidget->boolRatio->isChecked() )
+ setOptionWidgetRatio((double)r.width() / (double)r.height() );
+}
+
+void KisToolCrop::buttonRelease(KisButtonReleaseEvent *e)
+{
+ if (m_subject && m_subject->currentImg() && m_selecting && e->button() == LeftButton) {
+
+ m_selecting = false;
+ m_haveCropSelection = true;
+
+ paintOutlineWithHandles();
+ validateSelection();
+ paintOutlineWithHandles();
+ }
+}
+
+void KisToolCrop::doubleClick(KisDoubleClickEvent *)
+{
+ if (m_haveCropSelection) crop();
+}
+
+void KisToolCrop::validateSelection(bool updateratio)
+{
+ if (m_subject) {
+ KisImageSP image = m_subject->currentImg();
+
+ if (image) {
+ Q_INT32 imageWidth = image->width();
+ Q_INT32 imageHeight = image->height();
+ m_rectCrop.setLeft(QMAX(0, m_rectCrop.left()));
+ m_rectCrop.setTop(QMAX(0, m_rectCrop.top()));
+ m_rectCrop.setRight(QMIN(imageWidth, m_rectCrop.right()));
+ m_rectCrop.setBottom(QMIN(imageHeight, m_rectCrop.bottom()));
+
+ updateWidgetValues(updateratio);
+ }
+ }
+}
+
+void KisToolCrop::paintOutlineWithHandles()
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+ KisCanvas *canvas = controller->kiscanvas();
+ KisCanvasPainter gc(canvas);
+ QRect rc;
+
+ paintOutlineWithHandles(gc, rc);
+ }
+}
+
+void KisToolCrop::paintOutlineWithHandles(KisCanvasPainter& gc, const QRect&)
+{
+ if (m_subject && (m_selecting || m_haveCropSelection)) {
+ KisCanvasController *controller = m_subject->canvasController();
+ RasterOp op = gc.rasterOp();
+ QPen old = gc.pen();
+ QPen pen(Qt::SolidLine);
+ pen.setWidth(1);
+ QPoint start;
+ QPoint end;
+
+ Q_ASSERT(controller);
+ start = controller->windowToView(m_rectCrop.topLeft());
+ end = controller->windowToView(m_rectCrop.bottomRight());
+
+ gc.setRasterOp(Qt::NotROP);
+ gc.setPen(pen);
+ //draw handles
+ m_handlesRegion = handles(QRect(start, end));
+
+ Q_INT32 startx;
+ Q_INT32 starty;
+ Q_INT32 endx;
+ Q_INT32 endy;
+ if(start.x()<=end.x())
+ {
+ startx=start.x();
+ endx=end.x();
+ }
+ else
+ {
+ startx=end.x();
+ endx=start.x();
+ }
+ if(start.y()<=end.y())
+ {
+ starty=start.y();
+ endy=end.y();
+ }
+ else
+ {
+ starty=end.y();
+ endy=start.y();
+ }
+ //draw upper line of selection
+ gc.drawLine(startx + m_handleSize / 2 + 1, starty, startx + (endx - startx - m_handleSize) / 2 + 1, starty);
+ gc.drawLine(startx + (endx - startx + m_handleSize) / 2 + 1, starty, endx - m_handleSize / 2, starty);
+ //draw lower line of selection
+ gc.drawLine(startx + m_handleSize / 2 + 1, endy, startx + (endx - startx - m_handleSize) / 2 + 1, endy);
+ gc.drawLine(startx + (endx - startx + m_handleSize) / 2 + 1, endy, endx - m_handleSize / 2 , endy);
+ //draw right line of selection
+ gc.drawLine(startx, starty + m_handleSize / 2 + 1, startx, starty + (endy - starty - m_handleSize) / 2 + 1);
+ gc.drawLine(startx, starty + (endy - starty + m_handleSize) / 2 + 1, startx, endy - m_handleSize / 2);
+ //draw left line of selection
+ gc.drawLine(endx, starty + m_handleSize / 2 + 1, endx, starty + (endy - starty - m_handleSize) / 2 + 1);
+ gc.drawLine(endx, starty + (endy - starty + m_handleSize) / 2 + 1, endx, endy - m_handleSize / 2);
+
+ //draw guides
+ gc.drawLine(0,endy,startx - m_handleSize / 2,endy);
+ gc.drawLine(startx,endy + m_handleSize / 2 + 1, startx, controller->kiscanvas()->height());
+ gc.drawLine(endx,0,endx,starty - m_handleSize / 2);
+ gc.drawLine(endx + m_handleSize / 2 + 1,starty, controller->kiscanvas()->width(), starty);
+ QMemArray <QRect> rects = m_handlesRegion.rects ();
+ for (QMemArray <QRect>::ConstIterator it = rects.begin (); it != rects.end (); ++it)
+ {
+ gc.fillRect (*it, Qt::black);
+ }
+
+
+ gc.setRasterOp(op);
+ gc.setPen(old);
+ }
+}
+
+void KisToolCrop::crop() {
+ // XXX: Should cropping be part of KisImage/KisPaintDevice's API?
+
+ m_haveCropSelection = false;
+ setCursor(m_cropCursor);
+
+ KisImageSP img = m_subject->currentImg();
+
+ if (!img)
+ return;
+
+ QRect rc = realRectCrop().normalize();
+
+ // The visitor adds the undo steps to the macro
+ if (m_optWidget->cmbType->currentItem() == 0) {
+
+ QRect dirty = img->bounds();
+
+ // The layer(s) under the current layer will take care of adding
+ // undo information to the Crop macro.
+ if (img->undo())
+ img->undoAdapter()->beginMacro(i18n("Crop"));
+
+ KisCropVisitor v(rc, false);
+ KisLayerSP layer = img->activeLayer();
+ layer->accept(v);
+ layer->setDirty( dirty );
+ if (img->undo())
+ img->undoAdapter()->endMacro();
+
+ }
+ else {
+ // Resize creates the undo macro itself
+ img->resize(rc, true);
+ }
+
+ m_rectCrop = QRect(0,0,0,0);
+
+ updateWidgetValues();
+}
+
+void KisToolCrop::setCropX(int x)
+{
+ if (!m_haveCropSelection) {
+ m_haveCropSelection = true;
+ }
+ else {
+ paintOutlineWithHandles(); // remove outlines
+ }
+
+ m_rectCrop.setX(x);
+
+ validateSelection();
+ paintOutlineWithHandles();
+}
+
+void KisToolCrop::setCropY(int y)
+{
+ if (!m_haveCropSelection) {
+ m_haveCropSelection = true;
+ }
+ else {
+ paintOutlineWithHandles(); // remove outlines
+ }
+
+ m_rectCrop.setY(y);
+
+ validateSelection();
+ paintOutlineWithHandles();
+
+}
+
+void KisToolCrop::setCropWidth(int w)
+{
+ if (!m_haveCropSelection) {
+ m_haveCropSelection = true;
+ }
+ else {
+ paintOutlineWithHandles(); // remove outlines
+ }
+
+ m_rectCrop.setWidth(w + 1);
+
+ if( m_optWidget->boolRatio->isChecked() )
+ {
+ m_rectCrop.setHeight( (int) ( w / m_optWidget->doubleRatio->value() ) );
+ } else {
+ setOptionWidgetRatio((double)m_rectCrop.width() / (double)m_rectCrop.height() );
+ }
+
+ validateSelection();
+ paintOutlineWithHandles();
+
+}
+
+void KisToolCrop::setCropHeight(int h)
+{
+ if (!m_haveCropSelection) {
+ m_haveCropSelection = true;
+ }
+ else {
+ paintOutlineWithHandles(); // remove outlines
+ }
+
+ m_rectCrop.setHeight(h + 1);
+
+ if( m_optWidget->boolRatio->isChecked() )
+ {
+ m_rectCrop.setWidth( (int) ( h * m_optWidget->doubleRatio->value() ) );
+ } else {
+ setOptionWidgetRatio((double)m_rectCrop.width() / (double)m_rectCrop.height() );
+ }
+
+ validateSelection();
+ paintOutlineWithHandles();
+
+}
+
+void KisToolCrop::setRatio(double )
+{
+ if( ! (m_optWidget->boolWidth->isChecked() && m_optWidget->boolHeight->isChecked() ))
+ {
+ if (!m_haveCropSelection) {
+ m_haveCropSelection = true;
+ }
+ else {
+ paintOutlineWithHandles(); // remove outlines
+ }
+ if( m_optWidget->boolWidth->isChecked() )
+ {
+ m_rectCrop.setHeight( (int) ( m_rectCrop.width() / m_optWidget->doubleRatio->value()) );
+ setOptionWidgetHeight( m_rectCrop.height() );
+ } else if(m_optWidget->boolHeight->isChecked()) {
+ m_rectCrop.setWidth( (int) (m_rectCrop.height() * m_optWidget->doubleRatio->value()) );
+ setOptionWidgetWidth( m_rectCrop.width() );
+ } else {
+ int newwidth = (int) (m_optWidget->doubleRatio->value() * m_rectCrop.height());
+ newwidth = (newwidth + m_rectCrop.width()) / 2;
+ m_rectCrop.setWidth( newwidth + 1);
+ setOptionWidgetWidth( newwidth );
+ m_rectCrop.setHeight( (int) (newwidth / m_optWidget->doubleRatio->value()) + 1 );
+ setOptionWidgetHeight( m_rectCrop.height() - 1 );
+ }
+ validateSelection(false);
+ paintOutlineWithHandles();
+ }
+}
+
+void KisToolCrop::setOptionWidgetX(Q_INT32 x)
+{
+ // Disable signals otherwise we get the valueChanged signal, which we don't want
+ // to go through the logic for setting values that way.
+ m_optWidget->intX->blockSignals(true);
+ m_optWidget->intX->setValue(x);
+ m_optWidget->intX->blockSignals(false);
+}
+
+void KisToolCrop::setOptionWidgetY(Q_INT32 y)
+{
+ m_optWidget->intY->blockSignals(true);
+ m_optWidget->intY->setValue(y);
+ m_optWidget->intY->blockSignals(false);
+}
+
+void KisToolCrop::setOptionWidgetWidth(Q_INT32 x)
+{
+ m_optWidget->intWidth->blockSignals(true);
+ m_optWidget->intWidth->setValue(x);
+ m_optWidget->intWidth->blockSignals(false);
+}
+
+void KisToolCrop::setOptionWidgetHeight(Q_INT32 y)
+{
+ m_optWidget->intHeight->blockSignals(true);
+ m_optWidget->intHeight->setValue(y);
+ m_optWidget->intHeight->blockSignals(false);
+}
+
+void KisToolCrop::setOptionWidgetRatio(double ratio)
+{
+ m_optWidget->doubleRatio->blockSignals(true);
+ m_optWidget->doubleRatio->setValue(ratio);
+ m_optWidget->doubleRatio->blockSignals(false);
+}
+
+
+QWidget* KisToolCrop::createOptionWidget(QWidget* parent)
+{
+ m_optWidget = new WdgToolCrop(parent);
+ Q_CHECK_PTR(m_optWidget);
+
+ connect(m_optWidget->bnCrop, SIGNAL(clicked()), this, SLOT(crop()));
+
+ connect(m_optWidget->intX, SIGNAL(valueChanged(int)), this, SLOT(setCropX(int)));
+ connect(m_optWidget->intY, SIGNAL(valueChanged(int)), this, SLOT(setCropY(int)));
+ connect(m_optWidget->intWidth, SIGNAL(valueChanged(int)), this, SLOT(setCropWidth(int)));
+ connect(m_optWidget->intHeight, SIGNAL(valueChanged(int)), this, SLOT(setCropHeight(int)));
+ connect(m_optWidget->doubleRatio, SIGNAL(valueChanged(double)), this, SLOT(setRatio( double )));
+
+ return m_optWidget;
+}
+
+QWidget* KisToolCrop::optionWidget()
+{
+ return m_optWidget;
+}
+
+void KisToolCrop::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("&Crop"),
+ "tool_crop",
+ 0,
+ this,
+ SLOT(activate()),
+ collection,
+ name());
+ Q_CHECK_PTR(m_action);
+
+ m_action->setToolTip(i18n("Crop an area"));
+ m_action->setExclusiveGroup("tools");
+
+ m_ownAction = true;
+ }
+}
+
+QRect toQRect(double x, double y, int w, int h)
+{
+ return QRect(int(x), int(y), w, h);
+}
+
+QRegion KisToolCrop::handles(QRect rect)
+{
+ QRegion handlesRegion;
+
+ //add handle at the lower right corner
+ handlesRegion += toQRect( QABS( rect.width() ) - m_handleSize / 2.0, QABS( rect.height() ) - m_handleSize / 2.0, m_handleSize, m_handleSize );
+ //add handle at the upper right corner
+ handlesRegion += toQRect( QABS( rect.width() ) - m_handleSize / 2.0 , 0 - m_handleSize / 2.0, m_handleSize, m_handleSize );
+ //add rectangle at the lower left corner
+ handlesRegion += toQRect( 0 - m_handleSize / 2.0 , QABS( rect.height() ) - m_handleSize / 2.0, m_handleSize, m_handleSize );
+ //add rectangle at the upper left corner
+ handlesRegion += toQRect( 0 - m_handleSize / 2.0, 0 - m_handleSize / 2.0, m_handleSize, m_handleSize );
+ //add handle at the lower edge of the rectangle
+ handlesRegion += toQRect( ( QABS( rect.width() ) - m_handleSize ) / 2.0 , QABS( rect.height() ) - m_handleSize / 2.0, m_handleSize, m_handleSize );
+ //add handle at the right edge of the rectangle
+ handlesRegion += toQRect( QABS( rect.width() ) - m_handleSize / 2.0 , ( QABS( rect.height() ) - m_handleSize ) / 2.0, m_handleSize, m_handleSize );
+ //add handle at the upper edge of the rectangle
+ handlesRegion += toQRect( ( QABS( rect.width() ) - m_handleSize ) / 2.0 , 0 - m_handleSize / 2.0, m_handleSize, m_handleSize );
+ //add handle at the left edge of the rectangle
+ handlesRegion += toQRect( 0 - m_handleSize / 2.0, ( QABS( rect.height() ) - m_handleSize ) / 2.0, m_handleSize, m_handleSize );
+
+ //move the handles to the correct position
+ if( rect.width() >= 0 && rect.height() >= 0)
+ {
+ handlesRegion.translate ( rect.x(), rect.y() );
+ }
+ else if( rect.width() < 0 && rect.height() >= 0)
+ {
+ handlesRegion.translate ( rect.x() - QABS( rect.width() ), rect.y() );
+ }
+ else if( rect.width() >= 0 && rect.height() < 0)
+ {
+ handlesRegion.translate ( rect.x(), rect.y() - QABS( rect.height() ) );
+ }
+ else if( rect.width() < 0 && rect.height() < 0)
+ {
+ handlesRegion.translate ( rect.x() - QABS( rect.width() ), rect.y() - QABS( rect.height() ) );
+ }
+ return handlesRegion;
+}
+
+Q_INT32 KisToolCrop::mouseOnHandle(QPoint currentViewPoint)
+{
+ KisCanvasController *controller = m_subject->canvasController();
+ Q_ASSERT(controller);
+ QPoint start = controller->windowToView(m_rectCrop.topLeft());
+ QPoint end = controller->windowToView(m_rectCrop.bottomRight());
+
+ Q_INT32 startx;
+ Q_INT32 starty;
+ Q_INT32 endx;
+ Q_INT32 endy;
+ if(start.x()<=end.x())
+ {
+ startx=start.x();
+ endx=end.x();
+ }
+ else
+ {
+ startx=end.x();
+ endx=start.x();
+ }
+ if(start.y()<=end.y())
+ {
+ starty=start.y();
+ endy=end.y();
+ }
+ else
+ {
+ starty=end.y();
+ endy=start.y();
+ }
+
+ if ( toQRect ( startx - m_handleSize / 2.0, starty - m_handleSize / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) )
+ {
+ if( !m_selecting )
+ {
+ m_dx= startx-currentViewPoint.x();
+ m_dy = starty - currentViewPoint.y();
+ }
+ return UpperLeft;
+ }
+ else if ( toQRect ( startx - m_handleSize / 2.0, endy - m_handleSize / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) )
+ {
+ if( !m_selecting )
+ {
+ m_dx = startx-currentViewPoint.x();
+ m_dy = endy-currentViewPoint.y();
+ }
+ return LowerLeft;
+ }
+ else if ( toQRect ( endx - m_handleSize / 2.0, starty - m_handleSize / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) )
+ {
+ if( !m_selecting )
+ {
+ m_dx = endx - currentViewPoint.x();
+ m_dy = starty - currentViewPoint.y() ;
+ }
+ return UpperRight;
+ }
+ else if ( toQRect ( endx - m_handleSize / 2.0, endy - m_handleSize / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) )
+ {
+ if( !m_selecting )
+ {
+ m_dx = endx - currentViewPoint.x();
+ m_dy= endy - currentViewPoint.y();
+ }
+ return LowerRight;
+ }
+ else if ( toQRect ( startx + ( endx - startx - m_handleSize ) / 2.0, starty - m_handleSize / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) )
+ {
+ if( !m_selecting )
+ {
+ m_dy = starty - currentViewPoint.y() ;
+ }
+ return Upper;
+ }
+ else if ( toQRect ( startx + ( endx - startx - m_handleSize ) / 2.0, endy - m_handleSize / 2, m_handleSize, m_handleSize ).contains( currentViewPoint ) )
+ {
+ if( !m_selecting )
+ {
+ m_dy = endy - currentViewPoint.y();
+ }
+ return Lower;
+ }
+ else if ( toQRect ( startx - m_handleSize / 2.0, starty + ( endy - starty - m_handleSize ) / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) )
+ {
+ if( !m_selecting )
+ {
+ m_dx = startx - currentViewPoint.x() ;
+ }
+ return Left;
+ }
+ else if ( toQRect ( endx - m_handleSize / 2.0 , starty + ( endy - starty - m_handleSize ) / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) )
+ {
+ if( !m_selecting )
+ {
+ m_dx = endx-currentViewPoint.x();
+ }
+ return Right;
+ }
+ else if ( toQRect ( startx , starty, endx - startx , endy - starty ).contains( currentViewPoint ) )
+ {
+ return Inside;
+ }
+ else return None;
+}
+
+void KisToolCrop::setMoveResizeCursor (Q_INT32 handle)
+{
+ switch (handle)
+ {
+ case (UpperLeft):
+ case (LowerRight):
+ m_subject->canvasController()->setCanvasCursor(KisCursor::sizeFDiagCursor());
+ return;
+ case (LowerLeft):
+ case (UpperRight):
+ m_subject->canvasController()->setCanvasCursor(KisCursor::sizeBDiagCursor());
+ return;
+ case (Upper):
+ case (Lower):
+ m_subject->canvasController()->setCanvasCursor(KisCursor::sizeVerCursor());
+ return;
+ case (Left):
+ case (Right):
+ m_subject->canvasController()->setCanvasCursor(KisCursor::sizeHorCursor());
+ return;
+ case (Inside):
+ m_subject->canvasController()->setCanvasCursor(KisCursor::sizeAllCursor());
+ return;
+ }
+ m_subject->canvasController()->setCanvasCursor(KisCursor::arrowCursor());
+ return;
+}
+
+
+#include "kis_tool_crop.moc"