diff options
Diffstat (limited to 'chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cpp')
-rw-r--r-- | chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cpp | 742 |
1 files changed, 742 insertions, 0 deletions
diff --git a/chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cpp b/chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cpp new file mode 100644 index 000000000..e73f5da3c --- /dev/null +++ b/chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cpp @@ -0,0 +1,742 @@ +/* + * kis_tool_transform.cpp -- part of Chalk + * + * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net> + * + * Based on the transform tool from : + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * Copyright (c) 2005 Casper Boemann <cbr@boemann.dk> + * + * 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; version 2 of the License. + * + * 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 "kis_tool_perspectivetransform.h" + + +#include <tqpainter.h> +#include <tqpen.h> +#include <tqpushbutton.h> +#include <tqobject.h> +#include <tqlabel.h> +#include <tqcombobox.h> +#include <tqapplication.h> + +#include <kdebug.h> +#include <tdeaction.h> +#include <kcommand.h> +#include <tdelocale.h> +#include <knuminput.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_selected_transaction.h> +#include <kis_button_press_event.h> +#include <kis_button_release_event.h> +#include <kis_move_event.h> +#include <kis_selection.h> +#include <kis_filter_strategy.h> +#include <kis_cmb_idlist.h> +#include <kis_id.h> +#include <kis_tool_controller.h> +#include <kis_perspectivetransform_worker.h> + +//#include "wdg_tool_transform.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" + +namespace { + class PerspectiveTransformCmd : public KisSelectedTransaction { + typedef KisSelectedTransaction super; + + public: + PerspectiveTransformCmd(KisToolPerspectiveTransform *tool, KisPaintDeviceSP device, KisPaintDeviceSP origDevice, KisPoint topleft, KisPoint topright, KisPoint bottomleft, KisPoint bottomright, KisSelectionSP origSel, TQRect initialRect); + virtual ~PerspectiveTransformCmd(); + + public: + virtual void execute(); + virtual void unexecute(); + void transformArgs(KisPoint &topleft, KisPoint &topright, KisPoint &bottomleft, KisPoint& bottomright) const; + KisSelectionSP origSelection(TQRect& initialRect) const; + KisPaintDeviceSP theDevice(); + KisPaintDeviceSP origDevice(); + + private: + TQRect m_initialRect; + KisPoint m_topleft, m_topright, m_bottomleft, m_bottomright; + KisToolPerspectiveTransform *m_tool; + KisSelectionSP m_origSelection; + KisPaintDeviceSP m_device; + KisPaintDeviceSP m_origDevice; + }; + + PerspectiveTransformCmd::PerspectiveTransformCmd(KisToolPerspectiveTransform *tool, KisPaintDeviceSP device, KisPaintDeviceSP origDevice, KisPoint topleft, KisPoint topright, KisPoint bottomleft, KisPoint bottomright, KisSelectionSP origSel, TQRect initialRect) : + super(i18n("Perspective Transform"), device), m_initialRect(initialRect) + , m_topleft(topleft), m_topright(topright), m_bottomleft(bottomleft), m_bottomright(bottomright) + , m_tool(tool), m_origSelection(origSel), m_device(device), m_origDevice(origDevice) + { + } + + PerspectiveTransformCmd::~PerspectiveTransformCmd() + { + } + + void PerspectiveTransformCmd::transformArgs(KisPoint &topleft, KisPoint &topright, KisPoint &bottomleft, KisPoint& bottomright) const + { + topleft = m_topleft; + topright = m_topright; + bottomleft = m_bottomleft; + bottomright = m_bottomright; + } + + KisSelectionSP PerspectiveTransformCmd::origSelection(TQRect& initialRect) const + { + initialRect = m_initialRect; + return m_origSelection; + } + + void PerspectiveTransformCmd::execute() + { + super::execute(); + } + + void PerspectiveTransformCmd::unexecute() + { + super::unexecute(); + } + + KisPaintDeviceSP PerspectiveTransformCmd::theDevice() + { + return m_device; + } + + KisPaintDeviceSP PerspectiveTransformCmd::origDevice() + { + return m_origDevice; + } +} + +KisToolPerspectiveTransform::KisToolPerspectiveTransform() + : super(i18n("Perspective Transform")) +{ + setName("tool_perspectivetransform"); + setCursor(KisCursor::selectCursor()); + m_subject = 0; + m_origDevice = 0; + m_origSelection = 0; + m_handleHalfSize = 8; + m_handleSize = 2 * m_handleHalfSize; + m_handleSelected = NOHANDLE; +} + +KisToolPerspectiveTransform::~KisToolPerspectiveTransform() +{ +} + +void KisToolPerspectiveTransform::deactivate() +{ + if (m_subject && m_subject->undoAdapter()) m_subject->undoAdapter()->removeCommandHistoryListener( this ); + + KisImageSP img = m_subject->currentImg(); + if (!img) return; + + paintOutline(); + + disconnect(m_subject->currentImg().data(), TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayerActivated(KisLayerSP))); +} + +void KisToolPerspectiveTransform::activate() +{ + super::activate(); + m_currentSelectedPoint = 0; + if(m_subject && m_subject->currentImg() && m_subject->currentImg()->activeDevice()) + { + //connect(m_subject, commandExecuted(KCommand *c), this, notifyCommandAdded( KCommand * c)); + m_subject->undoAdapter()->setCommandHistoryListener( this ); + +// KisToolControllerInterface *controller = m_subject->toolController(); +// if (controller) +// controller->setCurrentTool(this); + + PerspectiveTransformCmd * cmd=0; + + if(m_subject->currentImg()->undoAdapter()->presentCommand()) + cmd = dynamic_cast<PerspectiveTransformCmd*>(m_subject->currentImg()->undoAdapter()->presentCommand()); + + // One of our commands is on top + if(cmd &&cmd->theDevice() == m_subject->currentImg()->activeDevice()) + { + m_interractionMode = EDITRECTINTERRACTION; + // and it even has the same device + // We should ask for tool args and orig selection + m_origDevice = cmd->origDevice(); + cmd->transformArgs(m_topleft, m_topright, m_bottomleft, m_bottomright); + m_origSelection = cmd->origSelection(m_initialRect); + paintOutline(); + } + else + { + m_interractionMode = DRAWRECTINTERRACTION; + m_points.clear(); + initHandles(); + } + } + connect(m_subject->currentImg(), TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayerActivated(KisLayerSP))); +} + +void KisToolPerspectiveTransform::initHandles() +{ +// TQ_INT32 x,y,w,h; + KisImageSP img = m_subject->currentImg(); + + KisPaintDeviceSP dev = img->activeDevice(); + if (!dev ) return; + + // Create a lazy copy of the current state + m_origDevice = new KisPaintDevice(*dev.data()); + Q_ASSERT(m_origDevice); + + if(dev->hasSelection()) + { + KisSelectionSP sel = dev->selection(); + m_origSelection = new KisSelection(*sel.data()); + m_initialRect = sel->selectedExactRect(); + } + else { + m_initialRect = dev->exactBounds(); + } + m_topleft = KisPoint(m_initialRect.topLeft()); + m_topright = KisPoint(m_initialRect.topRight()); + m_bottomleft = KisPoint(m_initialRect.bottomLeft()); + m_bottomright = KisPoint(m_initialRect.bottomRight()); + + m_subject->canvasController() ->updateCanvas(); +} + +void KisToolPerspectiveTransform::paint(KisCanvasPainter& gc) +{ + paintOutline(gc, TQRect()); +} + +void KisToolPerspectiveTransform::paint(KisCanvasPainter& gc, const TQRect& rc) +{ + paintOutline(gc, rc); +} + +bool KisToolPerspectiveTransform::mouseNear(const TQPoint& mousep, const TQPoint point) +{ + return (TQRect( (point.x() - m_handleHalfSize), (point.y() - m_handleHalfSize), m_handleSize, m_handleSize).contains(mousep) ); +} + +void KisToolPerspectiveTransform::buttonPress(KisButtonPressEvent *event) +{ + if (m_subject) { + switch(m_interractionMode) + { + case DRAWRECTINTERRACTION: + { + if (m_points.isEmpty()) + { + m_dragging = false; + m_dragStart = event->pos(); + m_dragEnd = event->pos(); + m_points.append(m_dragStart); + paintOutline(); + } else { + m_dragging = true; + m_dragStart = m_dragEnd; + m_dragEnd = event->pos(); + paintOutline(); + } + } + case EDITRECTINTERRACTION: + { + KisImageSP img = m_subject->currentImg(); + + if (img && img->activeDevice() && event->button() == Qt::LeftButton) { + m_actualyMoveWhileSelected = false; + m_dragEnd = event->pos(); + KisCanvasController *controller = m_subject->canvasController(); + TQPoint mousep = controller->windowToView( event->pos().roundTQPoint() ); + if( mouseNear( mousep, controller->windowToView(m_topleft.roundTQPoint() ) ) ) + { + kdDebug() << " PRESS TOPLEFT HANDLE " << endl; + m_currentSelectedPoint = &m_topleft; + } + else if( mouseNear( mousep, controller->windowToView(m_topright.roundTQPoint() ) ) ) + { + kdDebug() << " PRESS TOPRIGHT HANDLE " << endl; + m_currentSelectedPoint = &m_topright; + } + else if( mouseNear( mousep, controller->windowToView(m_bottomleft.roundTQPoint() ) ) ) + { + kdDebug() << " PRESS BOTTOMLEFT HANDLE " << endl; + m_currentSelectedPoint = &m_bottomleft; + } + else if( mouseNear( mousep, controller->windowToView(m_bottomright.roundTQPoint() ) ) ) + { + kdDebug() << " PRESS BOTTOMRIGHT HANDLE " << endl; + m_currentSelectedPoint = &m_bottomright; + } else if( mouseNear( mousep, controller->windowToView(KisPoint((m_topleft+m_topright)*0.5).roundTQPoint() ) ) ) + { + kdDebug() << " PRESS TOP HANDLE " << endl; + m_handleSelected = TOPHANDLE; + }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_topleft+m_bottomleft)*0.5).roundTQPoint() ) ) ) + { + kdDebug() << " PRESS LEFT HANDLE " << endl; + m_handleSelected = LEFTHANDLE; + }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_bottomleft+m_bottomright)*0.5).roundTQPoint() ) ) ) + { + kdDebug() << " PRESS BOTTOM HANDLE " << endl; + m_handleSelected = BOTTOMHANDLE; + }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_bottomright+m_topright)*0.5).roundTQPoint() ) ) ) + { + kdDebug() << " PRESS RIGHT HANDLE " << endl; + m_handleSelected = RIGHTHANDLE; + }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_topleft+m_bottomleft + m_bottomright+m_topright)*0.25).roundTQPoint() ) ) ) + { + kdDebug() << " PRESS MIDDLE HANDLE " << endl; + m_handleSelected = MIDDLEHANDLE; + } + } + } + } + } +} + +void KisToolPerspectiveTransform::move(KisMoveEvent *event) +{ + switch(m_interractionMode) + { + case DRAWRECTINTERRACTION: + { + if (m_dragging) { + // erase old lines on canvas + paintOutline(); + // get current mouse position + m_dragEnd = event->pos(); + // draw new lines on canvas + paintOutline(); + } + } + + case EDITRECTINTERRACTION: + { + if(m_currentSelectedPoint) + { + paintOutline(); + KisPoint translate = event->pos() - m_dragEnd; + m_dragEnd = event->pos(); + *m_currentSelectedPoint += translate;; + paintOutline(); + m_actualyMoveWhileSelected = true; + } + else if(m_handleSelected == TOPHANDLE || m_handleSelected == LEFTHANDLE || m_handleSelected == BOTTOMHANDLE || m_handleSelected == RIGHTHANDLE) + { + paintOutline(); + + KisPoint translate = event->pos() - m_dragEnd; + m_dragEnd = event->pos(); + + double matrixFrom[3][3]; + double* b = KisPerspectiveMath::computeMatrixTransfoToPerspective(m_topleft, m_topright, m_bottomleft, m_bottomright, m_initialRect); + for(int i = 0; i < 3; i++) + { + for(int j = 0; j < 3; j++) + { + matrixFrom[i][j] = b[3*i+j]; + } + } + delete b; + + KisPoint topLeft = KisPerspectiveMath::matProd(matrixFrom, KisPoint(m_initialRect.topLeft()) ); + KisPoint topRight = KisPerspectiveMath::matProd(matrixFrom, KisPoint(m_initialRect.topRight()) ); + KisPoint bottomLeft = KisPerspectiveMath::matProd(matrixFrom, KisPoint(m_initialRect.bottomLeft()) ); + KisPoint bottomRight = KisPerspectiveMath::matProd(matrixFrom, KisPoint(m_initialRect.bottomRight()) ); + TQRect dstRect = m_initialRect; + switch(m_handleSelected) + { + case TOPHANDLE: + dstRect.setTop( static_cast<int>( dstRect.top() + translate.y() ) ) ; + break; + case LEFTHANDLE: + dstRect.setLeft( static_cast<int>( dstRect.left() + translate.x() ) ); + break; + case BOTTOMHANDLE: + dstRect.setBottom( static_cast<int>( dstRect.bottom() + translate.y() ) ); + break; + case RIGHTHANDLE: + dstRect.setRight( static_cast<int>( dstRect.right() + translate.x() ) ); + break; + case MIDDLEHANDLE: + case NOHANDLE: + kdDebug() << "Should NOT happen" << endl; + } + double matrixTo[3][3]; + b = KisPerspectiveMath::computeMatrixTransfoToPerspective(topLeft, topRight, bottomLeft, bottomRight, dstRect ); + for(int i = 0; i < 3; i++) + { + for(int j = 0; j < 3; j++) + { + matrixTo[i][j] = b[3*i+j]; + } + } + delete b; + m_topleft = KisPerspectiveMath::matProd(matrixTo, KisPoint(m_initialRect.topLeft())); + m_topright = KisPerspectiveMath::matProd(matrixTo, KisPoint(m_initialRect.topRight())); + m_bottomleft = KisPerspectiveMath::matProd(matrixTo, KisPoint(m_initialRect.bottomLeft())); + m_bottomright = KisPerspectiveMath::matProd(matrixTo, KisPoint(m_initialRect.bottomRight())); + + paintOutline(); + m_actualyMoveWhileSelected = true; + } else if (m_handleSelected == MIDDLEHANDLE) { + paintOutline(); + KisPoint translate = event->pos() - m_dragEnd; + m_dragEnd = event->pos(); + m_topleft += translate; + m_topright += translate; + m_bottomleft += translate; + m_bottomright += translate; + paintOutline(); + m_actualyMoveWhileSelected = true; + } + } + }; +} + +void KisToolPerspectiveTransform::buttonRelease(KisButtonReleaseEvent * event) +{ + KisImageSP img = m_subject->currentImg(); + + if (!img) + return; + if( event->button() == Qt::LeftButton) + { + switch(m_interractionMode) + { + case DRAWRECTINTERRACTION: + { + if (m_dragging && event->button() == Qt::LeftButton) { + paintOutline(); + m_dragging = false; + m_points.append (m_dragEnd); + if( m_points.size() == 4) + { + // from the points, select which is topleft ? topright ? bottomright ? and bottomleft ? + m_topleft = m_points[0]; + m_topright = m_points[1]; + m_bottomleft = m_points[3]; + m_bottomright = m_points[2]; + double matrix[3][3]; + double* b = KisPerspectiveMath::computeMatrixTransfoToPerspective(m_topleft, m_topright, m_bottomleft, m_bottomright, m_initialRect ); + for(int i = 0; i < 3; i++) + { + for(int j = 0; j < 3; j++) + { + kdDebug() << "sol[" << 3*i+j << "]=" << b[3*i+j] << endl; + matrix[i][j] = b[3*i+j]; + } + } + m_topleft = KisPerspectiveMath::matProd(matrix, KisPoint(m_initialRect.topLeft())); + m_topright = KisPerspectiveMath::matProd(matrix, KisPoint(m_initialRect.topRight())); + m_bottomleft = KisPerspectiveMath::matProd(matrix, KisPoint(m_initialRect.bottomLeft())); + m_bottomright = KisPerspectiveMath::matProd(matrix, KisPoint(m_initialRect.bottomRight())); + m_interractionMode = EDITRECTINTERRACTION; + paintOutline(); + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + transform(); + TQApplication::restoreOverrideCursor(); + } else { + paintOutline(); + } + } + } + break; + case EDITRECTINTERRACTION: + { + if(m_currentSelectedPoint ) + { + m_currentSelectedPoint = 0; + if(m_actualyMoveWhileSelected) + { + paintOutline(); + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + transform(); + TQApplication::restoreOverrideCursor(); + } + } + if(m_handleSelected != NOHANDLE) + { + m_handleSelected = NOHANDLE; + if(m_actualyMoveWhileSelected) + { +// paintOutline(); + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + transform(); + TQApplication::restoreOverrideCursor(); + } + } + } + break; + } + } +} + +void KisToolPerspectiveTransform::paintOutline() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + TQRect rc; + + paintOutline(gc, rc); + } +} + +void KisToolPerspectiveTransform::paintOutline(KisCanvasPainter& gc, const TQRect&) +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + RasterOp op = gc.rasterOp(); + TQPen old = gc.pen(); + TQPen pen(TQt::SolidLine); + pen.setWidth(1); + Q_ASSERT(controller); + + switch(m_interractionMode) + { + case DRAWRECTINTERRACTION: + { + kdDebug() << "DRAWRECTINTERRACTION paintOutline " << m_points.size() << endl; + KisPoint start, end; + TQPoint startPos; + TQPoint endPos; + for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) { + + if (it == m_points.begin()) + { + start = (*it); + } else { + end = (*it); + + startPos = controller->windowToView(start.floorTQPoint()); + endPos = controller->windowToView(end.floorTQPoint()); + + gc.drawLine(startPos, endPos); + + start = end; + } + } + } + break; + case EDITRECTINTERRACTION: + { + TQPoint topleft = controller->windowToView(m_topleft ).roundTQPoint(); + TQPoint topright = controller->windowToView(m_topright).roundTQPoint(); + TQPoint bottomleft = controller->windowToView(m_bottomleft).roundTQPoint(); + TQPoint bottomright = controller->windowToView(m_bottomright).roundTQPoint(); + + gc.setRasterOp(TQt::NotROP); + gc.setPen(pen); + gc.drawRect(topleft.x()-4, topleft.y()-4, 8, 8); + gc.drawLine(topleft.x(), topleft.y(), (topleft.x()+topright.x())/2, (topleft.y()+topright.y())/2); + gc.drawRect((topleft.x()+topright.x())/2-4, (topleft.y()+topright.y())/2-4, 8, 8); + gc.drawLine((topleft.x()+topright.x())/2, (topleft.y()+topright.y())/2, topright.x(), topright.y()); + gc.drawRect(topright.x()-4, topright.y()-4, 8, 8); + gc.drawLine(topright.x(), topright.y(), (topright.x()+bottomright.x())/2, (topright.y()+bottomright.y())/2); + gc.drawRect((topright.x()+bottomright.x())/2-4, (topright.y()+bottomright.y())/2-4, 8, 8); + gc.drawLine((topright.x()+bottomright.x())/2, (topright.y()+bottomright.y())/2,bottomright.x(), bottomright.y()); + gc.drawRect(bottomright.x()-4, bottomright.y()-4, 8, 8); + gc.drawLine(bottomright.x(), bottomright.y(), (bottomleft.x()+bottomright.x())/2, (bottomleft.y()+bottomright.y())/2); + gc.drawRect((bottomleft.x()+bottomright.x())/2-4, (bottomleft.y()+bottomright.y())/2-4, 8, 8); + gc.drawLine((bottomleft.x()+bottomright.x())/2, (bottomleft.y()+bottomright.y())/2, bottomleft.x(), bottomleft.y()); + gc.drawRect(bottomleft.x()-4, bottomleft.y()-4, 8, 8); + gc.drawLine(bottomleft.x(), bottomleft.y(), (topleft.x()+bottomleft.x())/2, (topleft.y()+bottomleft.y())/2); + gc.drawRect((topleft.x()+bottomleft.x())/2-4, (topleft.y()+bottomleft.y())/2-4, 8, 8); + gc.drawLine((topleft.x()+bottomleft.x())/2, (topleft.y()+bottomleft.y())/2, topleft.x(), topleft.y()); + gc.drawRect((bottomleft.x()+bottomright.x()+topleft.x()+topright.x())/4-4, (bottomleft.y()+bottomright.y()+topleft.y()+topright.y())/4-4, 8, 8); + } + break; + } + gc.setRasterOp(op); + gc.setPen(old); + } +} + +void KisToolPerspectiveTransform::transform() +{ + KisImageSP img = m_subject->currentImg(); + + if (!img || !img->activeDevice()) + return; + + KisProgressDisplayInterface *progress = m_subject->progressDisplay(); + + // This mementoes the current state of the active device. + PerspectiveTransformCmd * transaction = new PerspectiveTransformCmd(this, img->activeDevice(), m_origDevice, + m_topleft, m_topright, m_bottomleft, m_bottomright, m_origSelection, m_initialRect); + + // Copy the original state back. + TQRect rc = m_origDevice->extent(); + rc = rc.normalize(); + img->activeDevice()->clear(); + KisPainter gc(img->activeDevice()); + gc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, m_origDevice, rc.x(), rc.y(), rc.width(), rc.height()); + gc.end(); + + // Also restore the original selection. + if(m_origSelection) + { + TQRect rc = m_origSelection->selectedRect(); + rc = rc.normalize(); + img->activeDevice()->selection()->clear(); + KisPainter sgc(img->activeDevice()->selection().data()); + sgc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, m_origSelection.data(), rc.x(), rc.y(), rc.width(), rc.height()); + sgc.end(); + } + else + if(img->activeDevice()->hasSelection()) + img->activeDevice()->selection()->clear(); + + // Perform the transform. Since we copied the original state back, this doesn't degrade + // after many tweaks. Since we started the transaction before the copy back, the memento + // has the previous state. + KisPerspectiveTransformWorker t(img->activeDevice(),m_topleft, m_topright, m_bottomleft, m_bottomright, progress); + t.run(); + + // If canceled, go back to the memento + if(t.isCanceled()) + { + transaction->unexecute(); + delete transaction; + return; + } + + img->activeDevice()->setDirty(rc); // XXX: This is not enough - should union with new extent + + // Else add the command -- this will have the memento from the previous state, + // and the transformed state from the original device we cached in our activated() + // method. + if (transaction) { + if (img->undo()) + img->undoAdapter()->addCommand(transaction); + else + delete transaction; + } +} + +void KisToolPerspectiveTransform::notifyCommandAdded( KCommand * command) +{ + PerspectiveTransformCmd * cmd = dynamic_cast<PerspectiveTransformCmd*>(command); + if (cmd == 0) { + // The last added command wasn't one of ours; + // we should reset to the new state of the canvas. + // In effect we should treat this as if the tool has been just activated + initHandles(); + } +} + +void KisToolPerspectiveTransform::notifyCommandExecuted( KCommand * command) +{ + Q_UNUSED(command); + PerspectiveTransformCmd * cmd=0; + if(m_subject->currentImg()->undoAdapter()->presentCommand()) + cmd = dynamic_cast<PerspectiveTransformCmd*>(m_subject->currentImg()->undoAdapter()->presentCommand()); + + if (cmd == 0) { + // The command now on the top of the stack isn't one of ours + // We should treat this as if the tool has been just activated + initHandles(); + } + else + { + // One of our commands is now on top + // We should ask for tool args and orig selection + m_origDevice = cmd->origDevice(); + cmd->transformArgs(m_topleft, m_topright, m_bottomleft, m_bottomright); + m_origSelection = cmd->origSelection(m_initialRect); + m_subject->canvasController() ->updateCanvas(); + } +} + +void KisToolPerspectiveTransform::slotLayerActivated(KisLayerSP) +{ + activate(); +} + + +TQWidget* KisToolPerspectiveTransform::createOptionWidget(TQWidget* /*parent*/) +{ +#if 0 + m_optWidget = new WdgToolPerspectiveTransform(parent); + TQ_CHECK_PTR(m_optWidget); + + m_optWidget->cmbFilter->clear(); + m_optWidget->cmbFilter->setIDList(KisFilterStrategyRegistry::instance()->listKeys()); + + m_optWidget->cmbFilter->setCurrentText("Mitchell"); + connect(m_optWidget->cmbFilter, TQT_SIGNAL(activated(const KisID &)), + this, TQT_SLOT(slotSetFilter(const KisID &))); + + KisID filterID = m_optWidget->cmbFilter->currentItem(); + m_filter = KisFilterStrategyRegistry::instance()->get(filterID); + +/* + connect(m_optWidget->intStartX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setStartX(int))); + connect(m_optWidget->intStartY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setStartY(int))); + connect(m_optWidget->intEndX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setEndX(int))); + connect(m_optWidget->intEndY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setEndY(int))); +*/ + m_optWidget->intStartX->hide(); + m_optWidget->intStartY->hide(); + m_optWidget->intEndX->hide(); + m_optWidget->intEndY->hide(); + m_optWidget->textLabel1->hide(); + m_optWidget->textLabel2->hide(); + m_optWidget->textLabel3->hide(); + m_optWidget->textLabel4->hide(); +#endif + return 0; +} + +TQWidget* KisToolPerspectiveTransform::optionWidget() +{ + return 0; +} + +void KisToolPerspectiveTransform::setup(TDEActionCollection *collection) +{ + m_action = static_cast<TDERadioAction *>(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Perspective Transform"), + "tool_perspectivetransform", + 0, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + m_action->setToolTip(i18n("Perspective transform a layer or a selection")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_perspectivetransform.moc" |