wxArt2D
drawer.cpp
Go to the documentation of this file.
1 /*! \file canvas/src/drawer.cpp
2  \author Klaas Holwerda
3 
4  Copyright: 2000-2004 (c) Klaas Holwerda
5 
6  Licence: wxWidgets Licence
7 
8  RCS-ID: $Id: drawer.cpp,v 1.241 2009/09/30 18:38:59 titato Exp $
9 */
10 
11 #include "a2dprec.h"
12 
13 #ifdef __BORLANDC__
14 #pragma hdrstop
15 #endif
16 
17 #ifndef WX_PRECOMP
18 #include "wx/wx.h"
19 #endif
20 
21 #include <wx/dcprint.h>
22 
23 #include <wx/print.h>
24 
25 #include "wx/canvas/layerinf.h"
26 #include "wx/canvas/drawer.h"
27 
28 #include "wx/canvas/canvas.h"
29 #include "wx/canvas/cansim.h"
30 #include "wx/canvas/tools.h"
31 #include "wx/artbase/drawer2d.h"
32 #include "wx/artbase/dcdrawer.h"
33 #include "wx/canvas/canglob.h"
34 #include "wx/canvas/algos.h"
35 #include "wx/canvas/drawing.h"
36 #include "wx/canvas/cameleon.h"
37 
38 #include <wx/wfstream.h>
39 
40 #include <wx/stdstream.h>
41 
42 #define CROSS_HAIR_X 300
43 #define CROSS_HAIR_Y 300
44 
45 //----------------------------------------------------------------------------
46 // a2dCursorStack
47 //----------------------------------------------------------------------------
48 
49 a2dCursorStack::a2dCursorStack()
50 {
51 }
52 
53 //----------------------------------------------------------------------------
54 // a2dPushInStack
55 //----------------------------------------------------------------------------
56 
57 a2dPushInStack::a2dPushInStack()
58 {
59 }
60 
61 //----------------------------------------------------------------------------
62 // globals
63 //----------------------------------------------------------------------------
64 WX_DEFINE_LIST( a2dUpdateListBase );
65 
66 
67 #ifdef CLASS_MEM_MANAGEMENT
68 a2dMemManager a2dUpdateList::sm_memManager( wxT( "a2dUpdateList memory manager" ) );
69 #endif //CLASS_MEM_MANAGEMENT
70 
71 //----------------------------------------------------------------------------
72 // a2dTileBox
73 //----------------------------------------------------------------------------
74 a2dTileBox::a2dTileBox( int x1, int y1, int x2, int y2 )
75 {
76  Init( x1, y1, x2, y2 );
77 }
78 
80 {
81 }
82 
83 void a2dTileBox::Init( int x1, int y1, int x2, int y2 )
84 {
85  m_x1 = x1;
86  m_y1 = y1;
87  m_x2 = x2;
88  m_y2 = y2;
89  m_rectPrevRow = NULL;
90  m_valid = false;
91  if ( m_x1 != m_x2 && m_y1 != m_y2 )
92  m_valid = true;
93 }
94 
95 void a2dTileBox::Expand( int x1, int y1, int x2, int y2 )
96 {
97  if ( !m_valid )
98  {
99  m_x1 = x1; m_y1 = y1;
100  m_x2 = x2; m_y2 = y2;
101  }
102  else
103  {
104  m_x1 = wxMin( m_x1, x1 );
105  m_x2 = wxMax( m_x2, x2 );
106  m_y1 = wxMin( m_y1, y1 );
107  m_y2 = wxMax( m_y2, y2 );
108  }
109  if ( m_x1 != m_x2 && m_y1 != m_y2 )
110  m_valid = true;
111 }
112 
113 //----------------------------------------------------------------------------
114 // a2dTiles
115 //----------------------------------------------------------------------------
116 a2dTiles::a2dTiles( int width, int height ): m_tiles( width* height )
117 {
118  m_width = width;
119  m_height = height;
120 }
121 
123 {
124 }
125 
126 void a2dTiles::SetSize( int width, int height )
127 {
128  m_tiles.resize( width * height );
129  m_width = width;
130  m_height = height;
131 }
132 
134 {
135  int t;
136  for ( t = 0; t < m_tiles.size(); t++ )
137  {
138  m_tiles[t].m_valid = false;
139  m_tiles[t].m_rectPrevRow = NULL;
140  }
141 }
142 
144 {
145  int t;
146  for ( t = 0; t < m_tiles.size(); t++ )
147  if ( m_tiles[t].m_valid == true )
148  return true;
149  return false;
150 }
151 
153 {
154  int x, y;
155  drawer->PushIdentityTransform();
156 
157  drawer->SetDrawerStroke( a2dStroke( wxColour( 0, 0, 0 ), 1 ) );
158 
159  for ( y = 0; y < m_height; y++ )
160  {
161  drawer->DrawLine( 0, toP( y ), toP( m_width ), toP( y ) );
162  for ( x = 0; x < m_width; x++ )
163  {
164  drawer->DrawLine( toP( x ), 0, toP( x ), toP( m_height ) );
165  }
166  }
167 
168  drawer->SetDrawerStroke( a2dStroke( wxColour( 210, 22, 25 ), 2 ) );
169  drawer->SetDrawerFill( a2dFill( wxColour( 10, 187, 15 ), a2dFILL_HORIZONTAL_HATCH ) );
170 
171  for ( y = 0; y < m_height; y++ )
172  {
173  for ( x = 0; x < m_width; x++ )
174  {
175  a2dTileBox box = m_tiles[ x + y * m_width ];
176  if ( box.m_valid )
177  {
178  int x1 = toP( x ) + box.m_x1;
179  int y1 = toP( y ) + box.m_y1;
180  int x2 = toP( x ) + box.m_x2;
181  int y2 = toP( y ) + box.m_y2;
182  drawer->DrawRoundedRectangle( x1, y1, x2 - x1, y2 - y1, 0 );
183  }
184  }
185  }
186  drawer->PopTransform();
187 }
188 
190 {
191  drawer->PushIdentityTransform();
192 
194 
195  a2dUpdateList::compatibility_iterator nodeb = a2dTiles->GetFirst();
196  while ( nodeb )
197  {
198  a2dUpdateArea* uobj = nodeb->GetData();
199 
200  int x, y, width, height;
201  x = uobj->x;
202  y = uobj->y;
203  width = uobj->width;
204  height = uobj->height;
205 
206  drawer->DrawRoundedRectangle( x, y, width, height, 0 );
207 
208  nodeb = nodeb->GetNext();
209  }
210 
211  drawer->PopTransform();
212  a2dTiles->DeleteContents( true );
213  delete a2dTiles;
214 }
215 
216 void a2dTiles::FillTiles( const wxRect& rect, bool expand )
217 {
218  FillTiles( rect.x, rect.y, rect.width, rect.height, expand );
219 }
220 
221 void a2dTiles::FillTiles( int xr, int yr, int w, int h, bool expand )
222 {
223  int x, y, x1, y1, x2, y2; //maximum and minimum tile corners which rect fits in
224 
225  if ( !w || !h )
226  return;
227 
228  int widthPix = m_width * a2d_TILESIZE;
229  int heightPix = m_height * a2d_TILESIZE;
230  // clip to buffer
231  if ( xr < 0 )
232  {
233  w += xr;
234  xr = 0;
235  }
236  if ( w <= 0 ) return;
237 
238  if ( yr < 0 )
239  {
240  h += yr;
241  yr = 0;
242  }
243  if ( h <= 0 ) return;
244 
245  if ( xr + w > widthPix )
246  {
247  w = widthPix - xr;
248  }
249  if ( w <= 0 ) return;
250 
251  if ( yr + h > heightPix )
252  {
253  h = heightPix - yr;
254  }
255  if ( h <= 0 ) return;
256 
257  if ( !expand )
258  Clear();
259 
260  x1 = toT( xr );
261  y1 = toT( yr );
262  x2 = toT( xr + w + a2d_TILESIZE );
263  y2 = toT( yr + h + a2d_TILESIZE );
264 
265  int width = x2 - x1; //tiles to check in x
266  int height = y2 - y1; //tiles to check in y
267 
268  int tx1, ty1, tx2, ty2; //rest at corner tiles.
269 
270  // get the rest at the corners of the rectangle, which partly covers 4 tiles.
271  tx1 = ModT( xr );
272  ty1 = ModT( yr );
273  // E.G Tiles(0 -> 255) ( 0 ->255 ) == pixels (0 -> 611)
274  tx2 = ModT( xr + w );
275  ty2 = ModT( yr + h );
276  if ( height == 1 )
277  {
278  if ( width == 1 )
279  m_tiles[ x1 + y1 * m_width ].Expand( tx1, ty1, tx2, ty2 );
280  else
281  {
282  int ti = x1 + y1 * m_width;
283  m_tiles[ ti++ ].Expand( tx1, ty1, a2d_TILESIZE - 1, ty2 );
284  for ( x = 1; x < width - 1; x++ )
285  m_tiles[ ti++ ].Expand( 0, ty1, a2d_TILESIZE - 1, ty2 );
286  m_tiles[ ti++ ].Expand( 0, ty1, tx2, ty2 );
287  }
288  }
289  else
290  {
291  if ( width == 1 )
292  {
293  m_tiles[ x1 + y1 * m_width ].Expand( tx1, ty1, tx2, a2d_TILESIZE - 1 );
294  for ( y = 1; y < height - 1; y++ )
295  m_tiles[ x1 + ( y1 + y )*m_width ].Expand( tx1, 0, tx2, a2d_TILESIZE - 1 );
296  m_tiles[ x1 + ( y1 + y )*m_width ].Expand( tx1, 0, tx2, ty2 );
297  }
298  else
299  {
300  //bottom row
301  int ti = x1 + y1 * m_width;
302  m_tiles[ ti++ ].Expand( tx1, ty1, a2d_TILESIZE - 1, a2d_TILESIZE - 1 );
303  for ( x = 1; x < width - 1; x++ )
304  m_tiles[ ti++ ].Expand( 0, ty1, a2d_TILESIZE - 1, a2d_TILESIZE - 1 );
305  m_tiles[ ti++ ].Expand( 0, ty1, tx2, a2d_TILESIZE - 1 );
306 
307  //all in the middle rows
308  for ( y = 1; y < height - 1; y++ )
309  {
310  ti = x1 + ( y1 + y ) * m_width;
311  m_tiles[ ti++ ].Expand( tx1, 0, a2d_TILESIZE - 1, a2d_TILESIZE - 1 );
312  for ( x = 1; x < width - 1; x++ )
313  m_tiles[ ti++ ].Expand( 0, 0, a2d_TILESIZE - 1, a2d_TILESIZE - 1 );
314  m_tiles[ ti++ ].Expand( 0, 0, tx2, a2d_TILESIZE - 1 );
315  }
316 
317  ti = x1 + ( y1 + y ) * m_width;
318  //top row
319  m_tiles[ ti++ ].Expand( tx1, 0, a2d_TILESIZE - 1, ty2 );
320  for ( x = 1; x < width - 1; x++ )
321  m_tiles[ ti++ ].Expand( 0, 0, a2d_TILESIZE - 1, ty2 );
322  m_tiles[ ti++ ].Expand( 0, 0, tx2, ty2 );
323  }
324  }
325 }
326 
328 {
329  a2dUpdateList* rects = new a2dUpdateList();
330 
331  GenerateUpdateRectangles( rects, 0 );
332 
333  return rects;
334 }
335 
337 {
338  int x1, y1, x2, y2;
339 
341  //tile indexes
342  int tilei, lefttilei;
343  int x, y;
344  tilei = 0;
345  for ( y = 0; y < m_height; y++ )
346  {
347  for ( x = 0; x < m_width; x++ )
348  {
349  tile = m_tiles[ tilei ];
350  if ( tile.m_valid )
351  {
352  x1 = toP( x ) + tile.m_x1;
353  y1 = toP( y ) + tile.m_y1;
354  y2 = toP( y ) + tile.m_y2;
355 
356  lefttilei = tilei;
357 
358  //extend rectangle to the right when this one is full in x and other is
359  //continue-ing at same y1 and y2
360  tile = m_tiles[tilei];
361  while ( x != m_width - 1 &&
362  tile.m_x2 == ( a2d_TILESIZE - 1 ) && //this tile connect to next tile in x
363  m_tiles[tilei + 1].m_x1 == 0 &&
364  tile.m_y1 == m_tiles[tilei + 1].m_y1 &&
365  tile.m_y2 == m_tiles[tilei + 1].m_y2
366  )
367  {
368  tilei++;
369  tile = m_tiles[tilei];
370  x++;
371  }
372  x2 = toP( x ) + tile.m_x2;
373 
374  //if we found some tiles filled ( and combined ) in this row?
375  if ( ( x1 ^ x2 ) | ( y1 ^ y2 ) )
376  {
377  a2dUpdateArea* prevRows = m_tiles[lefttilei].m_rectPrevRow;
378  if ( prevRows &&
379  x1 == prevRows->x &&
380  x2 == prevRows->x + prevRows->width &&
381  y1 == prevRows->y + prevRows->height + 1 //only when y1 is at border to previous row
382  )
383  {
384  //extend lower rectangle with this one
385  prevRows->height = y2 - prevRows->y;
386  }
387  else
388  {
389  //add a new rectangle for output, and use it as prevRow pointer in coming row
390  prevRows = new a2dUpdateArea( x1, y1, x2 - x1, y2 - y1, id );
391  rects->Append( prevRows );
392  }
393 
394  //store the found rect or NULL inside the coming row, in order to later merge with that row
395  // its found rectangles when possible.
396  if ( y != m_height - 1 )
397  m_tiles[lefttilei + m_width].m_rectPrevRow = prevRows;
398  }
399  }
400  tilei++;
401  }
402  }
403 }
404 
405 //----------------------------------------------------------------------------
406 // a2dUpdateArea
407 //----------------------------------------------------------------------------
408 #ifdef CLASS_MEM_MANAGEMENT
409 a2dMemManager a2dUpdateArea::sm_memManager( wxT( "a2dUpdateArea memory manager" ) );
410 #endif //CLASS_MEM_MANAGEMENT
411 
412 a2dUpdateArea::a2dUpdateArea( int x, int y, int width, int height, wxUint8 id ): wxRect( x, y, width, height )
413 {
414  m_update_done = false;
415  m_update_direct = false;
416  m_id = id;
417 }
418 
419 a2dUpdateArea::~a2dUpdateArea()
420 {
421 }
422 
423 
424 
425 //----------------------------------------------------------------------------
426 // a2dDrawingPart
427 //----------------------------------------------------------------------------
428 
429 a2dPropertyIdUint16* a2dDrawingPart::PROPID_drawstyle = NULL;
430 a2dPropertyIdBool* a2dDrawingPart::PROPID_gridlines = NULL;
431 a2dPropertyIdBool* a2dDrawingPart::PROPID_grid = NULL;
432 a2dPropertyIdBool* a2dDrawingPart::PROPID_showorigin = NULL;
433 a2dPropertyIdUint16* a2dDrawingPart::PROPID_hitmargin = NULL;
434 a2dPropertyIdBool* a2dDrawingPart::PROPID_gridatfront = NULL;
435 a2dPropertyIdUint16* a2dDrawingPart::PROPID_gridsize = NULL;
436 a2dPropertyIdUint16* a2dDrawingPart::PROPID_gridthres = NULL;
437 a2dPropertyIdDouble* a2dDrawingPart::PROPID_gridx = NULL;
438 a2dPropertyIdDouble* a2dDrawingPart::PROPID_gridy = NULL;
439 
440 INITIALIZE_PROPERTIES( a2dDrawingPart, a2dObject )
441 {
442  A2D_PROPID_D( a2dPropertyIdUint16, drawstyle, a2dFILLED );
443  A2D_PROPID_M( a2dPropertyIdBool, a2dDrawingPart, gridlines, false, m_gridlines );
444  A2D_PROPID_M( a2dPropertyIdBool, a2dDrawingPart, grid, false, m_grid );
445  A2D_PROPID_M( a2dPropertyIdBool, a2dDrawingPart, showorigin, false, m_showorigin );
446  A2D_PROPID_M( a2dPropertyIdBool, a2dDrawingPart, gridatfront, false, m_gridatfront );
447  A2D_PROPID_M( a2dPropertyIdUint16, a2dDrawingPart, hitmargin, 0, m_hitmargin );
448  A2D_PROPID_M( a2dPropertyIdUint16, a2dDrawingPart, gridsize, 0, m_gridsize );
449  A2D_PROPID_M( a2dPropertyIdUint16, a2dDrawingPart, gridthres, 0, m_gridthres );
450  A2D_PROPID_M( a2dPropertyIdDouble, a2dDrawingPart, gridx, 0, m_gridx );
451  A2D_PROPID_M( a2dPropertyIdDouble, a2dDrawingPart, gridy, 0, m_gridy );
452  return true;
453 }
454 
455 const a2dSignal a2dDrawingPart::sig_changedLayers = wxNewId();
456 const a2dSignal a2dDrawingPart::sig_changedLayerAvailable = wxNewId();
457 const a2dSignal a2dDrawingPart::sig_changedLayerVisibleInView = wxNewId();
458 const a2dSignal a2dDrawingPart::sig_changedShowObject = wxNewId();
459 
461 {
462  Update();
463 }
464 
465 IMPLEMENT_DYNAMIC_CLASS( a2dDrawingPart, a2dObject )
466 
467 BEGIN_EVENT_TABLE( a2dDrawingPart, a2dObject )
468  EVT_ENTER_WINDOW( a2dDrawingPart::OnEnter )
469  EVT_IDLE( a2dDrawingPart::OnIdle )
470  EVT_MOUSE_EVENTS( a2dDrawingPart::OnMouseEvent )
471  EVT_CHAR( a2dDrawingPart::OnCharEvent )
472  EVT_UPDATE_DRAWING( a2dDrawingPart::OnUpdate )
473  EVT_COM_EVENT( a2dDrawingPart::OnComEvent )
474  //EVT_CLOSE_VIEW( a2dDrawingPart::OnCloseView )
475 #ifdef _DEBUG
476  EVT_DO( a2dDrawingPart::OnDoEvent )
477  EVT_UNDO( a2dDrawingPart::OnUndoEvent )
478  EVT_REDO( a2dDrawingPart::OnRedoEvent )
479 #endif // _DEBUG
481  EVT_ENDBUSY( a2dDrawingPart::OnBusyEnd )
482  EVT_SET_FOCUS( a2dDrawingPart::OnSetFocus )
483  EVT_KILL_FOCUS( a2dDrawingPart::OnKillFocus )
484 END_EVENT_TABLE()
485 
486 a2dDrawingPart::a2dDrawingPart( const wxSize& size ):
487 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG)
488  m_initCurrentSmartPointerOwner( this ),
489 #endif
490  m_tiles( ( size.GetWidth() >> a2d_TILESHIFT ) + 1 , ( size.GetHeight() >> a2d_TILESHIFT ) + 1 ),
491  m_tiles2( ( size.GetWidth() >> a2d_TILESHIFT ) + 1 , ( size.GetHeight() >> a2d_TILESHIFT ) + 1 )
492 {
493  m_width = size.GetWidth();
494  m_height = size.GetHeight();
495 
496  m_drawer2D = new a2dMemDcDrawer( m_width, m_height );
497 
498  Init();
499 }
500 
501 a2dDrawingPart::a2dDrawingPart( int width, int height ):
502 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG)
503  m_initCurrentSmartPointerOwner( this ),
504 #endif
505  m_tiles( ( width >> a2d_TILESHIFT ) + 1 , ( height >> a2d_TILESHIFT ) + 1 ),
506  m_tiles2( ( width >> a2d_TILESHIFT ) + 1 , ( height >> a2d_TILESHIFT ) + 1 )
507 {
508  m_width = width;
509  m_height = height;
510 
511  m_drawer2D = new a2dMemDcDrawer( m_width, m_height );
512 
513  Init();
514 }
515 
516 a2dDrawingPart::a2dDrawingPart( int width, int height, a2dDrawer2D* drawer ):
517 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG)
518  m_initCurrentSmartPointerOwner( this ),
519 #endif
520  m_tiles( ( width >> a2d_TILESHIFT ) + 1 , ( height >> a2d_TILESHIFT ) + 1 ),
521  m_tiles2( ( width >> a2d_TILESHIFT ) + 1 , ( height >> a2d_TILESHIFT ) + 1 )
522 {
523  m_width = width;
524  m_height = height;
525 
526  m_drawer2D = drawer;
527  m_drawer2D->DestroyClippingRegion();
528 
529  Init();
530 }
531 
533 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG)
534  m_initCurrentSmartPointerOwner( this ),
535 #endif
536  m_tiles( ( drawer->GetWidth() >> a2d_TILESHIFT ) + 1 , ( drawer->GetHeight() >> a2d_TILESHIFT ) + 1 ),
537  m_tiles2( ( drawer->GetWidth() >> a2d_TILESHIFT ) + 1 , ( drawer->GetHeight() >> a2d_TILESHIFT ) + 1 )
538 {
539  m_drawer2D = drawer;
540  m_width = drawer->GetWidth();
541  m_height = drawer->GetHeight();
542 
543  Init();
544 }
545 
546 void a2dDrawingPart::Init()
547 {
548  a2dHabitat* habitat = a2dCanvasGlobals->GetHabitat();
549 
550  m_hitmargin = habitat->GetHitMarginDevice();
551  m_documentDrawStyle = habitat->GetDrawStyle() | habitat->GetSelectDrawStyle();
552  m_selectFill = habitat->GetSelectFill();
553  m_selectStroke = habitat->GetSelectStroke();
554  m_select2Fill = habitat->GetSelect2Fill();
555  m_select2Stroke = habitat->GetSelect2Stroke();
556  m_reverse_order = habitat->GetReverseOrder();
557 
558  m_toolWantsIt = false;
559  // wxLogDebug( "(a2dDrawingPart*)0x%p", this );
560  m_layerRenderArray.resize( wxMAXLAYER );
561 
563 
564  m_recur = false;
565  m_drawingDisplay = NULL;
566  //we want all layers to be rendered and selected objects.
573 
574  if ( m_drawer2D && m_drawer2D->HasAlpha() )
575  {
576  m_highLightStroke = a2dStroke( wxColor( 0, 255, 255, 255 ), 2 );
577  m_highLightFill = a2dFill( wxColor( 255, 122, 0, 165 ) );
578  }
579  else
580  {
581  m_highLightStroke = a2dStroke( wxColor( 0, 255, 255 ), 2 );
583  }
584 
585  if ( m_drawer2D )
586  {
587  m_drawer2D->SetDisplay( m_drawingDisplay );
588  }
589 
590  m_toolcontroller = 0; //needed
591 
592  //mouse events handled by canvas itself
593  m_mouseevents = true;
594 
595  m_top = 0;
596  m_border = 0;
597 
598  m_frozen = false;
599 
600  m_virtualarea_set = false;
601 
602  m_gridatfront = false;
603  m_gridx = 100;
604  m_gridy = 100;
605  m_gridlines = false;
606  m_gridthres = 5;
607  m_gridsize = 0;
608  m_grid = false;
609 
610  m_showorigin = true;
611 
615 
616  m_capture = ( a2dCanvasObject* )NULL;
618 
619  m_crosshairStroke = a2dStroke( wxColour( 200, 30, 30 ), 0, a2dSTROKE_DOT );
620  m_crosshair = false;
621  m_crosshairx = 0;
622  m_crosshairy = 0;
623  m_crosshairLengthX = CROSS_HAIR_X;
624  m_crosshairLengthY = CROSS_HAIR_Y;
625  m_mouse_x = m_mouse_y = 0;
626 
627  m_printtitle = true;
628  m_printfilename = true;
629  m_printscalelimit = 0;
630  m_printframe = true;
631  m_printfittopage = false;
632 
633  m_viewDependentObjects = false;
634 #if defined(_DEBUG)
635  m_updatesVisible = false;
636 #endif
637 }
638 
640 {
641  if ( GetDrawing() && GetDrawing()->GetCanvasCommandProcessor() &&
644 
645  //prevent event handling from now one ( else problem from event distribution can happen ).
646  //Unregister is done in a2dView.
647  SetEvtHandlerEnabled( false );
649 
650  m_drawingDisplay = NULL; //is used to test inside controllers.
651  m_top = NULL;
652  m_toolcontroller = 0;
653 
654  if ( m_drawer2D )
655  delete m_drawer2D;
656 }
657 
658 a2dDrawingPart::a2dDrawingPart( const a2dDrawingPart& other )
659 : a2dObject( other, a2dObject::clone_deep, NULL ),
660  m_tiles( ( other.m_width >> a2d_TILESHIFT ) + 1 , ( other.m_height >> a2d_TILESHIFT ) + 1 ),
661  m_tiles2( ( other.m_width >> a2d_TILESHIFT ) + 1 , ( other.m_height >> a2d_TILESHIFT ) + 1 )
662 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG)
663  , m_initCurrentSmartPointerOwner( this )
664 #endif
665 {
666  m_drawer2D = NULL;
667 
668  Init();
669 
671 
673 
674  m_gridstroke = other.m_gridstroke;
675 
676  m_gridfill = other.m_gridfill;
677 
678  m_fixFill = other.m_fixFill;
679  m_fixStroke = other.m_fixStroke;
680 
683 
684  m_selectFill = other.m_selectFill;
688 
689  m_gridx = other.m_gridx;
690  m_gridy = other.m_gridy;
691  m_gridlines = other.m_gridlines;
692  m_gridsize = other.m_gridsize;
693  m_gridthres = other.m_gridthres;
694 
695  m_showorigin = other.m_showorigin;
696 
697  m_grid = other.m_grid;
698 
699  m_top = other.m_top;
700 
702  m_crosshair = other.m_crosshair;
703  m_crosshairx = other.m_crosshairx;
704  m_crosshairy = other.m_crosshairy;
707 
708  m_printtitle = other.m_printtitle;
711  m_printframe = other.m_printframe;
713 
716 
717 }
718 
719 #if wxUSE_PRINTING_ARCHITECTURE
720 wxPrintout* a2dDrawingPart::OnCreatePrintout( a2dPrintWhat typeOfPrint, const wxPageSetupDialogData& pageSetupData )
721 {
722  return new a2dDrawingPrintOut( pageSetupData, this, m_printtitle ? GetDrawing()->GetDescription() : ( const wxString& )wxEmptyString, "", typeOfPrint, false, false, false );
723 }
724 #endif
725 
727 {
728  if ( m_top )
729  return m_top->GetRoot();
730  return NULL;
731 }
732 
733 void a2dDrawingPart::SetReverseOrder( bool revorder )
734 {
735  m_reverse_order = revorder;
737 }
738 
740 {
741  assert( m_drawer2D );
742  return m_drawer2D->DeviceToWorldXRel( m_hitmargin );
743 }
744 
745 void a2dDrawingPart::SetDisplayWindow( wxWindow* display )
746 {
747  m_drawingDisplay = display;
748  if ( m_drawingDisplay )
749  m_drawingDisplay->SetDropTarget( new a2dDnDCanvasObjectDropTarget( this ));
750 
751  if ( m_drawer2D )
752  m_drawer2D->SetDisplay( display );
753 }
754 
755 void a2dDrawingPart::SetBufferSize( int w, int h )
756 {
757  m_width = w;
758  m_height = h;
759  m_tiles.SetSize( ( w >> a2d_TILESHIFT ) + 1, ( h >> a2d_TILESHIFT ) + 1 );
760  m_tiles2.SetSize( ( w >> a2d_TILESHIFT ) + 1, ( h >> a2d_TILESHIFT ) + 1 );
761  if ( m_drawer2D )
762  m_drawer2D->SetBufferSize( w, h );
763 }
764 
765 void a2dDrawingPart::SetDrawer2D( a2dDrawer2D* drawer2d, bool noDelete )
766 {
767  if ( noDelete != true )
768  {
769  if ( m_drawer2D )
770  delete m_drawer2D;
771  }
772  m_drawer2D = drawer2d;
773  if ( m_drawer2D )
774  {
775  m_drawer2D->SetDisplay( m_drawingDisplay );
776  m_width = m_drawer2D->GetWidth();
777  m_height = m_drawer2D->GetHeight();
778  // klion: we change m_width and m_height, so we must change m_tiles
779  m_tiles.SetSize( ( m_width >> a2d_TILESHIFT ) + 1, ( m_height >> a2d_TILESHIFT ) + 1 );
780  m_tiles2.SetSize( ( m_width >> a2d_TILESHIFT ) + 1, ( m_height >> a2d_TILESHIFT ) + 1 );
781  }
782 }
783 
784 
786 {
787  a2dToolContr* returnc = m_toolcontroller;
788 
789  if ( m_toolcontroller ) //remove the old one
790  {
791  wxASSERT_MSG( m_toolcontroller->GetDrawingPart() == this, wxT( "a2dToolContr has different a2dDrawingPart set for it" ) );
793  }
794 
795  if ( controller ) //set the new one
796  {
797  wxASSERT_MSG( controller->GetDrawingPart() == this, wxT( "a2dToolContr has different a2dDrawingPart set for it" ) );
798  }
799  m_toolcontroller = controller;
800  return returnc != 0;
801 }
802 
803 bool a2dDrawingPart::ProcessEvent( wxEvent& event )
804 {
805  bool processed = false;
806 
807  // An event handler can be enabled or disabled
808  if ( GetEvtHandlerEnabled() )
809  {
810  //prevent the object from being deleted until this process event is at an end
812 
813  if ( event.GetEventType() == wxEVT_IDLE )
814  {
815  if ( m_top && m_top->GetRoot() )
816  processed = m_top->GetRoot()->ProcessEvent( event );
817 
818  event.Skip();
819  processed = a2dObject::ProcessEvent( event );
820  if ( m_toolcontroller )
821  {
822  event.Skip(); //skipped because not processed so prepare for controller
823  processed = m_toolcontroller->ProcessEvent( event );
824  }
825  }
826  else if ( m_toolcontroller && event.GetEventType() == wxEVT_PAINT )
827  {
828  if ( m_drawingDisplay )
829  {
830  SetEvtHandlerEnabled( false ); //this event coming back from the display will not be handled
831  event.ResumePropagation( wxEVENT_PROPAGATE_MAX );
832  m_drawingDisplay->GetEventHandler()->ProcessEvent( event );
833  event.StopPropagation();
834  SetEvtHandlerEnabled( true );
835  }
836  processed = a2dObject::ProcessEvent( event );
837  if ( !processed || m_toolWantsIt )
838  {
839  event.Skip(); //skipped because not processed so prepare for controller
840  processed = m_toolcontroller->ProcessEvent( event );
841  m_toolWantsIt = false;
842  }
843  }
844  else if ( m_toolcontroller && event.GetEventType() == a2dEVT_COM_EVENT )
845  {
846  // communication event of changes in state, should always continue
847  processed = m_toolcontroller->ProcessEvent( event );
848  event.Skip(); //skipped because not processed so prepare for view
849  processed = a2dObject::ProcessEvent( event );
850  }
851  else if ( m_toolcontroller && event.GetEventType() == wxEVT_CHAR )
852  {
853  processed = m_toolcontroller->ProcessEvent( event );
854  if ( !processed || m_toolWantsIt )
855  {
856  event.Skip(); //skipped because not processed so prepare for view
857  processed = a2dObject::ProcessEvent( event );
858  m_toolWantsIt = false;
859  }
860  }
861  else if ( m_toolcontroller && event.GetEventType() == wxEVT_KEY_DOWN )
862  {
863  processed = m_toolcontroller->ProcessEvent( event );
864  if ( !processed || m_toolWantsIt )
865  {
866  event.Skip(); //skipped because not processed so prepare for view
867  processed = a2dObject::ProcessEvent( event );
868  m_toolWantsIt = false;
869  }
870  }
871  else if ( m_toolcontroller && event.GetEventType() == wxEVT_KEY_UP )
872  {
873  processed = m_toolcontroller->ProcessEvent( event );
874  if ( !processed || m_toolWantsIt )
875  {
876  event.Skip(); //skipped because not processed so prepare for view
877  processed = a2dObject::ProcessEvent( event );
878  m_toolWantsIt = false;
879  }
880  }
881  else if ( m_toolcontroller )
882  {
883  processed = m_toolcontroller->ProcessEvent( event );
884  if ( !processed || m_toolWantsIt )
885  {
886  event.Skip(); //skipped because not processed so prepare for view
887  processed = a2dObject::ProcessEvent( event );
888  m_toolWantsIt = false;
889  }
890  }
891  else
892  {
893  processed = a2dObject::ProcessEvent( event );
894  }
895 
896  return processed;
897  }
898 
899  return false;
900 }
901 
902 void a2dDrawingPart::OnEnter( wxMouseEvent& event )
903 {
904 
905  //if ( GetDisplayWindow() )
906  //GetDisplayWindow()->SetFocus();
907 
908  event.Skip();
909 }
910 
911 void a2dDrawingPart::OnIdle( wxIdleEvent& event )
912 {
913  //wxLogDebug( "void a2dDrawingPart::OnIdle(wxIdleEvent &event)" );
914 
915  if ( m_frozen )
916  {
917  event.Skip(); //to the display of the drawer.
918  return;
919  }
920 
922  {
924  }
925 
926  AddOverlayAreas( false );
927 
928  // only redraw the areas which are currently in the updatelist,
929  // waiting to be redrawn. After they are redrawn, directly blit those areas
930  // to the window ( if available ).
931  if ( m_tiles.HasFilledTiles() || m_tiles2.HasFilledTiles() || m_updateareas.GetCount() )
932  {
933  // Although pending areas most often result from pending object in the first place,
934  // in some cases pending area are added directly and not via pending objects.
935  // In those cases it is possible that there are pendingobjects in the document which do not have their
936  // boundingbox yet calculated. e.g. SetMappingShowAll() followed by adding new objects in the code.
937  // This idle event is first always sent to the document, so this should not be solved by arriving there first.
938  //Therefore if the GetCanvasDocument() has still pending objects wait until those have bin added too.
939 
940  //But better save then sorry!
941  if ( GetDrawing() && !GetDrawing()->GetUpdatesPending() )
943  }
944 
945  event.Skip(); //to the display of this view.
946 }
947 
948 void a2dDrawingPart::AddOverlayAreas( bool update )
949 {
950  if ( m_overlayObjects.size() )
951  {
952  a2dCanvasObjectList::iterator iter = m_overlayObjects.begin();
953  for( iter = m_overlayObjects.begin(); iter != m_overlayObjects.end(); ++iter )
954  {
955  a2dCanvasObjectList::value_type obj = *iter;
956  if ( obj->GetPending() )
957  {
958  AddPendingUpdateArea( obj, 1 );
959  obj->Update( a2dCanvasObject::updatemask_normal );
960  AddPendingUpdateArea( obj, 1 );
961  obj->SetPending( false );
962  }
963  }
964  }
965 
966  if ( update && m_tiles2.HasFilledTiles() )
967  {
969  }
970 
971 }
972 
974 {
975  obj->SetRoot( GetDrawing(), false );
976  m_overlayObjects.push_back( obj );
977 }
978 
980 {
981  a2dCanvasObjectList::iterator iter = m_overlayObjects.begin();
982  for( iter = m_overlayObjects.begin(); iter != m_overlayObjects.end(); ++iter )
983  {
984  a2dCanvasObjectList::value_type iobj = *iter;
985  if ( iobj == obj || obj == NULL )
986  {
987  AddPendingUpdateArea( obj, 1 );
988  m_overlayObjects.erase( iter );
989  break;
990  }
991  }
992 }
993 
994 void a2dDrawingPart::OnSetFocus( wxFocusEvent& focusevent )
995 {
996  //wxLogDebug( "focus %p", this );
997 
998  if ( GetDrawing() )
999  {
1001  }
1002  focusevent.Skip();
1003 }
1004 
1005 void a2dDrawingPart::OnKillFocus( wxFocusEvent& focusevent )
1006 {
1007  //wxLogDebug( "off focus %p", this );
1008  if ( GetDrawing() && GetDrawing()->GetCanvasCommandProcessor() )
1009  {
1010  // keep this one active until some other becomes active. (e.g. Dialog uses this a2dDrawingPart, while not InFocus)
1011  //GetDrawing()->GetCanvasCommandProcessor()->SetActiveDrawingPart( NULL );
1012  }
1013  focusevent.Skip();
1014 }
1015 
1016 void a2dDrawingPart::SetDocumentDrawStyle( wxUint32 documentDrawStyle )
1017 {
1019 }
1020 
1021 void a2dDrawingPart::SetOverlayDrawStyle( a2dDocumentRenderStyle drawstyle )
1022 {
1023  m_overlayDrawStyle = drawstyle;
1024 }
1025 
1027 {
1028  m_frozen = true;
1029 }
1030 
1031 void a2dDrawingPart::Thaw( bool update )
1032 {
1033  m_frozen = false;
1034 
1035  if ( update )
1036  {
1038  }
1039 }
1040 
1042 {
1043  m_endCorridorObject = endCorridorObject;
1044 }
1045 
1046 void a2dDrawingPart::SetCursor( const wxCursor& cursor )
1047 {
1048  if ( m_drawingDisplay )
1049  m_drawingDisplay->SetCursor( cursor );
1050 }
1051 
1052 void a2dDrawingPart::PushCursor( const wxCursor& cursor )
1053 {
1054  m_cursorStack.push_back( cursor );
1055  if ( m_drawingDisplay )
1056  m_drawingDisplay->SetCursor( cursor );
1057 }
1058 
1060 {
1061  if ( m_cursorStack.size() )
1062  {
1063  m_cursorStack.pop_back();
1064  if ( m_drawingDisplay )
1065  {
1066  if ( m_cursorStack.size() )
1067  m_drawingDisplay->SetCursor( m_cursorStack.back() );
1068  else
1069  m_drawingDisplay->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW ) );
1070  }
1071  }
1072 }
1073 
1075 {
1076  m_cursorStack.clear();
1077  if ( m_drawingDisplay )
1078  m_drawingDisplay->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW ) );
1079 }
1080 
1082 {
1083  m_mouseevents = onoff;
1084 }
1085 
1086 void a2dDrawingPart::SetCrossHairStroke( const a2dStroke& crosshairStroke )
1087 {
1088  m_crosshairStroke = crosshairStroke;
1089 };
1090 
1092 {
1093  m_crosshair = onoff;
1095 }
1096 
1097 void a2dDrawingPart::MouseToToolWorld( int x, int y, double& xWorldLocal, double& yWorldLocal )
1098 {
1099  if ( wxDynamicCast( GetDisplayWindow(), a2dCanvas ) )
1100  {
1101  //a2dCanvas is aligned with view its buffer origin
1102  }
1103  else if ( wxDynamicCast( GetDisplayWindow(), a2dCanvasSim ) )
1104  {
1105  //a2dCanvasSim its virtual origin is aligned with view its buffer origin
1106  a2dCanvasSim* can = wxStaticCast( GetDisplayWindow(), a2dCanvasSim );
1107  can->CalcUnscrolledPosition( x, y, &x , &y );
1108  }
1109 
1110  xWorldLocal = GetDrawer2D()->DeviceToWorldX( x );
1111  yWorldLocal = GetDrawer2D()->DeviceToWorldY( y );
1112 }
1113 
1114 void a2dDrawingPart::ToolWorldToMouse( double xWorld, double yWorld, int& x, int& y )
1115 {
1116  x = GetDrawer2D()->WorldToDeviceX( xWorld );
1117  y = GetDrawer2D()->WorldToDeviceY( yWorld );
1118 
1119  if ( wxDynamicCast( GetDisplayWindow(), a2dCanvas ) )
1120  {
1121  //a2dCanvas is aligned with view its buffer origin
1122  }
1123  else if ( wxDynamicCast( GetDisplayWindow(), a2dCanvasSim ) )
1124  {
1125  //a2dCanvasSim its virtual origin is aligned with view its buffer origin
1126  a2dCanvasSim* can = wxStaticCast( GetDisplayWindow(), a2dCanvasSim );
1127  can->CalcScrolledPosition( x, y, &x , &y );
1128  }
1129 }
1130 
1131 void a2dDrawingPart::OnMouseEvent( wxMouseEvent& event )
1132 {
1133  m_mouse_x = event.GetX();
1134  m_mouse_y = event.GetY();
1135 
1136  UpdateCrossHair( m_mouse_x, m_mouse_y );
1137 
1138  if ( !GetDrawing() || !m_mouseevents )
1139  {
1140  event.Skip();
1141  return;
1142  }
1143 
1144  //to world coordinates to do hit test in world coordinates
1145  double xw = m_drawer2D->DeviceToWorldX( m_mouse_x );
1146  double yw = m_drawer2D->DeviceToWorldY( m_mouse_y );
1147 
1148  if ( m_capture && !GetDrawing()->GetRootObject()->Find( m_capture ) )
1149  m_capture = ( a2dCanvasObject* ) NULL;
1150 
1151  a2dIterC ic( this );
1153  cworld.Invert();
1154  a2dIterCU cu( ic, cworld );
1155  ic.SetPerLayerMode( false );
1156  ic.SetLayer( wxLAYER_ALL );
1157  a2dHitEvent hitinfo( xw, yw );
1158  hitinfo.m_event = &event;
1159  if ( GetShowObject()->ProcessCanvasObjectEvent( ic, hitinfo ) )
1160  return;
1161  event.Skip(); //windows containing view may handle it
1162 
1163  return;
1164 }
1165 
1166 /*
1167 void a2dDrawingPart::OnMouseEvent( wxMouseEvent& event )
1168 {
1169  m_mouse_x = event.GetX();
1170  m_mouse_y = event.GetY();
1171 
1172  UpdateCrossHair( m_mouse_x, m_mouse_y );
1173 
1174  if ( !GetDrawing() || !m_mouseevents )
1175  {
1176  event.Skip();
1177  return;
1178  }
1179 
1180  //to world coordinates to do hit test in world coordinates
1181  double xw = m_drawer2D->DeviceToWorldX( m_mouse_x );
1182  double yw = m_drawer2D->DeviceToWorldY( m_mouse_y );
1183 
1184  if ( m_capture && !GetDrawing()->GetRootObject()->Find( m_capture ) )
1185  m_capture = ( a2dCanvasObject* ) NULL;
1186 
1187  a2dIterC ic( this );
1188  a2dAffineMatrix cworld = GetShowObject()->GetTransformMatrix();
1189  cworld.Invert();
1190  a2dIterCU cu( ic, cworld );
1191  ic.SetLayer( wxLAYER_ALL );
1192  ic.SetPerLayerMode( false );
1193  //ic.SetObjectFilter( new a2dCanvasObjectFilterLayerMask( wxLAYER_ALL, a2dCanvasOFlags::VISIBLE | a2dCanvasOFlags::SELECTABLE ) );
1194 
1195  a2dHitEvent hitinfo( xw, yw, false );
1196  hitinfo.m_event = &event;
1197  //at the top level the group its matrix is to be ignored.
1198  //Since it is normally NOT ignored within a2dCanvasObject, force an inverse.
1199  hitinfo.m_xyRelToChildren = false;
1200 
1201  a2dCanvasObject* res = NULL;
1202 
1203  bool processed = false;
1204  res = GetShowObject()->ChildIsHitWorld( ic, hitinfo, true );
1205 
1206  m_patToHitPrev = m_patToHitCur;
1207  m_patToHitCur = ic.m_contextList;
1208 
1209  //wxLogDebug( "sizeo %d ", m_patToHitPrev.size() );
1210  //wxLogDebug( "sizen %d ", m_patToHitCur.size() );
1211  {
1212  a2dIterC icpp( this );
1213  a2dAffineMatrix cworld = GetShowObject()->GetTransformMatrix();
1214  cworld.Invert();
1215  a2dIterCU cu( icpp, cworld );
1216  ic.SetPerLayerMode( false );
1217 
1218  for( a2dSmrtPtrList< a2dIterPP >::iterator iter = m_patToHitCur.begin(); iter != m_patToHitCur.end(); iter++ )
1219  {
1220  a2dIterPP* pp = *iter;
1221  a2dCanvasObject* obj = pp->GetObject();
1222 
1223  if ( obj )
1224  {
1225  a2dIterCU cu( icpp, obj );
1226 
1227  bool found = false;
1228  for( a2dSmrtPtrList< a2dIterPP >::iterator iterp = m_patToHitPrev.begin(); iterp != m_patToHitPrev.end(); iterp++ )
1229  {
1230  a2dIterPP* pp = *iterp;
1231  a2dCanvasObject* objp = pp->GetObject();
1232  if ( obj == objp )
1233  found = true;
1234  //obj->ProcessEvent( ic, hitinfo );
1235  }
1236  if ( !found && obj )
1237  {
1238  //wxLogDebug( "PPenter %p ", obj );
1239  a2dCanvasObjectMouseEvent enter( &ic, obj, wxEVT_CANVASOBJECT_ENTER_EVENT, xw, yw, event );
1240  obj->ProcessEvent( enter );
1241  }
1242  }
1243  }
1244 
1245  for( a2dSmrtPtrList< a2dIterPP >::reverse_iterator iter = m_patToHitCur.rbegin(); iter != m_patToHitCur.rend(); iter++ )
1246  {
1247  a2dIterPP* pp = *iter;
1248  a2dCanvasObject* obj = pp->GetObject();
1249 
1250  if ( obj )
1251  {
1252  a2dIterCU cu( icpp, obj );
1253  wxMouseEvent* mouse = wxDynamicCast( &event, wxMouseEvent );
1254  if ( mouse )
1255  {
1256  a2dHit how;
1257  a2dCanvasObjectMouseEvent CanvasObjectMouseEvent( &ic, obj, how, xw, yw, *mouse );
1258  processed = obj->ProcessEvent( CanvasObjectMouseEvent );
1259  }
1260  else
1261  processed = obj->ProcessEvent( event );
1262  }
1263  }
1264 
1265  for( a2dSmrtPtrList< a2dIterPP >::iterator iter = m_patToHitPrev.begin(); iter != m_patToHitPrev.end(); iter++ )
1266  {
1267  a2dIterPP* pp = *iter;
1268  a2dCanvasObject* obj = pp->GetObject();
1269 
1270  if ( obj )
1271  {
1272  a2dIterCU cu( icpp, obj );
1273 
1274  bool found = false;
1275  for( a2dSmrtPtrList< a2dIterPP >::iterator iterp = m_patToHitCur.begin(); iterp != m_patToHitCur.end(); iterp++ )
1276  {
1277  a2dIterPP* pp = *iterp;
1278  a2dCanvasObject* objp = pp->GetObject();
1279  if ( obj == objp )
1280  found = true;
1281  }
1282  if ( !found && obj )
1283  {
1284  //wxLogDebug( "PPleaf %p ", obj );
1285  a2dCanvasObjectMouseEvent leave( &ic, obj, wxEVT_CANVASOBJECT_LEAVE_EVENT, xw, yw, event );
1286  obj->ProcessEvent( leave );
1287  }
1288  }
1289  }
1290  }
1291  if ( !processed )
1292  event.Skip(); //windows containing view may handle it
1293 
1294 }
1295 */
1296 void a2dDrawingPart::OnCharEvent( wxKeyEvent& event )
1297 {
1298  if ( m_capture )
1299  m_capture->ProcessEvent( event );
1300  else
1301  event.Skip(); // to base class, but also a2dCanvas and tools.
1302 }
1303 
1304 bool a2dDrawingPart::ProcessCanvasObjectEvent( wxEvent& event, bool& isHit,
1305  double x, double y, int margin,
1306  int layer )
1307 {
1308 
1309  a2dIterC ict( this );
1310  ict.SetHitMarginDevice( margin );
1311  ict.SetPerLayerMode( false );
1312  ict.SetLayer( wxLAYER_ALL );
1314  tcworld.Invert();
1315  //rotateable view experiment
1316  //cworld.Rotate( -30 );
1317  a2dIterCU cut( ict, tcworld );
1318 
1320  a2dHitEvent hitinfot( x, y );
1321  hitinfot.m_event = &event;
1322  bool res = GetShowObject()->ProcessCanvasObjectEvent( ict, hitinfot );
1323  isHit = hitinfot.m_isHit;
1325  return res;
1326 
1327 
1328  if ( !GetDrawing() )
1329  {
1330  event.Skip();
1331  return false;
1332  }
1333 
1334  //to world coordinates to do hit test in world coordinates
1335  double xw = x;
1336  double yw = y;
1337 
1338  a2dIterC ic( this );
1339  ic.SetHitMarginDevice( margin );
1341  cworld.Invert();
1342  a2dIterCU cu( ic, cworld );
1343  ic.SetLayer( wxLAYER_ALL );
1344  //ic.SetPerLayerMode( false );
1345  //ic.SetObjectFilter( new a2dCanvasObjectFilterLayerMask( wxLAYER_ALL, a2dCanvasOFlags::VISIBLE | a2dCanvasOFlags::SELECTABLE ) );
1346 
1347  a2dHitEvent hitinfo( xw, yw, false );
1348  hitinfo.m_event = &event;
1349  //at the top level the group its matrix is to be ignored.
1350  //Since it is normally NOT ignored within a2dCanvasObject, force an inverse.
1351  //hitinfo.m_xyRelToChildren = false;
1352 
1353  a2dCanvasObject* reso = NULL;
1354 
1355  bool processed = false;
1356  reso = GetShowObject()->ChildIsHitWorld( ic, hitinfo, true );
1357 
1358  if ( reso )
1359  reso = GetShowObject()->ChildIsHitWorld( ic, hitinfo, true );
1360 
1361  m_patToHitPrev = m_patToHitCur;
1362  m_patToHitCur = ic.m_contextListDeep;
1363 
1364  //wxLogDebug( "sizeo %d ", m_patToHitPrev.size() );
1365  //wxLogDebug( "sizen %d ", m_patToHitCur.size() );
1366  {
1367  a2dIterC icpp( this );
1369  cworld.Invert();
1370  a2dIterCU cu( icpp, cworld );
1371  ic.SetPerLayerMode( false );
1372 
1373  for( a2dSmrtPtrList< a2dIterPP >::iterator iter = m_patToHitCur.begin(); iter != m_patToHitCur.end(); iter++ )
1374  {
1375  a2dIterPP* pp = *iter;
1376  a2dCanvasObject* obj = pp->GetObject();
1377 
1378  if ( obj )
1379  {
1380  icpp.Push( obj, pp->m_clip );
1381 
1382  bool found = false;
1383  for( a2dSmrtPtrList< a2dIterPP >::iterator iterp = m_patToHitPrev.begin(); iterp != m_patToHitPrev.end(); iterp++ )
1384  {
1385  a2dIterPP* pp = *iterp;
1386  a2dCanvasObject* objp = pp->GetObject();
1387  if ( obj == objp )
1388  found = true;
1389  //obj->ProcessEvent( ic, hitinfo );
1390  }
1391  if ( !found && obj )
1392  {
1393  //wxLogDebug( "PPenter %p ", obj );
1394  wxMouseEvent* mouse = wxDynamicCast( &event, wxMouseEvent );
1395  if ( mouse )
1396  {
1397  a2dCanvasObjectMouseEvent enter( &icpp, obj, wxEVT_CANVASOBJECT_ENTER_EVENT, xw, yw, *mouse );
1398  obj->ProcessEvent( enter );
1399  }
1400  }
1401  }
1402  else
1403  icpp.Push( pp->GetLocalTransform(), pp->m_clip );
1404  }
1405 
1406 
1407  a2dSmrtPtrList< a2dIterPP >::reverse_iterator riter = m_patToHitCur.rbegin();
1408  while ( riter != m_patToHitCur.rend() && !processed )
1409  {
1410  a2dIterPP* ppr = *riter;
1411  a2dCanvasObject* receive = ppr->GetObject();
1412 
1413  a2dIterC icpp2( this );
1414  icpp2.SetPerLayerMode( false );
1415 
1416  for( a2dSmrtPtrList< a2dIterPP >::iterator iter = m_patToHitCur.begin(); iter != m_patToHitCur.end(); iter++ )
1417  {
1418  a2dIterPP* pp = *iter;
1419  a2dCanvasObject* obj = pp->GetObject();
1420 
1421  if ( obj )
1422  {
1423  if ( obj == receive )
1424  {
1425  wxMouseEvent* mouse = wxDynamicCast( &event, wxMouseEvent );
1426  if ( mouse )
1427  {
1428  a2dHit how;
1429  a2dCanvasObjectMouseEvent CanvasObjectMouseEvent( &icpp2, obj, how, xw, yw, *mouse );
1430  processed = obj->ProcessEvent( CanvasObjectMouseEvent );
1431  if ( processed )
1432  break;
1433  }
1434  else
1435  {
1436  processed = obj->ProcessEvent( event );
1437  if ( processed )
1438  break;
1439  }
1440  }
1441  icpp2.Push( obj, pp->m_clip );
1442  }
1443  else
1444  icpp2.Push( pp->GetLocalTransform(), pp->m_clip );
1445  }
1446  riter++;
1447  }
1448 
1449 
1450  a2dIterC icpp3( this );
1451  icpp3.SetPerLayerMode( false );
1452 
1453  for( a2dSmrtPtrList< a2dIterPP >::iterator iter = m_patToHitPrev.begin(); iter != m_patToHitPrev.end(); iter++ )
1454  {
1455  a2dIterPP* pp = *iter;
1456  a2dCanvasObject* obj = pp->GetObject();
1457 
1458  if ( obj )
1459  {
1460  icpp3.Push( obj, pp->m_clip );
1461 
1462  bool found = false;
1463  for( a2dSmrtPtrList< a2dIterPP >::iterator iterp = m_patToHitCur.begin(); iterp != m_patToHitCur.end(); iterp++ )
1464  {
1465  a2dIterPP* pp = *iterp;
1466  a2dCanvasObject* objp = pp->GetObject();
1467  if ( obj == objp )
1468  found = true;
1469  }
1470  if ( !found && obj )
1471  {
1472  //wxLogDebug( "PPleaf %p ", obj );
1473  wxMouseEvent* mouse = wxDynamicCast( &event, wxMouseEvent );
1474  if ( mouse )
1475  {
1476  a2dCanvasObjectMouseEvent leave( &icpp3, obj, wxEVT_CANVASOBJECT_LEAVE_EVENT, xw, yw, *mouse );
1477  obj->ProcessEvent( leave );
1478  }
1479  }
1480  }
1481  else
1482  icpp3.Push( pp->GetLocalTransform(), pp->m_clip );
1483  }
1484  }
1485  if ( !processed )
1486  event.Skip(); //windows containing view may handle it
1487 
1488  return processed;
1489 }
1490 
1492  double x, double y, int margin,
1493  int layer )
1494 {
1495  a2dIterC ic( this );
1496  ic.SetHitMarginDevice( margin );
1497  ic.SetPerLayerMode( false );
1498  ic.SetLayer( layer );
1500  cworld.Invert();
1501  //rotateable view experiment
1502  //cworld.Rotate( -30 );
1503  a2dIterCU cu( ic, cworld );
1504 
1505  event.SetIterC( &ic );
1506 
1508  a2dHitEvent hitinfo( x, y );
1509  hitinfo.m_event = &event;
1510  bool res = GetShowObject()->ProcessCanvasObjectEvent( ic, hitinfo );
1511  isHit = hitinfo.m_isHit;
1513  return res;
1514 }
1515 
1517 {
1518  a2dWalker_FindAndSetCorridorPath findcorridor( findObject );
1519  findcorridor.SetSkipNotRenderedInDrawing( true );
1520  findcorridor.Start( GetShowObject() );
1521 
1522  if( findcorridor.GetResult() )
1523  {
1524  SetEndCorridorObject( findObject );
1525  if( capture )
1526  {
1527  SetCaptured( findObject );
1528  }
1529  return true;
1530  }
1531  return false;
1532 }
1533 
1535 {
1536  ClearCorridorPath( true );
1537  a2dCanvasObjectList::const_iterator iter = corridor.begin();
1538  while( iter != corridor.end() )
1539  {
1540  a2dCanvasObjectList::value_type obj = *iter;
1541  obj->SetIsOnCorridorPath( true );
1542  iter++;
1543  }
1544  if ( !corridor.empty() )
1545  SetEndCorridorObject( corridor.back() );
1546  SetCaptured( corridor.GetCaptured() );
1547 }
1548 
1550 {
1551  if( uncapture )
1552  {
1553  SetCaptured( NULL );
1554  }
1555  SetEndCorridorObject( NULL );
1556 
1557  if ( GetShowObject() )
1558  {
1560  setflags.SetSkipNotRenderedInDrawing( true );
1561  setflags.Start( GetShowObject(), false );
1562  }
1563 }
1564 
1566  double x, double y,
1567  int layer,
1568  a2dHitOption option,
1569  bool filterSelectableLayers
1570 )
1571 {
1573  a2dIterC ic( this );
1574  ic.SetPerLayerMode( false );
1575  ic.SetLayer( layer );
1577 
1578  //rotateable view experiment
1579  a2dAffineMatrix cworld;
1580  //cworld.Rotate( -30 );
1581  a2dIterCU cu( ic, cworld );
1582 
1583  a2dHitEvent hitinfo( x, y );
1584  hitinfo.m_option = option;
1585  //at the top level the group its matrix is to be ignored.
1586  //Since it is normally NOT ignored within a2dCanvasObject, force an inverse.
1587  hitinfo.m_xyRelToChildren = false;
1588 
1589  a2dCanvasObject* res = GetShowObject()->ChildIsHitWorld( ic, hitinfo, filterSelectableLayers );
1590  return res;
1591 }
1592 
1594  double x, double y,
1595  int layer,
1596  a2dHitOption option,
1597  bool filterSelectableLayers
1598 )
1599 {
1601  a2dIterC ic( this );
1602  ic.SetPerLayerMode( false );
1603  ic.SetLayer( layer );
1605 
1606  //rotateable view experiment
1607  a2dAffineMatrix cworld;
1608  //cworld.Rotate( -30 );
1609  a2dIterCU cu( ic, cworld );
1610 
1611  a2dHitEvent hitinfo( x, y, false, a2dCANOBJHITOPTION_NONE, true );
1612  hitinfo.m_option = option;
1613  //at the top level the group its matrix is to be ignored.
1614  //Since it is normally NOT ignored within a2dCanvasObject, force an inverse.
1615  hitinfo.m_xyRelToChildren = false;
1616 
1617  a2dCanvasObject* res = GetShowObject()->ChildIsHitWorld( ic, hitinfo, filterSelectableLayers );
1618  m_patToHitCur = m_patToHitPrev;
1619  m_patToHitCur = ic.m_contextList;
1620  return res;
1621 }
1622 
1624  a2dHitEvent& hitEvent,
1625  int layer
1626 )
1627 {
1629  a2dIterC ic( this );
1630  ic.SetLayer( layer );
1631  a2dCanvasObject* res = GetShowObject()->ChildIsHitWorld( ic, hitEvent );
1632  return res;
1633 }
1634 
1635 void a2dDrawingPart::SetLayerCheck( wxUint16 layer )
1636 {
1637  m_layerRenderArray[ layer ].SetCheck( true );
1638  Set_UpdateAvailableLayers( true ); //see OnIdle
1639 }
1640 
1642 {
1643  unsigned int j;
1644  for ( j = 0; j < wxMAXLAYER; j++ )
1645  {
1646  m_layerRenderArray[j].SetCheck( false );
1647  m_layerRenderArray[j].SetAvailable( false );
1648  }
1649  if ( m_top )
1650  {
1651  a2dWalker_SetAvailable set( this );
1652  set.SetSkipNotRenderedInDrawing( true );
1653  set.Start( m_top );
1654  }
1655  //this one always available because editing handles are on it.
1656  m_layerRenderArray[wxLAYER_DEFAULT].SetAvailable( true );
1657  Set_UpdateAvailableLayers( false );
1658 }
1659 
1660 /*
1661 void a2dDrawingPart::OnCloseView( a2dCloseViewEvent& event )
1662 {
1663  //when a view is closed, and a controller, and its tools or still active,
1664  //they need to be terminated and removed.
1665 
1666  if ( m_toolcontroller.Get() )
1667  m_toolcontroller->Disable();
1668  m_toolcontroller = 0;
1669  event.Skip();
1670 }
1671 */
1672 
1674 {
1675  if ( GetEvtHandlerEnabled() )
1676  {
1677  if ( event.GetId() == sig_changedLayers )
1678  {
1679  Set_UpdateAvailableLayers( true );
1680  }
1681  else if ( event.GetId() == a2dDrawing::sig_changedLayer )
1682  {
1683  a2dDrawing* drawing = wxDynamicCast( event.GetEventObject(), a2dDrawing );
1684 
1685  if ( drawing == GetDrawing() )
1686  {
1687  a2dNamedProperty* property = event.GetProperty();
1688  if ( property->GetUint16() != wxLAYER_ALL )
1689  {
1690  m_layerRenderArray[property->GetUint16()].SetCheck( true );
1691  //m_layerRenderArray[property->GetUint16()].SetAvailable( true );
1692  }
1693  else
1694  Set_UpdateAvailableLayers( true );
1695  }
1696  }
1697  else if ( event.GetId() == a2dDrawing::sig_layersetupChanged )
1698  {
1699  a2dDrawing* drawing = wxDynamicCast( event.GetEventObject(), a2dDrawing );
1700  if ( drawing == GetDrawing() )
1702  //Set_UpdateAvailableLayers(true);
1703  }
1704  else if ( event.GetId() == a2dLayerInfo::sig_changedLayerInfo )
1705  {
1706  a2dCanvasObject* obj = wxDynamicCast( event.GetEventObject(), a2dCanvasObject );
1707  if ( m_top == obj->GetRoot()->GetRootObject() )
1709  }
1710  else
1711  event.Skip();
1712  }
1713  else
1714  event.Skip();
1715 }
1716 
1717 #ifdef _DEBUG
1718 void a2dDrawingPart::OnDoEvent( a2dCommandProcessorEvent& event )
1719 {
1720  event.Skip();
1721 }
1722 
1723 void a2dDrawingPart::OnRedoEvent( a2dCommandProcessorEvent& event )
1724 {
1725  event.Skip();
1726 }
1727 
1728 void a2dDrawingPart::OnUndoEvent( a2dCommandProcessorEvent& event )
1729 {
1730  event.Skip();
1731 }
1732 #endif // _DEBUG
1733 
1735 {
1736  PushCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_WAIT ) );
1737 }
1738 
1740 {
1741  PopCursor();
1742 }
1743 
1744 void a2dDrawingPart::Update( unsigned int how, wxObject* hintObject )
1745 {
1746  if ( !m_top || !GetDrawing() )
1747  return;
1748 
1749  a2dDrawingEvent event( how, GetDrawing() );
1750  ProcessEvent( event );
1751 }
1752 
1754 {
1755  //wxLogDebug( _T( "update in view: %p with m_top %p" ), this, m_top );
1756 
1757  if ( !m_top )
1758  return;
1759 
1760  wxASSERT_MSG( m_top->GetRoot(), wxT( "showobject without root set" ) );
1761 
1762  if ( !m_top || m_top->GetRoot() != event.GetDrawing() )
1763  return;
1764 
1765  if ( !GetEvtHandlerEnabled() )
1766  return;
1767 
1769 
1770  if ( event.GetUpdateHint() != 0 )
1771  how = event.GetUpdateHint();
1772 
1773  //order of actions is important!
1774 
1775  if ( how & a2dCANVIEW_UPDATE_PENDING &&
1777  )
1778  {
1779  wxUint16 j;
1780  for ( j = 0; j < wxMAXLAYER; j++ )
1781  m_layerRenderArray[j].SetObjectCount( 0 );
1782 
1783  AddObjectPendingUpdates( how );
1784 
1785  for ( j = 0; j < wxMAXLAYER; j++ )
1786  {
1787  wxUint16 count = m_layerRenderArray[j].GetObjectCount();
1788  m_layerRenderArray[j].SetPreviousObjectCount( count );
1789  }
1790  }
1791 
1792  if ( how & a2dCANVIEW_UPDATE_PENDING &&
1794  )
1795  {
1796  wxUint16 j;
1797  for ( j = 0; j < wxMAXLAYER; j++ )
1798  m_layerRenderArray[j].SetObjectCount( 0 );
1799  AddObjectPendingUpdates( how );
1800  for ( j = 0; j < wxMAXLAYER; j++ )
1801  m_layerRenderArray[j].SetAvailable( m_layerRenderArray[j].GetObjectCount() != 0 );
1802  for ( j = 0; j < wxMAXLAYER; j++ )
1803  {
1804  //check if first object put on a layer or last removed from a layer
1805  if ( ( m_layerRenderArray[j].GetPreviousObjectCount() != 0 && m_layerRenderArray[j].GetObjectCount() == 0 ) ||
1806  ( m_layerRenderArray[j].GetPreviousObjectCount() == 0 && m_layerRenderArray[j].GetObjectCount() != 0 )
1807  )
1808  {
1809  a2dComEvent changedlayer( this, j, sig_changedLayerAvailable );
1810  ProcessEvent( changedlayer );
1811  }
1812  }
1813  }
1814 
1815  if ( how & a2dCANVIEW_UPDATE_VIEWDEPENDENT )
1816  {
1818  }
1819 
1820  if ( how & a2dCANVIEW_UPDATE_OLDNEW )
1821  {
1823  }
1824 
1825  if ( how & a2dCANVIEW_UPDATE_ALL )
1826  {
1827  SetAvailable();
1830  }
1831 
1832  if ( how & a2dCANVIEW_UPDATE_AREAS )
1833  {
1834  //redraw pending update areas into buffer
1836  }
1837 
1838  if ( how & a2dCANVIEW_UPDATE_AREAS_NOBLIT )
1839  {
1840  //redraw pending update areas into buffer
1841  RedrawPendingUpdateAreas( true );
1842  }
1843 
1844  if ( how & a2dCANVIEW_UPDATE_BLIT )
1845  {
1846  if ( GetCanvas() && GetCanvas()->IsShown() )
1848  else
1849  // if there is something in the buffer to blit to the windows which is not visible,
1850  // they can be skipped.
1851  m_updateareas.clear();
1852  }
1853 }
1854 
1856 {
1857  wxASSERT_MSG( m_recur == false, wxT( "recursive calls in updating not allowed" ) );
1858  m_recur = true;
1859 
1860  m_tiles.Clear();
1861  m_tiles2.Clear();
1862 
1863  //all pending updates become redundant, make the list empty
1864  a2dUpdateList::compatibility_iterator nodeb = m_updateareas.GetFirst();
1865  while ( nodeb )
1866  {
1867  a2dUpdateArea* uobj = nodeb->GetData();
1868  delete uobj;
1869  m_updateareas.DeleteNode( nodeb );
1870  nodeb = m_updateareas.GetFirst();
1871  }
1872 
1873  m_recur = false;
1874 }
1875 
1877 {
1878  if ( m_frozen ) return;
1879 
1880  if ( m_recur ) return;
1881  wxASSERT_MSG( m_recur == false, wxT( "recursive calls in updating not allowed" ) );
1882 
1883  m_recur = true;
1884 
1886  m_tiles.Clear();
1887  m_tiles2.GenerateUpdateRectangles( &m_updateareas, 1 );
1888  m_tiles2.Clear();
1889 
1890  a2dUpdateList::compatibility_iterator nodeb = m_updateareas.GetFirst();
1891  while ( nodeb )
1892  {
1893  a2dUpdateArea* uobj = nodeb->GetData();
1894 
1895  if ( !uobj->m_update_done )
1896  {
1897  //update a little more then is strictly needed,
1898  //to get rid of the 1 bit bugs
1899  //SEE wxRect a2dCanvasObject::GetAbsoluteArea( const a2dAffineMatrix& cworld )
1900 
1901  int x, y, width, height;
1902  uobj->Inflate( 2 );
1903  x = uobj->x;
1904  y = uobj->y;
1905  width = uobj->width;
1906  height = uobj->height;
1907 
1908 
1909  UpdateArea( x, y, width, height, uobj->m_id );
1910 
1911  //update is done Blitting needs to be done
1912  uobj->m_update_done = true;
1913 
1914  if ( noblit )
1915  {
1916  //we can delete this rect
1917  delete uobj;
1918  a2dUpdateList::compatibility_iterator nodeh = nodeb;
1919  nodeb = nodeb->GetNext();
1920  m_updateareas.DeleteNode( nodeh );
1921  }
1922  else
1923  nodeb = nodeb->GetNext();
1924  }
1925  else
1926  nodeb = nodeb->GetNext();
1927  }
1928 
1929  m_recur = false;
1930 }
1931 
1933 {
1934  //if there are blits we need a refresh for tools and/or controls
1935  bool refresh = false;
1936 
1937  if ( !GetDrawing() || m_frozen || !m_updateareas.GetFirst() )
1938  return refresh;
1939 
1940  wxASSERT_MSG( m_recur == false, wxT( "recursive calls in updating not allowed" ) );
1941  m_recur = true;
1942 
1943  //first find out if there will be blit, to prevent expensive call if there are not
1944  //areas to blit
1945  a2dUpdateList::compatibility_iterator node = m_updateareas.GetFirst();
1946  while ( node )
1947  {
1948  a2dUpdateArea* rect = node->GetData();
1949 
1950  if ( rect->m_update_done )
1951  refresh = true;
1952  node = node->GetNext();
1953  }
1954 
1955  if ( refresh )
1956  {
1957  m_drawer2D->BeginDraw();
1958 
1959  a2dUpdateList::compatibility_iterator node = m_updateareas.GetFirst();
1960  while ( node )
1961  {
1962  a2dUpdateArea* rect = node->GetData();
1963 
1964  if ( rect->m_update_done )
1965  {
1966  m_drawer2D->BlitBuffer( *rect, wxPoint( m_drawer2D->GetMapX(), m_drawer2D->GetMapY() ) );
1967 
1968  if ( m_drawingDisplay && m_drawingDisplay->GetChildren().GetCount() )
1969  {
1970  m_drawingDisplay->Refresh( false, rect );
1971  }
1972 
1973  //we can delete this rect
1974  delete rect;
1975  a2dUpdateList::compatibility_iterator nodeh = node;
1976  node = node->GetNext();
1977  m_updateareas.DeleteNode( nodeh );
1978  }
1979  else
1980  node = node->GetNext();
1981  }
1982 
1983  if ( refresh )
1984  {
1985  //place for code which needs to refresh objects which are drawn on top of the buffer bitmap
1986  // for example wxWindows derived controls.
1987  }
1988 
1990 
1991  m_drawer2D->EndDraw();
1992  }
1993 
1994  m_recur = false;
1995 
1996  return refresh;
1997 }
1998 
1999 void a2dDrawingPart::UpdateArea( int x, int y, int width, int height, wxUint8 id )
2000 {
2001  if ( !GetDrawing() )
2002  {
2003  wxASSERT_MSG( GetDrawing() != 0, wxT( "invalid a2dDrawing in a2dDrawingPart" ) );
2004  return;
2005  }
2006 
2007  // clip to buffer
2008  if ( x < 0 )
2009  {
2010  width += x;
2011  x = 0;
2012  }
2013  if ( width <= 0 ) return;
2014 
2015  if ( y < 0 )
2016  {
2017  height += y;
2018  y = 0;
2019  }
2020  if ( height <= 0 ) return;
2021 
2022  if ( x + width > m_width )
2023  {
2024  width = m_width - x;
2025  }
2026  if ( width <= 0 ) return;
2027 
2028  if ( y + height > m_height )
2029  {
2030  height = m_height - y;
2031  }
2032  if ( height <= 0 ) return;
2033 
2034  m_drawer2D->SetDrawStyle( a2dFILLED );
2035  m_drawer2D->BeginDraw();
2036 
2037  //wxLogDebug("update x=%d, y=%d w=%d h=%d", x, y, width, height );
2038 
2039  //This to make all rendering only work on this area
2040  //when using Dc's
2041  //We do not do it inside the rendering routines since
2042  //setting the clippingregion for every object is expensive
2043  //and not usefull in case of DC's where clipping is already
2044  //part of API drawing routines.
2045  //Still the canvasobject is checked for intersection with the update region
2046  //This to prevent drawing objects that are not within
2047  //the update region. Which would be useless.
2048  //Calculalation of boundingboxes etc. for all object is seperate from the rendering stage.
2049  m_drawer2D->SetClippingRegionDev( x, y, width, height );
2050 
2051  bool ignore = GetDrawing()->GetIgnorePendingObjects();
2052 
2053  if ( !ignore )
2055 
2056  PaintBackground( x, y, width, height );
2057 
2058  if ( m_grid && !m_gridatfront )
2059  PaintGrid( x, y, width, height );
2060 
2061  m_drawer2D->SetDrawerFill( *a2dTRANSPARENT_FILL );
2062  m_drawer2D->SetDrawerStroke( *a2dTRANSPARENT_STROKE );
2063 
2066 
2067  //tools always render on top of everything else, excepts the grid.
2068  if ( m_toolcontroller )
2070 
2071  if ( m_grid && m_gridatfront )
2072  PaintGrid( x, y, width, height );
2073 
2074  m_drawer2D->DestroyClippingRegion();
2075  DrawOrigin();
2076 
2077  if ( !ignore )
2078  GetDrawing()->SetIgnorePendingObjects( false );
2079 
2080 // debuggy
2081  /*
2082  if ( m_drawingDisplay )
2083  {
2084  m_drawer2D->PushIdentityTransform();
2085  m_drawer2D->SetDrawerFill( *a2dTRANSPARENT_FILL );
2086  m_drawer2D->SetDrawerStroke( *a2dBLACK_STROKE );
2087  m_drawer2D->DrawRoundedRectangle(x, y, width, height,0);
2088  m_drawer2D->PopTransform();
2089  }
2090  */
2091 
2092  m_drawer2D->EndDraw();
2093 
2094  /*
2095  if ( m_drawingDisplay && m_drawingDisplay->GetChildren().GetCount() )
2096  {
2097  wxRect rect = wxRect(x, y, width, height);
2098  m_drawingDisplay->Refresh( false, &rect );
2099  }
2100  */
2101 
2102 }
2103 
2104 void a2dDrawingPart::ClearArea( int x, int y, int width, int height )
2105 {
2106  if ( !GetDrawing() )
2107  {
2108  wxASSERT_MSG( GetDrawing() != 0, wxT( "invalid a2dDrawing in a2dDrawingPart" ) );
2109  return;
2110  }
2111 
2112  // clip to buffer
2113  if ( x < 0 )
2114  {
2115  width += x;
2116  x = 0;
2117  }
2118  if ( width <= 0 ) return;
2119 
2120  if ( y < 0 )
2121  {
2122  height += y;
2123  y = 0;
2124  }
2125  if ( height <= 0 ) return;
2126 
2127  if ( x + width > m_width )
2128  {
2129  width = m_width - x;
2130  }
2131  if ( width <= 0 ) return;
2132 
2133  if ( y + height > m_height )
2134  {
2135  height = m_height - y;
2136  }
2137  if ( height <= 0 ) return;
2138 
2139  m_drawer2D->SetDrawStyle( a2dFILLED );
2140  m_drawer2D->BeginDraw();
2141 
2142  m_drawer2D->SetClippingRegionDev( x, y, width, height );
2143 
2144  PaintBackground( x, y, width, height );
2145  if ( m_grid )
2146  PaintGrid( x, y, width, height );
2147 
2148  m_drawer2D->DestroyClippingRegion();
2149  DrawOrigin();
2150 
2151  m_drawer2D->EndDraw();
2152 }
2153 
2154 void a2dDrawingPart::BlitBuffer( int x, int y, int width, int height, int xbuf, int ybuf )
2155 {
2156  if ( !GetDrawing() )
2157  {
2158  //wxASSERT_MSG( GetDrawing() != 0, wxT( "invalid a2dDrawing in a2dDrawingPart" ) );
2159  return;
2160  }
2161 
2162  // clip to buffer
2163  if ( x < 0 )
2164  {
2165  width += x;
2166  x = 0;
2167  }
2168  if ( width <= 0 ) return;
2169 
2170  if ( y < 0 )
2171  {
2172  height += y;
2173  y = 0;
2174  }
2175  if ( height <= 0 ) return;
2176 
2177  if ( x + width > m_width )
2178  {
2179  width = m_width - x;
2180  }
2181  if ( width <= 0 ) return;
2182 
2183  if ( y + height > m_height )
2184  {
2185  height = m_height - y;
2186  }
2187  if ( height <= 0 ) return;
2188 
2189  m_drawer2D->SetDrawStyle( a2dFILLED );
2190  m_drawer2D->BeginDraw();
2191 
2192  m_drawer2D->BlitBuffer( x, y, width, height , xbuf, ybuf );
2193 
2194  m_drawer2D->EndDraw();
2195 }
2196 
2197 
2198 void a2dDrawingPart::RenderChildObject( a2dCanvasObject* obj )
2199 {
2200  if ( !GetDrawing() )
2201  {
2202  wxASSERT_MSG( GetDrawing() != 0, wxT( "invalid a2dDrawing in a2dDrawingPart" ) );
2203  return;
2204  }
2205 
2206  int x, y, width, height;
2207 
2208  if ( obj && obj->GetRoot()->GetRootObject() == m_top )
2209  {
2210  a2dIterC ic( this );
2211  a2dIterCU cu( ic, a2dIDENTITY_MATRIX );
2212  wxRect absarea = obj->GetAbsoluteArea( ic );
2213  x = absarea.GetX();
2214  y = absarea.GetY();
2215  width = absarea.GetWidth();
2216  height = absarea.GetHeight();
2217  }
2218 
2219  // clip to buffer
2220  if ( x < 0 )
2221  {
2222  width += x;
2223  x = 0;
2224  }
2225  if ( width <= 0 ) return;
2226 
2227  if ( y < 0 )
2228  {
2229  height += y;
2230  y = 0;
2231  }
2232  if ( height <= 0 ) return;
2233 
2234  if ( x + width > m_width )
2235  {
2236  width = m_width - x;
2237  }
2238  if ( width <= 0 ) return;
2239 
2240  if ( y + height > m_height )
2241  {
2242  height = m_height - y;
2243  }
2244  if ( height <= 0 ) return;
2245 
2246  m_drawer2D->SetDrawStyle( a2dFILLED );
2247  m_drawer2D->BeginDraw();
2248 
2249  m_drawer2D->SetClippingRegionDev( x, y, width, height );
2250 
2251  PaintBackground( x, y, width, height );
2252  if ( m_grid )
2253  PaintGrid( x, y, width, height );
2254 
2255  a2dIterC ic( this );
2256  ic.SetDisableInvert( true );
2257  ic.SetDrawStyle( RenderWIREFRAME_HighLight );
2258 
2259  //at the top level the group its matrix is to be ignored.
2260  //Since it is normally NOT ignored within a2dCanvasObject, do an inverse first here.
2262  cworld.Invert();
2263 
2264  a2dBoundingBox absarea = m_top->GetMappedBbox( cworld );
2265  OVERLAP clipparent = m_drawer2D->GetClippingBox().Intersect( absarea );
2266  if ( clipparent != _OUT )
2267  {
2268  ic.SetPerLayerMode( false );
2269  m_drawer2D->SetDisableDrawing( true );
2270  ic.SetLayer( wxLAYER_ALL );
2271  a2dIterCU cu( ic, cworld );
2272  obj->Render( ic, clipparent );
2273  m_drawer2D->SetDisableDrawing( false );
2274 
2275  ic.Reset();
2276  }
2277 
2278  m_drawer2D->DestroyClippingRegion();
2279  DrawOrigin();
2280 
2281  m_drawer2D->BlitBuffer( x, y, width, height , m_drawer2D->GetMapX(), m_drawer2D->GetMapY() );
2282 
2283  m_drawer2D->EndDraw();
2284 }
2285 
2286 
2287 
2289 {
2290  if ( ! m_viewDependentObjects )
2291  return;
2292 
2293  a2dDrawing* drawing = GetDrawing();
2294  if( drawing )
2295  {
2296  if( !m_top )
2297  return;
2298  a2dIterC ic( this );
2300  cworld.Invert();
2301  a2dIterCU cu( ic, cworld );
2303  }
2304 }
2305 
2306 void a2dDrawingPart::RenderTopObject( wxUint32 documentDrawStyle, wxUint8 id )
2307 {
2308  if ( documentDrawStyle & RenderLAYERED_All )
2309  {
2310  m_drawer2D->SetDrawStyle( a2dFILLED );
2311  RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderLAYERED_All );
2312  }
2313  if ( documentDrawStyle & RenderLAYERED )
2314  {
2315  m_drawer2D->SetDrawStyle( a2dFILLED );
2316  RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderLAYERED );
2317  }
2318  if ( documentDrawStyle & RenderWIREFRAME )
2319  {
2320  m_drawer2D->SetDrawStyle( a2dWIREFRAME );
2321  RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderWIREFRAME );
2322  }
2323  if ( documentDrawStyle & RenderWIREFRAME_ZERO_WIDTH )
2324  {
2325  m_drawer2D->SetDrawStyle( a2dWIREFRAME_ZERO_WIDTH );
2326  RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderWIREFRAME_ZERO_WIDTH );
2327  }
2328  if ( documentDrawStyle & RenderWIREFRAME_INVERT )
2329  {
2330  m_drawer2D->SetDrawStyle( a2dWIREFRAME_INVERT );
2331  RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderWIREFRAME_INVERT );
2332  }
2333  if ( documentDrawStyle & RenderWIREFRAME_INVERT_ZERO_WIDTH )
2334  {
2336  RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderWIREFRAME_INVERT_ZERO_WIDTH );
2337  }
2338  if ( documentDrawStyle & RenderFIX_STYLE )
2339  {
2340  m_drawer2D->SetDrawerFill( m_fixFill );
2341  m_drawer2D->SetDrawerStroke( m_fixStroke );
2342  m_drawer2D->SetDrawStyle( a2dFIX_STYLE );
2343  RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderFIX_STYLE );
2344  m_drawer2D->ResetFixedStyle();
2345  }
2346  if ( documentDrawStyle & RenderRectangles )
2347  {
2348  m_drawer2D->SetDrawerFill( m_fixFill );
2349  m_drawer2D->SetDrawerStroke( m_fixStroke );
2350  m_drawer2D->SetDrawStyle( a2dFIX_STYLE );
2351  RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderRectangles );
2352  m_drawer2D->ResetFixedStyle();
2353  }
2354 
2355  if ( documentDrawStyle & RenderWIREFRAME_HighLight )
2356  {
2357  m_drawer2D->SetDrawerFill( m_highLightFill );
2358  m_drawer2D->SetDrawerStroke( m_highLightStroke );
2359  m_drawer2D->SetDrawStyle( a2dFIX_STYLE );
2360  RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderWIREFRAME_HighLight );
2361  m_drawer2D->ResetFixedStyle();
2362  }
2363 
2364  if ( documentDrawStyle & RenderTOOL_OBJECTS )
2365  {
2366  //we want the object that is being edited, on top of all others, but before selection
2367  m_drawer2D->SetDrawerFill( m_fixFill );
2368  m_drawer2D->SetDrawerStroke( m_fixStroke );
2369  m_drawer2D->SetDrawStyle( a2dFIX_STYLE );
2370  RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderTOOL_OBJECTS );
2371  m_drawer2D->ResetFixedStyle();
2372  }
2373 
2374  if ( documentDrawStyle & RenderTOOL_OBJECTS_STYLED )
2375  {
2376  m_drawer2D->SetDrawStyle( a2dFILLED );
2377  RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderTOOL_OBJECTS_STYLED );
2378  }
2379 
2380  if ( documentDrawStyle & RenderRectangleTOOL_OBJECTS )
2381  {
2382  m_drawer2D->SetDrawerFill( m_fixFill );
2383  m_drawer2D->SetDrawerStroke( m_fixStroke );
2384  m_drawer2D->SetDrawStyle( a2dFIX_STYLE );
2385  RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderRectangleTOOL_OBJECTS );
2386  m_drawer2D->ResetFixedStyle();
2387  }
2388 
2389  if ( documentDrawStyle & RenderTOOL_DECORATIONS )
2390  {
2391  m_drawer2D->SetDrawStyle( a2dFILLED );
2392  RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderTOOL_DECORATIONS );
2393  }
2394 
2395  //we want the objects that are selected, in a select color, on top of all others, that is done next.
2396  if ( documentDrawStyle & RenderWIREFRAME_SELECT )
2397  {
2398  m_drawer2D->SetDrawerFill( m_selectFill );
2399  m_drawer2D->SetDrawerStroke( m_selectStroke );
2400  m_drawer2D->SetDrawStyle( a2dFIX_STYLE );
2401  RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderWIREFRAME_SELECT );
2402  m_drawer2D->ResetFixedStyle();
2403  }
2404  if ( documentDrawStyle & RenderWIREFRAME_SELECT_INVERT )
2405  {
2406  m_drawer2D->SetDrawerFill( m_selectFill );
2407  m_drawer2D->SetDrawerStroke( m_selectStroke );
2408  m_drawer2D->SetDrawStyle( a2dFIX_STYLE_INVERT );
2409  RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderWIREFRAME_SELECT_INVERT );
2410  m_drawer2D->ResetFixedStyle();
2411  }
2412  if ( documentDrawStyle & RenderWIREFRAME_SELECT2 )
2413  {
2414  m_drawer2D->SetDrawerFill( m_select2Fill );
2415  m_drawer2D->SetDrawerStroke( m_select2Stroke );
2416  m_drawer2D->SetDrawStyle( a2dFIX_STYLE );
2417  RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderWIREFRAME_SELECT2 );
2418  m_drawer2D->ResetFixedStyle();
2419  }
2420 
2421  m_drawer2D->SetDrawStyle( a2dFILLED );
2422 }
2423 
2425 {
2426  if ( m_overlayObjects.empty() )
2427  return;
2428 
2429  if ( documentDrawStyle & RenderLAYERED )
2430  {
2431  m_drawer2D->SetDrawStyle( a2dFILLED );
2432  }
2433  if ( documentDrawStyle & RenderWIREFRAME )
2434  {
2435  m_drawer2D->SetDrawStyle( a2dWIREFRAME );
2436  }
2437  if ( documentDrawStyle & RenderWIREFRAME_ZERO_WIDTH )
2438  {
2439  m_drawer2D->SetDrawStyle( a2dWIREFRAME_ZERO_WIDTH );
2440  }
2441  if ( documentDrawStyle & RenderWIREFRAME_INVERT )
2442  {
2443  m_drawer2D->SetDrawStyle( a2dWIREFRAME_INVERT );
2444  }
2445  if ( documentDrawStyle & RenderWIREFRAME_INVERT_ZERO_WIDTH )
2446  {
2448  }
2449  if ( documentDrawStyle & RenderFIX_STYLE )
2450  {
2451  m_drawer2D->SetDrawerFill( m_fixFill );
2452  m_drawer2D->SetDrawerStroke( m_fixStroke );
2453  m_drawer2D->SetDrawStyle( a2dFIX_STYLE );
2454  }
2455  if ( documentDrawStyle & RenderRectangles )
2456  {
2457  m_drawer2D->SetDrawerFill( m_fixFill );
2458  m_drawer2D->SetDrawerStroke( m_fixStroke );
2459  m_drawer2D->SetDrawStyle( a2dFIX_STYLE );
2460  }
2461 
2462  if ( documentDrawStyle & RenderWIREFRAME_HighLight )
2463  {
2464  m_drawer2D->SetDrawerFill( m_highLightFill );
2465  m_drawer2D->SetDrawerStroke( m_highLightStroke );
2466  //m_drawer2D->SetDrawerFill( a2dFill( wxColour( 66, 159, 25, 50 ) ) );
2467  //m_drawer2D->SetDrawerStroke( a2dStroke( wxColour( 66, 59, 235, 165 ), 2, a2dSTROKE_LONG_DASH) );
2468  m_drawer2D->SetDrawStyle( a2dFIX_STYLE );
2469  }
2470 
2471  if ( documentDrawStyle & RenderTOOL_OBJECTS )
2472  {
2473  //we want the object that is being edited, on top of all others, but before selection
2474  m_drawer2D->SetDrawerFill( m_fixFill );
2475  m_drawer2D->SetDrawerStroke( m_fixStroke );
2476  m_drawer2D->SetDrawStyle( a2dFIX_STYLE );
2477  }
2478 
2479  if ( documentDrawStyle & RenderTOOL_OBJECTS_STYLED )
2480  {
2481  m_drawer2D->SetDrawStyle( a2dFILLED );
2482  }
2483 
2484  if ( documentDrawStyle & RenderRectangleTOOL_OBJECTS )
2485  {
2486  m_drawer2D->SetDrawerFill( m_fixFill );
2487  m_drawer2D->SetDrawerStroke( m_fixStroke );
2488  m_drawer2D->SetDrawStyle( a2dFIX_STYLE );
2489  }
2490 
2491  if ( documentDrawStyle & RenderTOOL_DECORATIONS )
2492  {
2493  m_drawer2D->SetDrawStyle( a2dFILLED );
2494  }
2495 
2496  //we want the objects that are selected, in a select color, on top of all others, that is done next.
2497  if ( documentDrawStyle & RenderWIREFRAME_SELECT )
2498  {
2499  m_drawer2D->SetDrawerFill( m_selectFill );
2500  m_drawer2D->SetDrawerStroke( m_selectStroke );
2501  m_drawer2D->SetDrawStyle( a2dFIX_STYLE );
2502  }
2503  if ( documentDrawStyle & RenderWIREFRAME_SELECT_INVERT )
2504  {
2505  m_drawer2D->SetDrawerFill( m_selectFill );
2506  m_drawer2D->SetDrawerStroke( m_selectStroke );
2507  m_drawer2D->SetDrawStyle( a2dFIX_STYLE_INVERT );
2508  }
2509 
2510  if ( documentDrawStyle & RenderWIREFRAME_SELECT2 )
2511  {
2512  m_drawer2D->SetDrawerFill( m_select2Fill );
2513  m_drawer2D->SetDrawerStroke( m_select2Stroke );
2514  m_drawer2D->SetDrawStyle( a2dFIX_STYLE );
2515  }
2516 
2518  cworld.Invert();
2519 
2520  // DO NOT clip to bbox m_top, since new objects not part of document can be outside it
2521  //a2dBoundingBox absarea = m_top->GetMappedBbox( cworld );
2522  //OVERLAP clipparent = m_drawer2D->GetClippingBox().Intersect( absarea );
2523  //if ( clipparent != _OUT || !m_top->GetChildObjectsCount() )
2524  OVERLAP clipparent = _IN;
2525  {
2526  a2dCanvasObjectList::iterator iter = m_overlayObjects.begin();
2527  for( iter = m_overlayObjects.begin(); iter != m_overlayObjects.end(); ++iter )
2528  {
2529  a2dCanvasObjectList::value_type obj = *iter;
2530  a2dIterC ic( this );
2531  ic.SetDisableInvert( true );
2532  ic.SetPerLayerMode( false );
2533  ic.SetLayer( wxLAYER_ALL );
2534  a2dIterCU cu( ic, cworld );
2535  obj->Render( ic, clipparent );
2536  m_drawer2D->ResetFixedStyle();
2537 
2538  ic.Reset();
2539  }
2540  }
2541 
2542  m_drawer2D->ResetFixedStyle();
2543 
2544  m_drawer2D->SetDrawStyle( a2dFILLED );
2545 }
2546 
2548 {
2549  if ( GetDrawing()->GetUpdatesPending() )
2550  GetDrawing()->AddPendingUpdatesOldNew(); //in general there are non, since the pending object are already updates before calling render
2551 
2552  a2dIterC ic( this );
2553  ic.SetDisableInvert( true );
2554  ic.SetDrawStyle( drawstyle );
2555 
2556  //at the top level the group its matrix is to be ignored.
2557  //Since it is normally NOT ignored within a2dCanvasObject, do an inverse first here.
2559  cworld.Invert();
2560  //rotateable view experiment
2561  //cworld.Rotate( -30 );
2562 
2563  a2dBoundingBox absarea = m_top->GetMappedBbox( cworld );
2564  OVERLAP clipparent = m_drawer2D->GetClippingBox().Intersect( absarea );
2565  if ( clipparent != _OUT )
2566  {
2567  if ( drawstyle == RenderLAYERED_All )
2568  {
2569  ic.SetPerLayerMode( false );
2570  wxUint16 layer = 0;
2571  if ( !GetDrawing()->GetLayerSetup() )
2572  {
2573  //wxLogDebug( "layer %d", layerobj->GetLayer() );
2574  m_drawer2D->ResetStyle();
2576  ic.SetLayer( layer );
2577 
2578  a2dIterCU cu( ic, cworld );
2579  m_top->Render( ic, clipparent );
2580 
2581  ic.Reset();
2582  }
2583  else
2584  {
2585  //wxLAYER_ALL is reserved and should never be part of the layersettings
2586  m_drawer2D->ResetStyle();
2587  ic.SetObjectFilter( new a2dCanvasObjectFilterLayerMaskNoToolNoEdit( wxLAYER_ALL, mask ) );
2588  ic.SetLayer( wxLAYER_ALL );
2589 
2590  a2dIterCU cu( ic, cworld );
2591  m_top->Render( ic, clipparent );
2592 
2593  ic.Reset();
2594  }
2595  }
2596  else if (
2597  drawstyle == RenderLAYERED ||
2598  drawstyle == RenderWIREFRAME ||
2599  drawstyle == RenderWIREFRAME_ZERO_WIDTH
2600  )
2601  {
2602  ic.SetPerLayerMode( true );
2603 
2604  if ( 0 ) //contextbased
2605  {
2606  unsigned int j;
2607  for ( j = 0; j < wxMAXLAYER; j++ )
2608  {
2609  a2dLayerInfo* layerobj;
2610  if ( m_reverse_order )
2611  layerobj = GetDrawing()->GetLayerSetup()->GetReverseOrderIndex()[j];
2612  else
2613  layerobj = GetDrawing()->GetLayerSetup()->GetOrderIndex()[j];
2614 
2615  // non defined layers, being those that where not in the layer setup, are sorted to the end of the indexes.
2616  // So the can be skipped.
2617  if ( layerobj == wxNullLayerInfo )
2618  break;
2619 
2620  //wxLogDebug( wxT("index %d layername %s, layer %d order %d"), j, layerobj->GetName(), layerobj->GetLayer(), layerobj->GetOrder() );
2621 
2622 
2623  //important!
2624  //if layer is visible it will be rendered
2625  //If an object on a layer is itself invisible it will not be drawn
2626  //wxLAYER_ALL is reserved and should never be part of the layersettings
2627  if ( m_layerRenderArray[ layerobj->GetLayer() ].DoRenderLayer() &&
2628  layerobj->GetVisible()
2629  )
2630  {
2631  //wxLogDebug( "layer %d", layerobj->GetLayer() );
2632  m_drawer2D->ResetStyle();
2634  ic.SetLayer( layerobj->GetLayer() );
2635 
2636  a2dIterCU cu( ic, cworld );
2637  a2dWalker_RenderLayers renderLay( ic );
2638  renderLay.SetSkipNotRenderedInDrawing( true );
2639  renderLay.Start( m_top );
2640 
2641  ic.Reset();
2642  }
2643 
2644  }
2645  }
2646  else
2647  {
2648  wxUint16 layer = 0;
2649  if ( !GetDrawing()->GetLayerSetup() )
2650  {
2651  //wxLogDebug( "layer %d", layerobj->GetLayer() );
2652  m_drawer2D->ResetStyle();
2654  ic.SetLayer( layer );
2655 
2656  a2dIterCU cu( ic, cworld );
2657  m_top->Render( ic, clipparent );
2658 
2659  ic.Reset();
2660  }
2661  else
2662  {
2663  unsigned int j;
2664  for ( j = 0; j < wxMAXLAYER; j++ )
2665  {
2666  a2dLayerInfo* layerobj;
2667  if ( m_reverse_order )
2668  layerobj = GetDrawing()->GetLayerSetup()->GetReverseOrderIndex()[j];
2669  else
2670  layerobj = GetDrawing()->GetLayerSetup()->GetOrderIndex()[j];
2671 
2672  // non defined layers, being those that where not in the layer setup, are sorted to the end of the indexes.
2673  // So the can be skipped.
2674  if ( layerobj == wxNullLayerInfo )
2675  break;
2676 
2677  //wxLogDebug( wxT("index %d layername %s, layer %d order %d"), j, layerobj->GetName(), layerobj->GetLayer(), layerobj->GetOrder() );
2678 
2679  layer = layerobj->GetLayer();
2680  //important!
2681  //if layer is visible it will be rendered
2682  //If an object on a layer is itself invisible it will not be drawn
2683  //wxLAYER_ALL is reserved and should never be part of the layersettings
2684  if ( m_layerRenderArray[ layer ].DoRenderLayer() &&
2685  layerobj->GetVisible()
2686  )
2687  {
2688  //wxLogDebug( "layer %d", layerobj->GetLayer() );
2689  m_drawer2D->ResetStyle();
2691  ic.SetLayer( layer );
2692 
2693  a2dIterCU cu( ic, cworld );
2694  m_top->Render( ic, clipparent );
2695 
2696  ic.Reset();
2697  }
2698  }
2699  }
2700  }
2701  }
2702  else if ( drawstyle == RenderWIREFRAME_HighLight )
2703  {
2704  ic.SetPerLayerMode( false );
2705  m_drawer2D->SetDisableDrawing( true );
2707  ic.SetLayer( wxLAYER_ALL );
2708  a2dIterCU cu( ic, cworld );
2709  m_top->Render( ic, clipparent );
2710  m_drawer2D->SetDisableDrawing( false );
2711 
2712  ic.Reset();
2713  /*
2714  ic.SetPerLayerMode( false );
2715 
2716  ic.SetObjectFilter( new a2dCanvasObjectFilterLayerMask( wxLAYER_ALL, mask ) );
2717  ic.SetLayer( wxLAYER_ALL );
2718  a2dIterCU cu( ic, cworld );
2719  top->Render( ic, clipparent );
2720  ic.Reset();
2721  */
2722  }
2723  else if ( drawstyle == RenderRectangles )
2724  {
2725  ic.SetPerLayerMode( false );
2726  a2dCanvasObjectList::iterator iter = m_top->GetChildObjectList()->begin();
2727  while( iter != m_top->GetChildObjectList()->end() )
2728  {
2729  a2dCanvasObject* obj = ( *iter );
2730  a2dIterCU cu( ic, cworld );
2731  a2dBoundingBox bbox = obj->GetBbox();
2732  if ( obj->CheckMask( mask ) )
2733  m_drawer2D->DrawRoundedRectangle( bbox.GetMinX(), bbox.GetMinY(), bbox.GetWidth(), bbox.GetHeight() , 0 );
2734  iter++;
2735  }
2736  }
2737  else if ( drawstyle == RenderRectangleTOOL_OBJECTS )
2738  {
2739  ic.SetPerLayerMode( false );
2740  a2dCanvasObjectList::iterator iter = m_top->GetChildObjectList()->begin();
2741  while( iter != m_top->GetChildObjectList()->end() )
2742  {
2743  a2dCanvasObject* obj = ( *iter );
2744  a2dIterCU cu( ic, cworld );
2745  a2dBoundingBox bbox = obj->GetBbox();
2746  if ( obj->CheckMask( mask ) && a2dCanvasObject::PROPID_ToolObject->GetPropertyValue( obj ) )
2747  m_drawer2D->DrawRoundedRectangle( bbox.GetMinX(), bbox.GetMinY(), bbox.GetWidth(), bbox.GetHeight() , 0 );
2748  iter++;
2749  }
2750  }
2751  else if ( drawstyle == RenderTOOL_OBJECTS ||
2752  drawstyle == RenderTOOL_OBJECTS_STYLED
2753  )
2754  {
2755  ic.SetPerLayerMode( false );
2756  m_drawer2D->SetDisableDrawing( true );
2758  ic.SetLayer( wxLAYER_ALL );
2759 
2760  a2dIterCU cu( ic, cworld );
2761  m_top->Render( ic, clipparent );
2762  m_drawer2D->SetDisableDrawing( false );
2763 
2764  ic.Reset();
2765  }
2766  else if ( drawstyle == RenderTOOL_DECORATIONS )
2767  {
2768  ic.SetPerLayerMode( false );
2769  m_drawer2D->SetDisableDrawing( true );
2771  ic.SetLayer( wxLAYER_ALL );
2772 
2773  a2dIterCU cu( ic, cworld );
2774  m_top->Render( ic, clipparent );
2775  m_drawer2D->SetDisableDrawing( false );
2776 
2777  ic.Reset();
2778  }
2779  else if ( drawstyle == RenderWIREFRAME_SELECT ||
2780  drawstyle == RenderWIREFRAME_SELECT_INVERT
2781  )
2782  {
2783  ic.SetPerLayerMode( false );
2784  m_drawer2D->SetDisableDrawing( true );
2786  ic.SetLayer( wxLAYER_ALL );
2787  a2dIterCU cu( ic, cworld );
2788  m_top->Render( ic, clipparent );
2789  m_drawer2D->SetDisableDrawing( false );
2790 
2791  ic.Reset();
2792  }
2793  else if ( drawstyle == RenderWIREFRAME_SELECT2 ||
2794  drawstyle == RenderWIREFRAME_SELECT_INVERT
2795  )
2796  {
2797  ic.SetPerLayerMode( false );
2798  m_drawer2D->SetDisableDrawing( true );
2800  ic.SetLayer( wxLAYER_ALL );
2801  a2dIterCU cu( ic, cworld );
2802  m_top->Render( ic, clipparent );
2803  m_drawer2D->SetDisableDrawing( false );
2804 
2805  ic.Reset();
2806  }
2807  else
2808  {
2809  ic.SetPerLayerMode( false );
2810  m_drawer2D->SetDisableDrawing( true );
2812  ic.SetLayer( wxLAYER_ALL );
2813  a2dIterCU cu( ic, cworld );
2814  m_top->Render( ic, clipparent );
2815  m_drawer2D->SetDisableDrawing( false );
2816 
2817  ic.Reset();
2818  }
2819 
2820  }
2821 }
2822 
2824 {
2825  int xi = m_drawer2D->WorldToDeviceX( box.GetMinX() );
2826  int yi = m_drawer2D->WorldToDeviceY( box.GetMinY() );
2827  int wi = m_drawer2D->WorldToDeviceXRel( box.GetWidth() );
2828  int hi = m_drawer2D->WorldToDeviceYRel( box.GetHeight() );
2829 
2830  if ( m_drawer2D->GetYaxis() )
2831  {
2832  wxRect rect( xi, yi + hi, wi, -hi );
2833  rect.Inflate( 2 ); //boundingbox is exact, to get rid of 1 pixel problems, always extend a little.
2834  AddPendingUpdateArea( rect, id );
2835  //wxLogDebug("update x=%d, y=%d w=%d h=%d", xi, yi+hi, wi, -hi );
2836  }
2837  else
2838  {
2839  wxRect rect( xi, yi, wi, hi );
2840  rect.Inflate( 2 ); //boundingbox is exact, to get rid of 1 pixel problems, always extend a little.
2841  AddPendingUpdateArea( rect, id );
2842  //wxLogDebug("update x=%d, y=%d w=%d h=%d", xi, yi, wi, hi );
2843  }
2844 }
2845 
2846 void a2dDrawingPart::AddPendingUpdateArea( const wxRect& recnew, wxUint8 id )
2847 {
2848  AddPendingUpdateArea( recnew.x, recnew.y, recnew.width, recnew.height, id );
2849 }
2850 
2851 void a2dDrawingPart::AddPendingUpdateArea( int x, int y, int w, int h, wxUint8 id )
2852 {
2853  // clip to buffer
2854  if ( x < 0 )
2855  {
2856  w += x;
2857  x = 0;
2858  }
2859  if ( w <= 0 ) return;
2860 
2861  if ( y < 0 )
2862  {
2863  h += y;
2864  y = 0;
2865  }
2866  if ( h <= 0 ) return;
2867 
2868  if ( x + w > m_width )
2869  {
2870  w = m_width - x;
2871  }
2872  if ( w <= 0 ) return;
2873 
2874  if ( y + h > m_height )
2875  {
2876  h = m_height - y;
2877  }
2878  if ( h <= 0 ) return;
2879 
2880  int xmax = x + w;
2881  int ymax = y + h;
2882 
2883  if ( id == 0 )
2884  m_tiles.FillTiles( x, y, xmax - x, ymax - y, true );
2885  else
2886  m_tiles2.FillTiles( x, y, xmax - x, ymax - y, true );
2887 
2888  m_recur = false;
2889 }
2890 
2891 void a2dDrawingPart::AddPendingUpdateArea( a2dCanvasObject* obj, wxUint8 id, bool refsalso )
2892 {
2893  if ( obj && ( id == 1 ) )
2894  {
2895  a2dIterC ic( this );
2896  a2dIterCU cu( ic, a2dIDENTITY_MATRIX );
2897  wxRect absarea = obj->GetAbsoluteArea( ic );
2898  AddPendingUpdateArea( absarea, id );
2899  /*
2900  //if this object is referenced somewhere else
2901  //Then there is a chance that it is inside this drawer, so update it.
2902  if ( refsalso && obj->GetOwnedBy() > 1)
2903  {
2904  obj->SetPending( true );
2905  //at the top level the group its matrix is to be ignored.
2906  //Since it is normally NOT ignored within a2dCanvasObject, do an inverse first here.
2907  a2dAffineMatrix cworld= m_top->GetTransformMatrix();
2908  cworld.Invert();
2909 
2910  a2dIterC ic( this );
2911  a2dIterCU cu( ic, cworld );
2912 
2913  m_top->AddPending( ic );
2914  obj->SetPending( false );
2915  }
2916  */
2917  }
2918 }
2919 
2920 bool a2dDrawingPart::AddObjectPendingUpdates( a2dCanViewUpdateFlagsMask how )
2921 {
2922  if ( !GetDrawing() )
2923  {
2924  wxASSERT_MSG( GetDrawing() != 0, wxT( "invalid a2dCanvasDocument in a2dDrawingPart" ) );
2925  return false;
2926  }
2927 
2928  if ( GetDrawing()->GetUpdatesPending() )
2929  {
2930  //at the top level the group its matrix is to be ignored.
2931  //Since it is normally NOT ignored within a2dCanvasObject, do an inverse first here.
2933  cworld.Invert();
2934 
2935  a2dIterC ic( this );
2936  ic.SetUpdateHint( how );
2937  a2dIterCU cu( ic, cworld );
2938 
2939  m_top->AddPending( ic );
2940  return true;
2941  }
2942  return false;
2943 }
2944 
2945 /** end of updating routines **/
2946 
2948 {
2949  m_capture = ( a2dCanvasObject* )NULL;
2950 
2951  if ( !GetDrawing() )
2952  {
2953  wxASSERT_MSG( GetDrawing() != 0, wxT( "invalid a2dCanvasDocument in a2dDrawingPart" ) );
2954  return ( a2dCanvasObject* ) NULL;
2955  }
2956 
2957  if ( m_top )
2958  {
2959  m_top->GetRoot()->DisconnectEventAll( this );
2960  m_cursorStack.clear();
2961  }
2962 
2963  a2dCanvasObject* newtop = wxStaticCast( GetDrawing()->GetRootObject()->Find( name, wxT( "" ), 0 ), a2dCanvasObject );
2964  if ( !newtop )
2965  newtop = GetDrawing()->GetRootObject();
2966 
2967  m_top = newtop;
2968  if ( m_top )
2969  {
2970  a2dHabitat* habitat = m_top->GetRoot()->GetHabitat();
2971 
2972  wxASSERT_MSG( m_top->GetRoot(), "root not set on show object" );
2973  a2dCanvasGlobals->SetHabitat( habitat );
2974 
2975  m_hitmargin = habitat->GetHitMarginDevice();
2976  m_documentDrawStyle = habitat->GetDrawStyle() | habitat->GetSelectDrawStyle();
2977  m_selectFill = habitat->GetSelectFill();
2978  m_selectStroke = habitat->GetSelectStroke();
2979  m_select2Fill = habitat->GetSelect2Fill();
2980  m_select2Stroke = habitat->GetSelect2Stroke();
2981  m_reverse_order = habitat->GetReverseOrder();
2982 
2984  {
2986  m_top->GetRoot()->GetCanvasCommandProcessor()->ConnectEvent( wxEVT_BEGINBUSY, this );
2987  m_top->GetRoot()->GetCanvasCommandProcessor()->ConnectEvent( wxEVT_ENDBUSY, this );
2988  }
2989  m_top->GetRoot()->ConnectEvent( wxEVT_MENUSTRINGS, this );
2990  m_top->GetRoot()->ConnectEvent( wxEVT_DO, this );
2991  m_top->GetRoot()->ConnectEvent( wxEVT_UNDO, this );
2992  m_top->GetRoot()->ConnectEvent( wxEVT_REDO, this );
2993  //m_top->GetRoot()->ConnectEvent( wxEVT_UPDATE_VIEWS, this );
2994  m_top->GetRoot()->ConnectEvent( wxEVT_UPDATE_DRAWING, this );
2995  }
2996 
2997  SetCaptured( NULL );
2998 
3000 
3001 
3002  a2dComEvent changedShow( this, m_top, sig_changedShowObject );
3003  if ( m_toolcontroller )
3004  {
3005  m_toolcontroller->ProcessEvent( changedShow );
3006  changedShow.Skip();
3007  }
3008  ProcessEvent( changedShow );
3009 
3010  return newtop;
3011 }
3012 
3014 {
3015  m_capture = ( a2dCanvasObject* )NULL;
3016 
3017  if ( m_top )
3018  {
3019  m_top->GetRoot()->DisconnectEventAll( this );
3020  m_cursorStack.clear();
3021  }
3023  if ( !found )
3024  m_top = NULL; //GetDrawing()->GetRootObject();
3025  else
3026  m_top = found;
3027 
3028  if ( m_top && m_top->GetRoot() )
3029  {
3030  wxASSERT_MSG( m_top->GetRoot(), "root not set on show object" );
3031 
3032  // use habitat of drawing ( a2dDrawingPart can be used on various drawing with different habitats).
3033  a2dHabitat* habitat = m_top->GetRoot()->GetHabitat();
3034 
3035  a2dCanvasGlobals->SetHabitat( habitat );
3036 
3037  m_hitmargin = habitat->GetHitMarginDevice();
3038  m_documentDrawStyle = habitat->GetDrawStyle() | habitat->GetSelectDrawStyle();
3039  m_selectFill = habitat->GetSelectFill();
3040  m_selectStroke = habitat->GetSelectStroke();
3041  m_select2Fill = habitat->GetSelect2Fill();
3042  m_select2Stroke = habitat->GetSelect2Stroke();
3043  m_reverse_order = habitat->GetReverseOrder();
3044 
3046  {
3048  m_top->GetRoot()->GetCanvasCommandProcessor()->ConnectEvent( wxEVT_BEGINBUSY, this );
3049  m_top->GetRoot()->GetCanvasCommandProcessor()->ConnectEvent( wxEVT_ENDBUSY, this );
3050  }
3051  m_top->GetRoot()->ConnectEvent( wxEVT_MENUSTRINGS, this );
3052  m_top->GetRoot()->ConnectEvent( wxEVT_DO, this );
3053  m_top->GetRoot()->ConnectEvent( wxEVT_UNDO, this );
3054  m_top->GetRoot()->ConnectEvent( wxEVT_REDO, this );
3055  //m_top->GetRoot()->ConnectEvent( wxEVT_UPDATE_VIEWS, this );
3056  m_top->GetRoot()->ConnectEvent( wxEVT_UPDATE_DRAWING, this );
3057  }
3058 
3059  SetCaptured( NULL );
3060 
3062 
3063  a2dComEvent changedShow( this, m_top, sig_changedShowObject );
3064  ProcessEvent( changedShow );
3065 
3066  return ( m_top.Get() != 0 );
3067 }
3068 
3070 {
3071  m_capture = ( a2dCanvasObject* )NULL;
3072 
3073  if ( m_top )
3074  {
3075  m_top->GetRoot()->DisconnectEventAll( this );
3076  m_cursorStack.clear();
3077  }
3079  if ( !found )
3080  m_top = NULL; //GetDrawing()->GetRootObject();
3081  else
3082  m_top = found;
3083 
3084  if ( m_top && m_top->GetRoot() )
3085  {
3086  a2dHabitat* habitat = m_top->GetRoot()->GetHabitat();
3087 
3088  wxASSERT_MSG( m_top->GetRoot(), "root not set on show object" );
3089  a2dCanvasGlobals->SetHabitat( habitat );
3090 
3091  m_hitmargin = habitat->GetHitMarginDevice();
3092  m_documentDrawStyle = habitat->GetDrawStyle() | habitat->GetSelectDrawStyle();
3093  m_selectFill = habitat->GetSelectFill();
3094  m_selectStroke = habitat->GetSelectStroke();
3095  m_select2Fill = habitat->GetSelect2Fill();
3096  m_select2Stroke = habitat->GetSelect2Stroke();
3097  m_reverse_order = habitat->GetReverseOrder();
3098 
3099  //update from drawing needed.
3100  m_top->GetRoot()->ConnectEvent( wxEVT_UPDATE_DRAWING, this );
3101  }
3102 
3103  SetCaptured( NULL );
3104 
3106 }
3107 
3109 {
3110  m_pushInStack.push_back( m_top );
3111  SetShowObject( pushin );
3112 }
3113 
3115 {
3116  if ( m_pushInStack.size() )
3117  {
3118  SetShowObject( m_pushInStack.back() );
3119  a2dCanvasObject* ret = m_pushInStack.back();
3120  m_pushInStack.pop_back();
3121  return ret;
3122  }
3123  return NULL;
3124 }
3125 
3127 {
3128  m_pushInStack.clear();
3129 }
3130 
3131 void a2dDrawingPart::SetBackgroundFill( const a2dFill& backgroundfill )
3132 {
3133  m_backgroundfill = backgroundfill;
3135 }
3136 
3137 void a2dDrawingPart::SetGridStroke( const a2dStroke& gridstroke )
3138 {
3139  m_gridstroke = gridstroke;
3141 }
3142 
3143 void a2dDrawingPart::SetGridFill( const a2dFill& gridfill )
3144 {
3145  m_gridfill = gridfill;
3147 }
3148 
3150 {
3151  if ( !m_top || !GetDrawing() )
3152  return;
3153 
3154  a2dBoundingBox untr = m_top->GetBbox();
3156  cworld.Invert();
3157  untr.MapBbox( cworld );
3158 
3159  untr.Enlarge( m_drawer2D->DeviceToWorldXRel( m_border ) );
3160 
3161  double worldw = untr.GetWidth();
3162  double worldh = untr.GetHeight();
3163 
3164  if ( worldw == 0 || worldh == 0 )
3165  {
3166  worldw = GetDrawing()->GetInitialSizeX();
3167  worldh = GetDrawing()->GetInitialSizeY();
3168  untr = a2dBoundingBox( 0, 0, worldw, worldh );
3169  }
3170 
3171  double xupp = worldw / m_width;
3172  double yupp = worldh / m_height;
3173 
3174  if ( yupp == 0 || xupp == 0 ) //no drawing at all
3175  {
3176  yupp = 1; xupp = 1; //some value
3177  }
3178 
3179  if ( yupp > xupp )
3180  {
3181  //centrate
3182  if ( worldw > yupp * m_width )
3183  untr.Translate( ( worldw - yupp * m_width ) / 2.0, 0 );
3184  }
3185  else
3186  {
3187  if ( worldh > xupp * m_height )
3188  untr.Translate( 0, ( worldh - xupp * m_height ) / 2.0 );
3189  }
3190 
3191  m_drawer2D->SetMappingWidthHeight( untr );
3192 }
3193 
3194 /*******************************************************************
3195 a2dDrawingPart (grid and background)
3196 ********************************************************************/
3197 
3198 
3200 {
3201  if ( m_showorigin )
3202  {
3203  //origin is in world coordinates at 0,0
3204  int x = m_drawer2D->WorldToDeviceX( 0.0 );
3205  int y = m_drawer2D->WorldToDeviceY( 0.0 );
3206  int w = 10;
3207  int h = 10;
3208  m_drawer2D->SetDrawerStroke( *a2dBLACK_STROKE );
3209  m_drawer2D->SetDrawerFill( *a2dBLACK_FILL );
3210  m_drawer2D->PushIdentityTransform();
3211  m_drawer2D->DrawLine( x - w, y, w + x, y );
3212  m_drawer2D->DrawLine( x, y - h, x, y + h );
3213  m_drawer2D->PopTransform();
3214  }
3215 }
3216 
3217 void a2dDrawingPart::PaintGrid( int x, int y, int width, int height )
3218 {
3219  m_drawer2D->SetDrawerStroke( m_gridstroke );
3220  m_drawer2D->SetDrawerFill( m_gridfill );
3221  // calculate in world coordinates the input size to redraw
3222  double min_x, max_x, min_y, max_y;
3223 
3224  /* This if buffer size based.
3225 
3226  double dvx = m_drawer2D->GetUppX() * m_width;
3227  double dvy = m_drawer2D->GetUppY() * m_height;
3228 
3229  min_x = m_drawer2D->GetVisibleMinX();
3230  max_x = m_drawer2D->GetVisibleMinX() + dvx;
3231 
3232  if ( m_drawer2D->GetYaxis() )
3233  {
3234  min_y = m_drawer2D->DeviceToWorldY( m_height );
3235  //the next would be wrong since GetVisibleMinY() is the miminum Y on screen
3236  //the buffer is bigger.
3237  //min_y = GetVisibleMinY();
3238  max_y = m_drawer2D->GetVisibleMinY() + dvy;
3239  }
3240  else
3241  {
3242  min_y = m_drawer2D->GetVisibleMinY();
3243  max_y = m_drawer2D->GetVisibleMinY() + dvy;
3244  }
3245  */
3246 
3247  double gridx = m_gridx;
3248  double gridy = m_gridy;
3249  while ( m_drawer2D->DeviceToWorldXRel( m_gridthres ) > gridx )
3250  gridx *= 2;
3251  while ( m_drawer2D->DeviceToWorldXRel( m_gridthres ) > gridy )
3252  gridy *= 2;
3253 
3254  const a2dAffineMatrix worldtodevice = m_drawer2D->GetMappingMatrix();
3255  min_x = m_drawer2D->DeviceToWorldX( x );
3256  max_x = m_drawer2D->DeviceToWorldX( x + width );
3257  if ( !m_drawer2D->GetYaxis() )
3258  {
3259  min_y = m_drawer2D->DeviceToWorldY( y );
3260  max_y = m_drawer2D->DeviceToWorldY( y + height );
3261  }
3262  else
3263  {
3264  max_y = m_drawer2D->DeviceToWorldY( y );
3265  min_y = m_drawer2D->DeviceToWorldY( y + height );
3266  }
3267 
3268  max_x = ceil( max_x / gridx ) * gridx;
3269  min_x = floor( min_x / gridx ) * gridx;
3270  min_y = floor( min_y / gridy ) * gridy;
3271  max_y = ceil( max_y / gridy ) * gridy;
3272 
3273  m_drawer2D->PushIdentityTransform();
3274  if ( !m_gridlines )
3275  {
3276  double i, j;
3277  for ( i = min_x; i < max_x; i += gridx )
3278  {
3279  for ( j = min_y; j < max_y; j += gridy )
3280  {
3281  double xi, yi;
3282  worldtodevice.TransformPoint( i, j, xi, yi );
3283  if ( m_gridsize )
3284  m_drawer2D->DrawCircle( xi, yi, m_gridsize / 2 );
3285  else
3286  m_drawer2D->DrawPoint( xi, yi );
3287  }
3288  }
3289  }
3290  else
3291  {
3292  double i, j;
3293  for ( i = min_x; i < max_x; i += gridx )
3294  {
3295  double xi, yi;
3296  worldtodevice.TransformPoint( i, 0, xi, yi );
3297  m_drawer2D->DrawLine( xi, 0, xi, m_height );
3298  }
3299  for ( j = min_y; j < max_y; j += gridy )
3300  {
3301  double xi, yi;
3302  worldtodevice.TransformPoint( 0, j, xi, yi );
3303  m_drawer2D->DrawLine( 0, yi, m_width, yi );
3304  }
3305  }
3306  m_drawer2D->PopTransform();
3307 
3308  m_drawer2D->SetDrawerFill( *a2dTRANSPARENT_FILL );
3309  m_drawer2D->SetDrawerStroke( *a2dTRANSPARENT_STROKE );
3310 }
3311 
3312 void a2dDrawingPart::PaintBackground( int x, int y, int width, int height )
3313 {
3314  m_drawer2D->SetDrawerStroke( *a2dTRANSPARENT_STROKE );
3315  m_drawer2D->SetDrawerFill( m_backgroundfill );
3316  //clear the buffer using the canvas background colour
3317  //remark (a transparent pen must mean a fully filled rectangle)
3318 
3320  {
3321  a2dVertexArray cpoints;
3322  //TODO it not completely rectangular
3323  //there is missing a scanline in the fill for horizontal lines.
3324  //But since the clipping regions should be set, this is a working hack.
3325  cpoints.AddPoint( 0, -10 );
3326  cpoints.AddPoint( 0, m_height + 10 );
3327  cpoints.AddPoint( m_width, m_height );
3328  cpoints.AddPoint( m_width, 0 );
3329 
3330  m_drawer2D->PushIdentityTransform();
3331  m_drawer2D->DrawPolygon( &cpoints );
3332  m_drawer2D->PopTransform();
3333  }
3334  else
3335  {
3336  m_drawer2D->PushIdentityTransform();
3337  m_drawer2D->DrawRoundedRectangle( x, y, width, height, 0 );
3338  m_drawer2D->PopTransform();
3339  }
3340  m_drawer2D->SetDrawerFill( *a2dTRANSPARENT_FILL );
3341  m_drawer2D->SetDrawerStroke( *a2dTRANSPARENT_STROKE );
3342 
3343  // the next gives you very good indication of what is updated or not on the canvas.
3344 #if defined(_DEBUG)
3345  if ( m_updatesVisible && !(x==0 && y==0 && m_width==width && m_height==height) )
3346  {
3347  wxUint8 range_max = 210;
3348  wxUint8 range_min = 190;
3349  wxUint8 r = double( rand() / double(RAND_MAX + 1) ) * (range_max - range_min) + range_min;
3350  wxUint8 g = double( rand() / double(RAND_MAX + 1) ) * (range_max - range_min) + range_min;
3351  wxUint8 b = double( rand() / double(RAND_MAX + 1) ) * (range_max - range_min) + range_min;
3352 
3353  m_drawer2D->PushIdentityTransform();
3354  m_drawer2D->SetDrawerFill( a2dFill( wxColour( r,g,b ) ) );
3355  m_drawer2D->DrawRoundedRectangle( x, y, width, height, 0 );
3356  m_drawer2D->PopTransform();
3357  }
3358 #endif
3359 }
3360 
3362 {
3363  if ( !m_crosshair ) //&& m_mouseevents )
3364  return;
3365 
3366  m_drawer2D->BeginDraw();
3367  m_drawer2D->PushIdentityTransform();
3368  m_drawer2D->SetDrawStyle( a2dWIREFRAME_INVERT );
3369 
3370  wxRect rect1( m_crosshairx - m_crosshairLengthX / 2 - 10, m_crosshairy - m_crosshairLengthY / 2 - 10,
3372 
3373  //paint cross
3374  m_drawer2D->SetDrawerStroke( m_crosshairStroke );
3375 
3378 
3379  m_crosshairx = x;
3380  m_crosshairy = y;
3381 
3384 
3385  m_drawer2D->BlitBuffer( rect1 );
3386 
3387  wxRect rect( m_crosshairx - m_crosshairLengthX / 2 - 10, m_crosshairy - m_crosshairLengthY / 2 - 10,
3389  m_drawer2D->BlitBuffer( rect );
3390 
3391  m_drawer2D->SetDrawerStroke( *a2dTRANSPARENT_STROKE );
3392 
3393  m_drawer2D->PopTransform();
3394  m_drawer2D->EndDraw();
3395  m_drawer2D->SetDrawStyle( a2dFILLED );
3396 }
3397 
3398 void a2dDrawingPart::Scroll( int dxy, bool yscroll, bool total )
3399 {
3400  bool gradient = ( m_backgroundfill.GetType() == a2dFILL_GRADIENT_FILL_LINEAR || m_backgroundfill.GetType() == a2dFILL_GRADIENT_FILL_RADIAL );
3401  int bw = m_width;
3402  int bh = m_height;
3403  if ( yscroll )
3404  {
3405  if ( total || gradient )
3406  {
3407  AddPendingUpdateArea( 0, 0, bw, bh );
3408  }
3409  else
3410  {
3411  if ( dxy > 0 && dxy < bh )
3412  {
3413  m_drawer2D->ShiftBuffer( dxy, yscroll );
3414  AddPendingUpdateArea( 0, 0, bw, dxy );
3415  }
3416  else if ( dxy < 0 && dxy > -bh )
3417  {
3418  m_drawer2D->ShiftBuffer( dxy, yscroll );
3419  AddPendingUpdateArea( 0, bh + dxy, bw, -dxy );
3420  }
3421  else
3422  AddPendingUpdateArea( 0, 0, bw, bh );
3423  }
3424  }
3425  else
3426  {
3427  if ( total || gradient )
3428  {
3429  AddPendingUpdateArea( 0, 0, bw, bh );
3430  }
3431  else
3432  {
3433  if ( dxy > 0 && dxy < bw )
3434  {
3435  m_drawer2D->ShiftBuffer( dxy, yscroll );
3436  AddPendingUpdateArea( 0, 0, dxy, bh );
3437  }
3438  else if ( dxy < 0 && dxy > -bw )
3439  {
3440  m_drawer2D->ShiftBuffer( dxy, yscroll );
3441  AddPendingUpdateArea( bw + dxy, 0, -dxy, bh );
3442  }
3443  else
3444  AddPendingUpdateArea( 0, 0, bw, bh );
3445  }
3446  }
3447 
3448  //now make sure the buffer is fully updated
3450 }
3451 
3452 void a2dDrawingPart::OnDrop(wxCoord x, wxCoord y, a2dDrawing* drawing )
3453 {
3454  double xWorldLocal, yWorldLocal;
3455  MouseToToolWorld( x, y, xWorldLocal, yWorldLocal );
3456  a2dCanvasObjectList* objects = drawing->GetRootObject()->GetChildObjectList();
3457  forEachIn( a2dCanvasObjectList, objects )
3458  {
3459  a2dCanvasObject* obj = *iter;
3460  obj->Translate( xWorldLocal, yWorldLocal );
3461  m_top->Append( obj );
3462  }
3463 
3464 }
3465 
3466 
3467 #if wxUSE_PRINTING_ARCHITECTURE
3468 
3469 
3470 //----------------------------------------------------------------------------
3471 // a2dPrintFactory
3472 //----------------------------------------------------------------------------
3473 
3474 wxPrinterBase *a2dPrintFactory::CreatePrinter( wxPrintDialogData *data )
3475 {
3476 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
3477  return new wxWindowsPrinter( data );
3478 #elif defined(__WXMAC__)
3479  return new wxMacPrinter( data );
3480 #elif defined(__WXPM__)
3481  return new wxOS2Printer( data );
3482 #else
3483  return new wxPostScriptPrinter( data );
3484 #endif
3485 }
3486 
3487 wxPrintPreviewBase *a2dPrintFactory::CreatePrintPreview( wxPrintout *preview,
3488  wxPrintout *printout, wxPrintDialogData *data )
3489 {
3490 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
3491  return new a2dWindowsPrintPreview( preview, printout, data );
3492 #elif defined(__WXMAC__)
3493  return new wxMacPrintPreview( preview, printout, data );
3494 #elif defined(__WXPM__)
3495  return new wxOS2PrintPreview( preview, printout, data );
3496 #else
3497  return new wxPostScriptPrintPreview( preview, printout, data );
3498 #endif
3499 }
3500 
3501 wxPrintPreviewBase *a2dPrintFactory::CreatePrintPreview( wxPrintout *preview,
3502  wxPrintout *printout, wxPrintData *data )
3503 {
3504 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
3505  return new a2dWindowsPrintPreview( preview, printout, data );
3506 #elif defined(__WXMAC__)
3507  return new wxMacPrintPreview( preview, printout, data );
3508 #elif defined(__WXPM__)
3509  return new wxOS2PrintPreview( preview, printout, data );
3510 #else
3511  return new wxPostScriptPrintPreview( preview, printout, data );
3512 #endif
3513 }
3514 
3515 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
3516 
3517 /*
3518 * Print preview
3519 */
3520 
3521 IMPLEMENT_CLASS( a2dWindowsPrintPreview, wxWindowsPrintPreview )
3522 
3523 a2dWindowsPrintPreview::a2dWindowsPrintPreview(wxPrintout *printout,
3524  wxPrintout *printoutForPrinting,
3525  wxPrintDialogData *data)
3526  : wxWindowsPrintPreview(printout, printoutForPrinting, data)
3527 {
3528  DetermineScaling();
3529 }
3530 
3531 a2dWindowsPrintPreview::a2dWindowsPrintPreview(wxPrintout *printout,
3532  wxPrintout *printoutForPrinting,
3533  wxPrintData *data)
3534  : wxWindowsPrintPreview( printout, printoutForPrinting, data)
3535 {
3536  DetermineScaling();
3537 }
3538 
3539 a2dWindowsPrintPreview::~a2dWindowsPrintPreview()
3540 {
3541 }
3542 
3543 bool a2dWindowsPrintPreview::RenderPageIntoBitmap(wxBitmap& bmp, int pageNum)
3544 {
3545  wxMemoryDC memoryDC;
3546  memoryDC.SelectObject(bmp);
3547  memoryDC.Clear();
3548 
3549  return RenderPageIntoDC(memoryDC, pageNum);
3550 }
3551 
3552 #endif
3553 
3554 #endif // wxUSE_PRINTING_ARCHITECTURE
3555 
3556 
3557 
3558 #if wxUSE_DRAG_AND_DROP
3559 
3560 // ----------------------------------------------------------------------------
3561 // A wxDataObject specialisation for the application-specific data
3562 // ----------------------------------------------------------------------------
3563 
3564 const wxChar *a2dCanvasObjectFormatId = wxT("a2dCanvasObject");
3565 
3566 
3567 // ----------------------------------------------------------------------------
3568 // A a2dDnDCameleonData specialisation for the application-specific data
3569 // ----------------------------------------------------------------------------
3570 
3571 a2dDnDCameleonData::a2dDnDCameleonData( a2dCanvasObject* canvasobject, double dragStartX, double dragStartY, a2dDrawingPart* drawingPart )
3572 : a2dDnDCanvasObjectDataCVG( drawingPart )
3573 {
3574 }
3575 
3576 a2dDnDCameleonData::~a2dDnDCameleonData()
3577 {
3578 }
3579 
3580 size_t a2dDnDCameleonData::GetDataSize(const wxDataFormat& format) const
3581 {
3582  if ( format == m_formatShape )
3583  {
3585 
3586  // Set the locale to english for this I/O operation
3587  // !!!! It would be better to set the locale of the stream itself,
3588  // but this does not work for two reasons:
3589  // 1. wxWindows streams don't support this
3590  // 2. CVG-IO uses e.g. wxString::ToDouble, which is independent of the stream
3591  wxString oldLocale = wxSetlocale( LC_NUMERIC, NULL );
3592 #ifdef __WXMSW__
3593  wxSetlocale( LC_NUMERIC, wxString( wxT( "English" ) ) );
3594 #else
3595  wxSetlocale( LC_NUMERIC, wxString( wxT( "en_US" ) ) );
3596 #endif
3597 
3598  m_mem.str("");
3599  a2dIOHandlerCVGOut CVGwriter;
3600  a2dCanvasObjectList* objects = m_drawing->GetRootObject()->GetChildObjectList();
3601  forEachIn( a2dCanvasObjectList, objects )
3602  {
3603  a2dCanvasObject* obj = *iter;
3604  obj->Translate( -m_dragStartX, -m_dragStartY);
3605 
3607  if ( ref )
3608  {
3609  //a2dCameleonInst* refinst = new a2dCameleonInst( 2, 5, ref->GetCameleon()->GetAppearance<a2dSymbol>() );
3610  a2dCameleonInst* refinst = new a2dCameleonInst( 2, 5, ref->GetCameleon()->GetAppearance<a2dDiagram>() );
3611  *iter = refinst;
3612  }
3613  }
3615 
3616  CVGwriter.SaveStartAt( m_mem, m_drawing, m_drawing->GetRootObject() );
3617 
3618  wxSetlocale( LC_NUMERIC, oldLocale );
3619 /* to debug contents
3620  wxFFileOutputStream file("c:/data/soft/out.txt");
3621  wxStdOutputStream out(file);
3622 
3623  out << m_mem.str() << std::endl;
3624 */
3625 
3626  m_mem.seekp(0);
3627 
3628  return m_mem.str().length()+10;
3629  }
3630  else
3631  {
3632  return a2dDnDCanvasObjectDataCVG::GetDataSize( format );
3633  }
3634 }
3635 
3636 bool a2dDnDCameleonData::SetData(const wxDataFormat& format, size_t len, const void *buf )
3637 {
3638  if ( format == m_formatShape )
3639  {
3640 
3641  wxCharBuffer cvgString = wxCharBuffer( (const char*) buf );
3642 
3643  // Set the locale to english for this I/O operation
3644  // !!!! It would be better to set the locale of the stream itself,
3645  // but this does not work for two reasons:
3646  // 1. wxWindows streams don't support this
3647  // 2. CVG-IO uses e.g. wxString::ToDouble, which is independent of the stream
3648  wxString oldLocale = wxSetlocale( LC_NUMERIC, NULL );
3649  wxSetlocale( LC_NUMERIC, wxString( wxT( "English" ) ) );
3650 
3651  #if wxART2D_USE_CVGIO
3652  #if wxUSE_STD_IOSTREAM
3653  #if wxUSE_UNICODE
3654  a2dDocumentStringInputStream stream( cvgString.data(), wxSTD ios_base::in );
3655  #else
3656  a2dDocumentStringInputStream stream( cvgString, wxSTD ios_base::in );
3657  #endif // wxUSE_UNICODE
3658  #else
3659  a2dDocumentStringInputStream stream( cvgStringtoExecute );
3660  #endif
3661  a2dIOHandlerCVGIn CvgString;
3662 
3663  CvgString.Load( stream, m_drawing, m_drawing->GetRootObject() );
3664 
3665  // the shape has changed
3666  m_hasBitmap = false;
3667 
3668  #if wxUSE_METAFILE
3669  m_hasMetaFile = false;
3670  #endif // wxUSE_METAFILE
3671  return true;
3672  #else
3673  return false;
3674  #endif //wxART2D_USE_CVGIO
3675  }
3676  else
3677  {
3678  a2dDnDCanvasObjectDataCVG::SetData( format, len, buf );
3679  }
3680  return false;
3681 }
3682 
3683 #endif // wxUSE_DRAG_AND_DROP
3684 
3685 //----------------------------------------------------------------------------
3686 // a2dDrawingPrintOut
3687 //----------------------------------------------------------------------------
3688 
3689 #if wxUSE_PRINTING_ARCHITECTURE
3690 
3692 
3693 /* print out for drawer */
3694 a2dDrawingPrintOut::a2dDrawingPrintOut( const wxPageSetupDialogData& pageSetupData, a2dDrawingPart* drawingPart, const wxString& title, const wxString& filename, a2dPrintWhat typeOfPrint, bool drawframe, double scalelimit, bool fitToPage ) :
3695  m_pageSetupData( pageSetupData ),
3696  wxPrintout( title )
3697 {
3698  m_typeOfPrint = typeOfPrint;
3699  m_drawingPart = drawingPart;
3700  m_title = title;
3701  m_filename = filename;
3702  m_scalelimit = scalelimit;
3703  m_drawframe = drawframe;
3704  m_fitToPage = fitToPage;
3705 }
3706 
3708 {
3709 }
3710 
3712 {
3713 
3714  wxDC* dc;
3715  dc = GetDC();
3716 
3717  // We get the paper size in device units and the margins in mm,
3718  // so we need to calculate the conversion with this trick
3719  wxCoord pw, ph;
3720  dc->GetSize( &pw, &ph );
3721  wxCoord mw, mh;
3722  GetPageSizeMM(&mw, &mh);
3723  float mmToDeviceX = float(pw) / mw;
3724  float mmToDeviceY = float(ph) / mh;
3725 
3726  // paper size in device units
3727  wxRect paperRect = wxRect( 0,0,pw,ph);
3728 
3729  // margins in mm
3730  wxPoint topLeft = m_pageSetupData.GetMarginTopLeft();
3731  wxPoint bottomRight = m_pageSetupData.GetMarginBottomRight();
3732 
3733  // calculate margins in device units
3734  wxRect pageMarginsRect(
3735  paperRect.x + wxRound(mmToDeviceX * topLeft.x),
3736  paperRect.y + wxRound(mmToDeviceY * topLeft.y),
3737  paperRect.width - wxRound(mmToDeviceX * (topLeft.x + bottomRight.x)),
3738  paperRect.height - wxRound(mmToDeviceY * (topLeft.y + bottomRight.y)));
3739 
3740  //! needed ?
3741  dc->SetBrush( *wxWHITE_BRUSH );
3742  dc->SetBackground( *wxWHITE_BRUSH );
3743  dc->Clear();
3744  dc->SetBackgroundMode( wxTRANSPARENT );
3745  dc->SetTextForeground( *wxBLACK );
3746  dc->SetBrush( *wxTRANSPARENT_BRUSH );
3747 
3748 
3749  int marginX = ( int )( ph * 0.015 );
3750  int marginY = marginX;
3751  int fontMarginYTop = 0;
3752  int fontMarginYBottom = 0;
3753  wxFont fontTitle = wxFont( marginY, wxDEFAULT, wxNORMAL, wxNORMAL );
3754  wxFont fontFilename = wxFont( int( marginY / 2. + 0.5 ), wxDEFAULT, wxNORMAL, wxNORMAL );
3755 
3756  if ( !m_title.IsEmpty() )
3757  {
3758  dc->SetFont( fontTitle );
3759  fontMarginYTop += 2 * fontTitle.GetPointSize();
3760  wxCoord xExtent, yExtent;
3761  dc->GetTextExtent( m_title, &xExtent, &yExtent );
3762  dc->DrawText( m_title, pw / 2 - xExtent / 2, marginY );
3763  }
3764 
3765  if ( !m_filename.IsEmpty() )
3766  {
3767  dc->SetFont( fontFilename );
3768  fontMarginYBottom += 2 * fontFilename.GetPointSize();
3769  dc->DrawText( m_filename, marginX, ph - marginY - fontMarginYBottom );
3770  }
3771 
3772 
3773  int widthX = pageMarginsRect.GetWidth();
3774  int widthY = pageMarginsRect.GetHeight();
3775  int orgX = pageMarginsRect.GetTopLeft().x;
3776  int orgY = pageMarginsRect.GetTopLeft().y;
3777 
3778  dc->SetBackgroundMode( wxSOLID );
3779  dc->SetFont( wxNullFont );
3780 
3781 /* todo
3782  double scaleX = ( widthX / ( double ) pw );
3783  double scaleY = ( widthY / ( double ) ph );
3784 // double scaleX = (w/widthX);
3785 // double scaleY = (h/widthY);
3786 
3787  if( !m_fitToPage )
3788  {
3789  double actualScale = wxMax( scaleX, scaleY );
3790 
3791  if( actualScale < m_scalelimit )
3792  actualScale = m_scalelimit;
3793  scaleX = scaleY = actualScale;
3794  }
3795 
3796  //if scale in X and Y did change, adjust incoming Dc to draw on that exact area.
3797  // Calculate the position on the DC for centering the graphic
3798  orgX = orgX + Round( ( pw - ( widthX / scaleX ) ) / 2.0 );
3799  orgY = orgY + fontMarginYTop + Round( ( ph - ( widthY / scaleY ) ) / 2.0 );
3800 */
3801 
3802  wxDC* memprint = wxDynamicCast( dc, wxMemoryDC );
3803 
3804  a2dDcDrawer* dcdrawer = NULL;
3805  if (!memprint && !m_printAsBitmap)
3806  dcdrawer = new a2dDcDrawer( widthX, widthY );
3807  else
3808  dcdrawer = new a2dMemDcDrawer( widthX, widthY );
3809 
3810  dcdrawer->SetPrintMode( true );
3811  dcdrawer->SetRealScale( !m_fitToPage );
3812  //dcdrawer->SetSmallTextThreshold( 10000 );
3813 
3814  // initialize with the view to print, but scaling will be changed later.
3815  a2dSmrtPtr<a2dDrawingPart> drawPart = new a2dDrawingPart( *m_drawingPart );
3816 
3817  //drawView is a a2dView and therefore gets events, but this is not wanted here.
3818  drawPart->SetEvtHandlerEnabled( false );
3819  drawPart->SetDrawer2D( dcdrawer );
3820  drawPart->SetShowOrigin( false );
3821  drawPart->SetGrid( false );
3822 
3823  // take some important settings from the view where this a2dDrawingPrintOut was created:
3824  // see a2dCanvasView::OnCreatePrintout()
3827  drawPart->SetAvailable();
3828  a2dDrawer2D* drawcont = m_drawingPart->GetDrawer2D();
3829  dcdrawer->SetYaxis( drawcont->GetYaxis() );
3830 
3831  if ( memprint || (!memprint && !m_printAsBitmap) )
3832  {
3833  //is wxPrinterDc, and we draw on it;
3834 
3836  {
3837  dcdrawer->SetMappingWidthHeight( drawcont->GetVisibleMinX(),
3838  drawcont->GetVisibleMinY(),
3839  drawcont->GetVisibleWidth(),
3840  drawcont->GetVisibleHeight() );
3841  }
3842  else //default do all of document
3843  {
3844  drawPart->SetMappingShowAll();
3845  }
3846 
3847  //now start drawing the document on our created view
3848  // Set the scale and origin
3849  // dc->SetUserScale(scaleX, scaleY);
3850  dc->SetDeviceOrigin( orgX, orgY );
3851  dcdrawer->SetRenderDC( dc ); //a trick to set the drawers internal dc.
3852  drawPart->UpdateArea( 0, 0, widthX, widthY );
3853  dcdrawer->SetRenderDC( NULL );
3854  }
3855  else if ( !memprint && m_printAsBitmap )
3856  {
3858  {
3859  dcdrawer->SetMappingWidthHeight( drawcont->GetVisibleMinX(),
3860  drawcont->GetVisibleMinY(),
3861  drawcont->GetVisibleWidth(),
3862  drawcont->GetVisibleHeight() );
3863  }
3864  else //default do all of document
3865  {
3866  drawPart->SetMappingShowAll();
3867  }
3868 
3869  //now start drawing the document on our created view
3870  drawPart->UpdateArea( 0, 0, widthX, widthY );
3871 
3872  wxBitmap buffer(dcdrawer->GetBuffer());
3873  drawPart = NULL; // Delete the 2nd reference to the bitmap. Otherwise dcb.SelectObject( buffer ); causes an exception
3874 
3875  //buffer.SaveFile( "c:/soft/aap.png", wxBITMAP_TYPE_PNG );
3876  wxMemoryDC dcb;
3877  dcb.SelectObject( buffer );
3878  dc->Blit( orgX, orgY, widthX, widthY, &dcb, 0, 0, wxCOPY, false );
3879  dcb.SelectObject( wxNullBitmap );
3880 /* if above does not work, this will!
3881  wxMemoryDC dcb;
3882  dcb.SelectObject( buffer );
3883  int stripHeight = 1000;
3884  int i, strips = widthY / stripHeight;
3885  int rest = widthY - strips * stripHeight;
3886  for ( i = 0; i < strips; i++ )
3887  {
3888  dc->Blit( 0 , stripHeight * i, widthX, stripHeight, &dcb, 0, stripHeight*i, wxCOPY, false );
3889  }
3890  dc->Blit( 0 , stripHeight * i, widthX, rest, &dcb, 0, stripHeight*i , wxCOPY, false );
3891  dcb.SelectObject( wxNullBitmap );
3892 */
3893  //dc->DrawBitmap( buffer , 0,0 );
3894  }
3895 
3896  if( m_drawframe )
3897  {
3898  dc->SetDeviceOrigin( 0, 0 );
3899  dc->SetBrush( *wxTRANSPARENT_BRUSH );
3900  dc->SetPen( *wxRED_PEN );
3901  dc->DrawRectangle( orgX, orgY, widthX, widthY );
3902  const wxPen& aPenForFrame = dc->GetPen();
3903  }
3904 
3905 
3906  /* debug
3907  dc->SetDeviceOrigin( 0, 0 );
3908  dc->SetPen( *wxBLACK_PEN );
3909  dc->SetBrush( *wxTRANSPARENT_BRUSH );
3910  dc->DrawRectangle( orgX, orgY, widthX, widthY);
3911  */
3912  return true;
3913 }
3914 
3915 bool a2dDrawingPrintOut::HasPage( int pageNum )
3916 {
3917  return ( pageNum == 1 );
3918 }
3919 
3920 bool a2dDrawingPrintOut::OnBeginDocument( int startPage, int endPage )
3921 {
3922  if ( !wxPrintout::OnBeginDocument( startPage, endPage ) )
3923  return false;
3924 
3925  return true;
3926 }
3927 
3928 void a2dDrawingPrintOut::GetPageInfo( int* minPage, int* maxPage, int* selPageFrom, int* selPageTo )
3929 {
3930  *minPage = 1;
3931  *maxPage = 1;
3932  *selPageFrom = 1;
3933  *selPageTo = 1;
3934 }
3935 
3936 #endif //wxUSE_PRINTING_ARCHITECTURE
void SetSize(int width, int height)
change tile area
Definition: drawer.cpp:126
virtual void SetYaxis(bool up)
set if the Yaxis goes up or down
Definition: drawer2d.cpp:438
Display Part of a a2dDrawing, in which a2dCanvasObjects are shown.
Definition: drawer.h:470
void PushCursor(const wxCursor &cursor)
push a cursor on the cursor stack, and set display cursor to new back being cursor.
Definition: drawer.cpp:1052
int WorldToDeviceXRel(double x) const
convert x relative from world to device coordinates
Definition: drawer2d.h:460
virtual bool ProcessCanvasObjectEvent(a2dIterC &ic, a2dHitEvent &hitEvent)
Hit objects will receive the event.
Definition: canobj.cpp:3964
virtual void PaintBackground(int x, int y, int width, int height)
(re)painting of background
Definition: drawer.cpp:3312
double GetHeight() const
returns height of the boundingbox
Definition: bbox.cpp:334
void Freeze()
prevent changing the a2dDrawingPart buffer and blitting it to the window
Definition: drawer.cpp:1026
bool m_gridlines
show grid as lines
Definition: drawer.h:1372
a2dTileBox is a subarea of a tile.
Definition: drawer.h:151
virtual void Render(a2dIterC &ic, OVERLAP clipparent)
Render this object to the active a2dDrawingPart.
Definition: canobj.cpp:4712
void SetGridFill(const a2dFill &gridfill)
set fill used for grid drawing
Definition: drawer.cpp:3143
(In) Visible property that can be added to Docview Objects.
Definition: gen.h:1785
virtual void RenderOverlay(a2dDocumentRenderStyle drawstyle)
render of overlay objects stored in m_overlayObjects specific to the view
Definition: drawer.cpp:2424
virtual wxPrintout * OnCreatePrintout(a2dPrintWhat typeOfPrint, const wxPageSetupDialogData &pageSetupData)
to create a a2dDrawingPrintOut, used to print a view or its document
Definition: drawer.cpp:720
#define wxDynamicCast(obj, className)
Define wxDynamicCast so that it will give a compiler error for unrelated types.
Definition: gen.h:75
objects with m_editingcopy or m_toolobject are skipped.
Definition: canobj.h:2809
Base class for all types of strokes, understood by a2dDrawer2D classes.
Definition: stylebase.h:378
void SetRoot(a2dDrawing *root, bool recurse=true)
Sets this object to a a2dCanvasDocument.
Definition: canobj.cpp:5933
bool SaveStartAt(a2dDocumentOutputStream &stream, const a2dDrawing *drawing, a2dCanvasObject *start)
saves as CVG starting at object start
Definition: xmlpars.cpp:344
bool m_frozen
buffer updating activity possible or not
Definition: drawer.h:1279
a2dTiles m_tiles
tiles on drawing surface, used to optimize update areas.
Definition: drawer.h:1458
int m_crosshairLengthX
crosshair cursor Length in X in pixels
Definition: drawer.h:1315
diagram is an appearance for a2dCameleon
Definition: cameleon.h:382
void AddPending(a2dIterC &ic)
search objects ( if nested recursive ) that have the pending flag Set
Definition: canobj.cpp:4521
void Clear()
All tiles become empty.
Definition: drawer.cpp:133
see a2dDrawingEvent
Definition: drawing.h:933
a2dFill m_gridfill
grid fill
Definition: drawer.h:1330
mouse event sent from a2dCanvasObject to itself
Definition: canglob.h:223
void ClearCorridorPath(bool uncapture)
Reset all corridor paths and uncapture object.
Definition: drawer.cpp:1549
Simple Memory manager for some objects which often create and destroy to replace OS-system calls...
Definition: a2dmemmgr.h:20
void SetDrawStyle(a2dDrawStyle drawstyle)
set drawstyle to use for drawing,
Definition: drawer2d.cpp:557
int m_y1
y1 in pixel coordinates
Definition: drawer.h:182
int WorldToDeviceY(double y) const
convert y from world to device coordinates
Definition: drawer2d.h:455
no special options
Definition: canobj.h:79
const a2dStroke * a2dBLACK_STROKE
global a2dStroke stock object for BLACK stroking
filter for tool related a2dCanvasObject&#39;s
Definition: canobj.h:2969
virtual void PopTransform(void)
Recall the previously saved user-to-world transform off the matrix stack.
Definition: drawer2d.cpp:480
const a2dAffineMatrix & GetTransformMatrix() const
get the matrix used to position the object
Definition: canobj.h:500
void OnBusyBegin(a2dCommandProcessorEvent &event)
do this at command start
Definition: drawer.cpp:1734
void SetRealScale(bool realScale)
If true use real scale else different scale by x and y.
Definition: drawer2d.h:656
void DrawRects(a2dDrawer2D *drawer)
draw optimized rectangles to given view in device coordinates.
Definition: drawer.cpp:189
double GetVisibleMinX() const
get Minimal X of the visible part in world coordinates
Definition: drawer2d.cpp:403
wxUint16 m_gridsize
grid point size
Definition: drawer.h:1369
wxUint32 GetDrawStyle()
get drawstyles used for drawing the document
Definition: canglob.h:577
filter for selected a2dCanvasObject&#39;s
Definition: canobj.h:2917
#define EVT_UPDATE_DRAWING(func)
event from a drawing when updated
Definition: drawing.h:988
wxBitmap GetBuffer() const
Return the buffer as a bitmap.
Definition: dcdrawer.h:60
int m_mouse_x
last mouse position
Definition: drawer.h:1324
~a2dDrawingPrintOut(void)
destructor
Definition: drawer.cpp:3707
simple canvas which takes as view the whole of the scrollable area. While a2dCanvas display and draws...
a2dCanvasObject * GetRootObject() const
get the root object, which holds the objects in the document
Definition: drawing.h:521
~a2dTiles()
destructor
Definition: drawer.cpp:122
const a2dFill * a2dBLACK_FILL
global a2dFill stock object for BLACK filling
int m_x1
x1 in pixel coordinates
Definition: drawer.h:180
void OnIdle(wxIdleEvent &event)
redraw and/or blit pending areas to the device
Definition: drawer.cpp:911
static a2dPropertyIdVoidPtr * PROPID_ToolObject
set for objects that act as tool object, when a tool is in action.
Definition: canobj.h:2678
wxUint32 m_documentDrawStyleRestore
to restore style after a temporary change.
Definition: drawer.h:1431
Ref Counted base object.
Definition: gen.h:1045
a2dTileBox(int x1=0, int y1=0, int x2=0, int y2=0)
constructor
Definition: drawer.cpp:74
a2dDrawing * GetRoot() const
get a2dCanvasDocument of the object.
Definition: canobj.h:952
void Enlarge(const double Marge)
enlarge with the given amount
Definition: bbox.cpp:162
void SetRenderDC(wxDC *dc)
set the DC that is used for rendering
Definition: dcdrawer.cpp:248
#define EVT_DO(func)
event sent from a2DocumentCommandProcessor when a command is initially done
Definition: comevt.h:795
double GetHitMarginWorld() const
Get HitMargin used to extend a hittest in world units.
Definition: drawer.cpp:739
virtual ~a2dDrawingPart()
destructor
Definition: drawer.cpp:639
virtual void DestroyClippingRegion()=0
set clipping region off
wxUint16 GetHitMarginDevice() const
hit marging in pixels.
Definition: canglob.h:609
Simple canvas using a whole view for all of the scrolled window.
Definition: cansim.h:54
int m_crosshairx
crosshair x
Definition: drawer.h:1309
int m_height
device size height
Definition: drawer.h:1387
void ConnectEvent(wxEventType type, wxEvtHandler *eventSink)
Definition: gen.cpp:876
void OnUpdate(a2dDrawingEvent &event)
depending on the hint value performs specific updating on the view.
Definition: drawer.cpp:1753
void OnBusyEnd(a2dCommandProcessorEvent &event)
do this at command end
Definition: drawer.cpp:1739
bool m_crosshair
is croshair visible
Definition: drawer.h:1306
a2dStroke m_gridstroke
grid stroke
Definition: drawer.h:1327
void SetDrawerStroke(const a2dStroke &stroke)
Used to set the current stroke.
Definition: drawer2d.cpp:565
virtual bool BlitPendingUpdateAreas()
blit pending update areas, that are already updated to the buffer, now to the screen.
Definition: drawer.cpp:1932
virtual void DrawPolygon(a2dVertexArray *points, bool spline=false, wxPolygonFillMode fillStyle=wxODDEVEN_RULE)
Draw polygon in world coordinates using pointarray.
Definition: drawer2d.cpp:1889
int toP(int tilexy)
convert internal tile to pixel coordinate tiles area
Definition: drawer.h:233
This class implements drawing functions for wxDC based drawing.
Definition: dcdrawer.h:43
virtual void Scroll(int dxy, bool yscroll, bool total)
scroll up down or left right
Definition: drawer.cpp:3398
void OnDrop(wxCoord x, wxCoord y, a2dDrawing *drawing)
used to drop a drawing object on the drawing part during Drag and Drop.
Definition: drawer.cpp:3452
double m_gridx
grid distance in x
Definition: drawer.h:1363
void Update(unsigned int how=(a2dCANVIEW_UPDATE_ALL|a2dCANVIEW_UPDATE_BLIT), wxObject *hintObject=NULL)
see OnUpdate
Definition: drawer.cpp:1744
#define EVT_REDO(func)
event sent from a2DocumentCommandProcessor when a command is redone
Definition: comevt.h:799
OVERLAP
Result of a a2dBoundingBox intersection or hittest.
Definition: bbox.h:24
record in update list of a2dDrawingPart.
Definition: drawer.h:64
a2dFill m_backgroundfill
background fill of canvas and background color of background fill in case of mono colour fill ...
Definition: drawer.h:1294
bool GetYaxis() const
get y axis orientation
Definition: drawer2d.h:280
const a2dFill * a2dWHITE_FILL
global a2dFill stock object for WHITE filling
void SetBackgroundFill(const a2dFill &backgroundfill)
background fill for the canvas
Definition: drawer.cpp:3131
bool OnPrintPage(int)
called for every page to print, for a2dDrawing in general just one.
Definition: drawer.cpp:3711
This class implements drawing functions for wxDC based drawing.
Definition: dcdrawer.h:203
void SetGrid(bool grid)
Set grid on/off.
Definition: drawer.h:905
a2dFill m_select2Fill
select style fill
Definition: drawer.h:1354
double GetVisibleMinY() const
get Minimal X of the visible part in world coordinates
Definition: drawer2d.cpp:408
void Expand(int x1, int y1, int x2, int y2)
expand a tile with this box
Definition: drawer.cpp:95
bool GetUpdatesPending()
returns true if some objects have changed recently within this document
Definition: drawing.cpp:424
int toT(int xy)
convert pixel to internal tile coordinate tiles area
Definition: drawer.h:236
void SetDocumentDrawStyle(wxUint32 drawstyle)
set drawstyles to use for drawing the document
Definition: drawer.cpp:1016
int ModT(int xy)
xy modules 256
Definition: drawer.h:239
a2dCameleonSymbolicRef
Definition: cameleon.h:874
bool m_valid
if set, true
Definition: drawer.h:177
bool SetCanvasToolContr(a2dToolContr *controller)
set toolcontroller ( reset with NULL )
Definition: drawer.cpp:785
virtual void UpdateArea(int x, int y, int width, int height, wxUint8 id=0)
update/redraw part of the buffer, using the given a2dDrawing and ShowObject within that root...
Definition: drawer.cpp:1999
vertex array of line and arc segments.
Definition: polyver.h:494
a2dCanvasObject is the base class for Canvas Objects.
Definition: canobj.h:371
static const a2dSignal sig_changedLayerVisibleInView
when one layer is set visible in a2dDrawingPart
Definition: drawer.h:1509
a2dAffineMatrix a2dIDENTITY_MATRIX
global a2dAffineMatrix to set/pass the identity matrix.
Definition: afmatrix.cpp:51
virtual void Render()
render the tool chain
Definition: tools.cpp:440
a2dStroke m_overlayStroke
overlay style stroke
Definition: drawer.h:1339
wxString m_title
title put above printout
Definition: drawer.h:2639
virtual void SetBufferSize(int w, int h)
sets buffersize ( if used ) for the a2dDrawer2D
Definition: drawer.cpp:755
static bool m_printAsBitmap
if set print a bitmap that was drawn into
Definition: drawer.h:2655
a2dCanvas * GetCanvas() const
Get the Display window of the a2dView. But casted to a a2dCanvas.
Definition: drawer.h:525
a2dDrawingPart * GetDrawingPart()
Get the a2dDrawingPart object that the controller is plugged into.
Definition: tools.h:104
int m_crosshairy
crosshair y
Definition: drawer.h:1312
bool m_printfittopage
If true, draw a view on all page without real scale.
Definition: drawer.h:1446
void PushIn(a2dCanvasObject *pushin)
set given canvasobject as show object, and store the current on the stack
Definition: drawer.cpp:3108
output handler for the CVG format.
Definition: xmlpars.h:103
#define A2D_PROPID_M(type, classname, propname, defaultval, mptr)
to define a get set property more easily
Definition: id.h:730
a2dCanvasObject * GetObject()
Get the current object.
Definition: canobj.h:3016
a2dLayers * GetLayerSetup()
Get the layersettings for the canvas.
Definition: drawing.h:506
a2dStroke m_selectStroke
select style stroke
Definition: drawer.h:1345
a2dCanvasObjectList * GetChildObjectList()
get the list where the child objects are stored in.
Definition: canobj.cpp:2551
a2dCanvas uses a2dCanvasView for displaying a view on a a2dCanvasDocument.
a2dStroke & GetSelect2Stroke()
Get Stroke to use for Selected2 a2dCanvasObject&#39;s.
Definition: canglob.cpp:894
void TransformPoint(double x, double y, double &tx, double &ty) const
Transform a point.
Definition: afmatrix.cpp:559
void SetObjectFilter(a2dCanvasObjectFilter *filter)
set object filter class.
Definition: canobj.h:3418
OVERLAP m_clip
how far this object in the view being rendered
Definition: canobj.h:3044
int m_x2
x2 in pixel coordinates
Definition: drawer.h:184
virtual void BlitBuffer(int x, int y, int width, int height, int xbuf, int ybuf)
blit part of the drawing buffer to the canvas
Definition: drawer.cpp:2154
int m_height
number of vertical tiles
Definition: drawer.h:274
wxUint32 m_documentDrawStyle
drawstyles to use when rendering document
Definition: drawer.h:1425
a2dCanvasObjectPtr m_top
top object for drawer object, from here the rendering starts
Definition: drawer.h:1291
a2dUpdateArea * m_rectPrevRow
prev row pointer to combine tiles into rectangles
Definition: drawer.h:189
bool m_drawframe
draw a frame around the page
Definition: drawer.h:2648
bool ProcessEvent(wxEvent &event)
process an event for the object, if the event is not handled by
Definition: tools.cpp:249
a2dLayerViewList m_layerRenderArray
which layer should be rendered ( visible and/or available )
Definition: drawer.h:1449
bool GetVisible()
is the layer visible
Definition: layerinf.cpp:341
static const a2dSignal sig_layersetupChanged
layer info changed id sent around when m_layersetup is changed.
Definition: drawing.h:771
a2dCanvasObject * PopOut()
pop last pushed canvasobject from the stack, now last becomes show object.
Definition: drawer.cpp:3114
set a2dCanvasObjects check flag when in view
Definition: algos.h:1235
void SetReverseOrder(bool revorder)
Set to draw layers in reverse order.
Definition: drawer.cpp:733
a2dDrawingPart * GetActiveDrawingPart()
return the currently/last active drawing part.
Definition: canglob.h:1262
a2dStroke m_crosshairStroke
stroke to use for crosshair
Definition: drawer.h:1321
filter for selected a2dCanvasObject&#39;s
Definition: canobj.h:2891
virtual double GetVisibleHeight() const
get Height of visible part in world coordinates
Definition: drawer2d.cpp:428
a2dPrintWhat m_typeOfPrint
type of print requested
Definition: drawer.h:2633
a2dCanvasObjectPtr m_endCorridorObject
when a corridor is active, this is set.
Definition: drawer.h:1285
bool Start(a2dCanvasObject *object)
Start traversing at object, returns true.
Definition: algos.cpp:2153
wxUint64 a2dCanvasObjectFlagsMask
mask flags for a2dCanvasObject
Definition: candefs.h:152
void SetDrawerFill(const a2dFill &fill)
Used to set the current fill.
Definition: drawer2d.cpp:621
void DrawTiles(a2dDrawer2D *drawer)
draw tiles to given view in device coordinates.
Definition: drawer.cpp:152
int GetMapY() const
Y mapping position in device coordinates.
Definition: drawer2d.h:407
int WorldToDeviceYRel(double y) const
convert y relative from world to device coordinates
Definition: drawer2d.h:465
static const a2dSignal sig_changedLayerAvailable
when an object is added to a layer, and therefore makes this layer available.
Definition: drawer.h:1507
static const a2dSignal sig_changedLayer
when an object is removed from a layer,
Definition: drawing.h:774
wxUint8 m_id
buffer id
Definition: drawer.h:99
bool m_xyRelToChildren
is set, m_x and m_y are supplied relative to the child objects ( object matrix m_world already applie...
Definition: canobj.h:297
a2dUpdateList * GenerateUpdateRectangles()
generate from files tiles a list of semi optimal covering rectangles
Definition: drawer.cpp:327
wxUint32 m_option
the way to hit/traverse the document.
Definition: canobj.h:299
bool AddObjectPendingUpdates(a2dCanViewUpdateFlagsMask how=a2dCANVIEW_UPDATE_PENDING)
recursive find pending objects and adds their areas to the updatelist
Definition: drawer.cpp:2920
bool GetIgnorePendingObjects()
get setting of ignore pending objects /sa GetUpdatesPending()
Definition: drawing.h:608
bool m_showorigin
showorigin?
Definition: drawer.h:1300
void SetCrossHairStroke(const a2dStroke &stroke)
set stroke for crosshair
Definition: drawer.cpp:1086
#define EVT_BEGINBUSY(func)
event sent from a2DocumentCommandProcessor when a command submit/execute is starting ...
Definition: comevt.h:806
bool Start(a2dObject *object)
object to start the algorithm
Definition: algos.cpp:193
virtual void SetDisplayWindow(wxWindow *display)
next to the base its m_display, this also sets m_drawer2d to this display
Definition: drawer.cpp:745
see a2dCanvasObjectMouseEvent
Definition: canglob.h:161
double DeviceToWorldY(double y) const
convert y from device to world coordinates
Definition: drawer2d.h:439
const a2dBoundingBox & Translate(a2dPoint2D &)
translate with given vector
Definition: bbox.cpp:370
double GetMinX() const
get minimum X of the boundingbox
Definition: bbox.cpp:304
void Init(int x1=0, int y1=0, int x2=0, int y2=0)
Initialize a tile.
Definition: drawer.cpp:83
virtual void DrawRoundedRectangle(double x, double y, double width, double height, double radius, bool pixelsize=false)
Draw RoundedRectangle in world coordinates.
Definition: drawer2d.cpp:2048
a2dDrawingPart * m_drawingPart
maping defined by this canvas
Definition: drawer.h:2636
void SetDrawStyle(a2dDocumentRenderStyle drawstyle)
set drawstyle used for rendering the document
Definition: canobj.h:3316
void AddPendingUpdateArea(a2dCanvasObject *obj, wxUint8 id=0, bool refsalso=true)
add pending update for the area that is the boundingbox of the given object
Definition: drawer.cpp:2891
void SetIgnorePendingObjects(bool onoff)
Switches ignorance of pending objects on and off.
Definition: drawing.cpp:432
bool m_mouseevents
enable/ disable mouse events handling by canvas
Definition: drawer.h:1288
static const a2dSignal sig_changedShowObject
Definition: drawer.h:1513
double m_scalelimit
limit scaling to this value (world/pixel)
Definition: drawer.h:2645
virtual void ResetStyle()
set a pre-defined style reseting cashed values.
Definition: drawer2d.cpp:545
#define forEachIn(listtype, list)
easy iteration for a2dlist
Definition: a2dlist.h:111
int m_y2
y2 in pixel coordinates
Definition: drawer.h:186
int m_width
device size width
Definition: drawer.h:1384
virtual void DrawPoint(double xc, double yc)=0
draw a single point
double m_printscalelimit
Set the scaling limit for printing, so that small stuff is not zoomed to full page.
Definition: drawer.h:1440
wxUint16 a2dPrintWhat
defines what to print
Definition: gen.h:4052
a2dHitOption
Enum for hit test options.
Definition: canobj.h:76
a2dCameleonInst to show one appearance of an a2dCameleon.
Definition: cameleon.h:272
void AddOverlayObject(a2dCanvasObject *obj)
add to list of overlay objects (must be children of m_top)
Definition: drawer.cpp:973
void OnComEvent(a2dComEvent &event)
called for a2dComEvent events.
Definition: drawer.cpp:1673
static const a2dCanvasObjectFlagsMask SELECTABLE
Definition: candefs.h:182
void SetHitMarginDevice(int pixels)
used to extend a hittest with the number of pixels.
Definition: canobj.cpp:596
#define EVT_COM_EVENT(func)
static wxEvtHandler for communication event
Definition: gen.h:564
layer settings for a a2dCanvasDocument Holds layers settings classes
int m_width
number of horizontal tiles
Definition: drawer.h:272
void SetAvailable()
check which layers do contain objects as seen from the ShowObject()
Definition: drawer.cpp:1641
virtual double GetVisibleWidth() const
get Width of visible part in world coordinates
Definition: drawer2d.cpp:423
Definition: bbox.h:26
#define wxStaticCast(obj, className)
The wxWindows 2.4.2 wxStaticCast is buggy. It evaluates its argument twice.
Definition: gen.h:123
Drawing context abstraction.
Definition: drawer2d.h:177
maintains a list of areas on a view to be redrawn.
Definition: drawer.h:111
a2dCanvasObject * GetShowObject() const
return pointer of then currently shown object on the drawer.
Definition: drawer.h:680
bool m_grid
grid on/off
Definition: drawer.h:1378
void SetDisableDrawing(bool disableDrawing)
when set, all drawing functions return immediately.
Definition: drawer2d.h:716
void SetDisableInvert(bool disableInvert)
when true, disable inversion of matrixes
Definition: canobj.h:3237
int GetHeight() const
get buffer/device height
Definition: drawer2d.h:395
void SetSpecificFlags(bool setOrClear, a2dCanvasObjectFlagsMask which)
set all bit flags in object that or true in mask to true or false
Definition: canobj.cpp:2645
int m_crosshairLengthY
crosshair cursor Length in Y in pixels
Definition: drawer.h:1318
void SetMouseEvents(bool onoff)
If not set do not process mouse events.
Definition: drawer.cpp:1081
static const a2dSignal sig_changedLayerInfo
when one layer its a2dLayerInfo has changed ( e.g. visible or order of rendering ) ...
Definition: layerinf.h:322
bool HasFilledTiles()
are there filled tiles available?
Definition: drawer.cpp:143
void SetActiveDrawingPart(a2dDrawingPart *part)
get the drawing part that has the focus/is active in a window.
Definition: canglob.cpp:1220
a2dCameleon * GetCameleon()
get referenced a2dCameleon
Definition: cameleon.cpp:1888
void SetPerLayerMode(bool value)
if set the rendering is done layers by layer from the top
Definition: canobj.h:3427
void Translate(double x, double y)
relative translate the object to position x,y in world coordinates
Definition: canobj.h:569
virtual void ShiftBuffer(int dxy, bool yshift)
quick scroll over small distance
Definition: drawer2d.h:271
wxStringInputStream a2dDocumentStringInputStream
string input stream based wxStreams
Definition: gen.h:3452
bool Load(a2dDocumentStringInputStream &stream, a2dDrawing *doc, a2dCanvasObject *parent)
reading a CVG document and add the contents as children to a given a2dCanvasObject parent...
Definition: xmlpars.cpp:146
bool m_isHit
in the end if there was a hit (even if not processed event)
Definition: canobj.h:315
Contains graphical drawing context specific classes. a2dDcDrawer and derived classes are used for dra...
void SetShowObjectAndRender(a2dCanvasObject *obj)
Used temporarely in rendering bitmas or in printing, to Set the show object and redraw the whole part...
Definition: drawer.cpp:3069
wxUint16 GetLayer() const
Returns the layer index where this object is drawn upon.
Definition: canobj.h:2368
a2dUpdateList m_updateareas
list of rectangles that need to be blited to the screen.
Definition: drawer.h:1403
int WorldToDeviceX(double x) const
convert x from world to device coordinates
Definition: drawer2d.h:453
a2dDrawer2D * GetDrawer2D()
get the internal m_drawer2D that is used for rendering the document
Definition: drawer.h:1125
contains the layer properties for one layer,
Definition: layerinf.h:41
virtual void DrawLine(double x1, double y1, double x2, double y2)
Draw line in world coordinates.
Definition: drawer2d.cpp:2167
void DeleteAllPendingAreas()
pending update areas in the update list are deleted.
Definition: drawer.cpp:1855
bool CheckMask(a2dCanvasObjectFlagsMask mask) const
Compares all flags in object to the given mask and return true is the same.
Definition: canobj.cpp:2665
static const a2dCanvasObjectFlagsMask IsOnCorridorPath
Definition: candefs.h:204
bool GetReverseOrder() const
Get Setting for draw layers in reverse order.
Definition: canglob.h:643
find the a2dcanvasObject, and set the corridor flag on the path to it.
Definition: algos.h:1121
void SetLayerCheck(wxUint16 layer)
signals the need to check the given layer for visibility/availibility as seen from this drawing part...
Definition: drawer.cpp:1635
Tappear * GetAppearance(bool autoCreate=false)
Get a specific a2dAppear derived class instance from here.
Definition: cameleon.h:666
void Disable()
can be used by a2dCanvas or a2dDrawingPart to disable this class
Definition: tools.cpp:134
a2dFill & GetSelect2Fill()
Get Fill to use for Selected2 a2dCanvasObject&#39;s.
Definition: canglob.cpp:899
wxUint16 m_gridthres
threshold for grid.
Definition: drawer.h:1375
a2dStroke m_fixStroke
fixed style stroke
Definition: drawer.h:1333
void ClearCursorStack()
clear the stack of cursor, and set display cursor ARROW.
Definition: drawer.cpp:1074
Contains a2dDrawing Class to hold a drawing.
a2dFill m_selectFill
select style fill
Definition: drawer.h:1348
void ResetFixedStyle()
only way to reset style after SetDrawStyle( a2dFIXED*** );
Definition: drawer2d.cpp:684
a2dCanvasObject * IsHitWorldPath(double x, double y, int layer=wxLAYER_ALL, a2dHitOption option=a2dCANOBJHITOPTION_NONE, bool filterSelectableLayers=false)
do a hittest on the view at coordinates x,y
Definition: drawer.cpp:1593
void RedrawPendingUpdateAreas(bool noblit=false)
redraw the pending update areas to the buffer given in device coordinates.
Definition: drawer.cpp:1876
set a2dCanvasObjects flags in a hierarchy of a a2dCanvasDocument
Definition: algos.h:486
wxUint16 m_border
border zoomout but leaf around a border of this amount of pixels.
Definition: drawer.h:1297
~a2dTileBox()
destructor
Definition: drawer.cpp:79
corridor as a direct event path to a a2dCanvasObject
Definition: objlist.h:313
void SetDisplay(wxWindow *window)
the display
Definition: drawer2d.h:208
defines common settinsg for a habitat for a set of a2dCameleons.
Definition: canglob.h:439
a2dCanvasObject * ChildIsHitWorld(a2dIterC &ic, a2dHitEvent &hitEvent, bool filterSelectableLayers=false)
Do hittest on children.
Definition: canobj.cpp:3289
void Thaw(bool update)
to release Freeze()
Definition: drawer.cpp:1031
double m_gridy
grid distance in y
Definition: drawer.h:1366
const a2dPrintWhat a2dPRINT_PreviewDrawingPart
preview print a2dDrawing Part
Definition: drawing.cpp:78
A 2x3 affine matrix class for 2D transformations.
Definition: afmatrix.h:53
bool GetResult()
depending upon derived class implementation.
Definition: gen.h:3979
virtual bool HasAlpha()
does a derived drawer have alpha support or not
Definition: drawer2d.h:783
void OnCharEvent(wxKeyEvent &event)
normally sent from wxWindow containing the view, via its ProcessEvent(wxEvent&amp; event) ...
Definition: drawer.cpp:1296
a2dCanvas is used to display one of the a2dCanvasObjects which are part of a a2dCanvasDocument object...
Definition: canvas.h:68
void Set_UpdateAvailableLayers(bool value)
Sets a flag for updating available layers checking, which makes sure layers will be checked first whe...
Definition: drawer.h:583
void OnPropertyChanged(const a2dPropertyId *id)
This function is called after a property changed.
Definition: drawer.cpp:460
a2dDocumentRenderStyle m_overlayDrawStyle
drawstyles to use when rendering overlay
Definition: drawer.h:1428
a storage for a a tiled area
Definition: drawer.h:206
while iterating a a2dCanvasDocument, this holds the context.
Definition: canobj.h:3212
bool m_reverse_order
draw in reverse order if set
Definition: drawer.h:1463
int GetWidth() const
get buffer/device width
Definition: drawer2d.h:392
Contains graphical drawing context specific classes. a2dDrawer2D and derived classes are used for dra...
virtual void PaintGrid(int x, int y, int width, int height)
Function to draw the grid.
Definition: drawer.cpp:3217
static const a2dSignal sig_changedLayers
when more layers changed ( rerendering view is needed).
Definition: drawer.h:1505
void UpdateViewDependentObjects(a2dIterC &ic)
update the transform matrix for objects with property &#39;PROPID_viewDependent&#39;
Definition: canobj.cpp:4605
a2dCanvasObject * GetCaptured() const
are events redirected to a captured corridor? if so return the captured object in it...
Definition: objlist.h:347
struct for how a single object on one layer was hit
Definition: polyver.h:38
vector< a2dTileBox > m_tiles
array of tiles ( normally m_width * m_height )
Definition: drawer.h:284
bool Get_UpdateAvailableLayers() const
update layers available needed?
Definition: drawer.h:570
a2dWalker based algorithms
void MapBbox(const a2dAffineMatrix &matrix)
Definition: bbox.cpp:445
Definition: bbox.h:28
set layers available in a2dCanvasView as found in document
Definition: algos.h:114
special a2dCanvasObject to make a multi view hierachy.
a2dStroke & GetSelectStroke()
Get Stroke to use for Selected a2dCanvasObject&#39;s.
Definition: canglob.cpp:874
a2dBoundingBox GetMappedBbox(a2dIterC &ic, bool withExtend=true)
first translate boundingbox with cworld and recalculate at new position
Definition: canobj.cpp:3256
void OnMouseEvent(wxMouseEvent &event)
normally sent from wxWindow containing the view, via its ProcessEvent(wxEvent&amp; event) ...
Definition: drawer.cpp:1131
virtual void SetClippingRegionDev(wxCoord minx, wxCoord miny, wxCoord maxx, wxCoord maxy)=0
set clipping region using x y values in device coordinates
std::vector< a2dLayerInfoPtr > & GetReverseOrderIndex()
return array index on ReverseOrder
Definition: layerinf.cpp:569
a2dSmrtPtr< a2dToolContr > m_toolcontroller
toolscontroller plugged in as first event handler
Definition: drawer.h:1409
static const a2dCanvasObjectFlagsMask VISIBLE
Definition: candefs.h:186
void FillTiles(const wxRect &rect, bool expand=true)
fill tiles covering the rect given see FillTiles( int x, int y, int w, int h, bool expand ) ...
Definition: drawer.cpp:216
void SetGridStroke(const a2dStroke &gridstroke)
set stroke used for grid drawing
Definition: drawer.cpp:3137
void SetPrintMode(bool onOff)
to modify drawing feature when used as context for printing
Definition: drawer2d.h:696
a2dCanvasCommandProcessor * GetCanvasCommandProcessor()
get a pointer to the command processor
Definition: drawing.cpp:375
virtual void BeginDraw()=0
start to draw on this context (used to initialize a specific drawer)
double DeviceToWorldX(double x) const
convert x from device to world coordinates
Definition: drawer2d.h:437
virtual void UpdateCrossHair(int x, int y)
blit old areas to remove last drawn crosshair and draw the cross hair at this new position...
Definition: drawer.cpp:3361
filter for selected a2dCanvasObject&#39;s
Definition: canobj.h:2943
This is the base class for all kinds of property id&#39;s for a2dObject.
Definition: id.h:154
double GetWidth() const
returns width of the boundingbox
Definition: bbox.cpp:328
An object of this class will update a a2dIterC with the required information.
Definition: canobj.h:3123
a2dCanvasObject * SetShowObject(const wxString &name)
set object available in the a2dDrawing to be shown on the drawer
Definition: drawer.cpp:2947
wxUint16 m_hitmargin
how close does a hit need to be to the object you are trying to hit.
Definition: drawer.h:1419
a2dDocumentRenderStyle GetSelectDrawStyle() const
returns draw style to be used for selected object
Definition: canglob.h:572
void BlitBuffer()
blit whole buffer to device
Definition: drawer2d.cpp:183
void SetLayer(wxUint16 layer)
set the layer that is to be rendered
Definition: canobj.h:3288
void AddPoint(const a2dPoint2D &point, bool atEnd=true)
add point to end or begin
Definition: polyver.cpp:714
a2dCanvasObject * IsHitWorld(double x, double y, int layer=wxLAYER_ALL, a2dHitOption option=a2dCANOBJHITOPTION_NONE, bool filterSelectableLayers=false)
do a hittest on the view at coordinates x,y
Definition: drawer.cpp:1565
bool Start(a2dCanvasObject *object, bool setTo)
start removing properties from the object given, and down.
Definition: algos.cpp:784
#define EVT_ENDBUSY(func)
event sent from a2DocumentCommandProcessor when a command submit/execute is ending ...
Definition: comevt.h:808
bool m_printtitle
if true, a printout is done with title (document name (description?)), otherwise not ...
Definition: drawer.h:1434
const a2dStroke * a2dTRANSPARENT_STROKE
global a2dStroke stock object for TRANSPARENT stroking
A list class for reference counted objects.
Definition: smrtptr.h:653
Event sent to a2dCommandProcessor.
Definition: comevt.h:701
bool m_gridatfront
grid drawn at front or back
Definition: drawer.h:1303
virtual void DrawOrigin()
Function to draw the origin.
Definition: drawer.cpp:3199
see a2dComEvent
Definition: gen.h:371
virtual bool ProcessCanvasObjectEvent(wxEvent &event, bool &isHit, double x, double y, int margin, int layer=wxLAYER_ALL)
Corridor and captured object event processing.
Definition: drawer.cpp:1304
void RemoveOverlayObject(a2dCanvasObject *obj)
remove from the list of overlay objects (must be children of m_top)
Definition: drawer.cpp:979
void SetEndCorridorObject(a2dCanvasObject *endCorridorObject)
use in combination with the a2dIterC class to set a corridor path for events.
Definition: drawer.cpp:1041
bool DisconnectEventAll(wxEvtHandler *eventSink)
Remove all dynamic events in classA, going to classB (eventSink)
Definition: gen.cpp:1021
wxString m_filename
filename put below printout
Definition: drawer.h:2642
bool m_printfilename
if true, a printout is done with filename (document file path), otherwise not
Definition: drawer.h:1437
bool FindAndSetCorridorPath(a2dCanvasObject *findObject, bool capture)
Find the show-object child object, set the path to the given child object and capture it...
Definition: drawer.cpp:1516
double GetInitialSizeX()
get size for view in userunits, when still empty
Definition: drawing.h:534
base classes for tools and controller on top of the tools.
bool m_recur
to prevent recursive updates
Definition: drawer.h:1406
The a2dBoundingBox class stores one a2dBoundingBox of a a2dCanvasObject.
Definition: bbox.h:39
std::vector< a2dLayerInfoPtr > & GetOrderIndex()
return array index on Order
Definition: layerinf.cpp:562
bool Invert(void)
Invert matrix.
Definition: afmatrix.cpp:197
a2dDrawingPart(int width=1000, int height=1000)
constructor
Definition: drawer.cpp:501
void SetCorridorPath(const a2dCorridor &corridor)
find object on the current corridor path.
Definition: drawer.cpp:1534
a2dTileBox tile(int i)
get tile at index i
Definition: drawer.h:277
double GetMinY() const
get minimum Y of the boundingbox
Definition: bbox.cpp:310
a2dDrawing * GetDrawing() const
get drawing via top object
Definition: drawer.cpp:726
void UpdateViewDependentObjects()
update the transform matrix for objects with property &#39;PROPID_viewDependent&#39;
Definition: drawer.cpp:2288
virtual void EndDraw()=0
end drawing on this context (used to reset a specific drawer)
the a2dDrawingPart is a a2dView specially designed for displaying parts of a a2dDrawing. It uses a a2dDrawer2D to actually redraw things from the document, by giving that a2dDrawer2D as drawing context to the document, and telling the document to redraw a certain rectangular area. At that last is what this class is for. It optimizes the areas to be redrawn after object in the document were changed. To do that it combines redraw areas to a minimal set of redrawing areas. All the administration for this and the way things will be redrawn is from this view.
bool AddPendingUpdatesOldNew()
adds current and future boundingbox of the objects with pending flag set, to the pendinglist of all a...
Definition: drawing.cpp:525
object not fitting the mask are drawn blind.
Definition: canobj.h:2830
a2dFill m_highLightFill
highLight style fill
Definition: drawer.h:1360
void SetCaptured(a2dCanvasObject *captured)
set the object that is captured for events in the a2dDrawing.
Definition: drawer.h:638
Input handler for the CVG format.
Definition: xmlpars.h:59
virtual void SetBufferSize(int w, int h)=0
Change the buffer size.
basetype GetPropertyValue(const a2dObject *obj) const
Get the property value in obj.
Definition: id.inl:325
a2dCanvasGlobal * a2dCanvasGlobals
global a2dCanvasGlobal to have easy access to global settings
Definition: canglob.cpp:1234
virtual void DrawCircle(double x, double y, double radius)
Draw Circle in world coordinates.
Definition: drawer2d.cpp:2116
a2dStroke m_select2Stroke
select style stroke
Definition: drawer.h:1351
#define EVT_UNDO(func)
event sent from a2DocumentCommandProcessor when a command is undone
Definition: comevt.h:797
static a2dPropertyIdBool * PROPID_ToolDecoration
set for objects that act as tool decorations, when a tool is in action.
Definition: canobj.h:2675
filter on this layer and mask.
Definition: canobj.h:2780
void SetCrossHair(bool onoff)
set enable crosshair cursor
Definition: drawer.cpp:1091
The a2dToolContr is the base class for Tool controller classes.
Definition: tools.h:87
const a2dPrintWhat a2dPRINT_PrintDrawingPart
print a2dDrawing Part
Definition: drawing.cpp:77
This template class is for property ids with a known data type.
Definition: id.h:477
wxUint32 GetDocumentDrawStyle()
get drawstyles used for drawing the document
Definition: drawer.h:1141
void Reset()
Reset this object for beeing reused. It will keep the drawer but NULL object infos.
Definition: canobj.cpp:588
wxRect GetAbsoluteArea(a2dIterC &ic, int inflate=2)
Get absolute occupied area in the device coordinates.
Definition: canobj.cpp:3199
virtual void RenderTopObject(wxUint32 documentDrawStyle, wxUint8 id)
does render the top object in the given style.
Definition: drawer.cpp:2306
bool m_update_available_layers
flag to updatelayers that are available.
Definition: drawer.h:1455
void SetShowOrigin(bool show)
Set showorigin on/off.
Definition: drawer.h:925
void SetDrawer2D(a2dDrawer2D *drawer2d, bool noDelete=false)
set the internal m_drawer2D to be used for rendering the document
Definition: drawer.cpp:765
void Append(a2dCanvasObject *obj)
append a a2dCanvasObject to the childobjects
Definition: canobj.cpp:6224
a2dStroke m_highLightStroke
highLight style stroke
Definition: drawer.h:1357
bool m_virtualarea_set
is the virtual area set already (used during startup)
Definition: drawer.h:1381
a2dFill & GetSelectFill()
Get Fill to use for Selected a2dCanvasObject&#39;s.
Definition: canglob.cpp:879
a2dTiles(int width, int height)
constructor
Definition: drawer.cpp:116
a2dDocumentRenderStyle
Define the manner in which a2dCanvasView draws the document to the device.
Definition: candefs.h:84
to print what is displayed on a a2dDrawingPart or the whole document as seen from the showobject of t...
Definition: drawer.h:2567
void PopCursor()
pop a cursor from the cursor stack, and set display cursor to back
Definition: drawer.cpp:1059
a2dFill m_fixFill
fixed style fill
Definition: drawer.h:1336
wxEvent * m_event
event to process in case of event processing call
Definition: canobj.h:309
const a2dAffineMatrix & GetMappingMatrix()
get the world-to-device (aka mapping) matrix
Definition: drawer2d.h:478
bool m_printframe
If true, draw a frame around printouts.
Definition: drawer.h:1443
void ToolWorldToMouse(double xWorld, double yWorld, int &x, int &y)
Definition: drawer.cpp:1114
a2dCanvasObjectPtr m_capture
object that is receiving events
Definition: drawer.h:1282
void MouseToToolWorld(int x, int y, double &xWorldLocal, double &yWorldLocal)
Definition: drawer.cpp:1097
int GetMapX() const
X mapping position in device coordinates.
Definition: drawer2d.h:404
double DeviceToWorldXRel(double x) const
convert x relative from device to world coordinates
Definition: drawer2d.h:444
virtual void SetMappingWidthHeight(double vx1, double vy1, double width, double height)
Give the virtual size to be displayed, the mapping matrix will be calculated.
Definition: drawer2d.cpp:333
void ClearPushInStack()
mak push in stack empty
Definition: drawer.cpp:3126
double GetInitialSizeY()
get size for view in userunits, when still empty
Definition: drawing.h:537
a2dBoundingBox & GetBbox()
get boundingbox in world coordinates exclusive stroke width relative to its parent ...
Definition: canobj.cpp:3175
structure to give as parameter to member functions of a2dCanvasObject
Definition: canobj.h:252
Contain one drawing as hierarchical tree of a2dCanvasObject&#39;s.
Definition: drawing.h:434
void SetMappingShowAll()
use the boundingbox of the ShowObject to set the mapping such that it will be displayed completely on...
Definition: drawer.cpp:3149
virtual void PushIdentityTransform()
push no transform, to draw directly in device coordinates
Definition: drawer2d.cpp:469
a2dFill m_overlayFill
overlay style fill
Definition: drawer.h:1342
a2dDrawingPrintOut(const wxPageSetupDialogData &pageSetupData, a2dDrawingPart *drawingPart, const wxString &title, const wxString &filename, a2dPrintWhat typeOfPrint, bool drawframe, double scalelimit, bool fitToPage)
initialize mapping based on an existing canvas
Definition: drawer.cpp:3694
static void SetIgnoreAllSetpending(bool value=true)
set static IgnoreAllSetpending flag
Definition: canobj.h:2307
const a2dFill * a2dTRANSPARENT_FILL
global a2dFill stock object for TRANSPARENT filling
general canvas module declarations and classes
virtual bool ProcessEvent(wxEvent &event)
Special event handling for a2dDrawingPart class.
Definition: drawer.cpp:803
#define a2dREFOBJECTPTR_KEEPALIVE
Definition: gen.h:1631
void GetClippingBox(double &x, double &y, double &w, double &h) const
what is the current clipping region in world coordinates
Definition: drawer2d.cpp:3006
drawer.cpp Source File -- Sun Oct 12 2014 17:04:16 -- Sun Oct 12 2014 -- 1.8.5 -- wxArt2D -- . -- Main Page Reference Documentation