diff options
author | Michele Calgaro <michele.calgaro@yahoo.it> | 2024-11-22 18:41:30 +0900 |
---|---|---|
committer | Michele Calgaro <michele.calgaro@yahoo.it> | 2024-11-22 20:55:03 +0900 |
commit | 5bed6e4a4c916a97f8fe4d1b07f7eecf4d733b90 (patch) | |
tree | f89cc49efc9ca1d0e1579ecb079ee7e7088ff8c8 /src/imageplugins/perspective/perspectivewidget.cpp | |
parent | 0bfbf616d9c1fd7abb1bd02732389ab35e5f8771 (diff) | |
download | digikam-5bed6e4a4c916a97f8fe4d1b07f7eecf4d733b90.tar.gz digikam-5bed6e4a4c916a97f8fe4d1b07f7eecf4d733b90.zip |
Rename 'digikam' folder to 'src'
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
(cherry picked from commit ee0d99607c14cb63d3ebdb3a970b508949fa8219)
Diffstat (limited to 'src/imageplugins/perspective/perspectivewidget.cpp')
-rw-r--r-- | src/imageplugins/perspective/perspectivewidget.cpp | 839 |
1 files changed, 839 insertions, 0 deletions
diff --git a/src/imageplugins/perspective/perspectivewidget.cpp b/src/imageplugins/perspective/perspectivewidget.cpp new file mode 100644 index 00000000..ae2c5c03 --- /dev/null +++ b/src/imageplugins/perspective/perspectivewidget.cpp @@ -0,0 +1,839 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2005-01-18 + * Description : a widget class to edit perspective. + * + * Copyright (C) 2005-2007 by Gilles Caulier <caulier dot gilles at gmail dot com> + * Copyright (C) 2006-2007 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> + * + * Matrix3 implementation inspired from gimp 2.0 + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * 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, 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. + * + * ============================================================ */ + +// C++ includes. + +#include <cstdio> +#include <cstdlib> +#include <cmath> + +// TQt includes. + +#include <tqregion.h> +#include <tqpainter.h> +#include <tqpen.h> +#include <tqbrush.h> +#include <tqpixmap.h> +#include <tqimage.h> +#include <tqpointarray.h> + +// KDE includes. + +#include <kstandarddirs.h> +#include <kcursor.h> +#include <tdeglobal.h> +#include <tdeapplication.h> + +// Local includes. + +#include "triangle.h" +#include "ddebug.h" +#include "imageiface.h" +#include "dimgimagefilters.h" +#include "perspectivewidget.h" +#include "perspectivewidget.moc" + +namespace DigikamPerspectiveImagesPlugin +{ + +PerspectiveWidget::PerspectiveWidget(int w, int h, TQWidget *parent) + : TQWidget(parent, 0, TQt::WDestructiveClose) +{ + setBackgroundMode(TQt::NoBackground); + setMinimumSize(w, h); + setMouseTracking(true); + + m_drawGrid = false; + m_drawWhileMoving = true; + m_currentResizing = ResizingNone; + m_guideColor = TQt::red; + m_guideSize = 1; + + m_iface = new Digikam::ImageIface(w, h); + uchar *data = m_iface->setPreviewImageSize(w, h); + m_w = m_iface->previewWidth(); + m_h = m_iface->previewHeight(); + m_origW = m_iface->originalWidth(); + m_origH = m_iface->originalHeight(); + m_previewImage = Digikam::DImg(m_w, m_h, m_iface->previewSixteenBit(), m_iface->previewHasAlpha(), data, false); + + m_pixmap = new TQPixmap(w, h); + + m_rect = TQRect(w/2-m_w/2, h/2-m_h/2, m_w, m_h); + m_grid = TQPointArray(60); + + reset(); +} + +PerspectiveWidget::~PerspectiveWidget() +{ + delete m_iface; + delete m_pixmap; +} + +Digikam::ImageIface* PerspectiveWidget::imageIface() +{ + return m_iface; +} + +TQPoint PerspectiveWidget::getTopLeftCorner(void) +{ + return TQPoint( lroundf((float)(m_topLeftPoint.x()*m_origW) / (float)m_w), + lroundf((float)(m_topLeftPoint.y()*m_origH) / (float)m_h)); +} + +TQPoint PerspectiveWidget::getTopRightCorner(void) +{ + return TQPoint( lroundf((float)(m_topRightPoint.x()*m_origW) / (float)m_w), + lroundf((float)(m_topRightPoint.y()*m_origH) / (float)m_h)); +} + +TQPoint PerspectiveWidget::getBottomLeftCorner(void) +{ + return TQPoint( lroundf((float)(m_bottomLeftPoint.x()*m_origW) / (float)m_w), + lroundf((float)(m_bottomLeftPoint.y()*m_origH) / (float)m_h)); +} + +TQPoint PerspectiveWidget::getBottomRightCorner(void) +{ + return TQPoint( lroundf((float)(m_bottomRightPoint.x()*m_origW) / (float)m_w), + lroundf((float)(m_bottomRightPoint.y()*m_origH) / (float)m_h)); +} + +TQRect PerspectiveWidget::getTargetSize(void) +{ + TQPointArray perspectiveArea; + + perspectiveArea.putPoints( 0, 4, + getTopLeftCorner().x(), getTopLeftCorner().y(), + getTopRightCorner().x(), getTopRightCorner().y(), + getBottomRightCorner().x(), getBottomRightCorner().y(), + getBottomLeftCorner().x(), getBottomLeftCorner().y() ); + + return perspectiveArea.boundingRect(); +} + +float PerspectiveWidget::getAngleTopLeft(void) +{ + Triangle topLeft(getTopLeftCorner(), getTopRightCorner(), getBottomLeftCorner()); + return topLeft.angleBAC(); +} + +float PerspectiveWidget::getAngleTopRight(void) +{ + Triangle topLeft(getTopRightCorner(), getBottomRightCorner(), getTopLeftCorner()); + return topLeft.angleBAC(); +} + +float PerspectiveWidget::getAngleBottomLeft(void) +{ + Triangle topLeft(getBottomLeftCorner(), getTopLeftCorner(), getBottomRightCorner()); + return topLeft.angleBAC(); +} + +float PerspectiveWidget::getAngleBottomRight(void) +{ + Triangle topLeft(getBottomRightCorner(), getBottomLeftCorner(), getTopRightCorner()); + return topLeft.angleBAC(); +} + +void PerspectiveWidget::reset(void) +{ + m_topLeftPoint.setX(0); + m_topLeftPoint.setY(0); + + m_topRightPoint.setX(m_w-1); + m_topRightPoint.setY(0); + + m_bottomLeftPoint.setX(0); + m_bottomLeftPoint.setY(m_h-1); + + m_bottomRightPoint.setX(m_w-1); + m_bottomRightPoint.setY(m_h-1); + + m_spot.setX(m_w / 2); + m_spot.setY(m_h / 2); + + m_antiAlias = true; + updatePixmap(); + repaint(false); +} + +void PerspectiveWidget::applyPerspectiveAdjustment(void) +{ + Digikam::DImg *orgImage = m_iface->getOriginalImg(); + Digikam::DImg destImage(orgImage->width(), orgImage->height(), orgImage->sixteenBit(), orgImage->hasAlpha()); + + Digikam::DColor background(0, 0, 0, orgImage->hasAlpha() ? 0 : 255, orgImage->sixteenBit()); + + // Perform perspective adjustment. + + buildPerspective(TQPoint(0, 0), TQPoint(m_origW, m_origH), + getTopLeftCorner(), getTopRightCorner(), + getBottomLeftCorner(), getBottomRightCorner(), + orgImage, &destImage, background); + + // Perform an auto-croping around the image. + + Digikam::DImg targetImg = destImage.copy(getTargetSize()); + + // Update target image. + m_iface->putOriginalImage(i18n("Perspective Adjustment"), + targetImg.bits(), targetImg.width(), targetImg.height()); +} + +void PerspectiveWidget::slotToggleAntiAliasing(bool a) +{ + m_antiAlias = a; + updatePixmap(); + repaint(false); +} + +void PerspectiveWidget::slotToggleDrawWhileMoving(bool draw) +{ + m_drawWhileMoving = draw; +} + +void PerspectiveWidget::slotToggleDrawGrid(bool grid) +{ + m_drawGrid = grid; + updatePixmap(); + repaint(false); +} + +void PerspectiveWidget::slotChangeGuideColor(const TQColor &color) +{ + m_guideColor = color; + updatePixmap(); + repaint(false); +} + +void PerspectiveWidget::slotChangeGuideSize(int size) +{ + m_guideSize = size; + updatePixmap(); + repaint(false); +} + +void PerspectiveWidget::updatePixmap(void) +{ + m_topLeftCorner.setRect(m_topLeftPoint.x() + m_rect.topLeft().x(), + m_topLeftPoint.y() + m_rect.topLeft().y(), 8, 8); + m_topRightCorner.setRect(m_topRightPoint.x() - 7 + m_rect.topLeft().x(), + m_topRightPoint.y() + m_rect.topLeft().y(), 8, 8); + m_bottomLeftCorner.setRect(m_bottomLeftPoint.x() + m_rect.topLeft().x(), + m_bottomLeftPoint.y() - 7 + m_rect.topLeft().y(), 8, 8); + m_bottomRightCorner.setRect(m_bottomRightPoint.x() - 7 + m_rect.topLeft().x(), + m_bottomRightPoint.y() - 7 + m_rect.topLeft().y(), 8, 8); + + // Compute the grid array + + int gXS = m_w / 15; + int gYS = m_h / 15; + + for (int i = 0 ; i < 15 ; i++) + { + int j = i*4; + + //Horizontal line. + m_grid.setPoint(j , 0, i*gYS); + m_grid.setPoint(j+1, m_w, i*gYS); + + //Vertical line. + m_grid.setPoint(j+2, i*gXS, 0); + m_grid.setPoint(j+3, i*gXS, m_h); + } + + // Draw background + + m_pixmap->fill(colorGroup().background()); + + // if we are resizing with the mouse, compute and draw only if drawWhileMoving is set + if (m_currentResizing == ResizingNone || m_drawWhileMoving) + { + // Create preview image + + Digikam::DImg destImage(m_previewImage.width(), m_previewImage.height(), + m_previewImage.sixteenBit(), m_previewImage.hasAlpha()); + + Digikam::DColor background(colorGroup().background()); + + m_transformedCenter = buildPerspective(TQPoint(0, 0), TQPoint(m_w, m_h), + m_topLeftPoint, m_topRightPoint, + m_bottomLeftPoint, m_bottomRightPoint, + &m_previewImage, &destImage, background); + + m_iface->putPreviewImage(destImage.bits()); + + // Draw image + + m_iface->paint(m_pixmap, m_rect.x(), m_rect.y(), + m_rect.width(), m_rect.height()); + } + else + { + m_transformedCenter = buildPerspective(TQPoint(0, 0), TQPoint(m_w, m_h), + m_topLeftPoint, m_topRightPoint, + m_bottomLeftPoint, m_bottomRightPoint); + } + + // Drawing selection borders. + + TQPainter p(m_pixmap); + p.setPen(TQPen(TQColor(255, 64, 64), 1, TQt::SolidLine)); + p.drawLine(m_topLeftPoint+m_rect.topLeft(), m_topRightPoint+m_rect.topLeft()); + p.drawLine(m_topRightPoint+m_rect.topLeft(), m_bottomRightPoint+m_rect.topLeft()); + p.drawLine(m_bottomRightPoint+m_rect.topLeft(), m_bottomLeftPoint+m_rect.topLeft()); + p.drawLine(m_bottomLeftPoint+m_rect.topLeft(), m_topLeftPoint+m_rect.topLeft()); + + // Drawing selection corners. + + TQBrush brush(TQColor(255, 64, 64)); + p.fillRect(m_topLeftCorner, brush); + p.fillRect(m_topRightCorner, brush); + p.fillRect(m_bottomLeftCorner, brush); + p.fillRect(m_bottomRightCorner, brush); + + // Drawing the grid. + + if (m_drawGrid) + { + for (uint i = 0 ; i < m_grid.size() ; i += 4) + { + //Horizontal line. + p.drawLine(m_grid.point(i)+m_rect.topLeft(), m_grid.point(i+1)+m_rect.topLeft()); + + //Vertical line. + p.drawLine(m_grid.point(i+2)+m_rect.topLeft(), m_grid.point(i+3)+m_rect.topLeft()); + } + } + + // Drawing transformed center. + + p.setPen(TQPen(TQColor(255, 64, 64), 3, TQt::SolidLine)); + p.drawEllipse( m_transformedCenter.x()+m_rect.topLeft().x()-2, + m_transformedCenter.y()+m_rect.topLeft().y()-2, 4, 4 ); + + // Drawing vertical and horizontal guide lines. + + int xspot = m_spot.x() + m_rect.x(); + int yspot = m_spot.y() + m_rect.y(); + p.setPen(TQPen(TQt::white, m_guideSize, TQt::SolidLine)); + p.drawLine(xspot, m_rect.top(), xspot, m_rect.bottom()); + p.drawLine(m_rect.left(), yspot, m_rect.right(), yspot); + p.setPen(TQPen(m_guideColor, m_guideSize, TQt::DotLine)); + p.drawLine(xspot, m_rect.top(), xspot, m_rect.bottom()); + p.drawLine(m_rect.left(), yspot, m_rect.right(), yspot); + + p.end(); + + emit signalPerspectiveChanged(getTargetSize(), getAngleTopLeft(), getAngleTopRight(), + getAngleBottomLeft(), getAngleBottomRight()); +} + +TQPoint PerspectiveWidget::buildPerspective(TQPoint orignTopLeft, TQPoint orignBottomRight, + TQPoint transTopLeft, TQPoint transTopRight, + TQPoint transBottomLeft, TQPoint transBottomRight, + Digikam::DImg *orgImage, Digikam::DImg *destImage, + Digikam::DColor background) +{ + Matrix matrix, transform; + double scalex; + double scaley; + + double x1 = (double)orignTopLeft.x(); + double y1 = (double)orignTopLeft.y(); + + double x2 = (double)orignBottomRight.x(); + double y2 = (double)orignBottomRight.y(); + + double tx1 = (double)transTopLeft.x(); + double ty1 = (double)transTopLeft.y(); + + double tx2 = (double)transTopRight.x(); + double ty2 = (double)transTopRight.y(); + + double tx3 = (double)transBottomLeft.x(); + double ty3 = (double)transBottomLeft.y(); + + double tx4 = (double)transBottomRight.x(); + double ty4 = (double)transBottomRight.y(); + + scalex = scaley = 1.0; + + if ((x2 - x1) > 0) + scalex = 1.0 / (double) (x2 - x1); + + if ((y2 - y1) > 0) + scaley = 1.0 / (double) (y2 - y1); + + // Determine the perspective transform that maps from + // the unit cube to the transformed coordinates + + double dx1, dx2, dx3, dy1, dy2, dy3; + + dx1 = tx2 - tx4; + dx2 = tx3 - tx4; + dx3 = tx1 - tx2 + tx4 - tx3; + + dy1 = ty2 - ty4; + dy2 = ty3 - ty4; + dy3 = ty1 - ty2 + ty4 - ty3; + + // Is the mapping affine? + + if ((dx3 == 0.0) && (dy3 == 0.0)) + { + matrix.coeff[0][0] = tx2 - tx1; + matrix.coeff[0][1] = tx4 - tx2; + matrix.coeff[0][2] = tx1; + matrix.coeff[1][0] = ty2 - ty1; + matrix.coeff[1][1] = ty4 - ty2; + matrix.coeff[1][2] = ty1; + matrix.coeff[2][0] = 0.0; + matrix.coeff[2][1] = 0.0; + } + else + { + double det1, det2; + + det1 = dx3 * dy2 - dy3 * dx2; + det2 = dx1 * dy2 - dy1 * dx2; + + if (det1 == 0.0 && det2 == 0.0) + matrix.coeff[2][0] = 1.0; + else + matrix.coeff[2][0] = det1 / det2; + + det1 = dx1 * dy3 - dy1 * dx3; + + if (det1 == 0.0 && det2 == 0.0) + matrix.coeff[2][1] = 1.0; + else + matrix.coeff[2][1] = det1 / det2; + + matrix.coeff[0][0] = tx2 - tx1 + matrix.coeff[2][0] * tx2; + matrix.coeff[0][1] = tx3 - tx1 + matrix.coeff[2][1] * tx3; + matrix.coeff[0][2] = tx1; + + matrix.coeff[1][0] = ty2 - ty1 + matrix.coeff[2][0] * ty2; + matrix.coeff[1][1] = ty3 - ty1 + matrix.coeff[2][1] * ty3; + matrix.coeff[1][2] = ty1; + } + + matrix.coeff[2][2] = 1.0; + + // transform is initialized to the identity matrix + transform.translate(-x1, -y1); + transform.scale (scalex, scaley); + transform.multiply (matrix); + + // Compute perspective transformation to image if image data containers exist. + if (orgImage && destImage) + transformAffine(orgImage, destImage, transform, background); + + // Calculate the grid array points. + double newX, newY; + for (uint i = 0 ; i < m_grid.size() ; i++) + { + transform.transformPoint(m_grid.point(i).x(), m_grid.point(i).y(), &newX, &newY); + m_grid.setPoint(i, lround(newX), lround(newY)); + } + + // Calculate and return new image center. + double newCenterX, newCenterY; + transform.transformPoint(x2/2.0, y2/2.0, &newCenterX, &newCenterY); + + return TQPoint(lround(newCenterX), lround(newCenterY)); +} + +void PerspectiveWidget::transformAffine(Digikam::DImg *orgImage, Digikam::DImg *destImage, + const Matrix &matrix, Digikam::DColor background) +{ + Matrix m(matrix), inv(matrix); + + int x1, y1, x2, y2; // target bounding box + int x, y; // target coordinates + int u1, v1, u2, v2; // source bounding box + double uinc, vinc, winc; // increments in source coordinates + // pr horizontal target coordinate + + double u[5],v[5]; // source coordinates, + // 2 + // / \ 0 is sample in the center of pixel + // 1 0 3 1..4 is offset 1 pixel in each + // \ / direction (in target space) + // 4 + + double tu[5],tv[5],tw[5]; // undivided source coordinates and divisor + + uchar *data, *newData; + bool sixteenBit; + int coords; + int width, height; + int bytesDepth; + int offset; + uchar *dest, *d; + Digikam::DColor color; + + bytesDepth = orgImage->bytesDepth(); + data = orgImage->bits(); + sixteenBit = orgImage->sixteenBit(); + width = orgImage->width(); + height = orgImage->height(); + newData = destImage->bits(); + + if (sixteenBit) + background.convertToSixteenBit(); + + //destImage->fill(background); + + Digikam::DImgImageFilters filters; + + // Find the inverse of the transformation matrix + m.invert(); + + u1 = 0; + v1 = 0; + u2 = u1 + width; + v2 = v1 + height; + + x1 = u1; + y1 = v1; + x2 = u2; + y2 = v2; + + dest = new uchar[width * bytesDepth]; + + uinc = m.coeff[0][0]; + vinc = m.coeff[1][0]; + winc = m.coeff[2][0]; + + coords = 1; + + // these loops could be rearranged, depending on which bit of code + // you'd most like to write more than once. + + for (y = y1; y < y2; y++) + { + // set up inverse transform steps + + tu[0] = uinc * (x1 + 0.5) + m.coeff[0][1] * (y + 0.5) + m.coeff[0][2] - 0.5; + tv[0] = vinc * (x1 + 0.5) + m.coeff[1][1] * (y + 0.5) + m.coeff[1][2] - 0.5; + tw[0] = winc * (x1 + 0.5) + m.coeff[2][1] * (y + 0.5) + m.coeff[2][2]; + + d = dest; + + for (x = x1; x < x2; x++) + { + int i; // normalize homogeneous coords + + for (i = 0; i < coords; i++) + { + if (tw[i] == 1.0) + { + u[i] = tu[i]; + v[i] = tv[i]; + } + else if (tw[i] != 0.0) + { + u[i] = tu[i] / tw[i]; + v[i] = tv[i] / tw[i]; + } + else + { + DDebug() << "homogeneous coordinate = 0...\n" << endl; + } + } + + // Set the destination pixels + + int iu = lround( u [0] ); + int iv = lround( v [0] ); + + if (iu >= u1 && iu < u2 && iv >= v1 && iv < v2) + { + // u, v coordinates into source + + int u = iu - u1; + int v = iv - v1; + + //TODO: Check why antialiasing shows no effect + /*if (m_antiAlias) + { + if (sixteenBit) + { + unsigned short *d16 = (unsigned short *)d; + filters.pixelAntiAliasing16((unsigned short *)data, + width, height, u, v, d16+3, d16+2, d16+1, d16); + } + else + { + filters.pixelAntiAliasing(data, width, height, u, v, + d+3, d+2, d+1, d); + } + } + else + {*/ + offset = (v * width * bytesDepth) + (u * bytesDepth); + color.setColor(data + offset, sixteenBit); + color.setPixel(d); + //} + + d += bytesDepth; + } + else // not in source range + { + // set to background color + + background.setPixel(d); + d += bytesDepth; + } + + for (i = 0; i < coords; i++) + { + tu[i] += uinc; + tv[i] += vinc; + tw[i] += winc; + } + } + + // set the pixel region row + + offset = (y - y1) * width * bytesDepth; + memcpy(newData + offset, dest, width * bytesDepth); + } + + delete [] dest; +} + +void PerspectiveWidget::paintEvent( TQPaintEvent * ) +{ + bitBlt(this, 0, 0, m_pixmap); +} + +void PerspectiveWidget::resizeEvent(TQResizeEvent * e) +{ + int old_w = m_w; + int old_h = m_h; + + delete m_pixmap; + int w = e->size().width(); + int h = e->size().height(); + uchar *data = m_iface->setPreviewImageSize(w, h); + m_w = m_iface->previewWidth(); + m_h = m_iface->previewHeight(); + m_previewImage = Digikam::DImg(m_w, m_h, m_iface->previewSixteenBit(), m_iface->previewHasAlpha(), data, false); + + m_pixmap = new TQPixmap(w, h); + TQRect oldRect = m_rect; + m_rect = TQRect(w/2-m_w/2, h/2-m_h/2, m_w, m_h); + + float xFactor = (float)m_rect.width()/(float)(oldRect.width()); + float yFactor = (float)m_rect.height()/(float)(oldRect.height()); + + m_topLeftPoint = TQPoint(lroundf(m_topLeftPoint.x()*xFactor), + lroundf(m_topLeftPoint.y()*yFactor)); + m_topRightPoint = TQPoint(lroundf(m_topRightPoint.x()*xFactor), + lroundf(m_topRightPoint.y()*yFactor)); + m_bottomLeftPoint = TQPoint(lroundf(m_bottomLeftPoint.x()*xFactor), + lroundf(m_bottomLeftPoint.y()*yFactor)); + m_bottomRightPoint = TQPoint(lroundf(m_bottomRightPoint.x()*xFactor), + lroundf(m_bottomRightPoint.y()*yFactor)); + m_transformedCenter = TQPoint(lroundf(m_transformedCenter.x()*xFactor), + lroundf(m_transformedCenter.y()*yFactor)); + + m_spot.setX((int)((float)m_spot.x() * ( (float)m_w / (float)old_w))); + m_spot.setY((int)((float)m_spot.y() * ( (float)m_h / (float)old_h))); + + updatePixmap(); +} + +void PerspectiveWidget::mousePressEvent ( TQMouseEvent * e ) +{ + if ( e->button() == TQt::LeftButton && + m_rect.contains( e->x(), e->y() )) + { + if ( m_topLeftCorner.contains( e->x(), e->y() ) ) + m_currentResizing = ResizingTopLeft; + else if ( m_bottomRightCorner.contains( e->x(), e->y() ) ) + m_currentResizing = ResizingBottomRight; + else if ( m_topRightCorner.contains( e->x(), e->y() ) ) + m_currentResizing = ResizingTopRight; + else if ( m_bottomLeftCorner.contains( e->x(), e->y() ) ) + m_currentResizing = ResizingBottomLeft; + else + { + m_spot.setX(e->x()-m_rect.x()); + m_spot.setY(e->y()-m_rect.y()); + } + } +} + +void PerspectiveWidget::mouseReleaseEvent ( TQMouseEvent * e ) +{ + if ( m_currentResizing != ResizingNone ) + { + unsetCursor(); + m_currentResizing = ResizingNone; + + // in this case, the pixmap has not been drawn on mouse move + if (!m_drawWhileMoving) + { + updatePixmap(); + repaint(false); + } + } + else + { + m_spot.setX(e->x()-m_rect.x()); + m_spot.setY(e->y()-m_rect.y()); + updatePixmap(); + repaint(false); + } +} + +void PerspectiveWidget::mouseMoveEvent ( TQMouseEvent * e ) +{ + if ( e->state() == TQt::LeftButton ) + { + if ( m_currentResizing != ResizingNone ) + { + TQPointArray unsablePoints; + TQPoint pm(e->x(), e->y()); + + if (!m_rect.contains( pm )) + { + if (pm.x() > m_rect.right()) + pm.setX(m_rect.right()); + else if (pm.x() < m_rect.left()) + pm.setX(m_rect.left()); + + if (pm.y() > m_rect.bottom()) + pm.setY(m_rect.bottom()); + else if (pm.y() < m_rect.top()) + pm.setY(m_rect.top()); + } + + if ( m_currentResizing == ResizingTopLeft ) + { + unsablePoints.putPoints(0, 7, + m_w-1, m_h-1, + 0, m_h-1, + 0, m_bottomLeftPoint.y()-10, + m_bottomLeftPoint.x(), m_bottomLeftPoint.y()-10, + m_topRightPoint.x()-10, m_topRightPoint.y(), + m_topRightPoint.x()-10, 0, + m_w-1, 0 ); + TQRegion unsableArea(unsablePoints); + + if ( unsableArea.contains(pm) ) return; + + m_topLeftPoint = pm - m_rect.topLeft(); + setCursor( KCursor::sizeFDiagCursor() ); + } + + else if ( m_currentResizing == ResizingTopRight ) + { + unsablePoints.putPoints(0, 7, + 0, m_h-1, + 0, 0, + m_topLeftPoint.x()+10, 0, + m_topLeftPoint.x()+10, m_topLeftPoint.y(), + m_bottomRightPoint.x(), m_bottomRightPoint.y()-10, + m_w-1, m_bottomRightPoint.y()-10, + m_w-1, m_h-1); + TQRegion unsableArea(unsablePoints); + + if ( unsableArea.contains(pm) ) return; + + m_topRightPoint = pm - m_rect.topLeft(); + setCursor( KCursor::sizeBDiagCursor() ); + } + + else if ( m_currentResizing == ResizingBottomLeft ) + { + unsablePoints.putPoints(0, 7, + m_w-1, 0, + m_w-1, m_h-1, + m_bottomRightPoint.x()-10, m_h-1, + m_bottomRightPoint.x()-10, m_bottomRightPoint.y()+10, + m_topLeftPoint.x(), m_topLeftPoint.y()+10, + 0, m_topLeftPoint.y(), + 0, 0); + TQRegion unsableArea(unsablePoints); + + if ( unsableArea.contains(pm) ) return; + + m_bottomLeftPoint = pm - m_rect.topLeft(); + setCursor( KCursor::sizeBDiagCursor() ); + } + + else if ( m_currentResizing == ResizingBottomRight ) + { + unsablePoints.putPoints(0, 7, + 0, 0, + m_w-1, 0, + m_w-1, m_topRightPoint.y()+10, + m_topRightPoint.x(), m_topRightPoint.y()+10, + m_bottomLeftPoint.x()+10, m_bottomLeftPoint.y(), + m_bottomLeftPoint.x()+10, m_w-1, + 0, m_w-1); + TQRegion unsableArea(unsablePoints); + + if ( unsableArea.contains(pm) ) return; + + m_bottomRightPoint = pm - m_rect.topLeft(); + setCursor( KCursor::sizeFDiagCursor() ); + } + + else + { + m_spot.setX(e->x()-m_rect.x()); + m_spot.setY(e->y()-m_rect.y()); + } + + updatePixmap(); + repaint(false); + } + } + else + { + if ( m_topLeftCorner.contains( e->x(), e->y() ) || + m_bottomRightCorner.contains( e->x(), e->y() ) ) + setCursor( KCursor::sizeFDiagCursor() ); + + else if ( m_topRightCorner.contains( e->x(), e->y() ) || + m_bottomLeftCorner.contains( e->x(), e->y() ) ) + setCursor( KCursor::sizeBDiagCursor() ); + else + unsetCursor(); + } +} + +} // NameSpace DigikamPerspectiveImagesPlugin + |