00001 /*! \file wx/canvas/canobj.h 00002 \brief The base class for all drawable objects in a a2dCanvasDocument. 00003 00004 Next to a2dCanvasObject, there are classes for filtering object ( a2dCanvasObjectFilter ) 00005 when iterating recursively through a document hierarchy. 00006 The class a2dIterC is used for holding the iteration context, 00007 which on its turn holds the drawing context when needed. 00008 00009 \author Klaas Holwerda & Robert Roebling 00010 00011 Copyright: 2000-2004 (c) Robert Roebling 00012 00013 Licence: wxWidgets Licence 00014 00015 RCS-ID: $Id: canobj.h,v 1.85 2009/07/10 19:23:13 titato Exp $ 00016 */ 00017 00018 #ifndef __WXCANOBJ_H__ 00019 #define __WXCANOBJ_H__ 00020 00021 #ifndef WX_PRECOMP 00022 #include "wx/wx.h" 00023 #endif 00024 00025 #include "wx/image.h" 00026 #include "wx/txtstrm.h" 00027 00028 #include "wx/general/genmod.h" 00029 00030 #include "wx/geometry.h" 00031 #include "wx/artbase/afmatrix.h" 00032 #include "wx/artbase/bbox.h" 00033 #include "wx/canvas/candefs.h" 00034 #include "wx/canvas/styleprop.h" 00035 #include "wx/canvas/xmlpars.h" 00036 #include "wx/canvas/restrict.h" 00037 #include "wx/canvas/hittest.h" 00038 00039 class a2dWalkerIOHandlerWithContext; 00040 00041 //---------------------------------------------------------------------------- 00042 // decls 00043 //---------------------------------------------------------------------------- 00044 00045 #if defined(WXART2D_USINGDLL) 00046 template class A2DCANVASDLLEXP a2dSmrtPtr<a2dCanvasObject>; 00047 template class A2DCANVASDLLEXP a2dSmrtPtr<a2dCanvasView>; 00048 #endif 00049 typedef a2dSmrtPtr<a2dCanvasObject> a2dCanvasObjectPtr; 00050 #if defined(WXART2D_USINGDLL) 00051 template class A2DCANVASDLLEXP a2dPropertyIdTyped<a2dCanvasObjectPtr, a2dCanvasObjectPtrProperty>; 00052 template class A2DCANVASDLLEXP a2dPropertyIdProp<a2dStyleProperty>; 00053 template class A2DCANVASDLLEXP a2dPropertyIdProp<a2dShadowStyleProperty>; 00054 template class A2DCANVASDLLEXP a2dPropertyIdTyped<a2dBoundingBox, a2dBoudingBoxProperty>; 00055 #endif 00056 typedef a2dPropertyIdTyped<a2dCanvasObjectPtr, class a2dCanvasObjectPtrProperty> a2dPropertyIdCanvasObject; 00057 typedef a2dPropertyIdProp<class a2dStyleProperty> a2dPropertyIdCanvasStyle; 00058 typedef a2dPropertyIdProp<class a2dShadowStyleProperty> a2dPropertyIdCanvasShadowStyle; 00059 typedef a2dPropertyIdTyped<a2dBoundingBox, a2dBoudingBoxProperty> a2dPropertyIdBoundingBox; 00060 00061 class A2DCANVASDLLEXP a2dPinClass; 00062 class A2DCANVASDLLEXP a2dHandle; 00063 00064 //! mask flags for a2dCanvasObject 00065 /*! 00066 \ingroup canvasobject 00067 */ 00068 typedef wxUint64 a2dCanvasObjectFlagsMask; 00069 00070 00071 //! Enum for hit test options 00072 00073 enum a2dHitOption { 00074 //! no special options 00075 a2dCANOBJHITOPTION_NONE = 0x0000, 00076 00077 //! if set, respect layer order, hit testing is done per layer from the top. 00078 a2dCANOBJHITOPTION_LAYERS = 0x0001, 00079 //! if set, don't hit test the root object or object for which IsHitWorld is called 00080 /*! 00081 This option hit tests the child objects as seen from the parent object. 00082 */ 00083 a2dCANOBJHITOPTION_NOROOT = 0x0002, 00084 00085 //! object hit should not have select flag set 00086 a2dCANOBJHITOPTION_NOTSELECTED = 0x0004, 00087 00088 //! if set, don't stop at the first hit, but test child/sibling objects anyway 00089 a2dCANOBJHITOPTION_ALL = 0x0008, 00090 }; 00091 00092 //! OR-ing a2dHitOption is allowed 00093 00094 inline a2dHitOption operator | ( a2dHitOption a, a2dHitOption b ) 00095 { 00096 return (a2dHitOption) ( (int) a | (int) b ); 00097 } 00098 00099 00100 00101 enum wxEditStyle 00102 { 00103 //! no special flags set 00104 wxEDITSTYLE_NONE = 0x0000, 00105 00106 //! edit a copy of the original object 00107 /*! There are two reasons, why you might want to edit a copy: 00108 00109 - In layered drawings, one might want to see the effect of the layering 00110 during editing (e.g. that the edited object ist partially obscured), 00111 while at the same time the outline of the object and the editing handles 00112 should be rendered on top. This behaviour is best implemented by having 00113 two objects, an editing object with handles on top and the usual object. 00114 00115 - in wxEDIT_COPY mode the editing information is transfered from the editing 00116 object to the original object using the command processor. This way the command 00117 processor is not only used for undo and redo but for all editing. This results 00118 in a more robust architecture (especially concerning undo/redo). 00119 00120 If this style is not set, the original object is edited directly. Commands 00121 are still generated for undo/redo but the original object is not changed 00122 by these commands, so undo/redo is less robust. 00123 */ 00124 wxEDITSTYLE_COPY = 0x0001, 00125 00126 //! editing is completely controlled by tools. No handles are added 00127 /*! If a master tool is used, handle editing is not realy appropriate, because 00128 the editing tool is not active and handles are not visible before the user 00129 clicks somewhere. Also master tools need fine control over editing and use 00130 tools that perform a very specific task. This can be done without handles. 00131 */ 00132 wxEDITSTYLE_NOHANDLES = 0x0002, 00133 00134 //! Clone the edit object using clone_reconnectable 00135 wxEDITSTYLE_CONNECTED = 0x0004 00136 }; 00137 00138 inline wxEditStyle operator | (wxEditStyle a, wxEditStyle b) { 00139 return (wxEditStyle) ( (int) a | (int) b ); 00140 } 00141 00142 //---------------------------------------------------------------------------- 00143 // a2dCanvasObject 00144 //---------------------------------------------------------------------------- 00145 00146 00147 //! a2dCanvasObject flags as a structure \ingroup canvasobject 00148 /*! 00149 \ingroup canvasobject 00150 */ 00151 class A2DCANVASDLLEXP a2dCanvasOFlags 00152 { 00153 00154 public: 00155 00156 //! Flags for a2dCanvasObject 00157 /*! 00158 Those flags or used in mask for set flag inside a a2dCanvasObject or 00159 to get the value of a flag. 00160 00161 \sa a2dCanvasObject_FlagsS 00162 \sa a2dCanvasObjectFlagsMask 00163 00164 \ingroup canvasobject 00165 */ 00166 static const a2dCanvasObjectFlagsMask NON ; /*!< No flags */ 00167 static const a2dCanvasObjectFlagsMask SELECTED ; /*!< object is selected */ 00168 static const a2dCanvasObjectFlagsMask SELECTABLE ; /*!< can select object */ 00169 static const a2dCanvasObjectFlagsMask HasSelectedObjectsBelow ; /*!< selected objects detected below */ 00170 static const a2dCanvasObjectFlagsMask SubEdit ; /*!< allow subedit of children within this object */ 00171 static const a2dCanvasObjectFlagsMask SubEditAsChild ; /*!< allow subedit on this object when child of other object */ 00172 static const a2dCanvasObjectFlagsMask VISIBLE ; /*!< is the object visible (overruled by parent object in some cases during rendering */ 00173 static const a2dCanvasObjectFlagsMask DRAGGABLE ; /*!< can be dragged */ 00174 static const a2dCanvasObjectFlagsMask SHOWSHADOW ; /*!< show shadow object if true and shadow property is available */ 00175 static const a2dCanvasObjectFlagsMask FILLED ; /*!< use fill to fill if set */ 00176 static const a2dCanvasObjectFlagsMask A ; /*!< group A flag (e.g boolean operations) */ 00177 static const a2dCanvasObjectFlagsMask B ; /*!< group B flag (e.g boolean operations) */ 00178 static const a2dCanvasObjectFlagsMask BIN ; /*!< general flag ( used for temporarely marking object ) */ 00179 static const a2dCanvasObjectFlagsMask BIN2 ; /*!< general flag ( used for temporarely marking object ) */ 00180 static const a2dCanvasObjectFlagsMask PENDING ; /*!< set when a2dCanvasObject needs an update (redraw) */ 00181 static const a2dCanvasObjectFlagsMask SNAP ; /*!< snapping of editable object or when moving */ 00182 static const a2dCanvasObjectFlagsMask SNAP_TO ; /*!< snapping of other object to this when in place*/ 00183 static const a2dCanvasObjectFlagsMask PUSHIN ; /*!< push into allowed */ 00184 static const a2dCanvasObjectFlagsMask PRERENDERASCHILD ; /*!< as child this object will be rendered before the parent object itself when true (default) */ 00185 static const a2dCanvasObjectFlagsMask VISIBLECHILDS ; /*!< child objects are visible or not */ 00186 static const a2dCanvasObjectFlagsMask EDITABLE ; /*!< object can be edited */ 00187 static const a2dCanvasObjectFlagsMask ChildrenOnSameLayer; /*!< child objects are rendered when the object is rendered itself. 00188 The effect is that the children will appear on the same layer as the object. */ 00189 static const a2dCanvasObjectFlagsMask DoConnect ; /*!< in case of pins on the object is it currely allowed for other object to connect to it? */ 00190 static const a2dCanvasObjectFlagsMask IsOnCorridorPath ; /*!< this object is on the corridor path to a captured object */ 00191 static const a2dCanvasObjectFlagsMask HasPins ; /*!< true if this object does have a2dPin's as children */ 00192 static const a2dCanvasObjectFlagsMask Editing ; /*!< true if the object is currently being edited */ 00193 static const a2dCanvasObjectFlagsMask EditingCopy ; /*!< true if the object needs is the editcopy of an object that is edited. */ 00194 static const a2dCanvasObjectFlagsMask IsProperty ; /*!< True if object is a property show object */ 00195 static const a2dCanvasObjectFlagsMask MouseInObject ; /*!< true is mouse is currently within object */ 00196 static const a2dCanvasObjectFlagsMask HighLight ; /*!< true is object is highlighted */ 00197 static const a2dCanvasObjectFlagsMask Notused ; /*!< not used for the moment */ 00198 static const a2dCanvasObjectFlagsMask ignoreSetpending ; /*!< ignore Setpending calls on a2dCanvasObject */ 00199 static const a2dCanvasObjectFlagsMask HasToolObjectsBelow ; /*!< special tool object detected below */ 00200 static const a2dCanvasObjectFlagsMask ChildOnlyTranslate ; /*!< do not tranfrom only translate. */ 00201 static const a2dCanvasObjectFlagsMask ignoreLayer ; /*!< ignore Layer id, just render always*/ 00202 static const a2dCanvasObjectFlagsMask generatePins ; /*!< generate Pins when asked for */ 00203 static const a2dCanvasObjectFlagsMask normalized ; /*!< normalized coordinates */ 00204 static const a2dCanvasObjectFlagsMask NoRenderCanvasObject ; /*!< do not render if no children */ 00205 static const a2dCanvasObjectFlagsMask ALL ; /*!< To set all flags at once */ 00206 00207 a2dCanvasOFlags( a2dCanvasObjectFlagsMask newmask = NON ); 00208 00209 void SetSpecificFlags( bool setOrClear, a2dCanvasObjectFlagsMask which ); 00210 00211 a2dCanvasObjectFlagsMask GetFlags() const; 00212 00213 void SetFlags( a2dCanvasObjectFlagsMask which ); 00214 00215 bool GetFlag( a2dCanvasObjectFlagsMask which ) const; 00216 00217 bool CheckMask( a2dCanvasObjectFlagsMask mask) const; 00218 00219 //!object is selected 00220 bool m_selected:1; 00221 00222 //!can select object 00223 bool m_selectable:1; 00224 00225 //!allow subedit of children within this object 00226 bool m_subEdit:1; 00227 00228 //!allow subedit on this object when child of other object 00229 bool m_subEditAsChild:1; 00230 00231 //!is the object visible (overruled by paranet object in some cases during rendering 00232 bool m_visible:1; 00233 00234 //!can be dragged 00235 bool m_draggable:1; 00236 00237 //!show shadow object if true and shadow property is available 00238 bool m_showshadow:1; 00239 00240 //!use fill to fill if set 00241 bool m_filled:1; 00242 00243 //!group A flag (e.g boolean operations) 00244 bool m_a:1; 00245 00246 //!group B flag (e.g boolean operations) 00247 bool m_b:1; 00248 00249 //! generate pins if true 00250 bool m_generatePins:1; 00251 00252 //!general flag ( used for temporarely marking object ) 00253 bool m_bin:1; 00254 00255 //!general flag ( used for temporarely marking object ) 00256 bool m_bin2:1; 00257 00258 //! set when a2dCanvasObject needs an update (redraw). 00259 bool m_pending:1; 00260 00261 //!snapping of editable object or when moving 00262 bool m_snap:1; 00263 00264 //!snapping of other objects to this when in place 00265 bool m_snap_to:1; 00266 00267 //! is push into allowed 00268 bool m_pushin; 00269 00270 //!as child this object will be rendered before the parent object itself when true (default) 00271 bool m_prerenderaschild:1; 00272 00273 //! child objects are visible or not 00274 bool m_visiblechilds:1; 00275 00276 //! object can be edited 00277 bool m_editable:1; 00278 00279 //! true if the object is currently being edited 00280 bool m_editing:1; 00281 00282 //! true if the object needs to be rendered in edit mode. 00283 bool m_editingCopy:1; 00284 00285 //! ignore this object in a2dCanvasObject::SetPending() 00286 bool m_ignoreSetpending:1; 00287 00288 //! child objects are rendered when the object is rendered itself. 00289 //! The effect is that the children will appear on the same layer as the object. 00290 bool m_childrenOnSameLayer:1; 00291 00292 //! in case of pins on the object is it currely allowed for other object to connect to it? 00293 bool m_doConnect:1; 00294 00295 //! This object is on the corridor path to a captured object or to a corridored object. 00296 /*! 00297 When an object is captured, it and its parent, grandparent etc. objects get this flag set. 00298 */ 00299 bool m_isOnCorridorPath:1; 00300 00301 //! true if this object does have a2dPin's as children 00302 bool m_hasPins:1; 00303 00304 bool m_IsProperty:1; 00305 00306 bool m_MouseInObject:1; 00307 00308 bool m_HighLight:1; 00309 00310 bool m_ChildOnlyTranslate:1; 00311 00312 //! when this is set DoRender() is called even if layer of the object is not the layer to be rendered. 00313 bool m_ignoreLayer:1; 00314 00315 //! GDSII format flag 00316 bool m_template:1 ; 00317 00318 //! GDSII format flag 00319 bool m_external :1 ; 00320 00321 //! GDSII format flag 00322 bool m_used :1 ; 00323 00324 //! special tool object detected below 00325 bool m_HasToolObjectsBelow :1 ; 00326 00327 //! true is the object is a a2dCanvasObject (or derived ) without rendering something if there or now children. 00328 bool m_NoRenderCanvasObject :1 ; 00329 00330 //! selected objects detected below 00331 bool m_HasSelectedObjectsBelow :1 ; 00332 00333 //! when true, the wxEVT_CANVASOBJECT_RESIZE_EVENT is sent to this object, if the child box did change. 00334 bool m_resizeToChilds :1 ; 00335 00336 //! true if the object is defined in normalized coordinates 00337 bool m_normalized:1; 00338 00339 }; 00340 00341 //! event mask flags for a2dCanvasObject hit 00342 /*! a2dCanvasObjectHitFlags used in a mask for defining how an object should be hit 00343 00344 \ingroup canvasobject 00345 00346 */ 00347 enum a2dCanvasObjectHitFlags 00348 { 00349 a2dCANOBJ_EVENT_NON=0x0001, //!< no hit will be reported 00350 a2dCANOBJ_EVENT_FILL=0x0002, //!< hit if filled 00351 a2dCANOBJ_EVENT_STROKE=0x0004, //!< hit if stroked 00352 a2dCANOBJ_EVENT_FILL_NON_TRANSPARENT=0x0008, //!< hit if filling is not transparent 00353 a2dCANOBJ_EVENT_STROKE_NON_TRANSPARENT=0x0010, //!< hit if stroke is not transparent 00354 a2dCANOBJ_EVENT_VISIBLE=0x0020, //!< hit if visible 00355 a2dCANOBJ_EVENT_ALL=0x0040 //!< always hit 00356 }; 00357 00358 //! flags for searching a connecting a2dpinClass, for the connecting task at hand. 00359 /*! 00360 The format is: 00361 00362 a2d_PinClassWanted_ForPinClassGiven_DirectionFlags 00363 00364 ObjectPinClass is the object to which we want to connect 00365 ToConnectPinClass is pinclass from where we want to connect to an object 00366 00367 */ 00368 enum a2dConnectTask 00369 { 00370 a2d_ToConnectPinClassWire_ObjectPinClass_In, //!< find wire/connect pinclass, given Normal Object In pinclass 00371 a2d_ToConnectPinClassWire_ObjectPinClass_Out, //!< find wire/connect pinclass, given Normal Object Out pinclass 00372 a2d_ToConnectPinClassWire_ObjectPinClass_InOut, //!< find wire/connect pinclass, given Normal Object In pinclass 00373 00374 a2d_ObjectPinClass_ToConnectPinClassWire_In, //!< find normal object pinclass, given Connect/wire pinclass In 00375 a2d_ObjectPinClass_ToConnectPinClassWire_Out, //!< find normal object pinclass, given Connect/wire pinclass Out 00376 a2d_ObjectPinClass_ToConnectPinClassWire_InOut, //!< find normal object pinclass, given Connect/wire pinclass In/Out 00377 00378 a2d_ToConnectPinClassObject_ObjectPinClass_In, //!< find pinclass, given Normal Object In pinclass 00379 a2d_ToConnectPinClassObject_ObjectPinClass_Out, //!< find pinclass, given Normal Object Out pinclass 00380 a2d_ToConnectPinClassObject_ObjectPinClass_InOut, //!< find pinclass, given Normal Object In/Out pinclass 00381 00382 a2d_ObjectPinClass_ToConnectPinClassObject_In, //!< find normal object pinclass, given Normal Object In pinclass 00383 a2d_ObjectPinClass_ToConnectPinClassObject_Out, //!< find normal object pinclass, given Normal Object Out pinclass 00384 a2d_ObjectPinClass_ToConnectPinClassObject_InOut, //!< find normal object pinclass, given Normal Object In/Out pinclass 00385 }; 00386 00387 //! a2dCanvasObject hit flags as a structure \ingroup canvasobject 00388 /*! a2dCanvasOHitFlags is used as mask for defining how an object should be hit 00389 */ 00390 struct a2dCanvasOHitFlags 00391 { 00392 //!no events 00393 bool m_non:1; 00394 //! only when over filled area of object 00395 bool m_fill:1; 00396 //! only when over stroked area of object 00397 bool m_stroke:1; 00398 //! only when non transparent fill 00399 bool m_fill_non_transparent:1; 00400 //! only when non transparent stroke 00401 bool m_stroke_non_transparent:1; 00402 //! only when visible 00403 bool m_visible:1; 00404 //!all events 00405 bool m_all:1; 00406 00407 }; 00408 00409 //! This is one hit result from a2dExtendedResult 00410 class A2DCANVASDLLEXP a2dExtendedResultItem 00411 { 00412 public: 00413 //! Default Constructor 00414 a2dExtendedResultItem() {} 00415 //! Standard Constructor 00416 a2dExtendedResultItem( a2dCanvasObject *object, a2dCanvasObject *parent, a2dHit type, int level, int typeex ) 00417 { 00418 m_object = object; 00419 m_parent = parent; 00420 m_type = type; 00421 m_level = level; 00422 m_typeex = typeex; 00423 } 00424 //! the hit object 00425 class a2dCanvasObject *GetObject() { return m_object; }; 00426 //! the parent object of the hit object 00427 class a2dCanvasObject *GetParent() { return m_parent; }; 00428 //! type of the hit 00429 const a2dHit &GetHitType() { return m_type; } 00430 //! level of the hit object below the start (root) object 00431 int GetLevel() { return m_level; } 00432 00433 protected: 00434 friend class a2dExtendedResult; 00435 //! the hit object 00436 a2dCanvasObject *m_object; 00437 //! the parent object of the hit object 00438 a2dCanvasObject *m_parent; 00439 //! type of the hit 00440 a2dHit m_type; 00441 //! level of the hit object below the start (root) object 00442 /*! note: the extended result can contain multiple hits on the same level */ 00443 int m_level; 00444 //! Extended hit type 00445 /*! This is generally class specific. 00446 Derived classes must include the IDs for the base class. 00447 a2dCanvasObject does not define extended hit IDs. 00448 */ 00449 int m_typeex; 00450 }; 00451 00452 //! An object of this class represents the context of a query like a hit test 00453 /*! This is similar to a2dIterC, but it is not used for iteration, but for 00454 return values. 00455 */ 00456 class A2DCANVASDLLEXP a2dExtendedResult: public std::vector<a2dExtendedResultItem> 00457 { 00458 public: 00459 //! Default constructor 00460 a2dExtendedResult(); 00461 //! Destructor 00462 ~a2dExtendedResult(); 00463 }; 00464 00465 //! structure to give as parameter to member functions of wxCanvasObject 00466 /*! 00467 During event processing and hittesting in a a2dCanvasView and a2dCanvasDocument, this 00468 structure is used to give and assemble information while traversing the document. 00469 */ 00470 class a2dHitEvent 00471 { 00472 00473 public: 00474 00475 a2dHitEvent( double absx = 0, double absy = 0, bool continues = true, 00476 a2dHitOption option = a2dCANOBJHITOPTION_NONE, bool wantExtended = false ) 00477 { 00478 m_option = option; 00479 m_maxlevel = INT_MAX; 00480 m_relx = 0; 00481 m_rely = 0; 00482 m_x = absx; 00483 m_y = absy; 00484 m_processed = false; 00485 m_continue = continues; 00486 m_isHit = false; 00487 m_how = a2dHit::stock_nohit; 00488 m_id = 0; 00489 m_extendedWanted = wantExtended; 00490 m_xyRelToChildren = false; 00491 m_event = NULL; 00492 } 00493 00494 void SetProcessed( bool val ) 00495 { 00496 #ifdef _DEBUG 00497 if ( val ) 00498 m_processed = true; 00499 else 00500 m_processed = false; 00501 #else 00502 m_processed = val; 00503 #endif 00504 } 00505 00506 //! (world coordinates) hit point x relative to the canvas object its parent object(s) 00507 double m_relx; 00508 //! (world coordinates) hit point y relative to the canvas object its parent object(s) 00509 double m_rely; 00510 //! (world coordinates) hit point x as in a2dCanvasView or any other top level 00511 double m_x; 00512 //! (world coordinates) hit point y as in a2dCanvasView or any other top level 00513 double m_y; 00514 //! is set, m_x and m_y are supplied relative to the child objects ( object matrix m_world already applied ) 00515 bool m_xyRelToChildren; 00516 //! the way to hit/traverse the document. 00517 wxUint32 m_option; 00518 //! return in which way the object was hit (stroke, fill, ...) 00519 a2dHit m_how; 00520 //! extended result information with e.g path to lead to the nested object hit 00521 a2dExtendedResult m_extended; 00522 //! fill m_extended or not 00523 bool m_extendedWanted; 00524 //! maximum level of hit object below this (this = level 0) 00525 int m_maxlevel; 00526 //! event to process in case of event processing call 00527 wxEvent* m_event; 00528 //! set if event was processed sofar 00529 bool m_processed; 00530 //! set if the event processing or hittest needs to continue after first hit 00531 bool m_continue; 00532 //! in the end if there was a hit (even if not processed event) 00533 bool m_isHit; 00534 //! application specific use 00535 int m_id; 00536 }; 00537 00538 00539 //! when a new wire or other connection object needs to be created, 00540 /*! this class or a derived one, will deliver the right connection object. 00541 In other situations it will tell which objects are connectable on two pins, and the wire needed for that. 00542 00543 The idea is that objects do not only decide themselfs if they can connect to other objects and which. 00544 Instead this job is centralized to this class. Because of that an object does not need to know himself 00545 to which objects it can connect, and what wire to use for that. The a2dConnectionGenerator knows which objects 00546 can connect to others. Actualy in the default situation it is not the object which decides, 00547 but the pinclass of a pin is the input for the a2dConnectionGenerator. So one asks the a2dConnectionGenerator 00548 if a pinclass of a pin on a certain object, can connect to something else. 00549 00550 This class here can restrict what is the default way of allowing connections, or implement its own rules. 00551 When you want to limit the possible connection you can switch to a derived a2dConnectionGenerator. 00552 An a2dConnectionGenerator is shared by a set of a2dPinClass Objects, and this is how one finds the 00553 a2dConnectionGenerator for a connection task at hand. 00554 00555 As an example of a derived a2dConnectionGenerator: 00556 if you want to limit a wire tool to only draw lines from objects which have pins 00557 of a specific pin class, overriding GeneratePossibleConnections() can do the job. 00558 00559 a2dPinClass itself has information on hich other a2dPinClass it may connect to, and two 00560 pin classes can only connect if they both agree. 00561 a2dPinClass even knows which type of wire/connect object is required hen this pinclass is meant for 00562 being on a wire its pin. 00563 So when starting a new wire, at a certain pin, the object and wire its a2dPinClass must be able 00564 to connect to one another. A wiretool is only able to connect two pins of objects if 00565 the pinclasses in its connect lists are compatible, meaning the one pin contains the other as connectable. 00566 If the pin is oke, the found PinClassMap defines what type of wire needs to be created now. 00567 This information is stored in the a2dPinClass, as a template wire/connect object. 00568 The tool therefore is able to generate a2dCanvasObject connections ( e.g. a2dWirePolylineL wires ) 00569 of different types, and which type is created depends on the pin that is hit when starting a wire. 00570 00571 In the above one object was normal and the connecting object was a wire. Another situation is when two normal objects 00572 are dragged appart and a wire needs to be created in between. Again pinclasses of the two a2dPin's that will be 00573 disconnected will be searched in its connect lists, for a wire pincclass, which can connect to both pins. 00574 When a wire pinclass is found which can connect to both pins, the type of wire will be created via that same 00575 pinclass its template object for a wire. This is achieved CreateConnectObject(). 00576 00577 To understand the principle, imagine 3 a2dCanvasObject's with pins which have Pin classes. 00578 - one with a2dPinClass A 00579 - the second with a2dPinClass B 00580 - the third with a2dPinClass C 00581 Now when A connects to B we want a wire of type X, if A connects to C, we want wire Y, 00582 at last when C connects to B we want wire Z. 00583 On top of this the direction of the connection can be defined, A to C can be different from C to A. 00584 The information on which pin can connect to which other pin, is stored in the a2dPinClass of the a2dPin. 00585 Here one can find which other a2dPinClass object can connect to this one, and if it is for a wire, a template object 00586 to create that wire. 00587 00588 If more B objects are connected to an A object, via multiple wires, the connection of wires to wires must be defined too 00589 To conclude we are not only defining the relations between A-B-C, but also the wire begin and end relations towards eachother. 00590 In our case here, we create wires which are extensions of the pin where they are connected to, meaning the end pin of the wire 00591 is the same as the pinclass to which the begin pin is connected. 00592 All this to connect one object pin with pinclass to other objects at a pin with a certain pin class. 00593 If we define 3 pinclasses for pins on the object A,B,C and three extra pinclasses WA WB WC for wire between those objects, 00594 we get the following connection tables. 00595 00596 For the pinclasses which can be connected to each other: 00597 00598 - (A-PinClass) -> (B-PinClass) (C-PinClass) (WB-PinClass) (WC-PinClass) 00599 - (B-PinClass) -> (A-PinClass) (C-PinClass) (WA-PinClass) (WC-PinClass) 00600 - (C-PinClass) -> (A-PinClass) (B-PinClass) (WA-PinClass) (WB-PinClass) 00601 00602 We get for wires which start at A or C: 00603 00604 - (A-PinClass) -> (WB-PinClass) Wire X (WA-PinClass) -> (B-PinClass) 00605 - (A-PinClass) -> (WC-PinClass) Wire Y (WA-PinClass) -> (C-PinClass) 00606 - (C-PinClass) -> (WB-PinClass) Wire Z (WC-PinClass) -> (B-PinClass) 00607 00608 And if bidirectional wires which start at B or C: 00609 00610 - (B-PinClass) -> (WA-PinClass) Wire X (WB-PinClass) -> (A-PinClass) 00611 - (C-PinClass) -> (WA-PinClass) Wire Y (WC-PinClass) -> (A-PinClass) 00612 - (B-PinClass) -> (WC-PinClass) Wire Z (WB-PinClass) -> (C-PinClass) 00613 00614 Interesting in this table is that one can not start a wire on an object, whithout knowing its type, since always two are possible. 00615 So a wire tool needs to define for which pinclass a wire is needed, before asking this a2dConnectionGenerator to tell if 00616 the object is oke with that. Another option is to start a wire on a starting pin, and only when finishing the wire decide what 00617 type of wire is really needed for the begin and end pin of the wire. 00618 It is best to give wire ohter pinclasses then normal objects, since that makes it easier to know if one can start a wire 00619 on a certain pin, and what type of wire it needs to be. 00620 00621 As an example, drawing a wire using a tool. 00622 If the user clicks on an object type pin, the corresponding pin 00623 in the newly created wire will be a Non object type pin. 00624 00625 At last in the above, there were three objects, but in fact they are of no interest, since the pins its pinclasses define all. 00626 This way it is possible to define several "flows" in a group of objects. E.g. You can define in and output pinclasses for each 00627 flow you require. Multiple flow pins can be added to the same object, connecting a set of flow pins by one type of wire. 00628 You end up with several flows within a group of objects ( control flow - data flow ). 00629 00630 */ 00631 class A2DCANVASDLLEXP a2dConnectionGenerator : public a2dObject 00632 { 00633 00634 00635 public: 00636 00637 //! constructor 00638 a2dConnectionGenerator(); 00639 //! destructor 00640 ~a2dConnectionGenerator(); 00641 00642 //! create connection object based on two pins which need to be connected. 00643 /*! 00644 Called from the default a2dCanvasObject::CreateConnectObject(), in order to easily change the behaviour 00645 of standard objects concerning possible connections. 00646 The returned object is a (connection) object (e.g. a2dWirePolylineL ), with correct pins at the 00647 position of pinThis and pinOther. The pins are connected already. 00648 When undo is true, the right commands are sent to the document its command processor. 00649 In general this means those commands are part of a group of commands in a a2dCommandGroup, 00650 which internal resulted in a connection being created. For example as a result of dragging an object. 00651 */ 00652 virtual a2dCanvasObject* CreateConnectObject( a2dCanvasObject* parent, a2dPin* pinThis, a2dPin* pinOther, bool undo = false ) const; 00653 00654 //! create connection object based on two pin classes, which (may) need to be connected. 00655 virtual a2dCanvasObject* GetConnectTemplate( const a2dCanvasObject* object, a2dPinClass* mapObject, const a2dCanvasObject* other, a2dPinClass* mapOther ) const; 00656 00657 //! generate temporary pins to which objects can connect 00658 /*! 00659 When drawing wires object, other object are asked to display pin possition, 00660 to which the wire may connect. See a2dCanvasObject::GeneratePinsPossibleConnections(). This process is called by the tools, 00661 and is called editing Feedback. The pins created are only temporary, and will be removed at the end of a tool its busy cycle. 00662 00663 The default implementation uses pinClass->GetConnectionGenerator() 00664 to ask this object to generate a pin in a2dCanvasObject::GeneratePins(). The reason for this, is that there may be more involved 00665 to allow a pin to connect. Like the pin class. 00666 00667 \param object The object on which to create temporary pins 00668 \param pinClass The pinclass to which the generated pins must be able to connect, if NULL any pinclass 00669 \param task for what purpose is the connection needed 00670 \param x only connect at this position 00671 \param y only connect at this position 00672 00673 */ 00674 virtual bool GeneratePossibleConnections( a2dCanvasObject* object, a2dPinClass* pinClass, a2dConnectTask task, double x, double y ) const; 00675 00676 //! return a a2dPinClass which should be used to connect to the input a2dPinClass. 00677 /*! 00678 The connection generator searches for a possible connection to the input a2dPinClass in combination 00679 with the canvasobject obj if needed. 00680 00681 \param pinClass pin class for which to search a connecting PinClass 00682 \param task for what purpose is the connection needed 00683 \param obj object for which pins are checked / needed. 00684 00685 \return If a a2dPinClass is not found NULL is returned. 00686 */ 00687 virtual a2dPinClass* GetPinClassForTask( a2dPinClass* pinClass, a2dConnectTask task, a2dCanvasObject* obj ) const; 00688 00689 //! return the pin class for GetPinClassForTask( a2dPinClass::Any ) 00690 /*! 00691 Basic object can generate pins by a2dPinclass, but i8n case of a2dPinClass::Any 00692 it will generate pins of this pinclass. 00693 */ 00694 a2dPinClass *GetAnyPinClass() const { return m_anypinclass; } 00695 00696 //! see GetAnyPinClass() 00697 void SetAnyPinClass( a2dPinClass* pinClass ) { m_anypinclass = pinClass; } 00698 00699 //! when a wire was created, this return the direction is was created ( first to last pin or visa versa ). 00700 bool GetLastConnectCreationDirection() const { return m_reverseCreate; } 00701 00702 protected: 00703 00704 //! template pinclass 00705 a2dPinClass* m_anypinclass; 00706 00707 //! how to create a connection 00708 mutable bool m_reverseCreate; 00709 00710 //! Some stuff needed by the ref counting base class 00711 virtual a2dObject* Clone( CloneOptions WXUNUSED(options) ) const { wxASSERT(0); return 0; } 00712 00713 private: 00714 00715 #if wxART2D_USE_CVGIO 00716 virtual void DoSave( wxObject* WXUNUSED(parent), a2dIOHandlerXmlSerOut &WXUNUSED(out), a2dXmlSer_flag WXUNUSED(xmlparts), a2dObjectList* WXUNUSED(towrite) ) { wxASSERT(0); } 00717 virtual void DoLoad( wxObject* WXUNUSED(parent), a2dIOHandlerXmlSerIn& WXUNUSED(parser), a2dXmlSer_flag WXUNUSED(xmlparts) ) { wxASSERT(0); } 00718 #endif //wxART2D_USE_CVGIO 00719 00720 }; 00721 00722 //! Smart pointer type for a2dConnectionGenerator 00723 template class A2DCANVASDLLEXP a2dSmrtPtr<a2dConnectionGenerator>; 00724 typedef a2dSmrtPtr<a2dConnectionGenerator> a2dConnectionGeneratorPtr; 00725 00726 //!a2dCanvasObject is the base class for Canvas Objects. 00727 /*! 00728 All objects for drawing on the a2dCanvas are derived from this class. 00729 A a2dCanvasDocument is filled with instances of this object. 00730 a2dCanvasObject can have children, which are also a2dCanvasObjects. 00731 A a2dCanvasObject itself can be a child of more than one parent a2dCanvasObject. 00732 The reference counter takes care of deleting the object when all references are released. 00733 00734 Child objects are stored in a2dCanvasObjectList m_childobjects, which is only created 00735 when the first child is added to the a2dCanvasObject. Else it points to wxNullCanvasObjectList. 00736 00737 Each a2dCanvasObject can also have a list of a2dObject objects. 00738 They are stored in the a2dObjectList m_properties. 00739 00740 Asking for the GetCount() of the above two lists, is save, since wxNullCanvasObjectList 00741 will return 0. 00742 00743 Traversing a a2dCanvasDocument is mainly by traversing of the child list of each a2dCanvasObject in the 00744 document in a recursive manner. 00745 Many functions in a2dCanvasObject need to traverse the document, therefore there is often a DoSomething 00746 function called from the base a2dCanvasObject, in order to do the object specific job while 00747 traversing the document. 00748 00749 Rendering of a2dCanvasObject's is via the base Render function, which takes care 00750 of rendering child objects. It also does the clipping of objects to the area to be drawn. 00751 First it searches for style properties in the property list, if found they will be used 00752 to set the drawing style of the active a2dCanvasView which is used to draw on a device. 00753 If no style properties are available, the layer settings are used to set the style of the a2dCanvasView. 00754 Next to style properties, there can be other properties which influence the rendering of the object 00755 in general; e.g. the a2dClipPathProperty, is pushed into the a2dCanvasView to clip the child objects. 00756 After setting the style the rendering can start. First the children which have the flag 00757 m_prerenderaschild set are rendered. Next the a2dCanvasObject derived object itself is rendered 00758 via the virtual DoRender() method. After that the rest of the child objects are rendered. 00759 In the end visible properties are rendered, via their a2dCanvasObject, which they may use for displaying 00760 themselfs. 00761 00762 It is possible to intercept mouse event on a a2dCanvasObject. 00763 a2dCanvasObject's receive there events after a hit of the mouse pointer was detected 00764 from within a a2dCanvasView or a2dCanvas object. 00765 The lowest object seen from the a2dCanvasView::ShowObject() receives the events first, and if skipped there 00766 and no othere child proesses the event, its parent will get the event etc. 00767 00768 \remark When a style (fill or stroke) is set it will be used instead of the layer fill and stroke 00769 \remark fill style is inherited by children 00770 00771 \ingroup canvasobject 00772 */ 00773 class A2DCANVASDLLEXP a2dCanvasObject: public a2dEvtHandler 00774 { 00775 00776 public: 00777 00778 friend class a2dCanvasObjectFilter; 00779 friend class a2dCanvasObjectFilterLayerMask; 00780 friend class a2dCanvasObjectFilterLayerMaskNoToolNoEdit; 00781 00782 //! used to tell which child object to render and to detect the need for it. 00783 struct RenderChild 00784 { 00785 bool m_prerender:1; /*!< object marked for pre rendering ( before the parent ) */ 00786 bool m_postrender:1; /*!< object marked for post rendering ( after the parent ) */ 00787 bool m_property:1; /*!< object marked for property rendering */ 00788 }; 00789 00790 00791 A2D_DECLARE_EVENT_TABLE() 00792 00793 //****************** CONSTRUCTION AND REF COUNTING ******************/ 00794 /*! \name Construction and reference counting 00795 */ 00796 //\{ 00797 00798 DECLARE_DYNAMIC_CLASS(a2dCanvasObject) 00799 00800 //!constructor called by derived objects 00801 a2dCanvasObject( double x = 0 , double y = 0); 00802 00803 //!constructor using reference to existing canvas object 00804 a2dCanvasObject( const a2dCanvasObject &other, CloneOptions options ); 00805 00806 //!Clone this object and return a pointer to the new object 00807 virtual a2dObject* Clone( CloneOptions options ) const; 00808 00809 inline a2dCanvasObject* TClone( CloneOptions options ) { return (a2dCanvasObject*) Clone( options ); } 00810 00811 //!destructor called by derived objects 00812 virtual ~a2dCanvasObject(); 00813 00814 //! returns if this object does have nested objects 00815 /*! 00816 If the object has children it is nested, but if not it can still have nested objects. This is when 00817 a derived a2dCanvasObject does have a2dCanvasObject's members itself. 00818 This function should return true if an object does have nested children or members. 00819 */ 00820 virtual bool IsRecursive(); 00821 00822 //! All direct a2dCanvasObject which are part of this one are made unique 00823 /*! 00824 The base implementation check all child objects in m_childobjects for being more then single referenced. 00825 If not a clone is created in put in place of the one there, leving the origenal to the other objects 00826 which owned that child too. 00827 Derived a2dCanvasObject must implement this, if it has members which can be multiple referenced. 00828 */ 00829 virtual void MakeReferencesUnique(); 00830 00831 00832 //\} 00833 //**************** END CONSTRUCTION AND REF COUNTING ****************/ 00834 00835 //****************** AFFINE TRANSFORMATION ******************/ 00836 /*! \name Affine Transformation 00837 Each a2dCanvasObject has an affine Transformation to translate, rotate, scale, 00838 and skew it. The Transformations are mutiplied with the transformations of 00839 all parent objects up the show object of teh current view. 00840 */ 00841 //\{ 00842 public: 00843 00844 //!Rotates this object clockwise 00845 /*! 00846 Rotates this object clockwise: If you call <code>Rotate(20); Rotate(10);</code> the 00847 absolute rotation will be 30 degrees (if initially rotation was 0 degrees) 00848 \see a2dAffineMatrix::Rotate 00849 \see SetRotation 00850 00851 \param rotation rotate by this angle in degrees 00852 */ 00853 void Rotate(double rotation); 00854 00855 //!Sets a rotation of this object 00856 /*! 00857 Sets in opposite to Rotate the absolute rotation of this object. 00858 \see a2dAffineMatrix::SetRotation 00859 \see Rotate 00860 00861 \param rotation set rotation angle in degrees 00862 */ 00863 void SetRotation(double rotation); 00864 00865 //! Scale in x and y ( > zero) 00866 /*! 00867 \param scalex scalling in X 00868 \param scaley scalling in Y 00869 */ 00870 void Scale( double scalex, double scaley ); 00871 00872 //!Mirrors this object in x or y orientation 00873 /*! 00874 \param x mirror at X-axis (horizontally orientation) 00875 \param y mirror at Y-axis (vertically orientation) 00876 */ 00877 void Mirror(bool x=true, bool y=false); 00878 00879 //! Skew in X 00880 /*! 00881 \param angle angle to skew in X 00882 */ 00883 void SkewX( double angle ); 00884 00885 //! Skew in Y 00886 /*! 00887 \param angle angle to skew in Y 00888 */ 00889 void SkewY( double angle ); 00890 00891 //!get the matrix used to position the object 00892 const a2dAffineMatrix& GetTransformMatrix() const { return m_lworld; } 00893 00894 a2dAffineMatrix GetTransform() const { return m_lworld; } 00895 void SetTransform( a2dAffineMatrix mat = a2dIDENTITY_MATRIX ){ m_lworld = mat; SetPending(true); } 00896 00897 //! Returns the matrix used to position the object 00898 /*! 00899 \param mat matrix set for transforming the object 00900 */ 00901 void SetTransformMatrix(const a2dAffineMatrix& mat = a2dIDENTITY_MATRIX ){ m_lworld = mat; SetPending(true); } 00902 00903 //!Sets the matrix used to position the object 00904 /*! 00905 A new matrix will be constructed for transforming this object. 00906 00907 \see SetTransformMatrix 00908 \see a2dAffineMatrix::a2dAffineMatrix 00909 00910 \param xt x translation 00911 \param yt y translation 00912 \param scalex x scale factor 00913 \param scaley y scale factor 00914 \param degrees rotation in degrees 00915 */ 00916 void SetTransformMatrix( double xt, double yt, double scalex = 1, double scaley = 1, double degrees = 0 ); 00917 00918 //!get x position from affine matrix 00919 double GetPosX() const { return m_lworld.GetValue(2,0); } 00920 00921 //!get y position from affine matrix 00922 double GetPosY() const { return m_lworld.GetValue(2,1); } 00923 00924 //!get position of object 00925 a2dPoint2D GetPosXY() const { return a2dPoint2D( m_lworld.GetValue(2,0), m_lworld.GetValue(2,1) ); } 00926 00927 //!set position to x,y 00928 /*! translation is set to x,y, rest of the affine matrix is preserved. 00929 \param x x position 00930 \param y y position 00931 \param restrict use a2dCanvasGlobals->GetRestrictionEngine() to snap position 00932 */ 00933 void SetPosXY( double x, double y, bool restrict = false ); 00934 00935 //!set position to x,y 00936 /*! translation is set to x,y, rest of the affine matrix is preserved. 00937 \param pos position 00938 */ 00939 void SetPosXyPoint( const a2dPoint2D &pos ) 00940 { 00941 SetPosXY( pos.m_x, pos.m_y, false ); 00942 } 00943 00944 //!set position to x,y but restricted, returns new values 00945 /*! translation is set to x,y, rest of the affine matrix is preserved. 00946 00947 Same as SetPoXY(), but returneing restricted values 00948 00949 \param x x position 00950 \param y y position 00951 \return true of point was restricted/changed 00952 */ 00953 bool SetPosXYRestrict( double& x, double& y ); 00954 00955 //!relative translate the object to position x,y in world coordinates 00956 /*! this function may be defined for each derived object, to move other object with this object. 00957 it is used internally for dragging and moving objects. 00958 \param x delta x for translation 00959 \param y delta y for translation 00960 */ 00961 void Translate( double x, double y ) { m_lworld.Translate(x,y); SetPending(true); } 00962 00963 //!transform the object using the given matrix 00964 /*!If the object can not rotate or scale those will be ignored 00965 and only translation will take place. 00966 If totally transformed it will return true else false. 00967 \param tworld matrix for transform 00968 */ 00969 void Transform( const a2dAffineMatrix& tworld ) { m_lworld = tworld*m_lworld; SetPending(true); } 00970 00971 //! called from an a2dRestrictionEngine, to restrict vertexes, lines, object to this object. 00972 /*! 00973 When other object, vertexes or lines are moved (e.g. by a tool), the restriction engine can be set to snap/restrict 00974 to neighbouring objects. Here you can define to which parts of those neighbour objects something can be snapped. 00975 For a simple polygon this will be its vertexes, for an ellipse its extremes. For complex objects, it can be anything. 00976 For objects with pins, it will be the pins if that is asked for. 00977 For the various types of snap, you only implement what is useful for the object. 00978 00979 The default can snap to: 00980 - pins snapToWhat == snapToWhat & a2dRestrictionEngine::snapToPins or a2dRestrictionEngine::snapToPinsUnconnected 00981 - the object its position snapToWhat == a2dRestrictionEngine::snapToObjectPos 00982 - the vector path conversion with GetAsCanvasVpaths() snapToWhat == a2dRestrictionEngine::snapToObjectVertexes 00983 */ 00984 virtual bool RestrictToObject( a2dRestrictionEngine* engine, a2dSnapToWhatMask snapToWhat ); 00985 00986 //! return a vectorpath indicating on which point/segments the object likes to be snap. 00987 /*! 00988 If a drag of this object is on going, one may want to snap itself to other objects, while dragging. 00989 This member functions will tell the a2dRestrictionEngine on which points this object likes to snap to others. 00990 00991 The default implementation for a2dRestrictionEngine::snapToObjectVertexes tries to convert to a Vpath, 00992 and if so, uses that as return, if not, it takes the boundingbox its points. 00993 For a2dRestrictionEngine::snapToObjectPos its is the position of the object that is added. 00994 For a2dRestrictionEngine::snapToBoundingBox its is the BoundingBox points of the object that are added. 00995 */ 00996 virtual a2dCanvasObjectList* GetSnapVpath( a2dSnapToWhatMask snapToWhat ); 00997 00998 //! reduce matrix to identity 00999 /*! Override if possible to eliminate matrix of the object 01000 For a non Derived a2dCanvasObject this function multiplies its children 01001 with this object matrix, and reduces its own matrix to identity. 01002 */ 01003 virtual bool EliminateMatrix(); 01004 01005 //\} 01006 //****************** END AFFINE TRANSFORMATION ******************/ 01007 01008 //****************** BOUNDING BOX ******************/ 01009 /*! \name Bounding box 01010 Each a2dCanvasObject has a Bounding box for efficient drawing and hit testing. 01011 The bounding box is always the bounding box of the vertices. It is extended 01012 in pixels or would units to cope for stroke width and decorations like handles. 01013 */ 01014 //\{ 01015 public: 01016 01017 //! flags for calculating boundingbox of derived object 01018 /*! 01019 Those flags are used in a a2dBboxFlags to indicate different ways of bounding boxes to be calculated. 01020 01021 \sa DoGetUnTransformedBbox() 01022 \sa GetUnTransformedBbox() 01023 01024 \ingroup canvasobject 01025 01026 */ 01027 enum a2dBboxFlag 01028 { 01029 a2dCANOBJ_BBOX_NON =0x0000, //!< return full boundingbox of derived object 01030 a2dCANOBJ_BBOX_EDIT =0x0001, //!< return to contain edit bbox, suitable for editing matrix of object 01031 a2dCANOBJ_BBOX_CHILDREN =0x0002 //!< return to contain children bbox 01032 }; 01033 01034 typedef unsigned int a2dBboxFlags; 01035 01036 //!get minimum X of the boundingbox in world coordinates relative to its parents 01037 /*! 01038 \remark stroke width is not included. 01039 */ 01040 double GetBboxMinX() { return GetBbox().GetMinX(); } 01041 01042 //!get minimum Y of the boundingbox in world coordinates relative to its parents 01043 /*! 01044 \remark stroke width is not included. 01045 */ 01046 double GetBboxMinY() { return GetBbox().GetMinY(); } 01047 01048 //!get maximum X of the boundingbox in world coordinates relative to its parents 01049 /*! 01050 \remark stroke width is not included. 01051 */ 01052 double GetBboxMaxX() { return GetBbox().GetMaxX(); } 01053 01054 //!get maximum Y of the boundingbox in world coordinates relative to its parents 01055 /*! 01056 \remark stroke width is not included. 01057 */ 01058 double GetBboxMaxY() { return GetBbox().GetMaxY(); } 01059 01060 //!get width of the boundingbox in world coordinates relative to its parents 01061 /*! 01062 \remark stroke width is not included. 01063 */ 01064 double GetBboxWidth() { return GetBbox().GetWidth(); } 01065 01066 //!get height of the boundingbox in world coordinates relative to its parents 01067 /*! 01068 \remark stroke width is not included. 01069 */ 01070 double GetBboxHeight() { return GetBbox().GetHeight(); } 01071 01072 //!get boundingbox in world coordinates exclusive stroke width relative to its parent 01073 /*! 01074 \remark stroke width is not included. 01075 01076 \remark if the boundingbox is not valid, it will be calculated right now, 01077 and to make sure parent object will have the right boundingbox, the object is 01078 set pending. That will in the update of a2dCanvasDocument, lead to redrawing and 01079 recalculation of this object and parent boundingbox will be recalculated. 01080 */ 01081 a2dBoundingBox& GetBbox(); 01082 01083 //!Get boundingbox without the affine matrix transform included. 01084 /*! 01085 Extends as a result of stroke etc. is not included. 01086 01087 \param flags default a2dCANOBJ_BBOX_CHILDREN to include child objects in the boundingbox 01088 */ 01089 virtual a2dBoundingBox GetUnTransformedBbox( a2dBboxFlags flags = a2dCANOBJ_BBOX_CHILDREN ) const; 01090 01091 //!Like GetBbox, but it always calculcates the bounding box from scratch 01092 /*! 01093 This is usefull, when you need the bounding box, but the stored bounding box 01094 is not up to date. The rendering system relies on doing this update on its own, 01095 because it needs the old bounding box for update area calculation. 01096 01097 \param nChildLevels number of child levels to include (0=no childs, 1=direct childs, ...) 01098 */ 01099 a2dBoundingBox GetCalculatedBoundingBox( int nChildLevels ); 01100 01101 //!first translate boundingbox with cworld and recalculate at new position 01102 /*! 01103 \remark a2dCanvasView for the a2dCanvasDocument must be set. 01104 \param ic iterative context contains matrix which is applied first to get to absolute position 01105 \param withExtend if true boundingbox includes extend in world and pixels ( a2dCanvasView must be set for m_root ) 01106 */ 01107 a2dBoundingBox GetMappedBbox( a2dIterC& ic, bool withExtend = true ); 01108 01109 //!first translate boundingbox with cworld and recalculate at new position 01110 /*! 01111 \param cworld matrix applied first to get to absolute position 01112 */ 01113 a2dBoundingBox GetMappedBbox( const a2dAffineMatrix& cworld ); 01114 01115 01116 //!Get absolute occupied area in the device coordinates. 01117 /*! 01118 The object its boundingbox in world coordinates is first translated using the matrix cworld. 01119 Cworld will normally contain the accumulated matrix to the object with in the 01120 object Tree structure. 01121 01122 \remark pixel and world extend are included. 01123 01124 \param ic iterative context to get matrix which is applied first to get to absolute position 01125 \param inflate extra pxiels added on each size, to get rid of double to int rounding problems. 01126 */ 01127 wxRect GetAbsoluteArea( a2dIterC& ic, int inflate = 2 ); 01128 01129 //!get world extend 01130 /*! 01131 world extend is the amount that the boundingbox is enlarged because 01132 of the stroke its size in case of a stroke with width defined in world coordinates. 01133 Other things may be included to get the total extend to the boundingbox of the object. 01134 01135 The complete area occupied by a a2dCanvasObject in general is the boundingbox enlarged with 01136 the worldExtend + the pixelExtend ( expressed in worldcoordinates ). 01137 But if needed one can add to the both extends whatever is needed. 01138 01139 \remark worldExtend is calculated while Updating document/object 01140 */ 01141 float GetWorldExtend() const { return m_worldExtend; } 01142 01143 //!get pixel extend 01144 /*! 01145 pixel extend is the amount that the boundingbox is enlarged because 01146 of the stroke its size in case of a storke with width defined in pixel coordinates. 01147 Other things may be included to get the total extend to the boundingbox of the object. 01148 01149 The complete area occupied by a a2dCanvasObject in general is the boundingbox enlarged with 01150 the worldExtend + the pixelExtend ( expressed in worldcoordinates ). 01151 But if needed one can add to the both extends whatever is needed. 01152 01153 \remark pixelExtend is calculated while Updating document/object 01154 01155 \remark a trick to be able to use objects complete in pixel coordinates, 01156 the boundingbox can be made zero while the pixel extend account for the rest. 01157 a2dHandle uses this approach. It will result in a total area that is square. 01158 */ 01159 int GetPixelExtend() const { return m_pixelExtend; } 01160 01161 //! used for deciding if the object needs to be rendered against the current clipping area of the active drawer. 01162 /*! 01163 \param ic iterative context contains matrix which is applied first to get to absolute position 01164 \param clipparent clipping status of parent object ( to optimize ) 01165 */ 01166 OVERLAP GetClipStatus( a2dIterC& ic, OVERLAP clipparent ); 01167 01168 //! returns boundingbox clipping object if clipping property is set 01169 /*! \sa a2dClipPathProperty 01170 \param ic iterative context contains matrix which is applied first to get to absolute position 01171 */ 01172 a2dBoundingBox GetClipBox( a2dIterC& ic ); 01173 01174 //\} 01175 //****************** END BOUNDING BOX ******************/ 01176 01177 //****************** EVENT PROCESSING AND HIT TESTING ******************/ 01178 /*! \name Event processing 01179 Windows events are routed to the canvas objects under the mouse 01180 */ 01181 //\{ 01182 public: 01183 01184 //! Do hittest on children 01185 /*! 01186 Ignores this object its m_layer and drawing for the object and properties. 01187 Only does a hit test on the children. 01188 When hitEvent.m_option & a2dCANOBJHITOPTION_LAYERS is true, iteration on layers is performed, 01189 by setting ic.SetPerLayerMode( true ). 01190 When hitEvent.m_xyRelToChildren is true, hit test is done relative to child objects, realized by 01191 adding inverse matrix of object to the a2dIterC first. 01192 The a2dIterC can contain a a2dIterC::SetObjectFilter() but this is only used when not iterating layers. 01193 When iterating layers, first normal objects are tested for a hit in reverse order of drawing the layers. 01194 So last drawn layer displayed on top, is tested first. At last the edit and tool object are tested. 01195 01196 \param ic iterative context, relative to this testing is performed. 01197 \param hitEvent contains x,y to test, and other hit info is assembled here 01198 \param filterSelectableLayers if true layers should not only be visible but also selectable 01199 */ 01200 a2dCanvasObject* ChildIsHitWorld( a2dIterC& ic, a2dHitEvent& hitEvent, bool filterSelectableLayers = false ); 01201 01202 //!If the position (x,y) is within the object return this 01203 /*! 01204 First a simple bounding box test is done, if that hit is positive, a recursive call on child objects 01205 and properties which are normarmally rendered id done. 01206 The hit test is in reverse order of the rendering order of the object and its nested child 01207 objects. 01208 01209 For an accurate hittest one needs to implement DoIsHitWorld() for the derived a2dCanvasObject, 01210 in that function one should test the object accurate, and also additional object which are 01211 not in the childslist but real members of the derived object. 01212 DoIsHitWorld() should return the way the object is hit by filling a2dHitEvent::m_how with the correct info. 01213 01214 \param ic contains iteration context 01215 \param hitEvent stores hit information 01216 01217 \return this pointer if there is a hit on this object or its children or its properties. 01218 */ 01219 a2dCanvasObject* IsHitWorld( a2dIterC& ic, a2dHitEvent& hitEvent ); 01220 01221 //!set hit flags 01222 /*! 01223 Based on these flags the object will generate a hit true. 01224 \param mask set hit flags in object according to given mask. 01225 */ 01226 void SetHitFlags( a2dCanvasObjectFlagsMask mask ); 01227 01228 //! Hit objects will receive the event 01229 /*! 01230 The event is first sent to the child objects, and if not processes there, 01231 testing for a hit on the object itself is done, and if true a2dEvtHandler::ProcessEvent is called. 01232 The function goes through the whole hierarchy, even if event is already processed. 01233 It maybe be that other events are generated while iterating over the document. 01234 01235 \param ic iteration context 01236 \param hitEvent stores hit information 01237 01238 \return true if Object (or a child ) did process the event and did not call event.Skip() 01239 */ 01240 virtual bool ProcessCanvasObjectEvent( a2dIterC& ic, a2dHitEvent& hitEvent ); 01241 01242 //! default handler for mouse events, sent to the object from the a2dCanvasView. 01243 /*! 01244 Mouse events are sent to the object when the mouse pointer is hiting the object. 01245 The default is used when the object is in edit mode. Else it will detect 01246 if the special object tip property named __OBJECTTIP__ is available, and switch 01247 it on or off when the mouse eneter or leaves the object. 01248 */ 01249 void OnCanvasObjectMouseEvent( a2dCanvasObjectMouseEvent& event ); 01250 01251 //! default handler for character events 01252 void OnChar(wxKeyEvent& event); 01253 01254 //! called on Right Down by default. 01255 void OnPopUpEvent(a2dCanvasObjectMouseEvent &event); 01256 01257 //! called when the mouse enters the object 01258 void OnEnterObject(a2dCanvasObjectMouseEvent &event); 01259 01260 //! called when the mouse leaves the object 01261 void OnLeaveObject(a2dCanvasObjectMouseEvent &event); 01262 01263 //! object with mouse in flag set, will sent a leave event, and set flag off. 01264 //! recursive for children. 01265 void LeaveInObjects( a2dIterC& ic, a2dHitEvent& hitEvent ); 01266 01267 //! called if a mouse event occured on a child object, that is a handle 01268 void OnHandleEvent(a2dHandleMouseEvent &event); 01269 01270 protected: 01271 01272 //!This is an internal function used by IsHitWorld(). Don't use it directly. 01273 a2dCanvasObject* IsHitWorldChildObjects( a2dIterC& ic, RenderChild& whichchilds, a2dHitEvent& hitEvent ); 01274 01275 //!Does hit test on the object (exclusif child objects) 01276 /*! 01277 DoIsHitWorld() should return the way the object is hit by filling a2dHitEvent::m_how with the correct info. 01278 01279 \param ic iterative context ( e.g. current transform WITH the local transform applied ) 01280 \param hitEvent stores hit information 01281 \return true if hit 01282 */ 01283 virtual bool DoIsHitWorld( a2dIterC& ic, a2dHitEvent& hitEvent ); 01284 01285 //!This is an internal function used by IsHitWorldChildObjects(). Don't use it directly. 01286 a2dCanvasObject* HitChildObjectsOneLayer( a2dIterC& ic, RenderChild& whichchilds, a2dHitEvent& hitEvent ); 01287 01288 //\} 01289 //****************** END EVENT PROECSSING AND HIT TESTING ******************/ 01290 01291 //****************** CHILD TREE AND DOCUMENT STRUCTURE ******************/ 01292 /*! \name Child tree and document structure 01293 Every a2dCanvasObject has a list of child objects. One a2dCanvasObject can 01294 be element of multiple child lists and can thus have multiple parents. 01295 Reference counting is used to control the life time of a a2dCanvasObject. 01296 Because a a2dCanvasObject can have multiple parents, it has no parent pointer. 01297 A a2dCanvasObject has a pointer to the a2dCanvasDocument it belongs to. 01298 */ 01299 //\{ 01300 public: 01301 01302 //!get a2dCanvasDocument of the object. 01303 /*! 01304 Root (a2dCanvasDocument) needs to be known to each object for the following reasons: 01305 - It is used to inform the document that there are pending objects in the document. 01306 - To reach the layer setup of the document. 01307 - To reach the command processor of the document, which is used to submit commands to, 01308 that can be undone if needed. 01309 01310 */ 01311 inline a2dCanvasDocument *GetCanvasDocument() const { return m_root; } 01312 01313 //! Sets this object to a a2dCanvasDocument. 01314 /*! 01315 \param root set the a2dCanvasDocument for this object to this (if appropriate recursive) 01316 \param recurse default true, which uses a2dWalker_SetCanvasDocument for doing the 01317 same recursive for nested object and nested object in derived classes. 01318 */ 01319 void SetCanvasDocument( a2dCanvasDocument *root, bool recurse = true ); 01320 01321 //!prepend a a2dCanvasObject to the childobjects 01322 void Prepend( a2dCanvasObject* obj ); 01323 01324 //!append a a2dCanvasObject to the childobjects 01325 void Append( a2dCanvasObject* obj ); 01326 01327 //!insert a a2dCanvasObject to the childobjects 01328 void Insert( size_t before, a2dCanvasObject* obj, bool ignoreReleased = true ); 01329 01330 //!get the list where the child objects are stored in. 01331 /*! 01332 \return A pointer to the childlist. If there is no child list yet, it returns wxNullCanvasObjectList. 01333 01334 \remark wxNullCanvasObjectList has no children and therefore one can use 01335 GetChildObjectList()->GetCount() to test for children. 01336 */ 01337 a2dCanvasObjectList* GetChildObjectList(); 01338 const a2dCanvasObjectList* GetChildObjectList() const; 01339 01340 //!create and get the list where the child objects are stored in. 01341 /*! 01342 If there is no childlist yet (wxNullCanvasObjectList), a new childlist will be created. 01343 Else the existing one will be returned. 01344 01345 \return A pointer to the childlist. 01346 */ 01347 a2dCanvasObjectList* CreateChildObjectList(); 01348 01349 //! get number of child objects 01350 /*! 01351 \return number of child objects 01352 */ 01353 unsigned int GetChildObjectsCount() const; 01354 01355 //!object with the same given mask are made into a group. 01356 /*! 01357 \param mask: mask for objects to assemble for creating a group of child objects 01358 \param createref: next to a new a2dCanvasObject, create a reference to the new object. 01359 \return return newly created object only if objects where found else NULL 01360 */ 01361 a2dCanvasObject* CreateHierarchy( a2dCanvasObjectFlagsMask mask, bool createref = true ); 01362 01363 //! move childs of childs and members which have hierarchy one level up to this object its child list. 01364 /*! 01365 The base implementation takes child object in m_childobjects to the parent object. 01366 The child object are transformed by the parent its transform. 01367 */ 01368 virtual void RemoveHierarchy(); 01369 01370 //!remove the given object from the childobjects 01371 /*! The object will be Realeased. 01372 if its refcount is 0 it will be deleted else its refcount decremented. 01373 01374 \param obj object to release 01375 \param backwards start at the end 01376 \param all if true remove all references to object 01377 \param now if true remove all references to object now!, else only delete flag is set, 01378 and Update() takes care of it. 01379 01380 \return number of released objects 01381 */ 01382 int ReleaseChild( a2dCanvasObject* obj, bool backwards = false, bool all = false, bool now = false ); 01383 01384 01385 //!removes and release only from the childobjects the objects with the given mask 01386 /*! 01387 \return true if some object were released 01388 */ 01389 bool ReleaseChildObjects( a2dCanvasObjectFlagsMask mask = a2dCanvasOFlags::ALL ); 01390 01391 //!returns index of the given a2dCanvasObject in this childobjects 01392 int IndexOf( a2dCanvasObject* obj ) const; 01393 01394 //!return the object which fits the filter. 01395 /*! 01396 \param objectname object with this name to search for 01397 \param classname If classname is empty it collects all objects else only object with this class name. 01398 \param mask object must have this mask. 01399 \param propid if a property id is given, the object must have a property with this id 01400 \param valueAsString StringValueRepresentation of the property that is required (if not empty). 01401 \param id GetUniqueSerializationId() should be this unless 0 01402 */ 01403 a2dCanvasObject* Find( const wxString& objectname, const wxString& classname = wxT(""), 01404 a2dCanvasObjectFlagsMask mask = a2dCanvasOFlags::ALL , const a2dPropertyId *propid = NULL, const wxString& valueAsString = wxT(""), 01405 wxUint32 id = 0 ) const; 01406 01407 //!return the child object if it is part of this object 01408 /*! 01409 \param obj object to search for 01410 */ 01411 a2dCanvasObject* Find( a2dCanvasObject* obj ) const; 01412 01413 //! the object with the given name is released and switched in place to newobject 01414 /*! 01415 \return true if object was found else false 01416 */ 01417 bool SwitchChildNamed( const wxString& objectname, a2dCanvasObject* newobject ); 01418 01419 //!Copy objects with the right conditions to the total list. 01420 /*! 01421 \param total list of object found (may already contain elements found in earlier call) 01422 \param classname If classname is empty it collects all objects else only object with this class name. 01423 \param mask object must have this mask. 01424 \param id If property id is set the object needs to have this property. 01425 \param bbox only find objects within this box. 01426 01427 \remark only searches this object and its children, not deeper. 01428 01429 \return number of objects found 01430 */ 01431 int CollectObjects( a2dCanvasObjectList* total, 01432 const wxString& classname = wxT(""), 01433 a2dCanvasObjectFlagsMask mask = a2dCanvasOFlags::ALL, 01434 const a2dPropertyId *id = 0, 01435 const a2dBoundingBox& bbox = wxNonValidBbox 01436 ) const; 01437 01438 //\} 01439 //****************** END CHILD TREE AND DOCUMENT STRUCTURE ******************/ 01440 01441 //****************** UPDATE AND PENDING ******************/ 01442 /*! \name Update and Pending 01443 */ 01444 //\{ 01445 public: 01446 //! Various mode flags for Update 01447 /*! It doesn't make sense to bit-or these, but these are bitflags anyway 01448 for quick multi-testing (e.g. ( mode & (mode1|mode2|mode3) ) */ 01449 enum UpdateMode 01450 { 01451 /*! saves old valid boundingbox as boundingbox property */ 01452 update_save = 0x0001, 01453 01454 /*! includes boundingbox properties in object its boundingbox */ 01455 update_includebboxprop = 0x0002, 01456 01457 /*! update_save and update_includebboxprop combined */ 01458 updatemask_save_includebboxprop = 01459 update_includebboxprop | 01460 update_save, 01461 01462 //! All updates of these modes force an update (e.g. update non-pending valid bounding boxes) 01463 updatemask_force = 01464 update_includebboxprop | 01465 update_save, 01466 01467 //! object with invalid boundingbox or pending objects their boundingbix is recalculated. 01468 //! When boundingbox properties are found, theye will be include in the box. 01469 updatemask_normal = 01470 update_includebboxprop 01471 }; 01472 01473 //! Update the state of the object according to its current position etc. 01474 /*! 01475 This usually does the following: 01476 - calculates the new bounding box in world coordinates relative to parents. 01477 - Release childs that have m_release set 01478 01479 This function is usually called in a2dCanvasDocument::AddPendingUpdatesOldNew between adding 01480 the old and the new bounding box to the pending area. 01481 You should NOT do any change here that issues commands to the command processor, 01482 because such commands wouldn't have a proper context. Such things should be 01483 done in UpdateImmediate. 01484 Other things like updating the cache data need to be done here. 01485 01486 Takes into account associated child, properties and derived objects. 01487 If a2dCanvasObject::UpdateMode = updatemask_force all boundingboxes are invalidated and recalculated, 01488 else it only recalculates if invalid or one of the children is invalid. 01489 01490 This function calls DoUpdate(), when needed. The idea is to minimize the number of recalculated boudingboxes. 01491 So if an object is setpending or a child became pending, the boudingbox needs to be recalculated, 01492 but since this is a combination of property, child and derived object boundingboxes, this is optimized. 01493 01494 \return true if the bounding box did change and the parent has to recalculate 01495 01496 01497 \remark The object its layers is set in the layersetup as being available in the document. 01498 \remark if overridden in derived class, also call baseclass Update 01499 \remark in derived classes DoUpdate() should be implemented to at least calculate the boundingbox of the object 01500 without children in m_childobjects, but including any referenced objects in the derived objects. Like arrow point 01501 objects on a line or polyline. 01502 */ 01503 virtual bool Update( UpdateMode mode ); 01504 01505 //! A data structure for DoUpdateImmediate 01506 /*! All this could be given as parameters as well, but for a recursive function 01507 with always identical parameters, using a struct is more efficient and easier to extend 01508 01509 This is derived from a2dPropObject, so that it can also be used as a means for 01510 communication between different objects (usually of the same class) during update. 01511 01512 \remark a2dDoUpdateImmediateData is derived from a2dPropObject so that it can have properties 01513 but a2dDoUpdateImmediateData is/should be never ref counted! 01514 01515 */ 01516 class A2DCANVASDLLEXP a2dDoUpdateImmediateData : public a2dPropObject 01517 { 01518 public: 01519 //! Current phase of the update process 01520 /*! This always starts with 0 and goes up if requested in phase 0 */ 01521 int m_phase; 01522 //! Set a bit in here to request execution of an update phase 01523 int m_phaserequest; 01524 //! This has a bit set for every phase, that was already done 01525 int m_phasedone; 01526 //! If true, the current phase is executed for the first time 01527 bool m_phase_first; 01528 //! If true this is a final update of the original data, not an intermediate update of the editcopy 01529 bool m_final; 01530 //! If true, DoImmediateUpdate was called on an original object 01531 /*! Usually DoUpdateImmediate is called on an editcopy */ 01532 bool m_original; 01533 //! If true, allow reconnecting the begin pin 01534 bool m_allowreconnectbegin; 01535 //! If true, allow reconnecting the end pin 01536 bool m_allowreconnectend; 01537 //! If true, before the next phase change the update object list is sorted by PROPID_UpdateImmediatePriority 01538 bool m_sortbeforenextphase; 01539 //! The tool, that issued this update, may be NULL, if not m_parent is set from it. 01540 class a2dBaseTool *m_tool; 01541 //! parent of the set of child objects to update. 01542 /*! 01543 Like the wires connecting normal objects, these are all children of the same parent. 01544 */ 01545 a2dCanvasObjectPtr m_parent; 01546 01547 //! constructor 01548 /*! 01549 \param final true when last stage needs to be executed in an reroute cycle, 01550 resulting in commands being issued. 01551 \param tool tool from which update is called, may be NULL 01552 \param parent parent of which the object need to be updated, if NULL, 01553 m_tool->GetCanvasView()->GetShowObject() is taken as m_parent 01554 */ 01555 a2dDoUpdateImmediateData( bool final, a2dBaseTool *tool, a2dCanvasObject* parent ); 01556 01557 //! Set a bit in m_phaserequest 01558 void RequestPhase( int i ) 01559 { 01560 wxASSERT( i>=0 && i<32 ); 01561 m_phaserequest |= (1<<i); 01562 } 01563 01564 //! Request that on the next phase change, the objects in the update list are sorted by PROPID_UpdateImmediatePriority 01565 void RequestSortPriorityBeforeNextPhase() 01566 { 01567 m_sortbeforenextphase = true; 01568 } 01569 01570 DECLARE_CLASS( a2dDoUpdateImmediateData ) 01571 01572 //! Holds temporary routing data 01573 static a2dPropertyIdRefObject* PROPID_RouteData; 01574 01575 DECLARE_PROPERTIES() 01576 }; 01577 01578 //! Like Update, but this is called not on OnIdle, but at well defined points 01579 /*! Use this function to adjust objects to a changing environment (e.g. wires 01580 to moving objects) when the changes are done by commands and need a proper 01581 command context. This function calls DoUpdateImmediate. 01582 01583 The DoUpdateImmediateData structure, contains data which controls the recursive/repeating 01584 calls to this function. The idea is that objects which change can request more phases. 01585 Which eventually leads to extra calls until no more is requested. 01586 01587 \param final signals last update that will be called in a row. 01588 \param tool tool from which update is called, may be NULL 01589 \param parent parent of which the object need to be updated, if NULL, 01590 m_tool->GetCanvasView()->GetShowObject() is taken as m_parent 01591 \param data a structure with data controlling the update process 01592 */ 01593 virtual void UpdateImmediate( bool final, a2dBaseTool *tool, a2dCanvasObject* parent = 0, a2dDoUpdateImmediateData *data = 0 ); 01594 01595 //! See UpdateImediate() 01596 virtual void DoUpdateImmediate( a2dDoUpdateImmediateData *data ); 01597 01598 //!is this object pending for update? 01599 /*!(overruled by parent object in some cases during rendering) 01600 \remark set the object its pending flag and inform root about this 01601 */ 01602 bool GetPending() const { return m_flags.m_pending; } 01603 01604 //!set this object pending for update 01605 /*! 01606 This flag is set when an object has changed, which means that it needs to be redrawn. 01607 Since an object can be Referenced also, it can be drawn at several positions. 01608 Therefore the redrawing needs to be done indirectly from the top, and for each a2dCanvasView 01609 displaying the object. In general old and new boundingbox areas are updated on the display. 01610 \li Step 1 add pending objects occupied areas to drawer. 01611 \li Step 2 The new boundingbox is calculated. 01612 \li Step 3 add pending objects occupied areas to draweronce more. 01613 \li Step 4 reset all pending flags for objects. 01614 01615 \remark Does also inform the a2dCanvasDocument that there are pending objects. 01616 \remark If because of this object becoming pending other objects should become pending also, 01617 one should override this function to set those other objects pending. 01618 \remark If redefined in derived object always call base also. 01619 01620 \sa DependencyPending() 01621 01622 \param pending if true set object pending 01623 01624 */ 01625 virtual void SetPending( bool pending ); 01626 01627 //!search objects ( if nested recursive ) that have the pending flag Set 01628 /*! 01629 And add the current absolute boudingbox of the object to the pendingareas in the active 01630 a2dCanvasView for update/redrawing that area later. After a this normally the boundingbox of 01631 this object will be recalculated in a2dCanvasObject::Update(), followed by one more call to this function 01632 here, in order to also redraw the new boundingbox its area. 01633 When all pending areas are combined to a minimum in a2dCanvasView, the areas will be redrawn. 01634 01635 The area currently occupied by the object in the active a2dCanvasView is added for update in case 01636 the object was pending. Next to that the a2dCanvasView is informed that the object its layer 01637 is available in the document and should be rendered. 01638 In case the object will be released ( m_Release is set ), the a2dCanvasView::SetLayerCheck( objectlayer ) 01639 is called, in order to recheck if there or still object on that layer as seen from that view. 01640 01641 \remark this method is fast if many objects need an update. 01642 \remark You are responsible for setting and resetting the pending flag. 01643 \remark Not valid boundingbox in the object, means the object and its children will be ignored. 01644 01645 \param ic iterative context, contains cumulative matrix for transforming object to absolute position 01646 */ 01647 void AddPending( a2dIterC& ic ); 01648 01649 01650 //!called by to check if this object becomes pending as a result of other objects 01651 /*! 01652 You can Override DependencyPending() to set your object pending, when another object was 01653 set pending. 01654 */ 01655 virtual void DependencyPending( a2dWalkerIOHandler* WXUNUSED(handler) ); 01656 01657 01658 //****************** END UPDATE AND PENDING ******************/ 01659 01660 //****************** RENDERING AND STYLE ******************/ 01661 /*! \name Rendering and style 01662 */ 01663 //\{ 01664 public: 01665 01666 //!Render this object to the active a2dCanvasView 01667 /*! 01668 01669 This function is called via the a2dCanvasDocument class or its nested children. 01670 The active a2dCanvasView which is set for the document is used to draw 01671 to (either on its buffer or directly on the device) 01672 All rendering goes through this function to be able to render specific things 01673 in the base class first (like a2dCanvasObject its properties.) 01674 Somewhere internal DoRender will be called to really render the derived object itself. 01675 Next to that nested a2dCanvasObject's will be rendered too. 01676 01677 If wanted only the canvas objects with a certain mask set, will be rendered. 01678 Mask example: Checking visible and selected 01679 01680 use: mask=(a2dCANOBJ_VISIBLE | a2dCANOBJ_SELECTED) 01681 01682 \remark 01683 Do not use directly from outside the containing document of this object. 01684 Normally only used directly in derived classes \sa a2dCanvasDocument 01685 01686 \remark The active clipping rectangle is set within the active drawer. 01687 It can be used to decide which parts of the object need to be re-drawn or not. 01688 This may speed up drawing in sepcial cases, but in general the active a2dCanvasView, simply 01689 clips all that is drawn on it to active clipping rectangle. 01690 The fact that the object is called to redrawn itself, is not decided here, instead it is part 01691 of the pending object mechanism. Which uses the object its boundingbox to request redrawing. 01692 01693 \remark Normally an object will be rendered if the given layer is equal to the object its layer. 01694 01695 \remark wxLAYER_ALL has a special meaning. 01696 If the given input layer is wxLAYER_ALL, then the m_layer of objects is not tested. 01697 So the child objects their own layer settings are ignored/not checked in that case. 01698 All child objects are drawn at once, still the style of the layers settings is used when needed. 01699 01700 If the flag "m_flags.m_childrenOnSameLayer" is set, a new iteration over layers will take place. 01701 The effect is that all children will be drawn at once ( not only objects on the given layer ), 01702 but the order of the layers will be taken into account to draw the children. 01703 If the flag "m_flags.m_childrenOnSameLayer" is NOT set, a new iteration on layers is NOT done, 01704 and only the objects on the given layer will be drawn. 01705 01706 \remark ic.GetPerLayerMode() is true, then only ic.GetLayer() is rendered, which can not be wxLAYER_ALL. 01707 01708 \param ic iteration context (has a2dCanvasView accumulative matrix to calculate absolute position of the object) 01709 \param clipparent this must be the clip status of parent object, it is used to optimize drawing speed. 01710 e.g If parent is completely within the current clipping rectangle of the a2dCanvasView, 01711 there is no need to check child objects. 01712 */ 01713 virtual void Render( a2dIterC& ic, OVERLAP clipparent ); 01714 01715 //! update the transform matrix for objects with property 'PROPID_viewDependent' 01716 /*! 01717 will recursive call the UpdateViewDependentObjects routines of all the child objects (TODO for optimize: with flag 'm_childpixelsize=true'). 01718 \param ic iteration context (has a2dCanvasView accumulative matrix to calculate absolute position of the object) 01719 01720 \remark Check all child objects with (TODO for optimize: flag 'm_childpixelsize=true'). 01721 */ 01722 void UpdateViewDependentObjects( a2dIterC& ic ); 01723 01724 //! called by Render() if m_flags.m_HighLight is set 01725 /*! 01726 \param ic iteration context (has a2dCanvasView accumulative matrix to calculate absolute position of the object) 01727 */ 01728 virtual void DrawHighLighted( a2dIterC& ic ); 01729 01730 //!set if this object will visible (be rendered or not) 01731 /*!(overruled by parent object in some cases during rendering) 01732 \remark set the object its pending flag and inform root about this 01733 \param visible if true set object visible 01734 */ 01735 void SetVisible(bool visible) 01736 { 01737 if(m_flags.m_visible != visible) { m_flags.m_visible = visible; SetPending(true); } 01738 } 01739 01740 //!get visibility (rendering depends on layer settings also) 01741 bool GetVisible() const { return m_flags.m_visible; } 01742 01743 //!get visibility (rendering depends on layer settings also) 01744 /*! 01745 Alias for GetVisible 01746 \see GetVisible 01747 */ 01748 inline bool IsVisible() const { return GetVisible(); } 01749 01750 //!Set a fill for the object which will be used instead of the layer fill 01751 /*! 01752 The fill is for filling the object. 01753 Use a2dCanvasNullFill or 0 to remove the fill from a object. 01754 Use a2dTRANSPARENT_FILL to not fill the object. 01755 \remark m_flags.m_filled flag overrules the fill to fill TRANSPARENT 01756 \remark inheritance to children of object 01757 \remark object is free to use style or not 01758 \remark a style resulting in wxLAYER_FILL means property will be removed 01759 \sa a2dStyleProperty 01760 */ 01761 void SetFill( const a2dFill& fill ); 01762 01763 a2dFill GetFill() const; 01764 01765 //!Set a fill color for the object which will be used instead of the layer fill 01766 /*! 01767 \param fillcolor color to fill object with 01768 \param style style for one colour fill 01769 \remark creates a a2dOneColourFill internal 01770 \remark inheritance to children of object 01771 \remark object is free to use style or not 01772 \sa a2dStyleProperty 01773 \sa a2dOneColourFill 01774 */ 01775 void SetFill( const wxColour& fillcolor, a2dFillStyle style = a2dFILL_SOLID ); 01776 01777 //!Set a fill color for the object which will be used instead of the layer fill 01778 /*! 01779 \param fillcolor color to fill object with 01780 \param fillcolor2 color to fill object with 01781 \param style style for one colour fill 01782 \remark inheritance to children of object 01783 \remark object is free to use style or not 01784 \sa a2dStyleProperty 01785 \sa a2dTwoColourFill 01786 */ 01787 void SetFill( const wxColour& fillcolor, const wxColour& fillcolor2, a2dFillStyle style = a2dFILL_SOLID ); 01788 01789 //! set first colour of fill 01790 void SetFillColour( const wxColour& colour ); 01791 01792 //! get first colour of fill 01793 wxColour GetFillColour() const; 01794 01795 //!Set a stroke for the object which will be used instead of the layer stroke 01796 /*! 01797 \param strokecolor color to stroke object with 01798 \param width width of stroke in world coordinates 01799 \param style style for one colour stroke 01800 \remark a style resulting in wxLAYER_STROKE means property will be removed 01801 \remark inheritance to children of object 01802 \remark object is free to use style or not 01803 \sa a2dStyleProperty 01804 */ 01805 void SetStroke( const wxColour& strokecolor, double width = 0, a2dStrokeStyle style = a2dSTROKE_SOLID ); 01806 01807 //!Set a stroke for the object which will be used instead of the layer stroke 01808 /*! 01809 \param strokecolor color to stroke object with 01810 \param width width of stroke in device coordinates 01811 \param style style for one colour stroke 01812 \remark creates a a2dOneColourStroke property internal 01813 \remark inheritance to children of object 01814 \remark object is free to use style or not 01815 \sa a2dStyleProperty 01816 */ 01817 void SetStroke( const wxColour& strokecolor, int width , a2dStrokeStyle style = a2dSTROKE_SOLID ); 01818 01819 //! Set stroke using pointer to a stroke 01820 /*! 01821 The stroke is for drawing outlines of the object. 01822 Use a2dNullStroke to remove the stroke from a object. 01823 Use a2dTRANSPARENT_STROKE to not fill the object. 01824 \remark a style resulting in wxLAYER_STROKE means property will be removed 01825 */ 01826 void SetStroke( const a2dStroke& stroke); 01827 01828 a2dStroke GetStroke() const; 01829 01830 //! set first colour of stroke 01831 void SetStrokeColour( const wxColour& colour ); 01832 01833 //! get first colour of stroke 01834 wxColour GetStrokeColour() const; 01835 01836 //!set the Contour width of the shape 01837 /*! 01838 Next to the stroke width one can sometimes set a contour width e.g. a circular donut. 01839 */ 01840 virtual void SetContourWidth(double WXUNUSED(width)) {} 01841 01842 //!get the Contour width of the shape 01843 virtual double GetContourWidth() const { return 0; } 01844 01845 //!sets fill and stroke of object to a2dCanvasView 01846 /*! 01847 sets local fill and pen into a2dCanvasView if available, else 01848 they will be set on basis of the layer index. 01849 \sa a2dCanvasView 01850 */ 01851 void SetDrawerStyle( a2dIterC& ic, a2dStyleProperty* style ); 01852 01853 //!if set children are rendered on the same layer as this object. 01854 /*! 01855 Children will be rendered at the same moment as the object itself, the effect 01856 is that they appear at the same layer. 01857 The rendering style of the children will be based on their own layer id's or style properties. 01858 01859 \param samelayer if true render children on same layer 01860 */ 01861 inline void SetChildrenOnSameLayer(bool samelayer) { SetPending(true); m_flags.m_childrenOnSameLayer = samelayer; } 01862 01863 //!are children rendered on the same layer as this object? 01864 inline bool GetChildrenOnSameLayer() const { return m_flags.m_childrenOnSameLayer; } 01865 01866 //!set the object view dependent and maybe process all children to set these flags 01867 /*! 01868 \param aView view for adding next properties on this object and maybe its children. 01869 \param viewdependent if true, then add property 'PROPID_viewDependent' to objects 01870 that are depending on 'aView' view when it comes to size. 01871 Else to remove this property. 01872 \param viewspecific if true then add property 'PROPID_viewSpecific' to objects 01873 that are only visible on 'aView' view. 01874 Else to remove this property to make visible on all views. 01875 \param onlyinternalarea removing scale for children 01876 \param deep if true then set flags for all nested children objects 01877 */ 01878 void SetViewDependent(a2dCanvasView* aView, bool viewdependent, bool viewspecific = false, bool onlyinternalarea = false, bool deep = false ); 01879 01880 //! How a child is placed towards its parent object. 01881 /*! 01882 If set true this object as a child object is placed only relative to the position of the 01883 parent object. Rotation and scaling of parent object are ignored. 01884 */ 01885 inline void SetChildOnlyTranslate(bool onlytranslate) { SetPending(true); m_flags.m_ChildOnlyTranslate = onlytranslate; } 01886 01887 //!are children rendered using just the translation of the parent or also rotation and scale. 01888 inline bool GetChildOnlyTranslate() const { return m_flags.m_ChildOnlyTranslate; } 01889 01890 //! If set, this object has a higher priority in rendering than other children objects. 01891 /*! 01892 This method sets a priority in rendering: All children which have set 01893 the property m_prerenderaschild will be rendered before other children objects. 01894 01895 As default the a2dCanvasObject has no priority in rendering, you have to 01896 set this property to true, if you want prerendering. 01897 01898 \param prerender <code>true</code> to prerender this object, else <code>false</code> 01899 01900 */ 01901 inline void SetPreRenderAsChild(bool prerender) { SetPending(true); m_flags.m_prerenderaschild = prerender; } 01902 01903 //! Returns if this object should be rendered before other children objects. 01904 inline bool GetPreRenderAsChild() const { return m_flags.m_prerenderaschild; } 01905 01906 //!is the object filled flag set 01907 //!Rendering is only outline when set. 01908 bool GetFilled() const { return m_flags.m_filled; } 01909 01910 //!set the filled flag to render only outlines 01911 /*!Rendering is only outline when set. 01912 \remark set the object its pending flag and inform root about this 01913 \param filled if true set object filled 01914 */ 01915 void SetFilled(bool filled) { if (m_flags.m_filled != filled) SetPending(true); m_flags.m_filled = filled; } 01916 01917 //! If True shadow object is visible (if property is there) 01918 bool GetShowShadow() const { return m_flags.m_showshadow; } 01919 01920 //! If True shadow object is visible (if property is there) 01921 void SetShowShadow(bool showshadow) { m_flags.m_showshadow = showshadow; } 01922 01923 //! see SetResizeOnChildBox() 01924 bool GetResizeOnChildBox() const { return m_flags.m_resizeToChilds; } 01925 01926 //! If True resize to child boundingbox 01927 /*! 01928 In a2dCanvasObject::Update() a wxEVT_CANVASOBJECT_RESIZE_EVENT will be sent to this object. 01929 Default there is no handler for the event. 01930 */ 01931 void SetResizeOnChildBox(bool resizeToChilds ) { m_flags.m_resizeToChilds = resizeToChilds; } 01932 01933 //!quick way to get the style property containing Shadow property 01934 /*! style is maintained within an object as a a2dStyleProperty called __SHADOW__ 01935 \remark object is free to use style or not 01936 \sa a2dShadowStyleProperty 01937 */ 01938 const a2dShadowStyleProperty* GetShadowStyle() const ; 01939 01940 void CallDoRender( a2dIterC& ic, OVERLAP clipparent ) 01941 { 01942 DoRender( ic, clipparent ); 01943 } 01944 01945 protected: 01946 01947 const a2dFill& MX_GetFill() const; 01948 void MX_SetFill( const a2dFill& value ); 01949 const a2dStroke& MX_GetStroke() const; 01950 void MX_SetStroke( const a2dStroke& value ); 01951 01952 01953 //!render derived object 01954 /*!if the object has sub objects (apart from the childobject which are handled here), 01955 those subobject most rendered by iterating on layer when needed/wanted, simular to child objects. 01956 We do not iterate here, since that is only needed if indeed there or subobjects. 01957 This will be know in a "wxDerivedCanvasObject DoRender". 01958 01959 SO parent objects that call this function, must: 01960 01961 \li 1- clip object against area to redraw. 01962 \li 2- iterate on layers when needed. 01963 01964 A a2dCanvasObject is rendered as a + (plus sign) when there or no children. 01965 01966 */ 01967 virtual void DoRender( a2dIterC& WXUNUSED(ic), OVERLAP WXUNUSED(clipparent) ); 01968 01969 //! update transform matrix klion: I'm not sure that this function necessary as virtual 01970 virtual void DoUpdateViewDependentTransform( a2dIterC& ic ); 01971 01972 //! update derived objects 01973 virtual void DoUpdateViewDependentObjects( a2dIterC& WXUNUSED(ic) ); 01974 01975 //! render only the child objects 01976 /*! 01977 \param ic iteration context (has a2dCanvasView accumulative matrix to calculate absolute position of the object) 01978 \param whichchilds defined which childs will be rendered now, and detects while rendering other types. 01979 \param clipparent this must be the clip status of parent object. 01980 */ 01981 virtual void RenderChildObjects( a2dIterC& ic, RenderChild& whichchilds, OVERLAP clipparent ); 01982 01983 //!to render the child objects 01984 /*! 01985 \param ic iteration context (has a2dCanvasView accumulative matrix to calculate absolute position of the object) 01986 \param whichchilds defined which childs will be rendered now, and detects while rendering other types. 01987 \param clipparent this must be the clip status of parent object. 01988 */ 01989 virtual void RenderChildObjectsOneLayer( a2dIterC& ic, RenderChild& whichchilds, OVERLAP clipparent ); 01990 01991 //\} 01992 //****************** END RENDERING AND STYLE ******************/ 01993 01994 //****************** EDITING AND HIGHLIGHTING ******************/ 01995 /*! \name Editing and Highlighting 01996 */ 01997 //\{ 01998 public: 01999 02000 //!Sets if this object may be edited 02001 /*! 02002 If editable is set to <code>true</code> the object may be edited by an user. 02003 The default behaviour of this object is to allow modifications (editable). 02004 02005 \param editable <code>true</code> to allow modifications, else <code>false</code> 02006 */ 02007 inline void SetEditable(bool editable) { m_flags.m_editable = editable; } 02008 02009 //!get if the object may be edited 02010 inline bool GetEditable() const { return m_flags.m_editable; } 02011 02012 //!get if the object may be edited 02013 /*! 02014 Alias for GetEditable 02015 \see GetEditable 02016 */ 02017 inline bool IsEditable() const { return GetEditable(); } 02018 02019 //!is the object selected flag set 02020 /*! 02021 Rendering is different when set, it will use a special layer in this case. 02022 */ 02023 bool GetSelected() const { return m_flags.m_selected;} 02024 02025 //!Is the object selected flag set 02026 /*! 02027 Alias for GetSelected 02028 \see GetSelected 02029 */ 02030 bool IsSelected() const { return GetSelected();} 02031 02032 //!Set the object selected flag if allowed 02033 /*! 02034 When set the second rendering cycle from the document a2dCanvasDocument::Render() etc. 02035 will draw this object selected. 02036 02037 \remark sets the object its pending flag and inform root about this 02038 \param selected if true set object selected 02039 */ 02040 void SetSelected(bool selected) { 02041 if (m_flags.m_selectable) { if(m_flags.m_selected != selected) SetPending(true); m_flags.m_selected = selected;} } 02042 02043 //!is the object selectable flag set 02044 /*! 02045 \return <code>true</code> if object is selectable, else <code>false</code> 02046 */ 02047 bool GetSelectable() const { return m_flags.m_selectable; } 02048 02049 //! Is the object selectable flag set 02050 /*! 02051 Alias for GetSelectable 02052 \see GetSelectable 02053 */ 02054 bool IsSelectable() const { return GetSelectable(); } 02055 02056 //!Allows to select this object. 02057 /*! 02058 If selectable is set to <code>true</code> the object may be selected by an user. 02059 The default behaviour of this object is to allow selection. 02060 02061 \param selectable <code>true</code> to allow selection, else <code>false</code> 02062 */ 02063 void SetSelectable( bool selectable ) { m_flags.m_selectable = selectable; } 02064 02065 //!Sets if this object may be dragged 02066 /*! 02067 If draggable is set to <code>true</code> the object may be dragged by an user. 02068 The default behaviour of this object is to allow dragg-operations. 02069 02070 \param draggable <code>true</code> to allow selection, else <code>false</code> 02071 */ 02072 inline void SetDraggable(bool draggable) { m_flags.m_draggable = draggable; } 02073 02074 //!get if the object can be dragged 02075 inline bool GetDraggable() const { return m_flags.m_draggable; } 02076 02077 //!get if the object can be dragged 02078 /*! 02079 Alias for GetDraggable 02080 \see GetDraggable 02081 */ 02082 inline bool IsDraggable() const { return GetDraggable(); } 02083 02084 //!is snap flag set? 02085 bool GetSnap() const { return m_flags.m_snap; } 02086 02087 //!Sets snap flag 02088 /*! 02089 If snap is set to <code>true</code> this object is snapped by 02090 the restriction engine of a2dCanvasGlobal, when it is edited/moved etc. 02091 02092 \see Restrict 02093 */ 02094 void SetSnap( bool snap ) { m_flags.m_snap = snap; } 02095 02096 //!Sets snap_to flag 02097 /*! 02098 If snap is set to <code>true</code> others objects may snap to this object by 02099 the restriction engine of a2dCanvasGlobal. 02100 02101 \see Restrict 02102 */ 02103 void SetSnapTo( bool snap ) { m_flags.m_snap_to = snap; } 02104 02105 //!is snap_to flag set? 02106 bool GetSnapTo() const { return m_flags.m_snap_to; } 02107 02108 //! you may use it to modify rendering of the object depending on setting 02109 /*! 02110 Override this function to define a way to modify rendering for a derived object. 02111 02112 e.g. When hiting an object you could modify the rendering to notify it to the user. 02113 */ 02114 virtual void SetMode( int WXUNUSED(mode) ) {} 02115 02116 //! get the rendering mode of the object. 02117 virtual int GetMode() const { return 0; } 02118 02119 //! create an editcopy and initialize editing of the editcopy 02120 /*! This is called for an original object and creates an editcopy object. 02121 02122 Calls DoStartEdit() in the end 02123 02124 \param tool tool from which this function is called. Currently this is the a2dObjectEditTool 02125 \param editmode tobe used in derived object to switch between different way of editing 02126 ( 0 means matrix mode of a2dCanvasObject ) 02127 \param editstyle style of editing e.g. filled and stroked or with a wire frame. 02128 */ 02129 virtual a2dCanvasObject* StartEdit( a2dBaseTool* tool, wxUint16 editmode, wxEditStyle editstyle = wxEDITSTYLE_COPY ); 02130 02131 //! cleanup an editcopy object 02132 /*! 02133 This will Remove the editcopy from its parent. 02134 If editstyle is not wxEDITSTYLE_COPY, EditEnd is called for an original 02135 object, which is deprecated. The only tool using non wxEDITSTYLE_COPY is 02136 the wxMultEditTool, which will be changed. 02137 Calls DoEndEdit() first 02138 */ 02139 virtual void EndEdit(); 02140 02141 //! to restart editing in a different mode 02142 void ReStartEdit( wxUint16 editmode ); 02143 02144 //! if this is an editcopy, return the orginal else NULL 02145 a2dCanvasObject* GetOriginal(); 02146 02147 //! set a2dHandle position with the given name 02148 a2dHandle* SetHandlePos( wxString name, double x, double y ); 02149 02150 //!redirect all mouse events for the canvas to this object 02151 void CaptureMouse( a2dIterC& ic ); 02152 02153 //!release the mouse capture for this object 02154 void ReleaseMouse( a2dIterC& ic ); 02155 02156 //!is the mouse captured for this object 02157 bool IsCapturedMouse( a2dIterC& ic ) const ; 02158 02159 //! selected object itself or one of its recursive children 02160 bool GetHasSelectedObjectsBelow() const { return m_flags.m_HasSelectedObjectsBelow; } 02161 02162 //! selected object itself or one of its recursive children 02163 void SetHasSelectedObjectsBelow(bool value) { m_flags.m_HasSelectedObjectsBelow = value; } 02164 02165 //! tool object itself or one of its recursive children 02166 bool GetHasToolObjectsBelow() const { return m_flags.m_HasToolObjectsBelow; } 02167 02168 //! selected object itself or one of its recursive children 02169 void SetHasToolObjectsBelow(bool value) { m_flags.m_HasToolObjectsBelow = value; } 02170 02171 //!provide visual feedback by other objects that might participate in an editing 02172 /*!In some situations, e.g. when drawing wires or when draging objects in hierarchies, 02173 it is helpfull if other objects provide visual feedback, that they e.g. would 02174 accept the currently edited objects. If e.g. a wire is drawn, all pins that can 02175 accept the wire can turn green and all other pins can turn red. This function 02176 is usually called for the show object of a a2dCanvasView and goes down recursively. 02177 The id paramater identifies the editing situation. This is a a2dIdBase 02178 derived ID object, that is usually stored as a static member in a class. 02179 Objects that don't know a specific ID simply ignore it. 02180 Generally this function is called at least twice, once when the visual feedback 02181 should start, and once when it should end. 02182 02183 02184 Pins are tested for possible connection to pins on other objects. If some pin can connect 02185 the EditFeedback() with the feedback id a2dPin::sm_feedbackCanConnect is called on it. 02186 */ 02187 class A2DCANVASDLLEXP a2dFeedbackId : public a2dIdBase 02188 { 02189 02190 }; 02191 02192 //! feed back information of pins which can connect according to the 02193 /*! 02194 02195 When drawing new wires, pins that can accept a wire, can be set in a rendering mode to show this. 02196 This feedback set the pin rendering mode store as part of the feedback to a bin which is not yet connected 02197 and exists in the pin map table. 02198 */ 02199 class A2DCANVASDLLEXP a2dFeedbackIdPinMapping : public a2dFeedbackId 02200 { 02201 public: 02202 02203 //! constructor 02204 a2dFeedbackIdPinMapping() 02205 { 02206 } 02207 02208 //! when a pin is found that fits the map, the rendering mode of the pin is set to this. 02209 void SetMode( int mode ) { m_mode = mode; } 02210 02211 //! returns mode see SetMode() 02212 int GetMode() { return m_mode; } 02213 02214 //! Set task to perform 02215 void SetTask( a2dConnectTask task ) { m_task= task; } 02216 02217 //! get task to perform 02218 a2dConnectTask GetTask() { return m_task; } 02219 02220 //! Set mask 02221 void SetMask( wxUint32 mask ) { m_mask= mask; } 02222 02223 //! get mask 02224 wxUint32 GetMask() { return m_mask; } 02225 02226 //! set pinclass 02227 void SetPinClass( a2dPinClass * pinclass ) { m_pinclass = pinclass; } 02228 02229 //! return the pin class of this pin 02230 a2dPinClass *GetPinClass() const { return m_pinclass; } 02231 02232 protected: 02233 02234 //! modifies rendering 02235 int m_mode; 02236 //! 02237 a2dConnectTask m_task; 02238 02239 //! pin class for task 02240 a2dPinClass* m_pinclass; 02241 02242 //! mask for flags in pin 02243 wxUint32 m_mask; 02244 }; 02245 02246 //! tool editing feedback 02247 /*! 02248 \param ic iteration context 02249 \param id the id for the editing situation. 02250 \param currentEdit the currently edited object or another hint object 02251 \param depth recursion depth (0=this object, 1=this object+childs, ...) 02252 \param flags objects with this flag set ignore the depth limit 02253 \param x x world coordinate of mouse 02254 \param y y world coordinate of mouse 02255 */ 02256 virtual void EditFeedback( a2dIterC& ic, const a2dFeedbackId *id, a2dCanvasObject *currentEdit=0, int depth=INT_MAX, a2dCanvasObjectFlagsMask flags = a2dCanvasOFlags::NON, double x=0, double y=0 ); 02257 02258 //\} 02259 //****************** END EDITING AND HIGHLIGHTING ******************/ 02260 02261 //****************** SERIALIZATION, IDs AND REFERENCES *****************/ 02262 /*! \name Serialization, IDs and references 02263 In the CVG format one can store multiple references to one and the same object. 02264 The object that is referenced is only written once, for the rest only 02265 the reference id is written to the CVG file. 02266 When loading a file in CVG, such references are resolved inside the document. 02267 So in the end the old reference is restored via by searching the object having that id. 02268 As such the refid attribute is just a place holder for a reference to the actual referenced object. 02269 The reason behind all this, is that the actual object might to be read yet, when a reference 02270 is encountered in the CVG file, and therefore the link can not be directly created. 02271 In other formats references are used in a simular manner, and to resolve them the same mechanism 02272 is used. 02273 */ 02274 //\{ 02275 public: 02276 02277 //!Check if this is a temporary object, which should not be saved 02278 virtual bool IsTemporary_DontSave() const; 02279 02280 #if wxART2D_USE_CVGIO 02281 02282 //!write object specific CVGL data 02283 virtual void DoSave( wxObject* parent, a2dIOHandlerXmlSerOut &out, a2dXmlSer_flag xmlparts , a2dObjectList* towrite ); 02284 02285 //!load object specific CVG data 02286 virtual void DoLoad( wxObject* parent, a2dIOHandlerXmlSerIn& parser, a2dXmlSer_flag xmlparts ); 02287 02288 //! load one canvas object from a CVG file. 02289 void DoLoadOneObject( wxObject* parent, a2dIOHandlerXmlSerIn& parser, a2dXmlSer_flag xmlparts ); 02290 02291 #endif //wxART2D_USE_CVGIO 02292 02293 02294 //\} 02295 //**************** END SERIALIZATION, IDs AND REFERENCES ***************/ 02296 02297 //********************** CONNECTION PINS AND WIRES *********************/ 02298 /*! \name Connection via Pins and Wires 02299 02300 - a a2dCanvasObject can have a2dPin objects as childs. 02301 These objects can connect to other a2dPin's and thus to other objects. 02302 02303 - a2dPin objects know their parent, so that a communication path 02304 a2dCanvasObject (has child) a2dPin (is connected to) a2dPin (has parent) a2dCanvasObject 02305 exists. 02306 02307 - There are wire objects, that connect pins in objects and modify themselfes if the 02308 objects they connect move. A wire object overloads "IsConnect" to return true. 02309 02310 - Note: There are two quite different wire classes: a2dWires and a2dWirePolylineL. 02311 a2dWires is more like a least-distance "airline" network used e.g. in routing applications to 02312 show unconnected nets. 02313 a2dWirePolylineL is a usual polyline with wire functioanlity. 02314 Some of the functions apply to one type, one to the other type. 02315 */ 02316 //\{ 02317 public: 02318 02319 //! return true, if this object is used to connect other object's using rubberband like structures. 02320 virtual bool IsConnect() const { return false; } 02321 02322 //!used in case of flexible canvas objects (wires). 02323 /*! 02324 If another object connected to this object changes, and that has an effect on this 02325 object, return true; 02326 */ 02327 virtual bool NeedsUpdateWhenConnected() const { return false; } 02328 02329 //! if return true, connection with other object on this object its pins is allowed. 02330 /*! This is usually used for temporarily disabling connectivity */ 02331 bool DoConnect() { return m_flags.m_doConnect; } 02332 02333 //! If set to true this object may be connected to other object on its pins. 02334 /*! This is usually used for temporarily disabling connectivity */ 02335 void DoConnect( bool doconnect ) { m_flags.m_doConnect = doconnect; } 02336 02337 //! check connect to other object 02338 /*! After the call Pin objects which can connect, have their bin flag set. 02339 */ 02340 bool CanConnectWith( a2dIterC &ic, a2dCanvasObject* toConnect, bool autocreate ); 02341 02342 //! is the given pin close enough to another a2dPin to allow connection? 02343 /*! 02344 The default searches for a2dPin children in this object, and a pointer to the one which 02345 can connect with the given pin is returned. If non, returns NULL. 02346 02347 Before trying to connect to the object DoCanConnectWith() is called, here the object can be prepared 02348 to be able to connect to the given pin here. The default implementation asks the object to GeneratePins() 02349 if autoccreate is set true. 02350 02351 \param ic iteration context 02352 \param pin pin to check for connection to this object 02353 \param margin pin as to be this close. 02354 \param autocreate when true, pins maybe be created at the position in a derived object. 02355 02356 */ 02357 a2dPin* CanConnectWith( a2dIterC &ic, a2dPin* pin, double margin, bool autocreate ); 02358 02359 //! Is the object connected ( Optinal to specific object ) ? 02360 /*! 02361 \param needsupdate if true, only return true when connected Object(s) need an update. 02362 \param toConnect when not ( NULL ), the object needs to be connected with toConnect. 02363 */ 02364 bool IsConnected(bool needsupdate, a2dCanvasObject* toConnect = 0 ); 02365 02366 //! get connected objects that are connected to this object via its pins. 02367 /*! 02368 \param connected list to which connected objects will be added. 02369 \param needsupdate if true only connected objects which need updating will be added. 02370 */ 02371 bool GetConnected(a2dCanvasObjectList* connected, bool needsupdate); 02372 02373 //!Do connect with another a2dCanvasObject by pinname 02374 /*! 02375 If pinname is an empty string the pins that lie on top of each-other will be connected. 02376 Zero Length wires or objects (having pins on top of eachother) are not connected if already a connection exists. 02377 If needed (eg pin was already connected to another object) extra wires will be added to keep connection intact. 02378 */ 02379 virtual bool ConnectWith( a2dCanvasObject* parent, a2dCanvasObject* toconnect, const wxString& pinname=wxT(""), double margin = 1, bool undo = false ); 02380 02381 //!Do connect with another a2dCanvasObject by pin pointer 02382 /*! 02383 Searches this object for a pin, which is at the same position as the one given. 02384 If that pin allows connection, those pins will be connected. 02385 */ 02386 virtual bool ConnectWith( a2dCanvasObject* parent, a2dPin* pin, double margin = 1, bool undo = false ); 02387 02388 //! connect two pins 02389 /*! by creating a a2dWires object in between, unless already connected and 02390 they are exactly at the same position. 02391 They idea is to connect pins without changing there position, and keep already connected 02392 objects at the given pins connected also (to the wire object that is created ). 02393 */ 02394 virtual void ConnectPinsCreateConnect( a2dCanvasObject* parent, a2dPin* pinc, a2dPin* pinother, bool undo = false ); 02395 02396 //! connect two pins which must be unconnected and at the same position 02397 /*! 02398 This is a simple straight forward connection of the two pins. 02399 When Undo is true proper commands are issued to connect the pins. 02400 If the pins are already connected with something, they will be first disconnected. 02401 */ 02402 void ConnectPins( a2dCanvasObject* parent, a2dPin* pinc, a2dPin* pinother, bool undo = false ); 02403 02404 //!Do Disconnect from another a2dCanvasObject by pin name 02405 /*! 02406 If toConnect = NULL all objects will be disconnected. 02407 If pinname is an empty string the pins connected to toConnect will be dis-connected, 02408 else only the ones with the pinname will be disconnected. 02409 */ 02410 virtual bool DisConnectWith( a2dCanvasObject* parent, a2dCanvasObject* toConnect = NULL, const wxString& pinname = wxT("") ); 02411 02412 //!Do Disconnect from another a2dCanvasObject by pin pointer 02413 /*! 02414 Disconnect at pin (of object or of connected object). 02415 */ 02416 virtual bool DisConnectAt( a2dCanvasObject* parent, a2dPin* pin ); 02417 02418 //! rewire the object to keep connection or to make connection with other objects 02419 void ReWireConnected( a2dCanvasObject* parent, bool undo = false ); 02420 02421 //! create wires on pins which do not have wires, but directly are connected to other objects. 02422 /*! 02423 This prepares the object for dragging/moving, while preserving the connection, since then wires will 02424 be rerouted when dragging. 02425 */ 02426 bool CreateWiresOnPins( a2dCanvasObject* parent, bool undo ); 02427 02428 //! set connected pending or not pending 02429 /*! 02430 \param onoff set connected object pending or not pending 02431 \param needsupdateonly if true only connected object which need updating will treated. 02432 */ 02433 bool SetConnectedPending( bool onoff, bool needsupdateonly ); 02434 02435 //!are there a2dPin derived children 02436 /*! 02437 \param realcheck if true checks all children else the flag m_flags.m_hasPins is returned 02438 \remark if realcheck is true also the m_flags.m_hasPins will be updated. 02439 */ 02440 bool HasPins( bool realcheck = false ); 02441 02442 //!are there a2dPin derived children which matches the given pin name? 02443 /*! 02444 \param pinName the name of the pin to search for ( uses wxString::Matches() ). 02445 \param NotConnected if true the pin must be unconnected too. 02446 02447 \return the a2dPin object found or NULL 02448 02449 \remark the m_flags.m_hasPins is ignored here for the moment 02450 */ 02451 a2dPin* HasPinNamed( const wxString pinName, bool NotConnected = false ); 02452 02453 //!How many a2dPin derived children are there. 02454 int GetPinCount(); 02455 02456 //! create pins in derived objects. 02457 /*! 02458 When wanting to connect to shapes which at construction have no pins, but still make sence 02459 to connect too, this function generates pins for the object, when connection is asked for by a tool. 02460 This is via EditFeedBack() 02461 02462 The idea is to generate temporary pins for the tools, so the user sees where connection are possible. 02463 02464 \param toConnectTo the pinClass to which the generated pin must be able to connect. 02465 \param task what/how to connect 02466 \param x x position of mouse or pin which wants/needs connection 02467 \param y y position of mouse or pin which wants/needs connection 02468 */ 02469 virtual bool GeneratePins( a2dPinClass* WXUNUSED(toConnectTo), a2dConnectTask WXUNUSED(task), double WXUNUSED(x), double WXUNUSED(y) ) { return false; } 02470 02471 //! Allow change in pin location when wiring things up. 02472 virtual bool AdjustPinLocation() { return false; } 02473 02474 //! generates pins on all possible locations where the object can be connected. 02475 /*! 02476 Default calls pinClass->GetConnectionGenerator()->GeneratePossibleConnections() 02477 And that leads to calling a2dCanvasObject::GeneratePins() 02478 This way a a2dConnectionGenerator can limit the pins which are generated. 02479 02480 \param pinClass if not NULL, only generate temporary pins that may connect to this pinClass. 02481 \param task what/how to connect 02482 \param x can be used to create pins depending on the poition of the mouse inside the object. 02483 \param y can be used to create pins depending on the poition of the mouse inside the object. 02484 */ 02485 virtual bool GeneratePinsPossibleConnections( a2dPinClass* pinClass, a2dConnectTask task, double x, double y ); 02486 02487 //! based on the a2dPinClass's of eventually a2dPin's wanted in both objects, a 02488 /*! connection object will be delivered as a template to be cloned by the caller. 02489 In principle calling this->GetConnectTemplate() and other->GetConnectTemplate() 02490 should result in the same. 02491 The default implementation uses a2dCanvasGlobals->GetPinClassMaps() which is a simple system 02492 to supply a template object based ob the two entry maps. 02493 You can override this function to define your own way of connections. 02494 */ 02495 virtual a2dCanvasObject* GetConnectTemplate( a2dPinClass* mapThis, a2dCanvasObject* other, a2dPinClass* mapOther ) const; 02496 02497 //! generates a connection object with pins and all. 02498 /*! 02499 Default calls pinThis->GetConnectionGenerator()->CreateConnectObject() 02500 This way a a2dConnectionGenerator can decide on the type of object to generate 02501 as a plugin. 02502 */ 02503 virtual a2dCanvasObject* CreateConnectObject( a2dCanvasObject* parent, a2dPin* pinThis, a2dPin* pinOther, bool undo = false ) const; 02504 02505 //! add a a2dPin as child 02506 /*! 02507 \param name name which the pin will get 02508 \param x x-position of pin 02509 \param y y-position of pin 02510 \param a2dpinFlags 02511 - a2dPin::dynamic if true pin will be dynamic 02512 - a2dPin::temporary if true pin will be temporary 02513 - a2dPin::objectPin if true pin is seen as part of an object and not a wire/connect 02514 \param pinClass pinClass of the pin, created pin cloned from a2dPinClass->GetPin() 02515 02516 \return the pin that was created and added to the object. 02517 */ 02518 a2dPin* AddPin( const wxString name, double x, double y, wxUint32 a2dpinFlags, a2dPinClass* pinClass ); 02519 02520 //! Remove all a2dPin children 02521 /*! 02522 \param NotConnected when true only pins which are not connected tp another pin will be deleted 02523 \param onlyTemporary when true only pins with the temporary flag set 02524 using a2dPin::SetTemporaryPin() will be deleted. 02525 These type of pins are used in automatic connection situations, and often 02526 after an editing attempt of other objects need to be deleted in the end. 02527 \param now if true remove pin object now!, else only delete flag is set, 02528 and it will be deleted in idle time. 02529 */ 02530 void RemovePins( bool NotConnected = false, bool onlyTemporary = false, bool now = false ); 02531 02532 //! Set a2dPin children visible or not 02533 void ShowPins( bool onoff ); 02534 02535 //! Calls a2dPin::SetRenderConnected() for all pins 02536 /*! By default connected pins are not rendered, you can set it true for all pins here. 02537 But you can also set each pin individual. 02538 */ 02539 void SetRenderConnectedPins( bool onoff ); 02540 02541 //! Find and clone all wires ( IsConnect()==true ) connected to this object or to such wires 02542 /*! After this function you must call copies->RestoreConnectionsAfterCloning() 02543 \param originals list of original wire objects 02544 \param copies list of wire object edit copies 02545 */ 02546 void CreateWireEditCopies( a2dCanvasObjectList *originals, a2dCanvasObjectList *copies ); 02547 02548 //! Restore connections after cloning 02549 /*! After cloning a tree of connected objects, this will restore 02550 the connections in the clone as they have been in the original 02551 \param cp if not 0, the connections are created by issuing a2dCommand_ConnectPins commands 02552 */ 02553 virtual void RestoreConnectionsAfterCloning( class a2dCanvasCommandProcessor *cp = 0 ); 02554 02555 //! Remove all pin connections by issuing a2dCommand_ConnectPins commands 02556 /*! This should be done before a a2dCommand_ReleaseObject is issued. 02557 \param cp the command processor receiving the commands 02558 */ 02559 virtual void ClearAllPinConnections( class a2dCanvasCommandProcessor *cp ); 02560 02561 //! set parent object of the pin or some other objects that needs a parent 02562 virtual void SetParent( a2dCanvasObject* WXUNUSED(parent) ) {}; 02563 02564 protected: 02565 02566 //! prepare an object for being connected to a given pin 02567 /*! 02568 Before trying to connect in CanConnectWith() to the object DoCanConnectWith() is called, 02569 here thy object can be prepared to be able to connect to the given pin here. 02570 The default implementation ask the object to GeneratePins() if autoccreate is set true. 02571 02572 In a derived class one can do more complicated to decide if a pin needs to be created or not. 02573 */ 02574 virtual bool DoCanConnectWith( a2dIterC &ic, a2dPin* pin, double margin, bool autocreate ); 02575 02576 //\} 02577 //******************** END CONNECTION PINS AND WIRES********************/ 02578 02579 //********************** PROPERTIES *********************/ 02580 /*! \name Properties 02581 a a2dCanvasObject has a list of general named properties 02582 */ 02583 //\{ 02584 public: 02585 02586 //! a2dCanvasObject set as property will be rendered after all other child objects 02587 //! when it is rendreed from a parent a2dCanvasObject 02588 inline void SetIsProperty(bool IsProperty ) { SetPending(true); m_flags.m_IsProperty = IsProperty; } 02589 02590 //! a2dCanvasObject set as property will be rendered after all other child objects 02591 //! when it is rendreed from a parent a2dCanvasObject 02592 inline bool GetIsProperty() const { return m_flags.m_IsProperty; } 02593 02594 //! quickly set a property name __OBJECTTIP__ 02595 /*! 02596 This function stores an OBJECTTIP property which will be shown when mouse is within an object. 02597 02598 \param tip the tip which should be shown 02599 \param x x-pos of the tip 02600 \param y y-pos of the tip 02601 \param size font-size in world coordinates (font size of the font-param will be ignored, see a2dText documentation) 02602 \param angle rotation in degrees 02603 \param font the font to use 02604 02605 \return a pointer to the a2dText object used to show the tip. 02606 */ 02607 a2dText* SetObjectTip( const wxString& tip, double x, double y, double size = 30, double angle = 0, 02608 const a2dFont& font = *a2dDEFAULT_CANVASFONT ); 02609 02610 //! quickly set a property a2dTipWindowProperty 02611 /*! 02612 This function stores a a2dTipWindowProperty property which will be shown when mouse is within an object. 02613 The function a2dCanvasObject::OnEnterObject() will show it. 02614 02615 \param tip the tip which should be shown 02616 */ 02617 void SetTipWindow( const wxString& tip ); 02618 02619 //! quickly get first property with name __OBJECTTIP__ 02620 a2dObject* GetObjectTip(); 02621 02622 //! edit properties of the object 02623 /*! 02624 This default implementation distributes the a2dPropertyEditEvent with 02625 id wxEVT_PROPOBJECT_EDITPROPERTIES_EVENT, to a2dDocviewGlobals->GetEventDistributer(). 02626 02627 This can be intercepted by any registrated class in order to edit the properties. 02628 When after return, the event its GetEdited() returns true, this indicates that the 02629 properties where indeed edited. 02630 02631 \param id If property id is set only matching properties are selected 02632 \param withUndo If true, the changes can be undone later. 02633 */ 02634 virtual bool EditProperties( const a2dPropertyId *id, bool withUndo ); 02635 02636 //! This function is called after a property changed 02637 /*! This is overloaded to set e.g. a pending flag 02638 */ 02639 void OnPropertyChanged( const a2dPropertyId* id ); 02640 02641 //\} 02642 //**************** END PROPERTIES ***************/ 02643 02644 //********************** FLAGS *********************/ 02645 /*! \name Flags 02646 a a2dCanvasObject has some falgs for general and algorithmic use. 02647 Other flags have special meaning or are used internally. The flags with special 02648 meaning (e.g. m_visible) are detailed in the proper sections. 02649 */ 02650 //\{ 02651 public: 02652 02653 //!set all bit flags in object that or true in mask to true or false 02654 /*! 02655 set specific flags to true or false 02656 02657 \remark the object is not setpending when something changed ( actually the pending flag can be set here also ) 02658 02659 \param setOrClear if true sets the flag to true else to false 02660 \param which set only those flags in object to true or false 02661 */ 02662 void SetSpecificFlags( bool setOrClear, a2dCanvasObjectFlagsMask which ); 02663 02664 //!Compares all flags in object to the given mask and return true is the same. 02665 bool CheckMask( a2dCanvasObjectFlagsMask mask) const; 02666 02667 //!set bit flags of object (true or false) to given newmask values 02668 /*! 02669 \remark does not recurse into children 02670 02671 \param newmask mask to set flags to in object (either true or false) 02672 */ 02673 void SetFlags( a2dCanvasObjectFlagsMask newmask ); 02674 02675 //!get specific bitflag value 02676 bool GetFlag( const a2dCanvasObjectFlagsMask which ) const; 02677 02678 //!get bitflags as an integer 02679 a2dCanvasObjectFlagsMask GetFlags() const; 02680 02681 //!general flag use at will. 02682 /*! 02683 \remark 02684 This flag should only be used for temporarly purposes. 02685 This object uses this flag too and you might run into problems if you use this flag. 02686 It's a good practice to set this flag if you need it and reset this flag to <code>false</code> 02687 if you don't need it anymore. Another possibility might be to add a new property to this object 02688 if you want to be on the secure side. 02689 02690 \param bin temporarely status information 02691 */ 02692 inline void SetBin(bool bin) { m_flags.m_bin = bin; } 02693 02694 //!general flag use at will. 02695 inline bool GetBin() const {return m_flags.m_bin;} 02696 02697 //!get the groupA flag 02698 /*! used to define operands in operation on two groups of objects 02699 */ 02700 bool GetGroupA() const { return m_flags.m_a; } 02701 02702 //!set the groupA flag 02703 /*! used to define operands in operation on two groups of objects 02704 \param value true to set group flag A 02705 */ 02706 void SetGroupA( bool value ) { SetPending(true); m_flags.m_a = value; } 02707 02708 //!get the groupA flag 02709 /*! used to define operands in operation on two groups of objects 02710 */ 02711 bool GetGroupB() const { return m_flags.m_b; } 02712 02713 //!set the groupA flag 02714 /*! used to define operands in operation on two groups of objects 02715 \param value true to set group flag B 02716 */ 02717 void SetGroupB( bool value ) { SetPending(true); m_flags.m_b = value; } 02718 02719 //!get the GeneratePins flag 02720 /*! used to define operands in operation on two groups of objects 02721 */ 02722 bool GetGeneratePins() const { return m_flags.m_generatePins; } 02723 02724 //!set the GeneratePins flag 02725 /*! used to define operands in operation on two groups of objects 02726 \param value true to set group flag C 02727 */ 02728 void SetGeneratePins( bool value ) { SetPending(true); m_flags.m_generatePins = value; } 02729 02730 //!set IgnoreSetpending flag 02731 /*!If this flag is set, the object will be not be set pending in SetPending()*/ 02732 void SetIgnoreSetpending( bool value = true ) { m_flags.m_ignoreSetpending = value; } 02733 02734 //!get IgnoreSetpending flag 02735 /*!If this flag is set, the object will be not be set pending in SetPending()*/ 02736 bool GetIgnoreSetpending( ) const { return m_flags.m_ignoreSetpending; } 02737 02738 //!set static IgnoreAllSetpending flag 02739 /*!If this flag is set, all a2dCanvasObject will be not be set pending in SetPending()*/ 02740 static void SetIgnoreAllSetpending( bool value = true ) { m_ignoreAllSetpending = value; } 02741 02742 //!get static IgnoreSetpending flag 02743 /*!If this flag is set, all a2dCanvasObject will be not be set pending in SetPending()*/ 02744 static bool GetIgnoreAllSetpending( ) { return m_ignoreAllSetpending; } 02745 02746 void SetIgnoreLayer( bool value = true ) { m_flags.m_ignoreLayer = value; } 02747 02748 bool GetIgnoreLayer( ) const { return m_flags.m_ignoreLayer; } 02749 02750 void SetSubEdit( bool value ) { m_flags.m_subEdit = value; } 02751 bool GetSubEdit( ) const { return m_flags.m_subEdit; } 02752 void SetSubEditAsChild( bool value ) { m_flags.m_subEditAsChild = value; } 02753 bool GetSubEditAsChild( ) const { return m_flags.m_subEditAsChild; } 02754 void SetShowshadow( bool value ) { m_flags.m_showshadow = value; } 02755 bool GetShowshadow( ) const { return m_flags.m_showshadow; } 02756 void SetPushin( bool value ) { m_flags.m_pushin = value; } 02757 bool GetPushin( ) const { return m_flags.m_pushin; } 02758 void SetBin2( bool value ) { m_flags.m_bin2 = value; } 02759 bool GetBin2( ) const { return m_flags.m_bin2; } 02760 void SetPrerenderaschild( bool value ) { m_flags.m_prerenderaschild = value; } 02761 bool GetPrerenderaschild( ) const { return m_flags.m_prerenderaschild; } 02762 void SetVisiblechilds( bool value ) { m_flags.m_visiblechilds = value; } 02763 bool GetVisiblechilds( ) const { return m_flags.m_visiblechilds; } 02764 void SetEditing( bool value ) { m_flags.m_editing = value; } 02765 bool GetEditing( ) const { return m_flags.m_editing; } 02766 void SetEditingRender( bool value ) { m_flags.m_editingCopy = value; } 02767 bool GetEditingRender( ) const { return m_flags.m_editingCopy; } 02768 void SetDoConnect( bool value ) { m_flags.m_doConnect = value; } 02769 bool GetDoConnect( ) const { return m_flags.m_doConnect; } 02770 void SetIsOnCorridorPath( bool value ) { m_flags.m_isOnCorridorPath = value; } 02771 bool GetIsOnCorridorPath( ) const { return m_flags.m_isOnCorridorPath; } 02772 void SetHasPins( bool value ) { m_flags.m_hasPins = value; } 02773 bool GetHasPins( ) const { return m_flags.m_hasPins; } 02774 void SetMouseInObject( bool value ) { m_flags.m_MouseInObject = value; } 02775 bool GetMouseInObject( ) const { return m_flags.m_MouseInObject; } 02776 void SetHighLight( bool value ) { m_flags.m_HighLight = value; } 02777 bool GetHighLight( ) const { return m_flags.m_HighLight; } 02778 02779 //! sents a layer change event around. 02780 void SentChangeLayerEvent( wxUint16 layer ); 02781 02782 protected: 02783 02784 //\} 02785 //**************** END FLAGS ***************/ 02786 02787 //********************** LAYERS *********************/ 02788 /*! \name Layers 02789 a a2dCanvasDocument is rendered in layers. Every canvas object belongs to excatly 02790 one layer. 02791 */ 02792 //\{ 02793 public: 02794 02795 //! Returns the layer index where this object is drawn upon. 02796 /*! 02797 The order of the a2dLayers in the root object decides if and when it will be drawn. 02798 02799 \see a2dCanvasDocument::SetLayerSetup 02800 \see a2dLayers 02801 */ 02802 inline wxUint16 GetLayer() const { return m_layer; } 02803 02804 //!set layer index where this object is drawn upon. 02805 /*! 02806 Default is layer wxLAYER_DEFAULT (colours etc taken from layer list) 02807 Some layers are predefined and used for special purposes (i.e. for selection of 02808 an object etc.). Please refer to wxLayerNames. 02809 If you want to define your own layer you should give it a value between 02810 <code>wxLAYER_USER_FIRST</code> and <code>wxLAYER_USER_LAST</code> 02811 (<code>wxLAYER_USER_FIRST <= myLayerIndex <= wxLAYER_USER_LAST</code>) 02812 02813 \see wxLayerNames 02814 \see a2dLayerInfo 02815 \see a2dLayers 02816 02817 \param layer the index of the layer 02818 */ 02819 virtual void SetLayer( wxUint16 layer ); 02820 02821 //\} 02822 //**************** END LAYERS ***************/ 02823 02824 //********************** APPLICATION SPECIFIC EXTENSIONS *********************/ 02825 /*! \name Application specific extensions. 02826 The functions in this section can be used to extend the functionality of 02827 a2dCanvasObject without adding new virtual member functions to the base class. 02828 */ 02829 //\{ 02830 public: 02831 02832 //!call fp for each object 02833 void foreach_f(void (*fp) (a2dCanvasObject* item) ); 02834 02835 //!call fp for each object 02836 void foreach_mf(void (a2dCanvasObject::*mfp) () ); 02837 02838 //!can be used by the user to implement a function that affects all a2dCanvas derived objects 02839 virtual bool UserBaseFunction() { return true;} 02840 02841 //!can be used by the user to implement a function that affects all a2dCanvas derived objects 02842 /*! 02843 a2dIOHandler can be used to transfer data to the function, for example a a2dWalkerIOHandler handler 02844 can be used to iterate the document, and calll this function on every object wanted. 02845 02846 \param function function id, to be able to use this function for more tasks. 02847 \param handler a2dIOHandler which was use to iterate the document 02848 */ 02849 virtual bool UserBaseFunctionEx( int WXUNUSED(function), a2dIOHandler* WXUNUSED(handler) = NULL ) { return true; } 02850 02851 //!can be used by the user to implement a function using a variable argument list that affects all a2dCanvas derived objects 02852 virtual bool UserBaseFunctionVar(...) { return true;} 02853 02854 //!can be used by the user to implement a function using a variable argument list and format string that affects all a2dCanvas derived objects 02855 virtual bool UserBaseFunctionFormat(wxString format,...) { return true;} 02856 02857 //! This is used to recursively walk through an object tree 02858 void WalkerWithContext( a2dIterC& ic, wxObject* parent, a2dWalkerIOHandlerWithContext& handler ); 02859 02860 protected: 02861 02862 //! iterate over this object and its children 02863 /*! 02864 This function allows you to extend the functionality of all a2dCanvasObject classes 02865 in a a2dCanvasDocument, without adding extra members to these objects. 02866 02867 Default functions are called on the a2dWalkerIOHandler, which redirect the 02868 calls to other functions based on this object its classname. 02869 On can register classes to a2dWalkerIOHandler or derived classes. 02870 This way for each unique object in the document there can be a function 02871 in a2dWalkerIOHandler. 02872 02873 \return false if some object did not have a function attached via a2dWalkerIOHandler. 02874 02875 See a2dWalkerIOHandler for more. 02876 */ 02877 virtual void DoWalker( wxObject* parent, a2dWalkerIOHandler& handler ); 02878 02879 // used if context is needed. 02880 virtual void DoWalkerWithContext( a2dIterC& ic, wxObject* parent, a2dWalkerIOHandlerWithContext& handler ); 02881 02882 //\} 02883 //********************** END APPLICATION SEPCIFIC EXTENSIONS *********************/ 02884 02885 //********************** DEBUGGING *********************/ 02886 /*! \name Debugging functions 02887 These functions are only enabled in Debug mode 02888 */ 02889 //\{ 02890 public: 02891 #ifdef _DEBUG 02892 02893 //! Dump an Object with its childs and properties 02894 /*! Note: this function is not virtual, because virtual functions cannot 02895 be called from the debugger 02896 */ 02897 void Dump( int indent = 0 ); 02898 //! Called by Dump to Dump class specific stuff 02899 /*! Add class specific info to line or output line and create a new line */ 02900 virtual void DoDump( int indent, wxString *line ); 02901 02902 #endif 02903 //\} 02904 02905 //! when implemented the object without its children, is converted to 02906 /*! 02907 to a list of a2dVectorPath's. 02908 Else wxNullCanvasObjectList is returned. 02909 */ 02910 virtual a2dCanvasObjectList* GetAsCanvasVpaths( bool transform = true ); 02911 02912 void SetTemplate( bool b = true ); 02913 void SetExternal( bool b = true ); 02914 void SetUsed( bool b = true ); 02915 02916 bool GetTemplate() const ; 02917 bool GetExternal() const ; 02918 bool GetUsed() const ; 02919 02920 protected: 02921 02922 bool ProcessCanvasEventChild( a2dIterC& ic, RenderChild& whichchilds, a2dHitEvent& hitEvent ); 02923 02924 bool ProcessCanvasEventChildOneLayer( a2dIterC& ic, RenderChild& whichchilds, a2dHitEvent& hitEvent ); 02925 02926 public: 02927 02928 //!only used for editable objects and under control of a editing tool. 02929 /*! 02930 If object is editable this function is used to initialize the object for editing. 02931 In general this means adding editing handles to the child list. 02932 In the event handling of the object those handles are hit and moved, the object itself 02933 is changed accordingly. 02934 02935 \return true is this object can be edited and is initialized for that. 02936 */ 02937 virtual bool DoStartEdit( wxUint16 editmode, wxEditStyle editstyle ); 02938 02939 protected: 02940 02941 virtual bool DoIgnoreIfNotMember( const a2dPropertyId &id ); 02942 02943 //!root group for rendering and accessing the canvas's also contains layer settings 02944 a2dCanvasDocument* m_root; 02945 02946 //!holds flags for objects 02947 a2dCanvasOFlags m_flags; 02948 02949 //!holds value for flags to initialize m_flags 02950 static a2dCanvasOFlags m_flagsInit; 02951 02952 //!allow hits on basis of those flags 02953 a2dCanvasOHitFlags m_hitflags; 02954 02955 //!boundingbox in world coordinates 02956 a2dBoundingBox m_bbox; 02957 02958 //! world extend in world coordinates. 02959 /*! 02960 Normally contains at least the stroke width when this is in world coordinates. 02961 */ 02962 float m_worldExtend; 02963 02964 //! Pixel extend 02965 /*! 02966 In case of pixel object or partial pixel object or pixel strokes, 02967 this will contain the needed oversize on top of the boundingbox. 02968 It is to be set in Update() or OnUpdate() 02969 */ 02970 wxUint16 m_pixelExtend; 02971 02972 //!layer of object, default wxLAYER_DEFAULT 02973 wxUint16 m_layer; 02974 02975 //!used for positioning the object (x,y,ang,scale etc.) 02976 a2dAffineMatrix m_lworld; 02977 02978 //!holds child objects 02979 a2dCanvasObjectList* m_childobjects; 02980 02981 //! parse Cvg transform of object 02982 bool ParseCvgTransForm( a2dAffineMatrix& result, a2dIOHandlerXmlSerIn& parser ); 02983 02984 //!called by addPending 02985 virtual void DoAddPending( a2dIterC& ic ); 02986 02987 //! In derived object this should be overriden to calculate the boundingbox of the object without its children. 02988 /*! 02989 The default return a non Valid boundingbox. 02990 02991 The real boundingbox of the object is often less desirable for editing. e.g. a rectangle with a contour, 02992 one does not want editing handles on the contour, instead they should still be on the basic rectangle. 02993 */ 02994 virtual a2dBoundingBox DoGetUnTransformedBbox( a2dBboxFlags flags = a2dCANOBJ_BBOX_NON ) const; 02995 02996 //!Update derived Object specific things ( mainly boundingbox) 02997 /*! 02998 Calculates the boundingbox of the object (exclusif base class child objects but with other nested objects). 02999 03000 \param mode way to update the objects 03001 \param childbox size of children boundingbox 03002 \param clipbox clip to this 03003 \param propbox size of properties boundingbox 03004 03005 \remark in a derived class this function can also be used to update object specific cache data. 03006 03007 \remark force may or may not have direct influence on the object itself, if this function is called directly 03008 for some reason (e.g from derived objects), you must invalidate the boudingbox yourself. 03009 GetDrawerBox()->SetValid( false ); 03010 */ 03011 virtual bool DoUpdate( UpdateMode mode, const a2dBoundingBox& childbox, const a2dBoundingBox& clipbox, const a2dBoundingBox& propbox ); 03012 03013 //!only used for editable objects and under control of a editing tool. 03014 /*! 03015 Do a clean up at the end of an editing sesion of the object. 03016 In general this means, remove editing handles from child list. 03017 */ 03018 virtual void DoEndEdit() {}; 03019 03020 public: 03021 03022 //! when set all SetPending() calss are supressed. 03023 static bool m_ignoreAllSetpending; 03024 03025 // member ids 03026 static a2dPropertyIdMatrix* PROPID_TransformMatrix; 03027 static a2dPropertyIdPoint2D* PROPID_Position; 03028 static a2dPropertyIdUint16* PROPID_Layer; 03029 static a2dPropertyIdBool* PROPID_Selected; 03030 static a2dPropertyIdBool* PROPID_Selectable; 03031 static a2dPropertyIdBool* PROPID_SubEdit; 03032 static a2dPropertyIdBool* PROPID_SubEditAsChild; 03033 static a2dPropertyIdBool* PROPID_Visible; 03034 static a2dPropertyIdBool* PROPID_Draggable; 03035 static a2dPropertyIdBool* PROPID_Showshadow; 03036 static a2dPropertyIdBool* PROPID_Filled; 03037 static a2dPropertyIdBool* PROPID_GroupA; 03038 static a2dPropertyIdBool* PROPID_GroupB; 03039 static a2dPropertyIdBool* PROPID_GeneratePins; 03040 static a2dPropertyIdBool* PROPID_Bin; 03041 static a2dPropertyIdBool* PROPID_Bin2; 03042 static a2dPropertyIdBool* PROPID_Pending; 03043 static a2dPropertyIdBool* PROPID_Snap; 03044 static a2dPropertyIdBool* PROPID_SnapTo; 03045 static a2dPropertyIdBool* PROPID_Pushin; 03046 static a2dPropertyIdBool* PROPID_Prerenderaschild; 03047 static a2dPropertyIdBool* PROPID_Visiblechilds; 03048 static a2dPropertyIdBool* PROPID_Editable; 03049 static a2dPropertyIdBool* PROPID_Editing; 03050 static a2dPropertyIdBool* PROPID_EditingRender; 03051 static a2dPropertyIdBool* PROPID_ChildrenOnSameLayer; 03052 static a2dPropertyIdBool* PROPID_DoConnect; 03053 static a2dPropertyIdBool* PROPID_IsOnCorridorPath; 03054 static a2dPropertyIdBool* PROPID_HasPins; 03055 static a2dPropertyIdBool* PROPID_IsProperty; 03056 static a2dPropertyIdBool* PROPID_MouseInObject; 03057 static a2dPropertyIdBool* PROPID_HighLight; 03058 static a2dPropertyIdBool* PROPID_Template; 03059 static a2dPropertyIdBool* PROPID_External; 03060 static a2dPropertyIdBool* PROPID_Used; 03061 static a2dPropertyIdBool* PROPID_Release; 03062 03063 // commonly used member ids in derived classes 03064 static a2dPropertyIdCanvasObject* PROPID_Begin; 03065 static a2dPropertyIdCanvasObject* PROPID_End; 03066 static a2dPropertyIdDouble* PROPID_EndScaleX; 03067 static a2dPropertyIdDouble* PROPID_EndScaleY; 03068 static a2dPropertyIdBool* PROPID_Spline; 03069 static a2dPropertyIdDouble* PROPID_ContourWidth; 03070 03071 // property ids 03072 static a2dPropertyIdBool* PROPID_Allowrotation; 03073 static a2dPropertyIdBool* PROPID_Allowsizing; 03074 static a2dPropertyIdBool* PROPID_Allowskew; 03075 static a2dPropertyIdBool* PROPID_IncludeChildren; 03076 static a2dPropertyIdRefObjectAutoZero* PROPID_Controller; 03077 static a2dPropertyIdCanvasObject* PROPID_Original; 03078 static a2dPropertyIdCanvasObject* PROPID_Editcopy; 03079 static a2dPropertyIdCanvasObject* PROPID_Parent; 03080 static a2dPropertyIdCanvasObject* PROPID_Objecttip; 03081 static a2dPropertyIdUint16* PROPID_Editmode; 03082 static a2dPropertyIdUint16* PROPID_Editstyle; 03083 static a2dPropertyIdUint16* PROPID_Index; 03084 static a2dPropertyIdCanvasShadowStyle* PROPID_Shadowstyle; 03085 static a2dPropertyIdFill* PROPID_Fill; 03086 static a2dPropertyIdStroke* PROPID_Stroke; 03087 static a2dPropertyIdInt32* PROPID_UpdateImmediatePriority; 03088 static a2dPropertyIdUint32* PROPID_RefDesCount; 03089 static a2dPropertyIdUint32* PROPID_RefDesNr; 03090 03091 //! set for objects that act as tool decorations, when a tool is in action. 03092 static a2dPropertyIdBool* PROPID_ToolDecoration; 03093 03094 //! set for objects that act as tool object, when a tool is in action. 03095 static a2dPropertyIdVoidPtr* PROPID_ToolObject; 03096 03097 //! set for objects that do not have to be saved 03098 static a2dPropertyIdBool* PROPID_TemporaryObject; 03099 03100 //! used to store state ( redraw area) of the object as it was before a change 03101 static a2dPropertyIdBoundingBox* PROPID_BoundingBox; 03102 03103 static a2dPropertyIdColour* PROPID_StrokeColour; 03104 static a2dPropertyIdColour* PROPID_FillColour; 03105 03106 //! when an object should only be rendered in the view pointed to by this property. 03107 //! This is tipically used when using tool object. 03108 static a2dPropertyIdRefObject* PROPID_ViewSpecific; 03109 03110 //! set in Startedit(), to be used to detect first (mouse)event sent to object. 03111 static a2dPropertyIdBool* PROPID_FirstEventInObject; 03112 03113 //! used in GDSII and KEY format to specify the DATATYPE of elements 03114 /*! GDSII compatible to sub identify this object. 03115 you can use it as a special tagged object 03116 */ 03117 static a2dPropertyIdUint16* PROPID_Datatype; 03118 03119 //! used for objects that depend on 'aView' view when it comes to size. 03120 static a2dPropertyIdRefObject* PROPID_ViewDependent; 03121 //! used for objects with* PROPID_viewDependent but only for internal area 03122 static a2dPropertyIdMatrix* PROPID_IntViewDependTransform; 03123 03124 //! when an object is removed from a layer, 03125 const static wxEventType sm_changedLayer; 03126 03127 //! some time property which a user wants to store 03128 static a2dPropertyIdDateTime* PROPID_DateTime; 03129 03130 static a2dPropertyIdDateTime* PROPID_ModificationDateTime; 03131 03132 static a2dPropertyIdDateTime* PROPID_AccessDateTime; 03133 03134 //! when set used for popup menu by default in OnPopUpEvent() 03135 static a2dPropertyIdMenu* PROPID_PopupMenu; 03136 03137 //! when set used for tip window by default in OnCanvasMouseEvent() 03138 static a2dPropertyIdWindow* PROPID_TipWindow; 03139 03140 DECLARE_PROPERTIES() 03141 03142 private: 03143 //!this is a not implemented copy constructor that avoids automatic creation of one 03144 a2dCanvasObject( const a2dCanvasObject &other ); 03145 }; 03146 03147 03148 bool operator < (const a2dCanvasObjectPtr& a, const a2dCanvasObjectPtr& b); 03149 03150 typedef bool (*a2dCanvasObjectSorter) ( const a2dCanvasObjectPtr& x, const a2dCanvasObjectPtr& y); 03151 A2DCANVASDLLEXP extern a2dCanvasObjectSorter s_a2dCanvasObjectSorter; 03152 03153 #ifdef _DEBUG 03154 // Here are two globals that can be used as registers in the debugger 03155 extern a2dCanvasObject *_dbco1; 03156 extern a2dCanvasObject *_dbco2; 03157 #endif 03158 03159 03160 03161 //! class use by a2dIterC to filter objects for rendering. 03162 /*! 03163 From a2dCanvasDocument render cycles for the document are initiated. 03164 An iteration context is set up, and this context can have an object filter set, 03165 only a2dCanvasObject objects that return true, will be rendered. 03166 03167 The idea is to derived from this class, and defined your own Filter() 03168 03169 This object can contain dynamic properties which can be used for filtering. 03170 It is also refcounted for use with smart pointers. 03171 */ 03172 class A2DCANVASDLLEXP a2dCanvasObjectFilter : public a2dPropObject 03173 { 03174 public: 03175 03176 //! 03177 /*! 03178 */ 03179 a2dCanvasObjectFilter() {}; 03180 03181 ~a2dCanvasObjectFilter() {}; 03182 03183 //! called from a2dCanvasObject to filter objects for rendering 03184 virtual bool Filter( a2dIterC& WXUNUSED(ic), a2dCanvasObject* WXUNUSED(canvasObject) ) { return true; } 03185 03186 //! called from a2dCanvasObject to reset filtering feature when filtered object goes out of context. 03187 virtual void EndFilter( a2dIterC& WXUNUSED(ic), a2dCanvasObject* WXUNUSED(canvasObject) ) {} 03188 }; 03189 03190 #if defined(WXART2D_USINGDLL) 03191 template class A2DCANVASDLLEXP a2dSmrtPtr<a2dCanvasObjectFilter>; 03192 03193 #endif 03194 03195 //! filter on this layer and mask. 03196 class A2DCANVASDLLEXP a2dCanvasObjectFilterLayerMask : public a2dCanvasObjectFilter 03197 { 03198 public: 03199 03200 //! 03201 /*! 03202 */ 03203 a2dCanvasObjectFilterLayerMask( wxUint16 layer, a2dCanvasObjectFlagsMask mask = a2dCanvasOFlags::ALL, a2dCanvasObjectFlagsMask antimask = a2dCanvasOFlags::NON ) 03204 { 03205 m_layer = layer; 03206 m_mask = mask; 03207 m_antimask = antimask; 03208 } 03209 03210 ~a2dCanvasObjectFilterLayerMask() {} 03211 03212 virtual bool Filter( a2dIterC& ic, a2dCanvasObject* canvasObject ); 03213 03214 protected: 03215 03216 wxUint16 m_layer; 03217 a2dCanvasObjectFlagsMask m_mask; 03218 a2dCanvasObjectFlagsMask m_antimask; 03219 }; 03220 03221 //! objects with m_editingcopy or m_toolobject are skipped. 03222 class A2DCANVASDLLEXP a2dCanvasObjectFilterLayerMaskNoToolNoEdit : public a2dCanvasObjectFilterLayerMask 03223 { 03224 public: 03225 03226 //! 03227 /*! 03228 */ 03229 a2dCanvasObjectFilterLayerMaskNoToolNoEdit( wxUint16 layer, a2dCanvasObjectFlagsMask mask = a2dCanvasOFlags::ALL, a2dCanvasObjectFlagsMask antimask = a2dCanvasOFlags::NON ) 03230 : a2dCanvasObjectFilterLayerMask( layer, mask, antimask ) 03231 { 03232 } 03233 03234 virtual bool Filter( a2dIterC& ic, a2dCanvasObject* canvasObject ); 03235 03236 virtual void EndFilter( a2dIterC& ic, a2dCanvasObject* canvasObject ); 03237 03238 }; 03239 03240 //! object not fitting the mask are drawn blind. 03241 class A2DCANVASDLLEXP a2dCanvasObjectFilterOnlyNoMaskBlind : public a2dCanvasObjectFilter 03242 { 03243 public: 03244 03245 //! 03246 /*! 03247 */ 03248 a2dCanvasObjectFilterOnlyNoMaskBlind( a2dCanvasObjectFlagsMask mask = a2dCanvasOFlags::ALL ) 03249 : a2dCanvasObjectFilter() 03250 { 03251 m_mask = mask; 03252 m_maskedCanvasObject = 0; 03253 } 03254 03255 virtual bool Filter( a2dIterC& ic, a2dCanvasObject* canvasObject ); 03256 03257 virtual void EndFilter( a2dIterC& ic, a2dCanvasObject* canvasObject ); 03258 03259 protected: 03260 03261 a2dCanvasObjectFlagsMask m_mask; 03262 a2dCanvasObjectPtr m_maskedCanvasObject; 03263 }; 03264 03265 //! objects not fitting the property are not drawn, inclusif its children. 03266 /*! 03267 Mask is still checked for objects with that property and its children 03268 The drawing is only enabled by the filter, the top in a2dCanvasDocument sets it off at start. 03269 */ 03270 class A2DCANVASDLLEXP a2dCanvasObjectFilterPropertyNoMaskBlind : public a2dCanvasObjectFilterOnlyNoMaskBlind 03271 { 03272 public: 03273 03274 //! 03275 /*! 03276 */ 03277 a2dCanvasObjectFilterPropertyNoMaskBlind( const a2dPropertyId *id, a2dCanvasObjectFlagsMask mask = a2dCanvasOFlags::ALL ) 03278 : a2dCanvasObjectFilterOnlyNoMaskBlind( mask ) 03279 { 03280 m_id = id; 03281 } 03282 03283 virtual bool Filter( a2dIterC& ic, a2dCanvasObject* canvasObject ); 03284 03285 virtual void EndFilter( a2dIterC& ic, a2dCanvasObject* canvasObject ); 03286 03287 protected: 03288 03289 const a2dPropertyId *m_id; 03290 }; 03291 03292 //! filter for selected a2dCanvasObject's 03293 /*! 03294 03295 */ 03296 class A2DCANVASDLLEXP a2dCanvasObjectFilterSelected : public a2dCanvasObjectFilterOnlyNoMaskBlind 03297 { 03298 public: 03299 03300 //! 03301 /*! 03302 */ 03303 a2dCanvasObjectFilterSelected( a2dCanvasObjectFlagsMask mask = a2dCanvasOFlags::ALL ) 03304 : a2dCanvasObjectFilterOnlyNoMaskBlind( mask ) 03305 { 03306 } 03307 03308 virtual bool Filter( a2dIterC& ic, a2dCanvasObject* canvasObject ); 03309 03310 virtual void EndFilter( a2dIterC& ic, a2dCanvasObject* canvasObject ); 03311 03312 protected: 03313 }; 03314 03315 //! filter for selected a2dCanvasObject's 03316 /*! 03317 03318 */ 03319 class A2DCANVASDLLEXP a2dCanvasObjectFilterHighLighted : public a2dCanvasObjectFilterOnlyNoMaskBlind 03320 { 03321 public: 03322 03323 //! 03324 /*! 03325 */ 03326 a2dCanvasObjectFilterHighLighted( a2dCanvasObjectFlagsMask mask = a2dCanvasOFlags::ALL ) 03327 : a2dCanvasObjectFilterOnlyNoMaskBlind( mask ) 03328 { 03329 } 03330 03331 virtual bool Filter( a2dIterC& ic, a2dCanvasObject* canvasObject ); 03332 03333 virtual void EndFilter( a2dIterC& ic, a2dCanvasObject* canvasObject ); 03334 03335 protected: 03336 }; 03337 03338 //! filter for tool related a2dCanvasObject's 03339 /*! 03340 03341 */ 03342 class A2DCANVASDLLEXP a2dCanvasObjectFilterToolObjects : public a2dCanvasObjectFilterOnlyNoMaskBlind 03343 { 03344 public: 03345 03346 //!constructor 03347 /*! 03348 */ 03349 a2dCanvasObjectFilterToolObjects( const a2dPropertyId *id, a2dCanvasObjectFlagsMask mask = a2dCanvasOFlags::ALL ) 03350 : a2dCanvasObjectFilterOnlyNoMaskBlind( mask ) 03351 { 03352 m_id = id; 03353 } 03354 03355 virtual bool Filter( a2dIterC& ic, a2dCanvasObject* canvasObject ); 03356 03357 virtual void EndFilter( a2dIterC& ic, a2dCanvasObject* canvasObject ); 03358 03359 protected: 03360 03361 const a2dPropertyId *m_id; 03362 }; 03363 03364 //! An object of this class will update a a2dIterC with the required information 03365 /*! As iteration goes down the child hierarchy, a a2dIterCU is created to 03366 update a a2dIterC. It will update the parent list as well as the matrix 03367 03368 Assume the following object tree 03369 03370 \verbatim 03371 A 03372 / \ 03373 B C 03374 / \ / \ 03375 D E F G 03376 \endverbatim 03377 03378 The constructors / destructors are called in the following order, and the values 03379 of GetParent and GetPreviousSibling, GetPreviousOrParent and GetPreviousDeep are shown 03380 (time is going from left to right): 03381 03382 \verbatim 03383 Const: A B D E C F G 03384 Destr: D E B F G C A 03385 03386 Parent: X 0 A B A B A 0 A C A C A 0 X 03387 03388 PrevSi: X 0 0 0 0 D 0 0 B 0 B F B 0 X 03389 03390 PrevOP: X 0 A B A D A 0 B C B F B 0 X 03391 03392 PrevD: X 0 0 0 D D E B B B F F G C A 03393 03394 Stack: - A A A A A A A A A A A A A - 03395 - - B B B B B - C C C C C - - 03396 - - - D - E - - - F - G - - - 03397 03398 \endverbatim 03399 03400 \see a2dIterC 03401 */ 03402 class A2DCANVASDLLEXP a2dIterCU 03403 { 03404 friend class a2dIterC; 03405 public: 03406 //! Update iteration context 03407 /*! Create an object of this type locally in a a2dCanvasObject child tree 03408 iteration function at each recusion level. This will update the iteration 03409 context and restore it later 03410 */ 03411 a2dIterCU( a2dIterC &ic, a2dCanvasObject *object, OVERLAP clip = _IN ); 03412 03413 //! construction of intitial 03414 a2dIterCU( a2dIterC &ic, const a2dAffineMatrix& matrix = a2dIDENTITY_MATRIX, OVERLAP clip = _IN ); 03415 03416 //! copy constructor 03417 a2dIterCU( const a2dIterCU& cu ); 03418 03419 //! Restore the iteration context 03420 ~a2dIterCU(); 03421 03422 //! Get the current object 03423 a2dCanvasObject *GetObject() { return m_object; } 03424 03425 //! get the parent of this instance of a2dIterCU 03426 a2dIterCU* GetParent() { return m_parent; } 03427 03428 //! Get the accumulated transforms up to and including m_object->m_lworld 03429 const a2dAffineMatrix &GetTransform() { return m_relativetransform; } 03430 03431 //! Get the accumulated transforms up to and including m_object->m_lworld 03432 const a2dAffineMatrix &GetInverseTransform() { return m_inverseRelativetransform; } 03433 03434 private: 03435 //! the canvas object at the current level of iteration 03436 a2dCanvasObject *m_object; 03437 03438 //! the previous direct child object of m_object (used for GetPreviousSameLevel) 03439 a2dCanvasObject *m_previous; 03440 03441 //! the context update of the parent 03442 a2dIterCU *m_parent; 03443 03444 //! the accumulated transforms up to and including m_object->m_lworld 03445 a2dAffineMatrix m_relativetransform; 03446 03447 //! inverse of m_relativetransform 03448 a2dAffineMatrix m_inverseRelativetransform; 03449 03450 //! the correpsonding iteration context 03451 a2dIterC *m_iterC; 03452 03453 //! indicates type of constructor used. 03454 bool m_objectLevel; 03455 03456 //! how far this object in the view being rendered 03457 OVERLAP m_clip; 03458 }; 03459 03460 03461 //! mask flags for a2dIterC 03462 /*! 03463 \ingroup canvasobject 03464 */ 03465 typedef unsigned int wxIterCFlagsMask ; 03466 03467 //! while iterating a a2dCanvasDocument, this holds the context. 03468 /*! 03469 The context is a collection of information, which might be needed when 03470 traversing the document. 03471 e.g. Transforms for drawing and conversion to absolute coordinates are stored here. 03472 03473 Specific information in the context can be valid or not. 03474 If the information is set and is valid, a flag is set too. 03475 This flag is checked when information is asked for. Asking for non valid information 03476 will result in an assert. 03477 */ 03478 class A2DCANVASDLLEXP a2dIterC 03479 { 03480 friend class a2dIterCU; 03481 friend class a2dCorridor; 03482 03483 public: 03484 03485 //! constructor used when drawer is not known 03486 a2dIterC(); 03487 03488 //! constructor used when drawer is known ( usually the case ) 03489 /*! 03490 \param drawer the drawer that is currently in use. 03491 \param level how deep is the starting object to render from the ShowObject of the a2dCanvasView. 03492 */ 03493 a2dIterC( a2dCanvasView* drawer, int level = 0 ); 03494 03495 //! destructor 03496 ~a2dIterC(); 03497 03498 //! when true, disable inversion of matrixes 03499 /*! 03500 e.g. when rendering a document the inverted matrix is not needed, so we disable the calculation to gain speed. 03501 */ 03502 void SetDisableInvert( bool disableInvert ) { m_disableInvert = disableInvert; } 03503 03504 //! see SetDisableInvert() 03505 inline bool GetDisableInvert() { return m_disableInvert; } 03506 03507 //! Reset this object for beeing reused. It will keep the drawer but NULL object infos 03508 void Reset(); 03509 03510 //! used to extend a hittest with the number of pixels. 03511 /*! to be able to hit a line of width zero, a margin is needed to hit it, 03512 which is set here. 03513 In fact this value is directly converted to a value in world coordinates, 03514 using the current GetDrawer2D(). GetHitMarginWorld() returns this value. 03515 03516 \remark default value is taken from a2dCanvasView or a2dCanvasGlobal 03517 */ 03518 void SetHitMarginDevice( int pixels ); 03519 03520 //! used to extend a hittest with the given margin in world coordinates. 03521 /*! to be able to hit a line of width zero, a margin is needed to hit it, 03522 which is set here. 03523 03524 \remark default value is taken from a2dCanvasGlobal::GetHitMarginWorld 03525 */ 03526 void SetHitMarginWorld( double world ); 03527 03528 //! Get HitMargin in World units. 03529 double GetHitMarginWorld(); 03530 03531 //! Transform a pixel extend from device to world units 03532 /*! If no drawer is there (e.g. command procesing) the return value will be zero */ 03533 double ExtendDeviceToWorld( int extend ); 03534 03535 //! transformed to object its coordinate system 03536 double GetTransformedHitMargin(); 03537 03538 //! get the layer that is to be rendered 03539 inline wxUint16 GetLayer() { return m_layer; } 03540 03541 //! set the layer that is to be rendered 03542 /*! 03543 wxLAYER_ALL has the special meaning that it renderers all layers at once. 03544 */ 03545 void SetLayer( wxUint16 layer ) { m_layer = layer; } 03546 03547 //! get setting for command generation or not. 03548 inline bool GetGenerateCommands() { return m_generateCommands; } 03549 03550 //! set to generate command or not in certain situations. 03551 /*! 03552 */ 03553 void SetGenerateCommands( bool generateCommands ) { m_generateCommands = generateCommands; } 03554 03555 //!get the mapping matrix 03556 const a2dAffineMatrix& GetMappingTransform() const; 03557 03558 //! get matrix which transforms directly from relative world coordinates to device 03559 const a2dAffineMatrix& GetUserToDeviceTransform() const; 03560 03561 //! get current a2dCanvasView 03562 a2dCanvasView* GetCanvasView() const; 03563 03564 //! get current a2dDrawer2D 03565 a2dDrawer2D* GetDrawer2D() const; 03566 03567 //!set drawstyle used for rendering the document 03568 /*! 03569 The drawstyle is set in a2dCanvasDocument when rendering parts of the document. 03570 03571 \param drawstyle one of the draw styles 03572 */ 03573 void SetDrawStyle( a2dDocumentRenderStyle drawstyle ) { m_drawstyle = drawstyle; } 03574 03575 //!get drawstyles used for drawing the document 03576 a2dDocumentRenderStyle GetDrawStyle() { return m_drawstyle; } 03577 03578 //! when traversing tree this the object one level higher. 03579 /*! 03580 Used internal during rendering etc. 03581 During recursive traversing a a2dCanvasDocument from top group that is displayed 03582 this holds the a2dCanvasObject that is one level higher in the branch that is traversed 03583 used during rendering etc., to know what is the parent object in a branch that is being rendered 03584 */ 03585 a2dCanvasObject* GetParent(); 03586 03587 //! the object where the iterative context is currently 03588 a2dCanvasObject* GetObject(); 03589 03590 //! Get the last object, for which the recursive function was called 03591 a2dCanvasObject* GetPreviousDeep(); 03592 03593 //! Get the last sibling, for which the recursive function was called 03594 a2dCanvasObject* GetPreviousSibling(); 03595 03596 //! Like GetPreviousSibling, but returns the Parent if PreviousSibling is 0 03597 a2dCanvasObject* GetPreviousOrParent(); 03598 03599 //! Get the accumulated transform up to and including m_lworld of the current object 03600 /*! This converts from relative local coordinates of the current object to world coordinates. 03601 This matrix transforms all drawing primitives used to draw a a2dCanvasObject from relative 03602 world coordinates to absolute world coordinates. 03603 */ 03604 const a2dAffineMatrix& GetTransform() const; 03605 03606 //! Inverse of GetTransform() 03607 const a2dAffineMatrix& GetInverseTransform() const; 03608 03609 //! Get the accumulated transform up to but NOT including m_lworld of the current obejct 03610 /*! This converts from local coordinates of the curent object to world coordinates 03611 !!!! I am not sure if it should contains the view transform (world->device) as well !!!! 03612 */ 03613 const a2dAffineMatrix& GetParentTransform() const; 03614 03615 //! inverse of GetParentTransform() 03616 const a2dAffineMatrix& GetInverseParentTransform() const; 03617 03618 //! number of levels deep we are inside a document as seen from the m_top 03619 int GetLevel() const { return m_levels; } 03620 03621 //! to set corridor path ( also to captured object), its a2dCanvasOFlags::IsOnCorridorPath flag is set on or off. 03622 /*! 03623 The iteration context knows its parent object via its m_bottom and m_parent a2dIterCU. 03624 Each a2dIterCU added when going deeper into the drawing hierarchy, knows from which object it came. 03625 This way, it is possible to iterate back to the top/show object in a a2dCanvasView. 03626 All canvasobjects passed that way is called the event path. 03627 Of course when going up in hierarchy, the event path is becoming smaller again. And when arriving at the top 03628 it will be zero. 03629 To preserve the event path to a specific canvas object, a flag can be set along the canvas objects in 03630 the current event path. Those flags will be kept intact inside the canvasobjects, even if the event path 03631 is changing after setting the flags. 03632 The a2dCanvasOFlags::IsOnCorridorPath set this way, is/can be used to find and redirect events to the 03633 objects along or at the end of this path. The path created like this is called the Corridor path. 03634 03635 When capturing an object, the corridor is used to redirect events to that object, even 03636 if the object is a deeper nested child. A non captured corridor also redirects 03637 events to the last object in the corridor, but still does normal event processing 03638 from that point on. So only a positive hittest will really make the event go to the object. 03639 When also capturing the object at the end of a corridor, the mouse event is always going to that object, 03640 even if it does not hit it. 03641 03642 \param OnOff to set the corridor path on or off. 03643 \param captureObject to set this as a captured object at the end of the corridor, if NULL non is captured. 03644 */ 03645 void SetCorridorPath( bool OnOff, a2dCanvasObject* captureObject = NULL ); 03646 03647 /* set corridor path to parent of current iteration context */ 03648 void SetCorridorPathToParent(); 03649 03650 //! leaves corridorpath as is, but resets the capture object at the end of the corridor to 03651 //! the given object. If NULL, the corridor is set to non captured. 03652 void SetCorridorPathCaptureObject( a2dCanvasObject* captureObject ); 03653 03654 //! when there is a corridor path set, this return if end has bin found while iterating. 03655 bool GetFoundCorridorEnd() { return m_foundCorridorEnd; } 03656 03657 //! when there is a corridorPath set, this is used internal to set this flag to indicate that the end of it was found. 03658 void SetFoundCorridorEnd( bool foundCorridorEnd ) { m_foundCorridorEnd = foundCorridorEnd; } 03659 03660 //! Set strokeworld extend of last added object, used in a2dCanvasObject::DoIsHitWorld() 03661 /*! 03662 Holds the size/width of the Stroke in world coordinates, else 0. 03663 This can be used in derived a2dCanvasObject to do a proper hittest. 03664 If the stroke is of type pixel, that value will be converted into world coordinates. 03665 */ 03666 void SetStrokeWorldExtend( double worldStrokeExtend ) { m_worldStrokeExtend = worldStrokeExtend; } 03667 03668 //! \see SetWorldStrokeExtend() 03669 double GetWorldStrokeExtend() { return m_worldStrokeExtend; } 03670 03671 //! what is the clipping withing the current view for the last added object in context 03672 OVERLAP GetClipStatus() const; 03673 03674 //! what is the clipping withing the current view for the second last added object in context 03675 OVERLAP GetParentClipStatus() const; 03676 03677 //! set the clipping withing the current view for the last added object in context 03678 void SetClipStatus( OVERLAP status ); 03679 03680 //! get the filter set for the iteration context. 03681 a2dCanvasObjectFilter* GetObjectFilter() { return m_objectFilter; } 03682 03683 //! set object filter class. 03684 void SetObjectFilter( a2dCanvasObjectFilter* filter ) { m_objectFilter = filter; } 03685 03686 //! apply object filter 03687 bool FilterObject( a2dCanvasObject* canvasObject ); 03688 03689 //! called when filter ends 03690 void EndFilterObject( a2dCanvasObject* canvasObject ); 03691 03692 //! if set the rendering is done layers by layer from the top 03693 void SetPerLayerMode( bool value ) { m_perLayerMode = value; } 03694 03695 //! if set the rendering is done layers by layer from the top 03696 bool GetPerLayerMode() { return m_perLayerMode; } 03697 03698 //! when set child object in derived a2dCanvasObject are rendered, else only the object itself. 03699 void SetRenderChildDerived( bool value ) { m_renderChildDerived = value; } 03700 03701 //! when set child object in derived a2dCanvasObject are rendered, else only the object itself. 03702 bool GetRenderChildDerived() { return m_renderChildDerived; } 03703 03704 //! set during event processing down the hierarchy, to the deepest object that was hit 03705 void SetDeepestHit( a2dCanvasObject* canvasObject ) { m_deepestHit = canvasObject; } 03706 03707 //! get deepest object that was hit during event processing down the hierarchy. 03708 a2dCanvasObject* GetDeepestHit() const { return m_deepestHit; } 03709 03710 private: 03711 03712 //! if true no inversion on matrixes is done. 03713 bool m_disableInvert; 03714 03715 //!world to device coordinate mapping 03716 a2dAffineMatrix m_mapping; 03717 03718 //!relative world to device transform matrix ( so includes mapping matrix ) 03719 a2dAffineMatrix m_usertodevice; 03720 03721 //! when traversing a group within a tree this points to the previous object that was traverersed 03722 /*! 03723 Used for GetPreviousDeep 03724 Used internal during rendering etc. 03725 This is set in the destructor of a2dIterCU, so it is always the object, for which the 03726 correspsonding recursive function was left last. 03727 */ 03728 a2dSmrtPtr<a2dCanvasObject> m_previous; 03729 03730 //! during event processing down the hierarchy, this is set to deepest object hit. 03731 a2dSmrtPtr<a2dCanvasObject> m_deepestHit; 03732 03733 //! from which a2dCanvasView the iteration started. 03734 a2dSmrtPtr<a2dCanvasView> m_drawer; 03735 03736 //! how close in pixles does a hit need to be to the object you are trying to hit. 03737 /*! this is in world units */ 03738 double m_hitmargin_world; 03739 03740 //! The top of the list of context update objects. 03741 a2dIterCU *m_top; 03742 03743 //! The bottom of the list of context update objects. 03744 a2dIterCU *m_bottom; 03745 03746 //! How much child levels deep are we, seen from the ShowObject of the a2dCanvasView. 03747 int m_levels; 03748 03749 //! when there is a corridorPath set, this is set when end is found. 03750 bool m_foundCorridorEnd; 03751 03752 //! \see SetWorldExtend() 03753 double m_worldStrokeExtend; 03754 03755 //! drawstyles used to render document 03756 a2dDocumentRenderStyle m_drawstyle; 03757 03758 //! for filtering objects when e.g. rendering 03759 a2dSmrtPtr<a2dCanvasObjectFilter> m_objectFilter; 03760 03761 //! the layer that is currently rendered. 03762 wxUint16 m_layer; 03763 03764 //! see SetGenerateCommands() 03765 bool m_generateCommands; 03766 03767 bool m_ownDrawer; 03768 03769 //! if set the rendering is done layers by layer from the top 03770 bool m_perLayerMode; 03771 03772 //! when set child object in derived a2dCanvasObject are rendered, else only the object itself. 03773 bool m_renderChildDerived; 03774 03775 }; 03776 03777 #endif // WXCANOBJ 03778 03779