00001 /*! \file wx/canvas/objlist.h 00002 \brief list for a2dCanvasObject 00003 00004 Action that can be performed on a list of a2dCanvasObject's go into a2dCanvasObjectList. 00005 00006 \author Klaas Holwerda 00007 00008 Copyright: 2000-2004 (c) Klaas Holwerda 00009 00010 Licence: wxWidgets Licence 00011 00012 RCS-ID: $Id: objlist.h,v 1.30 2009/09/26 19:01:02 titato Exp $ 00013 */ 00014 00015 #ifndef __WXOBJLIST_H__ 00016 #define __WXOBJLIST_H__ 00017 00018 #ifndef WX_PRECOMP 00019 #include "wx/wx.h" 00020 #endif 00021 00022 #include "wx/geometry.h" 00023 #include "wx/artbase/afmatrix.h" 00024 #include "wx/canvas/candefs.h" 00025 #include "wx/canvas/canobj.h" 00026 #include "wx/canvas/canprop.h" 00027 00028 //---------------------------------------------------------------------------- 00029 // decls 00030 //---------------------------------------------------------------------------- 00031 00032 //! define a NON a2dCanvasObjectList 00033 /*! 00034 Even if a a2dCanvasObject has no children, still its Length can be asked for. 00035 */ 00036 A2DCANVASDLLEXP_DATA(extern a2dCanvasObjectList*) wxNullCanvasObjectList; 00037 00038 //initalization 00039 #if defined(WXART2D_USINGDLL) 00040 template class A2DCANVASDLLEXP std::allocator<class a2dSmrtPtr<class a2dCanvasObject> >; 00041 template class A2DCANVASDLLEXP std::allocator< std::_List_nod<class a2dSmrtPtr<class a2dCanvasObject>, std::allocator<class a2dSmrtPtr<class a2dCanvasObject> > >::_Node >; 00042 template class A2DCANVASDLLEXP std::allocator< std::_List_ptr<class a2dSmrtPtr<class a2dCanvasObject>, std::allocator<class a2dSmrtPtr<class a2dCanvasObject> > >::_Nodeptr >; 00043 template class A2DCANVASDLLEXP std::list<class a2dSmrtPtr<class a2dCanvasObject> >::iterator; 00044 template class A2DCANVASDLLEXP std::list<class a2dSmrtPtr<class a2dCanvasObject> >; 00045 template class A2DCANVASDLLEXP a2dlist<a2dSmrtPtr<a2dCanvasObject> >; 00046 template class A2DCANVASDLLEXP a2dSmrtPtrList<a2dCanvasObject>; 00047 #endif 00048 00049 #include <wx/listimpl.cpp> 00050 00051 //! list of a2dCanvasObject's 00052 /*! 00053 Action that can be performed on a list of a2dCanvasObject's go into a2dCanvasObjectList. 00054 00055 \ingroup canvasobject 00056 */ 00057 00058 class a2dCanvasObjectIter; 00059 00060 class A2DCANVASDLLEXP a2dCanvasObjectList: public a2dSmrtPtrList<a2dCanvasObject> 00061 { 00062 00063 public: 00064 a2dCanvasObjectList(); 00065 00066 ~a2dCanvasObjectList(); 00067 00068 //!this only copies pointer stored in the list. 00069 /*! 00070 if you want the object itself copied also, use Clone 00071 */ 00072 a2dCanvasObjectList& operator=( const a2dCanvasObjectList& other ); 00073 00074 //!Clone everything ( Clones objects also) in a new created list 00075 a2dCanvasObjectList* Clone( a2dObject::CloneOptions options ) const; 00076 00077 //! clone to new list only objects with certain mask 00078 /*! 00079 \param mask object must have this mask. 00080 \param options way to clone 00081 \param objectsIndex list with indexes of cloned objects 00082 \param bbox only find objects within this box. 00083 00084 \return cloned objects list 00085 */ 00086 a2dCanvasObjectList* Clone( a2dCanvasObjectFlagsMask mask = a2dCanvasOFlags::ALL, a2dObject::CloneOptions options = a2dObject::clone_deep, a2dlist< long >* objectsIndex = NULL, const a2dBoundingBox& bbox = wxNonValidBbox ) const; 00087 00088 //! clone to new list only objects with check flag set 00089 /*! 00090 \param options way to clone 00091 \param objectsIndex list with indexes of cloned objects 00092 00093 \return cloned objects list 00094 */ 00095 a2dCanvasObjectList* CloneChecked( a2dObject::CloneOptions options = a2dObject::clone_deep, a2dlist< long >* objectsIndex = NULL ) const; 00096 00097 //! sort in X and is same also Y 00098 void SortXY(); 00099 00100 //! sort in X and is same also in reverse Y 00101 void SortXRevY(); 00102 00103 //! sort in Y and is same also X 00104 void SortYX(); 00105 00106 //! sort in Y and is same also in reverse X 00107 void SortYRevX(); 00108 00109 //! all with reference count > 1 are cloned. 00110 void MakeUnique(); 00111 00112 //!set all given bit flags at once recursive for all objects in given boundingbox 00113 bool SetSpecificFlags( bool setOrClear, a2dCanvasObjectFlagsMask which, const wxString& classname = wxT(""), 00114 a2dCanvasObjectFlagsMask whichobjects = a2dCanvasOFlags::ALL, const a2dBoundingBox& bbox = wxNonValidBbox, 00115 const a2dAffineMatrix& tworld = a2dIDENTITY_MATRIX ); 00116 00117 //!move only in this group objects with the given mask to the layer given 00118 bool ChangeLayer( wxUint16 layer, a2dCanvasObjectFlagsMask mask = a2dCanvasOFlags::ALL ); 00119 00120 //!move only in this group objects with the given mask to the back of the list drawn last 00121 /*! 00122 \param mask object must have this mask. 00123 \param check if true, moved objects will have check flag set 00124 00125 \return number of moved objects 00126 */ 00127 int BringToTop( a2dCanvasObjectFlagsMask mask = a2dCanvasOFlags::ALL, bool check = false ); 00128 00129 //!move only in this group objects with the given mask to the front of the list drawn first 00130 /*! 00131 \param mask object must have this mask. 00132 \param check if true, moved objects will have check flag set 00133 00134 \return number of moved objects 00135 */ 00136 int BringToBack( a2dCanvasObjectFlagsMask mask = a2dCanvasOFlags::ALL, bool check = false ); 00137 00138 //! release only objects with the given mask and classname and has property named propertyname and object name 00139 /*! 00140 \param mask object must have this mask. 00141 \param classname if set, this classname is required 00142 \param id is object contains this property, it will be released. If NULL, this parameter is ignored. 00143 \param name if set, this name is required for the objects 00144 \param now if true remove all references to object right now, else only set its delete flag for delete in update cycle. 00145 empty string means ignore. 00146 */ 00147 int Release( a2dCanvasObjectFlagsMask mask = a2dCanvasOFlags::ALL, const wxString& classname = wxT(""), const a2dPropertyId *id = NULL, const wxString& name = wxT(""), bool now = true ); 00148 00149 //! release a specific object 00150 /*! 00151 \param object object to release 00152 \param backwards start at the end 00153 \param all if true remove all references to object 00154 \param now if true remove all references to object right now, else only set its delete flag for delete in update cycle. 00155 \param id is object contains this property, it will be released. If NULL, this parameter is ignored. 00156 00157 \return number of released objects 00158 */ 00159 int Release( a2dCanvasObject* object, bool backwards = false, bool all = true, bool now = true, const a2dPropertyId *id = NULL ); 00160 00161 //!copy only in this group object with the same mask 00162 /*! 00163 \param x copy object at distance x 00164 \param y copy object at distance y 00165 \param mask object must have this mask. 00166 \param target if not -1, objects will be copied to this layer 00167 \param check if true, copied objects will have check flag set 00168 00169 \return number of copied objects 00170 */ 00171 int Copy( double x, double y, a2dCanvasObjectFlagsMask mask = a2dCanvasOFlags::ALL, long target = -1, bool check = false ); 00172 00173 //!move only in this group object with the same mask 00174 /*! 00175 \param x move object distance x 00176 \param y move object distance y 00177 \param mask object must have this mask. 00178 \param target if not -1, objects will be copied to this layer 00179 \param check if true, moved objects will have check flag set 00180 00181 \return number of moved objects 00182 */ 00183 int Move( double x, double y, a2dCanvasObjectFlagsMask mask = a2dCanvasOFlags::ALL, long target = -1, bool check = false ); 00184 00185 //!return the object if it is part of the list 00186 /*! 00187 \param obj object to search for 00188 */ 00189 a2dCanvasObject* Find( a2dCanvasObject* obj ) const; 00190 00191 //!return the object which fits the filter. 00192 /*! 00193 \param objectname object with this name to search for 00194 \param classname If classname is empty it collects all objects else only object with this class name. 00195 \param mask object must have this mask. 00196 \param propid if a property id is given, the object must have a property with this id 00197 \param valueAsString StringValueRepresentation of the property that is required (if not empty). 00198 \param id GetUniqueSerializationId() should be this unless 0 00199 */ 00200 a2dCanvasObject* Find( const wxString& objectname, const wxString& classname = wxT(""), 00201 a2dCanvasObjectFlagsMask mask = a2dCanvasOFlags::ALL , const a2dPropertyId *propid = NULL, const wxString& valueAsString = wxT(""), 00202 wxUint32 id = 0 ) const; 00203 00204 //! If object with the given name is found, it is switched to newobject 00205 /*! 00206 The old object will be released. 00207 The new object will be owned. 00208 00209 \return true is object was found. 00210 */ 00211 bool SwitchObjectNamed( const wxString& objectname, a2dCanvasObject* newobject ); 00212 00213 //!Transform objects fitting the given filter. 00214 /*! 00215 \param tworld transform matrix to transform the objects 00216 \param type If type is empty it collects all objects else only object with this class name. 00217 \param mask object must have this mask. 00218 \param id if a property id is given, the object must have a property with this id 00219 */ 00220 void Transform( const a2dAffineMatrix& tworld , const wxString& type=wxT(""), 00221 a2dCanvasObjectFlagsMask mask = a2dCanvasOFlags::ALL , 00222 const a2dPropertyId *id = NULL ); 00223 00224 //!Transform objects fitting the given filter. 00225 /*! 00226 \param tworld transform matrix to be set as the new transform for the objects 00227 \param type If type is empty it collects all objects else only object with this class name. 00228 \param mask object must have this mask. 00229 \param id if a property id is given, the object must have a property with this id 00230 */ 00231 void SetTransform( const a2dAffineMatrix& tworld , const wxString& type=wxT(""), 00232 a2dCanvasObjectFlagsMask mask = a2dCanvasOFlags::ALL , 00233 const a2dPropertyId *id = NULL ); 00234 00235 //!Move objects fitting the given filter to the total list. 00236 /*! 00237 \param total list of object found (may already contain elements found in earlier call) 00238 \param type If type is empty it collects all objects else only object with this class name. 00239 \param mask object must have this mask. 00240 \param id the object needs to have this property set if not NULL 00241 00242 \return number of objects found 00243 */ 00244 int TakeOverTo( a2dCanvasObjectList* total, const wxString& type=wxT(""), 00245 a2dCanvasObjectFlagsMask mask = a2dCanvasOFlags::ALL , 00246 const a2dPropertyId *id = NULL ); 00247 00248 //!Move objects fitting the given filter from the total list to this list 00249 /*! 00250 \param total list of object found (may already contain elements found in earlier call) 00251 \param type If type is empty it collects all objects else only object with this class name. 00252 \param mask object must have this mask. 00253 \param id the object needs to have this property set if not NULL 00254 00255 \return number of objects found 00256 */ 00257 int TakeOverFrom( a2dCanvasObjectList* total, const wxString& type=wxT(""), 00258 a2dCanvasObjectFlagsMask mask = a2dCanvasOFlags::ALL , 00259 const a2dPropertyId *id = NULL ); 00260 00261 00262 //!Copy objects fitting the given filter to the total list. 00263 /*! 00264 \param total list of object found (may already contain elements found in earlier call) 00265 \param type If type is empty it collects all objects else only object with this class name. 00266 \param mask object must have this mask. 00267 \param id if a property id is given, the object must have a property with this id 00268 \param bbox only find objects within this box. 00269 00270 \return number of objects found 00271 */ 00272 int CollectObjects( a2dCanvasObjectList* total, const wxString& type=wxT(""), 00273 a2dCanvasObjectFlagsMask mask = a2dCanvasOFlags::ALL , 00274 const a2dPropertyId *id = NULL, 00275 const a2dBoundingBox& bbox = wxNonValidBbox 00276 ); 00277 00278 //!set only in this list fill and stroke of objects with the given mask 00279 bool SetDrawerStyle( const a2dFill& brush, const a2dStroke& stroke, a2dCanvasObjectFlagsMask mask = a2dCanvasOFlags::ALL ); 00280 00281 //DECLARE_CLASS(a2dCanvasObjectList) 00282 00283 //! Restore connections after cloning 00284 /* After cloning a tree of connected objects, this will restore the 00285 the connections in the clone as they have been in the original 00286 \param cp if not 0, the connections are created by issuing a2dCommand_ConnectPins commands 00287 */ 00288 void RestoreConnectionsAfterCloning( class a2dCanvasCommandProcessor *cp = 0 ); 00289 00290 //! Like Update, but this is called not on OnIdle, but at well defined points 00291 /*! Use this function to adjust objects to a changing environment (e.g. wires 00292 to moving objects) when the changes are done by commands and need a proper 00293 command context. 00294 \param final if true issue commands on the original, otherwise modify the editcopy 00295 \param tool tool calling from the update 00296 \param extra an extra object, that is not in the list, but needs updating with the objects in the list 00297 \param parent parent of which the object need to be updated, if NULL, 00298 m_tool->GetCanvasView()->GetShowObject() is taken as m_parent 00299 \param data a structure with data controlling the update process 00300 */ 00301 void UpdateImmediate( bool final, a2dBaseTool *tool, a2dCanvasObject *extra = 0, a2dCanvasObject* parent = 0, a2dCanvasObject::a2dDoUpdateImmediateData *data = 0 ); 00302 00303 //! Check if all objects are only once in the list 00304 void AssertUnique(); 00305 00306 //! insert at index, taking into account released objects if needed. 00307 void Insert( size_t before, a2dCanvasObject* obj, bool ignoreReleased ); 00308 00309 }; 00310 00311 typedef a2dCanvasObjectList::iterator a2dCanvasObjectListIter; 00312 00313 #if defined(__WXDEBUG__) && wxUSE_GLOBAL_MEMORY_OPERATORS && wxUSE_DEBUG_NEW_ALWAYS 00314 #define new new(__TFILE__,__LINE__) 00315 #endif 00316 00317 //! corridor as a direct event path to a a2dCanvasObject 00318 /*! 00319 This class is used to store the state of a corridor path set inside a a2dCanvasDocument. 00320 All a2dCanvasObject's on the path do have the a2dCanvasOFlags::IsOnCorridorPath flag set. 00321 A corridor path is normally initiated from inside a a2dCanvasDocument, somewhere in one of its nested a2dCanvasObject's. 00322 This is done via a2dIterC::SetCorridorPath(), this function also stores the matrixes that the iterative context did 00323 calculate sofar. This object can therefore be initiated with a a2dIterC. 00324 00325 The a2dCorridor is used in drawings and editing tools to restore a corridor to a specific object in a document, 00326 e.g when pushing and popping a tool from the toolstack. See a2dBaseTool::GetCorridor() 00327 00328 When one tries to construct a corridor based on a2dCanvasView, the matrixes are calculated based on the matrix 00329 of the objects in the list. 00330 */ 00331 class A2DCANVASDLLEXP a2dCorridor: public a2dCanvasObjectList 00332 { 00333 public: 00334 00335 a2dCorridor(); 00336 00337 a2dCorridor( const a2dIterC& context ); 00338 00339 //! initiate corridor from the current corridor path in a document. 00340 /*! 00341 The a2dCanvasObject in the document with the m_flags.m_isOnCorridorPath set, are searched 00342 starting from the view its ShowObject(), and pushed into the corridor list. 00343 00344 The matrix (and its inverse) at the end of the corridor is calculated from the multiplied 00345 a2dCanvasObject matrixes in the corridor. 00346 */ 00347 a2dCorridor( const a2dCanvasView& view ); 00348 00349 ~a2dCorridor(); 00350 00351 //! push object onto existing corridor 00352 void Push( a2dCanvasObject* object ); 00353 00354 //! Get the accumulated transform up to and including m_lworld of the current object 00355 /*! This converts from relative local coordinates of the current object to world coordinates. 00356 This matrix transforms all drawing primitives used to draw a a2dCanvasObject from relative 00357 world coordinates to absolute world coordinates. 00358 */ 00359 const a2dAffineMatrix& GetTransform() const { return m_relativetransform; } 00360 00361 //! Inverse of GetTransform() 00362 const a2dAffineMatrix& GetInverseTransform() const { return m_inverseRelativetransform; } 00363 00364 //!are events redirected to a captured corridor? if so return the captured object in it, else NULL 00365 inline a2dCanvasObject* GetCaptured() const { return m_capture; } 00366 00367 private: 00368 00369 //! the accumulated transforms up to and including m_lworld of last object 00370 a2dAffineMatrix m_relativetransform; 00371 00372 //! inverse of m_relativetransform 00373 a2dAffineMatrix m_inverseRelativetransform; 00374 00375 //!set to capctured object at the end of the corridor. 00376 a2dCanvasObjectPtr m_capture; 00377 }; 00378 00379 class A2DCANVASDLLEXP a2dCanvasObjectIter: public a2dCanvasObjectList::iterator 00380 { 00381 public: 00382 00383 a2dCanvasObjectIter(); 00384 00385 a2dCanvasObjectIter& operator=( const a2dCanvasObjectIter& other ) 00386 { 00387 *this = other; 00388 return *this; 00389 } 00390 00391 void operator++() 00392 { 00393 a2dCanvasObjectList::iterator::operator++(); 00394 } 00395 00396 a2dCanvasObject* Item() 00397 { 00398 a2dCanvasObject* cur = (*this)->Get(); 00399 return cur; 00400 } 00401 00402 }; 00403 00404 #endif /* __WXOBJLIST_H__ */