whirlpinchplugin.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2002, 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#include <core/vselection.h>
21#include "whirlpinchplugin.h"
22#include <karbon_view.h>
23#include <karbon_part.h>
24#include <kgenericfactory.h>
25#include <core/vdocument.h>
26#include <core/vcomposite.h>
27#include <core/vpath.h>
28#include <core/vsegment.h>
29#include <core/vglobal.h>
30
31#include <kdebug.h>
32
33#include <tqgroupbox.h>
34#include <tqlabel.h>
35
36#include <knuminput.h>
37
38typedef KGenericFactory<WhirlPinchPlugin, KarbonView> WhirlPinchPluginFactory;
39K_EXPORT_COMPONENT_FACTORY( karbon_whirlpinchplugin, WhirlPinchPluginFactory( "karbonwhirlpinchplugin" ) )
40
41WhirlPinchPlugin::WhirlPinchPlugin( KarbonView *parent, const char* name, const TQStringList & ) : Plugin( parent, name )
42{
43 new TDEAction(
44 i18n( "&Whirl/Pinch..." ), "14_whirl", 0, this,
45 TQ_SLOT( slotWhirlPinch() ), actionCollection(), "path_whirlpinch" );
46
47 m_whirlPinchDlg = new VWhirlPinchDlg();
48 m_whirlPinchDlg->setAngle( 20.0 );
49 m_whirlPinchDlg->setPinch( 0.0 );
50 m_whirlPinchDlg->setRadius( 100.0 );
51}
52
53void
54WhirlPinchPlugin::slotWhirlPinch()
55{
56 KarbonPart *part = ((KarbonView *)parent())->part();
57 if( part && m_whirlPinchDlg->exec() )
58 part->addCommand( new VWhirlPinchCmd( &part->document(), m_whirlPinchDlg->angle(), m_whirlPinchDlg->pinch(), m_whirlPinchDlg->radius() ), true );
59}
60
61VWhirlPinchDlg::VWhirlPinchDlg( TQWidget* parent, const char* name )
62 : KDialogBase( parent, name, true, i18n( "Whirl Pinch" ), Ok | Cancel )
63{
64 // add input fields:
65 TQGroupBox* group = new TQGroupBox( 2, TQt::Horizontal, i18n( "Properties" ), this );
66
67 new TQLabel( i18n( "Angle:" ), group );
68 m_angle = new KDoubleNumInput( group );
69 new TQLabel( i18n( "Pinch:" ), group );
70 m_pinch = new KDoubleNumInput( group );
71 new TQLabel( i18n( "Radius:" ), group );
72 m_radius = new KDoubleNumInput( group );
73 group->setMinimumWidth( 300 );
74
75 // signals and slots:
76 connect( this, TQ_SIGNAL( okClicked() ), this, TQ_SLOT( accept() ) );
77 connect( this, TQ_SIGNAL( cancelClicked() ), this, TQ_SLOT( reject() ) );
78
79 setMainWidget( group );
80 setFixedSize( baseSize() );
81}
82
83double
84VWhirlPinchDlg::angle() const
85{
86 return m_angle->value();
87}
88
89double
90VWhirlPinchDlg::pinch() const
91{
92 return m_pinch->value();
93}
94
95double
96VWhirlPinchDlg::radius() const
97{
98 return m_radius->value();
99}
100
101void
102VWhirlPinchDlg::setAngle( double value )
103{
104 m_angle->setValue( value);
105}
106
107void
108VWhirlPinchDlg::setPinch( double value )
109{
110 m_pinch->setValue(value);
111}
112
113void
114VWhirlPinchDlg::setRadius( double value )
115{
116 m_radius->setValue( value);
117}
118
119VWhirlPinchCmd::VWhirlPinchCmd( VDocument* doc,
120 double angle, double pinch, double radius )
121 : VReplacingCmd( doc, i18n( "Whirl Pinch" ) )
122{
123 m_angle = angle;
124 m_pinch = pinch;
125 m_radius = radius;
126 m_center = document()->selection()->boundingBox().center();
127}
128
129VWhirlPinchCmd::~VWhirlPinchCmd()
130{
131}
132
133void
134VWhirlPinchCmd::visitVPath( VPath& composite )
135{
136 // first subdivide:
137// VInsertKnots insertKnots( 2 );
138// insertKnots.visit( composite );
139
140 VVisitor::visitVPath( composite );
141}
142
143void
144VWhirlPinchCmd::visitVSubpath( VSubpath& path )
145{
146 TQWMatrix m;
147 KoPoint delta;
148 double dist;
149
150 path.first();
151
152 VSegment *curr = path.current();
153
154 while( curr )
155 {
156// TODO: selfmade this function since it's gone:
157// path.current()->convertToCurve();
158
159 // Apply effect to each segment node.
160 for( int i = 0; i < curr->degree(); ++i )
161 {
162 // calculate distance from whirl center to actual point
163 delta = curr->point( i ) - m_center;
164 dist = sqrt( delta.x() * delta.x() + delta.y() * delta.y() );
165
166 // check if point is inside the whirl radius
167 if( dist < m_radius )
168 {
169 m.reset();
170
171 // normalize distance to whirl radius
172 dist /= m_radius;
173
174 double scale = pow( sin( VGlobal::pi_2 * dist ), -m_pinch );
175 // pinch:
176 m.translate( m_center.x(), m_center.y() );
177 m.scale( scale, scale );
178
179 // whirl:
180 m.rotate( m_angle * ( 1.0 - dist ) * ( 1.0 - dist ) );
181 m.translate( -m_center.x(), -m_center.y() );
182
183 path.current()->setPoint( i, curr->point( i ).transform( m ) );
184 }
185
186 }
187
188 if( !success() )
189 setSuccess();
190
191 curr = path.next();
192 }
193
194 // Invalidate bounding box once.
196}
197
198#include "whirlpinchplugin.moc"
199
Keeps track of visual per document properties.
Definition karbon_part.h:46
void addCommand(VCommand *cmd, bool repaint=false)
insert a command into the undo/redo-history:
All non-visual, static doc info is in here.
Definition vdocument.h:53
void invalidateBoundingBox()
Invalidates the bounding box, so it has to be recalculated.
Definition vobject.h:127
A composite path consists of one or many subpaths.
Definition vcomposite.h:48
VReplacingCmd is a generic command.
A class representing lines and beziers.
Definition vsegment.h:43
void setPoint(int i, const KoPoint &p)
Sets the segment's point with index 0 <= i < degree() to "p".
Definition vsegment.h:143
unsigned short degree() const
Returns the segment's degree, which is identical to the number of nodes.
Definition vsegment.h:77
const KoPoint & point(int i) const
Returns the segment's point with index 0 <= i < degree().
Definition vsegment.h:115
VSubpath provides a sophisticated list of VSegment.
Definition vpath.h:43
virtual void visitVPath(VPath &composite)
Visit method for a VPath.
Definition vvisitor.cpp:74