diff options
Diffstat (limited to 'kig/objects/point_type.cpp')
-rw-r--r-- | kig/objects/point_type.cpp | 665 |
1 files changed, 665 insertions, 0 deletions
diff --git a/kig/objects/point_type.cpp b/kig/objects/point_type.cpp new file mode 100644 index 00000000..59f495b9 --- /dev/null +++ b/kig/objects/point_type.cpp @@ -0,0 +1,665 @@ +// Copyright (C) 2002 Dominique Devriese <devriese@kde.org> + +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301, USA. + +#include "point_type.h" + +#include "point_imp.h" +#include "curve_imp.h" +#include "line_imp.h" +#include "other_imp.h" +#include "bogus_imp.h" + +#include "../modes/moving.h" +#include "../misc/coordinate_system.h" +#include "../misc/common.h" +#include "../misc/calcpaths.h" +#include "../misc/kiginputdialog.h" +#include "../kig/kig_part.h" +#include "../kig/kig_document.h" +#include "../kig/kig_view.h" +#include "../kig/kig_commands.h" + +#include <tdelocale.h> + +static const ArgsParser::spec argsspecFixedPoint[] = +{ + { DoubleImp::stype(), "x", "SHOULD NOT BE SEEN", false }, + { DoubleImp::stype(), "y", "SHOULD NOT BE SEEN", false } +}; + +KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( FixedPointType ) + +FixedPointType::FixedPointType() + : ArgsParserObjectType( "FixedPoint", argsspecFixedPoint, 2 ) +{ +} + +FixedPointType::~FixedPointType() +{ +} + +ObjectImp* FixedPointType::calc( const Args& parents, const KigDocument& ) const +{ + if ( ! margsparser.checkArgs( parents ) ) return new InvalidImp; + + double a = static_cast<const DoubleImp*>( parents[0] )->data(); + double b = static_cast<const DoubleImp*>( parents[1] )->data(); + + return new PointImp( Coordinate( a, b ) ); +} + +static const ArgsParser::spec argsspecRelativePoint[] = +{ + { DoubleImp::stype(), "relative-x", "SHOULD NOT BE SEEN", false }, + { DoubleImp::stype(), "relative-y", "SHOULD NOT BE SEEN", false }, + { ObjectImp::stype(), "object", "SHOULD NOT BE SEEN", false } +}; + +KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( RelativePointType ) + +RelativePointType::RelativePointType() + : ArgsParserObjectType( "RelativePoint", argsspecRelativePoint, 3 ) +{ +} + +RelativePointType::~RelativePointType() +{ +} + +ObjectImp* RelativePointType::calc( const Args& parents, const KigDocument& ) const +{ + if ( ! margsparser.checkArgs( parents ) ) return new InvalidImp; + if ( ! parents[2]->attachPoint().valid() ) return new InvalidImp; + + Coordinate reference = static_cast<const ObjectImp*>( parents[2] )->attachPoint(); + double a = static_cast<const DoubleImp*>( parents[0] )->data(); + double b = static_cast<const DoubleImp*>( parents[1] )->data(); + + return new PointImp( reference + Coordinate( a, b ) ); +} + +KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( CursorPointType ) + +CursorPointType::CursorPointType() + : ObjectType( "CursorPoint" ) +{ +} + +CursorPointType::~CursorPointType() +{ +} + +const CursorPointType* CursorPointType::instance() +{ + static const CursorPointType t; + return &t; +} + +ObjectImp* CursorPointType::calc( const Args& parents, const KigDocument& ) const +{ + assert ( parents[0]->inherits( DoubleImp::stype() ) ); + assert ( parents[1]->inherits( DoubleImp::stype() ) ); + double a = static_cast<const DoubleImp*>( parents[0] )->data(); + double b = static_cast<const DoubleImp*>( parents[1] )->data(); + + return new BogusPointImp( Coordinate( a, b ) ); +} + +const ObjectImpType* CursorPointType::resultId() const +{ + return BogusPointImp::stype(); +} + +ObjectImp* ConstrainedPointType::calc( const Args& parents, const KigDocument& doc ) const +{ + if ( ! margsparser.checkArgs( parents ) ) return new InvalidImp; + + double param = static_cast<const DoubleImp*>( parents[0] )->data(); + const Coordinate nc = static_cast<const CurveImp*>( parents[1] )->getPoint( param, doc ); + if ( nc.valid() ) return new PointImp( nc ); + else return new InvalidImp; +} + +const ArgsParser::spec argsspecConstrainedPoint[] = +{ + { DoubleImp::stype(), "parameter", "SHOULD NOT BE SEEN", false }, + { CurveImp::stype(), "Constrain the point to this curve", "SHOULD NOT BE SEEN", true } +}; + +KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( ConstrainedPointType ) + +ConstrainedPointType::ConstrainedPointType() + : ArgsParserObjectType( "ConstrainedPoint", argsspecConstrainedPoint, 2 ) +{ +} + +ConstrainedPointType::~ConstrainedPointType() +{ +} + +void FixedPointType::move( ObjectTypeCalcer& ourobj, const Coordinate& to, + const KigDocument& ) const +{ + // fetch the old coord..; + std::vector<ObjectCalcer*> pa = ourobj.parents(); + assert( margsparser.checkArgs( pa ) ); + assert( dynamic_cast<ObjectConstCalcer*>( pa.front() ) ); + assert( dynamic_cast<ObjectConstCalcer*>( pa.back() ) ); + + ObjectConstCalcer* ox = static_cast<ObjectConstCalcer*>( pa.front() ); + ObjectConstCalcer* oy = static_cast<ObjectConstCalcer*>( pa.back() ); + + ox->setImp( new DoubleImp( to.x ) ); + oy->setImp( new DoubleImp( to.y ) ); +} + +void RelativePointType::move( ObjectTypeCalcer& ourobj, const Coordinate& to, + const KigDocument& ) const +{ + // fetch the attach point..; + // this routine is tightly paired with what moveReferencePoint returns! + // right now moveReferencePoint always returns the origin + std::vector<ObjectCalcer*> pa = ourobj.parents(); + assert( margsparser.checkArgs( pa ) ); + assert( dynamic_cast<ObjectConstCalcer*>( pa[0] ) ); + assert( dynamic_cast<ObjectConstCalcer*>( pa[1] ) ); + + ObjectConstCalcer* ox = static_cast<ObjectConstCalcer*>( pa[0] ); + ObjectConstCalcer* oy = static_cast<ObjectConstCalcer*>( pa[1] ); + ObjectCalcer* ob = static_cast<ObjectCalcer*>( pa[2] ); + + Coordinate attach = ob->imp()->attachPoint(); + ox->setImp( new DoubleImp( to.x - attach.x ) ); + oy->setImp( new DoubleImp( to.y - attach.y ) ); +} + +void CursorPointType::move( ObjectTypeCalcer& ourobj, const Coordinate& to, + const KigDocument& ) const +{ + // fetch the old coord..; + + std::vector<ObjectCalcer*> pa = ourobj.parents(); + assert( pa.size() == 2 ); + assert( dynamic_cast<ObjectConstCalcer*>( pa.front() ) ); + assert( dynamic_cast<ObjectConstCalcer*>( pa.back() ) ); + + ObjectConstCalcer* ox = static_cast<ObjectConstCalcer*>( pa.front() ); + ObjectConstCalcer* oy = static_cast<ObjectConstCalcer*>( pa.back() ); + + ox->setImp( new DoubleImp( to.x ) ); + oy->setImp( new DoubleImp( to.y ) ); +} + +void ConstrainedPointType::move( ObjectTypeCalcer& ourobj, const Coordinate& to, + const KigDocument& d ) const +{ + // fetch the CurveImp.. + std::vector<ObjectCalcer*> parents = ourobj.parents(); + assert( margsparser.checkArgs( parents ) ); + + assert( dynamic_cast<ObjectConstCalcer*>( parents[0] ) ); + ObjectConstCalcer* paramo = static_cast<ObjectConstCalcer*>( parents[0] ); + const CurveImp* ci = static_cast<const CurveImp*>( parents[1]->imp() ); + + // fetch the new param.. + const double np = ci->getParam( to, d ); + + paramo->setImp( new DoubleImp( np ) ); +} + +bool ConstrainedPointType::canMove( const ObjectTypeCalcer& ) const +{ + return true; +} + +bool ConstrainedPointType::isFreelyTranslatable( const ObjectTypeCalcer& ) const +{ + return false; +} + +bool FixedPointType::canMove( const ObjectTypeCalcer& ) const +{ + return true; +} + +bool FixedPointType::isFreelyTranslatable( const ObjectTypeCalcer& ) const +{ + return true; +} + +bool RelativePointType::canMove( const ObjectTypeCalcer& ) const +{ + return true; +} + +bool RelativePointType::isFreelyTranslatable( const ObjectTypeCalcer& ) const +{ + return true; +} + +bool CursorPointType::canMove( const ObjectTypeCalcer& ) const +{ + return true; +} + +static const ArgsParser::spec argsspecMidPoint[] = +{ + { PointImp::stype(), I18N_NOOP( "Construct the midpoint of this point and another point" ), + I18N_NOOP( "Select the first of the two points of which you want to construct the midpoint..." ), false }, + { PointImp::stype(), I18N_NOOP( "Construct the midpoint of this point and another point" ), + I18N_NOOP( "Select the other of the two points of which you want to construct the midpoint..." ), false } +}; + +KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( MidPointType ) + +MidPointType::MidPointType() + : ObjectABType( "MidPoint", argsspecMidPoint, 2 ) +{ +} + +MidPointType::~MidPointType() +{ +} + +const MidPointType* MidPointType::instance() +{ + static const MidPointType t; + return &t; +} + +ObjectImp* MidPointType::calc( const Coordinate& a, const Coordinate& b ) const +{ + return new PointImp( ( a + b ) / 2 ); +} + +bool ConstrainedPointType::inherits( int type ) const +{ + return type == ID_ConstrainedPointType; +} + +const ConstrainedPointType* ConstrainedPointType::instance() +{ + static const ConstrainedPointType t; + return &t; +} + +bool FixedPointType::inherits( int type ) const +{ + return type == ID_FixedPointType; +} + +const FixedPointType* FixedPointType::instance() +{ + static const FixedPointType t; + return &t; +} + +const ObjectImpType* FixedPointType::resultId() const +{ + return PointImp::stype(); +} + +const RelativePointType* RelativePointType::instance() +{ + static const RelativePointType t; + return &t; +} + +const ObjectImpType* RelativePointType::resultId() const +{ + return PointImp::stype(); +} + +const ObjectImpType* ConstrainedPointType::resultId() const +{ + return PointImp::stype(); +} + +const ObjectImpType* CursorPointType::impRequirement( const ObjectImp* o, const Args& ) const +{ + if ( o->inherits( DoubleImp::stype() ) ) + return DoubleImp::stype(); + + if ( o->inherits( PointImp::stype() ) ) + return PointImp::stype(); + + return 0; +} + +bool CursorPointType::isDefinedOnOrThrough( const ObjectImp*, const Args& ) const +{ + return false; +} + +std::vector<ObjectCalcer*> CursorPointType::sortArgs( const std::vector<ObjectCalcer*>& args ) const +{ + return args; +} + +Args CursorPointType::sortArgs( const Args& args ) const +{ + return args; +} + +const ObjectImpType* MidPointType::resultId() const +{ + return PointImp::stype(); +} + +TQStringList FixedPointType::specialActions() const +{ + TQStringList ret; + ret << i18n( "Set &Coordinate..." ); + ret << i18n( "Redefine" ); + return ret; +} + +TQStringList ConstrainedPointType::specialActions() const +{ + TQStringList ret; + ret << i18n( "Set &Parameter..." ); + ret << i18n( "Redefine" ); + return ret; +} + +static void redefinePoint( ObjectHolder* o, KigPart& d, KigWidget& w ) +{ + PointRedefineMode pm( o, d, w ); + d.runMode( &pm ); +} + +void FixedPointType::executeAction( + int i, ObjectHolder& oh, ObjectTypeCalcer& o, + KigPart& d, KigWidget& w, NormalMode& ) const +{ + switch( i ) + { + case 0: + { + bool ok = true; + assert ( o.imp()->inherits( PointImp::stype() ) ); + Coordinate oldc = static_cast<const PointImp*>( o.imp() )->coordinate(); + KigInputDialog::getCoordinate( + i18n( "Set Coordinate" ), + i18n( "Enter the new coordinate." ) + TQString::fromLatin1( "<br>" ) + + d.document().coordinateSystem().coordinateFormatNoticeMarkup(), + &w, &ok, d.document(), &oldc ); + if ( ! ok ) break; + + MonitorDataObjects mon( getAllParents( &o ) ); + o.move( oldc, d.document() ); + KigCommand* kc = new KigCommand( d, PointImp::stype()->moveAStatement() ); + mon.finish( kc ); + + d.history()->addCommand( kc ); + break; + }; + case 1: + redefinePoint( &oh, d, w ); + break; + default: + assert( false ); + }; +} + +void ConstrainedPointType::executeAction( + int i, ObjectHolder& oh, ObjectTypeCalcer& o, KigPart& d, KigWidget& w, + NormalMode& ) const +{ + switch( i ) + { + case 1: + redefinePoint( &oh, d, w ); + break; + case 0: + { + std::vector<ObjectCalcer*> parents = o.parents(); + assert( dynamic_cast<ObjectConstCalcer*>( parents[0] ) && + parents[0]->imp()->inherits( DoubleImp::stype() ) ); + + ObjectConstCalcer* po = static_cast<ObjectConstCalcer*>( parents[0] ); + double oldp = static_cast<const DoubleImp*>( po->imp() )->data(); + + bool ok = true; + double newp = getDoubleFromUser( + i18n( "Set Point Parameter" ), i18n( "Choose the new parameter: " ), + oldp, &w, &ok, 0, 1, 4 ); + if ( ! ok ) return; + + MonitorDataObjects mon( parents ); + po->setImp( new DoubleImp( newp ) ); + KigCommand* kc = new KigCommand( d, i18n( "Change Parameter of Constrained Point" ) ); + mon.finish( kc ); + d.history()->addCommand( kc ); + break; + }; + default: + assert( false ); + }; +} + +const Coordinate FixedPointType::moveReferencePoint( const ObjectTypeCalcer& ourobj ) const +{ + assert( ourobj.imp()->inherits( PointImp::stype() ) ); + return static_cast<const PointImp*>( ourobj.imp() )->coordinate(); +} + +const Coordinate RelativePointType::moveReferencePoint( const ObjectTypeCalcer& ourobj ) const +{ + assert( ourobj.imp()->inherits( PointImp::stype() ) ); +// return static_cast<const PointImp*>( ourobj.imp() )->coordinate(); + return Coordinate( 0., 0. ); +} + +const Coordinate ConstrainedPointType::moveReferencePoint( const ObjectTypeCalcer& ourobj ) const +{ + assert( ourobj.imp()->inherits( PointImp::stype() ) ); + return static_cast<const PointImp*>( ourobj.imp() )->coordinate(); +} + +std::vector<ObjectCalcer*> FixedPointType::movableParents( const ObjectTypeCalcer& ourobj ) const +{ + return ourobj.parents(); +} + +std::vector<ObjectCalcer*> RelativePointType::movableParents( const ObjectTypeCalcer& ourobj ) const +{ + std::vector<ObjectCalcer*> ret; + ret.push_back( ourobj.parents()[0] ); + ret.push_back( ourobj.parents()[1] ); + return ret; +} + +std::vector<ObjectCalcer*> ConstrainedPointType::movableParents( const ObjectTypeCalcer& ourobj ) const +{ + std::vector<ObjectCalcer*> ret; + ret.push_back( ourobj.parents()[0] ); + return ret; +} + +/* ----------------- Transport of measure ------------------------------ */ + +ObjectImp* MeasureTransportType::calc( const Args& parents, const KigDocument& doc ) const +{ + double measure; + + if ( parents.size() != 3 ) return new InvalidImp; + + if ( parents[0]->inherits (SegmentImp::stype()) ) + { + const SegmentImp* s = static_cast<const SegmentImp*>( parents[0] ); + measure = s->length(); + } else if ( parents[0]->inherits (ArcImp::stype()) ) + { + const ArcImp* s = static_cast<const ArcImp*>( parents[0] ); + measure = s->radius()*s->angle(); + } else return new InvalidImp; + + const Coordinate& p = static_cast<const PointImp*>( parents[2] )->coordinate(); + if ( parents[1]->inherits (LineImp::stype()) ) + { + const LineImp* c = static_cast<const LineImp*>( parents[1] ); + + if ( !c->containsPoint( p, doc ) ) + return new InvalidImp; + + const LineData line = c->data(); + const Coordinate dir = line.dir()/line.length(); + const Coordinate nc = p + measure*dir; + + if ( nc.valid() ) return new PointImp( nc ); + else return new InvalidImp; + } else if ( parents[1]->inherits (CircleImp::stype()) ) + { + const CircleImp* c = static_cast<const CircleImp*>( parents[1] ); + if ( !c->containsPoint( p, doc ) ) + return new InvalidImp; + + double param = c->getParam( p, doc ); + measure /= 2*c->radius()*M_PI; + param += measure; + while (param > 1) param -= 1; + + const Coordinate nc = c->getPoint( param, doc ); + if ( nc.valid() ) return new PointImp( nc ); + else return new InvalidImp; + } + + return new InvalidImp; +} + +// I18N_NOOP( "Select the segment/arc to transport on the circle/line..." ), false }, +// I18N_NOOP( "Select the circle/line on which to transport a measure..." ), true }, +// I18N_NOOP( "Select a point on the circle/line..." ), false } + +KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( MeasureTransportType ) + +MeasureTransportType::MeasureTransportType() + : ObjectType( "TransportOfMeasure" ) +{ +} + +MeasureTransportType::~MeasureTransportType() +{ +} + +const MeasureTransportType* MeasureTransportType::instance() +{ + static const MeasureTransportType t; + return &t; +} + +const ObjectImpType* MeasureTransportType::resultId() const +{ + return PointImp::stype(); +} + +const ObjectImpType* MeasureTransportType::impRequirement( const ObjectImp* obj, const Args& ) const +{ + if ( obj->inherits( PointImp::stype () ) ) + return PointImp::stype (); + + if ( obj->inherits( LineImp::stype () ) ) + return LineImp::stype (); + + if ( obj->inherits( CircleImp::stype () ) ) + return CircleImp::stype (); + + if ( obj->inherits( SegmentImp::stype () ) ) + return SegmentImp::stype (); + + if ( obj->inherits( ArcImp::stype () ) ) + return ArcImp::stype (); + + return 0; +} + +bool MeasureTransportType::isDefinedOnOrThrough( const ObjectImp* o, const Args& ) const +{ + if ( o->inherits( LineImp::stype() ) ) return true; + if ( o->inherits( CircleImp::stype() ) ) return true; + return false; +} + +std::vector<ObjectCalcer*> MeasureTransportType::sortArgs( const std::vector<ObjectCalcer*>& args ) const +{ + return args; /* should already be in correct order */ +} + +Args MeasureTransportType::sortArgs( const Args& args ) const +{ + return args; +} + +/* - transport of measure (old, for compatibility with prev. kig files) - */ + +ObjectImp* MeasureTransportTypeOld::calc( const Args& parents, const KigDocument& doc ) const +{ + if ( ! margsparser.checkArgs( parents ) ) return new InvalidImp; + + const CircleImp* c = static_cast<const CircleImp*>( parents[0] ); + const Coordinate& p = static_cast<const PointImp*>( parents[1] )->coordinate(); + + if ( !c->containsPoint( p, doc ) ) + return new InvalidImp; + + const SegmentImp* s = static_cast<const SegmentImp*>( parents[2] ); + double param = c->getParam( p, doc ); + double measure = s->length(); + measure /= 2*c->radius()*M_PI; + param += measure; + while (param > 1) param -= 1; + + const Coordinate nc = c->getPoint( param, doc ); + if ( nc.valid() ) return new PointImp( nc ); + else return new InvalidImp; +} + +static const ArgsParser::spec argsspecMeasureTransportOld[] = +{ + { CircleImp::stype(), "Transport a measure on this circle", + I18N_NOOP( "Select the circle on which to transport a measure..." ), true }, + { PointImp::stype(), "Start transport from this point of the circle", + I18N_NOOP( "Select a point on the circle..." ), false }, + { SegmentImp::stype(), "Segment to transport", + I18N_NOOP( "Select the segment to transport on the circle..." ), false } +}; + +KIG_INSTANTIATE_OBJECT_TYPE_INSTANCE( MeasureTransportTypeOld ) + +MeasureTransportTypeOld::MeasureTransportTypeOld() + : ArgsParserObjectType( "MeasureTransport", argsspecMeasureTransportOld, 3 ) +{ +} + +MeasureTransportTypeOld::~MeasureTransportTypeOld() +{ +} + +const MeasureTransportTypeOld* MeasureTransportTypeOld::instance() +{ + static const MeasureTransportTypeOld t; + return &t; +} + +const ObjectImpType* MeasureTransportTypeOld::resultId() const +{ + return PointImp::stype(); +} + +/* ----------------- end transport of measure ------------------------- */ + |