moved kdeaccessibility kdeaddons kdeadmin kdeartwork kdebindings kdeedu kdegames...
[kdeedu.git] / kig / objects / point_type.cc
blobec2de11ac40ae5210ccba5c1ebd4119d50f17fd0
1 // Copyright (C) 2002 Dominique Devriese <devriese@kde.org>
3 // This program is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU General Public License
5 // as published by the Free Software Foundation; either version 2
6 // of the License, or (at your option) any later version.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
16 // 02111-1307, USA.
18 #include "point_type.h"
20 #include "point_imp.h"
21 #include "curve_imp.h"
22 #include "line_imp.h"
23 #include "other_imp.h"
24 #include "bogus_imp.h"
26 #include "../modes/moving.h"
27 #include "../misc/coordinate_system.h"
28 #include "../misc/common.h"
29 #include "../misc/calcpaths.h"
30 #include "../kig/kig_part.h"
31 #include "../kig/kig_document.h"
32 #include "../kig/kig_view.h"
33 #include "../kig/kig_commands.h"
35 #include <klocale.h>
37 static const ArgsParser::spec argsspecFixedPoint[] =
39 { DoubleImp::stype(), "x", "SHOULD NOT BE SEEN", false },
40 { DoubleImp::stype(), "y", "SHOULD NOT BE SEEN", false }
43 KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( FixedPointType )
45 FixedPointType::FixedPointType()
46 : ArgsParserObjectType( "FixedPoint", argsspecFixedPoint, 2 )
50 FixedPointType::~FixedPointType()
54 ObjectImp* FixedPointType::calc( const Args& parents, const KigDocument& ) const
56 if ( ! margsparser.checkArgs( parents ) ) return new InvalidImp;
58 double a = static_cast<const DoubleImp*>( parents[0] )->data();
59 double b = static_cast<const DoubleImp*>( parents[1] )->data();
61 return new PointImp( Coordinate( a, b ) );
64 static const ArgsParser::spec argsspecRelativePoint[] =
66 { DoubleImp::stype(), "relative-x", "SHOULD NOT BE SEEN", false },
67 { DoubleImp::stype(), "relative-y", "SHOULD NOT BE SEEN", false },
68 { ObjectImp::stype(), "object", "SHOULD NOT BE SEEN", false }
71 KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( RelativePointType )
73 RelativePointType::RelativePointType()
74 : ArgsParserObjectType( "RelativePoint", argsspecRelativePoint, 3 )
78 RelativePointType::~RelativePointType()
82 ObjectImp* RelativePointType::calc( const Args& parents, const KigDocument& ) const
84 if ( ! margsparser.checkArgs( parents ) ) return new InvalidImp;
85 if ( ! parents[2]->attachPoint().valid() ) return new InvalidImp;
87 Coordinate reference = static_cast<const ObjectImp*>( parents[2] )->attachPoint();
88 double a = static_cast<const DoubleImp*>( parents[0] )->data();
89 double b = static_cast<const DoubleImp*>( parents[1] )->data();
91 return new PointImp( reference + Coordinate( a, b ) );
94 KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( CursorPointType )
96 CursorPointType::CursorPointType()
97 : ObjectType( "CursorPoint" )
101 CursorPointType::~CursorPointType()
105 const CursorPointType* CursorPointType::instance()
107 static const CursorPointType t;
108 return &t;
111 ObjectImp* CursorPointType::calc( const Args& parents, const KigDocument& ) const
113 assert ( parents[0]->inherits( DoubleImp::stype() ) );
114 assert ( parents[1]->inherits( DoubleImp::stype() ) );
115 double a = static_cast<const DoubleImp*>( parents[0] )->data();
116 double b = static_cast<const DoubleImp*>( parents[1] )->data();
118 return new BogusPointImp( Coordinate( a, b ) );
121 const ObjectImpType* CursorPointType::resultId() const
123 return BogusPointImp::stype();
126 ObjectImp* ConstrainedPointType::calc( const Args& parents, const KigDocument& doc ) const
128 if ( ! margsparser.checkArgs( parents ) ) return new InvalidImp;
130 double param = static_cast<const DoubleImp*>( parents[0] )->data();
131 const Coordinate nc = static_cast<const CurveImp*>( parents[1] )->getPoint( param, doc );
132 if ( nc.valid() ) return new PointImp( nc );
133 else return new InvalidImp;
136 const ArgsParser::spec argsspecConstrainedPoint[] =
138 { DoubleImp::stype(), "parameter", "SHOULD NOT BE SEEN", false },
139 { CurveImp::stype(), "Constrain the point to this curve", "SHOULD NOT BE SEEN", true }
142 KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ConstrainedPointType )
144 ConstrainedPointType::ConstrainedPointType()
145 : ArgsParserObjectType( "ConstrainedPoint", argsspecConstrainedPoint, 2 )
149 ConstrainedPointType::~ConstrainedPointType()
153 void FixedPointType::move( ObjectTypeCalcer& ourobj, const Coordinate& to,
154 const KigDocument& ) const
156 // fetch the old coord..;
157 std::vector<ObjectCalcer*> pa = ourobj.parents();
158 assert( margsparser.checkArgs( pa ) );
159 assert( dynamic_cast<ObjectConstCalcer*>( pa.front() ) );
160 assert( dynamic_cast<ObjectConstCalcer*>( pa.back() ) );
162 ObjectConstCalcer* ox = static_cast<ObjectConstCalcer*>( pa.front() );
163 ObjectConstCalcer* oy = static_cast<ObjectConstCalcer*>( pa.back() );
165 ox->setImp( new DoubleImp( to.x ) );
166 oy->setImp( new DoubleImp( to.y ) );
169 void RelativePointType::move( ObjectTypeCalcer& ourobj, const Coordinate& to,
170 const KigDocument& ) const
172 // fetch the attach point..;
173 // this routine is tightly paired with what moveReferencePoint returns!
174 // right now moveReferencePoint always returns the origin
175 std::vector<ObjectCalcer*> pa = ourobj.parents();
176 assert( margsparser.checkArgs( pa ) );
177 assert( dynamic_cast<ObjectConstCalcer*>( pa[0] ) );
178 assert( dynamic_cast<ObjectConstCalcer*>( pa[1] ) );
180 ObjectConstCalcer* ox = static_cast<ObjectConstCalcer*>( pa[0] );
181 ObjectConstCalcer* oy = static_cast<ObjectConstCalcer*>( pa[1] );
182 ObjectCalcer* ob = static_cast<ObjectCalcer*>( pa[2] );
184 Coordinate attach = ob->imp()->attachPoint();
185 ox->setImp( new DoubleImp( to.x - attach.x ) );
186 oy->setImp( new DoubleImp( to.y - attach.y ) );
189 void CursorPointType::move( ObjectTypeCalcer& ourobj, const Coordinate& to,
190 const KigDocument& ) const
192 // fetch the old coord..;
194 std::vector<ObjectCalcer*> pa = ourobj.parents();
195 assert( pa.size() == 2 );
196 assert( dynamic_cast<ObjectConstCalcer*>( pa.front() ) );
197 assert( dynamic_cast<ObjectConstCalcer*>( pa.back() ) );
199 ObjectConstCalcer* ox = static_cast<ObjectConstCalcer*>( pa.front() );
200 ObjectConstCalcer* oy = static_cast<ObjectConstCalcer*>( pa.back() );
202 ox->setImp( new DoubleImp( to.x ) );
203 oy->setImp( new DoubleImp( to.y ) );
206 void ConstrainedPointType::move( ObjectTypeCalcer& ourobj, const Coordinate& to,
207 const KigDocument& d ) const
209 // fetch the CurveImp..
210 std::vector<ObjectCalcer*> parents = ourobj.parents();
211 assert( margsparser.checkArgs( parents ) );
213 assert( dynamic_cast<ObjectConstCalcer*>( parents[0] ) );
214 ObjectConstCalcer* paramo = static_cast<ObjectConstCalcer*>( parents[0] );
215 const CurveImp* ci = static_cast<const CurveImp*>( parents[1]->imp() );
217 // fetch the new param..
218 const double np = ci->getParam( to, d );
220 paramo->setImp( new DoubleImp( np ) );
223 bool ConstrainedPointType::canMove( const ObjectTypeCalcer& ) const
225 return true;
228 bool ConstrainedPointType::isFreelyTranslatable( const ObjectTypeCalcer& ) const
230 return false;
233 bool FixedPointType::canMove( const ObjectTypeCalcer& ) const
235 return true;
238 bool FixedPointType::isFreelyTranslatable( const ObjectTypeCalcer& ) const
240 return true;
243 bool RelativePointType::canMove( const ObjectTypeCalcer& ) const
245 return true;
248 bool RelativePointType::isFreelyTranslatable( const ObjectTypeCalcer& ) const
250 return true;
253 bool CursorPointType::canMove( const ObjectTypeCalcer& ) const
255 return true;
258 static const ArgsParser::spec argsspecMidPoint[] =
260 { PointImp::stype(), I18N_NOOP( "Construct the midpoint of this point and another point" ),
261 I18N_NOOP( "Select the first of the two points of which you want to construct the midpoint..." ), false },
262 { PointImp::stype(), I18N_NOOP( "Construct the midpoint of this point and another point" ),
263 I18N_NOOP( "Select the other of the two points of which you want to construct the midpoint..." ), false }
266 KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( MidPointType )
268 MidPointType::MidPointType()
269 : ObjectABType( "MidPoint", argsspecMidPoint, 2 )
273 MidPointType::~MidPointType()
277 const MidPointType* MidPointType::instance()
279 static const MidPointType t;
280 return &t;
283 ObjectImp* MidPointType::calc( const Coordinate& a, const Coordinate& b ) const
285 return new PointImp( ( a + b ) / 2 );
288 bool ConstrainedPointType::inherits( int type ) const
290 return type == ID_ConstrainedPointType;
293 const ConstrainedPointType* ConstrainedPointType::instance()
295 static const ConstrainedPointType t;
296 return &t;
299 bool FixedPointType::inherits( int type ) const
301 return type == ID_FixedPointType;
304 const FixedPointType* FixedPointType::instance()
306 static const FixedPointType t;
307 return &t;
310 const ObjectImpType* FixedPointType::resultId() const
312 return PointImp::stype();
315 const RelativePointType* RelativePointType::instance()
317 static const RelativePointType t;
318 return &t;
321 const ObjectImpType* RelativePointType::resultId() const
323 return PointImp::stype();
326 const ObjectImpType* ConstrainedPointType::resultId() const
328 return PointImp::stype();
331 const ObjectImpType* CursorPointType::impRequirement( const ObjectImp* o, const Args& ) const
333 if ( o->inherits( DoubleImp::stype() ) )
334 return DoubleImp::stype();
336 if ( o->inherits( PointImp::stype() ) )
337 return PointImp::stype();
339 return 0;
342 bool CursorPointType::isDefinedOnOrThrough( const ObjectImp*, const Args& ) const
344 return false;
347 std::vector<ObjectCalcer*> CursorPointType::sortArgs( const std::vector<ObjectCalcer*>& args ) const
349 return args;
352 Args CursorPointType::sortArgs( const Args& args ) const
354 return args;
357 const ObjectImpType* MidPointType::resultId() const
359 return PointImp::stype();
362 QStringList FixedPointType::specialActions() const
364 QStringList ret;
365 ret << i18n( "Set &Coordinate..." );
366 ret << i18n( "Redefine" );
367 return ret;
370 QStringList ConstrainedPointType::specialActions() const
372 QStringList ret;
373 ret << i18n( "Set &Parameter..." );
374 ret << i18n( "Redefine" );
375 return ret;
378 static void redefinePoint( ObjectHolder* o, KigPart& d, KigWidget& w )
380 PointRedefineMode pm( o, d, w );
381 d.runMode( &pm );
384 void FixedPointType::executeAction(
385 int i, ObjectHolder& oh, ObjectTypeCalcer& o,
386 KigPart& d, KigWidget& w, NormalMode& ) const
388 switch( i )
390 case 0:
392 bool ok = true;
393 assert ( o.imp()->inherits( PointImp::stype() ) );
394 Coordinate oldc = static_cast<const PointImp*>( o.imp() )->coordinate();
395 Coordinate c = d.document().coordinateSystem().getCoordFromUser(
396 i18n( "Set Coordinate" ), i18n( "Enter the new coordinate: " ),
397 d.document(), &w, &ok, &oldc );
398 if ( ! ok ) break;
400 MonitorDataObjects mon( getAllParents( &o ) );
401 o.move( c, d.document() );
402 KigCommand* kc = new KigCommand( d, PointImp::stype()->moveAStatement() );
403 mon.finish( kc );
405 d.history()->addCommand( kc );
406 break;
408 case 1:
409 redefinePoint( &oh, d, w );
410 break;
411 default:
412 assert( false );
416 void ConstrainedPointType::executeAction(
417 int i, ObjectHolder& oh, ObjectTypeCalcer& o, KigPart& d, KigWidget& w,
418 NormalMode& ) const
420 switch( i )
422 case 1:
423 redefinePoint( &oh, d, w );
424 break;
425 case 0:
427 std::vector<ObjectCalcer*> parents = o.parents();
428 assert( dynamic_cast<ObjectConstCalcer*>( parents[0] ) &&
429 parents[0]->imp()->inherits( DoubleImp::stype() ) );
431 ObjectConstCalcer* po = static_cast<ObjectConstCalcer*>( parents[0] );
432 double oldp = static_cast<const DoubleImp*>( po->imp() )->data();
434 bool ok = true;
435 double newp = getDoubleFromUser(
436 i18n( "Set Point Parameter" ), i18n( "Choose the new parameter: " ),
437 oldp, &w, &ok, 0, 1, 4 );
438 if ( ! ok ) return;
440 MonitorDataObjects mon( parents );
441 po->setImp( new DoubleImp( newp ) );
442 KigCommand* kc = new KigCommand( d, i18n( "Change Parameter of Constrained Point" ) );
443 mon.finish( kc );
444 d.history()->addCommand( kc );
445 break;
447 default:
448 assert( false );
452 const Coordinate FixedPointType::moveReferencePoint( const ObjectTypeCalcer& ourobj ) const
454 assert( ourobj.imp()->inherits( PointImp::stype() ) );
455 return static_cast<const PointImp*>( ourobj.imp() )->coordinate();
458 const Coordinate RelativePointType::moveReferencePoint( const ObjectTypeCalcer& ourobj ) const
460 assert( ourobj.imp()->inherits( PointImp::stype() ) );
461 // return static_cast<const PointImp*>( ourobj.imp() )->coordinate();
462 return Coordinate( 0., 0. );
465 const Coordinate ConstrainedPointType::moveReferencePoint( const ObjectTypeCalcer& ourobj ) const
467 assert( ourobj.imp()->inherits( PointImp::stype() ) );
468 return static_cast<const PointImp*>( ourobj.imp() )->coordinate();
471 std::vector<ObjectCalcer*> FixedPointType::movableParents( const ObjectTypeCalcer& ourobj ) const
473 return ourobj.parents();
476 std::vector<ObjectCalcer*> RelativePointType::movableParents( const ObjectTypeCalcer& ourobj ) const
478 std::vector<ObjectCalcer*> ret;
479 ret.push_back( ourobj.parents()[0] );
480 ret.push_back( ourobj.parents()[1] );
481 return ret;
484 std::vector<ObjectCalcer*> ConstrainedPointType::movableParents( const ObjectTypeCalcer& ourobj ) const
486 std::vector<ObjectCalcer*> ret;
487 ret.push_back( ourobj.parents()[0] );
488 return ret;
491 /* ----------------- Transport of measure ------------------------------ */
493 ObjectImp* MeasureTransportType::calc( const Args& parents, const KigDocument& doc ) const
495 double measure;
497 if ( parents.size() != 3 ) return new InvalidImp;
499 if ( parents[0]->inherits (SegmentImp::stype()) )
501 const SegmentImp* s = static_cast<const SegmentImp*>( parents[0] );
502 measure = s->length();
503 } else if ( parents[0]->inherits (ArcImp::stype()) )
505 const ArcImp* s = static_cast<const ArcImp*>( parents[0] );
506 measure = s->radius()*s->angle();
507 } else return new InvalidImp;
509 const Coordinate& p = static_cast<const PointImp*>( parents[2] )->coordinate();
510 if ( parents[1]->inherits (LineImp::stype()) )
512 const LineImp* c = static_cast<const LineImp*>( parents[1] );
514 if ( !c->containsPoint( p, doc ) )
515 return new InvalidImp;
517 const LineData line = c->data();
518 const Coordinate dir = line.dir()/line.length();
519 const Coordinate nc = p + measure*dir;
521 if ( nc.valid() ) return new PointImp( nc );
522 else return new InvalidImp;
523 } else if ( parents[1]->inherits (CircleImp::stype()) )
525 const CircleImp* c = static_cast<const CircleImp*>( parents[1] );
526 if ( !c->containsPoint( p, doc ) )
527 return new InvalidImp;
529 double param = c->getParam( p, doc );
530 measure /= 2*c->radius()*M_PI;
531 param += measure;
532 while (param > 1) param -= 1;
534 const Coordinate nc = c->getPoint( param, doc );
535 if ( nc.valid() ) return new PointImp( nc );
536 else return new InvalidImp;
539 return new InvalidImp;
542 // I18N_NOOP( "Select the segment/arc to transport on the circle/line..." ), false },
543 // I18N_NOOP( "Select the circle/line on which to transport a measure..." ), true },
544 // I18N_NOOP( "Select a point on the circle/line..." ), false }
546 KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( MeasureTransportType )
548 MeasureTransportType::MeasureTransportType()
549 : ObjectType( "TransportOfMeasure" )
553 MeasureTransportType::~MeasureTransportType()
557 const MeasureTransportType* MeasureTransportType::instance()
559 static const MeasureTransportType t;
560 return &t;
563 const ObjectImpType* MeasureTransportType::resultId() const
565 return PointImp::stype();
568 const ObjectImpType* MeasureTransportType::impRequirement( const ObjectImp* obj, const Args& ) const
570 if ( obj->inherits( PointImp::stype () ) )
571 return PointImp::stype ();
573 if ( obj->inherits( LineImp::stype () ) )
574 return LineImp::stype ();
576 if ( obj->inherits( CircleImp::stype () ) )
577 return CircleImp::stype ();
579 if ( obj->inherits( SegmentImp::stype () ) )
580 return SegmentImp::stype ();
582 if ( obj->inherits( ArcImp::stype () ) )
583 return ArcImp::stype ();
585 return 0;
588 bool MeasureTransportType::isDefinedOnOrThrough( const ObjectImp* o, const Args& ) const
590 if ( o->inherits( LineImp::stype() ) ) return true;
591 if ( o->inherits( CircleImp::stype() ) ) return true;
592 return false;
595 std::vector<ObjectCalcer*> MeasureTransportType::sortArgs( const std::vector<ObjectCalcer*>& args ) const
597 return args; /* should already be in correct order */
600 Args MeasureTransportType::sortArgs( const Args& args ) const
602 return args;
605 /* - transport of measure (old, for compatibility with prev. kig files) - */
607 ObjectImp* MeasureTransportTypeOld::calc( const Args& parents, const KigDocument& doc ) const
609 if ( ! margsparser.checkArgs( parents ) ) return new InvalidImp;
611 const CircleImp* c = static_cast<const CircleImp*>( parents[0] );
612 const Coordinate& p = static_cast<const PointImp*>( parents[1] )->coordinate();
614 if ( !c->containsPoint( p, doc ) )
615 return new InvalidImp;
617 const SegmentImp* s = static_cast<const SegmentImp*>( parents[2] );
618 double param = c->getParam( p, doc );
619 double measure = s->length();
620 measure /= 2*c->radius()*M_PI;
621 param += measure;
622 while (param > 1) param -= 1;
624 const Coordinate nc = c->getPoint( param, doc );
625 if ( nc.valid() ) return new PointImp( nc );
626 else return new InvalidImp;
629 static const ArgsParser::spec argsspecMeasureTransportOld[] =
631 { CircleImp::stype(), "Transport a measure on this circle",
632 I18N_NOOP( "Select the circle on which to transport a measure..." ), true },
633 { PointImp::stype(), "Start transport from this point of the circle",
634 I18N_NOOP( "Select a point on the circle..." ), false },
635 { SegmentImp::stype(), "Segment to transport",
636 I18N_NOOP( "Select the segment to transport on the circle..." ), false }
639 KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( MeasureTransportTypeOld )
641 MeasureTransportTypeOld::MeasureTransportTypeOld()
642 : ArgsParserObjectType( "MeasureTransport", argsspecMeasureTransportOld, 3 )
646 MeasureTransportTypeOld::~MeasureTransportTypeOld()
650 const MeasureTransportTypeOld* MeasureTransportTypeOld::instance()
652 static const MeasureTransportTypeOld t;
653 return &t;
656 const ObjectImpType* MeasureTransportTypeOld::resultId() const
658 return PointImp::stype();
661 /* ----------------- end transport of measure ------------------------- */