00001 /*! \file wx/canvas/cansim.h 00002 \brief simple canvas which takes as view the whole of the scrollable area. 00003 While a2dCanvas display and draws only what is visible, this a2dCanvasSim always 00004 draws all that will be scrollable. So scrolling is quick. 00005 00006 \author Klaas Holwerda 00007 00008 Copyright: 2001-2004 (C) Klaas Holwerda 00009 00010 Licence: wxWidgets Licence 00011 00012 RCS-ID: $Id: cansim.h,v 1.15 2008/07/19 18:29:43 titato Exp $ 00013 */ 00014 00015 #ifndef __A2DCANVASSIM_H__ 00016 #define __A2DCANVASSIM_H__ 00017 00018 #ifndef WX_PRECOMP 00019 #include "wx/wx.h" 00020 #endif 00021 00022 #include "wx/image.h" 00023 #include "wx/txtstrm.h" 00024 #include "wx/geometry.h" 00025 #include "wx/canvas/candefs.h" 00026 #include "wx/canvas/canobj.h" 00027 #include "wx/artbase/bbox.h" 00028 #include "wx/canvas/drawer.h" 00029 00030 //! Simple canvas using a whole view for all of the scrolled window 00031 /*! 00032 This canvas use a wxScrolledWindow as basis. 00033 The a2dCanvasView used to draw has a buffer the size of the virtual scrollable area. 00034 The scrollable/virtual area is defined in pixels. The window show the part of the virtual area 00035 which is visible. One can scroll through the contents of the buffer, and the scroll bars show which 00036 part of the buffer is visble. 00037 So the scrollable area calculated in world coordinates, defines the maximum boundaries of what can be seen 00038 of the drawing in the associated a2dCanvasDocument. One can set the mapping matrixes which calculates 00039 device to world coordinates and visa versa, but this does not influence the scrollbars, since the always 00040 only show what part of the buffer is visible. Resizing a window, sets the drawing buffer to the new virtual 00041 size of the scrolled window, but mapping from world to device coordinates stays the same. 00042 00043 This is rather different from what is done in a2dCanvas, where the scrollable area is defined in 00044 worldcoordinates, and zooming recalculates the scrollbar positions in such a manner that they indicate 00045 what part of the drawing is shown in the canvas window as compared to the total visible area. 00046 00047 \sa a2dCanvas 00048 a2dCanvasView 00049 a2dMemDcDrawer 00050 a2dCanvasDocument 00051 a2dCanvasObject 00052 00053 \ingroup drawer docview 00054 */ 00055 class A2DCANVASDLLEXP a2dCanvasSim: public a2dDocumentViewScrolledWindow 00056 { 00057 public: 00058 00059 //!constructor 00060 /*! 00061 construct a canvas window. 00062 00063 Internal a a2dCanvasView and a2dCanvasDocument are created 00064 to render all objects stored in the a2dCanvasDocument into this a2dCanvas window. 00065 00066 The document and drawer or deleted in the destructor. 00067 00068 00069 \remark used for standalone a2dCanvas windows. 00070 00071 \param parent parent window (use wxNO_FULL_REPAINT_ON_RESIZE on parent wxFrame) 00072 \param id window id 00073 \param pos position of window 00074 \param size size of window 00075 \param style type of window (wxHSCROLL|wxVSCROLL) 00076 00077 \remark with new unknown drawer types you can derive or extend the library 00078 */ 00079 a2dCanvasSim( wxWindow *parent, wxWindowID id = -1, 00080 const wxPoint& pos = wxDefaultPosition, 00081 const wxSize& size = wxDefaultSize, 00082 long style = wxScrolledWindowStyle ); 00083 00084 //!destructor 00085 /*!when a tool controller was set is will be deleted also. 00086 */ 00087 virtual ~a2dCanvasSim(); 00088 00089 //! use the boundingbox of the ShowObject to set the mapping such that it will be displayed completely. 00090 /*! 00091 \param centre if true centre on window, else to (0,0) of device 00092 */ 00093 void SetMappingShowAll( bool centre = true ); 00094 00095 //! what is the drawer 00096 a2dCanvasView* GetCanvasView() const { return wxStaticCastNull( m_view.Get(), a2dCanvasView ); } 00097 00098 //! Get the drawer of the view 00099 a2dDrawer2D *GetDrawer2D() const { return GetCanvasView()->GetDrawer2D(); } 00100 00101 //! Clears the canvas (like wxWindow::ClearBackground) 00102 /*! 00103 * Calls internally a2dCanvasSim::ClearBackground() 00104 * Clear() was renamed in wxWin 2.5 to ClearBackground() 00105 * 00106 * \todo 00107 * Remove this method after wxWin 2.6 release. 00108 */ 00109 void ClearBackground(); 00110 00111 //!background fill for the canvas 00112 void SetBackgroundFill( const a2dFill& backgroundfill ); 00113 00114 //! Refresh window 00115 /*! 00116 Next to base class, makes sure all pending objects are processed, and scrolling is set right. 00117 */ 00118 virtual void Refresh( bool eraseBackground = true, const wxRect* rect = NULL ); 00119 00120 //!Set grid setting for drawing grid in front or back 00121 void SetGridAtFront(bool gridatfront) { (wxStaticCast( m_view.Get(), a2dCanvasView ) )->SetGridAtFront(gridatfront); } 00122 00123 //!Get grid setting for drawing grid in front or back 00124 bool GetGridAtFront() { return (wxStaticCast( m_view.Get(), a2dCanvasView ) )->GetGridAtFront(); } 00125 00126 //!set stroke used for grid drawing 00127 void SetGridStroke( const a2dStroke& gridstroke) { (wxStaticCast( m_view.Get(), a2dCanvasView ) )->SetGridStroke(gridstroke); } 00128 00129 //!set size of grid circle 00130 void SetGridSize( wxUint16 gridsize) { (wxStaticCast( m_view.Get(), a2dCanvasView ) )->SetGridSize(gridsize); } 00131 00132 //!set brush used for grid drawing 00133 void SetGridFill( const a2dFill& gridfill) { (wxStaticCast( m_view.Get(), a2dCanvasView ) )->SetGridFill(gridfill); } 00134 00135 //!Get grid distance in X 00136 double GetGridX() { return (wxStaticCast( m_view.Get(), a2dCanvasView ) )->GetGridX(); } 00137 00138 //!Set grid distance in X 00139 void SetGridX(double gridx) { (wxStaticCast( m_view.Get(), a2dCanvasView ) )->SetGridX(gridx); } 00140 00141 //!Get grid distance in Y 00142 double GetGridY() { return (wxStaticCast( m_view.Get(), a2dCanvasView ) )->GetGridY(); } 00143 00144 //!Set grid distance in Y 00145 void SetGridY(double gridy) { (wxStaticCast( m_view.Get(), a2dCanvasView ) )->SetGridY(gridy); } 00146 00147 //!Set grid on/off 00148 void SetGrid(bool grid) { (wxStaticCast( m_view.Get(), a2dCanvasView ) )->SetGrid(grid); } 00149 00150 //!Get grid setting on/off 00151 bool GetGrid() { return (wxStaticCast( m_view.Get(), a2dCanvasView ) )->GetGrid(); } 00152 00153 //!Get grid setting for line drawing 00154 void SetGridLines(bool gridlines) { (wxStaticCast( m_view.Get(), a2dCanvasView ) )->SetGridLines(gridlines); } 00155 00156 //!set grid to draw lines instead of points 00157 bool GetGridLines() { return (wxStaticCast( m_view.Get(), a2dCanvasView ) )->GetGridLines(); } 00158 00159 //!Set showorigin on/off 00160 void SetShowOrigin(bool show) { (wxStaticCast( m_view.Get(), a2dCanvasView ) )->SetShowOrigin(show); } 00161 00162 //!set if the Yaxis goes up or down 00163 void SetYaxis(bool up); 00164 00165 //!get currently used Yaxis setting 00166 bool GetYaxis() const; 00167 00168 //! zoomout leafs a border of this amount of pixels around the drawing 00169 void SetZoomOutBorder( wxUint16 border ) { m_border = border; } 00170 00171 //!Returns if canvas is frozen. 00172 bool IsFrozen() { return m_frozen; } 00173 00174 //!prevent changing the a2dCanvasView buffer and blitting it to the window 00175 /*! To make sure the contents displayed into the a2dCanvasView buffer does not change. 00176 Pending objects inside a root will be added to the update list of the a2dCanvasView, 00177 but not redrawn into the buffer until Thaw. 00178 */ 00179 void Freeze(); 00180 00181 //!allow a2dCanvasView buffer to be changed and blitting it to the window 00182 /*! Enable updating of the a2dCanvasView buffer contents. 00183 */ 00184 void Thaw(); 00185 00186 //!get root group that is displayed on the canvas 00187 a2dCanvasDocument* GetCanvasDocument(); 00188 00189 //!Give the virtual size to be displayed, the mappingmatrix will be calculated. 00190 /*! 00191 The current window size in pixels is used to calculate the mapping such that 00192 at least it will display all of the area given. 00193 00194 Setting virtual area to boundingbox of a drawing (currently visible ShowObject() 00195 \code 00196 m_worldcanvas->SetMappingWidthHeight(m_worldcanvas->GetShowObject()->GetXMin(), 00197 m_worldcanvas->GetShowObject()->GetYMin(), 00198 m_worldcanvas->GetShowObject()->GetWidth(), 00199 m_worldcanvas->GetShowObject()->GetHeight()) 00200 \endcode 00201 00202 \remark do not use during start up since window size is not well defined in that case resulting in 00203 \remark bad settings for the mapping. 00204 00205 \param vx1 minimum world x coordinate 00206 \param vy1 minimum world y coordiante ( either Lower or Upper Left corner depending on SetYaxis() ) 00207 \param width minimum width in world coordinates which we want to display on this window 00208 \param height minimum height in world coordinates which we want to display on this window 00209 */ 00210 void SetMappingWidthHeight( double vx1, double vy1, double width, double height ); 00211 00212 //!Give the virtual size to be displayed, the mappingmatrix will be calculated. 00213 /*! 00214 To display all of a drawing, set this here to the boundingbox of the show object 00215 of the canvas. 00216 So vx1 and vx2 to the miminum x and y of the boundingbox. 00217 Calculate xpp and ypp in such a manner that it will show the whole drawing. 00218 00219 Setting virtual area to boundingbox of a drawing (currently visible group) 00220 00221 \code 00222 int dx2,dy2; 00223 m_canvas->GetClientSize(&dx2,&dy2); 00224 double xupp=(m_canvas->GetShowObject()->GetWidth())/dx2; 00225 double yupp=(m_canvas->GetShowObject()->GetHeight())/dy2; 00226 if (yupp > xupp) 00227 xupp=yupp; 00228 m_worldcanvas->SetMappingUpp(m_worldcanvas->GetShowObject->GetXMin(), 00229 m_worldcanvas->GetShowObject->GetYMin(),xupp,xupp); 00230 \endcode 00231 00232 If a scrollable area is set, it will be called also to adjust it. 00233 \param vx1 minimum world x coordinate 00234 \param vy1 minimum world y coordiante ( either Lower or Upper Left corner depending on SetYaxis() ) 00235 \param xpp: Number of world units per pixel in x 00236 \param ypp: Number of world units per pixel in y 00237 */ 00238 void SetMappingUpp( double vx1, double vy1, double xpp, double ypp); 00239 00240 //!convert x from window to virtual coordinates 00241 inline double DeviceToWorldX(int x) const { return (wxStaticCast( m_view.Get(), a2dCanvasView ) )->GetDrawer2D()->DeviceToWorldX(x); } 00242 //!convert y from window to virtual coordinates 00243 inline double DeviceToWorldY(int y) const { return (wxStaticCast( m_view.Get(), a2dCanvasView ) )->GetDrawer2D()->DeviceToWorldY(y); } 00244 //!convert x relative from window to virtual coordinates 00245 //!use this to convert a Length of a line for instance 00246 inline double DeviceToWorldXRel(int x) const { return (wxStaticCast( m_view.Get(), a2dCanvasView ) )->GetDrawer2D()->DeviceToWorldXRel(x); } 00247 //!convert y relative from window to virtual coordinates 00248 //!use this to convert a Length of a line for instance 00249 inline double DeviceToWorldYRel(int y) const { return (wxStaticCast( m_view.Get(), a2dCanvasView ) )->GetDrawer2D()->DeviceToWorldYRel(y); } 00250 00251 //!convert x from virtual to window coordinates 00252 inline int WorldToDeviceX(double x) const { return (wxStaticCast( m_view.Get(), a2dCanvasView ) )->GetDrawer2D()->WorldToDeviceX(x); } 00253 //!convert y from virtual to window coordinates 00254 inline int WorldToDeviceY(double y) const { return (wxStaticCast( m_view.Get(), a2dCanvasView ) )->GetDrawer2D()->WorldToDeviceY(y); } 00255 //!convert x relative from virtual to window coordinates 00256 //!use this to convert a Length of a line for instance 00257 inline int WorldToDeviceXRel(double x) const { return (wxStaticCast( m_view.Get(), a2dCanvasView ) )->GetDrawer2D()->WorldToDeviceXRel(x); } 00258 //!convert y relative from virtual to window coordinates 00259 //!use this to convert a Length of a line for instance 00260 inline int WorldToDeviceYRel(double y) const { return (wxStaticCast( m_view.Get(), a2dCanvasView ) )->GetDrawer2D()->WorldToDeviceYRel(y); } 00261 00262 //!set object available in the a2dCanvasDocument to be shown on the canvas 00263 //!\param name: name of top object 00264 //!\return pointer to the object found else NULL 00265 a2dCanvasObject* SetShowObject(const wxString& name); 00266 00267 //!set top object available in the a2dCanvasDocument to be shown on the canvas 00268 //!\param obj: pointer to object to show 00269 bool SetShowObject(a2dCanvasObject* obj); 00270 00271 //!return pointer of then currently shown object on the canvas. 00272 //!\return pointer to the current object that is shown. 00273 a2dCanvasObject* GetShowObject() const { return (wxStaticCast( m_view.Get(), a2dCanvasView ) )->GetShowObject(); } 00274 00275 //!do a hittest on the canvas at coordinates x,y 00276 /*! 00277 \param x: x of point to do hittest 00278 \param y: y of point to do hittest 00279 \param layer only if object is on this layer or if set to wxLAYER_ALL ignore layer id. 00280 \param option special hittest options 00281 \return the top object that was hit (e.g.in case of groups) 00282 00283 \remark hit margin is defined in a2dCanvasDocument containing the root group 00284 */ 00285 a2dCanvasObject* IsHitWorld( 00286 double x, double y, 00287 int layer = wxLAYER_ALL, 00288 a2dHitOption option = a2dCANOBJHITOPTION_NOROOT | a2dCANOBJHITOPTION_LAYERS 00289 ); 00290 00291 //!Mouse events are handled by the canvas. 00292 //!They are redirected to the object hit. 00293 //!You can switch this off here, used in most tools. 00294 void SetMouseEvents(bool onoff); 00295 00296 bool GetMouseEvents(); 00297 00298 //! write what you see to an SVG( scalable vector graphics file ) 00299 bool WriteSVG(const wxString& filename, double Width, double Height, wxString unit); 00300 00301 protected: 00302 00303 //! resize, adjusting buffer of a2dCanvasView if needed. 00304 void OnSize( wxSizeEvent &event ); 00305 00306 //! repaint damaged araes, taking into acount non updated araes in a2dCanvasView. 00307 void OnPaint( wxPaintEvent &event ); 00308 00309 //! Not yet implemented 00310 void OnEraseBackground( wxEraseEvent &event ); 00311 00312 //! remove all pending update areas in a2dCanvasView 00313 void DeleteAllPendingAreas(); 00314 00315 private: 00316 00317 //!oversize of buffer compared to screen width and height 00318 int m_delta; 00319 00320 //!prevent updating activity if true 00321 bool m_frozen; 00322 00323 //! to check if drawer document was changed 00324 a2dCanvasDocument* m_doc; 00325 00326 //! border zoomout but leaf around a border of this amount of pixels. 00327 wxUint16 m_border; 00328 00329 DECLARE_CLASS(a2dCanvasSim) 00330 DECLARE_EVENT_TABLE() 00331 00332 }; 00333 00334 #endif 00335 // A2DCANVAS 00336