diff options
Diffstat (limited to 'karbon/tools/vpolylinetool.cpp')
-rw-r--r-- | karbon/tools/vpolylinetool.cpp | 504 |
1 files changed, 504 insertions, 0 deletions
diff --git a/karbon/tools/vpolylinetool.cpp b/karbon/tools/vpolylinetool.cpp new file mode 100644 index 00000000..38ac9d25 --- /dev/null +++ b/karbon/tools/vpolylinetool.cpp @@ -0,0 +1,504 @@ +/* This file is part of the KDE project + Copyright (C) 2001, 2002, 2003 The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + +*/ + +#include <tqcursor.h> +#include <tqevent.h> +#include <tqlabel.h> + +#include <tdelocale.h> + +#include <karbon_part.h> +#include <karbon_view.h> +#include <core/vcolor.h> +#include <core/vcomposite.h> +#include <core/vfill.h> +#include <core/vstroke.h> +#include <core/vglobal.h> +#include <core/vcursor.h> +#include <render/vpainter.h> +#include <render/vpainterfactory.h> +#include "vpolylinetool.h" +#include <commands/vshapecmd.h> +#include <commands/vcommand.h> +#include <widgets/vcanvas.h> + +VPolylineTool::VPolylineTool( KarbonView *view ) + : VTool( view, "tool_polyline" ) +{ + m_bezierPoints.setAutoDelete( true ); + registerTool( this ); + m_crossCursor = new TQCursor( VCursor::createCursor( VCursor::CrossHair ) ); +} + +VPolylineTool::~VPolylineTool() +{ + delete m_crossCursor; +} + +TQString +VPolylineTool::contextHelp() +{ + TQString s = i18n( "<qt><b>Polyline tool:</b><br>" ); + s += i18n( "- <i>Click</i> to add a node and <i>drag</i> to set its bezier vector.<br>" ); + s += i18n( "- Press <i>Ctrl</i> while dragging to edit the previous bezier vector.<br>" ); + s += i18n( "- Press <i>Shift</i> while dragging to change the curve in a straight line.<br>" ); + s += i18n( "- Press <i>Backspace</i> to cancel the last curve.<br>" ); + s += i18n( "- Press <i>Esc</i> to cancel the whole polyline.<br>" ); + s += i18n( "- Press <i>Enter</i> or <i>double click</i> to end the polyline.</qt>" ); + + return s; +} + +void +VPolylineTool::activate() +{ + VTool::activate(); + view()->statusMessage()->setText( i18n( "Polyline Tool" ) ); + view()->setCursor( *m_crossCursor ); + + m_bezierPoints.clear(); + m_close = false; + + connect( view()->part()->commandHistory(), TQT_SIGNAL(commandExecuted()), this, TQT_SLOT(commandExecuted()) ); +} + +void +VPolylineTool::initializePath( VPath &path ) +{ + KoPoint* p1 = m_bezierPoints.first(); + KoPoint* p2; + KoPoint* p3; + KoPoint* p4; + + path.moveTo( *p1 ); + + while( + ( p2 = m_bezierPoints.next() ) && + ( p3 = m_bezierPoints.next() ) && + ( p4 = m_bezierPoints.next() ) ) + { + if ( *p1 == *p2 ) + if ( *p3 == *p4 ) + path.lineTo( *p4 ); + else + //polyline->curve1To( *p3, *p4 ); + path.curveTo( *p3, *p4, *p4 ); + else + if ( *p3 == *p4 ) + //polyline->curve2To( *p2, *p4 ); + path.curveTo( *p2, *p2, *p4 ); + else + path.curveTo( *p2, *p3, *p4 ); + p1 = p4; + } +} + +void +VPolylineTool::createObject() +{ + VPath* polyline = 0L; + if( m_bezierPoints.count() > 2 ) + { + polyline = new VPath( 0L ); + if( polyline ) + { + initializePath( *polyline ); + if( m_close ) + polyline->close(); + + VShapeCmd* cmd = new VShapeCmd( + &view()->part()->document(), + i18n( "Polyline" ), + polyline, + "14_polyline" ); + + view()->part()->addCommand( cmd, true ); + } + } + + m_bezierPoints.clear(); + m_close = false; +} + +void +VPolylineTool::deactivate() +{ + m_bezierPoints.removeLast(); + m_bezierPoints.removeLast(); + + createObject(); + + disconnect( view()->part()->commandHistory(), TQT_SIGNAL(commandExecuted()), this, TQT_SLOT(commandExecuted()) ); +} + +void +VPolylineTool::draw() +{ + VPainter* painter = view()->painterFactory()->editpainter(); + painter->setRasterOp( TQt::NotROP ); + + if( m_bezierPoints.count() > 2 ) + { + VPath polyline( 0L ); + initializePath( polyline ); + + polyline.setState( VObject::edit ); + polyline.draw( painter, &polyline.boundingBox() ); + } +} + +void +VPolylineTool::drawBezierVector( KoPoint& start, KoPoint& end ) +{ + VPainter* painter = view()->painterFactory()->editpainter(); + + painter->save(); + + float zoomFactor = view()->zoom(); + + painter->setRasterOp( TQt::NotROP ); + painter->newPath(); +/* VStroke stroke( TQt::blue, 0L, 1.0 ); + TQValueList<float> array; + array << 2.0 << 3.0; + stroke.dashPattern().setArray( array );*/ + painter->setPen( TQt::DotLine /*stroke*/ ); + painter->setBrush( TQt::NoBrush ); + + painter->moveTo( start ); + painter->lineTo( end ); + painter->strokePath(); + painter->setRasterOp( TQt::XorROP ); + painter->newPath(); + painter->setPen( TQt::yellow ); + + float width = 2.0; + + painter->moveTo( KoPoint( + end.x() - width / zoomFactor, + end.y() - width / zoomFactor ) ); + painter->lineTo( KoPoint( + end.x() + width / zoomFactor, + end.y() - width / zoomFactor ) ); + painter->lineTo( KoPoint( + end.x() + width / zoomFactor, + end.y() + width / zoomFactor ) ); + painter->lineTo( KoPoint( + end.x() - width / zoomFactor, + end.y() + width / zoomFactor ) ); + painter->lineTo( KoPoint( + end.x() - width / zoomFactor, + end.y() - width / zoomFactor ) ); + + painter->strokePath(); + painter->restore(); +} + +void +VPolylineTool::mouseMove() +{ + if( m_bezierPoints.count() != 0 ) + { + KoPoint _last = view()->canvasWidget()->snapToGrid( last() ); + draw(); + + m_bezierPoints.removeLast(); + m_bezierPoints.removeLast(); + m_bezierPoints.append( new KoPoint( _last ) ); + m_bezierPoints.append( new KoPoint( _last ) ); + + draw(); + } +} + +void +VPolylineTool::mouseButtonPress() +{ + KoPoint _last = view()->canvasWidget()->snapToGrid( last() ); + if( m_bezierPoints.count() != 0 ) + { + draw(); + m_bezierPoints.removeLast(); + m_bezierPoints.removeLast(); + m_bezierPoints.append( new KoPoint( _last ) ); + } + + m_lastVectorEnd = m_lastVectorStart = _last; + + m_bezierPoints.append( new KoPoint( _last ) ); + m_bezierPoints.append( new KoPoint( _last ) ); + drawBezierVector( m_lastVectorStart, m_lastVectorEnd ); + draw(); +} + +void +VPolylineTool::mouseButtonRelease() +{ + KoPoint _last = view()->canvasWidget()->snapToGrid( last() ); + if( m_bezierPoints.count() == 2 ) + { + drawBezierVector( m_lastVectorStart, m_lastVectorEnd ); + + m_bezierPoints.removeLast(); + m_bezierPoints.append( new KoPoint( _last ) ); + + VPainter* painter = view()->painterFactory()->editpainter(); + painter->save(); + painter->setZoomFactor( view()->zoom() ); + painter->setRasterOp( TQt::XorROP ); + VStroke stroke( TQt::yellow, 0L, 1.0 ); + painter->setPen( stroke ); + painter->setBrush( TQt::yellow ); + painter->newPath(); + painter->drawNode( m_lastVectorStart, 2 ); + painter->strokePath(); + painter->restore(); + } + else + { + drawBezierVector( m_lastVectorStart, m_lastVectorEnd ); + draw(); + m_bezierPoints.removeLast(); + KoPoint* p = new KoPoint( *m_bezierPoints.last() ); + m_bezierPoints.removeLast(); + KoPoint* b = new KoPoint( *m_bezierPoints.last() ); + m_bezierPoints.removeLast(); + + if( shiftPressed() ) + { + m_bezierPoints.removeLast(); + m_bezierPoints.append( new KoPoint( *m_bezierPoints.last() ) ); + m_bezierPoints.append( new KoPoint( *p ) ); + m_bezierPoints.append( new KoPoint( *p ) ); + m_bezierPoints.append( new KoPoint( *p ) ); + m_lastVectorStart = m_lastVectorEnd = *p; + } + else if( ctrlPressed() ) + { + m_bezierPoints.removeLast(); + m_lastVectorStart = *m_bezierPoints.last(); + m_bezierPoints.append( new KoPoint( _last ) ); + m_bezierPoints.append( new KoPoint( *b ) ); + m_bezierPoints.append( new KoPoint( *p ) ); + m_bezierPoints.append( new KoPoint( *p - ( *b - *p ) ) ); + m_lastVectorEnd = _last; + } + else + { + m_bezierPoints.append( new KoPoint( _last ) ); + m_bezierPoints.append( new KoPoint( *p ) ); + m_bezierPoints.append( new KoPoint( *p - ( _last - *p ) ) ); + m_lastVectorStart = *p; + m_lastVectorEnd = _last; + } + if( m_bezierPoints.count() > 2 && p->isNear( *m_bezierPoints.first(), 3 ) ) + { + m_bezierPoints.append( new KoPoint( _last ) ); + m_close = true; + createObject(); + return; + } + } + + m_bezierPoints.append( new KoPoint( _last ) ); + m_bezierPoints.append( new KoPoint( _last ) ); + + draw(); +} + +void +VPolylineTool::rightMouseButtonRelease() +{ + // end line without adding new points + m_bezierPoints.removeLast(); + m_bezierPoints.removeLast(); + + createObject(); +} + +void +VPolylineTool::mouseButtonDblClick() +{ + createObject(); +} + +void +VPolylineTool::mouseDrag() +{ + KoPoint _last = view()->canvasWidget()->snapToGrid( last() ); + + if( m_bezierPoints.count() == 2 ) + { + drawBezierVector( m_lastVectorStart, m_lastVectorEnd ); + + m_bezierPoints.removeLast(); + m_bezierPoints.append( new KoPoint( _last ) ); + m_lastVectorEnd = _last; + + drawBezierVector( m_lastVectorStart, m_lastVectorEnd ); + } + else + { + drawBezierVector( m_lastVectorStart, m_lastVectorEnd ); + draw(); + + m_bezierPoints.removeLast(); + KoPoint* p = new KoPoint( *m_bezierPoints.last() ); + m_bezierPoints.removeLast(); + KoPoint* b = new KoPoint( *m_bezierPoints.last() ); + m_bezierPoints.removeLast(); + + if( shiftPressed() ) + { + m_bezierPoints.removeLast(); + m_bezierPoints.append( new KoPoint( *m_bezierPoints.last() ) ); + m_bezierPoints.append( new KoPoint( *p ) ); + m_bezierPoints.append( new KoPoint( *p ) ); + m_bezierPoints.append( new KoPoint( *p ) ); + m_lastVectorStart = m_lastVectorEnd = *p; + } + else if( ctrlPressed() ) + { + m_bezierPoints.removeLast(); + m_lastVectorStart = *m_bezierPoints.last(); + m_bezierPoints.append( new KoPoint( _last ) ); + m_bezierPoints.append( new KoPoint( *b ) ); + m_bezierPoints.append( new KoPoint( *p ) ); + m_bezierPoints.append( new KoPoint( *p - ( *b - *p ) ) ); + m_lastVectorEnd = _last; + } + else + { + m_bezierPoints.append( new KoPoint( _last ) ); + m_bezierPoints.append( new KoPoint( *p ) ); + m_bezierPoints.append( new KoPoint( *p - ( _last - *p ) ) ); + m_lastVectorStart = *p; + m_lastVectorEnd = _last; + } + + draw(); + drawBezierVector( m_lastVectorStart, m_lastVectorEnd ); + } +} + +void +VPolylineTool::mouseDragRelease() +{ + mouseButtonRelease(); +} + +void +VPolylineTool::mouseDragShiftPressed() +{ +} + +void +VPolylineTool::mouseDragCtrlPressed() +{ + // Moves the mouse to the other bezier vector position. + if( m_bezierPoints.count() > 3 ) + { + KoPoint p; + p = *m_bezierPoints.at( m_bezierPoints.count() - 4) - *m_bezierPoints.at( m_bezierPoints.count() - 3 ); + + view()->setPos( p ); + } +} + +void +VPolylineTool::mouseDragShiftReleased() +{ +} + +void +VPolylineTool::mouseDragCtrlReleased() +{ + if( m_bezierPoints.count() > 3 ) + { + KoPoint p; + p = *m_bezierPoints.at( m_bezierPoints.count() - 3) - *m_bezierPoints.at( m_bezierPoints.count() - 4 ); + + view()->setPos( p ); + } +} + +void +VPolylineTool::cancel() +{ + draw(); + + m_bezierPoints.clear(); +} + +void +VPolylineTool::cancelStep() +{ + draw(); + + if ( m_bezierPoints.count() > 6 ) + { + m_bezierPoints.removeLast(); + m_bezierPoints.removeLast(); + m_bezierPoints.removeLast(); + KoPoint p1 = *m_bezierPoints.last(); + m_bezierPoints.removeLast(); + m_bezierPoints.removeLast(); + m_bezierPoints.append( new KoPoint( p1 ) ); + m_bezierPoints.append( new KoPoint( p1 ) ); + + view()->setPos( p1 ); + } + else + { + m_bezierPoints.clear(); + } + + draw(); +} + +void +VPolylineTool::accept() +{ + activate(); +} + +void +VPolylineTool::setup( TDEActionCollection *collection ) +{ + m_action = static_cast<TDERadioAction *>(collection -> action( name() ) ); + + if( m_action == 0 ) + { + TDEShortcut shortcut( TQt::Key_Plus ); + shortcut.append( TDEShortcut( TQt::Key_F9 ) ); + m_action = new TDERadioAction( i18n( "Polyline Tool" ), "14_polyline", shortcut, this, TQT_SLOT( activate() ), collection, name() ); + m_action->setToolTip( i18n( "Polyline" ) ); + m_action->setExclusiveGroup( "freehand" ); + //m_ownAction = true; + } +} + +void +VPolylineTool::commandExecuted() +{ + cancel(); +} + +#include "vpolylinetool.moc" |