// $Revision: 1.25 $ //-------------------------------------------------------------------------------------------------- // File Name: PolygonComponent.c (Part of GrafEdit) // // Description: Implementations for Polygon graphic components. // // Authors: Robert Seidl // // Classes defined in this file: // // ¥ TPolygonComponent // defn of the TGraphicComponent subclass // ¥ TPolygonTool // tool for creating a new Polygon (uses TCreatePolygonTracker) // ¥ TCreatePolygonTracker // multi-click tracker. Uses TNewComponentCommand after last click // ¥ TPolygonEditTracker // hit-through tracker (uses TChangePolygonShapeCommand) // ¥ TChangePolygonShapeCommand // for command-based hit-through editing // // Modification history: // // 1 Nov 93 rtw Upgrade to new graf ports and graphics and general clean-up // 8 Oct 92 rbs Upgrade to New CHER // 24 jul 92 rbs d24 change: TSeed -> TPseudoTimeStamp // 4 dec 91 rhs d21 checkin // 26 jul 91 rhs first grafedit checkin // 4 Jul 91 rhs prep for d18 release // 16 May 91 rhs forked off from PolylineComponent.h // // Copyright (C) 1994 Taligent, Inc. All rights reserved. // Copyright (C) 1994 Taligent, Inc. All rights reserved. //-------------------------------------------------------------------------------------------------- #ifndef Taligent_CANVASPOLYGON #include "CanvasPolygon.h" #endif #ifndef Taligent_CANVASCOMMANDS #include "CanvasCommands.h" #endif #ifndef Taligent_CANVASINTERACTION #include "CanvasInteraction.h" #endif #ifndef Taligent_GUICOMPOUNDDOCUMENTUTILITY #include #endif #ifndef Taligent_GRAFEDITTRACE #include "GrafEditTrace.h" #endif //======================================== // Constructors and Destructors //======================================== TCanvasPolygon::TCanvasPolygon () : MCanvasGraphic (), fPolygon (NIL), fBounds (TGRect::kZeroRect) { } TCanvasPolygon::TCanvasPolygon (const TGPolygon& aPolygon) : MCanvasGraphic (), fPolygon (NIL) { fPolygon = new TGPolygon (aPolygon); fBounds = fPolygon? fPolygon->GetBounds () : TGRect (TGRect::kZeroRect); } TCanvasPolygon::TCanvasPolygon (const TCanvasPolygon& source) : MCanvasGraphic (source), fPolygon (NIL) { fPolygon = source.fPolygon? new TGPolygon (*source.fPolygon) : NIL; fBounds = fPolygon? fPolygon->GetBounds () : TGRect (TGRect::kZeroRect); } TCanvasPolygon::~TCanvasPolygon () { } //======================================== // MCollectible overrides //======================================== MCollectibleDefinitionsMacro (TCanvasPolygon, kOriginalVersion); DynamicCastDefinitionsMacroOne (TCanvasPolygon, MCanvasGraphic); // // Assignment // TCanvasPolygon& TCanvasPolygon::operator= (const TCanvasPolygon& source) { if ( this != &source ) { MCanvasGraphic::operator= (source); fPolygon = source.fPolygon? new TGPolygon (*source.fPolygon) : NIL; fBounds = fPolygon? fPolygon->GetBounds () : TGRect (TGRect::kZeroRect); } return *this; } // // Streaming // TStream& TCanvasPolygon::operator>>= (TStream& toWhere) const { WriteVersion (toWhere); MCanvasGraphic::operator>>= (toWhere); bool hasPolygon = (fPolygon != NIL); hasPolygon >>= toWhere; if( hasPolygon ) { *fPolygon >>= toWhere; fBounds >>= toWhere; } return toWhere; } TStream& TCanvasPolygon::operator<<= (TStream& fromWhere) { VersionInfo info = ReadVersion (fromWhere); MCanvasGraphic::operator<<= (fromWhere); bool hasPolygon; hasPolygon <<= fromWhere; if ( hasPolygon ) { fPolygon = new TGPolygon (); *fPolygon <<= fromWhere; fBounds <<= fromWhere; } else { fPolygon = NIL; fBounds = TGRect (TGRect::kZeroRect); } return fromWhere; } //======================================== // MCanvasGraphic overrides //======================================== void TCanvasPolygon::HandleDraw (TGrafPort& port) const { if ( fPolygon ) port.Draw (*fPolygon); } TGRect TCanvasPolygon::HandleGetBounds () const { return fBounds; } bool TCanvasPolygon::HandleHit (const TGPoint& p) const { if ( fPolygon ) { TGRect r (p,p); r.Inset (TGPoint(-2.,-2.)); return fPolygon->Intersects (r); } else return false; } //======================================== // TPolygonComponent methods //======================================== // // GetParametric // bool TCanvasPolygon::GetParametric (const TGPoint& p, GCoordinate& u) const { if( !fPolygon || !fBounds.Contains(p) ) // quick reject: no Polygon or p nowhere near Polygon return false; const GCoordinate hitDist = 10. ; u = fPolygon->NearestParametric ( p ) ; TGPoint diff = fPolygon->Evaluate ( u ) - p ; bool hit = diff.VectorLength() <= hitDist ; // Is the nearest parametric within hitDist. return hit; } // // DragPolygonTo // void TCanvasPolygon::DragPolygonTo (GCoordinate u, const TGPoint& p) { if( fPolygon ) { ((TGPolygon*)fPolygon)->TGPolygon::DragPosition (u, p); fBounds = fPolygon->GetBounds (); } } //================================================================================ // class TCanvasPolygonCreationInteractor // // description An interactor that creates canvas polygons from multiple // click points. // // modification rtw 12/30/93 created //================================================================================ //======================================== // Metadata //======================================== VersionDefinitionsMacro (TCanvasPolygonCreationInteractor,0); //======================================== // Constructors and Destructors //======================================== TCanvasPolygonCreationInteractor::TCanvasPolygonCreationInteractor (MCanvasSelection* adoptTarget, MToolHandler* handler) : TCanvasPolylineMulticlickInteractor (handler), fTarget (adoptTarget) { #ifdef DEBUG ::qprintf ("TCanvasPolygonCreationInteractor::TCanvasPolygonCreationInteractor\n"); #endif } TCanvasPolygonCreationInteractor::~TCanvasPolygonCreationInteractor () { #ifdef DEBUG ::qprintf ("TCanvasPolygonCreationInteractor::~TCanvasPolygonCreationInteractor\n"); #endif } //======================================== // TCanvasInteractor Overrides //======================================== void TCanvasPolygonCreationInteractor::EndInteraction () { #ifdef DEBUG ::qprintf ("TCanvasPolygonCreationInteractor::EndInteraction\n"); #endif if ( fTarget && GetNumberOfPoints() > 2 ) { // // Create and do a new polygon component command // if ( GetNumberOfPoints() > 3 ) { // // Check if user closed the loop // TGPoint distanceVector = GetLastPoint() - GetFirstPoint(); if ( distanceVector.VectorLength() < 4 ) RemoveLastPoint (); } TGPolygon p (GetPoints()); TCanvasPolygon* thePolygon = new TCanvasPolygon (p); TAdoptCanvasGraphicCmd *command = new TAdoptCanvasGraphicCmd (thePolygon); AdoptAndDo (new TToolCommandBindingTo (command, fTarget.OrphanObject())); } } //================================================================================ // class TCanvasPolygonCreationTool // // description A tool that creates canvas polygons. // // modification rtw 12/30/93 created //================================================================================ //======================================== // Constructors and destructors //======================================== TCanvasPolygonCreationTool::TCanvasPolygonCreationTool () : TSimpleMouseTool (TTypeDescription(static_type_info(MCanvasSelection))) { #ifdef DEBUG ::qprintf ("TCanvasPolygonCreationTool::TCanvasPolygonCreationTool\n"); #endif } TCanvasPolygonCreationTool::TCanvasPolygonCreationTool (const TCanvasPolygonCreationTool& source) : TSimpleMouseTool (source) { #ifdef DEBUG ::qprintf ("TCanvasPolygonCreationTool::TCanvasPolygonCreationTool\n"); #endif } TCanvasPolygonCreationTool::~TCanvasPolygonCreationTool () { #ifdef DEBUG ::qprintf ("TCanvasPolygonCreationTool::~TCanvasPolygonCreationTool\n"); #endif } //======================================== // MCollectible overrides //======================================== MCollectibleDefinitionsMacro (TCanvasPolygonCreationTool, kOriginalVersion); TCanvasPolygonCreationTool& TCanvasPolygonCreationTool::operator= (const TCanvasPolygonCreationTool& source) { TSimpleMouseTool::operator= (source); return *this; } // // Streaming // TStream& TCanvasPolygonCreationTool::operator>>= (TStream& toWhere) const { #ifdef DEBUG ::qprintf ("TCanvasPolygonCreationTool::operator>>=\n"); #endif // Just in case we need to add data to this class later WriteVersion (toWhere); TSimpleMouseTool::operator>>= (toWhere); return toWhere; } TStream& TCanvasPolygonCreationTool::operator<<= (TStream& fromWhere) { #ifdef DEBUG ::qprintf ("TCanvasPolygonCreationTool::operator<<=\n"); #endif // Just in case we need to add data to this class later VersionInfo version = ReadVersion (fromWhere); if ( version != kOriginalVersion ) throw TGlobalExceptionKludge (kStreamBadVersion, 0); TSimpleMouseTool::operator<<= (fromWhere); return fromWhere; } //======================================== // TTool overrides //======================================== void TCanvasPolygonCreationTool::GetPaletteText (TText& theText) const { #ifdef DEBUG ::qprintf ( "TCanvasPolygonCreationTool::GetPaletteText\n" ); #endif TLocale locale; TLocale::GetCurrentLocale(locale); try { TDeleterFor theArchive = TArchive::CopyArchiveForSharedLibrary(); TArchiveEnvelope theEnvelope(theArchive, locale); theText.Replace (*theEnvelope.CopyObject( TStandardText("Polygon") )); } catch (const TStandardException&) { ::qprintf("Error reading tool palette text from archive\n"); theText.Replace( TStandardText("Polygon") ); } } MGraphic* TCanvasPolygonCreationTool::CreatePaletteGraphic () const { #ifdef DEBUG ::qprintf ("TCanvasPolygonCreationTool::CreatePaletteGraphic (empty)\n"); #endif return NIL; } MGraphic* TCanvasPolygonCreationTool::CreateCursorGraphic () const { #ifdef DEBUG ::qprintf ( "TCanvasPolygonCreationTool::CreateCursorGraphic\n" ); #endif TGPolygon crossHair (12); crossHair.SetPoint (0,TGPoint(-1,7)); crossHair.SetPoint (1,TGPoint(1,7)); crossHair.SetPoint (2,TGPoint(1,1)); crossHair.SetPoint (3,TGPoint(7,1)); crossHair.SetPoint (4,TGPoint(7,-1)); crossHair.SetPoint (5,TGPoint(1,-1)); crossHair.SetPoint (6,TGPoint(1,-7)); crossHair.SetPoint (7,TGPoint(-1,-7)); crossHair.SetPoint (8,TGPoint(-1,-1)); crossHair.SetPoint (9,TGPoint(-7,-1)); crossHair.SetPoint (10,TGPoint(-7,1)); crossHair.SetPoint (11,TGPoint(-1,1)); TRGBColor black(0,0,0),white(1,1,1); TGrafBundle* bundle = new TGrafBundle(new TColorPaint(black),new TColorPaint(white)); return new TPolygon (crossHair, bundle); } TToolInteractor* TCanvasPolygonCreationTool::CreateInteractor (MToolTarget* target) const { #ifdef DEBUG ::qprintf ("TCanvasPolygonCreationTool::CreateInteractor\n"); #endif TCanvasPolygonCreationInteractor* theInteractor = NIL; MCanvasSelection *selection = NIL; ::DynamicCastTo (selection, target); if ( selection ) { theInteractor = new TCanvasPolygonCreationInteractor ( selection, ::NonConst((TTool*)this)->GetToolHandler()); theInteractor->SetCoordinateView (::NonConst((TTool*)this)->GetToolView()); } return theInteractor; }