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

Generated on Wed May 31 15:26:39 2006 for TNTsdk by  doxygen 1.3.8-20040913