25#include <tqgroupbox.h>
26#include <tqcombobox.h>
27#include <tqcheckbox.h>
29#include <tqwidgetstack.h>
35#include <karbon_part.h>
36#include <karbon_view.h>
38#include <core/vcolor.h>
39#include <core/vcomposite.h>
40#include <core/vfill.h>
41#include <core/vstroke.h>
42#include <core/vglobal.h>
43#include <core/vselection.h>
44#include <core/vcursor.h>
45#include <render/vpainter.h>
46#include <render/vpainterfactory.h>
47#include "vpenciltool.h"
48#include <commands/vshapecmd.h>
52#include "vpenciltool.moc"
54VPencilOptionsWidget::VPencilOptionsWidget( KarbonView*view, TQWidget* parent,
const char* name )
55 : KDialogBase( parent, name, true, i18n(
"Pencil Settings" ), Ok | Cancel ), m_view( view )
57 TQVBox *vbox =
new TQVBox(
this );
59 m_combo =
new TQComboBox( vbox );
61 m_combo->insertItem( i18n(
"Raw" ) );
62 m_combo->insertItem( i18n(
"Curve" ) );
63 m_combo->insertItem( i18n(
"Straight" ) );
65 m_widgetStack =
new TQWidgetStack( vbox );
67 TQGroupBox *group1 =
new TQGroupBox( 2, TQt::Horizontal, i18n(
"Properties" ), m_widgetStack );
68 m_widgetStack->addWidget( group1, 1 );
69 m_optimizeRaw =
new TQCheckBox( i18n(
"Optimize" ), group1 );
71 group1->setInsideMargin( 4 );
72 group1->setInsideSpacing( 2 );
74 TQGroupBox *group2 =
new TQGroupBox( 2, TQt::Horizontal, i18n(
"Properties" ), m_widgetStack );
75 m_widgetStack->addWidget( group2, 2 );
77 TQVBox *vbox2 =
new TQVBox( group2 );
79 m_optimizeCurve =
new TQCheckBox( i18n(
"Optimize" ), vbox2 );
80 m_fittingError =
new KDoubleNumInput( 0.0, 400.0, 4.00, 0.50, 3, vbox2 );
81 m_fittingError->setLabel( i18n(
"Exactness:" ) );
83 group2->setInsideMargin( 4 );
84 group2->setInsideSpacing( 2 );
86 TQGroupBox *group3 =
new TQGroupBox( 2, TQt::Horizontal, i18n(
"Properties" ), m_widgetStack );
87 m_widgetStack->addWidget( group3, 3 );
89 m_combineAngle =
new KDoubleNumInput( 0.0, 360.0, 0.10, 0.50, 3, group3 );
90 m_combineAngle->setSuffix(
" deg" );
91 m_combineAngle->setLabel( i18n(
"Combine angle:" ) );
93 group3->setInsideMargin( 4 );
94 group3->setInsideSpacing( 2 );
96 connect( m_combo, TQ_SIGNAL( activated(
int ) ),
this, TQ_SLOT( selectMode() ) );
99 m_mode = VPencilTool::CURVE;
102 m_optimizeCurve->setChecked(
true );
103 m_optimizeRaw->setChecked(
true );
105 setMainWidget( vbox );
108float VPencilOptionsWidget::combineAngle()
110 return m_combineAngle->value();
113bool VPencilOptionsWidget::optimize()
115 return ( m_optimizeRaw->isChecked() || m_optimizeCurve->isChecked() );
118float VPencilOptionsWidget::fittingError()
120 return m_fittingError->value();
123void VPencilOptionsWidget::selectMode()
125 m_widgetStack->raiseWidget( m_combo->currentItem() + 1 );
127 switch( m_combo->currentItem() )
129 case 0: m_mode = VPencilTool::RAW;
break;
130 case 1: m_mode = VPencilTool::CURVE;
break;
131 case 2: m_mode = VPencilTool::STRAIGHT;
break;
135int VPencilOptionsWidget::currentMode(){
141VPencilTool::VPencilTool( KarbonView *view )
142 :
VTool( view,
"tool_pencil" )
144 m_Points.setAutoDelete(
true );
145 m_optionWidget =
new VPencilOptionsWidget( view );
146 registerTool(
this );
149 m_combineAngle = 3.0f;
153VPencilTool::~VPencilTool()
161 TQString s = i18n(
"<qt><b>Pencil tool:</b><br>" );
162 s += i18n(
"- <i>Click</i> to begin drawing, release when you have finished.");
163 s += i18n(
"- Press <i>Enter</i> or <i>double click</i> to end the polyline.</qt>" );
172 view()->statusMessage()->setText( i18n(
"Pencil Tool" ) );
173 view()->setCursor( *m_cursor );
174 view()->part()->document().selection()->showHandle(
false );
188 TQPtrList<KoPoint> complete;
189 TQPtrList<KoPoint> *points = &
m_Points;
193 if( m_optimize ||
m_mode == STRAIGHT )
195 complete.setAutoDelete(
true );
201 cangle = m_combineAngle;
205 #define ANGLE(P0,P1)\
206 atan((P1)->y()-(P0)->y())/((P1)->x()-(P0)->x())*(180/M_PI)
209 complete.append(
m_Points.first() );
213 float langle = ANGLE( complete.at( 0 ), complete.at( 1 ) );
215 KoPoint *nextp = NULL;
216 while( ( nextp =
m_Points.next() ) )
218 float angle = ANGLE( complete.last(), nextp );
219 if( TQABS( angle - langle ) < cangle )
220 complete.removeLast();
221 complete.append(nextp);
234 line = bezierFit( *points, m_optionWidget->fittingError() );
240 line =
new VPath( 0L );
241 KoPoint* p1 = (*points).first();
247 while( ( pnext = (*points).next() ) )
249 line->lineTo( *pnext );
262 VShapeCmd* cmd =
new VShapeCmd(
263 &
view()->part()->document(),
268 view()->part()->addCommand( cmd,
true );
275 VPainter* painter =
view()->painterFactory()->editpainter();
276 painter->setRasterOp( TQt::NotROP );
278 m_mode = m_optionWidget->currentMode();
279 m_optimize = m_optionWidget->optimize();
280 m_combineAngle = m_optionWidget->combineAngle();
289 line.lineTo( *pnext );
395 return m_optionWidget->exec() == TQDialog::Accepted;
401 m_action =
static_cast<TDERadioAction *
>(collection ->
action( name() ) );
405 m_action =
new TDERadioAction( i18n(
"Pencil Tool" ),
"14_pencil", TQt::SHIFT+TQt::Key_P,
this, TQ_SLOT(
activate() ), collection, name() );
406 m_action->setToolTip( i18n(
"Pencil" ) );
407 m_action->setExclusiveGroup(
"freehand" );
@ CrossHair
unthemed crosshair cursor
static TQCursor createCursor(CursorType type)
Creates a predefined cursor of the specified type.
virtual void setState(const VState state)
Sets the state to a specified new state.
@ edit
visible, active and is currently manipulated by a tool
A composite path consists of one or many subpaths.
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.