karbon

vpolylinetool.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2001, 2002, 2003 The Karbon Developers
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18
19*/
20
21#include <tqcursor.h>
22#include <tqevent.h>
23#include <tqlabel.h>
24
25#include <tdelocale.h>
26
27#include <karbon_part.h>
28#include <karbon_view.h>
29#include <core/vcolor.h>
30#include <core/vcomposite.h>
31#include <core/vfill.h>
32#include <core/vstroke.h>
33#include <core/vglobal.h>
34#include <core/vcursor.h>
35#include <render/vpainter.h>
36#include <render/vpainterfactory.h>
37#include "vpolylinetool.h"
38#include <commands/vshapecmd.h>
39#include <commands/vcommand.h>
40#include <widgets/vcanvas.h>
41
42VPolylineTool::VPolylineTool( KarbonView *view )
43 : VTool( view, "tool_polyline" )
44{
45 m_bezierPoints.setAutoDelete( true );
46 registerTool( this );
47 m_crossCursor = new TQCursor( VCursor::createCursor( VCursor::CrossHair ) );
48}
49
50VPolylineTool::~VPolylineTool()
51{
52 delete m_crossCursor;
53}
54
55TQString
57{
58 TQString s = i18n( "<qt><b>Polyline tool:</b><br>" );
59 s += i18n( "- <i>Click</i> to add a node and <i>drag</i> to set its bezier vector.<br>" );
60 s += i18n( "- Press <i>Ctrl</i> while dragging to edit the previous bezier vector.<br>" );
61 s += i18n( "- Press <i>Shift</i> while dragging to change the curve in a straight line.<br>" );
62 s += i18n( "- Press <i>Backspace</i> to cancel the last curve.<br>" );
63 s += i18n( "- Press <i>Esc</i> to cancel the whole polyline.<br>" );
64 s += i18n( "- Press <i>Enter</i> or <i>double click</i> to end the polyline.</qt>" );
65
66 return s;
67}
68
69void
71{
73 view()->statusMessage()->setText( i18n( "Polyline Tool" ) );
74 view()->setCursor( *m_crossCursor );
75
76 m_bezierPoints.clear();
77 m_close = false;
78
79 connect( view()->part()->commandHistory(), TQ_SIGNAL(commandExecuted()), this, TQ_SLOT(commandExecuted()) );
80}
81
82void
84{
85 KoPoint* p1 = m_bezierPoints.first();
86 KoPoint* p2;
87 KoPoint* p3;
88 KoPoint* p4;
89
90 path.moveTo( *p1 );
91
92 while(
93 ( p2 = m_bezierPoints.next() ) &&
94 ( p3 = m_bezierPoints.next() ) &&
95 ( p4 = m_bezierPoints.next() ) )
96 {
97 if ( *p1 == *p2 )
98 if ( *p3 == *p4 )
99 path.lineTo( *p4 );
100 else
101 //polyline->curve1To( *p3, *p4 );
102 path.curveTo( *p3, *p4, *p4 );
103 else
104 if ( *p3 == *p4 )
105 //polyline->curve2To( *p2, *p4 );
106 path.curveTo( *p2, *p2, *p4 );
107 else
108 path.curveTo( *p2, *p3, *p4 );
109 p1 = p4;
110 }
111}
112
113void
115{
116 VPath* polyline = 0L;
117 if( m_bezierPoints.count() > 2 )
118 {
119 polyline = new VPath( 0L );
120 if( polyline )
121 {
122 initializePath( *polyline );
123 if( m_close )
124 polyline->close();
125
126 VShapeCmd* cmd = new VShapeCmd(
127 &view()->part()->document(),
128 i18n( "Polyline" ),
129 polyline,
130 "14_polyline" );
131
132 view()->part()->addCommand( cmd, true );
133 }
134 }
135
136 m_bezierPoints.clear();
137 m_close = false;
138}
139
140void
142{
143 m_bezierPoints.removeLast();
144 m_bezierPoints.removeLast();
145
146 createObject();
147
148 disconnect( view()->part()->commandHistory(), TQ_SIGNAL(commandExecuted()), this, TQ_SLOT(commandExecuted()) );
149}
150
151void
153{
154 VPainter* painter = view()->painterFactory()->editpainter();
155 painter->setRasterOp( TQt::NotROP );
156
157 if( m_bezierPoints.count() > 2 )
158 {
159 VPath polyline( 0L );
160 initializePath( polyline );
161
162 polyline.setState( VObject::edit );
163 polyline.draw( painter, &polyline.boundingBox() );
164 }
165}
166
167void
168VPolylineTool::drawBezierVector( KoPoint& start, KoPoint& end )
169{
170 VPainter* painter = view()->painterFactory()->editpainter();
171
172 painter->save();
173
174 float zoomFactor = view()->zoom();
175
176 painter->setRasterOp( TQt::NotROP );
177 painter->newPath();
178/* VStroke stroke( TQt::blue, 0L, 1.0 );
179 TQValueList<float> array;
180 array << 2.0 << 3.0;
181 stroke.dashPattern().setArray( array );*/
182 painter->setPen( TQt::DotLine /*stroke*/ );
183 painter->setBrush( TQt::NoBrush );
184
185 painter->moveTo( start );
186 painter->lineTo( end );
187 painter->strokePath();
188 painter->setRasterOp( TQt::XorROP );
189 painter->newPath();
190 painter->setPen( TQt::yellow );
191
192 float width = 2.0;
193
194 painter->moveTo( KoPoint(
195 end.x() - width / zoomFactor,
196 end.y() - width / zoomFactor ) );
197 painter->lineTo( KoPoint(
198 end.x() + width / zoomFactor,
199 end.y() - width / zoomFactor ) );
200 painter->lineTo( KoPoint(
201 end.x() + width / zoomFactor,
202 end.y() + width / zoomFactor ) );
203 painter->lineTo( KoPoint(
204 end.x() - width / zoomFactor,
205 end.y() + width / zoomFactor ) );
206 painter->lineTo( KoPoint(
207 end.x() - width / zoomFactor,
208 end.y() - width / zoomFactor ) );
209
210 painter->strokePath();
211 painter->restore();
212}
213
214void
216{
217 if( m_bezierPoints.count() != 0 )
218 {
219 KoPoint _last = view()->canvasWidget()->snapToGrid( last() );
220 draw();
221
222 m_bezierPoints.removeLast();
223 m_bezierPoints.removeLast();
224 m_bezierPoints.append( new KoPoint( _last ) );
225 m_bezierPoints.append( new KoPoint( _last ) );
226
227 draw();
228 }
229}
230
231void
233{
234 KoPoint _last = view()->canvasWidget()->snapToGrid( last() );
235 if( m_bezierPoints.count() != 0 )
236 {
237 draw();
238 m_bezierPoints.removeLast();
239 m_bezierPoints.removeLast();
240 m_bezierPoints.append( new KoPoint( _last ) );
241 }
242
244
245 m_bezierPoints.append( new KoPoint( _last ) );
246 m_bezierPoints.append( new KoPoint( _last ) );
248 draw();
249}
250
251void
253{
254 KoPoint _last = view()->canvasWidget()->snapToGrid( last() );
255 if( m_bezierPoints.count() == 2 )
256 {
258
259 m_bezierPoints.removeLast();
260 m_bezierPoints.append( new KoPoint( _last ) );
261
262 VPainter* painter = view()->painterFactory()->editpainter();
263 painter->save();
264 painter->setZoomFactor( view()->zoom() );
265 painter->setRasterOp( TQt::XorROP );
266 VStroke stroke( TQt::yellow, 0L, 1.0 );
267 painter->setPen( stroke );
268 painter->setBrush( TQt::yellow );
269 painter->newPath();
270 painter->drawNode( m_lastVectorStart, 2 );
271 painter->strokePath();
272 painter->restore();
273 }
274 else
275 {
277 draw();
278 m_bezierPoints.removeLast();
279 KoPoint* p = new KoPoint( *m_bezierPoints.last() );
280 m_bezierPoints.removeLast();
281 KoPoint* b = new KoPoint( *m_bezierPoints.last() );
282 m_bezierPoints.removeLast();
283
284 if( shiftPressed() )
285 {
286 m_bezierPoints.removeLast();
287 m_bezierPoints.append( new KoPoint( *m_bezierPoints.last() ) );
288 m_bezierPoints.append( new KoPoint( *p ) );
289 m_bezierPoints.append( new KoPoint( *p ) );
290 m_bezierPoints.append( new KoPoint( *p ) );
292 }
293 else if( ctrlPressed() )
294 {
295 m_bezierPoints.removeLast();
297 m_bezierPoints.append( new KoPoint( _last ) );
298 m_bezierPoints.append( new KoPoint( *b ) );
299 m_bezierPoints.append( new KoPoint( *p ) );
300 m_bezierPoints.append( new KoPoint( *p - ( *b - *p ) ) );
301 m_lastVectorEnd = _last;
302 }
303 else
304 {
305 m_bezierPoints.append( new KoPoint( _last ) );
306 m_bezierPoints.append( new KoPoint( *p ) );
307 m_bezierPoints.append( new KoPoint( *p - ( _last - *p ) ) );
309 m_lastVectorEnd = _last;
310 }
311 if( m_bezierPoints.count() > 2 && p->isNear( *m_bezierPoints.first(), 3 ) )
312 {
313 m_bezierPoints.append( new KoPoint( _last ) );
314 m_close = true;
315 createObject();
316 return;
317 }
318 }
319
320 m_bezierPoints.append( new KoPoint( _last ) );
321 m_bezierPoints.append( new KoPoint( _last ) );
322
323 draw();
324}
325
326void
328{
329 // end line without adding new points
330 m_bezierPoints.removeLast();
331 m_bezierPoints.removeLast();
332
333 createObject();
334}
335
336void
341
342void
344{
345 KoPoint _last = view()->canvasWidget()->snapToGrid( last() );
346
347 if( m_bezierPoints.count() == 2 )
348 {
350
351 m_bezierPoints.removeLast();
352 m_bezierPoints.append( new KoPoint( _last ) );
353 m_lastVectorEnd = _last;
354
356 }
357 else
358 {
360 draw();
361
362 m_bezierPoints.removeLast();
363 KoPoint* p = new KoPoint( *m_bezierPoints.last() );
364 m_bezierPoints.removeLast();
365 KoPoint* b = new KoPoint( *m_bezierPoints.last() );
366 m_bezierPoints.removeLast();
367
368 if( shiftPressed() )
369 {
370 m_bezierPoints.removeLast();
371 m_bezierPoints.append( new KoPoint( *m_bezierPoints.last() ) );
372 m_bezierPoints.append( new KoPoint( *p ) );
373 m_bezierPoints.append( new KoPoint( *p ) );
374 m_bezierPoints.append( new KoPoint( *p ) );
376 }
377 else if( ctrlPressed() )
378 {
379 m_bezierPoints.removeLast();
381 m_bezierPoints.append( new KoPoint( _last ) );
382 m_bezierPoints.append( new KoPoint( *b ) );
383 m_bezierPoints.append( new KoPoint( *p ) );
384 m_bezierPoints.append( new KoPoint( *p - ( *b - *p ) ) );
385 m_lastVectorEnd = _last;
386 }
387 else
388 {
389 m_bezierPoints.append( new KoPoint( _last ) );
390 m_bezierPoints.append( new KoPoint( *p ) );
391 m_bezierPoints.append( new KoPoint( *p - ( _last - *p ) ) );
393 m_lastVectorEnd = _last;
394 }
395
396 draw();
398 }
399}
400
401void
406
407void
411
412void
414{
415 // Moves the mouse to the other bezier vector position.
416 if( m_bezierPoints.count() > 3 )
417 {
418 KoPoint p;
419 p = *m_bezierPoints.at( m_bezierPoints.count() - 4) - *m_bezierPoints.at( m_bezierPoints.count() - 3 );
420
421 view()->setPos( p );
422 }
423}
424
425void
429
430void
432{
433 if( m_bezierPoints.count() > 3 )
434 {
435 KoPoint p;
436 p = *m_bezierPoints.at( m_bezierPoints.count() - 3) - *m_bezierPoints.at( m_bezierPoints.count() - 4 );
437
438 view()->setPos( p );
439 }
440}
441
442void
444{
445 draw();
446
447 m_bezierPoints.clear();
448}
449
450void
452{
453 draw();
454
455 if ( m_bezierPoints.count() > 6 )
456 {
457 m_bezierPoints.removeLast();
458 m_bezierPoints.removeLast();
459 m_bezierPoints.removeLast();
460 KoPoint p1 = *m_bezierPoints.last();
461 m_bezierPoints.removeLast();
462 m_bezierPoints.removeLast();
463 m_bezierPoints.append( new KoPoint( p1 ) );
464 m_bezierPoints.append( new KoPoint( p1 ) );
465
466 view()->setPos( p1 );
467 }
468 else
469 {
470 m_bezierPoints.clear();
471 }
472
473 draw();
474}
475
476void
481
482void
483VPolylineTool::setup( TDEActionCollection *collection )
484{
485 m_action = static_cast<TDERadioAction *>(collection -> action( name() ) );
486
487 if( m_action == 0 )
488 {
489 TDEShortcut shortcut( TQt::Key_Plus );
490 shortcut.append( TDEShortcut( TQt::Key_F9 ) );
491 m_action = new TDERadioAction( i18n( "Polyline Tool" ), "14_polyline", shortcut, this, TQ_SLOT( activate() ), collection, name() );
492 m_action->setToolTip( i18n( "Polyline" ) );
493 m_action->setExclusiveGroup( "freehand" );
494 //m_ownAction = true;
495 }
496}
497
498void
499VPolylineTool::commandExecuted()
500{
501 cancel();
502}
503
504#include "vpolylinetool.moc"
void addCommand(VCommand *cmd, bool repaint=false)
insert a command into the undo/redo-history:
@ CrossHair
unthemed crosshair cursor
Definition vcursor.h:38
static TQCursor createCursor(CursorType type)
Creates a predefined cursor of the specified type.
Definition vcursor.cpp:75
virtual void setState(const VState state)
Sets the state to a specified new state.
Definition vobject.h:163
@ edit
visible, active and is currently manipulated by a tool
Definition vobject.h:62
A composite path consists of one or many subpaths.
Definition vcomposite.h:48
virtual void draw(VPainter *painter, const KoRect *rect=0L) const
Draw the object to a painting device.
void close()
Closes the current subpath.
virtual const KoRect & boundingBox() const
Calculates the tightest bounding box around the object.
void initializePath(VPath &path)
Initializes the specified path with the actual bezier points.
virtual void mouseDragCtrlReleased()
"Ctrl" key released while mouse drag.
virtual TQString contextHelp()
The context help of the tool.
virtual void activate()
Called during the tool activation.
virtual void mouseDrag()
Mouse drag.
KoPoint m_lastVectorEnd
The end of the last drawn vector.
virtual void mouseDragRelease()
Mouse button release.
virtual void cancelStep()
Cancels the last tool step (if any).
virtual void deactivate()
Deactivates the tool.
virtual void mouseButtonRelease()
Left mouse button release.
virtual void setup(TDEActionCollection *collection)
Called after tool creation.
void drawBezierVector(KoPoint &start, KoPoint &end)
Helper method: draws a bezier vector.
virtual void mouseButtonPress()
Left mouse button press.
virtual void mouseDragShiftPressed()
Mouse drag with "Shift" key pressed at the same time.
virtual void rightMouseButtonRelease()
Right mouse button release.
TQPtrList< KoPoint > m_bezierPoints
The list of this polyline points.
void createObject()
Creates the polyline from the bezier points.
virtual void accept()
Terminates the current tool drawing (if any).
virtual void mouseDragShiftReleased()
"Shift" key released while mouse drag.
virtual void cancel()
Cancels all tool operations.
virtual void mouseMove()
Mouse move.
virtual void mouseDragCtrlPressed()
Mouse drag with "Ctrl" key pressed at the same time.
bool m_close
Indicates if the polyline is to close.
virtual void mouseButtonDblClick()
Mouse button double click.
void draw()
Helper method: draws the polyline.
KoPoint m_lastVectorStart
The start of the last drawn vector.
Manages stroke properties.
Definition vstroke.h:49
The base class for all karbon tools.
Definition vtool.h:52
const KoPoint & last() const
The last mouse coordinate.
Definition vtool.h:285
bool ctrlPressed() const
The status of the ctrl key.
Definition vtool.h:299
TDERadioAction * action() const
Returns the tool's associated action object.
Definition vtool.h:151
virtual void activate()
Called during the tool activation.
Definition vtool.cpp:252
bool shiftPressed() const
The status of the shift key.
Definition vtool.h:292
TDERadioAction * m_action
The tool's action object.
Definition vtool.h:309
KarbonView * view() const
Returns the connected karbon part.
Definition vtool.cpp:66