00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "a2dprec.h"
00012
00013 #ifdef __BORLANDC__
00014 #pragma hdrstop
00015 #endif
00016
00017 #ifndef WX_PRECOMP
00018 #include "wx/wx.h"
00019 #endif
00020
00021 #include "wx/canvas/layerinf.h"
00022 #include "wx/canvas/drawer.h"
00023
00024 #include "wx/canvas/candoc.h"
00025 #include "wx/canvas/cancom.h"
00026 #include "wx/canvas/canvas.h"
00027 #include "wx/canvas/cansim.h"
00028 #include "wx/canvas/tools.h"
00029 #include "wx/artbase/drawer2d.h"
00030 #include "wx/artbase/dcdrawer.h"
00031 #include "wx/canvas/canglob.h"
00032 #include "wx/canvas/algos.h"
00033
00034 #include <wx/wfstream.h>
00035
00036 #define CROSS_HAIR_X 300
00037 #define CROSS_HAIR_Y 300
00038
00039
00040
00041
00042
00043 a2dCursorStack::a2dCursorStack()
00044 {
00045 }
00046
00047
00048
00049
00050 WX_DEFINE_LIST(a2dUpdateListBase);
00051
00052
00053 #ifdef CLASS_MEM_MANAGEMENT
00054 a2dMemManager a2dUpdateList::sm_memManager(wxT("a2dUpdateList memory manager"));
00055 #endif //CLASS_MEM_MANAGEMENT
00056
00057
00058
00059
00060 a2dTileBox::a2dTileBox(int x1, int y1, int x2, int y2 )
00061 {
00062 Init(x1,y1,x2,y2);
00063 }
00064
00065 a2dTileBox::~a2dTileBox()
00066 {
00067 }
00068
00069 void a2dTileBox::Init(int x1, int y1, int x2, int y2 )
00070 {
00071 m_x1 = x1;
00072 m_y1 = y1;
00073 m_x2 = x2;
00074 m_y2 = y2;
00075 m_rectPrevRow = NULL;
00076 m_valid = false;
00077 if ( m_x1 != m_x2 && m_y1 != m_y2 )
00078 m_valid = true;
00079 }
00080
00081 void a2dTileBox::Expand( int x1, int y1, int x2, int y2 )
00082 {
00083 if (!m_valid)
00084 {
00085 m_x1 = x1; m_y1 = y1;
00086 m_x2 = x2; m_y2 = y2;
00087 }
00088 else
00089 {
00090 m_x1 = wxMin(m_x1, x1);
00091 m_x2 = wxMax(m_x2, x2);
00092 m_y1 = wxMin(m_y1, y1);
00093 m_y2 = wxMax(m_y2, y2);
00094 }
00095 if ( m_x1 != m_x2 && m_y1 != m_y2 )
00096 m_valid = true;
00097 }
00098
00099
00100
00101
00102 a2dTiles::a2dTiles(int width, int height): m_tiles( width * height )
00103 {
00104 m_width = width;
00105 m_height = height;
00106 }
00107
00108 a2dTiles::~a2dTiles()
00109 {
00110 }
00111
00112 void a2dTiles::SetSize(int width, int height)
00113 {
00114 m_tiles.resize( width * height );
00115 m_width = width;
00116 m_height = height;
00117 }
00118
00119 void a2dTiles::Clear()
00120 {
00121 int t;
00122 for (t = 0; t < m_tiles.size(); t++)
00123 {
00124 m_tiles[t].m_valid = false;
00125 m_tiles[t].m_rectPrevRow = NULL;
00126 }
00127 }
00128
00129 bool a2dTiles::HasFilledTiles()
00130 {
00131 int t;
00132 for (t = 0; t < m_tiles.size(); t++)
00133 if ( m_tiles[t].m_valid == true )
00134 return true;
00135 return false;
00136 }
00137
00138 void a2dTiles::DrawTiles( a2dDrawer2D* drawer )
00139 {
00140 int x,y;
00141 drawer->PushIdentityTransform();
00142
00143 drawer->SetDrawerStroke( a2dStroke( wxColour(0,0,0),1 ) );
00144
00145 for (y = 0; y < m_height; y++)
00146 {
00147 drawer->DrawLine( 0, toP(y), toP(m_width), toP(y) );
00148 for (x = 0; x < m_width; x++)
00149 {
00150 drawer->DrawLine( toP(x), 0, toP(x), toP(m_height) );
00151 }
00152 }
00153
00154 drawer->SetDrawerStroke( a2dStroke( wxColour(210,22,25),2 ) );
00155 drawer->SetDrawerFill( a2dFill( wxColour(10,187,15), a2dFILL_HORIZONTAL_HATCH ) );
00156
00157 for (y = 0; y < m_height; y++)
00158 {
00159 for (x = 0; x < m_width; x++)
00160 {
00161 a2dTileBox box = m_tiles[ x + y*m_width ];
00162 if ( box.m_valid )
00163 {
00164 int x1 = toP(x) + box.m_x1;
00165 int y1 = toP(y) + box.m_y1;
00166 int x2 = toP(x) + box.m_x2;
00167 int y2 = toP(y ) + box.m_y2;
00168 drawer->DrawRoundedRectangle( x1, y1, x2 - x1, y2 - y1, 0 );
00169 }
00170 }
00171 }
00172 drawer->PopTransform();
00173 }
00174
00175 void a2dTiles::DrawRects( a2dDrawer2D* drawer )
00176 {
00177 drawer->PushIdentityTransform();
00178
00179 a2dUpdateList* a2dTiles = GenerateUpdateRectangles();
00180
00181 a2dUpdateList::compatibility_iterator nodeb = a2dTiles->GetFirst();
00182 while (nodeb)
00183 {
00184 a2dUpdateArea* uobj = nodeb->GetData();
00185
00186 int x,y,width,height;
00187 x = uobj->x;
00188 y = uobj->y;
00189 width = uobj->width;
00190 height = uobj->height;
00191
00192 drawer->DrawRoundedRectangle( x, y, width, height, 0 );
00193
00194 nodeb = nodeb->GetNext();
00195 }
00196
00197 drawer->PopTransform();
00198 a2dTiles->DeleteContents( true );
00199 delete a2dTiles;
00200 }
00201
00202 void a2dTiles::FillTiles( const wxRect& rect, bool expand )
00203 {
00204 FillTiles( rect.x, rect.y, rect.width, rect.height, expand );
00205 }
00206
00207 void a2dTiles::FillTiles( int xr, int yr, int w, int h, bool expand )
00208 {
00209 int x, y, x1, y1, x2, y2;
00210
00211 if ( !w|| !h )
00212 return;
00213
00214 int widthPix = m_width * a2d_TILESIZE;
00215 int heightPix = m_height * a2d_TILESIZE;
00216
00217 if (xr < 0)
00218 {
00219 w += xr;
00220 xr = 0;
00221 }
00222 if (w <= 0) return;
00223
00224 if (yr < 0)
00225 {
00226 h += yr;
00227 yr = 0;
00228 }
00229 if (h <= 0) return;
00230
00231 if (xr+w > widthPix )
00232 {
00233 w = widthPix - xr;
00234 }
00235 if (w <= 0) return;
00236
00237 if (yr+h > heightPix )
00238 {
00239 h = heightPix - yr;
00240 }
00241 if (h <= 0) return;
00242
00243 if ( !expand )
00244 Clear();
00245
00246 x1 = toT( xr );
00247 y1 = toT( yr );
00248 x2 = toT( xr + w + a2d_TILESIZE );
00249 y2 = toT( yr + h + a2d_TILESIZE );
00250
00251 int width = x2 - x1;
00252 int height = y2 - y1;
00253
00254 int tx1, ty1, tx2, ty2;
00255
00256
00257 tx1 = ModT(xr);
00258 ty1 = ModT(yr);
00259
00260 tx2 = ModT( xr + w );
00261 ty2 = ModT( yr + h );
00262 if (height == 1)
00263 {
00264 if (width == 1)
00265 m_tiles[ x1 + y1*m_width ].Expand( tx1, ty1, tx2, ty2 );
00266 else
00267 {
00268 int ti = x1 + y1*m_width;
00269 m_tiles[ ti++ ].Expand( tx1, ty1, a2d_TILESIZE-1, ty2 );
00270 for (x = 1; x < width-1; x++)
00271 m_tiles[ ti++ ].Expand(0, ty1, a2d_TILESIZE-1, ty2);
00272 m_tiles[ ti++ ].Expand( 0, ty1, tx2, ty2 );
00273 }
00274 }
00275 else
00276 {
00277 if (width == 1)
00278 {
00279 m_tiles[ x1 + y1*m_width ].Expand( tx1, ty1, tx2, a2d_TILESIZE-1 );
00280 for ( y = 1; y < height-1; y++)
00281 m_tiles[ x1 + (y1+y)*m_width ].Expand( tx1, 0, tx2, a2d_TILESIZE-1);
00282 m_tiles[ x1 + (y1+y)*m_width ].Expand( tx1, 0, tx2, ty2 );
00283 }
00284 else
00285 {
00286
00287 int ti = x1 + y1*m_width;
00288 m_tiles[ ti++ ].Expand( tx1, ty1, a2d_TILESIZE-1, a2d_TILESIZE-1 );
00289 for (x = 1; x < width-1; x++)
00290 m_tiles[ ti++ ].Expand( 0, ty1, a2d_TILESIZE-1, a2d_TILESIZE-1 );
00291 m_tiles[ ti++ ].Expand( 0, ty1, tx2, a2d_TILESIZE-1 );
00292
00293
00294 for (y = 1; y < height-1; y++)
00295 {
00296 ti = x1 + (y1+y)*m_width;
00297 m_tiles[ ti++ ].Expand( tx1, 0, a2d_TILESIZE-1, a2d_TILESIZE-1 );
00298 for (x = 1; x < width-1; x++)
00299 m_tiles[ ti++ ].Expand( 0, 0, a2d_TILESIZE-1, a2d_TILESIZE-1 );
00300 m_tiles[ ti++ ].Expand(0, 0, tx2, a2d_TILESIZE-1 );
00301 }
00302
00303 ti = x1 + (y1+y)*m_width;
00304
00305 m_tiles[ ti++ ].Expand( tx1, 0, a2d_TILESIZE-1, ty2 );
00306 for (x = 1; x < width-1; x++)
00307 m_tiles[ ti++ ].Expand( 0, 0, a2d_TILESIZE-1, ty2 );
00308 m_tiles[ ti++ ].Expand( 0, 0, tx2, ty2 );
00309 }
00310 }
00311 }
00312
00313 a2dUpdateList* a2dTiles::GenerateUpdateRectangles()
00314 {
00315 a2dUpdateList* rects = new a2dUpdateList();
00316
00317 GenerateUpdateRectangles( rects, 0 );
00318
00319 return rects;
00320 }
00321
00322 void a2dTiles::GenerateUpdateRectangles( a2dUpdateList* rects, wxUint8 id )
00323 {
00324 int x1, y1, x2, y2;
00325
00326 a2dTileBox tile;
00327
00328 int tilei,lefttilei;
00329 int x, y;
00330 tilei = 0;
00331 for (y = 0; y < m_height; y++)
00332 {
00333 for (x = 0; x < m_width; x++)
00334 {
00335 tile = m_tiles[ tilei ];
00336 if ( tile.m_valid )
00337 {
00338 x1 = toP(x) + tile.m_x1;
00339 y1 = toP(y) + tile.m_y1;
00340 y2 = toP(y) + tile.m_y2;
00341
00342 lefttilei = tilei;
00343
00344
00345
00346 tile = m_tiles[tilei];
00347 while (x != m_width - 1 &&
00348 tile.m_x2 == (a2d_TILESIZE-1) &&
00349 m_tiles[tilei + 1].m_x1 == 0 &&
00350 tile.m_y1 == m_tiles[tilei + 1].m_y1 &&
00351 tile.m_y2 == m_tiles[tilei + 1].m_y2
00352 )
00353 {
00354 tilei++;
00355 tile = m_tiles[tilei];
00356 x++;
00357 }
00358 x2 = toP(x) + tile.m_x2;
00359
00360
00361 if ((x1 ^ x2) | (y1 ^ y2))
00362 {
00363 a2dUpdateArea* prevRows = m_tiles[lefttilei].m_rectPrevRow;
00364 if ( prevRows &&
00365 x1 == prevRows->x &&
00366 x2 == prevRows->x + prevRows->width &&
00367 y1 == prevRows->y + prevRows->height +1
00368 )
00369 {
00370
00371 prevRows->height = y2 - prevRows->y;
00372 }
00373 else
00374 {
00375
00376 prevRows = new a2dUpdateArea( x1, y1, x2 - x1, y2 - y1, id );
00377 rects->Append( prevRows );
00378 }
00379
00380
00381
00382 if (y != m_height - 1 )
00383 m_tiles[lefttilei + m_width].m_rectPrevRow = prevRows;
00384 }
00385 }
00386 tilei++;
00387 }
00388 }
00389 }
00390
00391
00392
00393
00394 #ifdef CLASS_MEM_MANAGEMENT
00395 a2dMemManager a2dUpdateArea::sm_memManager(wxT("a2dUpdateArea memory manager"));
00396 #endif //CLASS_MEM_MANAGEMENT
00397
00398 a2dUpdateArea::a2dUpdateArea(int x, int y, int width, int height, wxUint8 id ):wxRect(x,y,width,height)
00399 {
00400 m_update_done = false;
00401 m_update_direct = false;
00402 m_id = id;
00403 }
00404
00405 a2dUpdateArea::~a2dUpdateArea()
00406 {
00407 }
00408
00409
00410
00411
00412
00413
00414 #if wxUSE_PRINTING_ARCHITECTURE
00415
00416 a2dViewPrintout::a2dViewPrintout( a2dCanvasView* drawingView,const wxString& title, const wxString& filename, a2dCommand* typeOfPrint, bool drawframe, double scalelimit, bool fitToPage ) : a2dDocumentPrintout( drawingView, title )
00417 {
00418 m_typeOfPrint = typeOfPrint;
00419 m_drawingView = drawingView;
00420 m_title = title;
00421 m_filename = filename;
00422 m_scalelimit = scalelimit;
00423 m_drawframe = drawframe;
00424 m_fitToPage = fitToPage;
00425 }
00426
00427 a2dViewPrintout::~a2dViewPrintout(void)
00428 {
00429 }
00430
00431 bool a2dViewPrintout::OnPrintPage(int)
00432 {
00433 wxDC* dc;
00434 dc = GetDC();
00435
00436 int w,h;
00437 dc->GetSize(&w, &h);
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458 int marginX = (int)(h * 0.015);
00459 int marginY = marginX;
00460 int fontMarginYTop = 0;
00461 int fontMarginYBottom = 0;
00462 wxFont fontTitle = wxFont(marginY,wxDEFAULT,wxNORMAL,wxNORMAL);
00463 wxFont fontFilename = wxFont(int(marginY/2.+0.5),wxDEFAULT,wxNORMAL,wxNORMAL);
00464
00465
00466 dc->SetBrush(*wxWHITE_BRUSH);
00467 dc->SetBackground(*wxWHITE_BRUSH);
00468 dc->Clear();
00469
00470 dc->SetBackgroundMode(wxTRANSPARENT);
00471
00472 dc->SetTextForeground(*wxBLACK);
00473 dc->SetBrush(*wxTRANSPARENT_BRUSH);
00474
00475 if ( !m_title.IsEmpty() )
00476 {
00477 dc->SetFont(fontTitle);
00478 fontMarginYTop += 2*fontTitle.GetPointSize();
00479 wxCoord xExtent, yExtent;
00480 dc->GetTextExtent(m_title, &xExtent, &yExtent);
00481 dc->DrawText(m_title, w/2-xExtent/2, marginY );
00482 }
00483
00484 if ( !m_filename.IsEmpty() )
00485 {
00486 dc->SetFont(fontFilename);
00487 fontMarginYBottom += 2*fontFilename.GetPointSize();
00488 dc->DrawText(m_filename, marginX, h - marginY - fontMarginYBottom);
00489 }
00490
00491 int widthX = w - (2*marginX);
00492 int widthY = h - (2*marginY+fontMarginYTop+fontMarginYBottom);
00493
00494 if( m_drawframe )
00495 {
00496 dc->DrawRectangle(marginX,marginY+fontMarginYTop,widthX,widthY);
00497 const wxPen& aPenForFrame = dc->GetPen();
00498 int penWidth = aPenForFrame.GetWidth();
00499 marginX += penWidth;
00500 marginY += penWidth;
00501 widthX -= 2*penWidth;
00502 widthY -= 2*penWidth;
00503 }
00504 dc->SetBackgroundMode(wxSOLID);
00505 dc->SetFont(wxNullFont);
00506
00507 double scaleX = (widthX/ (double) w);
00508 double scaleY = (widthY/ (double) h);
00509
00510
00511
00512 if(!m_fitToPage)
00513 {
00514 double actualScale = wxMax(scaleX,scaleY);
00515
00516 if( actualScale < m_scalelimit )
00517 actualScale = m_scalelimit;
00518 scaleX = scaleY = actualScale;
00519 }
00520
00521
00522
00523 int posX = marginX + Round((w - (widthX/scaleX))/2.0);
00524 int posY = marginY + fontMarginYTop + Round((h - (widthY/scaleY))/2.0);
00525
00526
00527
00528 dc->SetDeviceOrigin(posX, posY);
00529
00530
00531 a2dDcDrawer* dcdrawer = new a2dDcDrawer(widthX,widthY);
00532 dcdrawer->SetPrintMode( true );
00533 dcdrawer->SetRealScale(!m_fitToPage);
00534
00535
00536 a2dSmrtPtr<a2dCanvasView> drawView = new a2dCanvasView( *m_drawingView );
00537
00538
00539 drawView->SetEvtHandlerEnabled( false );
00540 drawView->SetDrawer2D( dcdrawer );
00541
00542
00543
00544 a2dCanvasDocument* doc = m_drawingView->GetCanvasDocument();
00545 drawView->SetDocument( doc );
00546 drawView->SetShowObject( m_drawingView->GetShowObject());
00547 drawView->SetDocumentDrawStyle( m_drawingView->GetDocumentDrawStyle() );
00548 dcdrawer->SetYaxis( m_drawingView->GetDrawer2D()->GetYaxis() );
00549
00550 if ( m_typeOfPrint->GetCommandId() == &a2dCommand_Print::Id )
00551 {
00552 a2dCommand_Print* printcmd = wxStaticCast( m_typeOfPrint, a2dCommand_Print );
00553 if ( a2dCommand_Print::PrintView == printcmd->What() ||
00554 a2dCommand_Print::PreviewView == printcmd->What() )
00555 {
00556 dcdrawer->SetMappingWidthHeight( m_drawingView->GetDrawer2D()->GetVisibleMinX(),
00557 m_drawingView->GetDrawer2D()->GetVisibleMinY(),
00558 m_drawingView->GetDrawer2D()->GetVisibleWidth(),
00559 m_drawingView->GetDrawer2D()->GetVisibleHeight());
00560 }
00561 else
00562 {
00563 drawView->SetMappingShowAll();
00564 }
00565 }
00566 else
00567 {
00568 drawView->SetMappingShowAll();
00569 }
00570
00571
00572 dcdrawer->SetRenderDC(dc);
00573
00574
00575 drawView->UpdateArea( 0, 0,widthX,widthY );
00576
00577 dcdrawer->SetRenderDC(NULL);
00578
00579 drawView->SetClosed();
00580 return true;
00581 }
00582 #endif //wxUSE_PRINTING_ARCHITECTURE
00583
00584
00585
00586
00587
00588 a2dPropertyIdUint16* a2dCanvasView::PROPID_drawstyle = NULL;
00589 a2dPropertyIdBool* a2dCanvasView::PROPID_gridlines = NULL;
00590 a2dPropertyIdBool* a2dCanvasView::PROPID_grid = NULL;
00591 a2dPropertyIdBool* a2dCanvasView::PROPID_showorigin = NULL;
00592 a2dPropertyIdUint16* a2dCanvasView::PROPID_hitmargin = NULL;
00593 a2dPropertyIdBool* a2dCanvasView::PROPID_gridatfront = NULL;
00594 a2dPropertyIdUint16* a2dCanvasView::PROPID_gridsize = NULL;
00595 a2dPropertyIdUint16* a2dCanvasView::PROPID_gridthres = NULL;
00596 a2dPropertyIdDouble* a2dCanvasView::PROPID_gridx = NULL;
00597 a2dPropertyIdDouble* a2dCanvasView::PROPID_gridy = NULL;
00598
00599 INITIALIZE_PROPERTIES( a2dCanvasView, a2dView )
00600 {
00601 A2D_PROPID_D( a2dPropertyIdUint16, drawstyle, a2dFILLED );
00602 A2D_PROPID_M( a2dPropertyIdBool, a2dCanvasView, gridlines, false, m_gridlines );
00603 A2D_PROPID_M( a2dPropertyIdBool, a2dCanvasView, grid, false, m_grid );
00604 A2D_PROPID_M( a2dPropertyIdBool, a2dCanvasView, showorigin, false, m_showorigin );
00605 A2D_PROPID_M( a2dPropertyIdBool, a2dCanvasView, gridatfront, false, m_gridatfront );
00606 A2D_PROPID_M( a2dPropertyIdUint16, a2dCanvasView, hitmargin, 0, m_hitmargin );
00607 A2D_PROPID_M( a2dPropertyIdUint16, a2dCanvasView, gridsize, 0, m_gridsize );
00608 A2D_PROPID_M( a2dPropertyIdUint16, a2dCanvasView, gridthres, 0, m_gridthres );
00609 A2D_PROPID_M( a2dPropertyIdDouble, a2dCanvasView, gridx, 0, m_gridx );
00610 A2D_PROPID_M( a2dPropertyIdDouble, a2dCanvasView, gridy, 0, m_gridy );
00611 return true;
00612 }
00613
00614 DEFINE_EVENT_TYPE( a2dCanvasView::sm_changedLayers )
00615 DEFINE_EVENT_TYPE( a2dCanvasView::sm_changedLayerAvailable )
00616 DEFINE_EVENT_TYPE( a2dCanvasView::sm_changedLayerVisibleInView )
00617 DEFINE_EVENT_TYPE( a2dCanvasView::sm_changedActiveView )
00618 DEFINE_EVENT_TYPE( a2dCanvasView::sm_changedShowObject )
00619
00620 void a2dCanvasView::OnPropertyChanged( const a2dPropertyId* WXUNUSED(id) )
00621 {
00622 Update();
00623 }
00624
00625 IMPLEMENT_DYNAMIC_CLASS( a2dCanvasView, a2dView )
00626
00627 A2D_BEGIN_EVENT_TABLE(a2dCanvasView,a2dView)
00628 A2D_EVT_ENTER_WINDOW( a2dCanvasView::OnEnter )
00629 A2D_EVT_IDLE( a2dCanvasView::OnIdle )
00630 A2D_EVT_MOUSE_EVENTS( a2dCanvasView::OnMouseEvent )
00631 A2D_EVT_CHAR( a2dCanvasView::OnCharEvent )
00632 A2D_EVT_SET_DOCUMENT( a2dCanvasView::OnSetDocument )
00633 A2D_EVT_ACTIVATE_VIEW( a2dCanvasView::OnActivate )
00634 A2D_EVT_UPDATE_VIEWS( a2dCanvasView::OnUpdate )
00635 A2D_EVT_COM_EVENT( a2dCanvasView::OnComEvent )
00636 A2D_EVT_CLOSE_VIEW( a2dCanvasView::OnCloseView )
00637 A2D_EVT_DISCONNECT_ALLVIEWS( a2dCanvasView::OnDisConnectView )
00638 A2D_END_EVENT_TABLE()
00639
00640 a2dCanvasView::a2dCanvasView( const wxSize& size ):
00641 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG)
00642 m_initCurrentSmartPointerOwner(this),
00643 #endif
00644 m_tiles( (size.GetWidth() >> a2d_TILESHIFT) + 1 , (size.GetHeight() >> a2d_TILESHIFT) + 1 ),
00645 m_tiles2( (size.GetWidth() >> a2d_TILESHIFT) + 1 , (size.GetHeight() >> a2d_TILESHIFT) + 1 )
00646 {
00647 m_width = size.GetWidth();
00648 m_height = size.GetHeight();
00649
00650 m_drawer2D = new a2dMemDcDrawer( m_width, m_height );
00651
00652 Init();
00653 }
00654
00655 a2dCanvasView::a2dCanvasView( int width, int height ):
00656 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG)
00657 m_initCurrentSmartPointerOwner(this),
00658 #endif
00659 m_tiles( (width >> a2d_TILESHIFT) + 1 , (height >> a2d_TILESHIFT) + 1 ),
00660 m_tiles2( (width >> a2d_TILESHIFT) + 1 , (height >> a2d_TILESHIFT) + 1 )
00661 {
00662 m_width = width;
00663 m_height = height;
00664
00665 m_drawer2D = new a2dMemDcDrawer( m_width, m_height );
00666
00667 Init();
00668 }
00669
00670 a2dCanvasView::a2dCanvasView( int width, int height, a2dDrawer2D * drawer ):
00671 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG)
00672 m_initCurrentSmartPointerOwner(this),
00673 #endif
00674 m_tiles( (width >> a2d_TILESHIFT) + 1 , (height >> a2d_TILESHIFT) + 1 ),
00675 m_tiles2( (width >> a2d_TILESHIFT) + 1 , (height >> a2d_TILESHIFT) + 1 )
00676 {
00677 m_width = width;
00678 m_height = height;
00679
00680 m_drawer2D = drawer;
00681 m_drawer2D->DestroyClippingRegion();
00682
00683 Init();
00684 }
00685
00686 a2dCanvasView::a2dCanvasView( a2dDrawer2D * drawer ):
00687 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG)
00688 m_initCurrentSmartPointerOwner(this),
00689 #endif
00690 m_tiles( (drawer->GetWidth() >> a2d_TILESHIFT) + 1 , (drawer->GetHeight() >> a2d_TILESHIFT) + 1 ),
00691 m_tiles2( (drawer->GetWidth() >> a2d_TILESHIFT) + 1 , (drawer->GetHeight() >> a2d_TILESHIFT) + 1 )
00692 {
00693 m_drawer2D = drawer;
00694 m_width = drawer->GetWidth();
00695 m_height = drawer->GetHeight();
00696
00697 Init();
00698 }
00699
00700 void a2dCanvasView::Init()
00701 {
00702
00703
00704 m_reverse_order = a2dCanvasGlobals->GetReverseOrder();
00705 m_update_available_layers = true;
00706
00707 m_recur = false;
00708
00709 m_documentDrawStyle = RenderLAYERED | a2dCanvasGlobals->GetSelectDrawStyle();
00710 m_overlayDrawStyle = RenderLAYERED;
00711 m_documentDrawStyleRestore = m_documentDrawStyle;
00712 m_fixFill = *a2dBLACK_FILL;
00713 m_fixStroke = *a2dBLACK_STROKE;
00714 m_overlayFill = *a2dBLACK_FILL;
00715 m_overlayStroke = *a2dBLACK_STROKE;
00716
00717 m_selectFill = a2dCanvasGlobals->GetSelectFill();
00718 m_selectStroke = a2dCanvasGlobals->GetSelectStroke();
00719 if ( m_drawer2D && m_drawer2D->HasAlpha() )
00720 {
00721 m_highLightStroke = a2dStroke( wxColor( 0,255,255, 255 ), 2);
00722 m_highLightFill = a2dFill( wxColor( 255,122,0,165 ) );
00723 }
00724 else
00725 {
00726 m_highLightStroke = a2dStroke( wxColor( 0,255,255 ), 2);
00727 m_highLightFill = *a2dTRANSPARENT_FILL;
00728 }
00729
00730 if (m_drawer2D)
00731 {
00732 m_drawer2D->SetDisplay( m_display );
00733 }
00734
00735 m_toolcontroller = 0;
00736
00737
00738 m_mouseevents=true;
00739
00740 m_top = 0;
00741
00742 m_frozen = false;
00743
00744 m_virtualarea_set = false;
00745
00746 m_gridatfront = false;
00747 m_gridx = 100;
00748 m_gridy = 100;
00749 m_gridlines = false;
00750 m_gridthres = 5;
00751 m_gridsize = 0;
00752 m_grid = false;
00753
00754 m_showorigin = true;
00755
00756 m_backgroundfill = *a2dWHITE_FILL;
00757 m_gridstroke = *a2dBLACK_STROKE;
00758 m_gridfill = *a2dTRANSPARENT_FILL;
00759
00760 m_capture = (a2dCanvasObject*)NULL;
00761 m_endCorridorObject = (a2dCanvasObject*)NULL;
00762
00763 m_crosshairStroke = a2dStroke( wxColour(200,30,30), 0, a2dSTROKE_DOT );
00764 m_crosshair = false;
00765 m_crosshairx = 0;
00766 m_crosshairy = 0;
00767 m_crosshairLengthX = CROSS_HAIR_X;
00768 m_crosshairLengthY = CROSS_HAIR_Y;
00769 m_mouse_x = m_mouse_y = 0;
00770
00771 m_hitmargin = a2dCanvasGlobals->GetHitMarginDevice();
00772
00773 m_printtitle = true;
00774 m_printfilename = true;
00775 m_printscalelimit = 0;
00776 m_printframe = true;
00777 m_printfittopage = false;
00778
00779 m_viewDependentObjects = false;
00780 }
00781
00782 a2dCanvasView::~a2dCanvasView()
00783 {
00784
00785
00786 SetEvtHandlerEnabled( false );
00787 DeleteAllPendingAreas();
00788
00789 m_display = NULL;
00790
00791 m_toolcontroller = 0;
00792
00793 if ( m_drawer2D )
00794 delete m_drawer2D;
00795 }
00796
00797 a2dCanvasView::a2dCanvasView( const a2dCanvasView& other)
00798 :a2dView( other ),
00799 m_tiles( (other.m_width >> a2d_TILESHIFT) + 1 , (other.m_height >> a2d_TILESHIFT) + 1 ),
00800 m_tiles2( (other.m_width >> a2d_TILESHIFT) + 1 , (other.m_height >> a2d_TILESHIFT) + 1 )
00801 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG)
00802 , m_initCurrentSmartPointerOwner(this)
00803 #endif
00804 {
00805 m_drawer2D = NULL;
00806
00807 Init();
00808
00809 m_backgroundfill = other.m_backgroundfill;
00810
00811 m_gridatfront = other.m_gridatfront;
00812
00813 m_gridstroke = other.m_gridstroke;
00814
00815 m_gridfill = other.m_gridfill;
00816
00817 m_fixFill = other.m_fixFill;
00818 m_fixStroke = other.m_fixStroke;
00819
00820 m_overlayFill = other.m_overlayFill;
00821 m_overlayStroke = other.m_overlayStroke;
00822
00823 m_selectFill = other.m_selectFill;
00824 m_selectStroke = other.m_selectStroke;
00825
00826 m_gridx = other.m_gridx;
00827 m_gridy = other.m_gridy;
00828 m_gridlines = other.m_gridlines;
00829 m_gridsize = other.m_gridsize;
00830 m_gridthres = other.m_gridthres;
00831
00832 m_showorigin = other.m_showorigin;
00833
00834 m_grid = other.m_grid;
00835
00836 m_top = other.m_top;
00837
00838 m_crosshairStroke = other.m_crosshairStroke;
00839 m_crosshair = other.m_crosshair;
00840 m_crosshairx = other.m_crosshairx;
00841 m_crosshairy = other.m_crosshairy;
00842 m_crosshairLengthX = other.m_crosshairLengthX;
00843 m_crosshairLengthY = other.m_crosshairLengthY;
00844
00845 m_printtitle = other.m_printtitle;
00846 m_printfilename = other.m_printfilename;
00847 m_printscalelimit = other.m_printscalelimit;
00848 m_printframe = other.m_printframe;
00849 m_printfittopage = other.m_printfittopage;
00850
00851 m_documentDrawStyle = other.m_documentDrawStyle;
00852 m_reverse_order = other.m_reverse_order;
00853
00854 }
00855
00856 void a2dCanvasView::SetReverseOrder(bool revorder)
00857 {
00858 m_reverse_order = revorder;
00859 Update( a2dCANVIEW_UPDATE_ALL );
00860 }
00861
00862 double a2dCanvasView::GetHitMarginWorld() const
00863 {
00864 assert( m_drawer2D );
00865 return m_drawer2D->DeviceToWorldXRel( m_hitmargin );
00866 }
00867
00868 void a2dCanvasView::SetDisplayWindow( wxWindow* display )
00869 {
00870 a2dView::SetDisplayWindow( display );
00871 if (m_drawer2D)
00872 m_drawer2D->SetDisplay( display );
00873 }
00874
00875 void a2dCanvasView::SetBufferSize( int w, int h )
00876 {
00877 m_width = w;
00878 m_height = h;
00879 m_tiles.SetSize( (w >> a2d_TILESHIFT) + 1, (h >> a2d_TILESHIFT) + 1 );
00880 m_tiles2.SetSize( (w >> a2d_TILESHIFT) + 1, (h >> a2d_TILESHIFT) + 1 );
00881 if (m_drawer2D)
00882 m_drawer2D->SetBufferSize( w, h );
00883 }
00884
00885 void a2dCanvasView::SetDrawer2D( a2dDrawer2D* drawer2d, bool noDelete )
00886 {
00887 if ( noDelete != true )
00888 {
00889 if (m_drawer2D)
00890 delete m_drawer2D;
00891 }
00892 m_drawer2D = drawer2d;
00893 if (m_drawer2D)
00894 {
00895 m_drawer2D->SetDisplay( m_display );
00896 m_width = m_drawer2D->GetWidth();
00897 m_height = m_drawer2D->GetHeight();
00898
00899 m_tiles.SetSize( (m_width >> a2d_TILESHIFT) + 1, (m_height >> a2d_TILESHIFT) + 1 );
00900 m_tiles2.SetSize( (m_width >> a2d_TILESHIFT) + 1, (m_height >> a2d_TILESHIFT) + 1 );
00901 }
00902 }
00903
00904
00905 bool a2dCanvasView::SetCanvasToolContr( a2dToolContr* controller )
00906 {
00907 a2dToolContr* returnc = m_toolcontroller;
00908
00909 if ( m_toolcontroller )
00910 {
00911 wxASSERT_MSG( m_toolcontroller->GetCanvasView() == this, wxT("a2dToolContr has different a2dCanvasView set for it") );
00912 m_toolcontroller->Disable();
00913 }
00914
00915 if ( controller )
00916 {
00917 wxASSERT_MSG( controller->GetCanvasView() == this, wxT("a2dToolContr has different a2dCanvasView set for it") );
00918 }
00919 m_toolcontroller = controller;
00920 return returnc != 0;
00921 }
00922
00923 bool a2dCanvasView::ProcessEvent(wxEvent& event)
00924 {
00925 bool processed = false;
00926
00927
00928 if ( (GetEvtHandlerEnabled() && m_viewEnabled) ||
00929 (event.GetEventType() == wxEVT_ENABLE_VIEW) ||
00930 (event.GetEventType() == wxEVT_ENABLE_VIEWS)
00931 )
00932 {
00933
00934 a2dREFOBJECTPTR_KEEPALIVE;
00935
00936 if ( event.GetEventType() == wxEVT_IDLE )
00937 {
00938 processed = a2dView::ProcessEvent( event);
00939 if ( m_toolcontroller )
00940 {
00941 event.Skip();
00942 processed = m_toolcontroller->ProcessEvent( event );
00943 }
00944 }
00945 else if ( m_toolcontroller && event.GetEventType() == wxEVT_PAINT )
00946 {
00947 if (m_display)
00948 {
00949 SetEvtHandlerEnabled(false);
00950 event.ResumePropagation( wxEVENT_PROPAGATE_MAX );
00951 m_display->GetEventHandler()->ProcessEvent( event );
00952 event.StopPropagation();
00953 SetEvtHandlerEnabled(true);
00954 }
00955 processed = a2dView::ProcessEvent( event);
00956 if ( !processed )
00957 {
00958 event.Skip();
00959 processed = m_toolcontroller->ProcessEvent( event );
00960 }
00961 }
00962 else if ( m_toolcontroller && event.GetEventType() == a2dEVT_COM_EVENT )
00963 {
00964
00965 processed = m_toolcontroller->ProcessEvent( event );
00966 event.Skip();
00967 processed = a2dView::ProcessEvent( event);
00968 }
00969 else if ( m_toolcontroller && event.GetEventType() == wxEVT_CHAR )
00970 {
00971 processed = m_toolcontroller->ProcessEvent( event );
00972 if ( !processed )
00973 {
00974 event.Skip();
00975 processed = a2dView::ProcessEvent( event);
00976 }
00977 }
00978 else if ( m_toolcontroller && event.GetEventType() == wxEVT_KEY_DOWN )
00979 {
00980 processed = m_toolcontroller->ProcessEvent( event );
00981 if ( !processed )
00982 {
00983 event.Skip();
00984 processed = a2dView::ProcessEvent( event);
00985 }
00986 }
00987 else if ( m_toolcontroller && event.GetEventType() == wxEVT_KEY_UP )
00988 {
00989 processed = m_toolcontroller->ProcessEvent( event );
00990 if ( !processed )
00991 {
00992 event.Skip();
00993 processed = a2dView::ProcessEvent( event);
00994 }
00995 }
00996 else if ( m_toolcontroller )
00997 {
00998 processed = m_toolcontroller->ProcessEvent( event );
00999 if ( !processed )
01000 {
01001 event.Skip();
01002 processed = a2dView::ProcessEvent( event);
01003 }
01004 }
01005 else
01006 {
01007 processed = a2dView::ProcessEvent( event);
01008 }
01009
01010 return processed;
01011 }
01012
01013 return false;
01014 }
01015
01016 void a2dCanvasView::OnEnter( wxMouseEvent& event )
01017 {
01018
01019
01020
01021
01022 event.Skip();
01023 }
01024
01025 void a2dCanvasView::OnIdle(wxIdleEvent &event)
01026 {
01027
01028
01029 if ( m_frozen )
01030 {
01031 event.Skip();
01032 return;
01033 }
01034
01035 if (Get_UpdateAvailableLayers())
01036 {
01037 Update( a2dCANVIEW_UPDATE_ALL );
01038 }
01039
01040 AddOverlayAreas( false );
01041
01042
01043
01044
01045 if ( m_tiles.HasFilledTiles() || m_tiles2.HasFilledTiles() || m_updateareas.GetCount() )
01046 {
01047
01048
01049
01050
01051
01052
01053
01054
01055 if ( GetCanvasDocument() && !GetCanvasDocument()->GetUpdatesPending() )
01056 Update( a2dCANVIEW_UPDATE_AREAS | a2dCANVIEW_UPDATE_BLIT );
01057 }
01058
01059 event.Skip();
01060 }
01061
01062 void a2dCanvasView::AddOverlayAreas( bool update )
01063 {
01064 if ( m_overlayObjects.size() )
01065 {
01066 a2dCanvasObjectList::iterator iter = m_overlayObjects.begin();
01067 for( iter = m_overlayObjects.begin(); iter != m_overlayObjects.end(); ++iter )
01068 {
01069 a2dCanvasObjectList::value_type obj = *iter;
01070 if ( obj->GetPending() )
01071 {
01072 AddPendingUpdateArea( obj, 1 );
01073 obj->Update( a2dCanvasObject::updatemask_normal );
01074 AddPendingUpdateArea( obj, 1 );
01075 obj->SetPending( false );
01076 }
01077 }
01078 }
01079
01080 if ( update && m_tiles2.HasFilledTiles() )
01081 {
01082 Update( a2dCANVIEW_UPDATE_AREAS | a2dCANVIEW_UPDATE_BLIT );
01083 }
01084
01085 }
01086
01087 void a2dCanvasView::AddOverlayObject( a2dCanvasObject* obj )
01088 {
01089 obj->SetCanvasDocument( GetCanvasDocument() );
01090 m_overlayObjects.push_back( obj );
01091 }
01092
01093 void a2dCanvasView::RemoveOverlayObject( a2dCanvasObject* obj )
01094 {
01095 a2dCanvasObjectList::iterator iter = m_overlayObjects.begin();
01096 for( iter = m_overlayObjects.begin(); iter != m_overlayObjects.end(); ++iter )
01097 {
01098 a2dCanvasObjectList::value_type iobj = *iter;
01099 if ( iobj == obj )
01100 {
01101 AddPendingUpdateArea( obj, 1 );
01102 m_overlayObjects.erase( iter );
01103 break;
01104 }
01105 }
01106 }
01107
01108 void a2dCanvasView::OnActivate( a2dViewEvent& viewevent )
01109 {
01110
01111 bool activate = viewevent.GetActive();
01112
01113 if ( activate && GetCanvasDocument() && viewevent.GetEventObject() == this )
01114 {
01115 if ( GetDisplayWindow() && wxWindow::FindFocus() != GetDisplayWindow() )
01116 {
01117 GetDisplayWindow()->SetFocus();
01118
01119 }
01120 }
01121 }
01122
01123 void a2dCanvasView::SetDocumentDrawStyle( wxUint32 documentDrawStyle )
01124 {
01125 m_documentDrawStyleRestore = m_documentDrawStyle; m_documentDrawStyle = documentDrawStyle;
01126 }
01127
01128 void a2dCanvasView::SetOverlayDrawStyle( a2dDocumentRenderStyle drawstyle )
01129 {
01130 m_overlayDrawStyle = drawstyle;
01131 }
01132
01133 void a2dCanvasView::Freeze()
01134 {
01135 m_frozen = true;
01136 }
01137
01138 void a2dCanvasView::Thaw(bool update)
01139 {
01140 m_frozen = false;
01141
01142 if (update)
01143 {
01144 Update( a2dCANVIEW_UPDATE_ALL );
01145 }
01146 }
01147
01148 void a2dCanvasView::SetEndCorridorObject( a2dCanvasObject* endCorridorObject )
01149 {
01150 m_endCorridorObject = endCorridorObject;
01151 }
01152
01153 void a2dCanvasView::SetCursor(const wxCursor& cursor)
01154 {
01155 if ( m_display )
01156 m_display->SetCursor( cursor );
01157 }
01158
01159 void a2dCanvasView::PushCursor(const wxCursor& cursor)
01160 {
01161 m_cursorStack.push_back( cursor );
01162 if ( m_display )
01163 m_display->SetCursor( cursor );
01164 }
01165
01166 void a2dCanvasView::PopCursor()
01167 {
01168 m_cursorStack.pop_back();
01169 if ( m_display )
01170 {
01171 if ( m_cursorStack.size() )
01172 m_display->SetCursor( m_cursorStack.back() );
01173 else
01174 m_display->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW ) );
01175 }
01176 }
01177
01178 void a2dCanvasView::ClearCursorStack()
01179 {
01180 m_cursorStack.clear();
01181 if ( m_display )
01182 m_display->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW ) );
01183 }
01184
01185 void a2dCanvasView::SetMouseEvents(bool onoff)
01186 {
01187 m_mouseevents=onoff;
01188 }
01189
01190 void a2dCanvasView::SetCrossHairStroke( const a2dStroke& crosshairStroke )
01191 {
01192 m_crosshairStroke = crosshairStroke;
01193 };
01194
01195
01196 void a2dCanvasView::SetCrossHair( bool onoff )
01197 {
01198 m_crosshair = onoff;
01199 Update( a2dCANVIEW_UPDATE_ALL );
01200 }
01201
01202 void a2dCanvasView::MouseToToolWorld( int x, int y, double& xWorldLocal, double& yWorldLocal )
01203 {
01204 if ( wxDynamicCast( GetDisplayWindow(), a2dCanvas ) )
01205 {
01206
01207 }
01208 else if ( wxDynamicCast( GetDisplayWindow(), a2dCanvasSim ) )
01209 {
01210
01211 a2dCanvasSim* can = wxStaticCast( GetDisplayWindow(), a2dCanvasSim );
01212 can->CalcUnscrolledPosition( x, y, &x , &y );
01213 }
01214
01215 xWorldLocal = GetDrawer2D()->DeviceToWorldX(x);
01216 yWorldLocal = GetDrawer2D()->DeviceToWorldY(y);
01217 }
01218
01219 void a2dCanvasView::OnMouseEvent(wxMouseEvent &event)
01220 {
01221 m_mouse_x = event.GetX();
01222 m_mouse_y = event.GetY();
01223
01224 UpdateCrossHair( m_mouse_x, m_mouse_y );
01225
01226 if (!GetCanvasDocument() || !m_mouseevents)
01227 {
01228 event.Skip();
01229 return;
01230 }
01231
01232
01233 double xw = m_drawer2D->DeviceToWorldX( m_mouse_x );
01234 double yw = m_drawer2D->DeviceToWorldY( m_mouse_y );
01235
01236 if (m_capture && !GetCanvasDocument()->Find( m_capture ) )
01237 m_capture = (a2dCanvasObject*) NULL;
01238
01239 a2dIterC ic( this );
01240 a2dAffineMatrix cworld = GetShowObject()->GetTransformMatrix();
01241 cworld.Invert();
01242 a2dIterCU cu( ic, cworld );
01243 ic.SetPerLayerMode( false );
01244 ic.SetLayer( wxLAYER_ALL );
01245 a2dHitEvent hitinfo( xw, yw );
01246 hitinfo.m_event = &event;
01247 if ( GetShowObject()->ProcessCanvasObjectEvent( ic, hitinfo ) )
01248 return;
01249 event.Skip();
01250
01251 return;
01252 }
01253
01254 void a2dCanvasView::OnCharEvent(wxKeyEvent &event)
01255 {
01256 if (m_capture )
01257 m_capture->ProcessEvent(event);
01258 else
01259 event.Skip();
01260 }
01261
01262 bool a2dCanvasView::ProcessCanvasObjectEvent( wxEvent& event, bool& isHit,
01263 double x, double y, int margin,
01264 int layer )
01265 {
01266 a2dIterC ic( this );
01267 ic.SetHitMarginDevice( margin );
01268 ic.SetPerLayerMode( false );
01269 ic.SetLayer( wxLAYER_ALL );
01270 a2dAffineMatrix cworld = GetShowObject()->GetTransformMatrix();
01271 cworld.Invert();
01272 a2dIterCU cu( ic, cworld );
01273
01274 GetShowObject()->SetSpecificFlags( true, a2dCanvasOFlags::IsOnCorridorPath );
01275 a2dHitEvent hitinfo( x, y );
01276 hitinfo.m_event = &event;
01277 bool res = GetShowObject()->ProcessCanvasObjectEvent( ic, hitinfo );
01278 isHit = hitinfo.m_isHit;
01279 GetShowObject()->SetSpecificFlags( false, a2dCanvasOFlags::IsOnCorridorPath );
01280 return res;
01281 }
01282
01283 bool a2dCanvasView::ProcessCanvasObjectEvent( a2dCanvasObjectEvent& event, bool& isHit,
01284 double x, double y, int margin,
01285 int layer )
01286 {
01287 a2dIterC ic( this );
01288 ic.SetHitMarginDevice( margin );
01289 ic.SetPerLayerMode( false );
01290 ic.SetLayer( layer );
01291 a2dAffineMatrix cworld = GetShowObject()->GetTransformMatrix();
01292 cworld.Invert();
01293 a2dIterCU cu( ic, cworld );
01294
01295 event.SetIterC( &ic );
01296
01297 GetShowObject()->SetSpecificFlags( true, a2dCanvasOFlags::IsOnCorridorPath );
01298 a2dHitEvent hitinfo( x, y );
01299 hitinfo.m_event = &event;
01300 bool res = GetShowObject()->ProcessCanvasObjectEvent( ic, hitinfo );
01301 isHit = hitinfo.m_isHit;
01302 GetShowObject()->SetSpecificFlags( false, a2dCanvasOFlags::IsOnCorridorPath );
01303 return res;
01304 }
01305
01306 bool a2dCanvasView::FindAndSetCorridorPath( a2dCanvasObject* findObject, bool capture )
01307 {
01308 a2dWalker_FindAndSetCorridorPath findcorridor( findObject );
01309 findcorridor.Start( GetShowObject() );
01310
01311 if( findcorridor.GetResult() )
01312 {
01313 SetEndCorridorObject( findObject );
01314 if( capture )
01315 {
01316 SetCaptured( findObject );
01317 }
01318 return true;
01319 }
01320 return false;
01321 }
01322
01323 void a2dCanvasView::SetCorridorPath( const a2dCorridor& corridor )
01324 {
01325 ClearCorridorPath( true );
01326 a2dCanvasObjectList::const_iterator iter = corridor.begin();
01327 while( iter != corridor.end() )
01328 {
01329 a2dCanvasObjectList::value_type obj = *iter;
01330 obj->SetIsOnCorridorPath( true );
01331 iter++;
01332 }
01333 if ( !corridor.empty() )
01334 SetEndCorridorObject( corridor.back() );
01335 SetCaptured( corridor.GetCaptured() );
01336 }
01337
01338 void a2dCanvasView::ClearCorridorPath( bool uncapture )
01339 {
01340 if( uncapture )
01341 {
01342 SetCaptured( NULL );
01343 }
01344 SetEndCorridorObject( NULL );
01345
01346 if ( GetShowObject() )
01347 {
01348 a2dWalker_SetSpecificFlagsCanvasObjects setflags( a2dCanvasOFlags::IsOnCorridorPath );
01349 setflags.Start( GetShowObject(), false );
01350 }
01351 }
01352
01353 a2dCanvasObject* a2dCanvasView::IsHitWorld(
01354 double x, double y,
01355 int layer,
01356 a2dHitOption option,
01357 bool filterSelectableLayers
01358 )
01359 {
01360 Update( a2dCANVIEW_UPDATE_PENDING );
01361 a2dIterC ic( this );
01362 ic.SetPerLayerMode( false );
01363 ic.SetLayer( layer );
01364 ic.SetObjectFilter( new a2dCanvasObjectFilterLayerMask( layer, a2dCanvasOFlags::VISIBLE | a2dCanvasOFlags::SELECTABLE ) );
01365
01366 a2dHitEvent hitinfo( x, y );
01367 hitinfo.m_option = option;
01368
01369
01370 hitinfo.m_xyRelToChildren = false;
01371
01372 a2dCanvasObject* res = GetShowObject()->ChildIsHitWorld( ic, hitinfo, filterSelectableLayers );
01373 return res;
01374 }
01375
01376 a2dCanvasObject* a2dCanvasView::IsHitWorld(
01377 a2dHitEvent& hitEvent,
01378 int layer
01379 )
01380 {
01381 Update( a2dCANVIEW_UPDATE_PENDING );
01382 a2dIterC ic( this );
01383 ic.SetLayer( layer );
01384 a2dCanvasObject* res = GetShowObject()->ChildIsHitWorld( ic, hitEvent );
01385 return res;
01386 }
01387
01388 void a2dCanvasView::OnDraw(wxDC* WXUNUSED(dc) )
01389 {
01390 wxFAIL_MSG( wxT("a2dCanvasView::OnDraw is not implemented, see a2dViewPrintout::OnPrintPage(int)") );
01391 }
01392
01393
01394 void a2dCanvasView::SetLayerCheck( wxUint16 layer )
01395 {
01396 GetLayerRenderArray()[ layer ].SetCheck( true );
01397 Set_UpdateAvailableLayers(true);
01398 }
01399
01400 void a2dCanvasView::SetAvailable()
01401 {
01402 unsigned int j;
01403 for ( j=0; j < wxMAXLAYER; j++ )
01404 {
01405 m_layerRenderArray[j].SetCheck( false );
01406 m_layerRenderArray[j].SetAvailable( false );
01407 }
01408
01409 m_layerRenderArray[wxLAYER_DEFAULT].SetAvailable( true );
01410
01411 if ( m_top )
01412 {
01413 a2dWalker_SetAvailable set( this );
01414 set.Start( m_top );
01415 }
01416 Set_UpdateAvailableLayers(false);
01417 }
01418
01419 void a2dCanvasView::OnCloseView( a2dCloseViewEvent& event )
01420 {
01421
01422
01423
01424 if ( m_toolcontroller.Get() )
01425 m_toolcontroller->Disable();
01426 m_toolcontroller = 0;
01427 event.Skip();
01428 }
01429
01430 void a2dCanvasView::OnComEvent( a2dComEvent& event )
01431 {
01432 if ( GetEvtHandlerEnabled() )
01433 {
01434 if ( event.GetEventComId() == &sm_changedLayers )
01435 {
01436 Set_UpdateAvailableLayers(true);
01437 }
01438 else if ( event.GetEventComId() == &a2dCanvasObject::sm_changedLayer )
01439 {
01440 a2dCanvasObject* obj = wxDynamicCast( event.GetEventObject(), a2dCanvasObject );
01441
01442 if ( obj->GetCanvasDocument() == m_viewDocument )
01443 {
01444 a2dNamedProperty *property = event.GetProperty();
01445 if ( property->GetUint16() != wxLAYER_ALL )
01446 m_layerRenderArray[property->GetUint16()].SetAvailable( true );
01447 else
01448 Set_UpdateAvailableLayers(true);
01449 }
01450 }
01451 else if ( event.GetEventComId() == &a2dCanvasDocument::sm_layersetupChanged )
01452 {
01453 a2dCanvasDocument* doc = wxDynamicCast( event.GetEventObject(), a2dCanvasDocument );
01454 if ( doc == m_viewDocument )
01455 Update( a2dCANVIEW_UPDATE_ALL );
01456
01457 }
01458 else if ( event.GetEventComId() == &a2dLayerInfo::sm_changedLayer )
01459 {
01460 a2dCanvasObject* obj = wxDynamicCast( event.GetEventObject(), a2dCanvasObject );
01461 if ( m_viewDocument == obj->GetCanvasDocument() )
01462 Update( a2dCANVIEW_UPDATE_ALL );
01463 }
01464 else
01465 event.Skip();
01466 }
01467 else
01468 event.Skip();
01469 }
01470
01471 void a2dCanvasView::Update( unsigned int how, wxObject* hintObject )
01472 {
01473 a2dView::Update( how, hintObject );
01474 }
01475
01476 void a2dCanvasView::OnUpdate( a2dDocumentEvent& event )
01477 {
01478 if ( !m_top )
01479 return;
01480
01481 if ( m_viewDocument != event.GetEventObject() )
01482 return;
01483
01484 if ( !GetEvtHandlerEnabled() )
01485 return;
01486
01487 if (!GetCanvasDocument())
01488 return;
01489
01490
01491
01492 static long lastProcessedEventTimeStamp = -1;
01493 if( lastProcessedEventTimeStamp == event.GetTimestamp() )
01494 return;
01495 lastProcessedEventTimeStamp = event.GetTimestamp();
01496
01497 int how = a2dCANVIEW_UPDATE_ALL | a2dCANVIEW_UPDATE_BLIT ;
01498
01499 if ( event.GetUpdateHint() != 0 )
01500 how = event.GetUpdateHint();
01501
01502
01503
01504 if ( how & a2dCANVIEW_UPDATE_PENDING )
01505 {
01506 AddObjectPendingUpdates();
01507 }
01508
01509 if ( how & a2dCANVIEW_UPDATE_VIEWDEPENDENT )
01510 {
01511 UpdateViewDependentObjects();
01512 }
01513
01514 if ( how & a2dCANVIEW_UPDATE_OLDNEW )
01515 {
01516 GetCanvasDocument()->AddPendingUpdatesOldNew();
01517 }
01518
01519 if ( how & a2dCANVIEW_UPDATE_ALL )
01520 {
01521 SetAvailable();
01522 DeleteAllPendingAreas();
01523 AddPendingUpdateArea( 0, 0, m_width, m_height );
01524 }
01525
01526 if ( how & a2dCANVIEW_UPDATE_AREAS )
01527 {
01528
01529 RedrawPendingUpdateAreas();
01530 }
01531
01532 if ( how & a2dCANVIEW_UPDATE_AREAS_NOBLIT )
01533 {
01534
01535 RedrawPendingUpdateAreas( true );
01536 }
01537
01538 if ( how & a2dCANVIEW_UPDATE_BLIT )
01539 {
01540 if (GetCanvas() && GetCanvas()->IsShown() )
01541 BlitPendingUpdateAreas();
01542 }
01543 }
01544
01545 void a2dCanvasView::DeleteAllPendingAreas()
01546 {
01547 wxASSERT_MSG( m_recur == false, wxT("recursive calls in updating not allowed") );
01548 m_recur = true;
01549
01550 m_tiles.Clear();
01551 m_tiles2.Clear();
01552
01553
01554 a2dUpdateList::compatibility_iterator nodeb = m_updateareas.GetFirst();
01555 while (nodeb)
01556 {
01557 a2dUpdateArea* uobj = nodeb->GetData();
01558 delete uobj;
01559 delete nodeb;
01560 nodeb = m_updateareas.GetFirst();
01561 }
01562
01563 m_recur = false;
01564 }
01565
01566 void a2dCanvasView::RedrawPendingUpdateAreas( bool noblit )
01567 {
01568 if (m_frozen) return;
01569
01570 if ( m_recur ) return;
01571 wxASSERT_MSG( m_recur == false, wxT("recursive calls in updating not allowed") );
01572
01573 m_recur = true;
01574
01575 m_tiles.GenerateUpdateRectangles( &m_updateareas, 0 );
01576 m_tiles.Clear();
01577 m_tiles2.GenerateUpdateRectangles( &m_updateareas, 1 );
01578 m_tiles2.Clear();
01579
01580 a2dUpdateList::compatibility_iterator nodeb = m_updateareas.GetFirst();
01581 while (nodeb)
01582 {
01583 a2dUpdateArea* uobj = nodeb->GetData();
01584
01585 if (!uobj->m_update_done)
01586 {
01587
01588
01589
01590
01591 int x,y,width,height;
01592 uobj->Inflate( 2 );
01593 x = uobj->x;
01594 y = uobj->y;
01595 width = uobj->width;
01596 height = uobj->height;
01597
01598
01599 UpdateArea( x, y, width, height, uobj->m_id );
01600
01601
01602 uobj->m_update_done = true;
01603
01604 if ( noblit )
01605 {
01606
01607 delete uobj;
01608 a2dUpdateList::compatibility_iterator nodeh = nodeb;
01609 nodeb = nodeb->GetNext();
01610 m_updateareas.DeleteNode(nodeh);
01611 }
01612 else
01613 nodeb = nodeb->GetNext();
01614 }
01615 else
01616 nodeb = nodeb->GetNext();
01617 }
01618
01619 m_recur = false;
01620 }
01621
01622 bool a2dCanvasView::BlitPendingUpdateAreas()
01623 {
01624
01625 bool refresh = false;
01626
01627 if ( !GetCanvasDocument() || m_frozen || !m_updateareas.GetFirst() )
01628 return refresh;
01629
01630 wxASSERT_MSG( m_recur == false, wxT("recursive calls in updating not allowed") );
01631 m_recur = true;
01632
01633
01634
01635 a2dUpdateList::compatibility_iterator node = m_updateareas.GetFirst();
01636 while (node)
01637 {
01638 a2dUpdateArea *rect = node->GetData();
01639
01640 if (rect->m_update_done)
01641 refresh = true;
01642 node = node->GetNext();
01643 }
01644
01645 if ( refresh )
01646 {
01647 m_drawer2D->BeginDraw();
01648
01649 a2dUpdateList::compatibility_iterator node = m_updateareas.GetFirst();
01650 while (node)
01651 {
01652 a2dUpdateArea *rect = node->GetData();
01653
01654 if (rect->m_update_done)
01655 {
01656 m_drawer2D->BlitBuffer( *rect, wxPoint( m_drawer2D->GetMapX(), m_drawer2D->GetMapY() ) );
01657
01658 if ( m_display && m_display->GetChildren().GetCount() )
01659 {
01660 m_display->Refresh( false, rect );
01661 }
01662
01663
01664 delete rect;
01665 a2dUpdateList::compatibility_iterator nodeh = node;
01666 node = node->GetNext();
01667 m_updateareas.DeleteNode(nodeh);
01668 }
01669 else
01670 node = node->GetNext();
01671 }
01672
01673 if ( refresh )
01674 {
01675
01676
01677 }
01678
01679 UpdateCrossHair( m_crosshairx, m_crosshairy );
01680
01681 m_drawer2D->EndDraw();
01682 }
01683
01684 m_recur = false;
01685
01686 return refresh;
01687 }
01688
01689 void a2dCanvasView::UpdateArea( int x, int y, int width, int height, wxUint8 id )
01690 {
01691 if (!GetCanvasDocument())
01692 {
01693 wxASSERT_MSG( GetCanvasDocument() != 0, wxT("invalid a2dCanvasDocument in a2dCanvasView") );
01694 return;
01695 }
01696
01697
01698 if (x < 0)
01699 {
01700 width += x;
01701 x = 0;
01702 }
01703 if (width <= 0) return;
01704
01705 if (y < 0)
01706 {
01707 height += y;
01708 y = 0;
01709 }
01710 if (height <= 0) return;
01711
01712 if (x+width > m_width )
01713 {
01714 width = m_width - x;
01715 }
01716 if (width <= 0) return;
01717
01718 if (y+height > m_height )
01719 {
01720 height = m_height - y;
01721 }
01722 if (height <= 0) return;
01723
01724 m_drawer2D->SetDrawStyle( a2dFILLED );
01725 m_drawer2D->BeginDraw();
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739 m_drawer2D->SetClippingRegionDev(x, y, width, height);
01740
01741 bool ignore = GetCanvasDocument()->GetIgnorePendingObjects();
01742
01743 if (!ignore)
01744 GetCanvasDocument()->SetIgnorePendingObjects( true );
01745
01746 PaintBackground(x, y, width, height);
01747
01748 if (m_grid && !m_gridatfront)
01749 PaintGrid( x, y, width, height );
01750
01751 m_drawer2D->SetDrawerFill( *a2dTRANSPARENT_FILL );
01752 m_drawer2D->SetDrawerStroke( *a2dTRANSPARENT_STROKE );
01753
01754 RenderTopObject( m_documentDrawStyle, id );
01755 RenderOverlay( m_overlayDrawStyle );
01756
01757
01758 if ( m_toolcontroller )
01759 m_toolcontroller->Render();
01760
01761 if (m_grid && m_gridatfront)
01762 PaintGrid( x, y, width, height );
01763
01764 m_drawer2D->DestroyClippingRegion();
01765 DrawOrigin();
01766
01767 if (!ignore)
01768 GetCanvasDocument()->SetIgnorePendingObjects( false );
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779 m_drawer2D->EndDraw();
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789 }
01790
01791 void a2dCanvasView::ClearArea( int x, int y, int width, int height )
01792 {
01793 if (!GetCanvasDocument())
01794 {
01795 wxASSERT_MSG( GetCanvasDocument() != 0, wxT("invalid a2dCanvasDocument in a2dCanvasView") );
01796 return;
01797 }
01798
01799
01800 if (x < 0)
01801 {
01802 width += x;
01803 x = 0;
01804 }
01805 if (width <= 0) return;
01806
01807 if (y < 0)
01808 {
01809 height += y;
01810 y = 0;
01811 }
01812 if (height <= 0) return;
01813
01814 if (x+width > m_width )
01815 {
01816 width = m_width - x;
01817 }
01818 if (width <= 0) return;
01819
01820 if (y+height > m_height )
01821 {
01822 height = m_height - y;
01823 }
01824 if (height <= 0) return;
01825
01826 m_drawer2D->SetDrawStyle( a2dFILLED );
01827 m_drawer2D->BeginDraw();
01828
01829 m_drawer2D->SetClippingRegionDev(x, y, width, height);
01830
01831 PaintBackground(x, y, width, height);
01832 if (m_grid )
01833 PaintGrid( x, y, width, height );
01834
01835 m_drawer2D->DestroyClippingRegion();
01836 DrawOrigin();
01837
01838 m_drawer2D->EndDraw();
01839 }
01840
01841 void a2dCanvasView::BlitBuffer( int x, int y, int width, int height, int xbuf, int ybuf )
01842 {
01843 if (!GetCanvasDocument())
01844 {
01845 wxASSERT_MSG( GetCanvasDocument() != 0, wxT("invalid a2dCanvasDocument in a2dCanvasView") );
01846 return;
01847 }
01848
01849
01850 if (x < 0)
01851 {
01852 width += x;
01853 x = 0;
01854 }
01855 if (width <= 0) return;
01856
01857 if (y < 0)
01858 {
01859 height += y;
01860 y = 0;
01861 }
01862 if (height <= 0) return;
01863
01864 if (x+width > m_width )
01865 {
01866 width = m_width - x;
01867 }
01868 if (width <= 0) return;
01869
01870 if (y+height > m_height )
01871 {
01872 height = m_height - y;
01873 }
01874 if (height <= 0) return;
01875
01876 m_drawer2D->SetDrawStyle( a2dFILLED );
01877 m_drawer2D->BeginDraw();
01878
01879 m_drawer2D->BlitBuffer( x, y, width, height , xbuf, ybuf );
01880
01881 m_drawer2D->EndDraw();
01882 }
01883
01884
01885 void a2dCanvasView::RenderChildObject( a2dCanvasObject* obj )
01886 {
01887 if (!GetCanvasDocument())
01888 {
01889 wxASSERT_MSG( GetCanvasDocument() != 0, wxT("invalid a2dCanvasDocument in a2dCanvasView") );
01890 return;
01891 }
01892
01893 int x,y,width,height;
01894
01895 if (obj && obj->GetCanvasDocument() == GetCanvasDocument())
01896 {
01897 a2dIterC ic( this );
01898 a2dIterCU cu( ic, a2dIDENTITY_MATRIX );
01899 wxRect absarea = obj->GetAbsoluteArea( ic );
01900 x = absarea.GetX();
01901 y = absarea.GetY();
01902 width = absarea.GetWidth();
01903 height = absarea.GetHeight();
01904 }
01905
01906
01907 if (x < 0)
01908 {
01909 width += x;
01910 x = 0;
01911 }
01912 if (width <= 0) return;
01913
01914 if (y < 0)
01915 {
01916 height += y;
01917 y = 0;
01918 }
01919 if (height <= 0) return;
01920
01921 if (x+width > m_width )
01922 {
01923 width = m_width - x;
01924 }
01925 if (width <= 0) return;
01926
01927 if (y+height > m_height )
01928 {
01929 height = m_height - y;
01930 }
01931 if (height <= 0) return;
01932
01933 m_drawer2D->SetDrawStyle( a2dFILLED );
01934 m_drawer2D->BeginDraw();
01935
01936 m_drawer2D->SetClippingRegionDev(x, y, width, height);
01937
01938 PaintBackground(x, y, width, height);
01939 if (m_grid )
01940 PaintGrid( x, y, width, height );
01941
01942 a2dIterC ic( this );
01943 ic.SetDisableInvert( true );
01944 ic.SetDrawStyle( RenderWIREFRAME_HighLight );
01945
01946
01947
01948 a2dAffineMatrix cworld= m_top->GetTransformMatrix();
01949 cworld.Invert();
01950
01951 a2dBoundingBox absarea = m_top->GetMappedBbox( cworld );
01952 OVERLAP clipparent = m_drawer2D->GetClippingBox().Intersect( absarea );
01953 if ( clipparent != _OUT )
01954 {
01955 ic.SetPerLayerMode( false );
01956 m_drawer2D->SetDisableDrawing( true );
01957 ic.SetLayer( wxLAYER_ALL );
01958 a2dIterCU cu( ic, cworld );
01959 obj->Render( ic, clipparent );
01960 m_drawer2D->SetDisableDrawing( false );
01961
01962 ic.Reset();
01963 }
01964
01965 m_drawer2D->DestroyClippingRegion();
01966 DrawOrigin();
01967
01968 m_drawer2D->BlitBuffer( x, y, width, height , m_drawer2D->GetMapX(), m_drawer2D->GetMapY() );
01969
01970 m_drawer2D->EndDraw();
01971 }
01972
01973
01974
01975 void a2dCanvasView::UpdateViewDependentObjects()
01976 {
01977 if ( ! m_viewDependentObjects )
01978 return;
01979
01980 a2dCanvasDocument* doc = GetCanvasDocument();
01981 if(doc)
01982 {
01983 if(!m_top)
01984 return;
01985 a2dIterC ic( this );
01986 a2dAffineMatrix cworld = m_top->GetTransformMatrix();
01987 cworld.Invert();
01988 a2dIterCU cu( ic, cworld );
01989 m_top->UpdateViewDependentObjects( ic );
01990 }
01991 }
01992
01993 void a2dCanvasView::RenderTopObject( wxUint32 documentDrawStyle, wxUint8 id )
01994 {
01995 if ( documentDrawStyle & RenderLAYERED )
01996 {
01997 m_drawer2D->SetDrawStyle( a2dFILLED );
01998 RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderLAYERED );
01999 }
02000 if ( documentDrawStyle & RenderWIREFRAME )
02001 {
02002 m_drawer2D->SetDrawStyle( a2dWIREFRAME );
02003 RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderWIREFRAME );
02004 }
02005 if ( documentDrawStyle & RenderWIREFRAME_ZERO_WIDTH )
02006 {
02007 m_drawer2D->SetDrawStyle( a2dWIREFRAME_ZERO_WIDTH );
02008 RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderWIREFRAME_ZERO_WIDTH );
02009 }
02010 if ( documentDrawStyle & RenderWIREFRAME_INVERT )
02011 {
02012 m_drawer2D->SetDrawStyle( a2dWIREFRAME_INVERT );
02013 RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderWIREFRAME_INVERT );
02014 }
02015 if ( documentDrawStyle & RenderWIREFRAME_INVERT_ZERO_WIDTH )
02016 {
02017 m_drawer2D->SetDrawStyle( a2dWIREFRAME_INVERT_ZERO_WIDTH );
02018 RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderWIREFRAME_INVERT_ZERO_WIDTH );
02019 }
02020 if ( documentDrawStyle & RenderFIX_STYLE )
02021 {
02022 m_drawer2D->SetDrawerFill( m_fixFill );
02023 m_drawer2D->SetDrawerStroke( m_fixStroke );
02024 m_drawer2D->SetDrawStyle( a2dFIX_STYLE );
02025 RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderFIX_STYLE );
02026 m_drawer2D->ResetFixedStyle();
02027 }
02028 if ( documentDrawStyle & RenderRectangles )
02029 {
02030 m_drawer2D->SetDrawerFill( m_fixFill );
02031 m_drawer2D->SetDrawerStroke( m_fixStroke );
02032 m_drawer2D->SetDrawStyle( a2dFIX_STYLE );
02033 RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderRectangles );
02034 m_drawer2D->ResetFixedStyle();
02035 }
02036
02037 if ( documentDrawStyle & RenderWIREFRAME_HighLight )
02038 {
02039 m_drawer2D->SetDrawerFill( m_highLightFill );
02040 m_drawer2D->SetDrawerStroke( m_highLightStroke );
02041 m_drawer2D->SetDrawStyle( a2dFIX_STYLE );
02042 RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderWIREFRAME_HighLight );
02043 m_drawer2D->ResetFixedStyle();
02044 }
02045
02046 if ( documentDrawStyle & RenderTOOL_OBJECTS )
02047 {
02048
02049 m_drawer2D->SetDrawerFill( m_fixFill );
02050 m_drawer2D->SetDrawerStroke( m_fixStroke );
02051 m_drawer2D->SetDrawStyle( a2dFIX_STYLE );
02052 RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderTOOL_OBJECTS );
02053 m_drawer2D->ResetFixedStyle();
02054 }
02055
02056 if ( documentDrawStyle & RenderTOOL_OBJECTS_STYLED )
02057 {
02058 m_drawer2D->SetDrawStyle( a2dFILLED );
02059 RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderTOOL_OBJECTS_STYLED );
02060 }
02061
02062 if ( documentDrawStyle & RenderRectangleTOOL_OBJECTS )
02063 {
02064 m_drawer2D->SetDrawerFill( m_fixFill );
02065 m_drawer2D->SetDrawerStroke( m_fixStroke );
02066 m_drawer2D->SetDrawStyle( a2dFIX_STYLE );
02067 RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderRectangleTOOL_OBJECTS );
02068 m_drawer2D->ResetFixedStyle();
02069 }
02070
02071 if ( documentDrawStyle & RenderTOOL_DECORATIONS )
02072 {
02073 m_drawer2D->SetDrawStyle( a2dFILLED );
02074 RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderTOOL_DECORATIONS );
02075 }
02076
02077
02078 if ( documentDrawStyle & RenderWIREFRAME_SELECT )
02079 {
02080 m_drawer2D->SetDrawerFill( m_selectFill );
02081 m_drawer2D->SetDrawerStroke( m_selectStroke );
02082 m_drawer2D->SetDrawStyle( a2dFIX_STYLE );
02083 RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderWIREFRAME_SELECT );
02084 m_drawer2D->ResetFixedStyle();
02085 }
02086 if ( documentDrawStyle & RenderWIREFRAME_SELECT_INVERT )
02087 {
02088 m_drawer2D->SetDrawerFill( m_selectFill );
02089 m_drawer2D->SetDrawerStroke( m_selectStroke );
02090 m_drawer2D->SetDrawStyle( a2dFIX_STYLE_INVERT );
02091 RenderTopObject( a2dCanvasOFlags::VISIBLE, RenderWIREFRAME_SELECT_INVERT );
02092 m_drawer2D->ResetFixedStyle();
02093 }
02094
02095 m_drawer2D->SetDrawStyle( a2dFILLED );
02096 }
02097
02098 void a2dCanvasView::RenderOverlay( a2dDocumentRenderStyle documentDrawStyle )
02099 {
02100 if ( m_overlayObjects.empty() )
02101 return;
02102
02103 if ( documentDrawStyle & RenderLAYERED )
02104 {
02105 m_drawer2D->SetDrawStyle( a2dFILLED );
02106 }
02107 if ( documentDrawStyle & RenderWIREFRAME )
02108 {
02109 m_drawer2D->SetDrawStyle( a2dWIREFRAME );
02110 }
02111 if ( documentDrawStyle & RenderWIREFRAME_ZERO_WIDTH )
02112 {
02113 m_drawer2D->SetDrawStyle( a2dWIREFRAME_ZERO_WIDTH );
02114 }
02115 if ( documentDrawStyle & RenderWIREFRAME_INVERT )
02116 {
02117 m_drawer2D->SetDrawStyle( a2dWIREFRAME_INVERT );
02118 }
02119 if ( documentDrawStyle & RenderWIREFRAME_INVERT_ZERO_WIDTH )
02120 {
02121 m_drawer2D->SetDrawStyle( a2dWIREFRAME_INVERT_ZERO_WIDTH );
02122 }
02123 if ( documentDrawStyle & RenderFIX_STYLE )
02124 {
02125 m_drawer2D->SetDrawerFill( m_fixFill );
02126 m_drawer2D->SetDrawerStroke( m_fixStroke );
02127 m_drawer2D->SetDrawStyle( a2dFIX_STYLE );
02128 }
02129 if ( documentDrawStyle & RenderRectangles )
02130 {
02131 m_drawer2D->SetDrawerFill( m_fixFill );
02132 m_drawer2D->SetDrawerStroke( m_fixStroke );
02133 m_drawer2D->SetDrawStyle( a2dFIX_STYLE );
02134 }
02135
02136 if ( documentDrawStyle & RenderWIREFRAME_HighLight )
02137 {
02138 m_drawer2D->SetDrawerFill( m_highLightFill );
02139 m_drawer2D->SetDrawerStroke( m_highLightStroke );
02140
02141
02142 m_drawer2D->SetDrawStyle( a2dFIX_STYLE );
02143 }
02144
02145 if ( documentDrawStyle & RenderTOOL_OBJECTS )
02146 {
02147
02148 m_drawer2D->SetDrawerFill( m_fixFill );
02149 m_drawer2D->SetDrawerStroke( m_fixStroke );
02150 m_drawer2D->SetDrawStyle( a2dFIX_STYLE );
02151 }
02152
02153 if ( documentDrawStyle & RenderTOOL_OBJECTS_STYLED )
02154 {
02155 m_drawer2D->SetDrawStyle( a2dFILLED );
02156 }
02157
02158 if ( documentDrawStyle & RenderRectangleTOOL_OBJECTS )
02159 {
02160 m_drawer2D->SetDrawerFill( m_fixFill );
02161 m_drawer2D->SetDrawerStroke( m_fixStroke );
02162 m_drawer2D->SetDrawStyle( a2dFIX_STYLE );
02163 }
02164
02165 if ( documentDrawStyle & RenderTOOL_DECORATIONS )
02166 {
02167 m_drawer2D->SetDrawStyle( a2dFILLED );
02168 }
02169
02170
02171 if ( documentDrawStyle & RenderWIREFRAME_SELECT )
02172 {
02173 m_drawer2D->SetDrawerFill( m_selectFill );
02174 m_drawer2D->SetDrawerStroke( m_selectStroke );
02175 m_drawer2D->SetDrawStyle( a2dFIX_STYLE );
02176 }
02177 if ( documentDrawStyle & RenderWIREFRAME_SELECT_INVERT )
02178 {
02179 m_drawer2D->SetDrawerFill( m_selectFill );
02180 m_drawer2D->SetDrawerStroke( m_selectStroke );
02181 m_drawer2D->SetDrawStyle( a2dFIX_STYLE_INVERT );
02182 }
02183
02184 a2dAffineMatrix cworld= m_top->GetTransformMatrix();
02185 cworld.Invert();
02186
02187
02188
02189
02190
02191 OVERLAP clipparent = _IN;
02192 {
02193 a2dCanvasObjectList::iterator iter = m_overlayObjects.begin();
02194 for( iter = m_overlayObjects.begin(); iter != m_overlayObjects.end(); ++iter )
02195 {
02196 a2dCanvasObjectList::value_type obj = *iter;
02197 a2dIterC ic( this );
02198 ic.SetDisableInvert( true );
02199 ic.SetPerLayerMode( false );
02200 ic.SetLayer( wxLAYER_ALL );
02201 a2dIterCU cu( ic, cworld );
02202 obj->Render( ic, clipparent );
02203 m_drawer2D->ResetFixedStyle();
02204
02205 ic.Reset();
02206 }
02207 }
02208
02209 m_drawer2D->ResetFixedStyle();
02210
02211 m_drawer2D->SetDrawStyle( a2dFILLED );
02212 }
02213
02214 void a2dCanvasView::RenderTopObject( a2dCanvasObjectFlagsMask mask, a2dDocumentRenderStyle drawstyle )
02215 {
02216 if ( GetCanvasDocument()->GetUpdatesPending() )
02217 GetCanvasDocument()->AddPendingUpdatesOldNew();
02218
02219 a2dIterC ic( this );
02220 ic.SetDisableInvert( true );
02221 ic.SetDrawStyle( drawstyle );
02222
02223
02224
02225 a2dAffineMatrix cworld= m_top->GetTransformMatrix();
02226 cworld.Invert();
02227
02228 a2dBoundingBox absarea = m_top->GetMappedBbox( cworld );
02229 OVERLAP clipparent = m_drawer2D->GetClippingBox().Intersect( absarea );
02230 if ( clipparent != _OUT )
02231 {
02232 if ( GetCanvasDocument()->GetLayerSetup() &&
02233 ( drawstyle == RenderLAYERED ||
02234 drawstyle == RenderWIREFRAME ||
02235 drawstyle == RenderWIREFRAME_ZERO_WIDTH
02236 )
02237 )
02238 {
02239 ic.SetPerLayerMode( true );
02240
02241 if ( 0 )
02242 {
02243 unsigned int j;
02244 for ( j=0; j < wxMAXLAYER; j++ )
02245 {
02246 a2dLayerInfo* layerobj;
02247 if ( m_reverse_order )
02248 layerobj = GetCanvasDocument()->GetLayerSetup()->GetReverseOrderIndex()[j];
02249 else
02250 layerobj = GetCanvasDocument()->GetLayerSetup()->GetOrderIndex()[j];
02251
02252
02253
02254 if ( layerobj == wxNullLayerInfo )
02255 break;
02256
02257
02258
02259
02260
02261
02262
02263
02264 if ( GetLayerRenderArray()[ layerobj->GetLayer() ].DoRenderLayer() &&
02265 layerobj->GetVisible()
02266 )
02267 {
02268
02269 m_drawer2D->ResetStyle();
02270 ic.SetObjectFilter( new a2dCanvasObjectFilterLayerMaskNoToolNoEdit( layerobj->GetLayer(), mask ) );
02271 ic.SetLayer( layerobj->GetLayer() );
02272
02273 a2dIterCU cu( ic, cworld );
02274 a2dWalker_RenderLayers renderLay( ic );
02275 renderLay.Start( m_top );
02276
02277 ic.Reset();
02278 }
02279
02280 }
02281 }
02282 else
02283 {
02284 unsigned int j;
02285 for ( j=0; j < wxMAXLAYER; j++ )
02286 {
02287 a2dLayerInfo* layerobj;
02288 if ( m_reverse_order )
02289 layerobj = GetCanvasDocument()->GetLayerSetup()->GetReverseOrderIndex()[j];
02290 else
02291 layerobj = GetCanvasDocument()->GetLayerSetup()->GetOrderIndex()[j];
02292
02293
02294
02295 if ( layerobj == wxNullLayerInfo )
02296 break;
02297
02298
02299
02300
02301
02302
02303
02304 if ( GetLayerRenderArray()[ layerobj->GetLayer() ].DoRenderLayer() &&
02305 layerobj->GetVisible()
02306 )
02307 {
02308
02309 m_drawer2D->ResetStyle();
02310 ic.SetObjectFilter( new a2dCanvasObjectFilterLayerMaskNoToolNoEdit( layerobj->GetLayer(), mask ) );
02311 ic.SetLayer( layerobj->GetLayer() );
02312
02313 a2dIterCU cu( ic, cworld );
02314 m_top->Render( ic, clipparent );
02315
02316 ic.Reset();
02317 }
02318 }
02319 }
02320 }
02321 else if ( drawstyle == RenderWIREFRAME_HighLight )
02322 {
02323 ic.SetPerLayerMode( false );
02324 m_drawer2D->SetDisableDrawing( true );
02325 ic.SetObjectFilter( new a2dCanvasObjectFilterHighLighted( mask ) );
02326 ic.SetLayer( wxLAYER_ALL );
02327 a2dIterCU cu( ic, cworld );
02328 m_top->Render( ic, clipparent );
02329 m_drawer2D->SetDisableDrawing( false );
02330
02331 ic.Reset();
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341 }
02342 else if ( drawstyle == RenderRectangles )
02343 {
02344 ic.SetPerLayerMode( false );
02345 a2dCanvasObjectList::iterator iter = m_top->GetChildObjectList()->begin();
02346 while( iter != m_top->GetChildObjectList()->end() )
02347 {
02348 a2dCanvasObject *obj = (*iter);
02349 a2dIterCU cu( ic, cworld );
02350 a2dBoundingBox bbox = obj->GetBbox();
02351 if ( obj->CheckMask( mask ) )
02352 m_drawer2D->DrawRoundedRectangle( bbox.GetMinX(), bbox.GetMinY(), bbox.GetWidth(), bbox.GetHeight() ,0 );
02353 iter++;
02354 }
02355 }
02356 else if ( drawstyle == RenderRectangleTOOL_OBJECTS )
02357 {
02358 ic.SetPerLayerMode( false );
02359 a2dCanvasObjectList::iterator iter = m_top->GetChildObjectList()->begin();
02360 while( iter != m_top->GetChildObjectList()->end() )
02361 {
02362 a2dCanvasObject *obj = (*iter);
02363 a2dIterCU cu( ic, cworld );
02364 a2dBoundingBox bbox = obj->GetBbox();
02365 if ( obj->CheckMask( mask ) && a2dCanvasObject::PROPID_ToolObject->GetPropertyValue( obj ))
02366 m_drawer2D->DrawRoundedRectangle( bbox.GetMinX(), bbox.GetMinY(), bbox.GetWidth(), bbox.GetHeight() ,0 );
02367 iter++;
02368 }
02369 }
02370 else if ( drawstyle == RenderTOOL_OBJECTS ||
02371 drawstyle == RenderTOOL_OBJECTS_STYLED
02372 )
02373 {
02374 ic.SetPerLayerMode( false );
02375 m_drawer2D->SetDisableDrawing( true );
02376 ic.SetObjectFilter( new a2dCanvasObjectFilterToolObjects( a2dCanvasObject::PROPID_ToolObject, mask ) );
02377 ic.SetLayer( wxLAYER_ALL );
02378
02379 a2dIterCU cu( ic, cworld );
02380 m_top->Render( ic, clipparent );
02381 m_drawer2D->SetDisableDrawing( false );
02382
02383 ic.Reset();
02384 }
02385 else if ( drawstyle == RenderTOOL_DECORATIONS )
02386 {
02387 ic.SetPerLayerMode( false );
02388 m_drawer2D->SetDisableDrawing( true );
02389 ic.SetObjectFilter( new a2dCanvasObjectFilterToolObjects( a2dCanvasObject::PROPID_ToolDecoration, mask ) );
02390 ic.SetLayer( wxLAYER_ALL );
02391
02392 a2dIterCU cu( ic, cworld );
02393 m_top->Render( ic, clipparent );
02394 m_drawer2D->SetDisableDrawing( false );
02395
02396 ic.Reset();
02397 }
02398 else if ( drawstyle == RenderWIREFRAME_SELECT ||
02399 drawstyle == RenderWIREFRAME_SELECT_INVERT
02400 )
02401 {
02402 ic.SetPerLayerMode( false );
02403 m_drawer2D->SetDisableDrawing( true );
02404 ic.SetObjectFilter( new a2dCanvasObjectFilterSelected( mask ) );
02405 ic.SetLayer( wxLAYER_ALL );
02406 a2dIterCU cu( ic, cworld );
02407 m_top->Render( ic, clipparent );
02408 m_drawer2D->SetDisableDrawing( false );
02409
02410 ic.Reset();
02411 }
02412 else
02413 {
02414 ic.SetPerLayerMode( false );
02415 m_drawer2D->SetDisableDrawing( true );
02416 ic.SetObjectFilter( new a2dCanvasObjectFilterOnlyNoMaskBlind( mask ) );
02417 ic.SetLayer( wxLAYER_ALL );
02418 a2dIterCU cu( ic, cworld );
02419 m_top->Render( ic, clipparent );
02420 m_drawer2D->SetDisableDrawing( false );
02421
02422 ic.Reset();
02423 }
02424
02425 }
02426 }
02427
02428 void a2dCanvasView::AddPendingUpdateArea( const a2dBoundingBox& box, wxUint8 id )
02429 {
02430 int xi = m_drawer2D->WorldToDeviceX( box.GetMinX());
02431 int yi = m_drawer2D->WorldToDeviceY( box.GetMinY());
02432 int wi = m_drawer2D->WorldToDeviceXRel( box.GetWidth());
02433 int hi = m_drawer2D->WorldToDeviceYRel( box.GetHeight());
02434
02435 if ( m_drawer2D->GetYaxis())
02436 {
02437 wxRect rect( xi, yi+hi, wi, -hi );
02438 rect.Inflate( 2 );
02439 AddPendingUpdateArea( rect, id );
02440
02441 }
02442 else
02443 {
02444 wxRect rect( xi, yi, wi, hi );
02445 rect.Inflate( 2 );
02446 AddPendingUpdateArea( rect, id );
02447
02448 }
02449 }
02450
02451 void a2dCanvasView::AddPendingUpdateArea( const wxRect& recnew, wxUint8 id )
02452 {
02453 AddPendingUpdateArea( recnew.x, recnew.y, recnew.width, recnew.height, id );
02454 }
02455
02456 void a2dCanvasView::AddPendingUpdateArea( int x, int y, int w, int h, wxUint8 id )
02457 {
02458
02459 if (x < 0)
02460 {
02461 w += x;
02462 x = 0;
02463 }
02464 if (w <= 0) return;
02465
02466 if (y < 0)
02467 {
02468 h += y;
02469 y = 0;
02470 }
02471 if (h <= 0) return;
02472
02473 if (x+w > m_width)
02474 {
02475 w = m_width - x;
02476 }
02477 if (w <= 0) return;
02478
02479 if (y+h > m_height)
02480 {
02481 h = m_height - y;
02482 }
02483 if (h <= 0) return;
02484
02485 int xmax = x + w;
02486 int ymax = y + h;
02487
02488 if ( id == 0 )
02489 m_tiles.FillTiles(x, y, xmax-x, ymax-y, true );
02490 else
02491 m_tiles2.FillTiles(x, y, xmax-x, ymax-y, true );
02492
02493 m_recur = false;
02494 }
02495
02496 void a2dCanvasView::AddPendingUpdateArea( a2dCanvasObject* obj, wxUint8 id, bool refsalso )
02497 {
02498 if (obj && ( obj->GetCanvasDocument() == GetCanvasDocument() || id == 1 ) )
02499 {
02500 a2dIterC ic( this );
02501 a2dIterCU cu( ic, a2dIDENTITY_MATRIX );
02502 wxRect absarea = obj->GetAbsoluteArea( ic );
02503 AddPendingUpdateArea( absarea, id );
02504
02505
02506
02507
02508
02509
02510
02511
02512
02513
02514
02515
02516
02517
02518
02519
02520
02521
02522 }
02523 }
02524
02525 bool a2dCanvasView::AddObjectPendingUpdates()
02526 {
02527 if (!GetCanvasDocument())
02528 {
02529 wxASSERT_MSG( GetCanvasDocument() != 0, wxT("invalid a2dCanvasDocument in a2dCanvasView") );
02530 return false;
02531 }
02532
02533 if ( GetCanvasDocument()->GetUpdatesPending() )
02534 {
02535
02536
02537 a2dAffineMatrix cworld= m_top->GetTransformMatrix();
02538 cworld.Invert();
02539
02540 a2dIterC ic( this );
02541 a2dIterCU cu( ic, cworld );
02542
02543 m_top->AddPending( ic );
02544 return true;
02545 }
02546 return false;
02547 }
02548
02549
02550
02551 a2dCanvasDocument* a2dCanvasView::GetCanvasDocument() const
02552 {
02553 return wxStaticCastNull( m_viewDocument.Get(), a2dCanvasDocument );
02554 }
02555
02556 void a2dCanvasView::OnSetDocument( a2dViewEvent& event )
02557 {
02558 a2dCanvasDocument* doc = (a2dCanvasDocument*) ((a2dView*)event.GetEventObject())->GetDocument();
02559
02560 m_capture = (a2dCanvasObject*)NULL;
02561
02562 a2dCanvasDocument* canvasdoc;
02563 if ( doc && m_viewDocument )
02564 {
02565 canvasdoc = wxDynamicCast( doc , a2dCanvasDocument);
02566 wxASSERT_MSG( canvasdoc != 0, wxT("a2dCanvasView::SetDocument not a a2dCanvasDocument") );
02567
02568 m_top = GetCanvasDocument()->GetRootObject();
02569
02570
02571 a2dComEvent changedShow( this, m_top, &sm_changedShowObject );
02572
02573 if ( m_toolcontroller )
02574 {
02575 m_toolcontroller->ProcessEvent( event );
02576 event.Skip();
02577 }
02578 a2dDocviewGlobals->GetEventDistributer()->ProcessEvent( changedShow );
02579
02580
02581 if ( GetCanvasDocument() )
02582 {
02583 GetCanvasDocument()->SetCanvasDocumentRecursive();
02584 Set_UpdateAvailableLayers( true);
02585 GetCanvasDocument()->AddPendingUpdatesOldNew();
02586 }
02587 }
02588 }
02589
02590 #if wxUSE_PRINTING_ARCHITECTURE
02591 wxPrintout* a2dCanvasView::OnCreatePrintout( a2dCommand* typeOfPrint )
02592 {
02593 return new a2dViewPrintout(this, m_printtitle ? GetCanvasDocument()->GetDescription() : (const wxString&)wxEmptyString, m_printfilename ? GetCanvasDocument()->GetFilename().GetFullPath() : wxString(wxT("")), typeOfPrint, m_printframe, m_printscalelimit, m_printfittopage );
02594 }
02595 #endif
02596
02597 a2dCanvasObject* a2dCanvasView::SetShowObject(const wxString& name)
02598 {
02599 m_capture = (a2dCanvasObject*)NULL;
02600
02601 if (!GetCanvasDocument())
02602 {
02603 wxASSERT_MSG( GetCanvasDocument() != 0, wxT("invalid a2dCanvasDocument in a2dCanvasView") );
02604 return (a2dCanvasObject*) NULL;
02605 }
02606
02607 a2dCanvasObject* newtop = GetCanvasDocument()->Find(name, wxT(""), 0 );
02608 if (!newtop)
02609 newtop = GetCanvasDocument()->GetRootObject();
02610
02611 m_top = newtop;
02612
02613 SetCaptured( NULL );
02614
02615 Update( a2dCANVIEW_UPDATE_OLDNEW | a2dCANVIEW_UPDATE_ALL );
02616
02617
02618 a2dComEvent changedShow( this, m_top, &sm_changedShowObject );
02619
02620 if ( m_toolcontroller )
02621 {
02622 m_toolcontroller->ProcessEvent( changedShow );
02623 changedShow.Skip();
02624 }
02625 a2dDocviewGlobals->GetEventDistributer()->ProcessEvent( changedShow );
02626
02627 return newtop;
02628 }
02629
02630 bool a2dCanvasView::SetShowObject(a2dCanvasObject* obj)
02631 {
02632 m_capture = (a2dCanvasObject*)NULL;
02633
02634 if (!GetCanvasDocument())
02635 {
02636 wxASSERT_MSG( GetCanvasDocument() != 0, wxT("invalid a2dCanvasDocument in a2dCanvasView") );
02637 return (a2dCanvasObject*) NULL;
02638 }
02639
02640
02641 a2dCanvasObject* found = GetCanvasDocument()->Find(obj);
02642 if (!found)
02643 m_top = GetCanvasDocument()->GetRootObject();
02644 else
02645 m_top = found;
02646
02647 SetCaptured( NULL );
02648
02649 Update( a2dCANVIEW_UPDATE_OLDNEW | a2dCANVIEW_UPDATE_ALL );
02650
02651 a2dComEvent changedShow( this, m_top, &sm_changedShowObject );
02652
02653 if ( m_toolcontroller )
02654 {
02655 m_toolcontroller->ProcessEvent( changedShow );
02656 changedShow.Skip();
02657 }
02658 a2dDocviewGlobals->GetEventDistributer()->ProcessEvent( changedShow );
02659
02660 return (m_top.Get() != 0);
02661 }
02662
02663 void a2dCanvasView::SetBackgroundFill( const a2dFill& backgroundfill )
02664 {
02665 m_backgroundfill = backgroundfill;
02666 Update( a2dCANVIEW_UPDATE_ALL );
02667 }
02668
02669 void a2dCanvasView::SetGridStroke( const a2dStroke& gridstroke)
02670 {
02671 m_gridstroke = gridstroke;
02672 Update( a2dCANVIEW_UPDATE_ALL );
02673 }
02674
02675 void a2dCanvasView::SetGridFill( const a2dFill& gridfill)
02676 {
02677 m_gridfill = gridfill;
02678 Update( a2dCANVIEW_UPDATE_ALL );
02679 }
02680
02681 void a2dCanvasView::SetMappingShowAll()
02682 {
02683 if (!m_top || !GetCanvasDocument())
02684 return;
02685
02686 a2dBoundingBox untr = m_top->GetBbox();
02687 a2dAffineMatrix cworld= m_top->GetTransformMatrix();
02688 cworld.Invert();
02689 untr.MapBbox(cworld);
02690
02691 double worldw = untr.GetWidth();
02692 double worldh = untr.GetHeight();
02693
02694 if ( worldw == 0 || worldh == 0 )
02695 {
02696 worldw = GetCanvasDocument()->GetInitialSizeX();
02697 worldh = GetCanvasDocument()->GetInitialSizeY();
02698 untr = a2dBoundingBox( 0, 0, worldw, worldh );
02699 }
02700
02701 double xupp = worldw/m_width;
02702 double yupp = worldh/m_height;
02703
02704 if (yupp == 0 || xupp == 0)
02705 {
02706 yupp = 1; xupp = 1;
02707 }
02708
02709 if (yupp > xupp)
02710 {
02711
02712 if ( worldw > yupp*m_width )
02713 untr.Translate( ( worldw - yupp*m_width ) / 2.0, 0 );
02714 }
02715 else
02716 {
02717 if ( worldh > xupp*m_height )
02718 untr.Translate( 0, ( worldh - xupp*m_height ) / 2.0 );
02719 }
02720
02721 m_drawer2D->SetMappingWidthHeight( untr );
02722 }
02723
02724
02725
02726
02727
02728
02729 void a2dCanvasView::DrawOrigin()
02730 {
02731 if (m_showorigin)
02732 {
02733
02734 int x = m_drawer2D->WorldToDeviceX(0.0);
02735 int y = m_drawer2D->WorldToDeviceY(0.0);
02736 int w = 10;
02737 int h = 10;
02738 m_drawer2D->SetDrawerStroke( *a2dBLACK_STROKE );
02739 m_drawer2D->SetDrawerFill( *a2dBLACK_FILL );
02740 m_drawer2D->PushIdentityTransform();
02741 m_drawer2D->DrawLine(x-w, y, w+x, y);
02742 m_drawer2D->DrawLine(x, y-h, x, y+h);
02743 m_drawer2D->PopTransform();
02744 }
02745 }
02746
02747 void a2dCanvasView::PaintGrid( int WXUNUSED(x), int WXUNUSED(y), int WXUNUSED(width), int WXUNUSED(height) )
02748 {
02749 m_drawer2D->SetDrawerStroke( m_gridstroke );
02750 m_drawer2D->SetDrawerFill( m_gridfill );
02751
02752 double dvx = m_drawer2D->GetUppX()*m_width;
02753 double dvy = m_drawer2D->GetUppY()*m_height;
02754
02755 double min_x = m_drawer2D->GetVisibleMinX();
02756 double max_x = m_drawer2D->GetVisibleMinX()+dvx;
02757
02758 double min_y;
02759 double max_y;
02760 if (m_drawer2D->GetYaxis())
02761 {
02762 min_y = m_drawer2D->DeviceToWorldY(m_height);
02763
02764
02765
02766 max_y = m_drawer2D->GetVisibleMinY()+dvy;
02767 }
02768 else
02769 {
02770 min_y = m_drawer2D->GetVisibleMinY();
02771 max_y = m_drawer2D->GetVisibleMinY()+dvy;
02772 }
02773
02774 double temp_x = floor(min_x/m_gridx + 0.5);
02775 double temp_y = floor(min_y/m_gridy + 0.5);
02776 min_x = temp_x*m_gridx;
02777 min_y = temp_y*m_gridy;
02778
02779 double gridx = m_gridx;
02780 double gridy = m_gridy;
02781 while ( m_drawer2D->DeviceToWorldXRel( m_gridthres ) > gridx )
02782 gridx *= 2;
02783 while ( m_drawer2D->DeviceToWorldXRel( m_gridthres ) > gridy )
02784 gridy *= 2;
02785
02786
02787 const a2dAffineMatrix worldtodevice = m_drawer2D->GetMappingMatrix();
02788
02789 if (!m_gridlines)
02790 {
02791 double i,j;
02792 for (i = min_x; i < max_x; i += gridx)
02793 {
02794 for (j = min_y; j < max_y; j += gridy)
02795 {
02796 double xi, yi;
02797 worldtodevice.TransformPoint( i, j, xi, yi );
02798 m_drawer2D->PushIdentityTransform();
02799 if (m_gridsize)
02800 m_drawer2D->DrawCircle(xi, yi, m_gridsize/2);
02801 else
02802 m_drawer2D->DrawPoint(xi, yi );
02803 m_drawer2D->PopTransform();
02804 }
02805 }
02806 }
02807 else
02808 {
02809 double i,j;
02810 for (i = min_x; i < max_x; i += gridx)
02811 {
02812 double xi, yi;
02813 worldtodevice.TransformPoint( i, 0, xi, yi );
02814 m_drawer2D->PushIdentityTransform();
02815 m_drawer2D->DrawLine(xi, 0, xi, m_height);
02816 m_drawer2D->PopTransform();
02817 }
02818 for (j = min_y; j < max_y; j += gridy)
02819 {
02820 double xi, yi;
02821 worldtodevice.TransformPoint( 0, j, xi, yi );
02822 m_drawer2D->PushIdentityTransform();
02823 m_drawer2D->DrawLine(0, yi, m_width, yi);
02824 m_drawer2D->PopTransform();
02825 }
02826 }
02827
02828 m_drawer2D->SetDrawerFill( *a2dTRANSPARENT_FILL );
02829 m_drawer2D->SetDrawerStroke( *a2dTRANSPARENT_STROKE );
02830 }
02831
02832 void a2dCanvasView::PaintBackground( int x, int y, int width, int height )
02833 {
02834 m_drawer2D->SetDrawerStroke( *a2dTRANSPARENT_STROKE );
02835 m_drawer2D->SetDrawerFill( m_backgroundfill );
02836
02837
02838
02839 if ( m_backgroundfill.GetType() == a2dFILL_GRADIENT_FILL_LINEAR || m_backgroundfill.GetType() == a2dFILL_GRADIENT_FILL_RADIAL )
02840 {
02841 a2dVertexArray cpoints;
02842
02843
02844
02845 cpoints.AddPoint( 0, -10 );
02846 cpoints.AddPoint( 0, m_height+10 );
02847 cpoints.AddPoint( m_width, m_height );
02848 cpoints.AddPoint( m_width, 0 );
02849
02850 m_drawer2D->PushIdentityTransform();
02851 m_drawer2D->DrawPolygon( &cpoints );
02852 m_drawer2D->PopTransform();
02853 }
02854 else
02855 {
02856 m_drawer2D->PushIdentityTransform();
02857 m_drawer2D->DrawRoundedRectangle( x, y, width, height, 0 );
02858 m_drawer2D->PopTransform();
02859 }
02860 m_drawer2D->SetDrawerFill( *a2dTRANSPARENT_FILL );
02861 m_drawer2D->SetDrawerStroke( *a2dTRANSPARENT_STROKE );
02862
02863
02864 #if 0
02865 m_drawer2D->PushIdentityTransform();
02866 m_drawer2D->SetDrawerFill( a2dFill( wxColour(rand()%254,rand()%254,rand()%254) ) );
02867 m_drawer2D->DrawRoundedRectangle( x, y, width, height, 0 );
02868 m_drawer2D->PopTransform();
02869 #endif
02870 }
02871
02872 void a2dCanvasView::UpdateCrossHair( int x, int y )
02873 {
02874 if ( !m_crosshair )
02875 return;
02876
02877 m_drawer2D->BeginDraw();
02878 m_drawer2D->PushIdentityTransform();
02879 m_drawer2D->SetDrawStyle( a2dWIREFRAME_INVERT );
02880
02881 wxRect rect1( m_crosshairx - m_crosshairLengthX/2-10, m_crosshairy - m_crosshairLengthY/2-10,
02882 m_crosshairLengthX+20, m_crosshairLengthY+20 );
02883
02884
02885 m_drawer2D->SetDrawerStroke( m_crosshairStroke );
02886
02887 m_drawer2D->DrawLine( m_crosshairx, m_crosshairy - m_crosshairLengthY/2, m_crosshairx, m_crosshairy + m_crosshairLengthY/2 );
02888 m_drawer2D->DrawLine( m_crosshairx - m_crosshairLengthX/2, m_crosshairy, m_crosshairx + m_crosshairLengthX/2, m_crosshairy );
02889
02890 m_crosshairx = x;
02891 m_crosshairy = y;
02892
02893 m_drawer2D->DrawLine( m_crosshairx, m_crosshairy - m_crosshairLengthY/2, m_crosshairx, m_crosshairy + m_crosshairLengthY/2 );
02894 m_drawer2D->DrawLine( m_crosshairx - m_crosshairLengthX/2, m_crosshairy, m_crosshairx + m_crosshairLengthX/2, m_crosshairy );
02895
02896 m_drawer2D->BlitBuffer( rect1 );
02897
02898 wxRect rect( m_crosshairx - m_crosshairLengthX/2-10, m_crosshairy - m_crosshairLengthY/2-10,
02899 m_crosshairLengthX+20, m_crosshairLengthY+20 );
02900 m_drawer2D->BlitBuffer( rect );
02901
02902 m_drawer2D->SetDrawerStroke( *a2dTRANSPARENT_STROKE );
02903
02904 m_drawer2D->PopTransform();
02905 m_drawer2D->EndDraw();
02906 m_drawer2D->SetDrawStyle( a2dFILLED );
02907 }
02908
02909 void a2dCanvasView::Scroll( int dxy, bool yscroll, bool total)
02910 {
02911 bool gradient = ( m_backgroundfill.GetType() == a2dFILL_GRADIENT_FILL_LINEAR || m_backgroundfill.GetType() == a2dFILL_GRADIENT_FILL_RADIAL );
02912 int bw = m_width;
02913 int bh = m_height;
02914 if (yscroll)
02915 {
02916 if ( total || gradient )
02917 {
02918 AddPendingUpdateArea( 0, 0, bw, bh );
02919 }
02920 else
02921 {
02922 if (dxy > 0 && dxy < bh )
02923 {
02924 m_drawer2D->ShiftBuffer( dxy, yscroll );
02925 AddPendingUpdateArea( 0, 0, bw, dxy);
02926 }
02927 else if (dxy < 0 && dxy > -bh)
02928 {
02929 m_drawer2D->ShiftBuffer( dxy, yscroll );
02930 AddPendingUpdateArea( 0, bh+dxy, bw, -dxy);
02931 }
02932 else
02933 AddPendingUpdateArea( 0, 0, bw, bh);
02934 }
02935 }
02936 else
02937 {
02938 if ( total || gradient )
02939 {
02940 AddPendingUpdateArea( 0, 0, bw, bh );
02941 }
02942 else
02943 {
02944 if (dxy > 0 && dxy < bw)
02945 {
02946 m_drawer2D->ShiftBuffer( dxy, yscroll );
02947 AddPendingUpdateArea( 0, 0, dxy, bh );
02948 }
02949 else if (dxy < 0 && dxy > -bw )
02950 {
02951 m_drawer2D->ShiftBuffer( dxy, yscroll );
02952 AddPendingUpdateArea( bw+dxy, 0, -dxy, bh );
02953 }
02954 else
02955 AddPendingUpdateArea( 0,0, bw, bh );
02956 }
02957 }
02958
02959
02960 RedrawPendingUpdateAreas();
02961 }
02962
02963 IMPLEMENT_CLASS( a2dZoomedView, wxWindow )
02964
02965 BEGIN_EVENT_TABLE( a2dZoomedView, wxWindow )
02966 EVT_UPDATE_VIEWS( a2dZoomedView::OnUpdate )
02967 EVT_COM_EVENT( a2dZoomedView::OnComEvent )
02968 EVT_PAINT( a2dZoomedView::OnPaint )
02969 EVT_SIZE( a2dZoomedView::OnSize )
02970 EVT_REMOVE_VIEW( a2dZoomedView::OnRemoveView )
02971 END_EVENT_TABLE()
02972
02973 a2dZoomedView::a2dZoomedView( wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, a2dCanvasView* canvasview ):
02974 wxWindow( parent, id, pos, size, style )
02975 {
02976 a2dDocviewGlobals->GetEventDistributer()->Register( this );
02977
02978 m_canvasDocview = canvasview;
02979 }
02980
02981 a2dZoomedView::~a2dZoomedView()
02982 {
02983 a2dDocviewGlobals->GetEventDistributer()->Unregister( this );
02984 }
02985
02986 void a2dZoomedView::OnUpdate( a2dDocumentEvent& event )
02987 {
02988 if ( !m_canvasDocview || m_canvasDocview->GetCanvasDocument() != event.GetEventObject() )
02989 return;
02990
02991 if ( !GetEvtHandlerEnabled() )
02992 return;
02993
02994 if ( !m_canvasDocview || m_canvasDocview->GetCanvasDocument() )
02995 return;
02996
02997
02998 }
02999
03000 void a2dZoomedView::OnPaint(wxPaintEvent& WXUNUSED(event) )
03001 {
03002 if ( !m_canvasDocview || m_canvasDocview->IsClosed() )
03003 {
03004 wxPaintDC dc( this );
03005 return;
03006 }
03007
03008 wxPaintDC dc(this);
03009
03010 int dvx, dvy;
03011 GetClientSize(&dvx,&dvy);
03012 if ( dvx == 0 ) dvx = 1;
03013 if ( dvy == 0 ) dvy = 1;
03014
03015
03016 double w = m_canvasDocview->GetCanvasDocument()->GetBboxWidth();
03017 double h = m_canvasDocview->GetCanvasDocument()->GetBboxHeight();
03018 double xview = m_canvasDocview->GetDrawer2D()->GetVisibleMinX();
03019 double yview = m_canvasDocview->GetDrawer2D()->GetVisibleMinY();
03020 double wview = m_canvasDocview->GetDrawer2D()->GetVisibleWidth();
03021 double hview = m_canvasDocview->GetDrawer2D()->GetVisibleHeight();
03022
03023 if ( h * dvx/w < dvy )
03024 {
03025
03026 dc.DrawRectangle(0,0, dvx, (int) (h * dvx/w) );
03027 dc.DrawRectangle( (int) (xview* dvx/w), (int) (yview* dvx/w), (int) (wview* dvx/w), (int) (hview* dvx/w) );
03028 }
03029 else
03030 {
03031
03032 dc.DrawRectangle(0,0, (int) (w * dvx/h), dvy );
03033 dc.DrawRectangle( (int) (xview* dvy/h), (int) (yview* dvy/h), (int) (wview* dvy/h), (int) (hview* dvy/h) );
03034 }
03035
03036 }
03037
03038 void a2dZoomedView::OnSize( wxSizeEvent& WXUNUSED(event) )
03039 {
03040 Refresh();
03041 }
03042
03043
03044 void a2dZoomedView::OnComEvent( a2dComEvent& event )
03045 {
03046 if ( event.GetEventComId() == &a2dDrawer2D::sm_changedZoom)
03047 {
03048 Refresh();
03049 }
03050 }
03051
03052 void a2dZoomedView::OnRemoveView( a2dDocumentEvent& event )
03053 {
03054 a2dView* viewremoved = (a2dView*) event.GetView();
03055 if ( viewremoved == m_canvasDocview )
03056 m_canvasDocview = NULL;
03057 }
03058