25#include <karbon_part.h>
26#include <karbon_view.h>
27#include <karbon_factory.h>
28#include <render/vpainter.h>
29#include <render/vpainterfactory.h>
30#include "vgradienttool.h"
31#include <widgets/vgradienttabwidget.h>
32#include <commands/vfillcmd.h>
33#include <commands/vstrokecmd.h>
34#include <core/vstroke.h>
35#include <core/vselection.h>
36#include <widgets/vstrokefillpreview.h>
40VGradientTool::VGradientOptionsWidget::VGradientOptionsWidget( VGradient& gradient )
41 : KDialogBase( 0L,
"", true, i18n(
"Edit Gradient" ), Ok | Cancel )
43 m_gradientWidget =
new VGradientTabWidget( gradient, KarbonFactory::rServer(),
this );
44 setMainWidget( m_gradientWidget );
45 setFixedSize( baseSize() );
48VGradientTool::VGradientTool( KarbonView *view )
49 :
VTool( view,
"gradienttool" ), m_state( normal ), m_handleSize( 3 ), m_active( false )
51 setName(
"tool_gradient" );
52 m_optionsWidget =
new VGradientOptionsWidget( m_gradient );
56VGradientTool::~VGradientTool()
58 delete m_optionsWidget;
66 view()->statusMessage()->setText( i18n(
"Gradient" ) );
67 view()->setCursor( TQCursor( TQt::crossCursor ) );
75 VStrokeFillPreview* preview =
view()->strokeFillPreview();
78 connect( preview, TQ_SIGNAL( fillSelected() ),
this, TQ_SLOT( targetChanged() ) );
79 connect( preview, TQ_SIGNAL( strokeSelected() ),
this, TQ_SLOT( targetChanged() ) );
81 view()->repaintAll(
view()->part()->document().selection()->boundingBox() );
94 VStrokeFillPreview* preview =
view()->strokeFillPreview();
97 disconnect( preview, TQ_SIGNAL( fillSelected() ),
this, TQ_SLOT( targetChanged() ) );
98 disconnect( preview, TQ_SIGNAL( strokeSelected() ),
this, TQ_SLOT( targetChanged() ) );
100 view()->repaintAll(
view()->part()->document().selection()->boundingBox() );
107 return i18n(
"Gradient Tool" );
113 TQString s = i18n(
"<qt><b>Gradient tool:</b><br>" );
114 s += i18n(
"<i>Click and drag</i> to choose the gradient vector.<br>" );
115 s += i18n(
"<i>Click and drag</i> a gradient vector handle to change the gradient vector.<br>" );
116 s += i18n(
"<i>Shift click and drag</i> to move the radial gradient focal point.<br>" );
117 s += i18n(
"<i>Press i or Shift+i</i> to decrease or increase the handle size.<br>" );
118 s += i18n(
"<br><b>Gradient editing:</b><br>" );
119 s += i18n(
"<i>Click and drag</i> to move points.<br>" );
120 s += i18n(
"<i>Double click</i> on a color point to edit it.<br>" );
121 s += i18n(
"<i>Right click</i> on a color point to remove it.</qt>" );
126VGradientTool::getGradient( VGradient &gradient )
132 VStrokeFillPreview *preview =
view()->strokeFillPreview();
133 bool strokeSelected = ( preview && preview->strokeIsSelected() );
135 VSelection* selection =
view()->part()->document().
selection();
136 if( selection->
objects().count() != 1 )
139 VObject *obj = selection->
objects().getFirst();
142 gradient = obj->
stroke()->gradient();
144 gradient = obj->
fill()->gradient();
152VGradientTool::getOpacity(
double &opacity )
158 VStrokeFillPreview *preview =
view()->strokeFillPreview();
159 bool strokeSelected = ( preview && preview->strokeIsSelected() );
161 VSelection* selection =
view()->part()->document().
selection();
162 if( selection->
objects().count() != 1 )
165 VObject *obj = selection->
objects().getFirst();
177VGradientTool::draw( VPainter* painter )
182 if( m_state != normal )
185 if( ! getGradient( m_gradient ) )
188 KoPoint s = m_gradient.origin();
189 KoPoint e = m_gradient.vector();
190 KoPoint f = m_gradient.focalPoint();
193 m_origin = KoRect( s.x()-m_handleSize, s.y()-m_handleSize, 2*m_handleSize, 2*m_handleSize );
194 m_vector = KoRect( e.x()-m_handleSize, e.y()-m_handleSize, 2*m_handleSize, 2*m_handleSize );
195 m_center = KoRect( f.x()-m_handleSize, f.y()-m_handleSize, 2*m_handleSize, 2*m_handleSize );
197 painter->setPen( TQt::blue.light() );
198 painter->setBrush( TQt::blue.light() );
199 painter->setRasterOp( TQt::XorROP );
203 painter->moveTo( s );
204 painter->lineTo( e );
205 painter->strokePath();
207 if( m_gradient.type() == VGradient::radial )
210 double size = (double)m_handleSize /
view()->zoom();
211 KoPoint focal = m_center.center();
212 KoRect cross = KoRect( focal.x()-3*size, focal.y()-3*size, 6*size, 6*size );
214 painter->moveTo( cross.topLeft() );
215 painter->lineTo( cross.bottomRight() );
216 painter->strokePath();
218 painter->moveTo( cross.bottomLeft() );
219 painter->lineTo( cross.topRight() );
220 painter->strokePath();
223 painter->drawNode( m_origin.center(), m_handleSize );
224 painter->drawNode( m_vector.center(), m_handleSize );
230 if( !
view() ||
view()->part()->document().selection()->objects().count() == 0 )
233 VPainter *painter =
view()->painterFactory()->editpainter();
234 painter->setRasterOp( TQt::NotROP );
236 painter->setPen( TQt::DotLine );
240 if( m_state == moveOrigin || m_state == moveVector )
242 painter->moveTo( m_fixed );
243 painter->lineTo( m_current );
245 painter->drawNode( m_fixed, m_handleSize );
246 painter->drawNode( m_current, m_handleSize );
248 else if( m_state == createNew )
250 painter->moveTo(
first() );
251 painter->lineTo( m_current );
253 painter->drawNode(
first(), m_handleSize );
254 painter->drawNode( m_current, m_handleSize );
256 else if( m_state == moveCenter )
259 double size = (double)m_handleSize /
view()->zoom();
260 KoRect cross = KoRect( m_current.x()-3*size, m_current.y()-3*size, 6*size, 6*size );
261 painter->moveTo( cross.topLeft() );
262 painter->lineTo( cross.bottomRight() );
263 painter->strokePath();
265 painter->moveTo( cross.bottomLeft() );
266 painter->lineTo( cross.topRight() );
269 painter->strokePath();
275 if( m_state == normal )
294 m_state = moveCenter;
296 else if( m_origin.contains( m_current ) )
298 m_state = moveOrigin;
299 m_fixed = m_vector.center();
301 else if( m_vector.contains( m_current ) )
303 m_state = moveVector;
304 m_fixed = m_origin.center();
315 if( !
view() ||
view()->part()->document().selection()->objects().count() == 0 )
319 VGradient oldGradient = m_gradient;
321 bool strokeSelected =
false;
324 VStrokeFillPreview* preview =
view()->strokeFillPreview();
325 if( preview && preview->strokeIsSelected() )
326 strokeSelected =
true;
330 m_optionsWidget->gradientWidget()->setGradient( m_gradient );
333 m_optionsWidget->gradientWidget()->setTarget( VGradientTabWidget::STROKE );
334 m_optionsWidget->gradientWidget()->setOpacity( 1.0 );
338 m_optionsWidget->gradientWidget()->setTarget( VGradientTabWidget::FILL );
340 if( getOpacity( opacity ) )
341 m_optionsWidget->gradientWidget()->setOpacity( opacity );
347 m_gradient = m_optionsWidget->gradientWidget()->gradient();
350 strokeSelected = ( m_optionsWidget->gradientWidget()->target() == VGradientTabWidget::STROKE );
354 if(
view()->part()->document().selection()->objects().count() == 1 )
362 switch( m_gradient.type() )
364 case VGradient::linear:
365 oldGradient.setOrigin( bbox.bottomLeft() + 0.5*(bbox.bottomRight()-bbox.bottomLeft()) );
366 oldGradient.setVector( bbox.topLeft() + 0.5*(bbox.topRight()-bbox.topLeft()) );
367 oldGradient.setFocalPoint( bbox.center() );
369 case VGradient::radial:
370 oldGradient.setOrigin( bbox.center() );
371 oldGradient.setVector( bbox.topLeft() + 0.5*(bbox.topRight()-bbox.topLeft()) );
372 oldGradient.setFocalPoint( bbox.center() );
374 case VGradient::conic:
375 oldGradient.setOrigin( bbox.center() );
376 oldGradient.setVector( bbox.topLeft() + 0.5*(bbox.topRight()-bbox.topLeft()) );
377 oldGradient.setFocalPoint( bbox.center() );
384 if( oldGradient.origin() == oldGradient.vector() )
385 oldGradient.vector().rx()+=1;
388 m_gradient.setVector( oldGradient.vector() );
389 m_gradient.setOrigin( oldGradient.origin() );
390 m_gradient.setFocalPoint( oldGradient.focalPoint() );
392 if( ! strokeSelected )
395 fill.gradient() = m_gradient;
397 VColor c = fill.color();
398 c.
setOpacity( m_optionsWidget->gradientWidget()->opacity() );
399 fill.setColor( c,
false );
401 new VFillCmd( &
view()->part()->document(), fill,
"14_gradient" ),
true );
406 new VStrokeCmd( &
view()->part()->document(), &m_gradient ),
true );
413 if( !
view() || m_state == normal )
416 if(
view()->part()->document().selection()->objects().count() == 0 )
422 if( m_state == moveOrigin )
423 m_gradient.setOrigin(
last() );
424 else if( m_state == moveVector )
425 m_gradient.setVector(
last() );
426 else if( m_state == moveCenter )
427 m_gradient.setFocalPoint(
last() );
428 else if( m_state == createNew )
430 m_gradient.setOrigin(
first() );
431 m_gradient.setFocalPoint(
first() );
432 m_gradient.setVector(
last() );
437 VStrokeFillPreview* preview =
view()->strokeFillPreview();
441 if( ! preview->strokeIsSelected() )
444 fill.gradient() = m_gradient;
446 VColor c = fill.color();
447 c.
setOpacity( m_optionsWidget->gradientWidget()->opacity() );
448 fill.setColor( c,
false );
450 new VFillCmd( &
view()->part()->document(), fill,
"14_gradient" ),
true );
454 new VStrokeCmd( &
view()->part()->document(), &m_gradient ),
true );
469 return m_optionsWidget->exec() == TQDialog::Accepted;
473VGradientTool::setup( TDEActionCollection *collection )
475 m_action =
static_cast<TDERadioAction *
>(collection ->
action( name() ) );
479 m_action =
new TDERadioAction( i18n(
"Gradient Tool" ),
"14_gradient", TQt::Key_G,
this, TQ_SLOT(
activate() ), collection, name() );
480 m_action->setToolTip( i18n(
"Gradient" ) );
481 m_action->setExclusiveGroup(
"misc" );
489 if( !
view() )
return;
492 if( m_origin.contains(
last() ) || m_vector.contains(
last() ) || m_center.contains(
last() ) )
493 view()->setCursor( TQCursor( TQt::SizeAllCursor ) );
495 view()->setCursor( TQCursor( TQt::arrowCursor ) );
499VGradientTool::keyReleased( TQt::Key key )
507 else if( m_handleSize > 3 )
510 default:
return false;
514 view()->repaintAll(
view()->part()->document().selection()->boundingBox() );
520VGradientTool::targetChanged()
523 view()->repaintAll(
view()->part()->document().selection()->boundingBox() );
526#include "vgradienttool.moc"
void addCommand(VCommand *cmd, bool repaint=false)
insert a command into the undo/redo-history:
void setOpacity(float opacity)
Sets the color opacity.
float opacity() const
Returns the color opacity.
VSelection * selection() const
Returns a pointer to the selection.
virtual const KoRect & boundingBox() const
Calculates the tightest bounding box around the object.
virtual VFill * fill() const
Gets the object's actual fill.
virtual VStroke * stroke() const
Gets the object's actual stroke.
const VObjectList & objects() const
Read only access to the selected objects.
void showHandle(bool handle=true)
Toggle selection handles on/off.