diff options
Diffstat (limited to 'krita/plugins/tools/tool_crop/kis_tool_crop.cc')
-rw-r--r-- | krita/plugins/tools/tool_crop/kis_tool_crop.cc | 925 |
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" |