gre/labelplacement.h

Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  * \file gre/labelplacement.h
00004  * \brief GRE::LABELPLACEMENT class definition
00005  *
00006  * \if NODOC
00007  * $Log: labelplacement.h_v $
00008  * Revision 1.27  2006/10/05 20:04:41  mju
00009  * Fwd declare color.
00010  *
00011  * Revision 1.26  2006/09/19 20:30:23  scowan
00012  * More fwd decl's.
00013  *
00014  * Revision 1.25  2006/09/19 16:09:04  scowan
00015  * More include file changes.
00016  *
00017  * Revision 1.24  2006/09/19 15:45:28  scowan
00018  * Removed unused include files.
00019  *
00020  * Revision 1.23  2006/09/19 15:40:46  scowan
00021  * Uses new header for symbol definition.
00022  *
00023  * Revision 1.22  2005/10/14 17:30:16  mju
00024  * GRE namespace.
00025  *
00026  * Revision 1.21  2005/03/31 16:57:06  fileserver!dwilliss
00027  * Rename one of our types to MIUNICODE because it conflicted with a Microsoft #define
00028  *
00029  * Revision 1.19  2004/09/17 17:40:09  dwilliss
00030  * Added a couple private methods
00031  * Added a Detach method
00032  *
00033  * Revision 1.18  2004/09/09 20:06:03  dwilliss
00034  * Added Zoom
00035  *
00036  * Revision 1.17  2004/09/08 22:47:26  dwilliss
00037  * Implement CopyOnWrite and ComputeLabelExtents
00038  *
00039  * Revision 1.16  2004/09/08 16:50:44  dwilliss
00040  * Added SetPointSymbol version that takes RVC::STYLE::SYMBOLPATTERN
00041  *
00042  * Revision 1.15  2004/09/03 22:49:39  dwilliss
00043  * Added Draw methods
00044  *
00045  * Revision 1.10  2004/07/22 22:16:54  dwilliss
00046  * Keep track of the layer
00047  * Allow labels to be deleted
00048  *
00049  * Revision 1.7  2004/07/20 17:43:29  dwilliss
00050  * Fixed End() to compile with gcc
00051  *
00052  * Revision 1.2  2004/04/15 20:51:44  dwilliss
00053  * LABELPLACE's data is now kept in a refcounted private data structure so
00054  * copy and assignment are faster.
00055  *
00056  * Revision 1.1  2004/04/14 22:47:08  dwilliss
00057  * Initial revision
00058  *
00059  * \endif
00060  *
00061  *****************************************************************************/
00062 
00063 #ifndef INC_GRE_LABELPLACEMENT_H
00064 #define INC_GRE_LABELPLACEMENT_H
00065 
00066 
00067 #ifndef INC_RVC_ELEMENT_H
00068 #include <rvc/element.h>
00069 #endif
00070 
00071 #ifndef INC_MI32_TEXTBASE_H
00072 #include <mi32/textbase.h>
00073 #endif
00074 
00075 #ifndef INC_MI32_POLYLINE_H
00076 #include <mi32/polyline.h>
00077 #endif
00078 
00079 class LABELSTYLE;
00080 class QUADTREE;
00081 class REGION2D;
00082 struct COLOR;
00083 struct LINESTYLE;
00084 struct POINTSTYLE;
00085 
00086 namespace MGD {
00087    class CONTEXT;
00088    }
00089    
00090 namespace RVC {
00091    class STYLEPATTERN_SYMBOL;
00092    }
00093 
00094 namespace GRE {
00095    class LAYER;
00096    class LAYERDC;
00097    class VIEW;
00098    class LABELPLACEMENT;
00099 
00100    class LABELATTACHMENT {
00101       public:
00102          //! Default Constructor
00103          LABELATTACHMENT (
00104             ) { }
00105 
00106          //! Constructor to attach to a given element
00107          LABELATTACHMENT (
00108             const RVC::ELEMENT& elem
00109             ) :
00110             m_elem(elem)
00111             {
00112             }
00113 
00114          //! Copy Ctor
00115          LABELATTACHMENT (
00116             const LABELATTACHMENT& rhs
00117             ) :
00118             m_elem(rhs.m_elem),
00119             m_leader(rhs.m_leader)
00120             {
00121             }
00122 
00123          //! Constructor to attach to a given element, with a leader
00124          LABELATTACHMENT (
00125             const RVC::ELEMENT& elem,
00126             const POLYLINE& leader
00127             ) :
00128             m_elem(elem),
00129             m_leader(leader)
00130             {
00131             }
00132 
00133          ~LABELATTACHMENT() {}
00134 
00135          const RVC::ELEMENT& GetElement (
00136             ) const {
00137             return (m_elem);
00138             }
00139 
00140          const POLYLINE& GetLeader (
00141             ) const {
00142             return (m_leader);
00143             }
00144 
00145          void SetElement (
00146             const RVC::ELEMENT& elem
00147             ) {
00148             m_elem = elem;
00149             }
00150 
00151          void SetLeader (
00152             const POLYLINE& leader
00153             ) {
00154             m_leader = leader;
00155             }
00156 
00157       private:
00158          RVC::ELEMENT m_elem;
00159          POLYLINE m_leader;
00160 
00161       };
00162 
00163    //! Class for keeping track of where a label is on the screen
00164    //! 
00165    //! Other things we may need in this class:
00166    //!   Flag to disallow moving - script for stacking label flags would want
00167    //!      to prevent the optimizer from moving labels.
00168    //!   
00169    class LABELPLACE {
00170       public:
00171          //! Default constructor
00172          LABELPLACE();
00173 
00174          //! Copy constructor
00175          LABELPLACE (
00176             const LABELPLACE& rhs
00177             );
00178 
00179          // dtor
00180          ~LABELPLACE();
00181 
00182          //! Assignment operator
00183          LABELPLACE& operator=(
00184             const LABELPLACE& rhs
00185             );
00186 
00187          // Compute the extents region of the label for a given GC
00188          // This computes the text label region (including frame) for a
00189          // given graphics context.
00190          void ComputeLabelExtents (
00191             MGD::CONTEXT* gc,
00192             REGION2D& region,
00193             bool bIgnoreLeaders = false
00194             ) const;
00195 
00196          //! Remove the attachment information for a given element
00197          void DeleteAttachment (
00198             const RVC::ELEMENT& element
00199             );
00200 
00201          // Detach the LABELPLACE from the LABELPLACEMENT.
00202          // Normally, a LABELPLACE is only a pointer to data owned by the
00203          // LABELPLACEMENT that's managing it.  Detach() copies the data
00204          // so that any changes made do not effect the master copy.
00205          void Detach (
00206             );
00207 
00208          //! Draw a label into a view
00209          ERRVALUE Draw (
00210             LAYERDC* pDC,   //!< layer DC to use (if NULL, will create a temporary one - not very efficient, but ok for datatips and such)
00211             const COLOR* ForegroundColor = 0 //!< Overrides Foreground color if not NULL
00212             ) const;
00213 
00214          //! Draw a label into an arbitrary device
00215          ERRVALUE DrawSample (
00216             MGD::CONTEXT& gc,
00217             const COLOR* ForegroundColor = 0, //!< Overrides Foreground color if not NULL
00218             bool bDrawLeaders = true
00219             ) const;
00220 
00221          //! Get the list of attachments
00222          const MILIST<LABELATTACHMENT>& GetAttachments (
00223             ) const;
00224 
00225          double GetBaseAngle (
00226             ) const;
00227 
00228          const POLYLINE& GetBaseLine (
00229             ) const;
00230 
00231          TEXTBASEORIGIN GetBaseOrigin (
00232             ) const;
00233 
00234          const DPOINT2D& GetBasePoint (
00235             ) const;
00236 
00237          bool GetDrawBaseLine (
00238             ) const;
00239          
00240          //! Get the line style for drawing the baseline
00241          //! @return true if line style has been set, false if not
00242          bool GetBaseLineStyle (
00243             LINESTYLE&
00244             ) const;
00245 
00246          //! Get the layer for this label.
00247          //! Note: you don't have to set the layer because LABLEPLACEMENT::Add
00248          //! does it for you.
00249          LAYER* GetLayer (
00250             ) const;
00251 
00252          //! Get the offset from the original location.
00253          //! If the optimizer is not run, this will return a (0,0)
00254          const DPOINT2D& GetOffset (
00255             ) const;
00256          
00257          //! Get the location of the point symbol (if any)
00258          //! in screen coordinates
00259          const DPOINT2D& GetSymbolPoint (
00260             ) const;
00261 
00262          //! Get the POINTSTYLE to use for the symbol
00263          const POINTSTYLE& GetPointStyle (
00264             ) const;
00265 
00266          //! Get the symbol data for the point symbol
00267          const SIMPLE_ARRAY<UINT8>& GetPointSymbol (
00268             ) const;
00269 
00270          //! Get the priority used in label optimization
00271          //! Higher numbers are higher priority
00272          double GetPriority (
00273             ) const;
00274 
00275          //! Return the region of the actual label.
00276          const REGION2D& GetRegion (
00277             ) const;
00278 
00279          const LABELSTYLE& GetStyle (
00280             ) const;
00281 
00282          const MISTRING& GetText (
00283             ) const;
00284 
00285          //! Returns true if the place holds point symbol information
00286          bool HasPoint (
00287             ) const;
00288 
00289          //! Returns true if the place holds text label information
00290          bool HasText (
00291             ) const;
00292 
00293          //! Returns true if the label is attached to the given element
00294          bool IsAttached (
00295             ELEMTYPE ElemType,
00296             INT32 ElemNum
00297             ) const;
00298 
00299          //! Returns true if the label is attached to the given element
00300          bool IsAttached (
00301             const RVC::ELEMENT& elem
00302             ) const;
00303 
00304          //! Return true if label is locked.
00305          //! When deconflicting labels, locked labels are not allowed to move.
00306          bool IsLocked (
00307             ) const;
00308 
00309          //! Lock a label in place.
00310          //! This prevents deconflicting from being able to move the label.
00311          void LockPosition (
00312             bool locked = true
00313             );
00314 
00315          //! Move a label a given ammount.
00316          void Move (
00317             const DPOINT2D& delta
00318             );
00319 
00320          //! Add an element attachment for this label
00321          void AddAttachment (
00322             const LABELATTACHMENT& attachment
00323             );
00324 
00325          //! Add an element attachment for this label (no leader line)
00326          void AddAttachment (
00327             const RVC::ELEMENT& element
00328             );
00329 
00330          void SetBaseLine (
00331             const POLYLINE& baseline
00332             );
00333 
00334          void SetBaseLine (
00335             const DPOINT2D& pt,
00336             double angle,
00337             TEXTBASEORIGIN origin
00338             );
00339 
00340          // Set CopyOnWrite for this instance.
00341          // LABELPLACE is implemented as a refcounted private data pointer
00342          // but by default does not do Copy-On-Write.  If you get a
00343          // label place through an iterator and mofify it, you usually want
00344          // to modify the original anyway.  In the rare case that you don't
00345          // call this method first.
00346          // Note that the CONST_ITERATOR sets CopyOnWrite to true, The
00347          // non-const ITERATOR sets it to false
00348          void SetCopyOnWrite (
00349             bool bCopyOnWrite = true
00350             ) {
00351             m_bCopyOnWrite = bCopyOnWrite;
00352             }
00353 
00354          void SetDrawBaseLine (
00355             bool draw = true
00356             );
00357 
00358          //! Set the style for drawing the baseline
00359          void SetBaseLineStyle (
00360             const LINESTYLE& style
00361             );
00362 
00363          //! Set the location of the point symbol (if any)
00364          //! in screen coordinates.
00365          void SetPoint (
00366             const DPOINT2D& location
00367             );
00368 
00369          //! Set the POINTSTYLE to use for the symbol
00370          void SetPointStyle (
00371             const POINTSTYLE& style
00372             );
00373 
00374          //! Set the symbol data for the point symbol
00375          void SetPointSymbol (
00376             const SIMPLE_ARRAY<UINT8>& symbol
00377             );
00378 
00379          //! Set the symbol data for the point symbol
00380          void SetPointSymbol (
00381             const RVC::STYLEPATTERN_SYMBOL& symbol
00382             );
00383 
00384          //! Set the priority used in label optimization
00385          //! Higher numbers are higher priority
00386          void SetPriority (
00387             double priority
00388             );
00389 
00390          //! Set the extents region of the label
00391          void SetRegion (
00392             const REGION2D& region
00393             );
00394 
00395          void SetStyle (
00396             const LABELSTYLE& style
00397             );
00398 
00399          void SetText (
00400             const MISTRING& str
00401             );
00402 
00403 #if !defined(GENERATING_DOXYGEN_OUTPUT)
00404          // Used by LABELPLACEMENT::Add()
00405          void SetParent (
00406             GRE::LABELPLACEMENT* parent
00407             );
00408 
00409          GRE::LABELPLACEMENT* GetParent (
00410             ) const;
00411          
00412          // For SML script access.
00413          // Retrieves the string attached by SetUserString.
00414          // note, returning const MIUNICODE* instead of MISTRING& for SML
00415          // implemention convenience.  SML has to construct an SMLSTRING
00416          // out of it anyway
00417          const MIUNICODE* GetUserString (
00418             ) const;
00419       
00420          //! For SML script access.
00421          //! This allows an SML Control Script to attach any string data
00422          //! to the label.  The only thing it's useful for is for the 
00423          //! script to retrieve later.
00424          void SetUserString (
00425             const MISTRING& str
00426             );
00427 
00428          void Zoom (
00429             double scale
00430             );
00431       
00432          //! Sets the ID in the qtree.
00433          //! used internally by Move and LABELPLACEMENT Add and Remove
00434          void SetID (
00435             INT32 id
00436             );
00437 #endif
00438 
00439       private:
00440 
00441          class PRIV;    // Actual data is a refcounted private structure
00442          PRIV *m_priv;  // so that copy constructor and assignment are fast
00443          bool m_bCopyOnWrite;
00444       };
00445 
00446 
00447 
00448 
00449    class LABELPLACEMENT {
00450       public:
00451          class ITERATOR;
00452          class CONST_ITERATOR;
00453          friend class CONST_ITERATOR;
00454 
00455          class CONST_ITERATOR {
00456             public:
00457 
00458                //! Default constructor
00459                CONST_ITERATOR (
00460                   ) :
00461                   m_placement(0),
00462                   m_num(-1)
00463                   { }
00464 
00465                //! Destructor
00466                virtual ~CONST_ITERATOR() {};
00467 
00468                //! Copy constructor
00469                CONST_ITERATOR (
00470                   const CONST_ITERATOR& rhs
00471                   ) :
00472                   m_placement(rhs.m_placement),
00473                   m_place(rhs.m_place),
00474                   m_num(rhs.m_num)
00475                   {}
00476 
00477                
00478                //! Internal ctor
00479                CONST_ITERATOR (
00480                   LABELPLACEMENT* placement
00481                   ) :
00482                   m_placement(placement),
00483                   m_num(-1)
00484                   { 
00485                      ReadNext(true);   // Incrementes to first non-deleted element
00486                   }
00487 
00488                //! Dereference operator
00489                const LABELPLACE& operator* (
00490                   ) const { return (m_place); }
00491 
00492                //! Dereference operator
00493                const LABELPLACE* operator-> (
00494                   ) const { return (&**this); }
00495 
00496                //! Pre-increment operator
00497                CONST_ITERATOR& operator++(
00498                   ) {
00499                   ReadNext(true);
00500                   return *this;
00501                   }  
00502 
00503                //! Post-increment operator
00504                CONST_ITERATOR operator++(int
00505                   ) {
00506                   CONST_ITERATOR temp = *this;
00507                   ++*this;
00508                   return(temp);
00509                   }
00510 
00511                //! Pre-decrement operator
00512                CONST_ITERATOR& operator--(
00513                   ) {
00514                   ReadPrev(true);
00515                   return *this;
00516                   }
00517 
00518                //! Post-decrement operator
00519                CONST_ITERATOR operator--(int
00520                   ) {
00521                   CONST_ITERATOR temp = *this;
00522                   --*this;
00523                   return(temp);
00524                   }
00525 
00526                //! Equality operator
00527                bool operator== (
00528                   const CONST_ITERATOR& rhs
00529                   ) const {
00530                   if (m_num == -1 && rhs.m_num == -1) return (true);
00531                   return (m_num == rhs.m_num && m_placement == rhs.m_placement);
00532                   }
00533 
00534                //! Inequality operator
00535                bool operator!= (
00536                   const CONST_ITERATOR& rhs
00537                   ) const { return (!(*this == rhs)); }
00538 
00539 #if !defined(GENERATING_DOXYGEN_OUTPUT)
00540             protected:  // non-const iterator can access all this
00541                LABELPLACEMENT* m_placement;
00542                LABELPLACE m_place;
00543                int m_num;
00544                void ReadPrev (bool bIsConst);
00545                void ReadNext (bool bIsConst);
00546 #endif
00547             };
00548 
00549          friend class ITERATOR;
00550          class ITERATOR : public CONST_ITERATOR {
00551             public:
00552                ITERATOR();
00553                
00554                //! Internal constructor
00555                ITERATOR(LABELPLACEMENT* placement) :
00556                   CONST_ITERATOR(placement) 
00557                   { }
00558 
00559                //! Dereference operator
00560                LABELPLACE& operator* (
00561                   ) { return (m_place); }
00562 
00563                //! Dereference operator
00564                LABELPLACE* operator-> (
00565                   ) { return (&**this); }
00566 
00567                //! Pre-increment operator
00568                ITERATOR& operator++() {
00569                   ReadNext(false);
00570                   return (*this);
00571                   }
00572 
00573                //! Post-increment operator
00574                ITERATOR operator++(int
00575                   ) {
00576                   ITERATOR temp = *this;
00577                   ++*this;
00578                   return(temp);
00579                   }
00580 
00581                //! Pre-decrement operator
00582                ITERATOR& operator--() {
00583                   ReadPrev(false);
00584                   return (*this);
00585                   };
00586 
00587                //! Post-decrement operator
00588                ITERATOR operator--(int
00589                   ) {
00590                   ITERATOR temp = *this;
00591                   --*this;
00592                   return(temp);
00593                   }
00594 
00595                //! Equality operator
00596                bool operator== (
00597                   const ITERATOR& rhs
00598                   ) const;
00599 
00600                //! Inequality operator
00601                bool operator!= (
00602                   const ITERATOR& rhs
00603                   ) const { return (!(*this == rhs)); }
00604             };
00605 
00606          //! Shuffle labels around so they don't overlap
00607          //! (note: not actually implemented yet)
00608          static ERRVALUE Deconflict (
00609             SIMPLE_ARRAY<LABELPLACEMENT*>& LabelSets
00610             );
00611 
00612          //! Default constructor
00613          LABELPLACEMENT (
00614             LAYER* layer,
00615             VIEW* view
00616             );
00617 
00618          //! Destructor
00619          virtual ~LABELPLACEMENT (
00620             );
00621 
00622          //! Add a place
00623          ERRVALUE Add (
00624             const LABELPLACE& place
00625             );
00626 
00627          //! LABELPLACE Iterator constructor
00628          CONST_ITERATOR Begin (
00629             ) const { return (CONST_ITERATOR(const_cast<LABELPLACEMENT*>(this))); }
00630 
00631          //! Clear all places
00632          void Clear (
00633             );
00634 
00635          //! Deletes placement information for all labels attached
00636          //! to a given element.  Note, if a label is associated with more
00637          //! than one element, only the leader line will be deleted.
00638          void DeleteLabels (
00639             const RVC::ELEMENT& element
00640             );
00641 
00642          //! LABELPLACE Iterator End condition
00643          CONST_ITERATOR End (
00644             ) const { return (CONST_ITERATOR(0)); }
00645 
00646          //! Given a screen coordinate, find the label (topmost in case of 
00647          //! multiples) at that location.
00648          //! pt is in screen coordinates.
00649          //! This version is for finding the label for data tips and things.
00650          //! The LABELPLACE returned is a copy, so changing it won't do
00651          //! anthing.
00652          //! 
00653          //! \return Number of items found or error if < 0
00654          INT32 Find (
00655             const DPOINT2D& pt,
00656             GRE::LABELPLACE& place,
00657             int maxdist = 0
00658             ) const;
00659 
00660          //! Given a screen coordinate, find all labels at that location.
00661          //! List will be sorted front to back.
00662          //! pt is in screen coordinates.
00663          //! \return Number of items found or error if < 0
00664          INT32 Find (
00665             const DPOINT2D& pt,
00666             MILIST<GRE::LABELPLACE*>& list,
00667             int maxdist = 0
00668             ) const;
00669 
00670          //! Find all labels intersecting a rectangle in screen coordinates.
00671          //! List will be sorted front to back.
00672          //! pt is in screen coordinates.
00673          //! \return Number of items found or error if < 0
00674          INT32 Find (
00675             const DRECT2D& rect,
00676             MILIST<GRE::LABELPLACE*>& list
00677             ) const;
00678 
00679 
00680          //! Find all labels intersecting a rectangle in screen coordinates.
00681          //! List will be sorted front to back.
00682          //! pt is in screen coordinates.
00683          //! \return Number of items found or error if < 0
00684          INT32 Find (
00685             const REGION2D& region,
00686             MILIST<GRE::LABELPLACE*>& list
00687             ) const;
00688 
00689 
00690          //! Get the union of of all label place regions. 
00691          //! This may be used for clip-under support, but then again, maybe not.
00692          //! If the actual labels will be drawn with balloon tips, this won't
00693          //! know about it.
00694          //! By default, the region passed in will be cleared of any previous
00695          //! value.  If you pass false for the bClear parameter, it will combine
00696          //! the label regions with the region passed in.
00697          ERRVALUE GetCombinedRegion (
00698             REGION2D& region,
00699             bool bClear = true      //!< Clear the region first
00700             ) const;
00701 
00702          //! Return the LABELPLACE for a given element.
00703          //! Will return true if the label is found, false if not.
00704          bool GetLabelPlace (
00705             const RVC::ELEMENT& elem,
00706             GRE::LABELPLACE& place
00707             ) const;
00708 
00709          //! Return the LABELPLACEs for all labels for given element.
00710          //! Will return true if the label is found, false if not.
00711          bool GetLabelPlaces (
00712             const RVC::ELEMENT& elem,
00713             MILIST<GRE::LABELPLACE>& places
00714             ) const;
00715 
00716          LAYER* GetLayer (
00717             ) const;
00718 
00719          int GetNumItems (
00720             ) const;
00721 
00722          VIEW* GetView (
00723             ) const;
00724 
00725       private:
00726 
00727          //! Compare the labels for two elements.
00728          //! Function should return true if the labels are the same, false if
00729          //! not.  The optimizer may use this (based on an option flag) to
00730          //! determine if one label could be used for two elements.
00731          //! There is a default implementation which returns false, preventing
00732          //! lable combining.
00733          virtual bool v_CompareLabels (
00734             const RVC::ELEMENT& elem1,
00735             const RVC::ELEMENT& elem2
00736             ) const;
00737 
00738 #if !defined(GENERATING_DOXYGEN_OUTPUT)
00739          class PRIV;
00740          PRIV* m_priv;
00741 
00742       protected:
00743          // Used by the iterator and by SML implementation
00744          GRE::LABELPLACE* GetItem (
00745             int num
00746             );
00747       public:
00748          // Used by LABELPLACE::Move
00749          QUADTREE& GetQuadTree();
00750 
00751 #endif
00752       };
00753 
00754 
00755    }
00756 
00757 
00758 #endif // INC_GRE_LABELPLACEMENT_H
00759 

Generated on Thu Apr 26 04:03:33 2007 for TNTsdk by  doxygen 1.5.2