00001 /*! \file wx/canvas/drawer.h 00002 \brief the a2dCanvasView is a a2dView specially designed for displaying 00003 parts of a a2dCanvasDocument. It uses a a2dDrawer2D to actually redraw things from the document, 00004 by giving that a2dDrawer2D as drawing context to the document, and telling the document to redraw 00005 a certain rectangular area. At that last is what this class is for. 00006 It optimizes the areas to be redrawn after object in the document were changed. 00007 To do that it combines redraw areas to a minimal set of redrawing areas. 00008 All the administration for this and the way things will be redrawn is from this view. 00009 00010 \author Klaas Holwerda 00011 00012 Copyright: 2000-2004 (c) Klaas Holwerda 00013 00014 Licence: wxWidgets Licence 00015 00016 RCS-ID: $Id: drawer.h,v 1.49 2008/10/21 21:48:30 titato Exp $ 00017 */ 00018 00019 #ifndef __WXDRAWER_H__ 00020 #define __WXDRAWER_H__ 00021 00022 #ifndef WX_PRECOMP 00023 #include "wx/wx.h" 00024 #endif 00025 00026 00027 #include "wx/image.h" 00028 #include "wx/geometry.h" 00029 00030 #if wxUSE_PRINTING_ARCHITECTURE 00031 #include "wx/prntbase.h" 00032 #endif 00033 00034 #include "wx/docview/docviewref.h" 00035 #include "wx/artbase/drawer2d.h" 00036 #include "wx/canvas/candefs.h" 00037 #include "wx/canvas/tools.h" 00038 00039 #include <vector> 00040 00041 class a2dCursorStack : public std::vector<wxCursor> 00042 { 00043 public: 00044 00045 a2dCursorStack(); 00046 }; 00047 00048 //! mask flags for a2dCanvasView::OnUpdate 00049 /*! a2dCanViewUpdateFlags 00050 \sa a2dCanvasView 00051 00052 \ingroup docview 00053 */ 00054 enum a2dCanViewUpdateFlags 00055 { 00056 a2dCANVIEW_UPDATE_OLDNEW = 0x0001, /*!< only add pending object areas from document to arealist of all drawer views, 00057 does reset pending objects */ 00058 a2dCANVIEW_UPDATE_PENDING = 0x0002, /*!< only add pending object areas from document to arealist of this drawer view, 00059 do NOT reset pending objects */ 00060 a2dCANVIEW_UPDATE_ALL = a2dVIEW_UPDATE_ALL, /*!< total area displayed by drawer is added as pending to arealist 00061 (removes all other pending areas) */ 00062 a2dCANVIEW_UPDATE_AREAS = 0x0008, /*!< redraw arealist into buffer or directly to device when not double buffered */ 00063 00064 a2dCANVIEW_UPDATE_AREAS_NOBLIT = 0x0010, /*!< redraw arealist into buffer but do not blit them by directly deleting the redrawn area */ 00065 00066 a2dCANVIEW_UPDATE_BLIT = 0x0020, /*!< blit updated areas to device window*/ 00067 00068 a2dCANVIEW_UPDATE_VIEWDEPENDENT = 0x0040, /*!< update objects which are view dependent */ 00069 00070 a2dCANVIEW_UPDATE_VIEWDEPENDENT_RIGHTNOW = 0x0080, /*!< update objects which are view dependent right now*/ 00071 00072 a2dCANVIEW_UPDATE_SYNC_DRAWERS = a2dCANVIEW_UPDATE_OLDNEW |a2dCANVIEW_UPDATE_AREAS | a2dCANVIEW_UPDATE_BLIT 00073 00074 }; 00075 00076 //! record in update list of a2dCanvasView. 00077 /*! 00078 \ingroup drawer 00079 */ 00080 class A2DCANVASDLLEXP a2dUpdateArea: public wxRect 00081 { 00082 #ifdef CLASS_MEM_MANAGEMENT 00083 //! memory manager for speed up to replace system calls allocation and deallocation 00084 static a2dMemManager sm_memManager; 00085 public: 00086 //! overloaded operator new for this class and it all derived classes 00087 void* operator new(size_t bytes) { 00088 return sm_memManager.Allocate(bytes); 00089 } 00090 00091 //! overloaded operator delete for this class and it all derived classes 00092 /*! 00093 This function doesn't free to OS-system memory block by pointer 'space'. 00094 It adds memory block by pointer 'space' to internal lists. 00095 It is speed up. 00096 */ 00097 void operator delete(void *space, size_t bytes) { 00098 sm_memManager.Deallocate(space, bytes); 00099 } 00100 #endif //CLASS_MEM_MANAGEMENT 00101 00102 public: 00103 a2dUpdateArea(int x, int y, int width, int height, wxUint8 id = 0 ); 00104 ~a2dUpdateArea(); 00105 00106 public: 00107 00108 // update done blit awaiting 00109 bool m_update_done; 00110 bool m_update_direct; 00111 00112 //! buffer id 00113 wxUint8 m_id; 00114 }; 00115 00116 #include <wx/listimpl.cpp> 00117 00118 //! Holds all updateareas within a a2dCanvasView 00119 WX_DECLARE_LIST_WITH_DECL(a2dUpdateArea, a2dUpdateListBase, class A2DCANVASDLLEXP); 00120 00121 //! maintains a list of areas on a view to be redrawn. 00122 /*! 00123 update areas reported directly to a view or extracted from tiles or stored here. 00124 */ 00125 class A2DCANVASDLLEXP a2dUpdateList : public a2dUpdateListBase 00126 { 00127 00128 #ifdef CLASS_MEM_MANAGEMENT 00129 //! memory manager for speed up to replace system calls allocation and deallocation 00130 static a2dMemManager sm_memManager; 00131 public: 00132 //! overloaded operator new for this class and it all derived classes 00133 void* operator new(size_t bytes) { 00134 return sm_memManager.Allocate(bytes); 00135 } 00136 00137 //! overloaded operator delete for this class and it all derived classes 00138 /*! 00139 This function doesn't free to OS-system memory block by pointer 'space'. 00140 It adds memory block by pointer 'space' to internal lists. 00141 It is speed up. 00142 */ 00143 void operator delete(void *space, size_t bytes) { 00144 sm_memManager.Deallocate(space, bytes); 00145 } 00146 #endif //CLASS_MEM_MANAGEMENT 00147 00148 public: 00149 a2dUpdateList(void) : a2dUpdateListBase() { 00150 } 00151 00152 }; 00153 00154 #define a2d_TILESHIFT 8 00155 #define a2d_TILESIZE 256 //(1 << a2d_TILESHIFT) 00156 00157 //! a2dTileBox is a subarea of a tile. 00158 /*! 00159 The drawing area is divided into tiles, where each tile is 256 * 256 pixels. 00160 The part of the tile which needs a redraw is stored in tile coordinates. 00161 */ 00162 class A2DCANVASDLLEXP a2dTileBox 00163 { 00164 public: 00165 00166 //! constructor 00167 a2dTileBox(int x1 = 0, int y1 = 0, int x2 = 0, int y2 = 0 ); 00168 00169 //! destructor 00170 ~a2dTileBox(); 00171 00172 //! Initialize a tile 00173 void Init( int x1 = 0, int y1 = 0, int x2 = 0, int y2 = 0 ); 00174 00175 //! expand a tile with this box 00176 void Expand( int x1, int y1, int x2, int y2 ); 00177 00178 //! get x1 in pixel coordinates 00179 inline int x1p() { return m_x1 << a2d_TILESHIFT; } 00180 //! get y1 in pixel coordinates 00181 inline int y1p() { return m_y1 << a2d_TILESHIFT; } 00182 //! get x2 in pixel coordinates 00183 inline int x2p() { return m_x2 << a2d_TILESHIFT; } 00184 //! get y2 in pixel coordinates 00185 inline int y2p() { return m_y2 << a2d_TILESHIFT; } 00186 00187 //! if set, true 00188 bool m_valid; 00189 00190 //! x1 in pixel coordinates 00191 int m_x1; 00192 //! y1 in pixel coordinates 00193 int m_y1; 00194 //! x2 in pixel coordinates 00195 int m_x2; 00196 //! y2 in pixel coordinates 00197 int m_y2; 00198 00199 //! prev row pointer to combine tiles into rectangles 00200 a2dUpdateArea* m_rectPrevRow; 00201 00202 }; 00203 00204 #define a2d_INIT_TILES 100 00205 00206 #if (defined(__WXMSW__) && defined(WXUSINGDLL) ) 00207 template class A2DCANVASDLLEXP a2dArrayGrow < a2dTileBox >; 00208 #endif 00209 00210 //! a storage for a a tiled area 00211 /*! 00212 An array of tiles width * height is maintained here. 00213 The tiles can be filled using scaning functions which take basic primitives as input. 00214 Later on the covered tiles can be extracted as a list of rectangles which 00215 cover the same area but with less rectangles in general. 00216 */ 00217 class A2DCANVASDLLEXP a2dTiles 00218 { 00219 public: 00220 00221 //! constructor 00222 /*! 00223 \param width number of horizontal tiles 00224 \param height number of vertical tiles 00225 */ 00226 a2dTiles(int width, int height); 00227 00228 //! destructor 00229 ~a2dTiles(); 00230 00231 //! change tile area 00232 void SetSize(int width, int height); 00233 00234 //! All tiles become empty 00235 void Clear(); 00236 00237 //! draw tiles to given view in device coordinates. 00238 void DrawTiles( a2dDrawer2D* drawer ); 00239 00240 //! draw optimized rectangles to given view in device coordinates. 00241 void DrawRects( a2dDrawer2D* drawer ); 00242 00243 //! convert internal tile to pixel coordinate tiles area 00244 inline int toP( int tilexy ) { return tilexy << a2d_TILESHIFT; } 00245 00246 //! convert pixel to internal tile coordinate tiles area 00247 inline int toT( int xy ) { return xy >> a2d_TILESHIFT; } 00248 00249 //! xy modules 256 00250 inline int ModT( int xy ) { return xy & (a2d_TILESIZE - 1); } 00251 00252 //! fill tiles covering the rect given see FillTiles( int x, int y, int w, int h, bool expand ) 00253 void FillTiles( const wxRect& rect, bool expand = true ); 00254 00255 //! fill tiles covering the rect given 00256 /*! 00257 The rect formed by x,y,w,h, is divided over the tiles, filling the the part of the tiles that 00258 are covered by the rectangle. 00259 00260 \param x x of rectangle 00261 \param y y of rectangle 00262 \param w width of rectangle 00263 \param h height of rectangle 00264 \param expand if true keep existing filled tiles, else clear all. 00265 */ 00266 void FillTiles( int x, int y, int w, int h, bool expand ); 00267 00268 //! are there filled tiles available? 00269 bool HasFilledTiles(); 00270 00271 //! generate from files tiles a list of semi optimal covering rectangles 00272 /*! 00273 The tiles are iterated in horizontal rows, combining filed tiles found 00274 in the rows when at same height and connecting with the previous tile. 00275 The found rect is then combined a rectangle already found in a previous row. 00276 */ 00277 a2dUpdateList* GenerateUpdateRectangles(); 00278 00279 //! see GenerateUpdateRectangles(), this one adds to the list given. 00280 void GenerateUpdateRectangles( a2dUpdateList* rects, wxUint8 id ); 00281 00282 //! number of horizontal tiles 00283 int m_width; 00284 //! number of vertical tiles 00285 int m_height; 00286 00287 //! get tile at index i 00288 inline a2dTileBox tile( int i ) 00289 { 00290 assert( i < ( m_width*m_height -1 ) ); 00291 return m_tiles[ i ]; 00292 } 00293 00294 //! array of tiles ( normally m_width * m_height ) 00295 vector< a2dTileBox > m_tiles; 00296 }; 00297 00298 class A2DCANVASDLLEXP a2dCanvas; 00299 class A2DCANVASDLLEXP a2dViewPrintout; 00300 00301 #if wxUSE_PRINTING_ARCHITECTURE 00302 class A2DCANVASDLLEXP a2dViewPrintout; 00303 00304 //! to print what is displayed on a a2dCanvasView or the whole document as seen from the showobject of the drawer. 00305 /*! 00306 Internal a second wxDarwer class is initiated with a mapping that nicely fits that mapping of the input 00307 a2dCanvasView to a piece of paper. This mapping depends on the type of print. If only what is on the view needs 00308 to be printed, the mapping of the input drawer is used, but if the whole document is wanted as seen 00309 from the ShowObject() of the input drawer, the boundingbox of the showobject will be used for the mapping. 00310 00311 00312 \ingroup docview 00313 */ 00314 class A2DCANVASDLLEXP a2dViewPrintout: public a2dDocumentPrintout 00315 { 00316 public: 00317 00318 //!initialize mapping based on an existing canvas 00319 /*! 00320 \param drawer the a2dCanvasView from which the print is wanted. 00321 00322 \param title title at top of the print 00323 00324 \param filename the name of the file to be printed (may be empty ) 00325 00326 \param typeOfPrint When called from a2dDocumentCommandProcessor, the a2dCommand* which lead to this call. 00327 00328 Depending on the command one can organize printing features. 00329 Like in the default implementation: 00330 \code 00331 a2dCommand_Print::a2dPrintWhat 00332 { 00333 Print, 00334 Preview, 00335 PrintView, 00336 PreviewView, 00337 PrintDocument, 00338 PreviewDocument, 00339 PrintSetup 00340 }; 00341 \endcode 00342 00343 Here View is to only print what is the visible view. 00344 Document print the document as seen from the 00345 a2dView::ShowObject(), it fits this to the paper. 00346 00347 \param drawframe print a frame rectangle in bounding box of drawing/view 00348 \param scalelimit limits the scaling (world/pixel) to the given value, so that small graphics are not zoomed to full page 00349 \param fitToPage scale to fit the page 00350 */ 00351 a2dViewPrintout(a2dCanvasView* drawer,const wxString& title, const wxString& filename, a2dCommand* typeOfPrint, bool drawframe, double scalelimit, bool fitToPage ); 00352 00353 //!destructor 00354 ~a2dViewPrintout(void); 00355 00356 //! called for every page to print, for a2dCanvasDocument in general just one. 00357 /*! 00358 It redraws/rerenders without double buffering the view or document on the pinter its wxDC. 00359 Internal a a2dDcDrawer is used to redraw the a2dCanvasDocument on the device. 00360 */ 00361 bool OnPrintPage(int); 00362 00363 protected: 00364 00365 //! type of print requested 00366 a2dCommand* m_typeOfPrint; 00367 00368 //! maping defined by this canvas 00369 a2dCanvasView* m_drawingView; 00370 00371 //!title put above printout 00372 wxString m_title; 00373 00374 //!filename put below printout 00375 wxString m_filename; 00376 00377 //! limit scaling to this value (world/pixel) 00378 double m_scalelimit; 00379 00380 //! draw a frame around the page 00381 bool m_drawframe; 00382 00383 //! draw a view without real scale, the scaling in X and Y may differ. 00384 //! The drawing is adjusted in X and Y seperately to draw until the sides/border of the printer area 00385 bool m_fitToPage; 00386 }; 00387 #endif 00388 00389 00390 //! Used by a2dCanvasView to decide what layers are to be rendered. 00391 /*! 00392 The a2dCanvasDocument is checked via a2dCanvasObject::Addpending() etc. which 00393 layers contain objects. The array containing this information is stored 00394 seperate for each a2dCanvasView. This is because each view can show different parts 00395 of a document, and one part can contain more layers then the other. 00396 This information is used to skip rendering layers which do not contain objects, 00397 or which are set invisible. 00398 00399 \ingroup canvasobject 00400 00401 \ingroup docview 00402 */ 00403 class A2DCANVASDLLEXP a2dLayerView 00404 { 00405 00406 public: 00407 00408 //!constructor 00409 a2dLayerView() 00410 { 00411 m_layervisible = true; 00412 m_layeravailable = false; 00413 m_check = true; 00414 } 00415 00416 ~a2dLayerView(){}; 00417 00418 //!is the layer visible 00419 bool GetVisible() { return m_layervisible; } 00420 00421 //! set layer visible 00422 void SetVisible( bool status ) { m_layervisible = status; } 00423 00424 //!are the objects on this layer 00425 bool GetAvailable() { return m_layeravailable; } 00426 00427 //! set layer available (will be rendered) 00428 void SetAvailable( bool status ) { m_layeravailable = status; } 00429 00430 //! check this layer? 00431 bool GetCheck() { return m_check; } 00432 00433 //! set the layer to be checked in idle time. 00434 void SetCheck( bool status ) { m_check = status; } 00435 00436 //! should this layer be rendered 00437 bool DoRenderLayer() 00438 { 00439 return ( m_layeravailable && m_layervisible ) || m_check; 00440 } 00441 00442 protected: 00443 00444 //!is the layer visible 00445 bool m_layervisible; 00446 00447 //!is the layer filled with primitives 00448 bool m_layeravailable; 00449 00450 //!if true layer need to be check again document for availability. 00451 bool m_check; 00452 }; 00453 00454 //! View on a a2dCanvasDocument, in which a2dCanvasObjects are shown. 00455 /*! 00456 a2dCanvasView is a specialized view to display parts of a a2dCanvasDocument. 00457 Such a part always starts at one a2dCanvasObject which is inside of a a2dCanvasDocument object. 00458 The a2dCanvasObject itself contains as children a2dCanvasObject derived drawable objects. A hierarchy 00459 of recursively nexted objects is what forms the actual drawing. 00460 The parent object to start the drawing is called the ShowObject. 00461 The member functions SetShowObject(...) are used to set the ShowObject to be displayed. 00462 All objects are defined in relative world coordinates, which are relative to the parent object(s). 00463 00464 a2dCanvasDocument is given as a drawing and/or updating context a a2dCanvasView. E.g. in 00465 a2dCanvasDocument::RenderTopObject() the a2dCanvasView is used by the a2dCanvasObject render functions to get to 00466 a2dCanvasView::m_drawer2D, which is the Drawing Context used to do the actual drawing within 00467 the a2dCanvasObjects. But a2dCanvasView::RenderTopObject() defines what drawing style is used to draw. 00468 00469 The real purpose of a2dCanvasView, is to maintain a list of damaged/changed areas in the view/drawing, and 00470 when time is ready, start redrawing those areas. When a a2dCanvasObject did change in position or size etc., 00471 the a2dCanvasDocument reports this change as a rectangular redraw areas to the a2dCanvasView's of that document. 00472 The update areas are based on the boundingbox of the object in its old state and in its new state. 00473 This reporting is done in idle time, and for all changed objects at once. When reporting of all changed areas is done, 00474 each a2dCanvasView knows what parts of its drawing need to be redrawn. It will then start redrawing those areas, 00475 but only after optimizing to the minimum areas to redraw. So overlapping areas will only be redrawn once. 00476 The mechanism for that is called tilling. 00477 00478 The size of the drawing in world coordinates and the size of the view in pixels is all indirectly defined by 00479 a2dCanvasView::m_drawer2D and a2dView::m_display. The area of the drawing in world coordinates that is visible, 00480 can be set via a2dCanvasView::m_drawer2D. Also if World coordinates is with the Y axis going up are down. 00481 a2dDrawer2D has methods to convert from world to device coordinates and visa versa. 00482 a2dCanvasView::m_drawer2D draws into a buffer. After rendering an update of all damaged parts into this buffer, 00483 it will be blitted from the buffer to the a2dView::m_display of the a2dCanvasView. This is done in Idle time, 00484 but can also be forced. In the end a2dCanvasView automatically always displays an up to date part of the drawing 00485 which is stored inside the a2dCanvasDocument. The user just changes a a2dCanvasObject inside the a2dCanvasDocument, 00486 and the redrawing on all the views will be done automatically. 00487 00488 A a2dCanvasView its a2dCanvasView::m_drawer2D knows where to draw to, this can be a bitmap buffer or a window etc. 00489 The job to update a window in case of drawing to a bitmap buffer, is not part of the a2dDrawer2D. 00490 This is/needs to be done by the class using the drawer, like a2dCanvasView and indirectly a2dCanvas here. 00491 The a2dCanvas receives a paint event, e.g. when moving an overlapping window or dialog, and it then blits the right 00492 parts from a2dCanvasView::m_drawer2D its drawing buffer to the canvas window. 00493 a2dCanvasView also takes care of scrolling the view, it does this by re-using the contents of the a2dDrawer2D drawing 00494 buffer when possible. 00495 The drawing buffer can be bigger then the size of the canvas window. a2dCanvasView always makes sure the whole buffer 00496 contains an up to date contents, as being the drawing to display form its document. Therefore if the canvas windows 00497 which uses the a2dCanvasView for drawing, implements scrolling and resizing, the canvas window is responsible for 00498 optimizing the scroll to take maximum advantage from the buffer of a2dCanvasView. Like if the buffer is bigger in 00499 size then the canvas windows size, a resize of the canvas window only needs to increase the buffer size of 00500 a2dCanvasView, when the size of the window exeeds the buffer size. 00501 One can even decide to set the buffer to the size of the complete virtual area that can be scrolled. 00502 This way one can make a trade of between buffer size and scrolling/resizing speed. 00503 Knowing this, one needs to realize that mouse coordinates as received inside a canvas window, are different 00504 if the origin in the drawing context is not at the orginin of the canvas window. 00505 The a2dCanvasView::m_drawer2D takes (0,0) of the buffer as the origin of device coodinates. 00506 */ 00507 class A2DCANVASDLLEXP a2dCanvasView: public a2dView 00508 { 00509 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG) 00510 a2dInitCurrentSmartPointerOwner m_initCurrentSmartPointerOwner; 00511 #endif 00512 A2D_DECLARE_EVENT_TABLE() 00513 00514 public: 00515 00516 00517 //!constructor 00518 /*! 00519 \remark 00520 Do not forget to call SetDocument() if used standalone 00521 (in a a2dDocumentCommandProcessor setting this is taken care of). 00522 */ 00523 a2dCanvasView( int width = 1000, int height = 1000 ); 00524 00525 //!constructor 00526 /*! 00527 Width and hight is given, mapping is as in drawer given. 00528 00529 \remark 00530 Do not forget to call SetDocument() if used standalone 00531 (in a a2dDocumentCommandProcessor setting this is taken care of). 00532 */ 00533 a2dCanvasView( int width, int height, a2dDrawer2D *drawer2D ); 00534 00535 //!constructor 00536 /*! 00537 Width and hight and mapping is as in drawer given. 00538 00539 \remark 00540 Do not forget to call SetDocument() if used standalone 00541 (in a a2dDocumentCommandProcessor setting this is taken care of). 00542 */ 00543 a2dCanvasView( a2dDrawer2D * drawer ); 00544 00545 //!constructor 00546 /*! 00547 \remark 00548 Do not forget to call SetDocument() if used standalone 00549 (in a a2dDocumentCommandProcessor setting this is taken care of) 00550 */ 00551 a2dCanvasView( const wxSize& size ); 00552 00553 //!copy constructor 00554 a2dCanvasView( const a2dCanvasView& other); 00555 00556 //! next to the base its m_display, this also sets m_drawer2d to this display 00557 virtual void SetDisplayWindow( wxWindow* display ); 00558 00559 //! Get the Display window of the a2dView. But casted to a a2dCanvas 00560 /*! when a a2dCanvas is used in this a2dCanvasView return it else 0. 00561 a2dCanvasView needs to know the window (a2dCanvas) to display itself. 00562 The a2dCanvasView updates to this window in idel time. 00563 Paint event to the a2dCanvas are using the a2dCanvasView its buffer for 00564 quick updating the a2dCanvas window. 00565 00566 \sa a2dView::SetDisplayWindow() 00567 */ 00568 a2dCanvas* GetCanvas() const { return (a2dCanvas*) m_display; } 00569 00570 //! sets buffersize ( if used ) for the a2dDrawer2D 00571 virtual void SetBufferSize( int w, int h ); 00572 00573 virtual bool GetTrippleBuf() { return false; } 00574 00575 virtual bool GetTrippleBufHasAlpha() { return false; } 00576 00577 virtual bool HasAlhpa() { return m_drawer2D->HasAlpha(); } 00578 00579 //!destructor 00580 virtual ~a2dCanvasView(); 00581 00582 //! if set true, document can contain objects that depend on this view (size etc). 00583 /*! If set those objects will be automatically updated for this view. 00584 Else the document is assumed to not contain viewdependent objects for this view, and that update cycle is skipped. 00585 */ 00586 void SetViewDependentObjects( bool viewDependentObjects ) { m_viewDependentObjects = viewDependentObjects; } 00587 00588 //! see SetViewDependentObjects() 00589 bool GetViewDependentObjects() const { return m_viewDependentObjects; } 00590 00591 //! get the layer render array 00592 a2dLayerView* GetLayerRenderArray() { return m_layerRenderArray; } 00593 00594 //!update layers available needed? 00595 /*! 00596 \sa Set_UpdateAvailableLayers 00597 */ 00598 bool Get_UpdateAvailableLayers() const { return m_update_available_layers; } 00599 00600 //! check which layers do contain objects as seen from the ShowObject() 00601 void SetAvailable(); 00602 00603 //! signals the need to check the given layer for visibility/availibility as seen from this view. 00604 void SetLayerCheck( wxUint16 layer ); 00605 00606 //! Sets a flag for updating available layers checking, which makes sure layers will be checked first when needed. 00607 /*! 00608 Eventually results in updating the layers table settings on layers available in document 00609 before rendering starts or simular functions. 00610 */ 00611 void Set_UpdateAvailableLayers( bool value ) { m_update_available_layers = value; } 00612 00613 //!Set to draw layers in reverse order 00614 void SetReverseOrder(bool revorder); 00615 00616 //!Get Setting for draw layers in reverse order 00617 bool GetReverseOrder() const { return m_reverse_order; } 00618 00619 //! used to extend a hittest with the number of pixels. 00620 /*! to be able to hit a line of width zero, a margin is needed to hit it, 00621 which is set here. 00622 00623 \remark default value is 2 pixels 00624 */ 00625 inline void SetHitMargin( wxUint16 pixels ) { m_hitmargin = pixels; } 00626 00627 //! Get HitMargin used to extend a hittest with the number of pixels. 00628 inline wxUint16 GetHitMarginDevice() const { return m_hitmargin; } 00629 00630 //! Get HitMargin used to extend a hittest in world units. 00631 double GetHitMarginWorld() const; 00632 00633 //! Special event handling for a2dCanvasView class 00634 /*! 00635 If eventprocessing is enabled and the view is enabled. OR in case this event ( wxEVT_ENABLE_VIEW | wxEVT_ENABLE_VIEWS ) 00636 is to enable this a2dView, the event is processed. 00637 00638 wxEVT_IDLE is first processed by the view, and next by the m_toolcontroller is set. 00639 wxEVT_PAINT is first processed by the m_display if set, next by the view, and next by the m_toolcontroller is set. 00640 This garantees proper redrawing of tools on top of the window. 00641 00642 Next to this check the command processor for its current parent object, and sent 00643 a command to set it right if change is needed. 00644 */ 00645 virtual bool ProcessEvent(wxEvent& event); 00646 00647 #if wxUSE_PRINTING_ARCHITECTURE 00648 //! to create a a2dViewPrintout, used to print a view or its document 00649 /*! 00650 The a2dViewPrintout created will take as much possible from the this view. 00651 a2dViewPrintout will create itself a view which fits the size of the paper, but important setting are taken from this view. 00652 */ 00653 virtual wxPrintout* OnCreatePrintout( a2dCommand* typeOfPrint ); 00654 #endif 00655 00656 //! If not set do not process mouse events. 00657 /*! 00658 Mouse events are handled by the canvas. 00659 They are redirected to the a2dCanvasObject hit. 00660 You can switch this off here, and skip the event from being processed. 00661 This is often used in tools, to prevent a2dCanvasObjects from receiving events. 00662 00663 \remark most events go to the m_toolcontroller first if set. \see ProcessEvent() 00664 */ 00665 void SetMouseEvents(bool onoff); 00666 00667 //! return true if this a2dCanvasView allows mouse events to be processed. 00668 bool GetMouseEvents() const { return m_mouseevents; } 00669 00670 //! set the object that is captured for events in the a2dCanvasDocument. 00671 /*! 00672 Used in combination with the a2dIterC class to set a corridor path for events. 00673 Do not use this function directly from outside a2dCorridor or a2diterC 00674 */ 00675 void SetCaptured( a2dCanvasObject* captured ) { m_capture = captured; } 00676 00677 //!are events redirected to a captured corridor? if so return the captured object in it, else NULL 00678 inline a2dCanvasObject* GetCaptured() const { return m_capture; } 00679 00680 //! use in combination with the a2dIterC class to set a corridor path for events. 00681 /*! 00682 A corridor path leads event to a specific a2dCanvasObject in a a2dCanvasDocument. 00683 This feature is used to do editing of nested a2dCanvasObject 's, and to captures events 00684 to such objects. 00685 The a2dCanvasObject's on a corridor path get the m_flags.m_isOnCorridorPath set, which result 00686 in redirecting events to the m_endCorridorObject. 00687 */ 00688 void SetEndCorridorObject( a2dCanvasObject* endCorridorObject ); 00689 00690 //! return the corridor object if set else NULL \see SetEndCorridorObject() 00691 a2dCanvasObject* GetEndCorridorObject() const { return m_endCorridorObject; } 00692 00693 //!get a2dCanvasDocument that is displayed on the canvas 00694 /*! 00695 As a side effect also sets this drawer for the document as active. 00696 */ 00697 a2dCanvasDocument* GetCanvasDocument() const; 00698 00699 //!set object available in the a2dCanvasDocument to be shown on the drawer 00700 /*! 00701 \param name name of top object 00702 \return pointer to the object found else NULL 00703 */ 00704 a2dCanvasObject* SetShowObject(const wxString& name); 00705 00706 //!set top object available in the a2dCanvasDocument to be shown on the drawer 00707 /*! 00708 \param obj: pointer to object to show 00709 */ 00710 bool SetShowObject(a2dCanvasObject* obj); 00711 00712 //!return pointer of then currently shown object on the drawer. 00713 /*! 00714 \return: pointer to the current object that is shown. 00715 */ 00716 a2dCanvasObject* GetShowObject() const { 00717 return m_top; } 00718 00719 //!add pending update for the area that is the boundingbox of the given object 00720 /*! 00721 Updates the boundingbox area of the given object at idle time. 00722 If obj is NULL nothing will be done 00723 If refalso is true then all references to this object will be updated also. 00724 00725 \param obj the object where to take the bounding box from 00726 \param refsalso <code>true</code> to update all references, else <code>false</code> 00727 */ 00728 void AddPendingUpdateArea( a2dCanvasObject* obj, wxUint8 id = 0, bool refsalso=true ); 00729 00730 //!recursive find pending objects and adds their areas to the updatelist 00731 /*! it does first test if the a2dCanvasDocument has the flag set to tell it has pending objects inside. 00732 If that is the case, it traverses the a2dCanvasDocument, and adds 00733 the absolute boundingbox of the pending object to the a2dCanvasView updatelist. 00734 This is for all paths leading to the object from the current ShowObject, so also a2dCanvasObjectReference's. 00735 \return true if did add pendingobject's else false 00736 */ 00737 bool AddObjectPendingUpdates(); 00738 00739 //!add boundingbox to update list for updating in idle time 00740 void AddPendingUpdateArea(const a2dBoundingBox& box, wxUint8 id = 0 ); 00741 00742 //!add rectangle to update list for updating in idle time 00743 void AddPendingUpdateArea( const wxRect& recnew, wxUint8 id = 0 ); 00744 00745 //!add area to update list for updating in idle time 00746 /*! 00747 the given area will be added to the 00748 list of rectangles to be blitted to the screen later in idle time, 00749 at repaint or after an UpdateNow action. 00750 The given area will be combined (merged/ignored) with the already available update areas. 00751 This to prevent un necessary redraws. 00752 */ 00753 void AddPendingUpdateArea( int x, int y, int w, int h, wxUint8 id = 0 ); 00754 00755 void AddOverlayAreas( bool update ); 00756 00757 //! add to list of overlay objects (must be children of m_top) 00758 void AddOverlayObject( a2dCanvasObject* obj ); 00759 00760 //! remove from the list of overlay objects (must be children of m_top) 00761 void RemoveOverlayObject( a2dCanvasObject* obj ); 00762 00763 //! Not implemented, use a2dViewPrintout to print 00764 /*! 00765 OnDraw is called when printing a view via wxView::OnPrint with wxDocPrintout::OnPrintPage. 00766 But for a2dCanvasView, i implemented it in a2dViewPrintout::OnPrintPage. 00767 00768 This funcion is and should NOT be used to Redraw the a2dCanvasView views, this is taken care of automatically, 00769 and if needed can be forced with OnUpdate or Update. 00770 Paint events are intercepted to blit damaged parts caused by overlaping windows, 00771 and in Idle time changes or updated in a2dCanvasView. 00772 */ 00773 virtual void OnDraw( wxDC* ); 00774 00775 //! depending on the hint value performs specific updating on the view. 00776 /*! 00777 Hint is unsigned int containing flags of type \sa a2dCanViewUpdateFlags which actions will be executed in the right order. 00778 In principle the view its internal data ( this is mostly the buffer ) should be updated, and be made ready 00779 for redisplay on the view its DisplayWindow(). 00780 A reason for updating a view, is a change in the a2dCanvasDocument. The document is checked for changes in idle 00781 time, and updates all views on the document at once when a change exists. 00782 First all changed areas on the view because of changes to the document, are reported by the document to the a2dCanvasView. 00783 The a2dCanvasView keeps an internal list of areas needing a redraw. 00784 The areas reported are found on the basis of the old and new boundingboxes of the changed objects. 00785 Next the areas in the updatelist are redrawn in the buffer of the a2dCanvasView, and at last those areas will be blitted. 00786 00787 The above is done automatic, but one is free for whatever reason to add pending areas directly to the 00788 a2dCanvasView its update arealist. Those will be updated also in idle time, along with all others areas as a result 00789 of changing objects. 00790 00791 \remark OnUpdate is the key routine to speedy redraws, proper use asures only redraw of changed or 00792 damaged areas in idle time. 00793 00794 \remark Called in a2dCanvasDocument from UpdateAllViews() and AddPendingUpdatesOldNew() to update this view. 00795 00796 \remark a2dCANVIEW_UPDATE_BLIT means, blit all updated areas for this a2dCanvas now to the screen, 00797 else it will happen in idle time. 00798 Use a2dCANVIEW_UPDATE_OLDNEW |a2dCANVIEW_UPDATE_BLIT | a2dCANVIEW_UPDATE_BLIT 00799 to support dragging for instance, because in such cases idle time 00800 will take to long. Other a2dCanvas using the same a2dCanvasDocument will not be redrawn and blitted 00801 when double buffered. 00802 */ 00803 void OnUpdate( a2dDocumentEvent& event ); 00804 00805 //! see OnUpdate 00806 /*!by default adds a full pending update for the drawer and all in it, and redraws this to the device. 00807 Use how = a2dCANVIEW_UPDATE_ALL when the contents/data of the canvas has changed 00808 without specific updates applied to areas. This will do the redraw in idle time. 00809 For example: after adding many new objects to the root object 00810 or other objects referenced or after changing the root object 00811 00812 \remark the default value is brute force redraw all, but in general not wise to use since it means a total redraw. 00813 instead most often a2dCANVIEW_UPDATE_OLDNEW is used, or if result needs to be displayed directly, use 00814 ( a2dCANVIEW_UPDATE_OLDNEW |a2dCANVIEW_UPDATE_AREAS | a2dCANVIEW_UPDATE_BLIT ) 00815 00816 */ 00817 void Update( unsigned int how = (a2dCANVIEW_UPDATE_ALL | a2dCANVIEW_UPDATE_BLIT) 00818 , wxObject* hintObject = NULL ); 00819 00820 //!update/redraw part of the buffer, using the given a2dCanvasDocument and ShowObject within that root. 00821 /*! 00822 This method also takes care of redrawing the background and the grid 00823 */ 00824 virtual void UpdateArea( int x, int y, int width, int height, wxUint8 id = 0 ); 00825 00826 virtual void ClearArea( int x, int y, int width, int height ); 00827 00828 virtual void RenderChildObject( a2dCanvasObject* obj ); 00829 00830 //! blit part of the drawing buffer to the canvas 00831 virtual void BlitBuffer( int x, int y, int width, int height, int xbuf, int ybuf ); 00832 00833 //!Function to draw the origin 00834 /*!override this function in a derived class to redefine painting of the origin*/ 00835 virtual void DrawOrigin(); 00836 00837 //!Function to draw the grid 00838 /*!override this function in a derived class to redefine painting of the grid*/ 00839 virtual void PaintGrid( int x, int y, int width, int height ); 00840 00841 //!(re)painting of background 00842 /*!override this function in a derived class to redefine painting of the background*/ 00843 virtual void PaintBackground( int x, int y, int width, int height ); 00844 00845 //! set enable crosshair cursor 00846 void SetCrossHair( bool onoff ); 00847 00848 //! get enable crosshair cursor 00849 bool GetCrossHair() { return m_crosshair; } 00850 00851 //! set crosshair cursor Length in X in pixels 00852 void SetCrossHairLengthX( int LengthX ) { m_crosshairLengthX = LengthX; } 00853 00854 //! set crosshair cursor Length in Y in pixels 00855 void SetCrossHairLengthY( int LengthY ) { m_crosshairLengthY = LengthY; } 00856 00857 //! get crosshair cursor Length in X in pixels 00858 int GetCrossHairLengthX() { return m_crosshairLengthX; } 00859 00860 //! get crosshair cursor Length in Y in pixels 00861 int GetCrossHairLengthY() { return m_crosshairLengthY; } 00862 00863 //!set stroke for crosshair 00864 void SetCrossHairStroke( const a2dStroke& stroke ); 00865 00866 //!get stroke for crosshair 00867 a2dStroke& GetCrossHairStroke() { return m_crosshairStroke; } 00868 00869 //! blit old areas to remove last drawn crosshair and draw the cross hair at this new position. 00870 virtual void UpdateCrossHair( int x, int y ); 00871 00872 //! set a2dFill to use when RenderFIX_STYLE is set. 00873 void SetFixedStyleFill( const a2dFill& fixFill ) { m_fixFill = fixFill; } 00874 00875 //! set a2dStroke to use when RenderFIX_STYLE is set. 00876 void SetFixedStyleStroke( const a2dStroke& fixStroke ) { m_fixStroke = fixStroke; } 00877 00878 //! set a2dFill to use when RenderWIREFRAME_SELECT or RenderWIREFRAME_SELECT_INVERT is set. 00879 void SetSelectFill( const a2dFill& selectFill ) { m_selectFill = selectFill; } 00880 00881 //! set a2dStroke to use when RenderWIREFRAME_SELECT or RenderWIREFRAME_SELECT_INVERT is set. 00882 void SetSelectStroke( const a2dStroke& selectStroke ) { m_selectStroke = selectStroke; } 00883 00884 //! set a2dFill to use when RenderWIREFRAME_HighLight. 00885 void SetHighLight( const a2dFill& hightLightFill ) { m_highLightFill = hightLightFill; } 00886 00887 //! set a2dStroke to use when RenderWIREFRAME_HighLight. 00888 void SetHighLight( const a2dStroke& hightLightStroke ) { m_highLightStroke = hightLightStroke; } 00889 00890 //! set a2dFill to use when RenderFIX_STYLE is set. 00891 void SetOverlayFill( const a2dFill& overlayFill ) { m_overlayFill = overlayFill; } 00892 00893 //! set a2dStroke to use when RenderFIX_STYLE is set. 00894 void SetOverlayStroke( const a2dStroke& overlayStroke ) { m_overlayStroke = overlayStroke; } 00895 00896 //!background fill for the canvas 00897 void SetBackgroundFill( const a2dFill& backgroundfill ); 00898 00899 //!get current background fill for the canvas 00900 a2dFill& GetBackgroundFill() { return m_backgroundfill; } 00901 00902 //!Set grid setting for drawing grid in front or back 00903 void SetGridAtFront(bool gridatfront){ m_gridatfront = gridatfront; Update( a2dCANVIEW_UPDATE_ALL ); } 00904 00905 //!Get grid setting for drawing grid in front or back 00906 bool GetGridAtFront(){ return m_gridatfront;} 00907 00908 //!set stroke used for grid drawing 00909 void SetGridStroke( const a2dStroke& gridstroke); 00910 00911 //!set size of grid circle 00912 void SetGridSize(wxUint16 gridsize){ m_gridsize = gridsize; Update( a2dCANVIEW_UPDATE_ALL );} 00913 00914 //!set fill used for grid drawing 00915 void SetGridFill( const a2dFill& gridfill); 00916 00917 //!Get grid distance in X 00918 double GetGridX(){return m_gridx;} 00919 00920 //!Set grid distance in X 00921 void SetGridX(double gridx){ m_gridx = gridx; Update( a2dCANVIEW_UPDATE_ALL );} 00922 00923 //!Get grid distance in Y 00924 double GetGridY(){return m_gridy;} 00925 00926 //!Set grid distance in Y 00927 void SetGridY(double gridy){ m_gridy = gridy; Update( a2dCANVIEW_UPDATE_ALL );} 00928 00929 //!Set grid on/off 00930 void SetGrid(bool grid){ m_grid = grid; Update( a2dCANVIEW_UPDATE_ALL ); } 00931 00932 //!Get grid setting on/off 00933 bool GetGrid(){return m_grid;} 00934 00935 //!Get grid setting for line drawing 00936 /*!Note: SetGridSize must be 0, if gridlines=false */ 00937 void SetGridLines(bool gridlines) { m_gridlines = gridlines; Update( a2dCANVIEW_UPDATE_ALL ); } 00938 00939 //!Get setting for grid to draw lines instead of points 00940 bool GetGridLines() { return m_gridlines; } 00941 00942 //!Set grid threshold, if grid distance is below this in pixels, it will be increased 00943 //! by factors of 2 until it fits. 00944 void SetGridThreshold( wxUint16 gridthres ) { m_gridthres = gridthres; Update( a2dCANVIEW_UPDATE_ALL ); } 00945 00946 //!Get grid threshold. 00947 wxUint16 GetGridThreshold() { return m_gridthres; } 00948 00949 //!Set showorigin on/off 00950 void SetShowOrigin(bool show) { m_showorigin = show; Update( a2dCANVIEW_UPDATE_ALL ); } 00951 00952 //!Returns if canvas is frozen. 00953 bool IsFrozen() { return m_frozen; } 00954 00955 //!prevent changing the a2dCanvasView buffer and blitting it to the window 00956 /*! 00957 This makes sure the contents displayed into the a2dCanvasView buffer does not change. 00958 Pending objects inside a root will be added to the update list of the a2dCanvasView, 00959 but not redrawn into the buffer until Thaw. 00960 00961 \see Thaw 00962 */ 00963 void Freeze(); 00964 00965 //! to release Freeze() 00966 /*! 00967 The Frozen view ( Freeze() ), is released. Pending update araes in the update list 00968 will be redrawn in OnIdle at the next idle event. 00969 00970 \see Freeze 00971 00972 \param update if true all shown on this view will be redrawn. 00973 */ 00974 void Thaw( bool update ); 00975 00976 //! blit pending update areas, that are already updated to the buffer, now to the screen. 00977 /*! does the second stage in the two stage process of updating 00978 */ 00979 virtual bool BlitPendingUpdateAreas(); 00980 00981 //! set toolcontroller ( reset with NULL ) 00982 /*! Toolcontrollers are meant to implement tools that manipulate the objects 00983 displayed on the a2dCanvas. 00984 All events to the canvas window or first redirected to the controller. 00985 When skipped in the controller the events will eventually reach the a2dCanvas itself. 00986 00987 \return true is there was a controller set already. 00988 00989 \remark The controller is owned by the canvas and will be deleted by the canvas on destruction or when changed. 00990 */ 00991 bool SetCanvasToolContr( a2dToolContr* controller ); 00992 00993 a2dToolContr* GetCanvasToolContr() { return m_toolcontroller; } 00994 00995 void SetCursor(const wxCursor&cursor); 00996 00997 //! push a cursor on the cursor stack, and set display cursor to new back being cursor. 00998 void PushCursor(const wxCursor& cursor); 00999 01000 //! pop a cursor from the cursor stack, and set display cursor to back 01001 void PopCursor(); 01002 01003 //! clear the stack of cursor, and set display cursor ARROW. 01004 void ClearCursorStack(); 01005 01006 //!do a hittest on the view at coordinates x,y 01007 /*! 01008 \param x x of point to do hittest 01009 \param y y of point to do hittest 01010 \param layer test only if objects are on this layer or if set to wxLAYER_ALL test obejcts on all layers 01011 \param option ways to hit 01012 \param mask only object with this mask set will be hit 01013 01014 \return the top object that was hit (e.g.in case of groups) 01015 01016 \remark hit margin is defined in a2dCanvasDocument containing the root group 01017 */ 01018 a2dCanvasObject* IsHitWorld( 01019 double x, double y, 01020 int layer = wxLAYER_ALL, 01021 a2dHitOption option = a2dCANOBJHITOPTION_NONE, 01022 bool filterSelectableLayers = false 01023 ); 01024 01025 //!do an advanged hittest on the view 01026 /*! 01027 \param hitEvent stores hit information 01028 \param layer test only if objects are on this layer or if set to wxLAYER_ALL test obejcts on all layers 01029 01030 \return the top object that was hit (e.g.in case of groups) 01031 01032 \remark hit margin is defined in a2dCanvasDocument containing the root group 01033 */ 01034 a2dCanvasObject* IsHitWorld( 01035 a2dHitEvent& hitEvent, 01036 int layer = wxLAYER_ALL 01037 ); 01038 01039 //! Corridor and captured object event processing. 01040 /*! 01041 Follow corridor set, and redirect the event to last object in the corridor. 01042 The event is first sent to the child objects, and if not processed there, 01043 testing for a hit on the object itself is done, and if true a2dEvtHandler::ProcessEvent is called. 01044 01045 \param event the event to process 01046 \param isHit return if there was a hit on an object 01047 \param x x of point to do hittest 01048 \param y y of point to do hittest 01049 \param margin margin that still gives a valid hittest. 01050 \param layer only if object is on this layer or if set to wxLAYER_ALL ignore layer id. 01051 01052 \return true if Object (or a child ) did process the event and did not call event.Skip() 01053 */ 01054 virtual bool ProcessCanvasObjectEvent( wxEvent& event, bool& isHit, 01055 double x, double y, int margin, 01056 int layer = wxLAYER_ALL ); 01057 01058 //! Corridor and captured object event processing. 01059 /*! This is the same as the function 01060 ProcessCanvasObjectEvent( wxEvent& event, bool& isHit, double x, double y, int margin, int layer = wxLAYER_ALL ), 01061 but it sets the iteration context pointer of the event. 01062 This is used when sending a2dCanvasObjectEvents from a simple (handle less) tool. 01063 01064 \param event the event to process 01065 \param isHit return if there was a hit on an object 01066 \param x x of point to do hittest 01067 \param y y of point to do hittest 01068 \param margin margin that still gives a valid hittest. 01069 \param layer only if object is on this layer or if set to wxLAYER_ALL ignore layer id. 01070 01071 \return true if Object (or a child ) did process the event and did not call event.Skip() 01072 */ 01073 virtual bool ProcessCanvasObjectEvent( a2dCanvasObjectEvent& event, bool& isHit, 01074 double x, double y, int margin, 01075 int layer = wxLAYER_ALL ); 01076 01077 //! This function is called after a property changed 01078 /*! This is overloaded to update the view if needed. 01079 */ 01080 void OnPropertyChanged( const a2dPropertyId* id ); 01081 01082 //! Find the show-object child object, set the path to the given child object and capture it 01083 /*! \see a2dIterC::SetCorridorPath 01084 This is used to redirect events to a specific child object, e.g. one found by 01085 extended hit testing. 01086 01087 \param findObject (child) object to be searched for. 01088 \param capture if true the findObject is captured 01089 \return true if findObject was found 01090 */ 01091 bool FindAndSetCorridorPath( a2dCanvasObject* findObject, bool capture ); 01092 01093 //! find object on the current corridor path. 01094 /*! 01095 The a2dCanvasObject in the document with the m_flags.m_isOnCorridorPath set, are 01096 pushed into a list, which is returned. If non found the return is false, else true and the list 01097 of objects leading to the end of the corridor. 01098 */ 01099 // bool FindCorridorPath( a2dCorridor& result ); 01100 01101 //! set a corridor from a list of objects 01102 void SetCorridorPath( const a2dCorridor& corridor ); 01103 01104 //! Reset all corridor paths and uncapture object 01105 /*! \see a2dIterC::SetCorridorPath 01106 Reset a corridor path set with FindAndSetCorridorPath 01107 01108 \param uncapture if true uncaptured the captured object 01109 */ 01110 void ClearCorridorPath( bool uncapture ); 01111 01112 01113 //! use the boundingbox of the ShowObject to set the mapping such that it will be displayed completely on the device. 01114 /*! 01115 \see SetMappingDeviceRect to map to a different device/buffer rectangle. 01116 */ 01117 void SetMappingShowAll(); 01118 01119 //! set the internal m_drawer2D to be used for rendering the document 01120 /*! The drawing context is owned by a2dCanvasView, it will delete it. 01121 Still you set it to NULL or othere context without deletion using the noDelete parameter. 01122 01123 \param drawer2d the drawing context object to set 01124 \param noDelete default the old drawing context object is deleted, but not is this is set true. 01125 This can be used to simulate ownership of the drawing context by another class. 01126 */ 01127 void SetDrawer2D( a2dDrawer2D* drawer2d, bool noDelete = false ); 01128 01129 //! get the internal m_drawer2D that is used for rendering the document 01130 a2dDrawer2D* GetDrawer2D() { return m_drawer2D; } 01131 01132 //!set drawstyles to use for drawing the document 01133 /*! 01134 The internal m_drawer2D is set to this style before rendering of the document starts. 01135 01136 \remark m_drawstyleRestore is set to the current drawstyle. So a temporary change can easily be restored. 01137 01138 \param drawstyle one of the draw styles 01139 */ 01140 void SetDocumentDrawStyle( wxUint32 drawstyle ); 01141 01142 //! restore drawstyle to the one before the last change 01143 void RestoreDrawStyle() { m_documentDrawStyle = m_documentDrawStyleRestore; } 01144 01145 //!get drawstyles used for drawing the document 01146 wxUint32 GetDocumentDrawStyle() { return m_documentDrawStyle; } 01147 01148 void SetOverlayDrawStyle( a2dDocumentRenderStyle drawstyle ); 01149 01150 //! scroll up down or left right 01151 /*! \param dxy scroll distance in X or Y 01152 \param yscroll if true scrolling is in Y else X 01153 \param total update whole device after scroll 01154 */ 01155 virtual void Scroll( int dxy, bool yscroll, bool total); 01156 01157 //! does render the top object in the given style. 01158 /*! 01159 This function can be used from tools to render the tool its objects which do become 01160 part of the document in a certain style. 01161 */ 01162 virtual void RenderTopObject( wxUint32 documentDrawStyle, wxUint8 id ); 01163 01164 //! single drawstyle render cycle called on document 01165 /*! 01166 Render the given topobject and all that is below it 01167 Will recursive call the render routines of all the objects seen from the topobject. 01168 This rendering iterates over layers. 01169 \param mask object must have this mask 01170 \param drawstyle which drawstyle should be used for this render action . 01171 01172 \remark If a layer is Invisible it will not be rendered. 01173 */ 01174 virtual void RenderTopObject( a2dCanvasObjectFlagsMask mask, a2dDocumentRenderStyle drawstyle ); 01175 01176 //! render of overlay objects stored in m_overlayObjects specific to the view 01177 virtual void RenderOverlay( a2dDocumentRenderStyle drawstyle ); 01178 01179 //! update the transform matrix for objects with property 'PROPID_viewDependent' 01180 /*! 01181 will recursive call the UpdateViewDependentObjects routines of all the objects seen from the topobject. 01182 01183 \remark TODO: Check all child objects (TODO for optimize: with flag 'm_childpixelsize=true'). 01184 */ 01185 void UpdateViewDependentObjects(); 01186 01187 //! If true render the printout with a title string, otherwise not 01188 void SetPrintTitle( bool val ) { m_printtitle = val; } 01189 01190 //! If true render the printout with a filename string, otherwise not 01191 void SetPrintFilename( bool val ) { m_printfilename = val; } 01192 01193 //! Set the scaling limit for printing, so that small stuff is not zoomed to full page 01194 void SetPrintScaleLimit( double val ) { m_printscalelimit = val; } 01195 01196 //! If true, draw a frame around printouts 01197 void SetPrintFrame( bool val ) { m_printframe = val; } 01198 01199 //! If true, draw a view on all page without real scale 01200 void SetPrintFitToPage( bool val ) { m_printfittopage = val; } 01201 01202 //! get mouse position X 01203 int GetMouseX() { return m_mouse_x; } 01204 //! get mouse position Y 01205 int GetMouseY() { return m_mouse_y; } 01206 01207 //! get mouse position X in world coordinates 01208 int GetWorldMouseX() { return (int)m_drawer2D->DeviceToWorldX(m_mouse_x); } 01209 //! get mouse position Y in world coordinates 01210 int GetWorldMouseY() { return (int)m_drawer2D->DeviceToWorldY(m_mouse_y); } 01211 01212 //! convert mouse position as seen from the display window, into world coordinates. 01213 //! If no display window is defined, 01214 void MouseToToolWorld( int x, int y, double& xWorldLocal, double& yWorldLocal ); 01215 01216 protected: 01217 01218 //! Default handler for wxEVT_ACTIVATE_VIEW called when the view gets the focus or something else needs 01219 /*! 01220 to have this view the active view ( the one which recieves events from the containing window ). 01221 This drawer is set (non)active for the a2dCanvasDocument which is displayed on this drawer. 01222 01223 \remark at least called when a2dCanvasView gets the focus 01224 01225 \sa wxView::Activate 01226 */ 01227 void OnActivate( a2dViewEvent& activateEvent ); 01228 01229 void OnEnter( wxMouseEvent & WXUNUSED(event) ); 01230 01231 //! redraw and/or blit pending areas to the device 01232 void OnIdle(wxIdleEvent &event); 01233 01234 //! normally sent from wxWindow containing the view, via its ProcessEvent(wxEvent& event) 01235 void OnMouseEvent( wxMouseEvent &event ); 01236 01237 //! normally sent from wxWindow containing the view, via its ProcessEvent(wxEvent& event) 01238 /*! 01239 01240 */ 01241 void OnCharEvent( wxKeyEvent &event ); 01242 01243 //! next to base class functionality, 01244 /*! 01245 this here removes or resets the toolcontroller. 01246 The wxEVT_CLOSE_VIEW is first sent to the m_toolcontroller, so in there it is 01247 intercepted too. 01248 */ 01249 void OnCloseView( a2dCloseViewEvent& event ); 01250 01251 //! called for a2dComEvent events. 01252 void OnComEvent( a2dComEvent& event ); 01253 01254 //! called when document of the a2dView has changed. 01255 /*! 01256 Sets the a2dCanvasDocument where the objects for this canvas are stored 01257 It will trigger boundingbox calculation and other administrative tasks 01258 to properly render the document onto this view 01259 */ 01260 void OnSetDocument( a2dViewEvent& event ); 01261 01262 //!redraw the pending update areas to the buffer given in device coordinates. 01263 void RedrawPendingUpdateAreas( bool noblit = false ); 01264 01265 //!pending update areas in the update list are deleted. 01266 /*! use when ready with updates, or when they become useless because of scroll etc. 01267 */ 01268 void DeleteAllPendingAreas(); 01269 01270 //! based on angle and radius and m_aberration calculate a proper delta phi and number of segments 01271 /*! 01272 The calculation is used for circular arc segments 01273 */ 01274 void Aberration( double angle, double radius, double& dphi, unsigned int& segments ); 01275 01276 //!buffer updating activity possible or not 01277 bool m_frozen; 01278 01279 //!object that is receiving events 01280 a2dCanvasObjectPtr m_capture; 01281 01282 //! when a corridor is active, this is set. 01283 a2dCanvasObjectPtr m_endCorridorObject; 01284 01285 //!enable/ disable mouse events handling by canvas 01286 bool m_mouseevents; 01287 01288 //!top object for drawer object, from here the rendering starts 01289 a2dCanvasObjectPtr m_top; 01290 01291 //!background fill of canvas and background color of background fill in case of mono colour fill 01292 a2dFill m_backgroundfill; 01293 01294 //!showorigin? 01295 bool m_showorigin; 01296 01297 //!grid drawn at front or back 01298 bool m_gridatfront; 01299 01300 //! is croshair visible 01301 bool m_crosshair; 01302 01303 //!crosshair x 01304 int m_crosshairx; 01305 01306 //!crosshair y 01307 int m_crosshairy; 01308 01309 //! crosshair cursor Length in X in pixels 01310 int m_crosshairLengthX; 01311 01312 //! crosshair cursor Length in Y in pixels 01313 int m_crosshairLengthY; 01314 01315 //! stroke to use for crosshair 01316 a2dStroke m_crosshairStroke; 01317 01318 //! last mouse position 01319 int m_mouse_x, m_mouse_y; 01320 01321 //!grid stroke 01322 a2dStroke m_gridstroke; 01323 01324 //!grid fill 01325 a2dFill m_gridfill; 01326 01327 //!fixed style stroke 01328 a2dStroke m_fixStroke; 01329 01330 //!fixed style fill 01331 a2dFill m_fixFill; 01332 01333 //!overlay style stroke 01334 a2dStroke m_overlayStroke; 01335 01336 //!overlay style fill 01337 a2dFill m_overlayFill; 01338 01339 //!select style stroke 01340 a2dStroke m_selectStroke; 01341 01342 //!select style fill 01343 a2dFill m_selectFill; 01344 01345 //!highLight style stroke 01346 a2dStroke m_highLightStroke; 01347 01348 //!highLight style fill 01349 a2dFill m_highLightFill; 01350 01351 //!grid distance in x 01352 double m_gridx; 01353 01354 //!grid distance in y 01355 double m_gridy; 01356 01357 //!grid point size 01358 wxUint16 m_gridsize; 01359 01360 //!show grid as lines 01361 bool m_gridlines; 01362 01363 //! threshold for grid. 01364 wxUint16 m_gridthres; 01365 01366 //!grid on/off 01367 bool m_grid; 01368 01369 //!is the virtual area set already (used during startup) 01370 bool m_virtualarea_set; 01371 01372 //!device size width 01373 int m_width; 01374 01375 //!device size height 01376 int m_height; 01377 01378 //! accuracy of spline 01379 double m_splineaberration; 01380 01381 //! pushed clipping regions 01382 a2dClipRegionList m_clipregionlist; 01383 01384 //!accuracy of arc segment calculation etc. in device coordinates 01385 double m_displayaberration; 01386 01387 //!list of rectangles that need to be blited to the screen. 01388 /*! 01389 This list holds several rectangles, which should be updated. 01390 The are blitted from the buffer, since they were damaged they first need to be updated. 01391 */ 01392 a2dUpdateList m_updateareas; 01393 01394 //!to prevent recursive updates 01395 bool m_recur; 01396 01397 //! toolscontroller plugged in as first event handler 01398 a2dSmrtPtr<a2dToolContr> m_toolcontroller; 01399 01400 a2dDrawer2D *m_drawer2D; 01401 01402 //! how close does a hit need to be to the object you are trying to hit. 01403 /*! This is given in device units (pixels) and tranformed to world units 01404 using the drawers transform 01405 */ 01406 wxUint16 m_hitmargin; 01407 01408 //! underneath the threshold draw rectangles. 01409 bool m_asrectangle; 01410 01411 //! drawstyles to use when rendering document 01412 wxUint32 m_documentDrawStyle; 01413 01414 //! drawstyles to use when rendering overlay 01415 a2dDocumentRenderStyle m_overlayDrawStyle; 01416 01417 //! to restore style after a temporary change. 01418 wxUint32 m_documentDrawStyleRestore; 01419 01420 //! if true, a printout is done with title (document name (description?)), otherwise not 01421 bool m_printtitle; 01422 01423 //! if true, a printout is done with filename (document file path), otherwise not 01424 bool m_printfilename; 01425 01426 //! Set the scaling limit for printing, so that small stuff is not zoomed to full page 01427 double m_printscalelimit; 01428 01429 //! If true, draw a frame around printouts 01430 bool m_printframe; 01431 01432 //! If true, draw a view on all page without real scale 01433 bool m_printfittopage; 01434 01435 //! which layer should be rendered ( visible and/or available ) 01436 a2dLayerView m_layerRenderArray[wxMAXLAYER]; 01437 01438 //!flag to updatelayers that are available. 01439 /*! 01440 It is set when m_layerRenderArray does not contain all layers used by a2dCanvasObject's 01441 */ 01442 bool m_update_available_layers; 01443 01444 //! tiles on drawing surface, used to optimize update areas. 01445 a2dTiles m_tiles; 01446 01447 a2dTiles m_tiles2; 01448 01449 //!draw in reverse order if set 01450 bool m_reverse_order; 01451 01452 bool m_viewDependentObjects; 01453 01454 a2dCursorStack m_cursorStack; 01455 01456 a2dCanvasObjectList m_overlayObjects; 01457 01458 public: 01459 01460 bool m_skipBuffer; 01461 01462 DECLARE_DYNAMIC_CLASS(a2dCanvasView) 01463 01464 private: 01465 01466 //initialize a drawer 01467 void Init(); 01468 01469 public: 01470 01471 static a2dPropertyIdUint16* PROPID_drawstyle; 01472 static a2dPropertyIdBool* PROPID_gridlines; 01473 static a2dPropertyIdBool* PROPID_grid; 01474 static a2dPropertyIdBool* PROPID_showorigin; 01475 static a2dPropertyIdUint16* PROPID_hitmargin; 01476 static a2dPropertyIdBool* PROPID_gridatfront; 01477 static a2dPropertyIdUint16* PROPID_gridsize; 01478 static a2dPropertyIdUint16* PROPID_gridthres; 01479 static a2dPropertyIdDouble* PROPID_gridx; 01480 static a2dPropertyIdDouble* PROPID_gridy; 01481 01482 //! when more layers changed ( rerendering view is needed). 01483 static const wxEventType sm_changedLayers; 01484 //! when an object is added to a layer, and therefore makes this layer available. 01485 static const wxEventType sm_changedLayerAvailable; 01486 //! when one layer is set visible in a2dCanvasView 01487 static const wxEventType sm_changedLayerVisibleInView; 01488 //! sent when activating a frame ( maybe containing several a2dView's ), used to update dialogs for the current 01489 //! active frame which shows some views. 01490 static const wxEventType sm_changedActiveView; 01491 01492 //! id for changed a2dObject 01493 //! a new show object was chosen in a2dCanvasView 01494 static const wxEventType sm_changedShowObject; 01495 01496 DECLARE_PROPERTIES() 01497 01498 }; 01499 01500 #if (defined(__WXMSW__) && defined(WXUSINGDLL) ) 01501 template class A2DCANVASDLLEXP a2dSmrtPtr<a2dCanvasView>; 01502 #endif 01503 01504 01505 //! view to display the size of a2dCanvasView compared to the whole of the a2dCanvasDocument that is viewed. 01506 /*! 01507 \ingroup docview 01508 */ 01509 class A2DCANVASDLLEXP a2dZoomedView: public wxWindow 01510 { 01511 DECLARE_EVENT_TABLE() 01512 01513 public: 01514 01515 //! constructor 01516 a2dZoomedView( wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, a2dCanvasView* canvasview ); 01517 01518 //!destructor 01519 virtual ~a2dZoomedView(); 01520 01521 protected: 01522 01523 //! called for a2dComEvent events. 01524 void OnComEvent( a2dComEvent& event ); 01525 01526 //! \cond 01527 01528 void OnUpdate( a2dDocumentEvent& event ); 01529 01530 //! repaint damaged araes. 01531 void OnPaint( wxPaintEvent &event ); 01532 01533 void OnRemoveView( a2dDocumentEvent& event ); 01534 01535 //! resize 01536 void OnSize( wxSizeEvent &event ); 01537 01538 //! \endcond 01539 01540 //! the view to view zoomed 01541 a2dCanvasView* m_canvasDocview; 01542 01543 DECLARE_CLASS(a2dZoomedView) 01544 01545 private: 01546 01547 01548 }; 01549 01550 01551 01552 01553 01554 01555 01556 #endif /* __WXDRAWER_H__ */ 01557 01558 01559