summaryrefslogtreecommitdiffstats
path: root/karbon/tools/vpolylinetool.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'karbon/tools/vpolylinetool.cpp')
-rw-r--r--karbon/tools/vpolylinetool.cpp504
1 files changed, 504 insertions, 0 deletions
diff --git a/karbon/tools/vpolylinetool.cpp b/karbon/tools/vpolylinetool.cpp
new file mode 100644
index 000000000..38ac9d256
--- /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"