diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
commit | 8362bf63dea22bbf6736609b0f49c152f975eb63 (patch) | |
tree | 0eea3928e39e50fae91d4e68b21b1e6cbae25604 /krita/plugins/tools/tool_perspectivetransform | |
download | koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.tar.gz koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.zip |
Added old abandoned KDE3 version of koffice
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'krita/plugins/tools/tool_perspectivetransform')
8 files changed, 1135 insertions, 0 deletions
diff --git a/krita/plugins/tools/tool_perspectivetransform/Makefile.am b/krita/plugins/tools/tool_perspectivetransform/Makefile.am new file mode 100644 index 00000000..5a833521 --- /dev/null +++ b/krita/plugins/tools/tool_perspectivetransform/Makefile.am @@ -0,0 +1,34 @@ +kde_services_DATA = kritatoolperspectivetransform.desktop + +# all_includes must remain last! +INCLUDES = -I$(srcdir)/../../../sdk \ + -I$(srcdir)/../../../core \ + -I$(srcdir)/../../../kritacolor/ \ + -I$(srcdir)/../../../ui \ + -I$/../../../ui \ + $(KOFFICE_INCLUDES) \ + $(all_includes) + +kritatoolperspectivetransform_la_SOURCES = \ + tool_perspectivetransform.cc \ + kis_tool_perspectivetransform.cc + +# Install this plugin in the KDE modules directory +kde_module_LTLIBRARIES = kritatoolperspectivetransform.la + +noinst_HEADERS = \ + tool_perspectivetransform.h \ + kis_tool_perspectivetransform.h + +kritatoolperspectivetransform_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +kritatoolperspectivetransform_la_LIBADD = ../../../libkritacommon.la + +kritatoolperspectivetransform_la_METASOURCES = AUTO + +KDE_OPTIONS = nofinal + +kritapics_DATA = \ + tool_perspectivetransform.png + +kritapicsdir = $(kde_datadir)/krita/pics + diff --git a/krita/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cc b/krita/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cc new file mode 100644 index 00000000..f334c429 --- /dev/null +++ b/krita/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cc @@ -0,0 +1,742 @@ +/* + * kis_tool_transform.cc -- part of Krita + * + * 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 <qpainter.h> +#include <qpen.h> +#include <qpushbutton.h> +#include <qobject.h> +#include <qlabel.h> +#include <qcombobox.h> +#include <qapplication.h> + +#include <kdebug.h> +#include <kaction.h> +#include <kcommand.h> +#include <klocale.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, QRect initialRect); + virtual ~PerspectiveTransformCmd(); + + public: + virtual void execute(); + virtual void unexecute(); + void transformArgs(KisPoint &topleft, KisPoint &topright, KisPoint &bottomleft, KisPoint& bottomright) const; + KisSelectionSP origSelection(QRect& initialRect) const; + KisPaintDeviceSP theDevice(); + KisPaintDeviceSP origDevice(); + + private: + QRect 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, QRect 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(QRect& 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(), SIGNAL(sigLayerActivated(KisLayerSP)), this, 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(), SIGNAL(sigLayerActivated(KisLayerSP)), this, SLOT(slotLayerActivated(KisLayerSP))); +} + +void KisToolPerspectiveTransform::initHandles() +{ +// Q_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 = m_initialRect.topLeft(); + m_topright = m_initialRect.topRight(); + m_bottomleft = m_initialRect.bottomLeft(); + m_bottomright = m_initialRect.bottomRight(); + + m_subject->canvasController() ->updateCanvas(); +} + +void KisToolPerspectiveTransform::paint(KisCanvasPainter& gc) +{ + paintOutline(gc, QRect()); +} + +void KisToolPerspectiveTransform::paint(KisCanvasPainter& gc, const QRect& rc) +{ + paintOutline(gc, rc); +} + +bool KisToolPerspectiveTransform::mouseNear(const QPoint& mousep, const QPoint point) +{ + return (QRect( (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() == LeftButton) { + m_actualyMoveWhileSelected = false; + m_dragEnd = event->pos(); + KisCanvasController *controller = m_subject->canvasController(); + QPoint mousep = controller->windowToView( event->pos().roundQPoint() ); + if( mouseNear( mousep, controller->windowToView(m_topleft.roundQPoint() ) ) ) + { + kdDebug() << " PRESS TOPLEFT HANDLE " << endl; + m_currentSelectedPoint = &m_topleft; + } + else if( mouseNear( mousep, controller->windowToView(m_topright.roundQPoint() ) ) ) + { + kdDebug() << " PRESS TOPRIGHT HANDLE " << endl; + m_currentSelectedPoint = &m_topright; + } + else if( mouseNear( mousep, controller->windowToView(m_bottomleft.roundQPoint() ) ) ) + { + kdDebug() << " PRESS BOTTOMLEFT HANDLE " << endl; + m_currentSelectedPoint = &m_bottomleft; + } + else if( mouseNear( mousep, controller->windowToView(m_bottomright.roundQPoint() ) ) ) + { + kdDebug() << " PRESS BOTTOMRIGHT HANDLE " << endl; + m_currentSelectedPoint = &m_bottomright; + } else if( mouseNear( mousep, controller->windowToView(KisPoint((m_topleft+m_topright)*0.5).roundQPoint() ) ) ) + { + kdDebug() << " PRESS TOP HANDLE " << endl; + m_handleSelected = TOPHANDLE; + }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_topleft+m_bottomleft)*0.5).roundQPoint() ) ) ) + { + kdDebug() << " PRESS LEFT HANDLE " << endl; + m_handleSelected = LEFTHANDLE; + }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_bottomleft+m_bottomright)*0.5).roundQPoint() ) ) ) + { + kdDebug() << " PRESS BOTTOM HANDLE " << endl; + m_handleSelected = BOTTOMHANDLE; + }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_bottomright+m_topright)*0.5).roundQPoint() ) ) ) + { + 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).roundQPoint() ) ) ) + { + 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, m_initialRect.topLeft() ); + KisPoint topRight = KisPerspectiveMath::matProd(matrixFrom, m_initialRect.topRight() ); + KisPoint bottomLeft = KisPerspectiveMath::matProd(matrixFrom, m_initialRect.bottomLeft() ); + KisPoint bottomRight = KisPerspectiveMath::matProd(matrixFrom, m_initialRect.bottomRight() ); + QRect 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, m_initialRect.topLeft()); + m_topright = KisPerspectiveMath::matProd(matrixTo, m_initialRect.topRight()); + m_bottomleft = KisPerspectiveMath::matProd(matrixTo, m_initialRect.bottomLeft()); + m_bottomright = KisPerspectiveMath::matProd(matrixTo, 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() == LeftButton) + { + switch(m_interractionMode) + { + case DRAWRECTINTERRACTION: + { + if (m_dragging && event->button() == 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, m_initialRect.topLeft()); + m_topright = KisPerspectiveMath::matProd(matrix, m_initialRect.topRight()); + m_bottomleft = KisPerspectiveMath::matProd(matrix, m_initialRect.bottomLeft()); + m_bottomright = KisPerspectiveMath::matProd(matrix, m_initialRect.bottomRight()); + m_interractionMode = EDITRECTINTERRACTION; + paintOutline(); + QApplication::setOverrideCursor(KisCursor::waitCursor()); + transform(); + QApplication::restoreOverrideCursor(); + } else { + paintOutline(); + } + } + } + break; + case EDITRECTINTERRACTION: + { + if(m_currentSelectedPoint ) + { + m_currentSelectedPoint = 0; + if(m_actualyMoveWhileSelected) + { + paintOutline(); + QApplication::setOverrideCursor(KisCursor::waitCursor()); + transform(); + QApplication::restoreOverrideCursor(); + } + } + if(m_handleSelected != NOHANDLE) + { + m_handleSelected = NOHANDLE; + if(m_actualyMoveWhileSelected) + { +// paintOutline(); + QApplication::setOverrideCursor(KisCursor::waitCursor()); + transform(); + QApplication::restoreOverrideCursor(); + } + } + } + break; + } + } +} + +void KisToolPerspectiveTransform::paintOutline() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + QRect rc; + + paintOutline(gc, rc); + } +} + +void KisToolPerspectiveTransform::paintOutline(KisCanvasPainter& gc, const QRect&) +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + RasterOp op = gc.rasterOp(); + QPen old = gc.pen(); + QPen pen(Qt::SolidLine); + pen.setWidth(1); + Q_ASSERT(controller); + + switch(m_interractionMode) + { + case DRAWRECTINTERRACTION: + { + kdDebug() << "DRAWRECTINTERRACTION paintOutline " << m_points.size() << endl; + KisPoint start, end; + QPoint startPos; + QPoint 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.floorQPoint()); + endPos = controller->windowToView(end.floorQPoint()); + + gc.drawLine(startPos, endPos); + + start = end; + } + } + } + break; + case EDITRECTINTERRACTION: + { + QPoint topleft = controller->windowToView(m_topleft ).roundQPoint(); + QPoint topright = controller->windowToView(m_topright).roundQPoint(); + QPoint bottomleft = controller->windowToView(m_bottomleft).roundQPoint(); + QPoint bottomright = controller->windowToView(m_bottomright).roundQPoint(); + + gc.setRasterOp(Qt::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. + QRect 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) + { + QRect 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(); +} + + +QWidget* KisToolPerspectiveTransform::createOptionWidget(QWidget* /*parent*/) +{ +#if 0 + m_optWidget = new WdgToolPerspectiveTransform(parent); + Q_CHECK_PTR(m_optWidget); + + m_optWidget->cmbFilter->clear(); + m_optWidget->cmbFilter->setIDList(KisFilterStrategyRegistry::instance()->listKeys()); + + m_optWidget->cmbFilter->setCurrentText("Mitchell"); + connect(m_optWidget->cmbFilter, SIGNAL(activated(const KisID &)), + this, SLOT(slotSetFilter(const KisID &))); + + KisID filterID = m_optWidget->cmbFilter->currentItem(); + m_filter = KisFilterStrategyRegistry::instance()->get(filterID); + +/* + connect(m_optWidget->intStartX, SIGNAL(valueChanged(int)), this, SLOT(setStartX(int))); + connect(m_optWidget->intStartY, SIGNAL(valueChanged(int)), this, SLOT(setStartY(int))); + connect(m_optWidget->intEndX, SIGNAL(valueChanged(int)), this, SLOT(setEndX(int))); + connect(m_optWidget->intEndY, SIGNAL(valueChanged(int)), this, 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; +} + +QWidget* KisToolPerspectiveTransform::optionWidget() +{ + return 0; +} + +void KisToolPerspectiveTransform::setup(KActionCollection *collection) +{ + m_action = static_cast<KRadioAction *>(collection->action(name())); + + if (m_action == 0) { + m_action = new KRadioAction(i18n("&Perspective Transform"), + "tool_perspectivetransform", + 0, + this, + SLOT(activate()), + collection, + name()); + Q_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" diff --git a/krita/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.h b/krita/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.h new file mode 100644 index 00000000..e2600cfc --- /dev/null +++ b/krita/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.h @@ -0,0 +1,130 @@ +/* + * kis_tool_transform.h - part of Krita + * + * 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. + */ + +#ifndef KIS_TOOL_PERSPECTIVETRANSFORM_H_ +#define KIS_TOOL_PERSPECTIVETRANSFORM_H_ + +#include <qpoint.h> + +#include <kis_layer.h> +#include <kis_point.h> +#include <kis_tool_non_paint.h> +#include <kis_tool_factory.h> +#include <kis_undo_adapter.h> +#include <kis_perspective_math.h> + +class KisTransaction; +class WdgToolPerspectiveTransform; +class KisID; +class KisFilterStrategy; + +/** + * PerspectiveTransform tool + * + */ +class KisToolPerspectiveTransform : public KisToolNonPaint, KisCommandHistoryListener { + + typedef KisToolNonPaint super; + Q_OBJECT + enum InterractionMode { DRAWRECTINTERRACTION, EDITRECTINTERRACTION }; + enum HandleSelected { NOHANDLE, TOPHANDLE, BOTTOMHANDLE, RIGHTHANDLE, LEFTHANDLE, MIDDLEHANDLE }; +public: + KisToolPerspectiveTransform(); + virtual ~KisToolPerspectiveTransform(); + + virtual QWidget* createOptionWidget(QWidget* parent); + virtual QWidget* optionWidget(); + + virtual void setup(KActionCollection *collection); + virtual enumToolType toolType() { return TOOL_TRANSFORM; } + virtual Q_UINT32 priority() { return 4; } + virtual void paint(KisCanvasPainter& gc); + virtual void paint(KisCanvasPainter& gc, const QRect& rc); + virtual void buttonPress(KisButtonPressEvent *e); + virtual void move(KisMoveEvent *e); + virtual void buttonRelease(KisButtonReleaseEvent *e); + void paintOutline(); + +public: + + void notifyCommandAdded(KCommand *); + void notifyCommandExecuted(KCommand *); + +public: + virtual void deactivate(); + +private: + + bool mouseNear(const QPoint& mousep, const QPoint point); + void paintOutline(KisCanvasPainter& gc, const QRect& rc); + void transform(); + void initHandles(); + +private slots: + void slotLayerActivated(KisLayerSP); + +protected slots: + virtual void activate(); + +private: + bool m_dragging; + InterractionMode m_interractionMode; + QRect m_initialRect; + KisPoint m_dragStart, m_dragEnd; + KisPoint m_topleft, m_topright, m_bottomleft, m_bottomright; + KisPoint* m_currentSelectedPoint; + bool m_actualyMoveWhileSelected; + + WdgToolPerspectiveTransform *m_optWidget; + + KisPaintDeviceSP m_origDevice; + KisSelectionSP m_origSelection; + int m_handleHalfSize, m_handleSize; + + // The following variables are used in during the draw rect interraction mode + typedef QValueVector<KisPoint> KisPointVector; + KisPointVector m_points; + // The following variables are used when moving a middle handle + HandleSelected m_handleSelected; + +}; + +class KisToolPerspectiveTransformFactory : public KisToolFactory { + typedef KisToolFactory super; + +public: + KisToolPerspectiveTransformFactory() : super() {}; + virtual ~KisToolPerspectiveTransformFactory(){}; + + virtual KisTool * createTool(KActionCollection * ac) { + KisTool * t = new KisToolPerspectiveTransform(); + Q_CHECK_PTR(t); + t->setup(ac); return t; + } + virtual KisID id() { return KisID("perspective transform", i18n("Perspective transform Tool")); } +}; + + + +#endif // KIS_TOOL_TRANSFORM_H_ + diff --git a/krita/plugins/tools/tool_perspectivetransform/kritatoolperspectivetransform.desktop b/krita/plugins/tools/tool_perspectivetransform/kritatoolperspectivetransform.desktop new file mode 100644 index 00000000..4ad0c64f --- /dev/null +++ b/krita/plugins/tools/tool_perspectivetransform/kritatoolperspectivetransform.desktop @@ -0,0 +1,37 @@ +[Desktop Entry] +Icon= +Name=Perspective transform Tool +Name[bg]=Инструмент трансформиране +Name[ca]=Eina de transformació de perspectiva +Name[da]=Perspectivetransformeringsværktøj +Name[de]=Perspektive-Transformationswerkzeug +Name[el]=Εργαλείο προοπτικού μετασχηματισμού +Name[eo]=Perspektivŝanĝo-ilo +Name[es]=Herramienta Transformar perspectiva +Name[et]=Perspektiivteisenduse tööriist +Name[fa]=ابزار تبدیل بُعدنما +Name[fr]=Outils de transformation de perspective +Name[fy]=Perspeksje oerset ark +Name[hu]=Perspektívaátalakító eszköz +Name[it]=Strumento di trasformazione della prospettiva +Name[ja]=視点変更ツール +Name[km]=ឧបករណ៍ប្លែងយថាទស្សន៍ +Name[nb]=Verktøy for perspektivtransformasjon +Name[nds]=Warktüüch för't Kiekwinkeltopassen +Name[ne]=दृश्यात्मक रूपान्तरण उपकरण +Name[nl]=Perspectiefrooster-gereedschap +Name[pl]=Narzędzie zmiany perspektywy +Name[pt]=Ferramenta de Transformação em Perspectiva +Name[pt_BR]=Ferramentas de Transformação em Perspectiva +Name[ru]=Перспектива +Name[sk]=Perspektívna transformácia +Name[sl]=Orodje za transformacijo perspektive +Name[sr]=Алати за трансформацију перспективе +Name[sr@Latn]=Alati za transformaciju perspektive +Name[sv]=Perspektivtransformverktyg +Name[uk]=Засіб перспективи +Name[zh_TW]=透視轉換工具 +ServiceTypes=Krita/Tool +Type=Service +X-KDE-Library=kritatoolperspectivetransform +X-Krita-Version=2 diff --git a/krita/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.cc b/krita/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.cc new file mode 100644 index 00000000..3fdbe3bb --- /dev/null +++ b/krita/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.cc @@ -0,0 +1,63 @@ +/* + * tool_perspectivetransform.cc -- Part of Krita + * + * 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 <stdlib.h> +#include <vector> + +#include <qpoint.h> + +#include <klocale.h> +#include <kiconloader.h> +#include <kinstance.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <kdebug.h> +#include <kgenericfactory.h> + +#include <kis_global.h> +#include <kis_types.h> +#include <kis_tool_registry.h> + +#include "tool_perspectivetransform.h" +#include "kis_tool_perspectivetransform.h" + + +typedef KGenericFactory<ToolPerspectiveTransform> ToolPerspectiveTransformFactory; +K_EXPORT_COMPONENT_FACTORY( kritatoolperspectivetransform, ToolPerspectiveTransformFactory( "krita" ) ) + + +ToolPerspectiveTransform::ToolPerspectiveTransform(QObject *parent, const char *name, const QStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ToolPerspectiveTransformFactory::instance()); + + if ( parent->inherits("KisToolRegistry") ) + { + kdDebug() << " add perspective transform tool to the registry" << endl; + KisToolRegistry * r = dynamic_cast<KisToolRegistry*>(parent); + r->add(new KisToolPerspectiveTransformFactory()); + } + +} + +ToolPerspectiveTransform::~ToolPerspectiveTransform() +{ +} + +#include "tool_perspectivetransform.moc" diff --git a/krita/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.h b/krita/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.h new file mode 100644 index 00000000..6cc6370f --- /dev/null +++ b/krita/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.h @@ -0,0 +1,42 @@ +/* + * 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. + */ + +#ifndef TOOL_PERSPECTIVE_TRANSFORM_H_ +#define TOOL_PERSPECTIVE_TRANSFORM_H_ + +#include <kparts/plugin.h> + +class KisView; + +/** + * A module that provides a tool for doinge perspective transformation. + */ +class ToolPerspectiveTransform : public KParts::Plugin +{ + Q_OBJECT +public: + ToolPerspectiveTransform(QObject *parent, const char *name, const QStringList &); + virtual ~ToolPerspectiveTransform(); + +private: + + KisView * m_view; + +}; + +#endif // TOOL_PERSPECTIVE_TRANSFORM_H_ diff --git a/krita/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.png b/krita/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.png Binary files differnew file mode 100644 index 00000000..7b6fea09 --- /dev/null +++ b/krita/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.png diff --git a/krita/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.svg b/krita/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.svg new file mode 100644 index 00000000..24405305 --- /dev/null +++ b/krita/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.svg @@ -0,0 +1,87 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://web.resource.org/cc/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="22" + height="22" + id="svg2" + sodipodi:version="0.32" + inkscape:version="0.43" + version="1.0" + sodipodi:docbase="/home/cyrille/koffice-1.6/krita/plugins/tools/tool_perspectivegrid" + sodipodi:docname="tool_perspectivegrid.svg" + inkscape:export-filename="/home/cyrille/koffice-1.6/krita/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.png" + inkscape:export-xdpi="90" + inkscape:export-ydpi="90"> + <defs + id="defs4" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="9.8597476" + inkscape:cx="12.855376" + inkscape:cy="7.6671075" + inkscape:document-units="px" + inkscape:current-layer="layer1" + inkscape:window-width="749" + inkscape:window-height="540" + inkscape:window-x="424" + inkscape:window-y="433" /> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#909090;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 4.8682788,20.580085 C 6.5924609,1.3098151 6.7953058,1.5126601 6.7953058,1.5126601 L 6.7953058,1.5126601 L 6.7953058,1.5126601" + id="path2183" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#909090;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 11.359317,18.551636 C 10.446515,2.3240399 10.446515,2.3240399 10.446515,2.3240399 L 10.446515,2.3240399 L 10.446515,2.3240399" + id="path2185" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#909090;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 17.444666,17.131721 C 13.894879,3.1354197 13.894879,3.1354197 13.894879,3.1354197" + id="path2187" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#909090;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 2.7384068,4.7581793 C 17.647511,6.5837838 17.546088,6.5837838 17.546088,6.5837838" + id="path2191" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#909090;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 2.0284495,10.742105 C 18.256045,9.7278805 18.86458,9.1193456 18.86458,9.1193456" + id="path2193" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#909090;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 1.0142247,17.131721 C 20.08165,12.56771 20.08165,12.364865 20.08165,12.364865" + id="path2195" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 3.1440967,0.59985768 L 16.531864,3.6425319 L 21.70441,15.813228 L 0.50711235,21.594309 L 3.1440967,0.59985768 z " + id="rect1307" + sodipodi:nodetypes="ccccc" /> + </g> +</svg> |