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

Generated on Thu Apr 26 04:44:40 2007 for TNTsdk by  doxygen 1.5.2