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

Generated on Tue Dec 14 13:18:12 2004 for TNTsdk by  doxygen 1.3.8-20040913