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/canmod.h"
00022 #include "wx/filename.h"
00023
00024 #include "wx/editor/sttool.h"
00025 #include "wx/editor/edit.h"
00026 #include "wx/editor/candocproc.h"
00027
00028 #if defined(__WXMSW__) && defined(__MEMDEBUG__)
00029 #include <wx/msw/msvcrt.h>
00030 #endif
00031
00032 #define CDRAWER2D GetCanvasView()->GetDrawer2D()
00033
00034
00035
00036
00037
00038 IMPLEMENT_CLASS(a2dStToolContr, a2dToolContr)
00039 IMPLEMENT_CLASS(a2dStTool,a2dBaseTool)
00040 IMPLEMENT_CLASS(a2dZoomTool,a2dStTool)
00041 IMPLEMENT_CLASS(a2dDragTool,a2dStTool)
00042 IMPLEMENT_CLASS(a2dDragOrgTool,a2dStTool)
00043 IMPLEMENT_CLASS(a2dDragNewTool,a2dDragTool)
00044 IMPLEMENT_CLASS(a2dCopyTool,a2dDragTool)
00045 IMPLEMENT_CLASS(a2dRotateTool,a2dStTool)
00046 IMPLEMENT_CLASS(a2dDeleteTool, a2dStTool)
00047 IMPLEMENT_CLASS(a2dSelectTool, a2dStTool)
00048 IMPLEMENT_CLASS(a2dStDrawTool, a2dStTool)
00049 IMPLEMENT_CLASS(a2dImageTool, a2dStDrawTool)
00050 IMPLEMENT_CLASS(a2dDrawRectangleTool, a2dStDrawTool)
00051 IMPLEMENT_CLASS(a2dDrawCircleTool, a2dStDrawTool)
00052 IMPLEMENT_CLASS(a2dDrawLineTool, a2dStDrawTool)
00053 IMPLEMENT_CLASS(a2dDrawEllipseTool, a2dStDrawTool)
00054 IMPLEMENT_CLASS(a2dDrawEllipticArcTool, a2dStDrawTool)
00055 IMPLEMENT_CLASS(a2dDrawArcTool, a2dStDrawTool)
00056 IMPLEMENT_CLASS(a2dDrawPolylineLTool, a2dStDrawTool)
00057 IMPLEMENT_CLASS(a2dDrawWirePolylineLTool, a2dDrawPolylineLTool)
00058 IMPLEMENT_CLASS(a2dDrawPolygonLTool, a2dStDrawTool)
00059 IMPLEMENT_CLASS(a2dDrawVPathTool, a2dStDrawTool)
00060 IMPLEMENT_CLASS(a2dDrawTextTool, a2dStDrawTool)
00061 IMPLEMENT_CLASS(a2dDragMultiTool,a2dStTool)
00062 IMPLEMENT_CLASS(a2dCopyMultiTool,a2dDragMultiTool)
00063 IMPLEMENT_CLASS(a2dPropertyTool, a2dStTool)
00064
00065 const a2dCommandId a2dDrawRectangleTool::COMID_PushTool_DrawRectangle( wxT("PushTool_DrawRectangle") );
00066 const a2dCommandId a2dZoomTool::COMID_PushTool_Zoom( wxT("PushTool_Zoom") );
00067 const a2dCommandId a2dSelectTool::COMID_PushTool_Select( wxT("PushTool_Select") );
00068 const a2dCommandId a2dImageTool::COMID_PushTool_Image( wxT("PushTool_Image") );
00069 const a2dCommandId a2dDragTool::COMID_PushTool_Drag( wxT("PushTool_Drag") );
00070 const a2dCommandId a2dDragOrgTool::COMID_PushTool_DragOrg( wxT("PushTool_DragOrg") );
00071 const a2dCommandId a2dDragNewTool::COMID_PushTool_DragNew( wxT("PushTool_DragNew") );
00072 const a2dCommandId a2dCopyTool::COMID_PushTool_Copy( wxT("PushTool_Copy") );
00073 const a2dCommandId a2dRotateTool::COMID_PushTool_Rotate( wxT("PushTool_Rotate") );
00074 const a2dCommandId a2dDeleteTool::COMID_PushTool_Delete( wxT("PushTool_Delete") );
00075 const a2dCommandId a2dDrawCircleTool::COMID_PushTool_DrawCircle( wxT("PushTool_DrawCircle") );
00076 const a2dCommandId a2dDrawLineTool::COMID_PushTool_DrawLine( wxT("PushTool_DrawLine") );
00077 const a2dCommandId a2dDrawLineTool::COMID_PushTool_DrawLineScaledArrow( wxT("PushTool_DrawLineScaledArrow") );
00078 const a2dCommandId a2dDrawEllipseTool::COMID_PushTool_DrawEllipse( wxT("PushTool_DrawEllipse") );
00079 const a2dCommandId a2dDrawEllipticArcTool::COMID_PushTool_DrawEllipticArc( wxT("PushTool_EllipticArc") );
00080 const a2dCommandId a2dDrawEllipticArcTool::COMID_PushTool_DrawEllipticArc_Chord( wxT("PushTool_EllipticArcChord") );
00081 const a2dCommandId a2dDrawArcTool::COMID_PushTool_DrawArc( wxT("PushTool_DrawArc") );
00082 const a2dCommandId a2dDrawArcTool::COMID_PushTool_DrawArc_Chord( wxT("PushTool_DrawArcChord") );
00083 const a2dCommandId a2dDrawPolygonLTool::COMID_PushTool_DrawPolygonL( wxT("PushTool_DrawPolygonL") );
00084 const a2dCommandId a2dDrawPolygonLTool::COMID_PushTool_DrawPolygonL_Splined( wxT("PushTool_DrawPolygonL_Splined") );
00085 const a2dCommandId a2dDrawPolylineLTool::COMID_PushTool_DrawPolylineL( wxT("PushTool_DrawPolylineL") );
00086 const a2dCommandId a2dDrawPolylineLTool::COMID_PushTool_DrawPolylineL_Splined( wxT("PushTool_DrawPolylineL_Splined") );
00087 const a2dCommandId a2dDrawWirePolylineLTool::COMID_PushTool_DrawWirePolylineL( wxT("PushTool_DrawWirePolylineL") );
00088 const a2dCommandId a2dDragMultiTool::COMID_PushTool_DragMulti( wxT("PushTool_DragMulti") );
00089 const a2dCommandId a2dCopyMultiTool::COMID_PushTool_CopyMulti( wxT("PushTool_CopyMulti") );
00090 const a2dCommandId a2dDrawTextTool::COMID_PushTool_DrawText( wxT("PushTool_DrawText") );
00091 const a2dCommandId a2dPropertyTool::COMID_PushTool_Property( wxT("PushTool_Property") );
00092 const a2dCommandId a2dDrawVPathTool::COMID_PushTool_DrawVPath( wxT("PushTool_DrawVPath") );
00093
00094
00095 WX_DEFINE_LIST( wxZoomList );
00096
00097 extern const long TC_UNDO = wxNewId();
00098 extern const long TC_REDO = wxNewId();
00099 extern const long TC_ENDTOOL = wxNewId();
00100 extern const long TC_ZOOMIN = wxNewId();
00101 extern const long TC_ZOOMOUT = wxNewId();
00102 extern const long TC_ZOOMBACK = wxNewId();
00103 extern const long TC_ZOOMOUT2 = wxNewId();
00104 extern const long TC_ZOOMIN2 = wxNewId();
00105 extern const long TC_ZOOMPANXY = wxNewId();
00106 extern const long TC_PROPERTY_XY = wxNewId();
00107
00108 #define DEFAULTOpacityFactor 125 ;
00109
00110
00111 const a2dPropertyIdBool a2dStToolContr::PROPID_zoomfirst( wxT("zoomfirst"), a2dPropertyId::flag_none, false );
00112
00113 DEFINE_EVENT_TYPE( a2dStToolContr::sm_showCursor )
00114
00115 A2D_BEGIN_EVENT_TABLE(a2dStToolContr, a2dToolContr)
00116 A2D_EVT_COM_EVENT( a2dStToolContr::OnComEvent )
00117 A2D_EVT_MOUSE_EVENTS(a2dStToolContr::OnMouseEvent)
00118 A2D_EVT_CHAR(a2dStToolContr::OnChar)
00119 A2D_EVT_KEY_DOWN(a2dStToolContr::OnKeyDown)
00120 A2D_EVT_KEY_UP(a2dStToolContr::OnKeyUp)
00121 A2D_EVT_MENU( TC_UNDO ,a2dStToolContr::Undo)
00122 A2D_EVT_MENU( TC_REDO ,a2dStToolContr::Redo)
00123 A2D_EVT_MENU( TC_ENDTOOL ,a2dStToolContr::EndTool)
00124 A2D_EVT_MENU( TC_ZOOMIN ,a2dStToolContr::ZoomWindowMenu)
00125 A2D_EVT_MENU( TC_ZOOMBACK ,a2dStToolContr::ZoomUndoMenu)
00126 A2D_EVT_MENU( TC_ZOOMOUT ,a2dStToolContr::ZoomoutMenu)
00127 A2D_EVT_MENU( TC_ZOOMPANXY ,a2dStToolContr::ZoomPanMenu)
00128 A2D_EVT_MENU( TC_ZOOMOUT2 ,a2dStToolContr::Zoomout2Menu)
00129 A2D_EVT_MENU( TC_ZOOMIN2 ,a2dStToolContr::Zoomin2Menu)
00130 A2D_EVT_MENU( TC_PROPERTY_XY ,a2dStToolContr::EditProperties)
00131 A2D_EVT_MENUSTRINGS( a2dStToolContr::OnSetmenuStrings )
00132
00133 A2D_END_EVENT_TABLE()
00134
00135
00136 a2dStToolContr::a2dStToolContr(a2dCanvasView* view, wxFrame* where): a2dToolContr(view)
00137 {
00138 m_view->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW ) );
00139
00140 m_useEditOpaque = false;
00141 m_editOpacityFactor = DEFAULTOpacityFactor;
00142 m_zoomoutCentered = true;
00143
00144 m_show_mousepos = true;
00145
00146 m_dragmode = wxDRAW_COPY;
00147 m_drawmode = a2dFILLED;
00148 m_defaultBehavior = wxTC_DefaultBehavior;
00149 m_where = where;
00150
00151 m_topTool = NULL;
00152 m_toolForZoom = new a2dZoomTool(this);
00153
00154
00155
00156
00157 m_mousemenu = new wxMenu( _("ZOOM"),(long)0);
00158 m_mousemenu->Append(TC_ENDTOOL, _("end tool"));
00159 m_mousemenu->AppendSeparator();
00160 m_mousemenu->Append(TC_UNDO, _("undo"));
00161 m_mousemenu->Append(TC_REDO, _("redo"));
00162 m_mousemenu->AppendSeparator();
00163 m_mousemenu->Append(TC_ZOOMIN, _("Zoom Window"));
00164 m_mousemenu->Append(TC_ZOOMBACK, _("Zoom Undo"));
00165 m_mousemenu->Append(TC_ZOOMOUT, _("Zoom out"));
00166 m_mousemenu->Append(TC_ZOOMOUT2, _("Zoom out 2X"));
00167 m_mousemenu->Append(TC_ZOOMIN2, _("Zoom in 2X"));
00168 m_mousemenu->Append(TC_ZOOMPANXY, _("Pan to XY"));
00169 m_mousemenu->Append(TC_PROPERTY_XY, _("Edit Properties"));
00170 }
00171
00172
00173 a2dStToolContr::~a2dStToolContr()
00174 {
00175 if(m_mousemenu)
00176 delete m_mousemenu;
00177
00178 m_view = NULL;
00179
00180 a2dSmrtPtr< a2dBaseTool > tool;
00181 a2dToolContr::PopTool( tool );
00182 while ( tool )
00183 {
00184 tool = NULL;
00185 a2dToolContr::PopTool( tool );
00186 }
00187
00188 m_zoomstack.DeleteContents( true );
00189 }
00190
00191 void a2dStToolContr::ReStart()
00192 {
00193 StopAllTools();
00194 if ( m_topTool )
00195 {
00196 m_topTool->ResetContext();
00197 PushTool(m_topTool);
00198 }
00199 }
00200
00201 void a2dStToolContr::SetMousePopupMenu( wxMenu* mousemenu )
00202 {
00203 if ( m_mousemenu )
00204 delete m_mousemenu;
00205 m_mousemenu = mousemenu;
00206 }
00207
00208 void a2dStToolContr::Undo( wxCommandEvent& )
00209 {
00210 a2dCanvasDocument *doc = m_view->GetCanvasDocument();
00211 doc->GetCommandProcessor()->Undo();
00212 }
00213
00214 void a2dStToolContr::Redo( wxCommandEvent& )
00215 {
00216 a2dCanvasDocument *doc = m_view->GetCanvasDocument();
00217 doc->GetCommandProcessor()->Redo();
00218 }
00219
00220 void a2dStToolContr::EndTool( wxCommandEvent& )
00221 {
00222 a2dSmrtPtr< a2dBaseTool > tool;
00223 if ( GetFirstTool() && GetFirstTool()->AllowPop() )
00224 PopTool( tool );
00225 }
00226
00227 void a2dStToolContr::EditProperties( wxCommandEvent& )
00228 {
00229 a2dPropertyTool* propedit = new a2dPropertyTool(this);
00230 PushTool( propedit );
00231 propedit->SetOneShot();
00232 propedit->StartEditing( m_mouse_x, m_mouse_y );
00233 }
00234
00235 void a2dStToolContr::OnSetmenuStrings( a2dCommandProcessorEvent& event )
00236 {
00237 if ( m_view->GetDocument() &&
00238 m_view->GetDocument()->GetCommandProcessor() &&
00239 event.GetEventObject() == m_view->GetDocument()->GetCommandProcessor() &&
00240 m_mousemenu
00241 )
00242 {
00243 if ( m_mousemenu->FindItem( TC_UNDO ) )
00244 {
00245 m_mousemenu->SetLabel(TC_UNDO, event.GetUndoMenuLabel());
00246 m_mousemenu->Enable(TC_UNDO, event.CanUndo());
00247 }
00248 if ( m_mousemenu->FindItem( TC_REDO ) )
00249 {
00250 m_mousemenu->SetLabel(TC_REDO, event.GetRedoMenuLabel());
00251 m_mousemenu->Enable(TC_REDO, event.CanRedo());
00252 }
00253 }
00254 }
00255
00256 void a2dStToolContr::SetZoomFirst( bool zoomfirst )
00257 {
00258 if ( !GetFirstTool() && zoomfirst)
00259 {
00260 m_topTool = m_toolForZoom;
00261 PushTool(m_topTool);
00262 }
00263 }
00264
00265 void a2dStToolContr::SetTopTool( a2dBaseTool* toolOnTop )
00266 {
00267 m_topTool = toolOnTop;
00268 if ( !GetFirstTool() && m_topTool )
00269 PushTool(m_topTool);
00270 }
00271
00272 void a2dStToolContr::SetZoomTool( a2dBaseTool* toolForZoom )
00273 {
00274 wxASSERT_MSG( wxDynamicCast( toolForZoom, a2dStTool) != 0, wxT("Only a2dStTool can be pushed into a2dStToolContr, and not NULL") );
00275 m_toolForZoom = toolForZoom;
00276 }
00277
00278 void a2dStToolContr::ZoomWindowMenu( wxCommandEvent& )
00279 {
00280 ZoomWindow();
00281 }
00282
00283 void a2dStToolContr::ZoomPanMenu( wxCommandEvent& )
00284 {
00285 ZoomPan();
00286 }
00287
00288 void a2dStToolContr::ZoomUndoMenu( wxCommandEvent& )
00289 {
00290 ZoomUndo();
00291 }
00292
00293 void a2dStToolContr::ZoomoutMenu( wxCommandEvent& )
00294 {
00295 Zoomout();
00296 }
00297
00298 void a2dStToolContr::Zoomout2Menu( wxCommandEvent& )
00299 {
00300 Zoomout2();
00301 }
00302
00303 void a2dStToolContr::Zoomin2Menu( wxCommandEvent& )
00304 {
00305 Zoomin2();
00306 }
00307
00308 void a2dStToolContr::ZoomWindow()
00309 {
00310 a2dBaseTool* tool = m_toolForZoom->TClone( clone_deep );
00311 tool->SetOneShot();
00312 PushTool( tool );
00313 }
00314
00315 void a2dStToolContr::ZoomPan()
00316 {
00317 double mouse_worldx, mouse_worldy;
00318 GetCanvasView()->MouseToToolWorld( m_mouse_x, m_mouse_y, mouse_worldx, mouse_worldy );
00319 mouse_worldx -= CDRAWER2D->GetVisibleWidth()/2;
00320 mouse_worldy -= CDRAWER2D->GetVisibleHeight()/2;
00321
00322 Zoom( mouse_worldx, mouse_worldy, CDRAWER2D->GetUppX(), CDRAWER2D->GetUppY());
00323 }
00324
00325 void a2dStToolContr::ZoomUndo()
00326 {
00327 a2dBoundingBox zoom;
00328 if (!m_zoomstack.size())
00329 {
00330 Zoomout();
00331 return;
00332 }
00333 wxZoomList::compatibility_iterator node=m_zoomstack.GetFirst();
00334 zoom=*node->GetData();
00335 delete node->GetData();
00336 m_zoomstack.DeleteNode(node);
00337
00338 CDRAWER2D->SetMappingWidthHeight( zoom.GetMinX(),zoom.GetMinY(),zoom.GetWidth(),zoom.GetHeight() );
00339 }
00340
00341 void a2dStToolContr::Zoomout()
00342 {
00343 if ( wxDynamicCast( m_view->GetDisplayWindow(), a2dCanvas ) )
00344 {
00345 a2dCanvas* can = wxStaticCast( m_view->GetDisplayWindow(), a2dCanvas );
00346 can->SetMappingShowAll(m_zoomoutCentered);
00347 }
00348 else if ( wxDynamicCast( m_view->GetDisplayWindow(), a2dCanvasSim ) )
00349 {
00350 a2dCanvasSim* can = wxStaticCast( m_view->GetDisplayWindow(), a2dCanvasSim );
00351 can->SetMappingShowAll(m_zoomoutCentered);
00352 }
00353 else
00354 wxASSERT_MSG( 0, wxT("not implemented for this type of canvas") );
00355 a2dDocviewGlobals->RecordF( this, _T("zoomout") );
00356 }
00357
00358 void a2dStToolContr::Zoomout2()
00359 {
00360 int dx,dy;
00361 m_view->GetDisplayWindow()->GetClientSize(&dx,&dy);
00362 if (dy > dx) dx=dy;
00363
00364 Zoom( CDRAWER2D->GetVisibleMinX()-CDRAWER2D->GetUppX()*dx/2,
00365 CDRAWER2D->GetVisibleMinY()-CDRAWER2D->GetUppY()*dy/2,
00366 CDRAWER2D->GetUppX()*2, CDRAWER2D->GetUppY()*2);
00367 }
00368
00369 void a2dStToolContr::Zoomin2()
00370 {
00371 int dx,dy;
00372 m_view->GetDisplayWindow()->GetClientSize(&dx,&dy);
00373 if (dy > dx) dx=dy;
00374
00375 Zoom( CDRAWER2D->GetVisibleMinX()+CDRAWER2D->GetUppX()*dx/4,
00376 CDRAWER2D->GetVisibleMinY()+CDRAWER2D->GetUppY()*dy/4,
00377 CDRAWER2D->GetUppX()*0.5, CDRAWER2D->GetUppY()*0.5);
00378 }
00379
00380 void a2dStToolContr::ZoomOut2AtMouse()
00381 {
00382 int dx,dy;
00383 m_view->GetDisplayWindow()->GetClientSize(&dx,&dy);
00384 if (dy > dx) dx=dy;
00385
00386 double mouse_worldx, mouse_worldy;
00387 GetCanvasView()->MouseToToolWorld( m_mouse_x, m_mouse_y, mouse_worldx, mouse_worldy );
00388 mouse_worldx -= CDRAWER2D->GetUppX()*dx/2;
00389 mouse_worldy -= CDRAWER2D->GetUppY()*dy/2;
00390
00391 Zoom( mouse_worldx, mouse_worldy, CDRAWER2D->GetUppX()*2, CDRAWER2D->GetUppY()*2);
00392 }
00393
00394 void a2dStToolContr::ZoomIn2AtMouse()
00395 {
00396 int dx,dy;
00397 m_view->GetDisplayWindow()->GetClientSize(&dx,&dy);
00398 if (dy > dx) dx=dy;
00399
00400 double mouse_worldx, mouse_worldy;
00401 GetCanvasView()->MouseToToolWorld( m_mouse_x, m_mouse_y, mouse_worldx, mouse_worldy );
00402 mouse_worldx -= CDRAWER2D->GetUppX()*dx/4;
00403 mouse_worldy -= CDRAWER2D->GetUppY()*dy/4;
00404
00405 Zoom( mouse_worldx, mouse_worldy, CDRAWER2D->GetUppX()*0.5, CDRAWER2D->GetUppY()*0.5 );
00406 }
00407
00408 void a2dStToolContr::Zoom( double x, double y, double uppx, double uppy )
00409 {
00410 CDRAWER2D->SetMappingUpp( x, y, uppx, uppy );
00411 a2dDocviewGlobals->RecordF( this, _T("zoom %f %f %f %f upp"), x, y, uppx, uppy );
00412 }
00413
00414 bool a2dStToolContr::PushTool(a2dBaseTool* tool)
00415 {
00416 wxASSERT_MSG( wxDynamicCast( tool, a2dStTool) != 0, wxT("Only a2dStTool can be pushed into a2dStToolContr") );
00417
00418 bool res = a2dToolContr::PushTool(tool);
00419 ShowMouse();
00420 return res;
00421 }
00422
00423 bool a2dStToolContr::PopTool( a2dSmrtPtr<a2dBaseTool>& tool, bool force )
00424 {
00425 a2dToolContr::PopTool( tool, force );
00426
00427 if ( !tool )
00428 return false;
00429
00430 if (GetFirstTool())
00431 {
00432
00433 if ( GetFirstTool()->GetStopTool() )
00434 PopTool( tool );
00435
00436 ActivateTop( true );
00437 }
00438 else
00439 {
00440
00441 if ( m_topTool )
00442 {
00443 PushTool( m_topTool );
00444 ActivateTop( true );
00445 }
00446 else
00447 m_view->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW ) );
00448 }
00449 ShowMouse();
00450 return true;
00451 }
00452
00453 void a2dStToolContr::OnComEvent( a2dComEvent& event )
00454 {
00455 if ( GetEvtHandlerEnabled() && m_view )
00456 {
00457 if ( event.GetEventComId() == &a2dComEvent::sm_changedProperty )
00458 {
00459 a2dNamedProperty* property = event.GetProperty();
00460
00461 if ( property->GetId() == a2dCentralCanvasCommandProcessor::PROPID_Snap )
00462 {
00463 SetSnap( wxStaticCast( property, a2dNamedProperty )->GetBool() );
00464 }
00465 }
00466 if ( event.GetEventComId() == &a2dCanvasView::sm_changedShowObject )
00467 {
00468 if ( event.GetEventObject() == GetCanvasView() )
00469 {
00470
00471
00472
00473 a2dCanvasObject* newtop = wxStaticCast( event.GetProperty()->GetRefObject(), a2dCanvasObject );
00474 if ( m_topTool && newtop )
00475 {
00476 a2dCorridor corridor( *GetCanvasView() );
00477 corridor.Push( newtop );
00478 m_topTool->SetCorridor( corridor );
00479 m_toolForZoom->SetCorridor( corridor );
00480 event.Skip();
00481 }
00482 }
00483 else
00484 event.Skip();
00485 }
00486 else
00487 event.Skip();
00488 }
00489 else
00490 event.Skip();
00491 }
00492
00493
00494
00495 void a2dStToolContr::OnChar(wxKeyEvent& event)
00496 {
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512 event.Skip();
00513 }
00514
00515 void a2dStToolContr::OnKeyDown(wxKeyEvent& event)
00516 {
00517
00518
00519 if( m_defaultBehavior & wxTC_NoDefaultKeys )
00520 {
00521 event.Skip();
00522 return;
00523 }
00524
00525 switch(event.GetKeyCode())
00526 {
00527
00528 case WXK_CONTROL:
00529 {
00530 if ( !GetFirstTool() || (GetFirstTool() && !GetFirstTool()->GetBusy()) )
00531 {
00532 a2dDragTool *c = wxDynamicCast(GetFirstTool(), a2dDragTool);
00533 if (!c)
00534 {
00535 a2dDragTool* drag = new a2dDragTool(this);
00536 PushTool(drag);
00537 drag->SetOneShot();
00538 }
00539 }
00540 }
00541 break;
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559 case WXK_ESCAPE:
00560 {
00561 if ( GetFirstTool() && GetFirstTool()->AllowPop() )
00562 {
00563 a2dSmrtPtr<a2dBaseTool> poped;
00564 PopTool( poped );
00565 }
00566
00567 ShowMouse();
00568
00569 }
00570 break;
00571 case 'Z':
00572 case 'z':
00573 {
00574 if ( event.m_controlDown && event.m_shiftDown )
00575 m_view->GetCanvasDocument()->GetCommandProcessor()->Redo();
00576 else if ( event.m_controlDown )
00577 m_view->GetCanvasDocument()->GetCommandProcessor()->Undo();
00578 else if ( !GetFirstTool() || (GetFirstTool() && !GetFirstTool()->GetBusy()) )
00579 {
00580 a2dBaseTool* tool = m_toolForZoom->TClone( clone_deep );
00581 PushTool( tool );
00582 }
00583 else
00584 event.Skip();
00585 break;
00586 }
00587 case 'Y':
00588 case 'y':
00589 {
00590 if ( event.m_controlDown )
00591 m_view->GetCanvasDocument()->GetCommandProcessor()->Redo();
00592 else
00593 event.Skip();
00594 break;
00595 }
00596 case WXK_NUMPAD_ADD:
00597 {
00598 if ( event.m_controlDown )
00599 ZoomIn2AtMouse();
00600 else
00601 Zoomin2();
00602 break;
00603 }
00604 case WXK_NUMPAD_SUBTRACT:
00605 {
00606 if ( event.m_controlDown )
00607 ZoomOut2AtMouse();
00608 else
00609 Zoomout2();
00610 break;
00611 }
00612 default:
00613 event.Skip();
00614 }
00615 }
00616
00617 void a2dStToolContr::OnKeyUp(wxKeyEvent& event)
00618 {
00619 if( m_defaultBehavior & wxTC_NoDefaultKeys )
00620 {
00621 event.Skip();
00622 return;
00623 }
00624
00625 if ( GetFirstTool() && !GetFirstTool()->GetBusy())
00626 {
00627 switch(event.GetKeyCode())
00628 {
00629 case WXK_F1:
00630 break;
00631
00632
00633 case WXK_CONTROL:
00634 {
00635 a2dDragTool *c = wxDynamicCast(GetFirstTool(), a2dDragTool);
00636 if (c)
00637 {
00638 a2dSmrtPtr<a2dBaseTool> poped;
00639 PopTool( poped );
00640 }
00641 break;
00642 }
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655 default:
00656 event.Skip();
00657 }
00658 }
00659 else
00660 event.Skip();
00661
00662 }
00663
00664 void a2dStToolContr::ShowMouse()
00665 {
00666 if ( m_show_mousepos && m_where && m_where->GetStatusBar() )
00667 {
00668 double mouse_worldx, mouse_worldy;
00669 GetCanvasView()->MouseToToolWorld( m_mouse_x, m_mouse_y, mouse_worldx, mouse_worldy );
00670
00671 wxString str;
00672 str.Printf( _T("%6.3f,%6.3f"), mouse_worldx, mouse_worldy );
00673
00674 if ( GetFirstTool() )
00675 str = str + _T(" :") + GetFirstTool()->GetClassInfo()->GetClassName();
00676 m_where->SetStatusText( str );
00677 }
00678 else
00679 {
00680 a2dComEvent event( this, &sm_showCursor );
00681 if ( GetFirstTool() )
00682 {
00683 if ( ! GetFirstTool()->ProcessEvent( event ) )
00684 m_where->GetEventHandler()->ProcessEvent( event );
00685 }
00686 }
00687 }
00688
00689 void a2dStToolContr::OnMouseEvent(wxMouseEvent& event)
00690 {
00691 wxPoint pos = event.GetPosition();
00692
00693 m_mouse_x = pos.x;
00694 m_mouse_y = pos.y;
00695
00696 ShowMouse();
00697
00698 if ( event.LeftDown() && wxWindow::FindFocus() != m_view->GetDisplayWindow() )
00699 {
00700
00701 m_view->GetDisplayWindow()->SetFocus();
00702 }
00703 if ( event.RightDown())
00704 {
00705
00706
00707
00708 if ( ToolsProcessEvent(event) )
00709 return;
00710
00711 if ( ! (m_defaultBehavior & wxTC_NoContextMenu) && m_mousemenu )
00712 {
00713 m_view->GetDisplayWindow()->PopupMenu(m_mousemenu,pos.x,pos.y);
00714 event.Skip(false);
00715 return;
00716 }
00717 }
00718 else if ( GetFirstTool() && !GetFirstTool()->GetBusy()
00719 && ! (m_defaultBehavior & wxTC_NoDefaultMouseActions) )
00720 {
00721 if ( !wxDynamicCast(GetFirstTool(), a2dZoomTool) && event.m_controlDown && event.m_shiftDown )
00722 {
00723 a2dBaseTool* tool = m_toolForZoom->TClone( clone_deep );
00724 tool->SetOneShot();
00725 PushTool( tool );
00726 }
00727 if (!wxDynamicCast(GetFirstTool(), a2dDragTool) && event.m_controlDown)
00728 {
00729 a2dDragTool* drag = new a2dDragTool(this);
00730 PushTool(drag);
00731 drag->SetOneShot();
00732 }
00733
00734
00735
00736
00737
00738
00739
00740
00741 }
00742
00743
00744
00745 event.Skip();
00746 }
00747
00748 bool a2dStToolContr::StartEditingObject( a2dCanvasObject* objectToEdit )
00749 {
00750 a2dObjectEditTool* edit = new a2dObjectEditTool( this );
00751 PushTool( edit );
00752 edit->StartToEdit( objectToEdit );
00753 return true;
00754 }
00755
00756 bool a2dStToolContr::StartEditingObject( a2dCanvasObject* objectToEdit, a2dIterC& ic )
00757 {
00758 a2dObjectEditTool* edit = new a2dObjectEditTool( this, ic );
00759 PushTool( edit );
00760 edit->StartToEdit( objectToEdit );
00761 return true;
00762 }
00763
00764 bool a2dStToolContr::TriggerReStartEdit( wxUint16 editmode )
00765 {
00766 a2dObjectEditTool* edit = wxDynamicCast( GetFirstTool(), a2dObjectEditTool );
00767 if ( edit )
00768 {
00769 edit->TriggerReStartEdit( editmode );
00770 return true;
00771 }
00772 return false;
00773 }
00774
00775
00776
00777
00778
00779
00780 DEFINE_EVENT_TYPE( a2dStTool::sm_toolComEventAddObject )
00781 DEFINE_EVENT_TYPE( a2dStTool::sm_toolComEventSetEditObject )
00782
00783 A2D_BEGIN_EVENT_TABLE(a2dStTool, a2dBaseTool)
00784 A2D_EVT_KEY_DOWN(a2dStTool::OnKeyDown)
00785 A2D_EVT_KEY_UP(a2dStTool::OnKeyUp)
00786 A2D_EVT_CHAR(a2dStTool::OnChar)
00787 A2D_EVT_MOUSE_EVENTS( a2dStTool::OnMouseEvent)
00788 A2D_EVT_COM_EVENT( a2dStTool::OnComEvent )
00789 A2D_EVT_PAINT( a2dStTool::OnPaint )
00790 A2D_EVT_IDLE( a2dStTool::OnIdle )
00791 A2D_EVT_DO( a2dStTool::OnDoEvent )
00792 A2D_EVT_UNDO( a2dStTool::OnUndoEvent )
00793 A2D_END_EVENT_TABLE()
00794
00795 a2dStTool::a2dStTool(a2dStToolContr* controller):a2dBaseTool((a2dToolContr*)controller)
00796 {
00797 m_eventHandler = new a2dStToolEvtHandler( controller );
00798
00799 m_useEditOpaque = a2dOpaqueMode_Controller;
00800 m_editOpacityFactor = DEFAULTOpacityFactor;
00801
00802 m_editatend = false;
00803
00804 m_anotate = false;
00805
00806 m_canvasobject = 0;
00807 m_original = 0;
00808
00809 m_stcontroller = controller;
00810 m_connectionGenerator = a2dCanvasGlobals->GetConnectionGenerator();
00811 m_xanotation = m_yanotation = 0;
00812 m_commandgroup = 0;
00813
00814 m_dragStarted = false;
00815 m_xprev = 0;
00816 m_yprev = 0;
00817 m_dragstartx = 0;
00818 m_dragstarty = 0;
00819 m_xwprev = 0.0;
00820 m_ywprev = 0.0;
00821
00822
00823
00824
00825
00826 AdjustRenderOptions();
00827 }
00828
00829 a2dStTool::a2dStTool( const a2dStTool& other, CloneOptions options )
00830 :a2dBaseTool( other, options )
00831 {
00832 m_eventHandler = other.m_eventHandler;
00833
00834 m_useEditOpaque = other.m_useEditOpaque;
00835 m_editOpacityFactor = other.m_editOpacityFactor;
00836
00837 m_editatend = other.m_editatend;
00838
00839 m_anotate = other.m_anotate;
00840
00841 m_canvasobject = 0;
00842 m_original = 0;
00843
00844 m_stcontroller = other.m_stcontroller;
00845 m_connectionGenerator = other.m_connectionGenerator;
00846 m_xanotation = other.m_xanotation;
00847 m_yanotation = other.m_yanotation;
00848 m_commandgroup = other.m_commandgroup;
00849 }
00850
00851 a2dStTool::~a2dStTool()
00852 {
00853 }
00854
00855 bool a2dStTool::SetContext( a2dIterC& ic, a2dCanvasObject* startObject )
00856 {
00857 m_corridor = a2dCorridor( ic );
00858 m_parentobject = m_corridor.back();
00859
00860 m_canvasobject = startObject;
00861 return true;
00862 }
00863
00864 wxRect a2dStTool::GetAbsoluteArea( a2dCanvasObject* object )
00865 {
00866 a2dIterC ic( GetCanvasView() );
00867 a2dIterCU cu( ic );
00868
00869 return object->GetAbsoluteArea( ic );
00870 }
00871
00872 void a2dStTool::GetTextExtent(const wxString& string, wxCoord *w, wxCoord *h, wxCoord *descent, wxCoord *externalLeading )
00873 {
00874 wxMemoryDC dc;
00875 dc.SetFont( m_annotateFont );
00876 dc.GetTextExtent( string, w, h, descent, externalLeading);
00877 }
00878
00879 bool a2dStTool::OnPushNewTool( a2dBaseTool* WXUNUSED(newtool) )
00880 {
00881
00882 if ( GetBusy() && !m_halted )
00883 {
00884 m_halted = true;
00885 }
00886 m_pending = true;
00887 return false;
00888 }
00889
00890 void a2dStTool::AddCurrent( a2dCanvasObject* objectToAdd )
00891 {
00892 a2dCanvasDocument *doc = GetCanvasView()->GetCanvasDocument();
00893
00894 if ( doc )
00895 {
00896 a2dComEvent event( this, objectToAdd, &sm_toolComEventAddObject );
00897 ProcessEvent( event );
00898 }
00899
00900 a2dGetCmdh()->AddCurrent( objectToAdd, true, NULL, m_parentobject );
00901 }
00902
00903 void a2dStTool::SetActive(bool active)
00904 {
00905 a2dBaseTool::SetActive( active );
00906 m_pending = true;
00907
00908 if ( active )
00909 {
00910 a2dRestrictionEngine *restrict = a2dCanvasGlobals->GetRestrictionEngine();
00911 if(restrict)
00912 {
00913 restrict->SetParentSnapObjects( m_parentobject );
00914 }
00915
00916
00917
00918
00919 if ( GetBusy() && GetCanvasView()->GetCanvasDocument() )
00920 {
00921 GetCanvasView()->SetCursor( m_toolBusyCursor );
00922 }
00923 else
00924 {
00925 GetCanvasView()->SetCursor( m_toolcursor );
00926 }
00927
00928
00929 if ( m_halted )
00930 {
00931 m_halted = false;
00932
00933
00934 OpenCommandGroup( true );
00935 }
00936 m_pending = true;
00937 }
00938 else
00939 {
00940
00941
00942
00943
00944 a2dGetCmdh()->SetCurrentCanvasObject( 0 );
00945
00946 m_pending = true;
00947 }
00948 }
00949
00950 bool a2dStTool::EnterBusyMode()
00951 {
00952 if(!a2dBaseTool::EnterBusyMode())
00953 return false;
00954
00955 if( !CreateToolObjects() )
00956 {
00957 a2dBaseTool::AbortBusyMode();
00958 return false;
00959 }
00960
00961 return true;
00962 }
00963
00964 void a2dStTool::FinishBusyMode( bool closeCommandGroup )
00965 {
00966 CleanupToolObjects();
00967
00968
00969 if( m_original )
00970 {
00971 m_original->SetVisible(true);
00972 m_original->SetSnapTo( true );
00973 m_original = 0;
00974 }
00975 m_canvasobject = 0;
00976
00977 a2dBaseTool::FinishBusyMode( closeCommandGroup );
00978 }
00979
00980 void a2dStTool::AbortBusyMode()
00981 {
00982 CleanupToolObjects();
00983
00984
00985 if( m_original )
00986 {
00987 m_original->SetVisible(true);
00988 m_original->SetPending(true);
00989 m_original = 0;
00990 }
00991 m_canvasobject = 0;
00992
00993 a2dBaseTool::AbortBusyMode();
00994 }
00995
00996 void a2dStTool::OnMouseEvent(wxMouseEvent& event)
00997 {
00998 wxPoint pos = event.GetPosition();
00999 if ( event.RightUp() && m_mousemenu )
01000 {
01001 GetCanvasView()->GetDisplayWindow()->PopupMenu( m_mousemenu, pos.x, pos.y );
01002 }
01003 else
01004 event.Skip();
01005 }
01006
01007 void a2dStTool::AdjustRenderOptions()
01008 {
01009 switch( m_stcontroller->GetDragMode() )
01010 {
01011 case wxDRAW_RECTANGLE:
01012 m_renderOriginal = false;
01013 m_renderEditcopy = false;
01014 m_renderEditcopyOnTop = false;
01015 m_renderEditcopyEdit = false;
01016 m_renderEditcopyRectangle = true;
01017 break;
01018
01019 case wxDRAW_ONTOP:
01020 m_renderOriginal = false;
01021 m_renderEditcopy = false;
01022 m_renderEditcopyOnTop = true;
01023 m_renderEditcopyEdit = false;
01024 m_renderEditcopyRectangle = false;
01025 break;
01026
01027 case wxDRAW_REDRAW:
01028 m_renderOriginal = true;
01029 m_renderEditcopy = false;
01030 m_renderEditcopyOnTop = false;
01031 m_renderEditcopyEdit = false;
01032 m_renderEditcopyRectangle = false;
01033 break;
01034
01035 case wxDRAW_COPY:
01036 m_renderOriginal = true;
01037 m_renderEditcopy = false;
01038 m_renderEditcopyOnTop = false;
01039 m_renderEditcopyEdit = true;
01040 m_renderEditcopyRectangle = false;
01041 break;
01042
01043 default:
01044 wxASSERT( 0 );
01045 m_renderOriginal = true;
01046 m_renderEditcopy = false;
01047 m_renderEditcopyOnTop = false;
01048 m_renderEditcopyEdit = true;
01049 m_renderEditcopyRectangle = false;
01050 }
01051 }
01052
01053 bool a2dStTool::CreateToolObjects()
01054 {
01055 return true;
01056 }
01057
01058 void a2dStTool::CleanupToolObjects()
01059 {
01060
01061 for( a2dCanvasObjectList::iterator iter = m_parentobject->GetChildObjectList()->begin(); iter != m_parentobject->GetChildObjectList()->end(); ++iter )
01062 {
01063 a2dCanvasObjectList::value_type obj = *iter;
01064
01065 bool release = false;
01066 void* tool = a2dCanvasObject::PROPID_ToolObject->GetPropertyValue( obj );
01067 if( tool == this )
01068 {
01069 a2dCanvasObject *original = a2dCanvasObject::PROPID_Original->GetPropertyValue( obj );
01070 if( original )
01071 obj->EndEdit();
01072 release = true;
01073 }
01074 else if ( a2dCanvasObject::PROPID_ToolDecoration->GetPropertyValue( obj ) )
01075 {
01076 release = true;
01077 }
01078
01079 if( release )
01080 {
01081 a2dWalker_RemovePropertyCandoc setp( a2dCanvasObject::PROPID_Original );
01082 setp.AddPropertyId( a2dCanvasObject::PROPID_Editcopy );
01083 setp.Start( obj );
01084
01085
01086 obj->RemoveProperty( a2dCanvasObject::PROPID_ToolObject );
01087 obj->RemoveProperty( a2dCanvasObject::PROPID_ToolDecoration );
01088 obj->RemoveProperty( a2dCanvasObject::PROPID_ViewSpecific );
01089
01090
01091 obj->SetRelease(true);
01092
01093 }
01094 }
01095
01096
01097 if( m_original )
01098 {
01099 m_original->SetVisible( true );
01100 }
01101 }
01102
01103 void a2dStTool::GetKeyIncrement(double *xIncr, double *yIncr, bool altDown)
01104 {
01105 double pixel = GetDrawer2D()->DeviceToWorldXRel( 1 );
01106
01107
01108 a2dRestrictionEngine *restrict = a2dCanvasGlobals->GetRestrictionEngine();
01109 if(restrict)
01110 {
01111 restrict->SetAltKeyDown( altDown );
01112 if(restrict->GetSnapGridX())
01113 *xIncr = restrict->GetSnapGridX()/GetCanvasView()->GetCanvasDocument()->GetUnitsScale();
01114 else
01115 *xIncr = pixel;
01116
01117 if(restrict->GetSnapGridY())
01118 *yIncr = restrict->GetSnapGridY()/GetCanvasView()->GetCanvasDocument()->GetUnitsScale();
01119 else
01120 *yIncr = pixel;
01121 }
01122 else
01123 {
01124 *xIncr = pixel;
01125 *yIncr = pixel;
01126 }
01127
01128 if ( !GetDrawer2D()->GetYaxis() )
01129 {
01130 *yIncr = -*yIncr;
01131 }
01132 }
01133
01134 void a2dStTool::GenerateAnotation()
01135 {
01136
01137 a2dStTool::AddAnotationToPendingUpdateArea();
01138
01139 m_anotation = _T("");
01140 m_xanotation = m_x;
01141 m_yanotation = m_y;
01142
01143 a2dStTool::AddAnotationToPendingUpdateArea();
01144 }
01145
01146 void a2dStTool::AddAnotationToPendingUpdateArea()
01147 {
01148 if ( m_anotate )
01149 {
01150 wxCoord w, h, descent, external;
01151 GetTextExtent( m_anotation, &w, &h, &descent, &external );
01152
01153 wxRect text( m_xanotation, m_yanotation, w, h );
01154 GetCanvasView()->AddPendingUpdateArea( text.Inflate(2,2) );
01155 }
01156 }
01157
01158 void a2dStTool::OnIdle( wxIdleEvent &event )
01159 {
01160 if ( m_canvasobject && m_pending && GetBusy())
01161 {
01162 m_pending = false;
01163
01164
01165
01166 GenerateAnotation();
01167 }
01168 else
01169 event.Skip();
01170 }
01171
01172 void a2dStTool::OnPaint( wxPaintEvent &event )
01173 {
01174 if (GetBusy())
01175 {
01176 m_pending = true;
01177 }
01178 event.Skip();
01179 }
01180
01181
01182 #ifdef _DEBUG
01183 bool renderingtool = false;
01184 #endif
01185
01186 void a2dStTool::Render()
01187 {
01188 #ifdef _DEBUG
01189 renderingtool = true;
01190 #endif
01191
01192 if ( m_canvasobject && GetBusy())
01193 {
01194 AdjustRenderOptions();
01195
01196 if ( m_original )
01197 {
01198 a2dCanvasObject::SetIgnoreAllSetpending( true );
01199 m_original->SetVisible( m_renderOriginal );
01200 a2dCanvasObject::SetIgnoreAllSetpending( false );
01201 }
01202
01203
01204 if( m_renderEditcopyOnTop )
01205 {
01206 GetCanvasView()->RenderTopObject( RenderTOOL_OBJECTS_STYLED, 0 );
01207 }
01208
01209
01210 if( m_renderEditcopyEdit )
01211 {
01212 if ( m_useEditOpaque == a2dOpaqueMode_Tool )
01213 {
01214 GetCanvasView()->GetDrawer2D()->SetOpacityFactor( m_editOpacityFactor );
01215 GetCanvasView()->RenderTopObject( RenderTOOL_OBJECTS_STYLED, 0 );
01216 GetCanvasView()->GetDrawer2D()->SetOpacityFactor( 255 );
01217 }
01218 else if ( m_useEditOpaque == a2dOpaqueMode_Tool_FixedStyle )
01219 {
01220 a2dFill fill = *a2dTRANSPARENT_FILL;
01221 a2dStroke stroke = a2dCanvasGlobals->GetHandle()->GetStroke();
01222 GetCanvasView()->GetDrawer2D()->SetOpacityFactor( m_editOpacityFactor );
01223 GetCanvasView()->SetFixedStyleFill( fill );
01224 GetCanvasView()->SetFixedStyleStroke( stroke );
01225 GetCanvasView()->RenderTopObject( RenderTOOL_OBJECTS, 0 );
01226 GetCanvasView()->GetDrawer2D()->SetOpacityFactor( 255 );
01227 }
01228 else if ( m_useEditOpaque == a2dOpaqueMode_Controller && m_stcontroller->GetUseOpaqueEditcopy() )
01229 {
01230 GetCanvasView()->GetDrawer2D()->SetOpacityFactor( m_stcontroller->GetOpacityFactorEditcopy() );
01231 GetCanvasView()->RenderTopObject( RenderTOOL_OBJECTS_STYLED, 0 );
01232 GetCanvasView()->GetDrawer2D()->SetOpacityFactor( 255 );
01233 }
01234 else
01235 {
01236 a2dFill fill = *a2dTRANSPARENT_FILL;
01237 a2dStroke stroke = a2dCanvasGlobals->GetHandle()->GetStroke();
01238 GetCanvasView()->GetDrawer2D()->SetOpacityFactor( 255 );
01239 GetCanvasView()->SetFixedStyleFill( fill );
01240 GetCanvasView()->SetFixedStyleStroke( stroke );
01241 GetCanvasView()->RenderTopObject( RenderTOOL_OBJECTS, 1 );
01242 }
01243 }
01244
01245
01246 if( m_renderEditcopyRectangle )
01247 {
01248 GetCanvasView()->SetFixedStyleFill( *a2dTRANSPARENT_FILL );
01249 GetCanvasView()->SetFixedStyleStroke( a2dCanvasGlobals->GetHandle()->GetStroke() );
01250 GetCanvasView()->RenderTopObject( RenderRectangleTOOL_OBJECTS, 1 );
01251 }
01252
01253 GetCanvasView()->RenderTopObject( RenderTOOL_DECORATIONS, 1 );
01254
01255 RenderAnotation();
01256 }
01257
01258 #ifdef _DEBUG
01259 renderingtool = false;
01260 #endif
01261 }
01262
01263 void a2dStTool::RenderAnotation()
01264 {
01265 if ( m_anotate && m_canvasobject && GetBusy())
01266 {
01267 GetDrawer2D()->DeviceDrawAnnotation( m_anotation, m_xanotation, m_yanotation, m_annotateFont );
01268 }
01269 }
01270
01271 void a2dStTool::OnUndoEvent( a2dCommandProcessorEvent& event )
01272 {
01273 event.Skip();
01274 }
01275
01276 void a2dStTool::OnDoEvent( a2dCommandProcessorEvent& event )
01277 {
01278 event.Skip();
01279 }
01280
01281 void a2dStTool::OnComEvent( a2dComEvent& event )
01282 {
01283 if ( GetEvtHandlerEnabled() )
01284 {
01285 if ( event.GetEventComId() == &a2dBaseTool::sm_toolPoped )
01286 {
01287
01288 if ( !GetBusy() && m_editatend )
01289 CloseCommandGroup();
01290 }
01291 }
01292
01293 event.Skip();
01294 }
01295
01296 void a2dStTool::OnKeyDown(wxKeyEvent& event)
01297 {
01298 if (GetBusy())
01299 {
01300 a2dRestrictionEngine *restrictEngine = a2dCanvasGlobals->GetRestrictionEngine();
01301 switch(event.GetKeyCode())
01302 {
01303 case WXK_SHIFT:
01304 {
01305 if (restrictEngine )
01306 restrictEngine->SetShiftKeyDown( true );
01307 break;
01308 }
01309 case WXK_ALT:
01310 {
01311 if (restrictEngine )
01312 restrictEngine->SetAltKeyDown( true );
01313 break;
01314 }
01315 default:
01316 event.Skip();
01317 }
01318 }
01319 else
01320 event.Skip();
01321 }
01322
01323 void a2dStTool::OnKeyUp(wxKeyEvent& event)
01324 {
01325 if (GetBusy())
01326 {
01327 a2dRestrictionEngine *restrictEngine = a2dCanvasGlobals->GetRestrictionEngine();
01328 switch(event.GetKeyCode())
01329 {
01330 case WXK_SHIFT:
01331 {
01332 if (restrictEngine )
01333 restrictEngine->SetShiftKeyDown( false );
01334 break;
01335 }
01336 case WXK_ALT:
01337 {
01338 if (restrictEngine )
01339 restrictEngine->SetAltKeyDown( false );
01340 break;
01341 }
01342 default:
01343 event.Skip();
01344 }
01345 }
01346 }
01347
01348
01349 void a2dStTool::OnChar(wxKeyEvent& event)
01350 {
01351 if (GetBusy() && m_canvasobject && m_canvasobject->IsDraggable() )
01352 {
01353 double dx = m_xwprev - m_canvasobject->GetPosX();
01354 double dy = m_ywprev - m_canvasobject->GetPosY();
01355
01356 m_xwprev = m_canvasobject->GetPosX();
01357 m_ywprev = m_canvasobject->GetPosY();
01358
01359 double shiftx;
01360 double shifty;
01361 GetKeyIncrement(&shiftx, &shifty, event.AltDown());
01362
01363
01364
01365 switch(event.GetKeyCode())
01366 {
01367 case WXK_UP:
01368 shiftx = 0;
01369 break;
01370
01371 case WXK_DOWN:
01372 shiftx = 0;
01373 shifty = -shifty;
01374 break;
01375
01376 case WXK_LEFT:
01377 shiftx = -shiftx;
01378 shifty = 0;
01379 break;
01380
01381 case WXK_RIGHT:
01382 shifty = 0;
01383 break;
01384 default:
01385 {
01386 shiftx = 0;
01387 shifty = 0;
01388 event.Skip();
01389 }
01390 }
01391
01392 m_xwprev += shiftx;
01393 m_ywprev += shifty;
01394
01395 m_canvasobject->Translate( shiftx, shifty );
01396
01397 m_pending = true;
01398 }
01399 else
01400 event.Skip();
01401 }
01402
01403 void a2dStTool::MouseToToolWorld( int x, int y, double& xWorldLocal, double& yWorldLocal )
01404 {
01405 GetCanvasView()->MouseToToolWorld( x, y, xWorldLocal, yWorldLocal );
01406 a2dAffineMatrix cworld;
01407 cworld = GetCanvasView()->GetShowObject()->GetTransform();
01408 cworld.Invert();
01409 cworld.TransformPoint(xWorldLocal,yWorldLocal, xWorldLocal, yWorldLocal );
01410 m_corridor.GetTransform().TransformPoint(xWorldLocal,yWorldLocal, xWorldLocal, yWorldLocal );
01411 }
01412
01413 a2dObjectEditTool* a2dStTool::StartEditTool( a2dCanvasObject *objecttoedit )
01414 {
01415
01416 a2dGetCmdh()->SetCurrentCanvasObject( 0 );
01417
01418 if ( m_editatend )
01419 {
01420 a2dStTool::FinishBusyMode( false );
01421
01422
01423
01424
01425 a2dObjectEditTool* edit = new a2dObjectEditTool( m_stcontroller );
01426
01427 edit->SetEvtHandler( GetEventHandler() );
01428 edit->SetFill( m_fill );
01429 edit->SetStroke( m_stroke );
01430 m_stcontroller->PushTool( edit );
01431 edit->StartToEdit( objecttoedit );
01432 objecttoedit->SetVisible( true );
01433 return edit;
01434 }
01435 else
01436 {
01437 a2dStTool::FinishBusyMode( true );
01438
01439
01440 GetCanvasView()->Update( a2dCANVIEW_UPDATE_SYNC_DRAWERS );
01441 return NULL;
01442 }
01443 }
01444
01445 a2dPin *a2dStTool::FindUnConnectedPin( a2dCanvasObject *root, double x, double y, a2dPinClass* withPinClass )
01446 {
01447
01448 a2dAffineMatrix tRootInv = root->GetTransformMatrix();
01449 tRootInv.Invert();
01450 double xh,yh;
01451 tRootInv.TransformPoint(x, y, xh, yh);
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462 for( a2dCanvasObjectList::iterator iter = root->GetChildObjectList()->begin(); iter != root->GetChildObjectList()->end(); ++iter )
01463 {
01464 a2dCanvasObject *obj = *iter;
01465
01466 if( !obj->HasPins() )
01467 continue;
01468 if( obj == m_canvasobject )
01469 continue;
01470 if( obj == m_original )
01471 continue;
01472
01473 a2dIterC ic( GetCanvasView() );
01474 a2dIterCU cu( ic );
01475
01476
01477
01478 for( a2dCanvasObjectList::iterator iterp = obj->GetChildObjectList()->begin(); iterp != obj->GetChildObjectList()->end(); ++iterp )
01479 {
01480 a2dPin* pin = wxDynamicCast( (*iterp).Get(), a2dPin );
01481 if (pin)
01482 {
01483
01484 if( ( pin->ConnectedTo() ) || pin->GetRelease( ) )
01485 continue;
01486
01487 a2dIterCU cu( ic, obj );
01488 a2dHitEvent hitevent = a2dHitEvent( xh, yh, false );
01489 if ( pin->IsHitWorld( ic, hitevent ))
01490 {
01491 if ( withPinClass )
01492 {
01493 if ( withPinClass == pin->GetPinClass() )
01494 return pin;
01495 }
01496 else
01497 {
01498 if ( !m_connectionGenerator )
01499 {
01500 a2dPinClass* canconnect = m_connectionGenerator->GetPinClassForTask( pin->GetPinClass(),
01501 a2d_ToConnectPinClassWire_ObjectPinClass_InOut, obj );
01502 if ( canconnect )
01503 return pin;
01504 }
01505 else
01506 return pin;
01507 }
01508 }
01509 }
01510 }
01511 }
01512 return 0;
01513 }
01514
01515
01516
01517
01518
01519
01520 A2D_BEGIN_EVENT_TABLE(a2dStDrawTool, a2dStTool)
01521 A2D_EVT_KEY_DOWN(a2dStDrawTool::OnKeyDown)
01522 A2D_EVT_KEY_UP(a2dStDrawTool::OnKeyUp)
01523 A2D_EVT_CHAR(a2dStDrawTool::OnChar)
01524 A2D_END_EVENT_TABLE()
01525
01526 a2dStDrawTool::a2dStDrawTool(a2dStToolContr* controller):a2dStTool(controller)
01527 {
01528
01529
01530 m_stroke = a2dStroke(*wxBLACK,0);
01531 m_fill = a2dFill(*wxRED);
01532 m_AllowModifyTemplate = true;
01533 }
01534
01535 a2dStDrawTool::~a2dStDrawTool()
01536 {
01537 }
01538
01539 bool a2dStDrawTool::CreateToolObjects()
01540 {
01541 a2dStTool::CreateToolObjects();
01542
01543
01544 m_canvasobject = m_original->TClone( clone_members | clone_childs | clone_seteditcopy | clone_setoriginal );
01545
01546 m_original->SetSnapTo( false );
01547
01548 m_canvasobject->SetSelected( false );
01549
01550 AddEditobject( m_canvasobject );
01551
01552 AdjustRenderOptions();
01553 m_original->SetVisible( m_renderOriginal );
01554
01555 m_pending = true;
01556 return true;
01557 }
01558
01559 bool a2dStDrawTool::EnterBusyMode()
01560 {
01561 m_pending = true;
01562 return a2dStTool::EnterBusyMode();
01563 }
01564
01565 void a2dStDrawTool::FinishBusyMode( bool closeCommandGroup )
01566 {
01567 a2dREFOBJECTPTR_KEEPALIVE;
01568 m_pending = true;
01569 a2dCanvasObjectPtr original = m_original;
01570 if( GetCanvasView() )
01571 {
01572 StartEditTool( original );
01573 }
01574 else
01575 a2dStTool::FinishBusyMode( closeCommandGroup );
01576
01577 }
01578
01579 void a2dStDrawTool::AbortBusyMode()
01580 {
01581 m_pending = true;
01582 a2dStTool::AbortBusyMode();
01583 }
01584
01585 void a2dStDrawTool::OnKeyDown(wxKeyEvent& event)
01586 {
01587 event.Skip();
01588 }
01589
01590 void a2dStDrawTool::OnKeyUp(wxKeyEvent& event)
01591 {
01592 event.Skip();
01593 }
01594
01595 void a2dStDrawTool::OnChar(wxKeyEvent& event)
01596 {
01597 if (GetBusy())
01598 {
01599 switch(event.GetKeyCode())
01600 {
01601 case WXK_SPACE:
01602 case WXK_ESCAPE:
01603 {
01604 FinishBusyMode();
01605 }
01606 break;
01607 default:
01608 event.Skip();
01609 }
01610 }
01611 else
01612 event.Skip();
01613 }
01614
01615 void a2dStDrawTool::AdjustRenderOptions()
01616 {
01617 a2dStTool::AdjustRenderOptions();
01618 }
01619
01620
01621
01622
01623
01624 A2D_BEGIN_EVENT_TABLE(a2dDrawRectangleTool,a2dStDrawTool)
01625 A2D_EVT_CHAR(a2dDrawRectangleTool::OnChar)
01626 A2D_EVT_MOUSE_EVENTS(a2dDrawRectangleTool::OnMouseEvent)
01627 A2D_END_EVENT_TABLE()
01628
01629 a2dDrawRectangleTool::a2dDrawRectangleTool(a2dStToolContr* controller):a2dStDrawTool(controller)
01630 {
01631 m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_PENCIL );
01632 m_toolBusyCursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_CROSS );
01633 m_radius = 0;
01634 }
01635
01636 a2dDrawRectangleTool::~a2dDrawRectangleTool()
01637 {
01638 }
01639
01640 void a2dDrawRectangleTool::GenerateAnotation()
01641 {
01642
01643 a2dStTool::AddAnotationToPendingUpdateArea();
01644
01645 a2dRect* rec = wxStaticCast( m_canvasobject.Get(), a2dRect );
01646 m_anotation.Printf( _T("w %6.3f h %6.3f"), rec->GetWidth(), rec->GetHeight() );
01647
01648 wxCoord w, h, descent, external;
01649 GetTextExtent( m_anotation, &w, &h, &descent, &external );
01650
01651 m_xanotation = m_x + h;
01652 m_yanotation = m_y + h;
01653
01654 a2dStDrawTool::AddAnotationToPendingUpdateArea();
01655 }
01656
01657 void a2dDrawRectangleTool::OnMouseEvent(wxMouseEvent& event)
01658 {
01659 if (!m_active)
01660 {
01661 event.Skip();
01662 return;
01663 }
01664
01665
01666
01667
01668
01669
01670 m_x = event.GetX();
01671 m_y = event.GetY();
01672 MouseToToolWorld( m_x, m_y, m_xwprev, m_ywprev );
01673
01674 a2dRestrictionEngine *restrict = a2dCanvasGlobals->GetRestrictionEngine();
01675 if(restrict)
01676 restrict->RestrictPoint(m_xwprev, m_ywprev);
01677
01678 if (event.LeftDown() && !GetBusy())
01679 {
01680 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
01681 GetCanvasView()->PushCursor( m_toolBusyCursor );
01682 m_original = new a2dRect( m_xwprev, m_ywprev, 0, 0, m_radius);
01683 EnterBusyMode();
01684 AddCurrent( m_original );
01685 }
01686 else if (event.LeftDown() && GetBusy())
01687 {
01688 GetCanvasView()->PopCursor();
01689 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
01690 a2dRect* rec = wxStaticCast( m_canvasobject.Get(), a2dRect );
01691 a2dDocviewGlobals->RecordF( this, _T("rect %f %f %f %f"), rec->GetPosX(), rec->GetPosY(), rec->GetWidth(), rec->GetHeight() );
01692
01693 FinishBusyMode();
01694 }
01695 else if ((event.Dragging()&& GetBusy()) || (event.Moving() && GetBusy()) )
01696 {
01697 a2dRect* rec = wxStaticCast( m_canvasobject.Get(), a2dRect );
01698 rec->SetWidth( m_xwprev - rec->GetPosX() );
01699 rec->SetHeight( m_ywprev - rec->GetPosY() );
01700
01701 a2dRect* recorg = wxStaticCast( m_original.Get(), a2dRect );
01702 recorg->SetWidth( rec->GetWidth() );
01703 recorg->SetHeight( rec->GetHeight() );
01704
01705 m_pending = true;
01706 }
01707 else
01708 event.Skip();
01709 }
01710
01711
01712
01713
01714
01715 A2D_BEGIN_EVENT_TABLE(a2dZoomTool,a2dStTool)
01716 A2D_EVT_CHAR(a2dZoomTool::OnChar)
01717 A2D_EVT_MOUSE_EVENTS(a2dZoomTool::OnMouseEvent)
01718 A2D_END_EVENT_TABLE()
01719
01720 a2dZoomTool::a2dZoomTool(a2dStToolContr* controller):a2dStTool(controller)
01721 {
01722 m_eventHandler = new a2dStToolFixedToolStyleEvtHandler( controller );
01723
01724 m_anotate = true;
01725 m_draggingCanvas = false;
01726 m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_MAGNIFIER );
01727 m_toolBusyCursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_CROSS );
01728
01729 if ( GetCanvasView()->GetDrawer2D()->HasAlpha() || GetCanvasView()->GetTrippleBuf() )
01730 {
01731 SetFill( a2dFill( wxColour( 66, 159, 235, 50 ) ) );
01732 SetStroke( a2dStroke( wxColour( 66, 159, 235, 165 ), 2, a2dSTROKE_LONG_DASH) );
01733 }
01734 else
01735 {
01736 SetFill( *a2dTRANSPARENT_FILL );
01737 SetStroke( a2dStroke(*wxBLACK, 1, a2dSTROKE_LONG_DASH) );
01738 }
01739 }
01740
01741 a2dZoomTool::a2dZoomTool( const a2dZoomTool& other, CloneOptions options )
01742 :a2dStTool( other, options )
01743 {
01744 m_eventHandler = other.m_eventHandler;
01745
01746 m_anotate = other.m_anotate;
01747 m_draggingCanvas = false;
01748 m_toolcursor = other.m_toolcursor;
01749 m_toolBusyCursor = other.m_toolBusyCursor;
01750
01751 m_fill = other.m_fill;
01752 m_stroke = other.m_stroke;
01753 }
01754
01755 a2dObject* a2dZoomTool::Clone( CloneOptions options ) const
01756 {
01757 return new a2dZoomTool( *this, options );
01758 }
01759
01760 a2dZoomTool::~a2dZoomTool()
01761 {
01762 }
01763
01764 void a2dZoomTool::GenerateAnotation()
01765 {
01766
01767 a2dStTool::AddAnotationToPendingUpdateArea();
01768
01769 a2dRect* rec = wxStaticCast( m_canvasobject.Get(), a2dRect );
01770 m_anotation.Printf( _T("w %6.3f h %6.3f"), rec->GetWidth(), rec->GetHeight() );
01771 m_xanotation = m_x;
01772 m_yanotation = m_y;
01773
01774 wxCoord w, h, descent, external;
01775 GetTextExtent( m_anotation, &w, &h, &descent, &external );
01776
01777 m_xanotation = m_x + h;
01778 m_yanotation = m_y + h;
01779
01780 a2dStTool::AddAnotationToPendingUpdateArea();
01781 }
01782
01783 void a2dZoomTool::OnChar(wxKeyEvent& event)
01784 {
01785 if (!GetBusy())
01786 {
01787 switch(event.GetKeyCode())
01788 {
01789 case WXK_RETURN:
01790 {
01791 m_stcontroller->Zoomout();
01792 }
01793 break;
01794 case WXK_SUBTRACT:
01795 {
01796 m_stcontroller->ZoomUndo();
01797 }
01798 break;
01799 default:
01800 event.Skip();
01801 }
01802 }
01803 else
01804 event.Skip();
01805 }
01806
01807 void a2dZoomTool::OnMouseEvent(wxMouseEvent& event)
01808 {
01809 if (!m_active)
01810 {
01811 event.Skip();
01812 return;
01813 }
01814
01815 if( m_draggingCanvas )
01816 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Move ) );
01817 else if ( GetBusy() )
01818 GetCanvasView()->SetCursor( m_toolBusyCursor );
01819 else
01820 GetCanvasView()->SetCursor( m_toolcursor );
01821
01822 m_x = event.GetX();
01823 m_y = event.GetY();
01824
01825 if (event.LeftDClick() && !GetBusy())
01826 {
01827 m_stcontroller->Zoomout();
01828 }
01829 else if (event.LeftDown() && !GetBusy())
01830 {
01831 MouseToToolWorld( m_x, m_y, m_xwprev, m_ywprev );
01832 a2dRect* rec = new a2dRect( m_xwprev, m_ywprev, 0, 0, 0);
01833 m_canvasobject = rec;
01834 if ( GetCanvasView()->GetTrippleBuf() )
01835 GetCanvasView()->AddOverlayObject( rec );
01836 else
01837 AddDecorationObject( rec );
01838 rec->SetFill( m_fill );
01839 rec->SetStroke( m_stroke );
01840 rec->Update( a2dCanvasObject::updatemask_force );
01841 m_pending = true;
01842
01843
01844
01845
01846 event.Skip();
01847 EnterBusyMode();
01848 }
01849 else if ( event.LeftUp() && GetBusy())
01850 {
01851 a2dRect* rec = wxStaticCast( m_canvasobject.Get(), a2dRect );
01852
01853 m_canvasobject->SetVisible(false);
01854
01855 double w = GetDrawer2D()->WorldToDeviceXRel( rec->GetWidth() );
01856 double h = GetDrawer2D()->WorldToDeviceYRel( rec->GetHeight() );
01857
01858
01859
01860 if (fabs( w ) < 3 && fabs( h )< 3)
01861 {
01862 GetDisplayWindow()->Refresh();
01863 FinishBusyMode();
01864 event.Skip();
01865 }
01866 else
01867 {
01868 double x1 = rec->GetBbox().GetMinX();
01869
01870 double y1 = rec->GetBbox().GetMinY();
01871
01872
01873 a2dBoundingBox* bbox = new a2dBoundingBox(GetDrawer2D()->GetVisibleMinX(),
01874 GetDrawer2D()->GetVisibleMinY(),
01875 GetDrawer2D()->GetVisibleMaxX(),
01876 GetDrawer2D()->GetVisibleMaxY()
01877 );
01878
01879 m_stcontroller->GetZoomList().Insert(bbox);
01880
01881 a2dGetCmdh()->Submit( new a2dCommand_Zoom( a2dCommand_Zoom::Args().what( a2dCommand_Zoom::Zoom ).x1(x1).y1(y1).
01882 x2(fabs(rec->GetWidth())).
01883 y2(fabs(rec->GetHeight())).upp( false ) ), false );
01884
01885
01886 a2dDocviewGlobals->RecordF( this, _T("zoom %f %f %f %f"), x1, y1, x1+rec->GetWidth(), y1+rec->GetHeight() );
01887
01888
01889
01890
01891
01892 FinishBusyMode();
01893 GetCanvasView()->RemoveOverlayObject( rec );
01894
01895 event.Skip();
01896 }
01897 }
01898 else if ((event.Dragging() && GetBusy()) && !m_draggingCanvas )
01899 {
01900 a2dRect* rec = wxStaticCast( m_canvasobject.Get(), a2dRect );
01901
01902 MouseToToolWorld( m_x, m_y, m_xwprev, m_ywprev );
01903
01904 rec->SetWidth( m_xwprev - rec->GetPosX() );
01905 rec->SetHeight( m_ywprev - rec->GetPosY() );
01906 rec->SetPending( true );
01907 m_pending = true;
01908 }
01909 else if ( event.Dragging() && m_draggingCanvas )
01910 {
01911 double dxworld = GetDrawer2D()->DeviceToWorldXRel( floor( m_xprev-m_x + 0.5 ) );
01912 double dyworld = GetDrawer2D()->DeviceToWorldYRel( floor( m_yprev-m_y + 0.5 ) );
01913
01914 GetCanvasView()->GetCanvas()->ScrollWindowConstrained( dxworld, dyworld );
01915 m_xprev = m_x;
01916 m_yprev = m_y;
01917 }
01918 else if( event.RightDown() && !m_draggingCanvas )
01919 {
01920 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Move ) );
01921 m_draggingCanvas = true;
01922 m_xprev = m_x;
01923 m_yprev = m_y;
01924 m_dragstartx = m_x;
01925 m_dragstarty = m_y;
01926 }
01927 else if( event.RightUp() && m_draggingCanvas )
01928 {
01929 m_draggingCanvas = false;
01930 if ( m_dragstartx == m_xprev && m_dragstarty == m_yprev )
01931 GetCanvasView()->GetDisplayWindow()->PopupMenu( m_stcontroller->GetMousePopupMenu(), m_x, m_y );
01932 if (m_oneshot)
01933 StopTool();
01934 }
01935 else
01936 event.Skip();
01937 }
01938
01939 A2D_BEGIN_EVENT_TABLE(a2dSelectTool,a2dStTool)
01940 A2D_EVT_CHAR(a2dSelectTool::OnChar)
01941 A2D_EVT_MOUSE_EVENTS(a2dSelectTool::OnMouseEvent)
01942 A2D_END_EVENT_TABLE()
01943
01944 a2dSelectTool::a2dSelectTool(a2dStToolContr* controller):a2dStTool(controller)
01945 {
01946 m_eventHandler = new a2dStToolFixedToolStyleEvtHandler( controller );
01947
01948 m_anotate = true;
01949 m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_CROSS );
01950 m_toolBusyCursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_CROSS );
01951 m_shift_is_add = false;
01952
01953 if ( GetCanvasView()->GetDrawer2D()->HasAlpha() || GetCanvasView()->GetTrippleBuf() )
01954 {
01955 SetFill( a2dFill( wxColour( 233, 15, 23, 20 ) ) );
01956 SetStroke( a2dStroke( wxColour( 255, 59, 25, 65 ), 1, a2dSTROKE_LONG_DASH) );
01957 }
01958 else
01959 {
01960 SetFill( *a2dTRANSPARENT_FILL );
01961 SetStroke( a2dStroke(*wxRED, 1, a2dSTROKE_LONG_DASH) );
01962 }
01963 }
01964
01965 a2dSelectTool::~a2dSelectTool()
01966 {
01967 }
01968
01969 void a2dSelectTool::DeselectAll()
01970 {
01971 GetCanvasCommandProcessor()->Submit( new a2dCommand_Select( a2dCommand_Select::Args().what(a2dCommand_Select::DeSelectAll) ) );
01972 }
01973
01974 void a2dSelectTool::GenerateAnotation()
01975 {
01976
01977 a2dStTool::AddAnotationToPendingUpdateArea();
01978
01979 a2dRect* rec = wxStaticCast( m_canvasobject.Get(), a2dRect );
01980 m_anotation.Printf( _T("w %6.3f h %6.3f"), rec->GetWidth(), rec->GetHeight() );
01981
01982 wxCoord w, h, descent, external;
01983 GetTextExtent( m_anotation, &w, &h, &descent, &external );
01984
01985 m_xanotation = m_x + h;
01986 m_yanotation = m_y + h;
01987
01988 a2dStTool::AddAnotationToPendingUpdateArea();
01989 }
01990
01991 void a2dSelectTool::OnChar(wxKeyEvent& event)
01992 {
01993 if (!GetBusy())
01994 {
01995 switch(event.GetKeyCode())
01996 {
01997 case WXK_RETURN:
01998 {
01999 m_stcontroller->Zoomout();
02000 }
02001 break;
02002 case WXK_SUBTRACT:
02003 {
02004 m_stcontroller->ZoomUndo();
02005 }
02006 break;
02007 default:
02008 event.Skip();
02009 }
02010 }
02011 else
02012 event.Skip();
02013 }
02014
02015 void a2dSelectTool::OnMouseEvent(wxMouseEvent& event)
02016 {
02017 if (!m_active)
02018 {
02019 event.Skip();
02020 return;
02021 }
02022
02023 m_x = event.GetX();
02024 m_y = event.GetY();
02025 MouseToToolWorld( m_x, m_y, m_xwprev, m_ywprev );
02026
02027 if ( event.Moving() )
02028 {
02029 if ( !GetBusy() )
02030 {
02031 double xWorld, yWorld;
02032 GetCanvasView()->MouseToToolWorld( m_x, m_y, xWorld, yWorld );
02033
02034 static a2dCanvasObject* oldhitobject = NULL;
02035 a2dCanvasObject* hitobject = NULL;
02036 hitobject = GetCanvasView()->IsHitWorld( xWorld, yWorld, wxLAYER_ALL, a2dCANOBJHITOPTION_LAYERS, true );
02037 if ( hitobject )
02038 {
02039 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_HAND ) );
02040 }
02041 else
02042 GetCanvasView()->SetCursor( m_toolcursor );
02043 }
02044 else
02045 GetCanvasView()->SetCursor( m_toolBusyCursor );
02046 }
02047
02048 if (event.LeftDClick() && !GetBusy())
02049 {
02050
02051 }
02052 else if (event.LeftDown() && !GetBusy())
02053 {
02054 EnterBusyMode();
02055 m_pending = true;
02056
02057
02058
02059
02060 event.Skip();
02061 }
02062 else if ( event.LeftUp() && GetBusy())
02063 {
02064 a2dRect* rec = wxStaticCast( m_canvasobject.Get(), a2dRect );
02065
02066 m_canvasobject->SetVisible(false);
02067
02068 double w = GetDrawer2D()->WorldToDeviceXRel( rec->GetWidth() );
02069 double h = GetDrawer2D()->WorldToDeviceYRel( rec->GetHeight() );
02070
02071 if (fabs( w ) < 3 && fabs( h )< 3)
02072 {
02073
02074
02075 a2dCanvasObject* hitobject = GetCanvasView()->IsHitWorld( m_xwprev, m_ywprev, wxLAYER_ALL, a2dCANOBJHITOPTION_LAYERS, true );
02076
02077 if( m_shift_is_add )
02078 {
02079 if ( !event.m_shiftDown )
02080 {
02081
02082 DeselectAll();
02083
02084 if ( hitobject )
02085 {
02086 GetCanvasCommandProcessor()->Submit(
02087 new a2dCommand_SetSelectFlag( hitobject, true )
02088 );
02089 }
02090 }
02091 else
02092 {
02093
02094 if ( hitobject )
02095 {
02096 GetCanvasCommandProcessor()->Submit(
02097 new a2dCommand_SetSelectFlag( hitobject, !hitobject->GetSelected() )
02098 );
02099 }
02100 }
02101
02102 if (!hitobject)
02103 {
02104 if( !m_oneshot )
02105 event.Skip();
02106 FinishBusyMode();
02107 return;
02108 }
02109 }
02110 else
02111 {
02112 if (!hitobject)
02113 {
02114 if( !m_oneshot )
02115 event.Skip();
02116 FinishBusyMode();
02117 return;
02118 }
02119
02120 if ( event.m_shiftDown || hitobject->GetSelected())
02121 {
02122 GetCanvasCommandProcessor()->Submit(
02123 new a2dCommand_SetSelectFlag( hitobject, false )
02124 );
02125 }
02126 else
02127 {
02128 GetCanvasCommandProcessor()->Submit(
02129 new a2dCommand_SetSelectFlag( hitobject, true )
02130 );
02131 }
02132 }
02133 }
02134 else
02135 {
02136 if( m_shift_is_add )
02137 {
02138
02139
02140
02141 if (!event.m_shiftDown)
02142 {
02143 DeselectAll();
02144 GetCanvasCommandProcessor()->Submit(
02145 new a2dCommand_Select( a2dCommand_Select::Args()
02146 .what(a2dCommand_Select::SelectRect)
02147 .x1( rec->GetBbox().GetMinX() )
02148 .y1( rec->GetBbox().GetMinY() )
02149 .x2( rec->GetBbox().GetMaxX() )
02150 .y2( rec->GetBbox().GetMaxY() )
02151 )
02152 );
02153 }
02154 else
02155 {
02156 GetCanvasCommandProcessor()->Submit(
02157 new a2dCommand_Select( a2dCommand_Select::Args()
02158 .what(a2dCommand_Select::SelectRect)
02159 .x1( rec->GetBbox().GetMinX() )
02160 .y1( rec->GetBbox().GetMinY() )
02161 .x2( rec->GetBbox().GetMaxX() )
02162 .y2( rec->GetBbox().GetMaxY() )
02163 )
02164 );
02165 }
02166 }
02167 else
02168 {
02169 if (event.m_shiftDown)
02170 {
02171 GetCanvasCommandProcessor()->Submit(
02172 new a2dCommand_Select( a2dCommand_Select::Args()
02173 .what(a2dCommand_Select::DeSelectRect)
02174 .x1( rec->GetBbox().GetMinX() )
02175 .y1( rec->GetBbox().GetMinY() )
02176 .x2( rec->GetBbox().GetMaxX() )
02177 .y2( rec->GetBbox().GetMaxY() )
02178 )
02179 );
02180 }
02181 else
02182 {
02183 GetCanvasCommandProcessor()->Submit(
02184 new a2dCommand_Select( a2dCommand_Select::Args()
02185 .what(a2dCommand_Select::SelectRect)
02186 .x1( rec->GetBbox().GetMinX() )
02187 .y1( rec->GetBbox().GetMinY() )
02188 .x2( rec->GetBbox().GetMaxX() )
02189 .y2( rec->GetBbox().GetMaxY() )
02190 )
02191 );
02192 }
02193 }
02194 }
02195
02196 m_pending = true;
02197 a2dREFOBJECTPTR_KEEPALIVE;
02198 FinishBusyMode();
02199 GetCanvasView()->Update( a2dCANVIEW_UPDATE_SYNC_DRAWERS );
02200 }
02201 else if ((event.Dragging() && GetBusy()) )
02202 {
02203 a2dRect* rec = wxStaticCast( m_canvasobject.Get(), a2dRect );
02204 rec->SetWidth( m_xwprev - rec->GetPosX() );
02205 rec->SetHeight( m_ywprev - rec->GetPosY() );
02206 rec->SetPending( true );
02207
02208 m_pending = true;
02209 }
02210 else
02211 event.Skip();
02212 }
02213
02214 bool a2dSelectTool::CreateToolObjects()
02215 {
02216
02217
02218 a2dRect* rec = new a2dRect( m_xwprev, m_ywprev, 0, 0, 0);
02219 m_canvasobject = rec;
02220 rec->SetFill( m_fill );
02221 rec->SetStroke( m_stroke );
02222 rec->Update( a2dCanvasObject::updatemask_force );
02223 rec->SetPending( true );
02224 AddDecorationObject( rec );
02225 return true;
02226 }
02227
02228 A2D_BEGIN_EVENT_TABLE(a2dImageTool,a2dStDrawTool)
02229 A2D_EVT_CHAR(a2dImageTool::OnChar)
02230 A2D_EVT_MOUSE_EVENTS(a2dImageTool::OnMouseEvent)
02231 A2D_END_EVENT_TABLE()
02232
02233 a2dImageTool::a2dImageTool(a2dStToolContr* controller):a2dStDrawTool(controller)
02234 {
02235 m_eventHandler = new a2dStToolFixedToolStyleEvtHandler( controller );
02236
02237 m_drawPatternOnTop = false;
02238 m_anotate = true;
02239 m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_PENCIL );
02240 m_toolBusyCursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_CROSS );
02241
02242
02243 SetFill( *a2dTRANSPARENT_FILL );
02244 SetStroke( a2dStroke(*wxRED, 1, a2dSTROKE_DOT) );
02245 }
02246
02247 a2dImageTool::~a2dImageTool()
02248 {
02249 }
02250
02251 void a2dImageTool::GenerateAnotation()
02252 {
02253
02254 a2dStDrawTool::AddAnotationToPendingUpdateArea();
02255
02256 a2dRect* rec = wxStaticCast( m_canvasobject.Get(), a2dRect );
02257 m_anotation.Printf( _T("w %6.3f h %6.3f"), rec->GetWidth(), rec->GetHeight() );
02258
02259 wxCoord w, h, d, l;
02260 GetTextExtent( m_anotation, &w, &h, &d, &l );
02261 m_xanotation = m_x + (int) h;
02262 m_yanotation = m_y + (int) h;
02263 a2dStDrawTool::AddAnotationToPendingUpdateArea();
02264 }
02265
02266 void a2dImageTool::OnChar(wxKeyEvent& event)
02267 {
02268 if (!GetBusy())
02269 {
02270 switch(event.GetKeyCode())
02271 {
02272 case WXK_RETURN:
02273 {
02274 m_stcontroller->Zoomout();
02275 }
02276 break;
02277 case WXK_SUBTRACT:
02278 {
02279 m_stcontroller->ZoomUndo();
02280 }
02281 break;
02282 default:
02283 event.Skip();
02284 }
02285 }
02286 else
02287 event.Skip();
02288 }
02289
02290 void a2dImageTool::OnMouseEvent(wxMouseEvent& event)
02291 {
02292 if (!m_active)
02293 {
02294 event.Skip();
02295 return;
02296 }
02297
02298 if ( GetBusy() )
02299 GetCanvasView()->SetCursor( m_toolBusyCursor );
02300 else
02301 GetCanvasView()->SetCursor( m_toolcursor );
02302
02303 m_x = event.GetX();
02304 m_y = event.GetY();
02305 MouseToToolWorld( m_x, m_y, m_xwprev, m_ywprev );
02306
02307 a2dRestrictionEngine *restrict = a2dCanvasGlobals->GetRestrictionEngine();
02308 if(restrict)
02309 restrict->RestrictPoint(m_xwprev, m_ywprev);
02310
02311 if (event.LeftDClick() && !GetBusy())
02312 {
02313
02314 }
02315 else if (event.LeftDown() && !GetBusy())
02316 {
02317 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
02318 a2dRect* rec = new a2dRect( m_xwprev, m_ywprev, 0, 0, 0);
02319 rec->SetCanvasDocument( GetCanvasView()->GetCanvasDocument() );
02320 rec->SetFill( m_fill );
02321 rec->SetStroke( m_stroke );
02322 rec->Update( a2dCanvasObject::updatemask_force );
02323
02324 m_original = rec;
02325 EnterBusyMode();
02326
02327
02328
02329
02330 event.Skip();
02331 }
02332 else if ( event.LeftDown() && GetBusy())
02333 {
02334 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
02335 CleanupToolObjects();
02336
02337 a2dRect* rec = wxStaticCast( m_canvasobject.Get(), a2dRect );
02338
02339 double w = GetDrawer2D()->WorldToDeviceXRel( rec->GetWidth() );
02340 double h = GetDrawer2D()->WorldToDeviceYRel( rec->GetHeight() );
02341
02342 static wxString image_dir = _T("./");
02343 static wxString filter = _T("All files (*.*)| *.*| BMP files (*.bmp)|*.bmp| GIF files (*.gif)|*.gif| JPEG files (*.jpg)|*.jpg| PNG files (*.png)| *.png");
02344
02345 wxFileName image_file;
02346
02347 wxFileDialog dialog( GetDisplayWindow(), _T("Select Image File"), image_dir, image_file.GetFullPath(), filter, wxFD_OPEN );
02348
02349 if ( dialog.ShowModal() != wxID_OK )
02350 return;
02351
02352
02353 image_dir = dialog.GetDirectory();
02354 image_file = dialog.GetFilename();
02355
02356 wxBitmapType type = wxBITMAP_TYPE_ANY;
02357
02358 if ( image_file.GetExt() == _T("bmp") )
02359 type = wxBITMAP_TYPE_BMP;
02360 else if ( image_file.GetExt() == _T("gif") )
02361 type = wxBITMAP_TYPE_GIF;
02362 else if ( image_file.GetExt() == _T("jpg") )
02363 type = wxBITMAP_TYPE_JPEG;
02364 else if ( image_file.GetExt() == _T("png") )
02365 type = wxBITMAP_TYPE_PNG;
02366 else
02367 type = wxBITMAP_TYPE_ANY;
02368
02369 wxImage image;
02370
02371 a2dImage* canvas_image;
02372
02373 #ifdef __WXMSW__
02374 const wxChar SEP = wxT('\\');
02375 #else
02376 const wxChar SEP = wxT('/');
02377 #endif
02378
02379 wxString image_fullpath = image_dir + SEP + image_file.GetFullPath();
02380 image.LoadFile( image_fullpath, type );
02381
02382 double x1 = rec->GetBbox().GetMinX();
02383 double y1 = rec->GetBbox().GetMinY();
02384 double image_w = fabs( rec->GetWidth() );
02385 double image_h = fabs( rec->GetHeight() );
02386
02387 if (fabs( w ) < 3 && fabs( h )< 3)
02388 {
02389 image_w = image.GetWidth();
02390 image_h = image.GetHeight();
02391
02392 canvas_image = new a2dImage( image, x1 + image_w/2 , y1 + image_h/2, 0, 0);
02393 }
02394 else
02395 {
02396 canvas_image = new a2dImage( image, x1 + image_w/2 , y1 + image_h/2, image_w, image_h );
02397 }
02398 canvas_image->SetFilename( image_fullpath, type, false );
02399 canvas_image->SetCanvasDocument( GetCanvasView()->GetCanvasDocument() );
02400 canvas_image->SetFill( *a2dTRANSPARENT_FILL );
02401 canvas_image->SetStroke( *a2dTRANSPARENT_STROKE );
02402 canvas_image->SetLayer( m_layer );
02403 canvas_image->SetImageType( type );
02404 canvas_image->SetDrawPatternOnTop( m_drawPatternOnTop );
02405
02406 m_original = canvas_image;
02407 AddCurrent( canvas_image );
02408
02409 a2dREFOBJECTPTR_KEEPALIVE;
02410 FinishBusyMode();
02411 GetCanvasView()->Update( a2dCANVIEW_UPDATE_SYNC_DRAWERS );
02412 }
02413 else if ((event.Dragging() && GetBusy()) || (event.Moving() && GetBusy()) )
02414 {
02415 a2dRect* rec = wxStaticCast( m_canvasobject.Get(), a2dRect );
02416 rec->SetWidth( m_xwprev - rec->GetPosX() );
02417 rec->SetHeight( m_ywprev - rec->GetPosY() );
02418
02419 m_pending = true;
02420 }
02421 else
02422 event.Skip();
02423 }
02424
02425
02426 A2D_BEGIN_EVENT_TABLE(a2dCopyTool,a2dDragTool)
02427 A2D_EVT_MOUSE_EVENTS(a2dCopyTool::OnMouseEvent)
02428 A2D_END_EVENT_TABLE()
02429
02430 a2dCopyTool::a2dCopyTool(a2dStToolContr* controller):a2dDragTool(controller)
02431 {
02432 m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW );
02433 m_toolBusyCursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_Copy );
02434 m_mindist = a2dCanvasGlobals->GetCopyMinDistance();
02435 }
02436
02437 bool a2dCopyTool::CreateToolObjects()
02438 {
02439
02440 m_canvasobject = m_original->TClone( clone_childs | clone_seteditcopy | clone_setoriginal | clone_members );
02441 m_canvasobject->SetSelected( false );
02442
02443 AddEditobject( m_canvasobject );
02444 m_pending = true;
02445
02446 return true;
02447 }
02448
02449 void a2dCopyTool::OnMouseEvent(wxMouseEvent& event)
02450 {
02451 if (!m_active)
02452 {
02453 event.Skip();
02454 return;
02455 }
02456
02457 int x = event.GetX();
02458 int y = event.GetY();
02459
02460
02461 double xw,yw;
02462 MouseToToolWorld( x, y, xw, yw );
02463
02464 a2dRestrictionEngine *restrict = a2dCanvasGlobals->GetRestrictionEngine();
02465 if(restrict)
02466 {
02467 restrict->SetShiftKeyDown( event.ShiftDown() );
02468 restrict->SetAltKeyDown( event.AltDown() );
02469 }
02470
02471 if ( event.Moving() && !GetBusy() )
02472 {
02473 a2dCanvasObject* hit = GetCanvasView()->IsHitWorld( xw, yw );
02474 if ( hit && hit->GetDraggable() )
02475 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_HAND ) );
02476 else
02477 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW ) );
02478
02479 }
02480
02481 if (event.LeftDown())
02482 {
02483 m_original = GetCanvasView()->IsHitWorld( xw, yw, wxLAYER_ALL, a2dCANOBJHITOPTION_LAYERS );
02484
02485 if (!m_original)
02486 {
02487 m_original=0;
02488 return;
02489 }
02490 if (!m_original->GetDraggable() )
02491 {
02492 m_original=0;
02493 return;
02494 }
02495
02496 EnterBusyMode();
02497
02498 m_original = m_original->TClone( clone_childs | clone_seteditcopy | clone_setoriginal );
02499 m_original->DoConnect(false);
02500
02501 GetCanvasCommandProcessor()->Submit(
02502 new a2dCommand_AddObject( m_parentobject, m_original )
02503 );
02504
02505 GetCanvasView()->SetCursor( m_toolcursor );
02506 m_xwprev = xw;
02507 m_ywprev = yw;
02508 m_startMousex = xw;
02509 m_startMousey = yw;
02510
02511 if(restrict)
02512 restrict->SetRestrictPoint( m_startMousex, m_startMousey );
02513
02514 double dx = xw-m_startMousex;
02515 double dy = yw-m_startMousey;
02516 AdjustShift( &dx, &dy );
02517 DragAbsolute( m_startObjectx+dx, m_startObjecty+dy );
02518 }
02519 else if (event.LeftUp() && GetBusy())
02520 {
02521 GetCanvasView()->SetCursor( m_toolcursor );
02522 m_original->DoConnect(true);
02523 m_original->ReWireConnected( GetCanvasView()->GetShowObject(), true );
02524
02525
02526 m_xwprev = xw;
02527 m_ywprev = yw;
02528
02529 FinishBusyMode();
02530 }
02531 else if (GetBusy())
02532 {
02533 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_HAND ) );
02534 double dx = xw-m_startMousex;
02535 double dy = yw-m_startMousey;
02536 AdjustShift( &dx, &dy );
02537 DragAbsolute( m_startObjectx+dx, m_startObjecty+dy );
02538 m_xwprev = xw;
02539 m_ywprev = yw;
02540 }
02541 else
02542 {
02543 event.Skip();
02544 }
02545 }
02546
02547 void a2dCopyTool::AdjustShift( double *dx, double *dy )
02548 {
02549 if( (*dx)*(*dx)+(*dy)*(*dy)<m_mindist )
02550 {
02551 if( (*dx) == 0 && (*dy) == 0 )
02552 {
02553 (*dx) = m_mindist * 1.0;
02554 (*dy) = m_mindist * 0.5;
02555 }
02556 else
02557 {
02558 double fac = m_mindist / sqrt((*dx)*(*dx)+(*dy)*(*dy));
02559 (*dx)*=fac;
02560 (*dy)*=fac;
02561 }
02562 }
02563 }
02564
02565 A2D_BEGIN_EVENT_TABLE(a2dDragTool,a2dStTool)
02566 A2D_EVT_MOUSE_EVENTS(a2dDragTool::OnMouseEvent)
02567 A2D_EVT_CHAR(a2dDragTool::OnChar)
02568 A2D_END_EVENT_TABLE()
02569
02570 a2dDragTool::a2dDragTool(a2dStToolContr* controller):a2dStTool(controller)
02571 {
02572 m_eventHandler = new a2dStToolFixedToolStyleEvtHandler( controller );
02573
02574 m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW );
02575 m_toolBusyCursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag );
02576 m_mousecaptured = false;
02577 m_deleteonoutsidedrop = false;
02578
02579 m_anotate = false;
02580 m_lateconnect = true;
02581
02582
02583 SetFill( *a2dTRANSPARENT_FILL );
02584 SetStroke( a2dStroke(*wxRED, 1, a2dSTROKE_DOT) );
02585 }
02586
02587 a2dDragTool::~a2dDragTool()
02588 {
02589 }
02590
02591 void a2dDragTool::OnChar(wxKeyEvent& event)
02592 {
02593 if (GetBusy())
02594 {
02595 double xw = m_xwprev;
02596 double yw = m_ywprev;
02597
02598 double shiftx;
02599 double shifty;
02600 GetKeyIncrement(&shiftx, &shifty, event.AltDown());
02601
02602
02603 switch(event.GetKeyCode())
02604 {
02605 case WXK_UP:
02606 shiftx = 0;
02607 break;
02608
02609 case WXK_DOWN:
02610 shiftx = 0;
02611 shifty = -shifty;
02612 break;
02613
02614 case WXK_LEFT:
02615 shiftx = -shiftx;
02616 shifty = 0;
02617 break;
02618
02619 case WXK_RIGHT:
02620 shifty = 0;
02621 break;
02622 default:
02623 {
02624 shiftx = 0;
02625 shifty = 0;
02626 event.Skip();
02627 }
02628 }
02629
02630 m_xwprev = xw + shiftx;
02631 m_ywprev = yw + shifty;
02632 DragAbsolute( m_xwprev, m_ywprev );
02633
02634 GetCanvasView()->Update( a2dCANVIEW_UPDATE_SYNC_DRAWERS );
02635 GetDisplayWindow()->WarpPointer( GetDrawer2D()->WorldToDeviceX(m_xwprev), GetDrawer2D()->WorldToDeviceY(m_ywprev) );
02636 }
02637 else
02638 event.Skip();
02639
02640 }
02641
02642 void a2dDragTool::Render()
02643 {
02644 if ( m_original && GetBusy())
02645 {
02646 a2dStTool::Render();
02647 }
02648 }
02649
02650 void a2dDragTool::AdjustShift( double *WXUNUSED(x), double *WXUNUSED(y) )
02651 {
02652 }
02653
02654 void a2dDragTool::OnMouseEvent(wxMouseEvent& event)
02655 {
02656 if (!m_active)
02657 {
02658 event.Skip();
02659 return;
02660 }
02661
02662 m_x = event.GetX();
02663 m_y = event.GetY();
02664
02665
02666 double xw,yw;
02667 MouseToToolWorld( m_x, m_y, xw, yw );
02668
02669 a2dRestrictionEngine *restrict = a2dCanvasGlobals->GetRestrictionEngine();
02670 if(restrict)
02671 {
02672 restrict->SetShiftKeyDown( event.ShiftDown() );
02673 restrict->SetAltKeyDown( event.AltDown() );
02674 }
02675
02676 if ( event.Moving() && !GetBusy() )
02677 {
02678 a2dCanvasObject* hit = GetCanvasView()->IsHitWorld( xw, yw );
02679 if ( hit && hit->GetDraggable() )
02680 GetCanvasView()->SetCursor( m_toolBusyCursor );
02681 else
02682 GetCanvasView()->SetCursor( m_toolcursor );
02683
02684 event.Skip();
02685 }
02686
02687 if (event.LeftDown())
02688 {
02689 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
02690 m_original = GetCanvasView()->IsHitWorld( xw, yw, wxLAYER_ALL, a2dCANOBJHITOPTION_LAYERS );
02691
02692 if (!m_original)
02693 return;
02694 if (!m_original->GetDraggable() )
02695 {
02696 m_original=0;
02697 return;
02698 }
02699
02700 m_transform = m_original->GetTransformMatrix();
02701
02702 EnterBusyMode();
02703
02704 m_xwprev = xw;
02705 m_ywprev = yw;
02706 m_startMousex = xw;
02707 m_startMousey = yw;
02708
02709 if(restrict)
02710 restrict->SetRestrictPoint( m_original->GetPosX(), m_original->GetPosY() );
02711 }
02712 else if (event.LeftUp() && GetBusy())
02713 {
02714 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
02715 FinishBusyMode();
02716 }
02717 else if (event.RightDown())
02718 {
02719 event.Skip();
02720 }
02721 else if (GetBusy())
02722 {
02723
02724
02725 GetCanvasView()->SetCursor( m_toolBusyCursor );
02726
02727 double xPosObject = m_startObjectx+xw-m_startMousex;
02728 double yPosObject = m_startObjecty+yw-m_startMousey;
02729 DragAbsolute( xPosObject, yPosObject );
02730 m_xwprev = xw;
02731 m_ywprev = yw;
02732 }
02733
02734
02735
02736 }
02737
02738
02739 void a2dDragTool::CaptureMouse()
02740 {
02741 GetCanvasView()->SetCaptured( m_canvasobject );
02742 GetCanvasView()->GetDisplayWindow()->CaptureMouse();
02743 m_mousecaptured = true;
02744 }
02745
02746 void a2dDragTool::ReleaseMouse()
02747 {
02748 if( m_mousecaptured )
02749 {
02750 GetCanvasView()->SetCaptured( NULL );
02751 GetCanvasView()->GetDisplayWindow()->ReleaseMouse();
02752 }
02753 m_mousecaptured = false;
02754 }
02755
02756 bool a2dDragTool::EnterBusyMode()
02757 {
02758
02759
02760 m_original->CreateWiresOnPins( GetParentObject(), true );
02761
02762 if(!a2dStTool::EnterBusyMode())
02763 return false;
02764
02765 CaptureMouse();
02766
02767
02768 m_canvasobject->DoConnect( false );
02769 m_wasMayConnect = m_original->DoConnect();
02770 if ( m_lateconnect )
02771 m_original->DoConnect( false );
02772
02773 m_startObjectx = m_canvasobject->GetPosX();
02774 m_startObjecty = m_canvasobject->GetPosY();
02775
02776 return true;
02777 }
02778
02779 void a2dDragTool::FinishBusyMode( bool closeCommandGroup )
02780 {
02781
02782 m_original->DoConnect( m_wasMayConnect );
02783
02784 if(
02785 m_deleteonoutsidedrop &&
02786 (
02787 m_xwprev < GetDrawer2D()->GetVisibleMinX() ||
02788 m_xwprev > GetDrawer2D()->GetVisibleMaxX() ||
02789 m_ywprev < GetDrawer2D()->GetVisibleMinY() ||
02790 m_ywprev > GetDrawer2D()->GetVisibleMaxY()
02791 )
02792 )
02793 {
02794
02795
02796 m_original->SetPending(true);
02797 m_original->SetVisible(false);
02798
02799
02800 GetCanvasView()->GetCanvasDocument()->AddPendingUpdatesOldNew();
02801
02802
02803 m_original->ClearAllPinConnections( GetCanvasCommandProcessor() );
02804
02805
02806 GetCanvasCommandProcessor()->Submit(
02807 new a2dCommand_ReleaseObject( m_parentobject, m_original )
02808 );
02809 }
02810 else
02811 {
02812
02813 GetCanvasCommandProcessor()->Submit(
02814 new a2dCommand_SetCanvasProperty( m_original, a2dCanvasObject::PROPID_TransformMatrix, m_canvasobject->GetTransformMatrix() )
02815 );
02816
02817 m_connectedwirecopies.UpdateImmediate( true, this, m_canvasobject );
02818 }
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831
02832
02833
02834
02835
02836
02837 ReleaseMouse();
02838
02839 a2dStTool::FinishBusyMode();
02840 }
02841
02842 void a2dDragTool::AbortBusyMode()
02843 {
02844 ReleaseMouse();
02845
02846 a2dStTool::AbortBusyMode();
02847 }
02848
02849 void a2dDragTool::DragAbsolute( double x, double y )
02850 {
02851 a2dPoint2D oldpos = m_canvasobject->GetPosXY();
02852
02853 a2dRestrictionEngine *restrict = a2dCanvasGlobals->GetRestrictionEngine();
02854 if(restrict)
02855 {
02856
02857 m_canvasobject->SetPosXY( x, y );
02858
02859 a2dPoint2D point;
02860 double dx, dy;
02861
02862 if ( restrict->GetShiftKeyDown() )
02863 {
02864 restrict->RestrictPoint( x, y );
02865 }
02866 else
02867 {
02868
02869 wxUint32 snapTo =
02870 a2dRestrictionEngine::snapToGridPos |
02871 a2dRestrictionEngine::snapToBoundingBox |
02872 a2dRestrictionEngine::snapToObjectPos |
02873 a2dRestrictionEngine::snapToPinsUnconnected |
02874 a2dRestrictionEngine::snapToObjectVertexes |
02875 a2dRestrictionEngine::snapToObjectSnapVPath;
02876 if ( restrict->RestrictCanvasObjectAtVertexes( m_canvasobject, point, dx, dy, snapTo ) )
02877 {
02878
02879 x += dx;
02880 y += dy;
02881 }
02882 }
02883 }
02884
02885
02886 m_canvasobject->SetPosXY(x,y);
02887 if ( m_stcontroller->GetDragMode() == wxDRAW_REDRAW )
02888 {
02889 m_original->SetPosXY(x,y);
02890 }
02891
02892 if( oldpos != m_canvasobject->GetPosXY() )
02893 {
02894 a2dIterC ic( GetCanvasView() );
02895 GetCanvasView()->GetShowObject()->EditFeedback( ic, &a2dPin::sm_feedbackCanConnect, 0, 2, 0 );
02896
02897 m_connectedwirecopies.UpdateImmediate( false, this, m_canvasobject );
02898
02899 m_pending = true;
02900 }
02901 }
02902
02903 bool a2dDragTool::CreateToolObjects()
02904 {
02905
02906 m_canvasobject = m_original->TClone( clone_childs | clone_reconnectable | clone_seteditcopy | clone_setoriginal | clone_members );
02907 m_canvasobject->SetSelected( false );
02908 m_original->SetSnapTo( false );
02909
02910
02911 a2dCanvasObjectList connectedwires;
02912 m_original->CreateWireEditCopies( &connectedwires, &m_connectedwirecopies );
02913 m_canvasobject->RestoreConnectionsAfterCloning();
02914 m_connectedwirecopies.RestoreConnectionsAfterCloning();
02915
02916
02917 m_original->SetVisible( m_renderOriginal );
02918 connectedwires.SetSpecificFlags( m_renderOriginal, a2dCanvasOFlags::VISIBLE );
02919
02920
02921 AddEditobject( m_canvasobject );
02922 for( a2dCanvasObjectList::iterator iter = m_connectedwirecopies.begin(); iter != m_connectedwirecopies.end(); ++iter )
02923 {
02924 AddEditobject( (*iter) );
02925 }
02926
02927 m_pending = true;
02928
02929 return true;
02930 }
02931
02932 void a2dDragTool::CleanupToolObjects()
02933 {
02934 a2dStTool::CleanupToolObjects();
02935 m_connectedwirecopies.clear();
02936 }
02937
02938 A2D_BEGIN_EVENT_TABLE(a2dDragOrgTool,a2dStTool)
02939 A2D_EVT_MOUSE_EVENTS(a2dDragOrgTool::OnMouseEvent)
02940 A2D_EVT_CHAR(a2dDragOrgTool::OnChar)
02941 A2D_END_EVENT_TABLE()
02942
02943 a2dDragOrgTool::a2dDragOrgTool(a2dStToolContr* controller):a2dStTool(controller)
02944 {
02945 m_eventHandler = new a2dStToolFixedToolStyleEvtHandler( controller );
02946
02947 m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW );
02948 m_toolBusyCursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag );
02949 m_mousecaptured = false;
02950 m_deleteonoutsidedrop = false;
02951
02952 m_anotate = false;
02953 m_lateconnect = true;
02954
02955
02956 SetFill( *a2dTRANSPARENT_FILL );
02957 SetStroke( a2dStroke(*wxRED, 1, a2dSTROKE_DOT) );
02958 }
02959
02960 a2dDragOrgTool::~a2dDragOrgTool()
02961 {
02962 }
02963
02964 void a2dDragOrgTool::OnChar(wxKeyEvent& event)
02965 {
02966 if (GetBusy())
02967 {
02968 double xw = m_xwprev;
02969 double yw = m_ywprev;
02970
02971 double shiftx;
02972 double shifty;
02973 GetKeyIncrement(&shiftx, &shifty, event.AltDown());
02974
02975
02976 switch(event.GetKeyCode())
02977 {
02978 case WXK_UP:
02979 shiftx = 0;
02980 break;
02981
02982 case WXK_DOWN:
02983 shiftx = 0;
02984 shifty = -shifty;
02985 break;
02986
02987 case WXK_LEFT:
02988 shiftx = -shiftx;
02989 shifty = 0;
02990 break;
02991
02992 case WXK_RIGHT:
02993 shifty = 0;
02994 break;
02995 default:
02996 {
02997 shiftx = 0;
02998 shifty = 0;
02999 event.Skip();
03000 }
03001 }
03002
03003 m_xwprev = xw + shiftx;
03004 m_ywprev = yw + shifty;
03005 DragAbsolute( m_xwprev, m_ywprev );
03006 GetCanvasView()->Update( a2dCANVIEW_UPDATE_SYNC_DRAWERS );
03007 GetDisplayWindow()->WarpPointer( GetDrawer2D()->WorldToDeviceX(m_xwprev), GetDrawer2D()->WorldToDeviceY(m_ywprev) );
03008 }
03009 else
03010 event.Skip();
03011
03012 }
03013
03014 void a2dDragOrgTool::Render()
03015 {
03016 if ( m_original && GetBusy())
03017 {
03018 a2dStTool::Render();
03019 }
03020 }
03021
03022 void a2dDragOrgTool::AdjustShift( double *WXUNUSED(x), double *WXUNUSED(y) )
03023 {
03024 }
03025
03026 void a2dDragOrgTool::OnMouseEvent(wxMouseEvent& event)
03027 {
03028 if (!m_active)
03029 {
03030 event.Skip();
03031 return;
03032 }
03033
03034 m_x = event.GetX();
03035 m_y = event.GetY();
03036
03037
03038 double xw,yw;
03039 MouseToToolWorld( m_x, m_y, xw, yw );
03040
03041 a2dRestrictionEngine *restrict = a2dCanvasGlobals->GetRestrictionEngine();
03042 if(restrict)
03043 restrict->RestrictPoint(xw, yw);
03044
03045 if ( event.Moving() && !GetBusy() )
03046 {
03047 a2dCanvasObject* hit = GetCanvasView()->IsHitWorld( xw, yw );
03048 if ( hit && hit->GetDraggable() )
03049 GetCanvasView()->SetCursor( m_toolBusyCursor );
03050 else
03051 GetCanvasView()->SetCursor( m_toolcursor );
03052 }
03053
03054 if (event.LeftDown())
03055 {
03056 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
03057 m_original = GetCanvasView()->IsHitWorld( xw, yw, wxLAYER_ALL, a2dCANOBJHITOPTION_LAYERS );
03058
03059 if (!m_original)
03060 return;
03061 if (!m_original->GetDraggable() )
03062 {
03063 m_original=0;
03064 return;
03065 }
03066
03067 m_transform = m_original->GetTransformMatrix();
03068
03069 EnterBusyMode();
03070
03071 m_xwprev = xw;
03072 m_ywprev = yw;
03073 m_startMousex = xw;
03074 m_startMousey = yw;
03075 }
03076 else if (event.LeftUp() && GetBusy())
03077 {
03078 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
03079 FinishBusyMode();
03080 }
03081 else if (event.RightDown())
03082 {
03083 event.Skip();
03084 }
03085 else if (GetBusy())
03086 {
03087 GetCanvasView()->SetCursor( m_toolBusyCursor );
03088 DragAbsolute( m_startObjectx+xw-m_startMousex, m_startObjecty+yw-m_startMousey );
03089
03090 m_xwprev = xw;
03091 m_ywprev = yw;
03092 }
03093
03094
03095
03096 }
03097
03098
03099 void a2dDragOrgTool::CaptureMouse()
03100 {
03101 GetCanvasView()->SetCaptured( m_canvasobject );
03102 GetCanvasView()->GetDisplayWindow()->CaptureMouse();
03103 m_mousecaptured = true;
03104 }
03105
03106 void a2dDragOrgTool::ReleaseMouse()
03107 {
03108 if( m_mousecaptured )
03109 {
03110 GetCanvasView()->SetCaptured( NULL );
03111 GetCanvasView()->GetDisplayWindow()->ReleaseMouse();
03112 }
03113 m_mousecaptured = false;
03114 }
03115
03116 bool a2dDragOrgTool::EnterBusyMode()
03117 {
03118
03119
03120 m_original->CreateWiresOnPins( GetParentObject(), true );
03121
03122 if(!a2dStTool::EnterBusyMode())
03123 return false;
03124
03125 CaptureMouse();
03126
03127
03128 m_canvasobject->DoConnect( false );
03129 m_wasMayConnect = m_original->DoConnect();
03130 if ( m_lateconnect )
03131 m_original->DoConnect( false );
03132
03133 m_startObjectx = m_canvasobject->GetPosX();
03134 m_startObjecty = m_canvasobject->GetPosY();
03135
03136 return true;
03137 }
03138
03139 void a2dDragOrgTool::FinishBusyMode( bool closeCommandGroup )
03140 {
03141
03142 m_original->DoConnect( m_wasMayConnect );
03143
03144 if(
03145 m_deleteonoutsidedrop &&
03146 (
03147 m_xwprev < GetDrawer2D()->GetVisibleMinX() ||
03148 m_xwprev > GetDrawer2D()->GetVisibleMaxX() ||
03149 m_ywprev < GetDrawer2D()->GetVisibleMinY() ||
03150 m_ywprev > GetDrawer2D()->GetVisibleMaxY()
03151 )
03152 )
03153 {
03154
03155
03156 m_original->SetPending(true);
03157 m_original->SetVisible(false);
03158
03159
03160 GetCanvasView()->GetCanvasDocument()->AddPendingUpdatesOldNew();
03161
03162
03163 m_original->ClearAllPinConnections( GetCanvasCommandProcessor() );
03164
03165
03166 GetCanvasCommandProcessor()->Submit(
03167 new a2dCommand_ReleaseObject( m_parentobject, m_original )
03168 );
03169 }
03170 else
03171 {
03172
03173 GetCanvasCommandProcessor()->Submit(
03174 new a2dCommand_SetCanvasProperty( m_original, a2dCanvasObject::PROPID_TransformMatrix, m_canvasobject->GetTransformMatrix() )
03175 );
03176
03177 m_connectedwirecopies.UpdateImmediate( true, this, NULL );
03178 }
03179
03180 ReleaseMouse();
03181
03182 a2dStTool::FinishBusyMode( closeCommandGroup );
03183 }
03184
03185 void a2dDragOrgTool::AbortBusyMode()
03186 {
03187 ReleaseMouse();
03188
03189 a2dStTool::AbortBusyMode();
03190 }
03191
03192 void a2dDragOrgTool::DragAbsolute( double x, double y )
03193 {
03194 a2dPoint2D oldpos = m_canvasobject->GetPosXY();
03195
03196 a2dRestrictionEngine *restrict = a2dCanvasGlobals->GetRestrictionEngine();
03197 if(restrict)
03198 {
03199
03200 m_canvasobject->SetPosXY( x, y );
03201
03202 a2dPoint2D point;
03203 double dx, dy;
03204 if ( restrict->RestrictCanvasObjectAtVertexes( m_canvasobject, point, dx, dy ) )
03205 {
03206
03207 x += dx;
03208 y += dy;
03209 }
03210 }
03211
03212
03213 m_canvasobject->SetPosXY(x,y);
03214 if ( m_stcontroller->GetDragMode() == wxDRAW_REDRAW )
03215 m_original->SetPosXY(x,y);
03216
03217 if( oldpos != m_canvasobject->GetPosXY() )
03218 {
03219 a2dIterC ic( GetCanvasView() );
03220 GetCanvasView()->GetShowObject()->EditFeedback( ic, &a2dPin::sm_feedbackCanConnect, 0, 2, 0 );
03221
03222 m_connectedwirecopies.UpdateImmediate( false, this, m_canvasobject );
03223
03224 m_pending = true;
03225 }
03226 }
03227
03228 bool a2dDragOrgTool::CreateToolObjects()
03229 {
03230
03231 m_canvasobject = m_original;
03232 m_canvasobject->SetSelected( false );
03233 m_original->SetSnapTo( false );
03234
03235
03236 a2dCanvasObjectList connectedwires;
03237 m_original->CreateWireEditCopies( &connectedwires, &m_connectedwirecopies );
03238 m_connectedwirecopies.RestoreConnectionsAfterCloning();
03239
03240
03241 for( a2dCanvasObjectList::iterator iter = m_connectedwirecopies.begin(); iter != m_connectedwirecopies.end(); ++iter )
03242 {
03243 AddEditobject( (*iter) );
03244 }
03245
03246 m_pending = true;
03247
03248 return true;
03249 }
03250
03251
03252 void a2dDragOrgTool::CleanupToolObjects()
03253 {
03254 a2dStTool::CleanupToolObjects();
03255 m_connectedwirecopies.clear();
03256 }
03257
03258 A2D_BEGIN_EVENT_TABLE(a2dDragNewTool,a2dDragTool)
03259 A2D_EVT_ENTER_WINDOW( a2dDragNewTool::OnEnter )
03260 A2D_EVT_MOUSE_EVENTS( a2dDragNewTool::OnMouseEvent )
03261 A2D_END_EVENT_TABLE()
03262
03263 a2dDragNewTool::a2dDragNewTool( a2dStToolContr* controller, a2dCanvasObject *newObject )
03264 : a2dDragTool(controller)
03265 {
03266 m_eventHandler = new a2dStToolFixedToolStyleEvtHandler( controller );
03267
03268 m_newObject = newObject;
03269 }
03270
03271 a2dDragNewTool::~a2dDragNewTool()
03272 {
03273 }
03274
03275 void a2dDragNewTool::OnComEvent( a2dComEvent& event )
03276 {
03277 if (GetBusy())
03278 {
03279 if ( event.GetEventComId() == &a2dStTool::sm_toolBeforePush )
03280 {
03281 a2dProperty* property = (a2dProperty*) event.GetProperty();
03282 a2dStTool* newtool = wxStaticCast( property->GetRefObject(), a2dStTool );
03283 if ( GetBusy() )
03284 {
03285 if ( !wxDynamicCast( newtool, a2dZoomTool ) )
03286 {
03287 FinishBusyMode();
03288 }
03289 else
03290 {
03291 m_halted = true;
03292 }
03293 }
03294 SetPending( true );
03295 }
03296 else
03297 event.Skip();
03298 }
03299 else
03300 event.Skip();
03301 }
03302
03303 void a2dDragNewTool::OnEnter( wxMouseEvent & WXUNUSED(event) )
03304 {
03305 GetCanvasView()->GetDisplayWindow()->SetFocus();
03306 }
03307
03308 void a2dDragNewTool::OnMouseEvent(wxMouseEvent& event)
03309 {
03310 if (!m_active)
03311 {
03312 event.Skip();
03313 return;
03314 }
03315
03316 m_x = event.GetX();
03317 m_y = event.GetY();
03318
03319
03320 double xw,yw;
03321 MouseToToolWorld( m_x, m_y, xw, yw );
03322
03323 a2dRestrictionEngine *restrict = a2dCanvasGlobals->GetRestrictionEngine();
03324 if(restrict)
03325 restrict->RestrictPoint(xw, yw);
03326
03327 if( !GetBusy() )
03328 {
03329
03330 m_original = m_newObject->TClone( clone_childs );
03331 m_original->SetPosXY(xw, yw);
03332 m_original->SetCanvasDocument( GetCanvasView()->GetCanvasDocument() );
03333
03334
03335 m_parentAddedTo = m_parentobject;
03336
03337 EnterBusyMode();
03338
03339 m_transform = m_original->GetTransformMatrix();
03340
03341 m_xwprev = xw;
03342 m_ywprev = yw;
03343 m_startMousex = xw;
03344 m_startMousey = yw;
03345 }
03346 else if (event.LeftDown())
03347 {
03348
03349 }
03350 else if (event.RightDown())
03351 {
03352 event.Skip();
03353 }
03354 else if (event.LeftUp())
03355 {
03356 a2dDragTool::OnMouseEvent( event );
03357 a2dGetCmdh()->SetCurrentCanvasObject( 0 );
03358 }
03359 else
03360 {
03361
03362 a2dDragTool::OnMouseEvent( event );
03363 }
03364 }
03365
03366 void a2dDragNewTool::AdjustRenderOptions()
03367 {
03368
03369
03370
03371 m_renderOriginal = false;
03372 }
03373
03374 void a2dDragNewTool::DoStopTool( bool WXUNUSED(abort) )
03375 {
03376
03377
03378 if( GetBusy() )
03379 {
03380 wxASSERT( m_original );
03381 AbortBusyMode();
03382 }
03383
03384 if ( m_commandgroup )
03385 CloseCommandGroup();
03386 }
03387
03388 bool a2dDragNewTool::EnterBusyMode()
03389 {
03390 if(!a2dDragTool::EnterBusyMode())
03391 return false;
03392
03393
03394 ReleaseMouse();
03395
03396
03397
03398
03399 return true;
03400 }
03401
03402 void a2dDragNewTool::FinishBusyMode( bool closeCommandGroup )
03403 {
03404
03405 m_original->DoConnect( m_wasMayConnect );
03406
03407
03408 GetCanvasCommandProcessor()->Submit(
03409 new a2dCommand_SetCanvasProperty( m_original, a2dCanvasObject::PROPID_TransformMatrix, m_canvasobject->GetTransformMatrix() )
03410 );
03411 AddCurrent( m_original );
03412
03413 m_connectedwirecopies.UpdateImmediate( true, this, m_canvasobject );
03414 ReleaseMouse();
03415
03416 a2dStTool::FinishBusyMode();
03417 }
03418
03419
03420 A2D_BEGIN_EVENT_TABLE(a2dDeleteTool,a2dStTool)
03421 A2D_EVT_CHAR(a2dDeleteTool::OnChar)
03422 A2D_EVT_MOUSE_EVENTS(a2dDeleteTool::OnMouseEvent)
03423 A2D_END_EVENT_TABLE()
03424
03425 a2dDeleteTool::a2dDeleteTool(a2dStToolContr* controller, a2dCanvasObjectFlagsMask whichobjects )
03426 :
03427 a2dStTool(controller)
03428 {
03429 m_eventHandler = new a2dStToolFixedToolStyleEvtHandler( controller );
03430
03431 m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_BULLSEYE );
03432 m_canvasobject=0;
03433 m_whichobjects = whichobjects;
03434 }
03435
03436 void a2dDeleteTool::OnChar(wxKeyEvent& event)
03437 {
03438 if (GetBusy())
03439 {
03440 switch(event.GetKeyCode())
03441 {
03442 case WXK_SPACE:
03443 {
03444 if( m_canvasobject )
03445 {
03446 OpenCommandGroup( false );
03447
03448 m_canvasobject->ClearAllPinConnections( GetCanvasCommandProcessor() );
03449
03450 GetCanvasCommandProcessor()->Submit(
03451 new a2dCommand_ReleaseObject( m_parentobject, m_canvasobject )
03452 );
03453 m_canvasobject->SetVisible( true );
03454 FinishBusyMode();
03455 }
03456 }
03457 break;
03458 default:
03459 event.Skip();
03460 }
03461 }
03462 else
03463 event.Skip();
03464
03465 }
03466
03467 void a2dDeleteTool::OnMouseEvent(wxMouseEvent& event)
03468 {
03469 if (!m_active)
03470 {
03471 event.Skip();
03472 return;
03473 }
03474 GetCanvasView()->SetCursor(m_toolcursor);
03475
03476 int x = event.GetX();
03477 int y = event.GetY();
03478
03479
03480 double xw,yw;
03481 MouseToToolWorld( x, y, xw, yw );
03482
03483 if (event.LeftDown())
03484 {
03485 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
03486 m_canvasobject = GetCanvasView()->IsHitWorld( xw, yw, wxLAYER_ALL, a2dCANOBJHITOPTION_LAYERS );
03487
03488 if (!m_canvasobject)
03489 {
03490 m_canvasobject=0;
03491 event.Skip();
03492 if (m_oneshot)
03493 StopTool();
03494 return;
03495 }
03496
03497 if( !m_canvasobject->CheckMask( m_whichobjects ) )
03498 {
03499 if (m_oneshot)
03500 StopTool();
03501 return;
03502 }
03503
03504 m_canvasobject->SetPending(true);
03505 m_canvasobject->SetVisible(false);
03506
03507 EnterBusyMode();
03508
03509
03510 GetCanvasView()->GetCanvasDocument()->AddPendingUpdatesOldNew();
03511
03512
03513 m_canvasobject->ClearAllPinConnections( GetCanvasCommandProcessor() );
03514
03515
03516 GetCanvasCommandProcessor()->Submit(
03517 new a2dCommand_ReleaseObject( m_parentobject, m_canvasobject )
03518 );
03519
03520 m_canvasobject->SetVisible( true );
03521 FinishBusyMode();
03522 }
03523 else
03524 event.Skip();
03525
03526 }
03527
03528 A2D_BEGIN_EVENT_TABLE(a2dDrawCircleTool,a2dStDrawTool)
03529 A2D_EVT_IDLE( a2dDrawCircleTool::OnIdle )
03530 A2D_EVT_CHAR( a2dDrawCircleTool::OnChar )
03531 A2D_EVT_MOUSE_EVENTS( a2dDrawCircleTool::OnMouseEvent )
03532 A2D_END_EVENT_TABLE()
03533
03534 a2dDrawCircleTool::a2dDrawCircleTool(a2dStToolContr* controller):a2dStDrawTool(controller)
03535 {
03536 m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_PENCIL );
03537 m_toolBusyCursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_CROSS );
03538 }
03539
03540 void a2dDrawCircleTool::GenerateAnotation()
03541 {
03542
03543 a2dStDrawTool::AddAnotationToPendingUpdateArea();
03544
03545
03546
03547 m_anotation.Printf( _T("radius %6.3f"), m_radius );
03548
03549 wxCoord w, h, descent, external;
03550 GetTextExtent( m_anotation, &w, &h, &descent, &external );
03551
03552 m_xanotation = m_x + h;
03553 m_yanotation = m_y + h;
03554
03555 a2dStDrawTool::AddAnotationToPendingUpdateArea();
03556 }
03557
03558
03559 void a2dDrawCircleTool::OnIdle( wxIdleEvent &event )
03560 {
03561 if (m_pending && GetBusy())
03562 {
03563 RemoveAllDecorations();
03564
03565 a2dCircle* cir = wxStaticCast( m_canvasobject.Get(), a2dCircle );
03566 a2dSLine* ll = new a2dSLine( cir->GetPosX(), cir->GetPosY(), m_xwprev, m_ywprev );
03567 ll->SetStroke( *wxRED, 0, a2dSTROKE_DOT );
03568
03569 a2dCircle* zero = new a2dCircle( m_start_x, m_start_y, GetDrawer2D()->DeviceToWorldXRel( 3 ) );
03570 zero->SetFill( *wxRED );
03571
03572 a2dRect* around = new a2dRect( cir->GetBboxMinX(), cir->GetBboxMinY(), cir->GetBboxWidth(), cir->GetBboxHeight() );
03573 around->SetStroke( *wxRED, 0, a2dSTROKE_LONG_DASH );
03574 around->SetFill( *a2dTRANSPARENT_FILL );
03575
03576 AddDecorationObject( around );
03577 AddDecorationObject( ll );
03578 AddDecorationObject( zero );
03579
03580 event.Skip();
03581 }
03582 else
03583 event.Skip();
03584 }
03585
03586 void a2dDrawCircleTool::OnChar(wxKeyEvent& event)
03587 {
03588 if (GetBusy())
03589 {
03590 switch(event.GetKeyCode())
03591 {
03592 case WXK_TAB:
03593 {
03594 m_mode++;
03595 SetMode( m_mode );
03596 }
03597 break;
03598
03599 default:
03600 event.Skip();
03601 }
03602 }
03603 else
03604 event.Skip();
03605
03606 }
03607
03608 void a2dDrawCircleTool::SetMode( int mode )
03609 {
03610 m_mode = mode;
03611 if (m_mode > 2) m_mode = 0;
03612
03613 if (!m_canvasobject)
03614 return;
03615
03616 a2dCircle* cir = wxStaticCast( m_canvasobject.Get(), a2dCircle );
03617 a2dCircle* cirorg = wxStaticCast( m_original.Get(), a2dCircle );
03618 switch ( m_mode )
03619 {
03620 case 0:
03621 {
03622 double dx, dy;
03623
03624 if ( fabs( m_xwprev - m_start_x ) > fabs( m_ywprev - m_start_y ) )
03625 {
03626 dx = ( m_xwprev - m_start_x ) /2 ;
03627 m_radius = fabs( dx );
03628 if ( m_ywprev > m_start_y )
03629 dy = m_radius;
03630 else
03631 dy = -m_radius;
03632 }
03633 else
03634 {
03635 dy = ( m_ywprev - m_start_y ) /2 ;
03636 m_radius = fabs( dy );
03637 if ( m_xwprev > m_start_x )
03638 dx = m_radius;
03639 else
03640 dx = -m_radius;
03641 }
03642 cir->SetPosXY( m_start_x + dx , m_start_y + dy );
03643 cirorg->SetPosXY( m_start_x + dx , m_start_y + dy );
03644 break;
03645 }
03646 case 1:
03647 {
03648 cir->SetPosXY( m_start_x, m_start_y );
03649 cirorg->SetPosXY( m_start_x, m_start_y );
03650 m_radius = sqrt(pow(m_xwprev-cir->GetPosX(),2)+pow(m_ywprev-cir->GetPosY(),2));
03651 break;
03652 }
03653 case 2:
03654 {
03655 cir->SetPosXY( (m_xwprev+m_start_x)/2, (m_ywprev+m_start_y)/2 );
03656 cirorg->SetPosXY( (m_xwprev+m_start_x)/2, (m_ywprev+m_start_y)/2 );
03657 m_radius = sqrt(pow(m_xwprev-m_start_x,2)+pow(m_ywprev-m_start_y,2))/2;
03658 break;
03659 }
03660 default:
03661 break;
03662 }
03663
03664 cir->SetRadius(m_radius);
03665 cirorg->SetRadius(m_radius);
03666 m_pending = true;
03667 }
03668
03669 void a2dDrawCircleTool::OnMouseEvent(wxMouseEvent& event)
03670 {
03671 if (!m_active)
03672 {
03673 event.Skip();
03674 return;
03675 }
03676
03677 if ( GetBusy() )
03678 GetCanvasView()->SetCursor( m_toolBusyCursor );
03679 else
03680 GetCanvasView()->SetCursor( m_toolcursor );
03681
03682 m_x = event.GetX();
03683 m_y = event.GetY();
03684 MouseToToolWorld( m_x, m_y, m_xwprev, m_ywprev );
03685
03686 a2dRestrictionEngine *restrict = a2dCanvasGlobals->GetRestrictionEngine();
03687 if(restrict)
03688 restrict->RestrictPoint(m_xwprev, m_ywprev);
03689
03690 if (event.LeftDown() && !GetBusy())
03691 {
03692 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
03693 m_radius = 0;
03694 m_original = new a2dCircle( m_xwprev, m_ywprev, m_radius);
03695 m_start_x = m_xwprev;
03696 m_start_y = m_ywprev;
03697 EnterBusyMode();
03698 AddCurrent( m_original );
03699 }
03700 else if (event.LeftDown() && GetBusy())
03701 {
03702 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
03703 a2dDocviewGlobals->RecordF( this, _T("circle %f %f %f"), m_canvasobject->GetPosX(), m_canvasobject->GetPosY(), m_radius );
03704
03705 FinishBusyMode();
03706 }
03707 else if ((event.Dragging()&& GetBusy()) || (event.Moving() && GetBusy()) )
03708 {
03709 SetMode( m_mode );
03710 }
03711 else
03712 event.Skip();
03713 }
03714
03715 A2D_BEGIN_EVENT_TABLE(a2dDrawPolygonLTool,a2dStDrawTool)
03716 A2D_EVT_IDLE( a2dDrawPolygonLTool::OnIdle )
03717 A2D_EVT_CHAR( a2dDrawPolygonLTool::OnChar )
03718 A2D_EVT_MOUSE_EVENTS(a2dDrawPolygonLTool::OnMouseEvent)
03719 A2D_EVT_UNDO( a2dDrawPolygonLTool::OnUndoEvent )
03720 A2D_EVT_REDO( a2dDrawPolygonLTool::OnRedoEvent )
03721 A2D_END_EVENT_TABLE()
03722
03723 void a2dDrawPolygonLTool::AddPoint( a2dLineSegment* point )
03724 {
03725 if ( m_reverse )
03726 m_points->push_front(point);
03727 else
03728 m_points->push_back(point);
03729 }
03730
03731 a2dDrawPolygonLTool::a2dDrawPolygonLTool(a2dStToolContr* controller, a2dPolygonL* templateObject ):a2dStDrawTool(controller)
03732 {
03733 m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_PENCIL );
03734 m_toolBusyCursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_CROSS );
03735 m_contourwidth = a2dGetCmdh()->GetContourWidthInDataBaseUnits();
03736
03737 m_canvasobject = (a2dCanvasObject*)0;
03738 m_points = (a2dVertexList*) 0;
03739
03740 m_reverse = false;
03741
03742 m_templateObject = templateObject;
03743 if ( !m_templateObject )
03744 {
03745 m_templateObject = new a2dPolygonL();
03746 m_templateObject->SetContourWidth( a2dGetCmdh()->GetContourWidthInDataBaseUnits() );
03747 m_contourwidth = a2dGetCmdh()->GetContourWidthInDataBaseUnits();
03748 m_templateObject->SetSpline( a2dGetCmdh()->GetSpline() );
03749 }
03750 else
03751 {
03752 m_layer = m_templateObject->GetLayer();
03753 m_fill = m_templateObject->GetFill();
03754 m_stroke = m_templateObject->GetStroke();
03755 m_contourwidth = m_templateObject->GetContourWidth();
03756 }
03757 }
03758
03759 a2dDrawPolygonLTool::~a2dDrawPolygonLTool()
03760 {
03761 }
03762
03763 void a2dDrawPolygonLTool::SetSpline(bool spline)
03764 {
03765 m_templateObject->SetSpline( spline );
03766 }
03767
03768 void a2dDrawPolygonLTool::OnIdle( wxIdleEvent &event )
03769 {
03770 if (m_pending && GetBusy())
03771 {
03772 RemoveAllDecorations();
03773
03774 a2dPolygonL* poly = wxStaticCast( m_canvasobject.Get(), a2dPolygonL );
03775 a2dRect* around = NULL;
03776 a2dPolygonL* nonSplined = NULL;
03777
03778 switch ( m_mode )
03779 {
03780 case 2:
03781 {
03782
03783 if ( poly->GetSpline() )
03784 {
03785 nonSplined = (a2dPolygonL*) poly->TClone( clone_childs );
03786 nonSplined->SetVisible( true );
03787 nonSplined->SetSpline( false );
03788 nonSplined->SetFill( *a2dTRANSPARENT_FILL );
03789
03790 nonSplined->SetStroke( *wxBLACK, 0, a2dSTROKE_DOT_DASH );
03791 AddDecorationObject( nonSplined );
03792
03793 }
03794 }
03795 case 1:
03796 {
03797 around = new a2dRect( poly->GetBboxMinX(), poly->GetBboxMinY(), poly->GetBboxWidth(), poly->GetBboxHeight() );
03798 around->SetStroke( *wxRED, 0, a2dSTROKE_DOT_DASH );
03799 around->SetFill( *a2dTRANSPARENT_FILL );
03800 around->SetCanvasDocument( GetCanvasView()->GetCanvasDocument() );
03801 AddDecorationObject( around );
03802 break;
03803 }
03804 default:
03805 break;
03806 }
03807
03808 event.Skip();
03809 }
03810 else
03811 event.Skip();
03812 }
03813
03814 void a2dDrawPolygonLTool::OnUndoEvent( a2dCommandProcessorEvent& WXUNUSED(event) )
03815 {
03816 if (GetBusy() && !m_halted)
03817 {
03818
03819
03820 a2dPolygonL* poly = wxStaticCast( m_original.Get(), a2dPolygonL );
03821 if ( poly->GetNumberOfSegments() )
03822 {
03823 a2dLineSegment* lastpoint = poly->GetSegments()->back();
03824
03825 CleanupToolObjects();
03826 GetCanvasView()->Update( a2dCANVIEW_UPDATE_OLDNEW );
03827 CreateToolObjects();
03828 m_points = wxStaticCast( m_canvasobject.Get(), a2dPolygonL )->GetSegments();
03829 m_point = lastpoint->Clone();
03830 m_points->push_back( m_point );
03831 }
03832 }
03833 }
03834
03835 void a2dDrawPolygonLTool::OnRedoEvent( a2dCommandProcessorEvent& event )
03836 {
03837 OnUndoEvent( event );
03838 }
03839
03840 void a2dDrawPolygonLTool::SetMode( int mode )
03841 {
03842 m_mode = mode;
03843 if (m_mode > 2) m_mode = 0;
03844
03845 if (!m_canvasobject)
03846 return;
03847
03848 m_pending = true;
03849 }
03850
03851 void a2dDrawPolygonLTool::OnChar(wxKeyEvent& event)
03852 {
03853 if (GetBusy() && m_canvasobject)
03854 {
03855 double shiftx;
03856 double shifty;
03857 GetKeyIncrement(&shiftx, &shifty, event.AltDown());
03858
03859 switch(event.GetKeyCode())
03860 {
03861 case WXK_TAB:
03862 {
03863 m_mode++;
03864 SetMode( m_mode );
03865 }
03866 break;
03867
03868 case WXK_UP:
03869 shiftx = 0;
03870 break;
03871
03872 case WXK_DOWN:
03873 shiftx = 0;
03874 shifty = -shifty;
03875 break;
03876
03877 case WXK_LEFT:
03878 shiftx = -shiftx;
03879 shifty = 0;
03880 break;
03881
03882 case WXK_RIGHT:
03883 shifty = 0;
03884 break;
03885
03886 default:
03887 {
03888 shiftx = 0;
03889 shifty = 0;
03890 event.Skip();
03891 }
03892 }
03893
03894 if ( event.m_controlDown )
03895 {
03896 m_point->m_x += shiftx;
03897 m_point->m_y += shifty;
03898 }
03899 else
03900 {
03901 double x = m_canvasobject->GetPosX();
03902 double y = m_canvasobject->GetPosY();
03903 m_canvasobject->SetPosXY( x + shiftx, y + shifty, true );
03904 a2dPolygonL* poly = wxStaticCast( m_canvasobject.Get(), a2dPolygonL );
03905 poly->EliminateMatrix();
03906 }
03907
03908 GetDisplayWindow()->WarpPointer( GetDrawer2D()->WorldToDeviceX( m_point->m_x ), GetDrawer2D()->WorldToDeviceY( m_point->m_y ) );
03909
03910 m_pending = true;
03911 }
03912 else
03913 event.Skip();
03914
03915 }
03916
03917 void a2dDrawPolygonLTool::OnMouseEvent(wxMouseEvent& event)
03918 {
03919 if (!m_active)
03920 {
03921 event.Skip();
03922 return;
03923 }
03924
03925 if ( GetBusy() )
03926 GetCanvasView()->SetCursor( m_toolBusyCursor );
03927 else
03928 GetCanvasView()->SetCursor( m_toolcursor );
03929
03930 m_x = event.GetX();
03931 m_y = event.GetY();
03932 MouseToToolWorld( m_x, m_y, m_xwprev, m_ywprev );
03933
03934 a2dRestrictionEngine *restrict = a2dCanvasGlobals->GetRestrictionEngine();
03935 if(restrict)
03936 restrict->RestrictPoint(m_xwprev, m_ywprev);
03937 if (event.LeftDown() && !GetBusy())
03938 {
03939 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
03940 m_original = m_templateObject->TClone( clone_childs | clone_members );
03941 m_original->Translate( m_xwprev, m_ywprev );
03942 m_original->EliminateMatrix();
03943 m_original->SetContourWidth( m_contourwidth );
03944 m_original->SetStroke( m_stroke );
03945 m_original->SetFill( m_fill );
03946 m_original->SetLayer(m_layer);
03947
03948 EnterBusyMode();
03949 AddCurrent( m_original );
03950
03951 m_original->SetCanvasDocument( GetCanvasDocument() );
03952
03953
03954 GetCanvasCommandProcessor()->Submit(
03955 new a2dCommand_AddPoint( m_original, m_xwprev, m_ywprev, -1 )
03956 );
03957
03958 m_points = wxStaticCast( m_canvasobject.Get(), a2dPolygonL )->GetSegments();
03959 m_point = new a2dLineSegment( m_xwprev,m_ywprev);
03960 AddPoint( m_point );
03961
03962
03963 a2dDocviewGlobals->RecordF( this, _T("polygon") );
03964 a2dDocviewGlobals->RecordF( this, _T("addpoint %f %f"), m_xwprev, m_ywprev );
03965
03966
03967 m_point = new a2dLineSegment( m_xwprev,m_ywprev);
03968 AddPoint( m_point );
03969
03970 m_prev_x = m_xwprev;
03971 m_prev_y = m_ywprev;
03972 m_pending = true;
03973 if(restrict)
03974 restrict->SetRestrictPoint( m_xwprev, m_ywprev );
03975 }
03976 else if (event.LeftDown() && GetBusy())
03977 {
03978 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
03979 int x = GetDrawer2D()->WorldToDeviceX(m_prev_x);
03980 int y = GetDrawer2D()->WorldToDeviceY(m_prev_y);
03981 if (abs(m_x-x) >=3 || abs(m_y-y) >= 3)
03982 {
03983 GetCanvasCommandProcessor()->Submit(
03984 new a2dCommand_AddPoint( m_original, m_xwprev, m_ywprev, -1 )
03985 );
03986
03987 a2dDocviewGlobals->RecordF( this, _T("addpoint %f %f "), m_xwprev, m_ywprev );
03988
03989 m_point = new a2dLineSegment( m_xwprev,m_ywprev);
03990 AddPoint( m_point );
03991 m_prev_x = m_xwprev;
03992 m_prev_y = m_ywprev;
03993 }
03994 m_pending = true;
03995 if(restrict)
03996 restrict->SetRestrictPoint( m_xwprev, m_ywprev );
03997 }
03998 else if (event.Moving() && GetBusy())
03999 {
04000 a2dBoundingBox updateareas;
04001
04002
04003 updateareas.Expand( m_prev_x, m_prev_y );
04004 updateareas.Expand( m_point->GetPoint() );
04005
04006 updateareas.Reset();
04007 updateareas.Expand( m_points->front()->GetPoint() );
04008 updateareas.Expand( m_point->GetPoint() );
04009
04010
04011 m_point->m_x = m_xwprev;
04012 m_point->m_y = m_ywprev;
04013 m_canvasobject->SetPending( true );
04014
04015 updateareas.Reset();
04016 updateareas.Expand( m_prev_x, m_prev_y );
04017 updateareas.Expand( m_point->GetPoint() );
04018
04019
04020 updateareas.Reset();
04021 updateareas.Expand( m_points->front()->GetPoint() );
04022 updateareas.Expand( m_point->GetPoint() );
04023
04024
04025 m_pending = true;
04026 event.Skip();
04027 }
04028 else if (event.LeftDClick() && GetBusy())
04029 {
04030 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
04031 a2dDocviewGlobals->RecordF( this, _T("end") );
04032 FinishBusyMode();
04033 }
04034 else
04035 event.Skip();
04036 }
04037
04038 A2D_BEGIN_EVENT_TABLE( a2dDrawPolylineLTool,a2dDrawPolygonLTool )
04039 A2D_EVT_MOUSE_EVENTS( a2dDrawPolylineLTool::OnMouseEvent )
04040 A2D_EVT_DO( a2dDrawPolylineLTool::OnDoEvent )
04041 A2D_END_EVENT_TABLE()
04042
04043 a2dDrawPolylineLTool::a2dDrawPolylineLTool(a2dStToolContr* controller, a2dPolylineL* templateObject ):
04044 a2dDrawPolygonLTool( controller, NULL )
04045 {
04046 m_AllowModifyTemplate = true;
04047 m_templatePline = templateObject;
04048 m_templateObject = templateObject;
04049 if ( !m_templatePline )
04050 {
04051 m_templatePline = new a2dPolylineL();
04052 m_templateObject = (a2dPolygonL*) m_templatePline;
04053 m_templatePline->SetEndScaleX( a2dGetCmdh()->GetEndScaleX() );
04054 m_templatePline->SetEndScaleY( a2dGetCmdh()->GetEndScaleY() );
04055 m_templatePline->SetBegin( a2dGetCmdh()->GetLineBegin() );
04056 m_templatePline->SetEnd( a2dGetCmdh()->GetLineEnd() );
04057 m_templatePline->SetPathType( a2dGetCmdh()->GetPathType() );
04058 m_templatePline->SetContourWidth( a2dGetCmdh()->GetContourWidthInDataBaseUnits() );
04059 m_contourwidth = a2dGetCmdh()->GetContourWidthInDataBaseUnits();
04060 }
04061 else
04062 {
04063 m_layer = m_templatePline->GetLayer();
04064 m_fill = m_templatePline->GetFill();
04065 m_stroke = m_templatePline->GetStroke();
04066 m_contourwidth = m_templatePline->GetContourWidth();
04067 }
04068 }
04069
04070 a2dDrawPolylineLTool::~a2dDrawPolylineLTool()
04071 {
04072 }
04073
04074 void a2dDrawPolylineLTool::SetPathType( a2dPATH_END_TYPE pathtype )
04075 {
04076 if ( GetBusy() )
04077 {
04078 a2dPolylineL* poly = wxStaticCastNull( m_canvasobject.Get(), a2dPolylineL );
04079 poly->SetPathType( pathtype );
04080 a2dPolylineL* polyorg = wxStaticCastNull( m_original.Get(), a2dPolylineL );
04081 polyorg->SetPathType( pathtype );
04082 }
04083
04084 m_templatePline->SetPathType( pathtype );
04085 }
04086
04087 void a2dDrawPolylineLTool::SetLineBegin(a2dCanvasObject* begin)
04088 {
04089 m_templatePline->SetBegin( begin );
04090 }
04091
04092 void a2dDrawPolylineLTool::SetLineEnd(a2dCanvasObject* end)
04093 {
04094 m_templatePline->SetEnd( end );
04095 }
04096
04097 void a2dDrawPolylineLTool::SetEndScaleX(double xs)
04098 {
04099 m_templatePline->SetEndScaleX( xs );
04100 }
04101
04102
04103 void a2dDrawPolylineLTool::SetEndScaleY(double ys)
04104 {
04105 m_templatePline->SetEndScaleY( ys );
04106 }
04107
04108 void a2dDrawPolylineLTool::OnDoEvent( a2dCommandProcessorEvent& event )
04109 {
04110 if ( !m_templateObject )
04111 {
04112 if ( event.GetCommand()->GetCommandId() == &a2dCommand_SetContourWidth::Id )
04113 {
04114 m_contourwidth = a2dGetCmdh()->GetContourWidthInDataBaseUnits();
04115 if ( GetBusy() )
04116 {
04117 m_canvasobject->SetContourWidth( m_contourwidth );
04118 m_original->SetContourWidth( m_contourwidth );
04119 }
04120 }
04121 if ( event.GetCommand()->GetCommandId() == &a2dCommand_SetPathType::Id )
04122 {
04123 a2dPATH_END_TYPE pathtype = a2dGetCmdh()->GetPathType();
04124 if ( GetBusy() )
04125 {
04126 a2dPolylineL* poly = wxStaticCast( m_original.Get(), a2dPolylineL );
04127 poly->SetPathType( pathtype );
04128 poly = wxStaticCast( m_canvasobject.Get(), a2dPolylineL );
04129 poly->SetPathType( pathtype );
04130 }
04131 }
04132 }
04133 }
04134
04135 void a2dDrawPolylineLTool::OnMouseEvent(wxMouseEvent& event)
04136 {
04137 if (!m_active)
04138 {
04139 event.Skip();
04140 return;
04141 }
04142
04143 if ( GetBusy() )
04144 GetCanvasView()->SetCursor( m_toolBusyCursor );
04145 else
04146 GetCanvasView()->SetCursor( m_toolcursor );
04147
04148 m_x = event.GetX();
04149 m_y = event.GetY();
04150 MouseToToolWorld( m_x, m_y, m_xwprev, m_ywprev );
04151
04152 a2dRestrictionEngine *restrict = a2dCanvasGlobals->GetRestrictionEngine();
04153 if(restrict)
04154 {
04155 restrict->SetShiftKeyDown( event.ShiftDown() );
04156 restrict->SetAltKeyDown( event.AltDown() );
04157 restrict->RestrictPoint(m_xwprev, m_ywprev);
04158 }
04159
04160 if (event.LeftDown() && !GetBusy())
04161 {
04162 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
04163 m_original = m_templateObject->TClone( clone_childs | clone_members );
04164 m_original->Translate( m_xwprev, m_ywprev );
04165 m_original->EliminateMatrix();
04166 m_original->SetContourWidth( m_contourwidth );
04167 m_original->SetStroke( m_stroke );
04168 m_original->SetFill( m_fill );
04169 m_original->SetLayer( m_layer );
04170 a2dPolylineL* line = wxStaticCast( m_original.Get(), a2dPolylineL );
04171 if ( line->GetBegin() && line->GetBegin()->GetFlag( a2dCanvasOFlags::normalized ) )
04172 {
04173 line->GetBegin()->SetSpecificFlags( false, a2dCanvasOFlags::normalized );
04174 double norm = GetCanvasDocument()->GetNormalizeScale();
04175 line->GetBegin()->Scale( norm, norm );
04176 }
04177 if ( line->GetEnd() && line->GetEnd()->GetFlag( a2dCanvasOFlags::normalized ) )
04178 {
04179 line->GetEnd()->SetSpecificFlags( false, a2dCanvasOFlags::normalized );
04180 double norm = GetCanvasDocument()->GetNormalizeScale();
04181 line->GetEnd()->Scale( norm, norm );
04182 }
04183
04184 EnterBusyMode();
04185 AddCurrent( m_original );
04186 m_canvasobject->SetContourWidth( m_contourwidth );
04187 a2dPolylineL* poly = wxStaticCast( m_canvasobject.Get(), a2dPolylineL );
04188 m_points = poly->GetSegments();
04189
04190 a2dDocviewGlobals->RecordF( this, _T("polyline") );
04191
04192 m_canvasobject->SetCanvasDocument( GetCanvasDocument() );
04193
04194
04195 if ( m_reverse )
04196 GetCanvasCommandProcessor()->Submit(
04197 new a2dCommand_AddPoint( m_original, m_xwprev, m_ywprev, 0 )
04198 );
04199 else
04200 GetCanvasCommandProcessor()->Submit(
04201 new a2dCommand_AddPoint( m_original, m_xwprev, m_ywprev, -1 )
04202 );
04203
04204 m_point = new a2dLineSegment( m_xwprev,m_ywprev);
04205 AddPoint( m_point );
04206
04207 a2dDocviewGlobals->RecordF( this, _T("addpoint %f %f "), m_xwprev, m_ywprev );
04208
04209
04210 m_point = new a2dLineSegment(m_xwprev,m_ywprev);
04211 AddPoint( m_point );
04212
04213 m_prev_x = m_xwprev;
04214 m_prev_y = m_ywprev;
04215
04216 if(restrict)
04217 restrict->SetRestrictPoint( m_xwprev, m_ywprev );
04218
04219 m_pending = true;
04220 }
04221 else
04222 event.Skip();
04223 }
04224
04225 A2D_BEGIN_EVENT_TABLE( a2dDrawWirePolylineLTool,a2dDrawPolylineLTool )
04226 A2D_EVT_MOUSE_EVENTS( a2dDrawWirePolylineLTool::OnMouseEvent )
04227 A2D_END_EVENT_TABLE()
04228
04229 a2dDrawWirePolylineLTool::a2dDrawWirePolylineLTool(a2dStToolContr* controller )
04230 : a2dDrawPolylineLTool(controller)
04231 {
04232 m_eventHandler = new a2dStToolFixedToolStyleEvtHandler( controller );
04233
04234 m_pinClassStartWire = NULL;
04235 m_pinClassEndWire = NULL;
04236 m_wiringMode = a2d_BasedOnClassStartPin;
04237
04238 m_toolBusyCursor = *wxSTANDARD_CURSOR;
04239
04240 }
04241
04242 a2dDrawWirePolylineLTool::~a2dDrawWirePolylineLTool()
04243 {
04244 }
04245
04246 void a2dDrawWirePolylineLTool::AdjustRenderOptions()
04247 {
04248
04249 m_renderOriginal = false;
04250 m_renderEditcopy = false;
04251 m_renderEditcopyEdit = false;
04252 m_renderEditcopyOnTop = true;
04253 m_renderEditcopyRectangle = false;
04254
04255 m_renderOriginal = true;
04256 m_renderEditcopy = false;
04257 m_renderEditcopyOnTop = false;
04258 m_renderEditcopyEdit = true;
04259 m_renderEditcopyRectangle = false;
04260 }
04261
04262 a2dPin *a2dDrawWirePolylineLTool::FindPin( a2dCanvasObject *root, double x, double y, bool ForStartPin )
04263 {
04264
04265 assert( !m_canvasobject || root->Find( m_canvasobject ) );
04266
04267
04268
04269 a2dAffineMatrix tRootInv = root->GetTransformMatrix();
04270 tRootInv.Invert();
04271 double xh,yh;
04272 tRootInv.TransformPoint(x, y, xh, yh);
04273
04274
04275
04276
04277
04278
04279
04280
04281
04282
04283
04284 for( a2dCanvasObjectList::iterator iter = root->GetChildObjectList()->begin(); iter != root->GetChildObjectList()->end(); ++iter )
04285 {
04286 a2dCanvasObject *obj = *iter;
04287
04288 if( !obj->HasPins() )
04289 continue;
04290 if( obj == m_canvasobject )
04291 continue;
04292 if( obj == m_original )
04293 continue;
04294
04295 a2dIterC ic( GetCanvasView() );
04296 a2dIterCU cu( ic );
04297
04298
04299
04300 for( a2dCanvasObjectList::iterator iterp = obj->GetChildObjectList()->begin(); iterp != obj->GetChildObjectList()->end(); ++iterp )
04301 {
04302 a2dPin* pin = wxDynamicCast( (*iterp).Get(), a2dPin );
04303 if (pin)
04304 {
04305
04306 if( pin->ConnectedTo() || pin->GetRelease( ) )
04307 continue;
04308
04309 a2dIterCU cu( ic, obj );
04310 a2dHitEvent hitevent = a2dHitEvent( xh, yh, false );
04311 if ( pin->IsHitWorld( ic, hitevent ))
04312 {
04313 if ( ForStartPin )
04314 {
04315 switch ( m_wiringMode )
04316 {
04317 case a2d_BasedOnClassStartPin:
04318 if ( m_pinClassStartWire = pin->GetPinClass()->GetPinClassForTask( a2d_ToConnectPinClassWire_ObjectPinClass_InOut, obj ) )
04319 return pin;
04320 break;
04321 case a2d_BasedOnWireClassRequired:
04322 if ( m_pinClassStartWire->CanConnectTo( pin->GetPinClass(), a2dPinClass::PC_input | a2dPinClass::PC_output ) )
04323 return pin;
04324 break;
04325 case a2d_BasedOnObjectClassRequired:
04326 if ( pin->GetPinClass()->CanConnectTo( m_pinClassStartWire, a2dPinClass::PC_input | a2dPinClass::PC_output ) )
04327 return pin;
04328 break;
04329 }
04330 }
04331 else
04332 {
04333 a2dConnectTask task = a2d_ToConnectPinClassWire_ObjectPinClass_InOut;
04334
04335 switch ( m_wiringMode )
04336 {
04337 case a2d_BasedOnClassStartPin:
04338 if ( m_pinClassEndWire->CanConnectTo( pin->GetPinClass(), a2dPinClass::PC_input | a2dPinClass::PC_output ) )
04339 return pin;
04340 break;
04341 case a2d_BasedOnWireClassRequired:
04342 if ( m_pinClassEndWire->GetPinClassForTask( task, obj ) == pin->GetPinClass() )
04343 return pin;
04344 break;
04345 case a2d_BasedOnObjectClassRequired:
04346 if ( m_pinClassEndWire->GetPinClassForTask( task, obj ) == pin->GetPinClass() )
04347 return pin;
04348 break;
04349 }
04350 }
04351 }
04352 }
04353 }
04354 }
04355 return 0;
04356 }
04357
04358 bool a2dDrawWirePolylineLTool::EnterBusyMode()
04359 {
04360 return a2dDrawPolylineLTool::EnterBusyMode();
04361 }
04362
04363 void a2dDrawWirePolylineLTool::FinishBusyMode( bool closeCommandGroup )
04364 {
04365 if( GetCanvasView() )
04366 {
04367 a2dIterC ic( GetCanvasView() );
04368 GetCanvasView()->GetShowObject()->EditFeedback( ic, &a2dPin::sm_feedbackEnd, 0, 2, 0 );
04369 }
04370 a2dDrawPolylineLTool::FinishBusyMode();
04371 }
04372
04373 void a2dDrawWirePolylineLTool::AbortBusyMode()
04374 {
04375 if( GetCanvasView() )
04376 {
04377 a2dIterC ic( GetCanvasView() );
04378 GetCanvasView()->GetShowObject()->EditFeedback( ic, &a2dPin::sm_feedbackEnd, 0, 2, 0 );
04379 }
04380 a2dDrawPolylineLTool::AbortBusyMode();
04381 }
04382
04383 void a2dDrawWirePolylineLTool::OnMouseEvent(wxMouseEvent& event)
04384 {
04385
04386
04387
04388
04389
04390
04391
04392 if (!m_active)
04393 {
04394 event.Skip();
04395 return;
04396 }
04397
04398 if ( GetBusy() )
04399 GetCanvasView()->SetCursor( m_toolBusyCursor );
04400 else
04401 GetCanvasView()->SetCursor( m_toolcursor );
04402
04403 m_x = event.GetX();
04404 m_y = event.GetY();
04405 MouseToToolWorld( m_x, m_y, m_xwprev, m_ywprev );
04406
04407 double unRestx = m_xwprev;
04408 double unResty = m_ywprev;
04409
04410 a2dRestrictionEngine *restrict = a2dCanvasGlobals->GetRestrictionEngine();
04411 if(restrict)
04412 restrict->RestrictPoint(m_xwprev, m_ywprev);
04413
04414 if (event.LeftDown() && !GetBusy())
04415 {
04416 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
04417
04418 a2dPin* pin = FindPin( GetCanvasView()->GetShowObject(), m_xwprev, m_ywprev, true );
04419 if( !pin )
04420 pin = FindPin( GetCanvasView()->GetShowObject(), unRestx, unResty, true );
04421 if( !pin )
04422 {
04423 (void)wxMessageBox(_("A connection must start at a pin or another connection"), _("Connect"), wxICON_INFORMATION | wxOK);
04424 return;
04425 }
04426
04427 if ( pin->IsTemporaryPin() )
04428 {
04429 pin = wxStaticCast( pin->Clone( clone_deep ), a2dPin );
04430 pin->SetTemporaryPin( false );
04431 GetCanvasCommandProcessor()->Submit( new a2dCommand_AddObject( pin->GetParent(), pin), true );
04432 }
04433
04434
04435 m_xwprev = pin->GetAbsX();
04436 m_ywprev = pin->GetAbsY();
04437
04438
04439
04440 OpenCommandGroupNamed( wxT("create connection") );
04441
04442 m_original = pin->GetPinClass()->GetConnectionGenerator()->CreateConnectObject( m_parentobject, pin, NULL, true );
04443 m_reverse = pin->GetPinClass()->GetConnectionGenerator()->GetLastConnectCreationDirection();
04444 wxASSERT_MSG( m_original.Get() != 0, wxT("a connection object could not be created for the pin clicked") );
04445
04446
04447
04448 m_original->EliminateMatrix();
04449
04450 EnterBusyMode();
04451
04452
04453
04454 m_canvasobject->RemovePins( true, false, true );
04455
04456 m_points = wxStaticCast( m_canvasobject.Get(), a2dPolylineL )->GetSegments();
04457 m_point = new a2dLineSegment(m_xwprev,m_ywprev);
04458 AddPoint( m_point );
04459
04460
04461 {
04462 const a2dPin* drawPin;
04463 if ( m_reverse )
04464 {
04465 drawPin = m_original->HasPinNamed( wxT("begin") );
04466 a2dPin tmp(
04467 m_canvasobject, wxT("begin"),
04468 drawPin->GetPinClass(),
04469 m_xwprev, m_ywprev
04470 );
04471 a2dIterC ic( GetCanvasView() );
04472 GetCanvasView()->GetShowObject()->EditFeedback( ic, &a2dPin::sm_feedbackStart, &tmp, 2, 0 );
04473 }
04474 else
04475 {
04476 drawPin = m_original->HasPinNamed( wxT("end") );
04477 a2dPin tmp(
04478 m_canvasobject, wxT("end"),
04479 drawPin->GetPinClass(),
04480 m_xwprev, m_ywprev
04481 );
04482 a2dIterC ic( GetCanvasView() );
04483 GetCanvasView()->GetShowObject()->EditFeedback( ic, &a2dPin::sm_feedbackStart, &tmp, 2, 0 );
04484 }
04485
04486 m_pinClassEndWire = drawPin->GetPinClass();
04487 }
04488
04489
04490 a2dDocviewGlobals->RecordF( this, _T("polylinewire") );
04491 a2dDocviewGlobals->RecordF( this, _T("addpoint %f %f "), m_xwprev, m_ywprev );
04492
04493
04494 m_point = new a2dLineSegment(m_xwprev,m_ywprev);
04495 AddPoint( m_point );
04496
04497 m_prev_x = m_xwprev;
04498 m_prev_y = m_ywprev;
04499
04500 if(restrict)
04501 restrict->SetRestrictPoint( m_xwprev, m_ywprev );
04502
04503 m_pending = true;
04504
04505 }
04506 else if (event.LeftDown() && GetBusy())
04507 {
04508 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
04509 m_original->RemovePins( true, true );
04510
04511 a2dPin
04512 *pin = FindPin( GetCanvasView()->GetShowObject(), m_xwprev, m_ywprev, false );
04513 if( !pin )
04514 pin = FindPin( GetCanvasView()->GetShowObject(), unRestx, unResty, false );
04515
04516 int x = GetDrawer2D()->WorldToDeviceX(m_prev_x);
04517 int y = GetDrawer2D()->WorldToDeviceY(m_prev_y);
04518 if (abs(m_x-x) >=3 || abs(m_y-y)>=3)
04519 {
04520 if( pin && !pin->GetPinClass()->CanConnectTo( m_original->HasPinNamed( m_reverse? wxT("begin"): wxT("end") )->GetPinClass() ) )
04521 {
04522 (void)wxMessageBox(_("You cannot connect to this end pin"), _("Connect"), wxICON_INFORMATION | wxOK);
04523 }
04524 else
04525 {
04526 if ( pin )
04527 {
04528
04529 m_xwprev = pin->GetAbsX();
04530 m_ywprev = pin->GetAbsY();
04531 }
04532
04533
04534 if(restrict)
04535 restrict->SetRestrictPoint( m_xwprev, m_ywprev );
04536
04537
04538 if ( m_reverse )
04539 GetCanvasCommandProcessor()->Submit(
04540 new a2dCommand_AddPoint( m_original, m_xwprev, m_ywprev, 0 )
04541 );
04542 else
04543 GetCanvasCommandProcessor()->Submit(
04544 new a2dCommand_AddPoint( m_original, m_xwprev, m_ywprev, -1 )
04545 );
04546
04547 a2dPin* drawPin;
04548 if ( m_reverse )
04549 drawPin = m_original->HasPinNamed( wxT("begin") );
04550 else
04551 drawPin = m_original->HasPinNamed( wxT("end") );
04552
04553
04554 m_point = new a2dLineSegment(m_xwprev,m_ywprev);
04555 if ( m_reverse )
04556 m_points->push_front(m_point);
04557 else
04558 m_points->push_back(m_point);
04559
04560 m_prev_x = m_xwprev;
04561 m_prev_y = m_ywprev;
04562
04563
04564 a2dDocviewGlobals->RecordF( this, _T("addpoint %f %f "), m_xwprev, m_ywprev );
04565
04566
04567
04568 if( pin )
04569 {
04570 if ( pin->IsTemporaryPin() )
04571 {
04572 pin = wxStaticCast( pin->Clone( clone_deep ), a2dPin );
04573 pin->SetTemporaryPin( false );
04574 GetCanvasCommandProcessor()->Submit( new a2dCommand_AddObject( pin->GetParent(), pin ), true );
04575 }
04576 GetCanvasCommandProcessor()->Submit( new a2dCommand_ConnectPins( drawPin, pin ), true );
04577
04578 a2dDocviewGlobals->RecordF( this, _T("end") );
04579
04580
04581
04582
04583
04584
04585
04586
04587
04588
04589
04590
04591
04592
04593
04594 FinishBusyMode();
04595 }
04596 }
04597 }
04598 }
04599 else if (event.LeftDClick() && GetBusy())
04600 {
04601 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
04602 a2dDocviewGlobals->RecordF( this, _T("end") );
04603 FinishBusyMode();
04604 }
04605 else if (event.Moving() && GetBusy())
04606 {
04607 a2dPin* drawPin;
04608 if ( m_reverse )
04609 drawPin = m_original->HasPinNamed( wxT("begin") );
04610 else
04611 drawPin = m_original->HasPinNamed( wxT("end") );
04612
04613
04614
04615
04616 {
04617
04618 a2dPin tmp(
04619 m_canvasobject, wxT("end"),
04620 drawPin->GetPinClass(),
04621 m_xwprev, m_ywprev
04622 );
04623
04624 a2dIterC ic( GetCanvasView() );
04625 GetCanvasView()->GetShowObject()->EditFeedback( ic, &a2dPin::sm_feedbackGeneratePin, &tmp, 2, 0, m_xwprev, m_ywprev );
04626 }
04627 event.Skip();
04628 }
04629 else if (event.Moving() && !GetBusy())
04630 {
04631
04632
04633 a2dPin::sm_feedbackOnPinmapConnect.SetMode( 2 );
04634 a2dIterC ic( GetCanvasView() );
04635 switch ( m_wiringMode )
04636 {
04637 case a2d_BasedOnClassStartPin:
04638 a2dPin::sm_feedbackOnPinmapConnect.SetTask( a2d_ToConnectPinClassWire_ObjectPinClass_InOut );
04639 a2dPin::sm_feedbackOnPinmapConnect.SetPinClass( a2dPinClass::Any );
04640 break;
04641 case a2d_BasedOnWireClassRequired:
04642 a2dPin::sm_feedbackOnPinmapConnect.SetTask( a2d_ObjectPinClass_ToConnectPinClassWire_InOut );
04643 a2dPin::sm_feedbackOnPinmapConnect.SetPinClass( m_pinClassStartWire );
04644 break;
04645 case a2d_BasedOnObjectClassRequired:
04646 a2dPin::sm_feedbackOnPinmapConnect.SetTask( a2d_ToConnectPinClassWire_ObjectPinClass_InOut );
04647 a2dPin::sm_feedbackOnPinmapConnect.SetPinClass( m_pinClassStartWire );
04648 break;
04649 }
04650 GetCanvasView()->GetShowObject()->EditFeedback( ic, &a2dPin::sm_feedbackOnPinmapConnect, NULL, 2, 0, m_xwprev, m_ywprev );
04651 event.Skip();
04652 }
04653 else
04654 {
04655 event.Skip();
04656 }
04657 }
04658
04659 void a2dDrawWirePolylineLTool::SetActive( bool active )
04660 {
04661
04662 if( !active )
04663 {
04664 if( GetCanvasView() )
04665 {
04666 a2dIterC ic( GetCanvasView() );
04667 GetCanvasView()->GetShowObject()->EditFeedback( ic, &a2dPin::sm_feedbackEnd, 0, 2, 0 );
04668 }
04669 }
04670 a2dDrawPolylineLTool::SetActive( active );
04671 }
04672
04673
04674 A2D_BEGIN_EVENT_TABLE(a2dDrawEllipseTool,a2dStDrawTool)
04675 A2D_EVT_IDLE( a2dDrawEllipseTool::OnIdle )
04676 A2D_EVT_CHAR( a2dDrawEllipseTool::OnChar )
04677 A2D_EVT_MOUSE_EVENTS(a2dDrawEllipseTool::OnMouseEvent)
04678 A2D_END_EVENT_TABLE()
04679
04680 a2dDrawEllipseTool::a2dDrawEllipseTool(a2dStToolContr* controller):a2dStDrawTool(controller)
04681 {
04682 m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_PENCIL );
04683 m_toolBusyCursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_CROSS );
04684 }
04685
04686 void a2dDrawEllipseTool::GenerateAnotation()
04687 {
04688
04689 a2dStDrawTool::AddAnotationToPendingUpdateArea();
04690
04691 a2dEllipse* ellip = wxStaticCast( m_canvasobject.Get(), a2dEllipse );
04692
04693 m_anotation.Printf( _T("w %6.3f h %6.3f"), ellip->GetWidth(), ellip->GetHeight() );
04694
04695 wxCoord w, h, descent, external;
04696 GetTextExtent( m_anotation, &w, &h, &descent, &external );
04697
04698 m_xanotation = m_x + h;
04699 m_yanotation = m_y + h;
04700
04701 a2dStDrawTool::AddAnotationToPendingUpdateArea();
04702 }
04703
04704 void a2dDrawEllipseTool::OnIdle( wxIdleEvent &event )
04705 {
04706 if (m_pending && GetBusy())
04707 {
04708 RemoveAllDecorations();
04709
04710 a2dEllipse* ellip = wxStaticCast( m_canvasobject.Get(), a2dEllipse );
04711 a2dSLine* ll = new a2dSLine( ellip->GetPosX(), ellip->GetPosY(), m_xwprev, m_ywprev );
04712 ll->SetStroke( *wxRED, 0, a2dSTROKE_DOT );
04713
04714 a2dCircle* zero = new a2dCircle( m_start_x, m_start_y, GetDrawer2D()->DeviceToWorldXRel( 3 ) );
04715 zero->SetFill( *wxRED );
04716
04717 a2dRect* around = new a2dRect( ellip->GetBboxMinX(), ellip->GetBboxMinY(), ellip->GetBboxWidth(), ellip->GetBboxHeight() );
04718 around->SetStroke( *wxRED, 0, a2dSTROKE_LONG_DASH );
04719 around->SetFill( *a2dTRANSPARENT_FILL );
04720
04721 AddDecorationObject( around );
04722 AddDecorationObject( ll );
04723 AddDecorationObject( zero );
04724
04725 event.Skip();
04726 }
04727 else
04728 event.Skip();
04729 }
04730
04731 void a2dDrawEllipseTool::SetMode( int mode )
04732 {
04733 m_mode = mode;
04734 if (m_mode > 1) m_mode = 0;
04735
04736 if (!m_canvasobject)
04737 return;
04738
04739 a2dEllipse* ellip = wxStaticCast( m_canvasobject.Get(), a2dEllipse );
04740 a2dEllipse* elliporg = wxStaticCast( m_original.Get(), a2dEllipse );
04741
04742 switch ( m_mode )
04743 {
04744 case 0:
04745 {
04746 ellip->SetPosXY( m_start_x, m_start_y );
04747 elliporg->SetPosXY( m_start_x, m_start_y );
04748
04749
04750 double xs,ys;
04751 xs = m_xwprev - ellip->GetPosX();
04752 ys = m_ywprev - ellip->GetPosY();
04753
04754 ellip->SetWidth(fabs(xs*2));
04755 ellip->SetHeight(fabs(ys*2));
04756 elliporg->SetWidth(fabs(xs*2));
04757 elliporg->SetHeight(fabs(ys*2));
04758 break;
04759 }
04760 case 1:
04761 {
04762 ellip->SetPosXY( (m_xwprev+m_start_x)/2, (m_ywprev+m_start_y)/2 );
04763 elliporg->SetPosXY( (m_xwprev+m_start_x)/2, (m_ywprev+m_start_y)/2 );
04764
04765
04766 double xs,ys;
04767 xs = m_xwprev - ellip->GetPosX();
04768 ys = m_ywprev - ellip->GetPosY();
04769
04770 ellip->SetWidth(fabs(xs*2));
04771 ellip->SetHeight(fabs(ys*2));
04772 elliporg->SetWidth(fabs(xs*2));
04773 elliporg->SetHeight(fabs(ys*2));
04774 break;
04775 }
04776 default:
04777 break;
04778 }
04779 m_pending = true;
04780 }
04781
04782 void a2dDrawEllipseTool::OnChar(wxKeyEvent& event)
04783 {
04784 if (GetBusy())
04785 {
04786 switch(event.GetKeyCode())
04787 {
04788 case WXK_TAB:
04789 {
04790 m_mode++;
04791 SetMode( m_mode );
04792 }
04793 break;
04794
04795 default:
04796 event.Skip();
04797 }
04798 }
04799 else
04800 event.Skip();
04801
04802 }
04803
04804 void a2dDrawEllipseTool::OnMouseEvent(wxMouseEvent& event)
04805 {
04806 if (!m_active)
04807 {
04808 event.Skip();
04809 return;
04810 }
04811
04812 if ( GetBusy() )
04813 GetCanvasView()->SetCursor( m_toolBusyCursor );
04814 else
04815 GetCanvasView()->SetCursor( m_toolcursor );
04816
04817 m_x = event.GetX();
04818 m_y = event.GetY();
04819 MouseToToolWorld( m_x, m_y, m_xwprev, m_ywprev );
04820
04821 a2dRestrictionEngine *restrict = a2dCanvasGlobals->GetRestrictionEngine();
04822 if(restrict)
04823 restrict->RestrictPoint(m_xwprev, m_ywprev);
04824
04825 if (event.LeftDown() && !GetBusy())
04826 {
04827 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
04828 m_original = new a2dEllipse( m_xwprev, m_ywprev, 0, 0 );
04829 m_start_x = m_xwprev;
04830 m_start_y = m_ywprev;
04831 a2dEllipse* ellip = wxStaticCast( m_original.Get(), a2dEllipse );
04832 ellip->SetCanvasDocument(GetCanvasView()->GetCanvasDocument());
04833 EnterBusyMode();
04834 AddCurrent( m_original );
04835 }
04836 else if (event.LeftDown() && GetBusy())
04837 {
04838 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
04839 a2dEllipse* ellip = wxStaticCast( m_canvasobject.Get(), a2dEllipse );
04840 a2dDocviewGlobals->RecordF( this, _T("ellipse %f %f %f %f"), ellip->GetPosX(), ellip->GetPosY(), ellip->GetWidth(), ellip->GetHeight() );
04841 FinishBusyMode();
04842 }
04843 else if ((event.Dragging()&& GetBusy()) || (event.Moving() && GetBusy()) )
04844 {
04845 SetMode( m_mode );
04846 }
04847 else
04848 event.Skip();
04849 }
04850
04851 A2D_BEGIN_EVENT_TABLE(a2dDrawEllipticArcTool,a2dStDrawTool)
04852 A2D_EVT_IDLE( a2dDrawEllipticArcTool::OnIdle )
04853 A2D_EVT_CHAR( a2dDrawEllipticArcTool::OnChar )
04854 A2D_EVT_MOUSE_EVENTS(a2dDrawEllipticArcTool::OnMouseEvent)
04855 A2D_END_EVENT_TABLE()
04856
04857 a2dDrawEllipticArcTool::a2dDrawEllipticArcTool(a2dStToolContr* controller, a2dEllipticArc* templateobject):a2dStDrawTool(controller)
04858 {
04859 m_mode2 = 0;
04860 m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_PENCIL );
04861 m_toolBusyCursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_CROSS );
04862 m_arcstart = 45;
04863 m_arcend = 315;
04864 m_chord = false;
04865
04866 m_templateobject = templateobject;
04867 }
04868
04869 void a2dDrawEllipticArcTool::GenerateAnotation()
04870 {
04871
04872 a2dStDrawTool::AddAnotationToPendingUpdateArea();
04873
04874 a2dEllipticArc* ellip = wxStaticCast( m_canvasobject.Get(), a2dEllipticArc );
04875
04876 m_anotation.Printf( _T("w %6.3f h %6.3f"), ellip->GetWidth(), ellip->GetHeight() );
04877
04878 wxCoord w, h, descent, external;
04879 GetTextExtent( m_anotation, &w, &h, &descent, &external );
04880
04881 m_xanotation = m_x + h;
04882 m_yanotation = m_y + h;
04883
04884 a2dStDrawTool::AddAnotationToPendingUpdateArea();
04885 }
04886
04887 void a2dDrawEllipticArcTool::OnIdle( wxIdleEvent &event )
04888 {
04889 if (m_pending && GetBusy())
04890 {
04891 RemoveAllDecorations();
04892
04893 a2dEllipticArc* ellip = wxStaticCast( m_canvasobject.Get(), a2dEllipticArc );
04894 a2dSLine* ll = new a2dSLine( ellip->GetPosX(), ellip->GetPosY(), m_xwprev, m_ywprev );
04895 ll->SetStroke( *wxRED, 0, a2dSTROKE_DOT );
04896
04897 a2dCircle* zero = new a2dCircle( m_start_x, m_start_y, GetDrawer2D()->DeviceToWorldXRel( 3 ) );
04898 zero->SetFill( *wxRED );
04899
04900 a2dRect* around = new a2dRect( ellip->GetBboxMinX(), ellip->GetBboxMinY(), ellip->GetBboxWidth(), ellip->GetBboxHeight() );
04901 around->SetStroke( *wxRED, 0, a2dSTROKE_LONG_DASH );
04902 around->SetFill( *a2dTRANSPARENT_FILL );
04903
04904 AddDecorationObject( ll );
04905 AddDecorationObject( around );
04906 AddDecorationObject( zero );
04907
04908 event.Skip();
04909 }
04910 else
04911 event.Skip();
04912 }
04913
04914 void a2dDrawEllipticArcTool::SetMode( int mode )
04915 {
04916 m_mode = mode;
04917 if (m_mode > 1) m_mode = 0;
04918
04919 if (!m_canvasobject)
04920 return;
04921
04922 a2dEllipticArc* ellip = wxStaticCast( m_canvasobject.Get(), a2dEllipticArc );
04923 a2dEllipticArc* elliporg = wxStaticCast( m_original.Get(), a2dEllipticArc );
04924
04925 switch ( m_mode )
04926 {
04927 case 0:
04928 {
04929 ellip->SetPosXY( m_start_x, m_start_y );
04930 elliporg->SetPosXY( m_start_x, m_start_y );
04931
04932
04933 double xs,ys;
04934 xs = m_xwprev - ellip->GetPosX();
04935 ys = m_ywprev - ellip->GetPosY();
04936
04937 ellip->SetWidth(fabs(xs*2));
04938 ellip->SetHeight(fabs(ys*2));
04939 elliporg->SetWidth(fabs(xs*2));
04940 elliporg->SetHeight(fabs(ys*2));
04941 break;
04942 }
04943 case 1:
04944 {
04945 ellip->SetPosXY( (m_xwprev+m_start_x)/2, (m_ywprev+m_start_y)/2 );
04946 elliporg->SetPosXY( (m_xwprev+m_start_x)/2, (m_ywprev+m_start_y)/2 );
04947
04948
04949 double xs,ys;
04950 xs = m_xwprev - ellip->GetPosX();
04951 ys = m_ywprev - ellip->GetPosY();
04952
04953 ellip->SetWidth(fabs(xs*2));
04954 ellip->SetHeight(fabs(ys*2));
04955 elliporg->SetWidth(fabs(xs*2));
04956 elliporg->SetHeight(fabs(ys*2));
04957 break;
04958 }
04959 default:
04960 break;
04961 }
04962 m_pending = true;
04963 }
04964
04965 void a2dDrawEllipticArcTool::SetMode2( int mode )
04966 {
04967 m_mode2 = mode;
04968 if (m_mode2 > 2) m_mode2 = 0;
04969
04970 if (!m_canvasobject)
04971 return;
04972
04973 m_pending = true;
04974 }
04975
04976 void a2dDrawEllipticArcTool::OnChar(wxKeyEvent& event)
04977 {
04978 if (GetBusy())
04979 {
04980 switch(event.GetKeyCode())
04981 {
04982 case WXK_SPACE:
04983 {
04984 a2dEllipticArc* ellip = wxStaticCast( m_canvasobject.Get(), a2dEllipticArc );
04985 a2dDocviewGlobals->RecordF( this, _T("ellipticArc %f %f% f %f %f %f"),
04986 ellip->GetPosX(), ellip->GetPosY(),
04987 ellip->GetWidth(), ellip->GetHeight(),
04988 ellip->GetStart(), ellip->GetEnd()
04989 );
04990 FinishBusyMode();
04991 }
04992 break;
04993 case WXK_TAB:
04994 {
04995 m_mode++;
04996 SetMode( m_mode );
04997 }
04998 break;
04999
05000 case WXK_RETURN:
05001 {
05002 m_mode2++;
05003 SetMode2( m_mode2 );
05004 }
05005 break;
05006
05007 default:
05008 event.Skip();
05009 }
05010 }
05011 else
05012 event.Skip();
05013
05014 }
05015
05016
05017 void a2dDrawEllipticArcTool::OnMouseEvent(wxMouseEvent& event)
05018 {
05019 if (!m_active)
05020 {
05021 event.Skip();
05022 return;
05023 }
05024
05025 if ( GetBusy() )
05026 GetCanvasView()->SetCursor( m_toolBusyCursor );
05027 else
05028 GetCanvasView()->SetCursor( m_toolcursor );
05029
05030 m_x = event.GetX();
05031 m_y = event.GetY();
05032 MouseToToolWorld( m_x, m_y, m_xwprev, m_ywprev );
05033
05034 a2dRestrictionEngine *restrict = a2dCanvasGlobals->GetRestrictionEngine();
05035 if(restrict)
05036 restrict->RestrictPoint(m_xwprev, m_ywprev);
05037
05038 if (event.LeftDown() && !GetBusy())
05039 {
05040 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
05041 a2dEllipticArc* ellip = 0;
05042 if ( m_templateobject )
05043 {
05044 m_original = m_templateobject->TClone( clone_childs );
05045 ellip = wxStaticCast( m_original.Get(), a2dEllipticArc );
05046 ellip->SetStart( m_arcstart );
05047 ellip->SetEnd( m_arcend );
05048 m_original->Translate( m_xwprev, m_ywprev );
05049 m_original->EliminateMatrix();
05050 }
05051 else
05052 {
05053 m_original = new a2dEllipticArc( m_xwprev, m_ywprev, 0, 0, m_arcstart, m_arcend );
05054 ellip = wxStaticCast( m_original.Get(), a2dEllipticArc );
05055 ellip->SetChord(m_chord);
05056 }
05057 EnterBusyMode();
05058 AddCurrent( m_original );
05059 m_start_x = m_xwprev;
05060 m_start_y = m_ywprev;
05061 }
05062 else if (event.LeftDown() && GetBusy())
05063 {
05064 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
05065 m_mode2 = 0;
05066
05067 a2dEllipticArc* ellip = wxStaticCast( m_canvasobject.Get(), a2dEllipticArc );
05068 a2dDocviewGlobals->RecordF( this, _T("ellipticArc %f %f %f %f %f %f"),
05069 ellip->GetPosX(), ellip->GetPosY(),
05070 ellip->GetWidth(), ellip->GetHeight(),
05071 ellip->GetStart(), ellip->GetEnd()
05072 );
05073 FinishBusyMode();
05074 }
05075 else if ((event.Dragging()&& GetBusy()) || (event.Moving() && GetBusy()) )
05076 {
05077 a2dEllipticArc* ellip = wxStaticCast( m_canvasobject.Get(), a2dEllipticArc );
05078 a2dEllipticArc* elliporg = wxStaticCast( m_original.Get(), a2dEllipticArc );
05079
05080 double xs,ys;
05081 xs = m_xwprev - ellip->GetPosX();
05082 ys = m_ywprev - ellip->GetPosY();
05083
05084 if ( m_mode2 == 1 )
05085 {
05086 m_arcstart = wxRadToDeg( atan2( ys, xs ) );
05087 ellip->SetStart(m_arcstart);
05088 elliporg->SetStart(m_arcstart);
05089 }
05090 else if ( m_mode2 == 2 )
05091 {
05092 m_arcend = wxRadToDeg( atan2( ys, xs ) );
05093 ellip->SetEnd(m_arcend);
05094 elliporg->SetEnd(m_arcend);
05095 }
05096 else
05097 {
05098 SetMode( m_mode );
05099 }
05100 m_pending = true;
05101 }
05102 else
05103 event.Skip();
05104 }
05105
05106 A2D_BEGIN_EVENT_TABLE(a2dDrawArcTool,a2dStDrawTool)
05107 A2D_EVT_IDLE( a2dDrawArcTool::OnIdle )
05108 A2D_EVT_CHAR(a2dDrawArcTool::OnChar)
05109 A2D_EVT_MOUSE_EVENTS(a2dDrawArcTool::OnMouseEvent)
05110 A2D_END_EVENT_TABLE()
05111
05112 a2dDrawArcTool::a2dDrawArcTool(a2dStToolContr* controller):a2dStDrawTool(controller)
05113 {
05114 m_mode2 = 0;
05115 m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_PENCIL );
05116 m_toolBusyCursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_CROSS );
05117 m_arcstart = 45;
05118 m_arcend = 315;
05119 m_chord = false;
05120 }
05121
05122 void a2dDrawArcTool::GenerateAnotation()
05123 {
05124
05125 a2dStDrawTool::AddAnotationToPendingUpdateArea();
05126
05127 a2dArc* arc = wxStaticCast( m_canvasobject.Get(), a2dArc );
05128
05129 m_anotation.Printf( _T("radius %6.3f"), arc->GetRadius() );
05130
05131 wxCoord w, h, descent, external;
05132 GetTextExtent( m_anotation, &w, &h, &descent, &external );
05133
05134 m_xanotation = m_x + h;
05135 m_yanotation = m_y + h;
05136
05137 a2dStDrawTool::AddAnotationToPendingUpdateArea();
05138 }
05139
05140 void a2dDrawArcTool::OnIdle( wxIdleEvent &event )
05141 {
05142 if (m_pending && GetBusy())
05143 {
05144 RemoveAllDecorations();
05145
05146 a2dArc* cir = wxStaticCast( m_canvasobject.Get(), a2dArc );
05147 a2dSLine* ll = new a2dSLine( cir->GetPosX(), cir->GetPosY(), m_xwprev, m_ywprev );
05148 ll->SetStroke( *wxRED, 0, a2dSTROKE_DOT );
05149
05150 a2dCircle* zero = new a2dCircle( m_start_x, m_start_y, GetDrawer2D()->DeviceToWorldXRel( 3 ) );
05151 zero->SetFill( *wxRED );
05152
05153 a2dRect* around = new a2dRect( cir->GetBboxMinX(), cir->GetBboxMinY(), cir->GetBboxWidth(), cir->GetBboxHeight() );
05154 around->SetStroke( *wxRED, 0, a2dSTROKE_LONG_DASH );
05155 around->SetFill( *a2dTRANSPARENT_FILL );
05156
05157 AddDecorationObject( ll );
05158 AddDecorationObject( around );
05159 AddDecorationObject( zero );
05160
05161 event.Skip();
05162 }
05163 else
05164 event.Skip();
05165 }
05166
05167 void a2dDrawArcTool::OnChar(wxKeyEvent& event)
05168 {
05169 if (GetBusy())
05170 {
05171 switch(event.GetKeyCode())
05172 {
05173 case WXK_SPACE:
05174 {
05175 a2dArc* arc = wxStaticCast( m_canvasobject.Get(), a2dArc );
05176 a2dDocviewGlobals->RecordF( this, _T("arc %f %f %f %f %f"),
05177 arc->GetPosX(), arc->GetPosY(),
05178 arc->GetRadius(),
05179 m_arcstart, m_arcend );
05180 FinishBusyMode();
05181 }
05182 break;
05183 case WXK_TAB:
05184 {
05185 m_mode++;
05186 SetMode( m_mode );
05187 }
05188 break;
05189
05190 case WXK_RETURN:
05191 {
05192 m_mode2++;
05193 SetMode2( m_mode2 );
05194 }
05195 break;
05196
05197 default:
05198 event.Skip();
05199 }
05200 }
05201 else
05202 event.Skip();
05203
05204 }
05205
05206 void a2dDrawArcTool::SetMode( int mode )
05207 {
05208 m_mode = mode;
05209 if (m_mode > 2) m_mode = 0;
05210
05211 if (!m_canvasobject)
05212 return;
05213
05214 a2dArc* cir = wxStaticCast( m_canvasobject.Get(), a2dArc );
05215 a2dArc* cirorg = wxStaticCast( m_original.Get(), a2dArc );
05216 double radius = 0;
05217 switch ( m_mode )
05218 {
05219 case 0:
05220 {
05221 double dx, dy;
05222
05223 if ( fabs( m_xwprev - m_start_x ) > fabs( m_ywprev - m_start_y ) )
05224 {
05225 dx = ( m_xwprev - m_start_x ) /2 ;
05226 radius = fabs( dx );
05227 if ( m_ywprev > m_start_y )
05228 dy = radius;
05229 else
05230 dy = -radius;
05231 }
05232 else
05233 {
05234 dy = ( m_ywprev - m_start_y ) /2 ;
05235 radius = fabs( dy );
05236 if ( m_xwprev > m_start_x )
05237 dx = radius;
05238 else
05239 dx = -radius;
05240 }
05241 cir->SetPosXY( m_start_x + dx , m_start_y + dy );
05242 cirorg->SetPosXY( m_start_x + dx , m_start_y + dy );
05243 break;
05244 }
05245 case 1:
05246 {
05247 cir->SetPosXY( m_start_x, m_start_y );
05248 cirorg->SetPosXY( m_start_x, m_start_y );
05249 radius=sqrt(pow(m_xwprev-cir->GetPosX(),2)+pow(m_ywprev-cir->GetPosY(),2));
05250 break;
05251 }
05252 case 2:
05253 {
05254 cir->SetPosXY( (m_xwprev+m_start_x)/2, (m_ywprev+m_start_y)/2 );
05255 cirorg->SetPosXY( (m_xwprev+m_start_x)/2, (m_ywprev+m_start_y)/2 );
05256 radius=sqrt(pow(m_xwprev-m_start_x,2)+pow(m_ywprev-m_start_y,2))/2;
05257 break;
05258 }
05259 default:
05260 break;
05261 }
05262
05263 cir->SetRadius(radius);
05264 cirorg->SetRadius(radius);
05265 m_pending = true;
05266 }
05267
05268
05269 void a2dDrawArcTool::SetMode2( int mode )
05270
05271 {
05272 m_mode2 = mode;
05273 if (m_mode2 > 2) m_mode2 = 0;
05274
05275 if (!m_canvasobject)
05276 return;
05277
05278 m_pending = true;
05279 }
05280
05281
05282 void a2dDrawArcTool::OnMouseEvent(wxMouseEvent& event)
05283 {
05284 if (!m_active)
05285 {
05286 event.Skip();
05287 return;
05288 }
05289
05290 if ( GetBusy() )
05291 GetCanvasView()->SetCursor( m_toolBusyCursor );
05292 else
05293 GetCanvasView()->SetCursor( m_toolcursor );
05294
05295 m_x = event.GetX();
05296 m_y = event.GetY();
05297 MouseToToolWorld( m_x, m_y, m_xwprev, m_ywprev );
05298
05299 a2dRestrictionEngine *restrict = a2dCanvasGlobals->GetRestrictionEngine();
05300 if(restrict)
05301 restrict->RestrictPoint(m_xwprev, m_ywprev);
05302
05303 if (event.LeftDown() && !GetBusy())
05304 {
05305 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
05306 double radius = 0.00001;
05307 m_original = new a2dArc( m_xwprev, m_ywprev, radius, m_arcstart, m_arcend );
05308 a2dArc* arc = wxStaticCast( m_original.Get(), a2dArc );
05309 m_start_x = m_xwprev;
05310 m_start_y = m_ywprev;
05311 arc->SetChord(m_chord);
05312 EnterBusyMode();
05313 AddCurrent( m_original );
05314 }
05315 else if (event.LeftDown() && GetBusy())
05316 {
05317 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
05318 m_mode2 = 0;
05319 a2dArc* arc = wxStaticCast( m_canvasobject.Get(), a2dArc );
05320 a2dDocviewGlobals->RecordF( this, _T("arc %f %f %f %f %f"),
05321 arc->GetPosX(), arc->GetPosY(),
05322 arc->GetRadius(),
05323 m_arcstart, m_arcend );
05324 FinishBusyMode();
05325 }
05326 else if ((event.Dragging()&& GetBusy()) || (event.Moving() && GetBusy()) )
05327 {
05328 a2dArc* arc = wxStaticCast( m_canvasobject.Get(), a2dArc );
05329 a2dArc* arcorg = wxStaticCast( m_original.Get(), a2dArc );
05330
05331 double xs,ys;
05332 xs = m_xwprev - arc->GetPosX();
05333 ys = m_ywprev - arc->GetPosY();
05334
05335 if ( m_mode2 == 1 )
05336 {
05337 double radius = arc->GetRadius();
05338
05339 m_arcstart = wxRadToDeg( atan2( ys, xs ) );
05340
05341
05342 arc->SetX1( cos( atan2( ys, xs ) ) * radius );
05343 arc->SetY1( sin( atan2( ys, xs ) ) * radius );
05344 arcorg->SetX1( cos( atan2( ys, xs ) ) * radius );
05345 arcorg->SetY1( sin( atan2( ys, xs ) ) * radius );
05346 }
05347 else if ( m_mode2 == 2 )
05348 {
05349
05350 arc->SetX2( xs );
05351 arc->SetY2( ys );
05352 arcorg->SetX2( xs );
05353 arcorg->SetY2( ys );
05354 m_arcend = wxRadToDeg( atan2( ys, xs ) );
05355 }
05356 else
05357 {
05358 SetMode( m_mode );
05359 }
05360 m_pending = true;
05361 }
05362 else
05363 event.Skip();
05364 }
05365
05366
05367 A2D_BEGIN_EVENT_TABLE(a2dDrawLineTool,a2dStDrawTool)
05368 A2D_EVT_CHAR(a2dDrawLineTool::OnChar)
05369 A2D_EVT_MOUSE_EVENTS(a2dDrawLineTool::OnMouseEvent)
05370 A2D_EVT_DO( a2dDrawLineTool::OnDoEvent )
05371 A2D_END_EVENT_TABLE()
05372
05373 a2dDrawLineTool::a2dDrawLineTool(a2dStToolContr* controller, a2dSLine* templateObject ):a2dStDrawTool(controller)
05374 {
05375 m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_PENCIL );
05376 m_toolBusyCursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_CROSS );
05377
05378 m_AllowModifyTemplate = true;
05379 m_templateObject = templateObject;
05380 if ( !m_templateObject )
05381 {
05382 m_templateObject = new a2dEndsLine();
05383 m_templateObject->SetEndScaleX( a2dGetCmdh()->GetEndScaleX() );
05384 m_templateObject->SetEndScaleY( a2dGetCmdh()->GetEndScaleY() );
05385 m_templateObject->SetBegin( a2dGetCmdh()->GetLineBegin() );
05386 m_templateObject->SetEnd( a2dGetCmdh()->GetLineEnd() );
05387 m_templateObject->SetPathType( a2dGetCmdh()->GetPathType() );
05388 m_templateObject->SetContourWidth( a2dGetCmdh()->GetContourWidthInDataBaseUnits() );
05389 m_contourwidth = a2dGetCmdh()->GetContourWidthInDataBaseUnits();
05390 }
05391 else
05392 {
05393 m_layer = m_templateObject->GetLayer();
05394 m_fill = m_templateObject->GetFill();
05395 m_stroke = m_templateObject->GetStroke();
05396 m_contourwidth = m_templateObject->GetContourWidth();
05397 }
05398 }
05399
05400 a2dDrawLineTool::~a2dDrawLineTool()
05401 {
05402 }
05403
05404 void a2dDrawLineTool::SetLineBegin(a2dCanvasObject* begin)
05405 {
05406 m_templateObject->SetBegin( begin );
05407 }
05408
05409 void a2dDrawLineTool::SetLineEnd(a2dCanvasObject* end)
05410
05411 {
05412 m_templateObject->SetEnd( end );
05413 }
05414
05415 void a2dDrawLineTool::SetEndScaleX(double xs)
05416 {
05417 m_templateObject->SetEndScaleX( xs );
05418 }
05419
05420
05421 void a2dDrawLineTool::SetEndScaleY(double ys)
05422 {
05423 m_templateObject->SetEndScaleY( ys );
05424 }
05425
05426 void a2dDrawLineTool::SetPathType( a2dPATH_END_TYPE pathtype )
05427 {
05428 if ( GetBusy() )
05429 {
05430 a2dSLine* line = wxStaticCast( m_original.Get(), a2dSLine );
05431 line->SetPathType( pathtype );
05432 line = wxStaticCast( m_canvasobject.Get(), a2dSLine );
05433 line->SetPathType( pathtype );
05434 }
05435
05436 m_templateObject->SetPathType( pathtype );
05437 }
05438
05439
05440 void a2dDrawLineTool::OnDoEvent( a2dCommandProcessorEvent& event )
05441 {
05442 }
05443
05444 void a2dDrawLineTool::GenerateAnotation()
05445 {
05446
05447 a2dStDrawTool::AddAnotationToPendingUpdateArea();
05448
05449 a2dSLine* line = wxStaticCast( m_canvasobject.Get(), a2dSLine );
05450
05451 m_anotation.Printf( _T("x %6.3f y %6.3f l %6.3f"), m_x2, m_y2, line->GetLength() );
05452
05453 wxCoord w, h, d, l;
05454 GetTextExtent( m_anotation, &w, &h, &d, &l );
05455 m_xanotation = GetDrawer2D()->WorldToDeviceX( m_x2 ) + (int) h;
05456 m_yanotation = GetDrawer2D()->WorldToDeviceY( m_y2 ) - (int) h;
05457
05458 a2dStDrawTool::AddAnotationToPendingUpdateArea();
05459 }
05460
05461 void a2dDrawLineTool::OnChar(wxKeyEvent& event)
05462 {
05463 if (GetBusy())
05464 {
05465 if ( event.GetKeyCode() == WXK_SPACE )
05466 {
05467 a2dDocviewGlobals->RecordF( this, _T("line %f %f %f %f"), m_x1, m_y1, m_x2, m_y2 );
05468
05469 FinishBusyMode();
05470 return;
05471 }
05472
05473 double shiftx;
05474 double shifty;
05475 GetKeyIncrement(&shiftx, &shifty, event.AltDown());
05476
05477
05478 switch(event.GetKeyCode())
05479 {
05480 case WXK_UP:
05481 shiftx = 0;
05482 break;
05483
05484 case WXK_DOWN:
05485 shiftx = 0;
05486 shifty = -shifty;
05487 break;
05488
05489 case WXK_LEFT:
05490 shiftx = -shiftx;
05491 shifty = 0;
05492 break;
05493
05494 case WXK_RIGHT:
05495 shifty = 0;
05496 break;
05497 default:
05498 {
05499 shiftx = 0;
05500 shifty = 0;
05501 event.Skip();
05502 }
05503 }
05504
05505 a2dSLine* line = wxStaticCast( m_canvasobject.Get(), a2dSLine );
05506 if ( event.m_controlDown )
05507 {
05508 m_x2 += shiftx;
05509 m_y2 += shifty;
05510 line->EliminateMatrix();
05511 line->SetPosXY12( m_x1, m_y1, m_x2, m_y2);
05512 }
05513 else
05514 {
05515 m_x1 += shiftx;
05516 m_y1 += shifty;
05517 m_x2 += shiftx;
05518 m_y2 += shifty;
05519 line->EliminateMatrix();
05520 line->SetPosXY12( m_x1, m_y1, m_x2, m_y2);
05521 }
05522
05523 GetDisplayWindow()->WarpPointer( GetDrawer2D()->WorldToDeviceX( m_x2 ), GetDrawer2D()->WorldToDeviceY( m_y2 ) );
05524
05525 m_pending = true;
05526 }
05527 else
05528 event.Skip();
05529
05530 }
05531
05532 void a2dDrawLineTool::OnMouseEvent(wxMouseEvent& event)
05533 {
05534 if (!m_active)
05535 {
05536 event.Skip();
05537 return;
05538 }
05539
05540 if ( GetBusy() )
05541 GetCanvasView()->SetCursor( m_toolBusyCursor );
05542 else
05543 GetCanvasView()->SetCursor( m_toolcursor );
05544
05545 m_x = event.GetX();
05546 m_y = event.GetY();
05547 MouseToToolWorld( m_x, m_y, m_xwprev, m_ywprev );
05548
05549 a2dRestrictionEngine *restrict = a2dCanvasGlobals->GetRestrictionEngine();
05550 if(restrict)
05551 restrict->RestrictPoint(m_xwprev, m_ywprev);
05552
05553 if (event.LeftDown() && !GetBusy())
05554 {
05555 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
05556 m_x2 = m_x1 = m_xwprev;
05557 m_y2 = m_y1 = m_ywprev;
05558
05559 m_original = m_templateObject->TClone( clone_childs | clone_members );
05560 m_original->Translate( m_xwprev, m_ywprev );
05561 m_original->EliminateMatrix();
05562 m_original->SetContourWidth( m_contourwidth );
05563 m_original->SetStroke( m_stroke );
05564 m_original->SetFill( m_fill );
05565 m_original->SetLayer( m_layer );
05566
05567 a2dSLine* line = wxStaticCast( m_original.Get(), a2dSLine );
05568 if ( line->GetBegin() && line->GetBegin()->GetFlag( a2dCanvasOFlags::normalized ) )
05569 {
05570 line->GetBegin()->SetSpecificFlags( false, a2dCanvasOFlags::normalized );
05571 double norm = GetCanvasDocument()->GetNormalizeScale();
05572 line->GetBegin()->Scale( norm, norm );
05573 }
05574 if ( line->GetEnd() && line->GetEnd()->GetFlag( a2dCanvasOFlags::normalized ) )
05575 {
05576 line->GetEnd()->SetSpecificFlags( false, a2dCanvasOFlags::normalized );
05577 double norm = GetCanvasDocument()->GetNormalizeScale();
05578 line->GetEnd()->Scale( norm, norm );
05579 }
05580
05581 EnterBusyMode();
05582 AddCurrent( m_original );
05583 }
05584 else if (event.LeftDown() && GetBusy())
05585 {
05586 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
05587
05588
05589 a2dDocviewGlobals->RecordF( this, _T("line %f %f %f %f"), m_x1, m_y1, m_x2, m_y2 );
05590
05591 FinishBusyMode();
05592 }
05593 else if ((event.Dragging()&& GetBusy()) || (event.Moving() && GetBusy()) )
05594 {
05595 a2dSLine* line = wxStaticCast( m_canvasobject.Get(), a2dSLine );
05596 a2dSLine* lineorg = wxStaticCast( m_original.Get(), a2dSLine );
05597
05598 m_x2 = m_xwprev;
05599 m_y2 = m_ywprev;
05600
05601 line->SetPosXY12( m_x1, m_y1, m_x2, m_y2);
05602 lineorg->SetPosXY12( m_x1, m_y1, m_x2, m_y2);
05603
05604 m_pending = true;
05605 }
05606 else
05607 event.Skip();
05608
05609 }
05610
05611 A2D_BEGIN_EVENT_TABLE(a2dRotateTool,a2dStTool)
05612 A2D_EVT_CHAR(a2dRotateTool::OnChar)
05613 A2D_EVT_MOUSE_EVENTS(a2dRotateTool::OnMouseEvent)
05614 A2D_EVT_IDLE( a2dRotateTool::OnIdle )
05615 A2D_EVT_KEY_DOWN( a2dRotateTool::OnKeyDown)
05616 A2D_END_EVENT_TABLE()
05617
05618 a2dRotateTool::a2dRotateTool(a2dStToolContr* controller):a2dStTool(controller)
05619 {
05620 m_eventHandler = new a2dStToolFixedToolStyleEvtHandler( controller );
05621
05622 m_canvasobject=0;
05623 m_mode = false;
05624 }
05625
05626 a2dRotateTool::~a2dRotateTool()
05627 {
05628 }
05629
05630 bool a2dRotateTool::EnterBusyMode()
05631 {
05632 if(!a2dStTool::EnterBusyMode())
05633 return false;
05634 CaptureMouse();
05635 return true;
05636 }
05637
05638 void a2dRotateTool::FinishBusyMode( bool closeCommandGroup )
05639 {
05640 ReleaseMouse();
05641 a2dStTool::FinishBusyMode();
05642 }
05643
05644 void a2dRotateTool::AbortBusyMode()
05645 {
05646 ReleaseMouse();
05647 a2dStTool::AbortBusyMode();
05648 }
05649
05650 void a2dRotateTool::OnChar(wxKeyEvent& event)
05651 {
05652 if (GetBusy() && m_canvasobject)
05653 {
05654 a2dRestrictionEngine *restrict = a2dCanvasGlobals->GetRestrictionEngine();
05655
05656 double dx = m_xwprev - m_xr;
05657 double dy = m_ywprev - m_yr;
05658 double ang;
05659 if (!dx && !dy)
05660 ang=0;
05661 else
05662 ang= atan2(dy,dx);
05663
05664 double shiftx;
05665 double shifty;
05666 double xw;
05667 double yw;
05668
05669 GetKeyIncrement(&shiftx, &shifty, event.AltDown());
05670
05671 switch(event.GetKeyCode())
05672 {
05673 case WXK_UP:
05674 {
05675 yw = m_yr + shifty;
05676 }
05677 break;
05678
05679 case WXK_DOWN:
05680 {
05681 yw = m_yr - shifty;
05682 }
05683 break;
05684
05685 case WXK_LEFT:
05686 {
05687 xw = m_xr - shiftx;
05688 }
05689 break;
05690
05691 case WXK_RIGHT:
05692 {
05693 xw = m_xr + shiftx;
05694 }
05695 break;
05696 case WXK_SPACE:
05697 {
05698 m_canvasobject->SetVisible( true );
05699 GetCanvasCommandProcessor()->Submit(
05700 new a2dCommand_SetCanvasProperty( m_canvasobject, a2dCanvasObject::PROPID_TransformMatrix, m_transform )
05701 );
05702 FinishBusyMode();
05703 }
05704 break;
05705 default:
05706 event.Skip();
05707 }
05708
05709 if(restrict)
05710 restrict->RestrictPoint(xw, yw, a2dRestrictionEngine::snapToPointAngle );
05711
05712 dx = xw - m_xr;
05713 dy = yw - m_yr;
05714
05715 double angn;
05716 if (!dx && !dy)
05717 angn=0;
05718 else
05719 angn= atan2(dy,dx);
05720
05721 m_ang = wxRadToDeg( angn );
05722 angn = angn - ang;
05723 if (angn<=0) angn += 2.0*wxPI;
05724 if (ang<0) ang += 2.0*wxPI;
05725 angn = angn + ang;
05726 ang = angn - ang;
05727
05728 a2dAffineMatrix rotate;
05729 rotate.Translate(-m_xr,-m_yr);
05730 rotate.Rotate(wxRadToDeg(-ang));
05731 rotate.Translate(m_xr,m_yr);
05732
05733 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_CROSS ) );
05734
05735 m_canvasobject->Transform(rotate);
05736
05737 m_pending = true;
05738
05739 m_xwprev = xw;
05740 m_ywprev = yw;
05741
05742 m_pending = true;
05743
05744
05745 }
05746 else
05747 event.Skip();
05748
05749
05750 }
05751
05752 void a2dRotateTool::OnIdle( wxIdleEvent &event )
05753 {
05754 if (m_pending && GetBusy())
05755 {
05756 RemoveAllDecorations();
05757
05758 a2dSLine* ll = new a2dSLine( m_xr,m_yr, m_xwprev, m_ywprev );
05759 ll->SetStroke( *wxRED, 0);
05760 ll->SetCanvasDocument( GetCanvasView()->GetCanvasDocument() );
05761
05762 m_anotation.Printf( _T("angle %6.3f"), m_ang );
05763 m_xanotation = GetDrawer2D()->WorldToDeviceX(m_xwprev);
05764 m_yanotation = GetDrawer2D()->WorldToDeviceY(m_ywprev);
05765
05766 AddDecorationObject( ll );
05767
05768 event.Skip();
05769 }
05770 else
05771 event.Skip();
05772 }
05773
05774 void a2dRotateTool::OnMouseEvent(wxMouseEvent& event)
05775 {
05776 if (!m_active)
05777 {
05778 event.Skip();
05779 return;
05780 }
05781
05782 static int px, py;
05783
05784 m_x = event.GetX();
05785 m_y = event.GetY();
05786
05787
05788 double xw,yw;
05789 MouseToToolWorld( m_x, m_y, xw, yw );
05790
05791 a2dRestrictionEngine *restrict = a2dCanvasGlobals->GetRestrictionEngine();
05792
05793 if ( event.Moving() && !GetBusy() )
05794 {
05795 if ( GetCanvasView()->IsHitWorld( xw, yw ) )
05796 GetCanvasView()->SetCursor( m_toolcursor );
05797 else
05798 GetCanvasView()->SetCursor( m_toolBusyCursor );
05799
05800 }
05801
05802 if (event.LeftDown() && !GetBusy())
05803 {
05804 if(restrict)
05805 restrict->RestrictPoint(m_xwprev, m_ywprev);
05806 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
05807
05808 m_canvasobject = GetCanvasView()->IsHitWorld( xw, yw, wxLAYER_ALL, a2dCANOBJHITOPTION_LAYERS );
05809
05810 if (!m_canvasobject)
05811 {
05812 m_canvasobject = 0;
05813 return;
05814 }
05815 if (!m_canvasobject->GetDraggable() )
05816 {
05817 m_canvasobject = 0;
05818 return;
05819 }
05820
05821 EnterBusyMode();
05822
05823 m_transform = m_canvasobject->GetTransformMatrix();
05824
05825 if ( event.m_shiftDown )
05826 m_mode = true;
05827 else
05828 m_mode = false;
05829
05830 if ( m_mode )
05831 {
05832 m_xr = m_canvasobject->GetPosX();
05833 m_yr = m_canvasobject->GetPosY();
05834 }
05835 else
05836 {
05837 m_xr = xw;
05838 m_yr = yw;
05839 }
05840
05841 m_xwprev = xw;
05842 m_ywprev = yw;
05843
05844 if(restrict)
05845 restrict->SetRestrictPoint( m_xr, m_yr );
05846 }
05847 else if (event.LeftUp() && GetBusy())
05848 {
05849 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
05850 GetCanvasView()->SetCursor(*wxSTANDARD_CURSOR);
05851
05852 a2dAffineMatrix newtransform = m_canvasobject->GetTransformMatrix();
05853 m_canvasobject->SetTransformMatrix( m_transform );
05854
05855 GetCanvasCommandProcessor()->Submit(
05856 new a2dCommand_SetCanvasProperty( m_canvasobject, a2dCanvasObject::PROPID_TransformMatrix, newtransform )
05857 );
05858
05859 FinishBusyMode();
05860 }
05861 else if ((event.Dragging()&& GetBusy()) || (event.Moving() && GetBusy()) )
05862 {
05863 if ( px != m_x || py != m_y )
05864 {
05865 double dx, dy;
05866
05867
05868 a2dAffineMatrix rotate;
05869
05870 if(restrict)
05871 restrict->RestrictPoint(xw, yw, a2dRestrictionEngine::snapToPointAngle );
05872
05873 dx = m_xwprev-m_xr;
05874 dy = m_ywprev-m_yr;
05875
05876 double ang;
05877 if (!dx && !dy)
05878 ang=0;
05879 else
05880 ang= atan2(dy,dx);
05881
05882 dx = xw - m_xr;
05883 dy = yw - m_yr;
05884 double angn;
05885 if (!dx && !dy)
05886 angn=0;
05887 else
05888 angn= atan2(dy,dx);
05889
05890 m_ang = wxRadToDeg( angn );
05891
05892 angn=angn-ang;
05893 if (angn<=0) angn += 2.0*wxPI;
05894
05895 if (ang<0) ang += 2.0*wxPI;
05896
05897 angn = angn + ang;
05898
05899 ang = angn - ang;
05900
05901 rotate.Translate(-m_xr,-m_yr);
05902 rotate.Rotate(wxRadToDeg(-ang));
05903 rotate.Translate(m_xr,m_yr);
05904
05905 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_CROSS ) );
05906
05907 m_canvasobject->Transform(rotate);
05908
05909 m_pending = true;
05910
05911 m_xwprev = xw;
05912 m_ywprev = yw;
05913 px = m_x;
05914 py = m_y;
05915 }
05916 }
05917 else
05918 {
05919 event.Skip();
05920 }
05921 }
05922
05923 void a2dRotateTool::CaptureMouse()
05924 {
05925 GetCanvasView()->SetCaptured( m_canvasobject );
05926 GetCanvasView()->GetDisplayWindow()->CaptureMouse();
05927 }
05928
05929 void a2dRotateTool::ReleaseMouse()
05930 {
05931 GetCanvasView()->SetCaptured( NULL );
05932 GetCanvasView()->GetDisplayWindow()->ReleaseMouse();
05933 }
05934
05935
05936 a2dPropertyIdFont* a2dDrawTextTool::PROPID_Font = NULL;
05937
05938 A2D_BEGIN_EVENT_TABLE(a2dDrawTextTool,a2dStDrawTool)
05939 A2D_EVT_MOUSE_EVENTS(a2dDrawTextTool::OnMouseEvent)
05940 A2D_END_EVENT_TABLE()
05941
05942 INITIALIZE_PROPERTIES( a2dDrawTextTool, a2dStDrawTool )
05943 {
05944 PROPID_Font = new a2dPropertyIdFont( wxT("Font"),
05945 a2dPropertyId::flag_transfer|a2dPropertyId::flag_clonedeep,
05946 *a2dNullFONT,
05947 static_cast < a2dPropertyIdFont::ConstGet >(&a2dDrawTextTool::MX_GetFont),
05948 static_cast < a2dPropertyIdFont::ConstSet >(&a2dDrawTextTool::MX_SetFont) );
05949 AddPropertyId( PROPID_Font );
05950 return true;
05951 }
05952
05953 a2dDrawTextTool::a2dDrawTextTool(a2dStToolContr* controller):a2dStDrawTool(controller)
05954 {
05955 m_useEditOpaque = a2dOpaqueMode_Off;
05956 m_toolcursor=a2dCanvasGlobals->GetCursor( a2dCURSOR_PENCIL );
05957 m_canvasobject=0;
05958 m_linespace = 100/10;
05959 m_font = a2dFont( 100.0, wxDECORATIVE, wxITALIC );
05960 m_caret = 0;
05961 m_up = false;
05962 if ( GetCanvasView() && GetCanvasView()->GetDrawer2D() )
05963 m_up = !GetCanvasView()->GetDrawer2D()->GetYaxis();
05964 }
05965
05966 a2dDrawTextTool::~a2dDrawTextTool()
05967 {
05968 }
05969
05970 void a2dDrawTextTool::OnMouseEvent(wxMouseEvent& event)
05971 {
05972 if (!m_active)
05973 {
05974 event.Skip();
05975 return;
05976 }
05977
05978 if ( GetBusy() )
05979 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_IBEAM ) );
05980 else
05981 GetCanvasView()->SetCursor( m_toolcursor );
05982
05983 m_x = event.GetX();
05984 m_y = event.GetY();
05985
05986
05987 MouseToToolWorld( m_x, m_y, m_xwprev, m_ywprev );
05988
05989 if (event.LeftDown() && !GetBusy())
05990 {
05991 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
05992 m_original = new a2dText( _T(""), m_xwprev, m_ywprev, m_font, 0, m_up );
05993 a2dText* textobject = wxStaticCast( m_original.Get(), a2dText );
05994 m_caret = 0;
05995 textobject->SetCaret( m_caret );
05996 textobject->SetCaretShow( false );
05997 textobject->SetLineSpacing( m_linespace );
05998 textobject->SetFont( m_font );
05999 textobject->SetNextLineDirection( m_up );
06000
06001 textobject->SetFill( m_fill );
06002 textobject->SetStroke( m_stroke );
06003
06004 a2dBaseTool::EnterBusyMode();
06005 bool backupstartedit = m_editatend;
06006 m_editatend = true;
06007 AddCurrent( m_original );
06008 a2dObjectEditTool* edittool = StartEditTool( textobject );
06009 edittool->SetUseOpaqueEditcopy( a2dOpaqueMode_Off );
06010
06011 if( m_oneshot )
06012 StopTool();
06013 m_editatend = backupstartedit;
06014 }
06015 else
06016 event.Skip();
06017 }
06018
06019 A2D_BEGIN_EVENT_TABLE(a2dDragMultiTool,a2dStTool)
06020 A2D_EVT_CHAR(a2dDragMultiTool::OnChar)
06021 A2D_EVT_MOUSE_EVENTS(a2dDragMultiTool::OnMouseEvent)
06022 A2D_END_EVENT_TABLE()
06023
06024 a2dDragMultiTool::a2dDragMultiTool(a2dStToolContr* controller):a2dStTool(controller)
06025 {
06026 m_eventHandler = new a2dStToolFixedToolStyleEvtHandler( controller );
06027
06028 }
06029
06030 a2dDragMultiTool::~a2dDragMultiTool()
06031 {
06032 }
06033
06034 void a2dDragMultiTool::OnChar(wxKeyEvent& event)
06035 {
06036 if (GetBusy())
06037 {
06038 switch(event.GetKeyCode())
06039 {
06040 case WXK_SPACE:
06041 {
06042 }
06043 break;
06044 default:
06045 event.Skip();
06046 }
06047 }
06048 else
06049 event.Skip();
06050
06051 }
06052
06053 void a2dDragMultiTool::OnMouseEvent(wxMouseEvent& event)
06054 {
06055 if (!m_active)
06056 {
06057 event.Skip();
06058 return;
06059 }
06060
06061 m_x = event.GetX();
06062 m_y = event.GetY();
06063 MouseToToolWorld( m_x, m_y, m_xwprev, m_ywprev );
06064
06065 a2dRestrictionEngine *restrict = a2dCanvasGlobals->GetRestrictionEngine();
06066 if(restrict)
06067 {
06068 restrict->SetShiftKeyDown( event.ShiftDown() );
06069 restrict->SetAltKeyDown( event.AltDown() );
06070 }
06071
06072 if (event.LeftDown())
06073 {
06074 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
06075
06076 m_original = GetCanvasView()->IsHitWorld( m_xwprev, m_ywprev, wxLAYER_ALL, a2dCANOBJHITOPTION_LAYERS, true );
06077
06078 if (!m_original || !m_original->IsSelected() || !m_original->GetDraggable() )
06079 {
06080 m_original=0;
06081 return;
06082 }
06083
06084
06085 GetCanvasView()->GetShowObject()->CollectObjects( &m_objects,_T(""),a2dCanvasOFlags::SELECTED );
06086 EnterBusyMode();
06087
06088 m_startMousexw = m_xwprev;
06089 m_startMouseyw = m_ywprev;
06090 m_startObjectx = m_original->GetPosX();
06091 m_startObjecty = m_original->GetPosY();
06092
06093 if(restrict)
06094 restrict->SetRestrictPoint( m_startObjectx, m_startObjecty );
06095 }
06096 else if (event.LeftUp() && GetBusy() )
06097 {
06098 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
06099 FinishBusyMode();
06100
06101
06102
06103
06104 }
06105 else if ( GetBusy() )
06106 {
06107 double dxm = m_xwprev-m_startMousexw;
06108 double dym = m_ywprev-m_startMouseyw;
06109 AdjustShift( &dxm, &dym );
06110
06111
06112 DragAbsolute( dxm+m_startObjectx, dym+m_startObjecty );
06113 }
06114 else
06115 {
06116 event.Skip();
06117 }
06118 }
06119
06120 bool a2dDragMultiTool::EnterBusyMode()
06121 {
06122 if(!a2dStTool::EnterBusyMode())
06123 return false;
06124 CaptureMouse();
06125 return true;
06126 }
06127
06128 void a2dDragMultiTool::FinishBusyMode( bool closeCommandGroup )
06129 {
06130 ReleaseMouse();
06131 for( a2dCanvasObjectList::iterator iter = m_objects.begin(); iter != m_objects.end(); ++iter )
06132 {
06133 a2dCanvasObject *copy = *iter;
06134 a2dCanvasObject *original = a2dCanvasObject::PROPID_Original->GetPropertyValue( copy );
06135
06136 GetCanvasCommandProcessor()->Submit(
06137 new a2dCommand_SetCanvasProperty( original, a2dCanvasObject::PROPID_TransformMatrix, copy->GetTransformMatrix() )
06138 );
06139 }
06140
06141 m_connectedwirecopies.UpdateImmediate( true, this );
06142
06143 m_objects.clear();
06144
06145 a2dStTool::FinishBusyMode();
06146 }
06147
06148 void a2dDragMultiTool::AbortBusyMode()
06149 {
06150 ReleaseMouse();
06151 a2dStTool::AbortBusyMode();
06152 }
06153
06154 void a2dDragMultiTool::CaptureMouse()
06155 {
06156 wxASSERT( m_canvasobject );
06157 GetCanvasView()->SetCaptured( m_canvasobject );
06158 GetCanvasView()->GetDisplayWindow()->CaptureMouse();
06159 }
06160
06161 void a2dDragMultiTool::ReleaseMouse()
06162 {
06163 GetCanvasView()->SetCaptured( NULL );
06164 GetCanvasView()->GetDisplayWindow()->ReleaseMouse();
06165 }
06166
06167 void a2dDragMultiTool::DragAbsolute( double x, double y )
06168 {
06169 a2dPoint2D oldpos = m_canvasobject->GetPosXY();
06170
06171 a2dRestrictionEngine *restrict = a2dCanvasGlobals->GetRestrictionEngine();
06172 if(restrict)
06173 {
06174
06175 m_canvasobject->SetPosXY( x, y );
06176
06177 a2dPoint2D point;
06178 double dx, dy;
06179
06180 if ( restrict->GetShiftKeyDown() )
06181 {
06182 restrict->RestrictPoint( x, y );
06183 }
06184 else
06185 {
06186
06187 wxUint32 snapTo =
06188 a2dRestrictionEngine::snapToBoundingBox |
06189 a2dRestrictionEngine::snapToObjectPos |
06190 a2dRestrictionEngine::snapToPinsUnconnected |
06191 a2dRestrictionEngine::snapToObjectVertexes |
06192 a2dRestrictionEngine::snapToObjectSnapVPath;
06193 if ( restrict->RestrictCanvasObjectAtVertexes( m_canvasobject, point, dx, dy, snapTo ) )
06194 {
06195
06196 x += dx;
06197 y += dy;
06198 }
06199 }
06200 }
06201
06202
06203 m_canvasobject->SetPosXY(x,y);
06204
06205 if( oldpos != m_canvasobject->GetPosXY() )
06206 {
06207 double dx = x - oldpos.m_x;
06208 double dy = y - oldpos.m_y;
06209 for( a2dCanvasObjectList::iterator iter = m_objects.begin(); iter != m_objects.end(); ++iter )
06210 {
06211 a2dCanvasObject *obj = *iter;
06212 if( obj != m_canvasobject )
06213 obj->Translate( dx, dy );
06214 }
06215
06216 a2dIterC ic( GetCanvasView() );
06217 GetCanvasView()->GetShowObject()->EditFeedback( ic, &a2dPin::sm_feedbackCanConnect, 0, 2, 0 );
06218
06219 m_connectedwirecopies.UpdateImmediate( false, this, m_canvasobject );
06220
06221 m_pending = true;
06222 }
06223 }
06224
06225 void a2dDragMultiTool::Render()
06226 {
06227 if ( m_canvasobject && GetBusy())
06228 {
06229 a2dStTool::Render();
06230 }
06231 }
06232
06233 void a2dDragMultiTool::AdjustShift( double *WXUNUSED(dx), double *WXUNUSED(dy) )
06234 {
06235 }
06236
06237 bool a2dDragMultiTool::CreateToolObjects()
06238 {
06239 a2dCanvasObjectList originals;
06240 a2dCanvasObjectList copies;
06241
06242 m_objects.AssertUnique();
06243
06244 a2dCanvasObjectList::iterator iter;
06245
06246 for( iter = m_objects.begin(); iter != m_objects.end(); ++iter )
06247 {
06248 a2dCanvasObjectPtr original = *iter;
06249 a2dCanvasObject *copy = original->TClone( clone_members | clone_childs | clone_seteditcopy | clone_setoriginal | clone_reconnectable );
06250 *iter = copy;
06251
06252 originals.push_back( original );
06253 if( copy->IsConnect() )
06254 m_connectedwirecopies.push_back( copy );
06255 else
06256 copies.push_back( copy );
06257 copy->SetSelected( false );
06258
06259 if( original == m_original )
06260 m_canvasobject = copy;
06261 }
06262
06263 int n = originals.size();
06264 int i;
06265
06266
06267 for( iter = originals.begin(), i=0 ; iter != originals.end() && i<n; ++iter, i++ )
06268 {
06269 (*iter)->CreateWireEditCopies( &originals, &m_connectedwirecopies );
06270 }
06271
06272
06273 copies.RestoreConnectionsAfterCloning();
06274 m_connectedwirecopies.RestoreConnectionsAfterCloning();
06275
06276
06277 originals.SetSpecificFlags( m_renderOriginal, a2dCanvasOFlags::VISIBLE );
06278
06279
06280 for( iter = copies.begin(); iter != copies.end(); ++iter )
06281 AddEditobject( (*iter) );
06282 for( iter = m_connectedwirecopies.begin(); iter != m_connectedwirecopies.end(); ++iter )
06283 AddEditobject( (*iter) );
06284
06285 m_pending = true;
06286
06287 return true;
06288 }
06289
06290 void a2dDragMultiTool::CleanupToolObjects()
06291 {
06292 a2dStTool::CleanupToolObjects();
06293 m_connectedwirecopies.clear();
06294 }
06295
06296 A2D_BEGIN_EVENT_TABLE(a2dCopyMultiTool,a2dDragMultiTool)
06297 A2D_EVT_CHAR(a2dCopyMultiTool::OnChar)
06298 A2D_EVT_MOUSE_EVENTS(a2dCopyMultiTool::OnMouseEvent)
06299 A2D_END_EVENT_TABLE()
06300
06301 a2dCopyMultiTool::a2dCopyMultiTool(a2dStToolContr* controller):a2dDragMultiTool(controller)
06302 {
06303 m_mindist = a2dCanvasGlobals->GetCopyMinDistance();
06304 }
06305
06306 void a2dCopyMultiTool::OnChar(wxKeyEvent& event)
06307 {
06308 if (GetBusy())
06309 {
06310 switch(event.GetKeyCode())
06311 {
06312 case WXK_SPACE:
06313 {
06314 }
06315 break;
06316 default:
06317 event.Skip();
06318 }
06319 }
06320 else
06321 event.Skip();
06322
06323 }
06324
06325 void a2dCopyMultiTool::OnMouseEvent(wxMouseEvent& event)
06326 {
06327 if (!m_active)
06328 {
06329 event.Skip();
06330 return;
06331 }
06332
06333 int x = event.GetX();
06334 int y = event.GetY();
06335
06336
06337 MouseToToolWorld( x, y, m_xwprev, m_ywprev );
06338
06339 a2dRestrictionEngine *restrict = a2dCanvasGlobals->GetRestrictionEngine();
06340 if(restrict)
06341 {
06342 restrict->SetShiftKeyDown( event.ShiftDown() );
06343 restrict->SetAltKeyDown( event.AltDown() );
06344 }
06345
06346 if (event.LeftDown())
06347 {
06348 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
06349
06350 m_original = GetCanvasView()->IsHitWorld( m_xwprev, m_ywprev, wxLAYER_ALL, a2dCANOBJHITOPTION_LAYERS, true );
06351
06352 if (!m_original || !m_original->IsSelected() || !m_original->GetDraggable() )
06353 {
06354 m_original=0;
06355 return;
06356 }
06357
06358
06359
06360 OpenCommandGroup( false );
06361
06362
06363
06364
06365 {
06366 #ifdef _DEBUG
06367 bool originalfound = false;
06368 #endif
06369 a2dCanvasObjectList::iterator iter;
06370 for( iter = m_parentobject->GetChildObjectList()->begin(); iter != m_parentobject->GetChildObjectList()->end(); ++iter )
06371 {
06372 a2dCanvasObject *obj = *iter;
06373 if( obj->GetSelected() )
06374 {
06375 a2dCanvasObject *objn=obj->TClone( clone_members | clone_childs | clone_seteditcopy | clone_setoriginal | clone_reconnectable );
06376
06377 m_objects.push_back( objn );
06378
06379 GetCanvasCommandProcessor()->Submit( new a2dCommand_SetFlag( obj, a2dCanvasOFlags::SELECTED, false ), true );
06380
06381 if( obj == m_original )
06382 {
06383 m_original = objn;
06384 #ifdef _DEBUG
06385 originalfound = true;
06386 #endif
06387 }
06388 }
06389 }
06390
06391 #ifdef _DEBUG
06392 wxASSERT( originalfound );
06393 #endif
06394
06395 for( iter = m_objects.begin(); iter != m_objects.end(); ++iter )
06396 {
06397 (*iter)->SetSelected( true );
06398
06399 GetCanvasCommandProcessor()->Submit( new a2dCommand_AddObject( m_parentobject, (*iter) ), true );
06400 }
06401
06402
06403 m_objects.RestoreConnectionsAfterCloning( GetCanvasCommandProcessor() );
06404 }
06405
06406 EnterBusyMode();
06407
06408 m_startMousexw = m_xwprev;
06409 m_startMouseyw = m_ywprev;
06410 m_startObjectx = m_original->GetPosX();
06411 m_startObjecty = m_original->GetPosY();
06412
06413 if(restrict)
06414 restrict->SetRestrictPoint( m_startObjectx, m_startObjecty );
06415
06416
06417 {
06418 double dxm = m_xwprev-m_startMousexw;
06419 double dym = m_ywprev-m_startMouseyw;
06420 AdjustShift( &dxm, &dym );
06421
06422
06423 DragAbsolute( dxm+m_startObjectx, dym+m_startObjecty );
06424 }
06425 }
06426 else if (event.LeftUp() && GetBusy() )
06427 {
06428 a2dDragMultiTool::OnMouseEvent( event );
06429 }
06430 else if ( GetBusy() )
06431 {
06432 a2dDragMultiTool::OnMouseEvent( event );
06433 }
06434 else
06435 {
06436 event.Skip();
06437 }
06438 }
06439
06440 void a2dCopyMultiTool::AdjustShift( double *dx, double *dy )
06441 {
06442 if( (*dx)*(*dx)+(*dy)*(*dy)<m_mindist )
06443 {
06444 if( (*dx) == 0 && (*dy) == 0 )
06445 {
06446 (*dx) = m_mindist * 1.0;
06447 (*dy) = m_mindist * 0.5;
06448 }
06449 else
06450 {
06451 double fac = m_mindist / sqrt((*dx)*(*dx)+(*dy)*(*dy));
06452 (*dx)*=fac;
06453 (*dy)*=fac;
06454 }
06455 }
06456 }
06457
06458 A2D_BEGIN_EVENT_TABLE(a2dPropertyTool,a2dStTool)
06459 A2D_EVT_CHAR(a2dPropertyTool::OnChar)
06460 A2D_EVT_MOUSE_EVENTS(a2dPropertyTool::OnMouseEvent)
06461 A2D_END_EVENT_TABLE()
06462
06463 a2dPropertyTool::a2dPropertyTool(a2dStToolContr* controller):a2dStTool(controller)
06464 {
06465 m_eventHandler = new a2dStToolFixedToolStyleEvtHandler( controller );
06466
06467 m_id = 0;
06468 m_withUndo = true;
06469
06470 m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_BULLSEYE );
06471 m_canvasobject=0;
06472 }
06473
06474 void a2dPropertyTool::OnChar(wxKeyEvent& event)
06475 {
06476 if (GetBusy())
06477 {
06478 switch(event.GetKeyCode())
06479 {
06480 case WXK_SPACE:
06481 {
06482 FinishBusyMode();
06483 }
06484 break;
06485 default:
06486 event.Skip();
06487 }
06488 }
06489 else
06490 event.Skip();
06491
06492 }
06493
06494 void a2dPropertyTool::OnMouseEvent(wxMouseEvent& event)
06495 {
06496 if (!m_active)
06497 {
06498 event.Skip();
06499 return;
06500 }
06501 GetCanvasView()->SetCursor(m_toolcursor);
06502
06503 int x = event.GetX();
06504 int y = event.GetY();
06505
06506
06507 double xw,yw;
06508 MouseToToolWorld( x, y, xw, yw );
06509
06510 if (event.LeftDown())
06511 {
06512 m_canvasobject = GetCanvasView()->IsHitWorld( xw, yw, wxLAYER_ALL, a2dCANOBJHITOPTION_LAYERS );
06513
06514 if (!m_canvasobject)
06515 {
06516 m_canvasobject=0;
06517 event.Skip();
06518 return;
06519 }
06520
06521 if ( !((a2dCentralEditorCommandProcessor*)a2dGetCmdh())->IsShownPropEditDlg() )
06522 {
06523 a2dCommand_ShowDlg* command = new a2dCommand_ShowDlg( a2dCentralEditorCommandProcessor::COMID_ShowDlgPropEdit );
06524 a2dGetCmdh()->Submit( command );
06525 }
06526
06527 a2dIterC ic( GetCanvasView() );
06528 OpenCommandGroup( false );
06529 m_canvasobject->EditProperties( m_id, m_withUndo );
06530
06531
06532
06533
06534
06535
06536
06537
06538
06539 m_canvasobject->SetPending(true);
06540 CloseCommandGroup();
06541 m_canvasobject=0;
06542 if (m_oneshot)
06543 StopTool();
06544 }
06545 else
06546 event.Skip();
06547
06548 }
06549
06550 bool a2dPropertyTool::StartEditing( double x, double y )
06551 {
06552 int mouse_x = GetDrawer2D()->WorldToDeviceX( x );
06553 int mouse_y = GetDrawer2D()->WorldToDeviceY( y );
06554
06555 return StartEditing( mouse_x, mouse_y );
06556 }
06557
06558 bool a2dPropertyTool::StartEditing( int x, int y )
06559 {
06560 wxMouseEvent event(wxEVT_LEFT_DOWN);
06561 event.m_x = x;
06562 event.m_y = y;
06563
06564 OnMouseEvent( event );
06565
06566 return true;
06567 }
06568
06569
06570
06571
06572
06573
06574 A2D_BEGIN_EVENT_TABLE(a2dStToolEvtHandler, a2dToolEvtHandler )
06575 A2D_EVT_KEY_DOWN( a2dStToolEvtHandler::OnKeyDown)
06576 A2D_EVT_KEY_UP( a2dStToolEvtHandler::OnKeyUp)
06577 A2D_EVT_COM_EVENT( a2dStToolEvtHandler::OnComEvent )
06578 A2D_EVT_DO( a2dStToolEvtHandler::OnDoEvent )
06579 A2D_EVT_UNDO( a2dStToolEvtHandler::OnUndoEvent )
06580 A2D_EVT_REDO( a2dStToolEvtHandler::OnRedoEvent )
06581 A2D_EVT_IDLE( a2dStToolEvtHandler::OnIdle )
06582 A2D_END_EVENT_TABLE()
06583
06584 a2dStToolEvtHandler::a2dStToolEvtHandler( a2dStToolContr* controller )
06585 {
06586 m_stcontroller = controller;
06587 m_options = a2dTakeToolstyleFromCmdhOnPop | a2dTakeToolstyleFromCmdhOnPush | a2dTakeToolstyleToNewObject;
06588 }
06589
06590 a2dStToolEvtHandler::~a2dStToolEvtHandler()
06591 {
06592 }
06593
06594 void a2dStToolEvtHandler::OnKeyDown(wxKeyEvent& event)
06595 {
06596 a2dBaseTool* first = m_stcontroller->GetFirstTool();
06597 switch(event.GetKeyCode())
06598 {
06599 case 'Z':
06600 case 'z':
06601 {
06602 if ( !first || (first && !first->GetBusy()) )
06603 {
06604 if ( event.m_controlDown && event.m_shiftDown )
06605 first->GetCanvasDocument()->GetCommandProcessor()->Redo();
06606 else if ( event.m_controlDown )
06607 first->GetCanvasDocument()->GetCommandProcessor()->Undo();
06608 else
06609 event.Skip();
06610 }
06611 else
06612 event.Skip();
06613 break;
06614 }
06615 case 'Y':
06616 case 'y':
06617 {
06618 if ( !first || (first && !first->GetBusy()) )
06619 {
06620 if ( event.m_controlDown )
06621 first->GetCanvasDocument()->GetCommandProcessor()->Redo();
06622 else
06623 event.Skip();
06624 }
06625 else
06626 event.Skip();
06627 break;
06628 }
06629 default:
06630 event.Skip();
06631 }
06632 }
06633
06634 void a2dStToolEvtHandler::OnKeyUp(wxKeyEvent& event)
06635 {
06636 event.Skip();
06637 }
06638
06639 void a2dStToolEvtHandler::TakeToCmdhFromEditedObject( a2dObjectEditTool* editTool )
06640 {
06641 editTool->SetLayer( editTool->m_original->GetLayer() );
06642 editTool->SetFill( editTool->m_original->GetFill() );
06643 editTool->SetStroke( editTool->m_original->GetStroke() );
06644 a2dGetCmdh()->SetLayer( editTool->m_original->GetLayer() );
06645 a2dGetCmdh()->SetFill( editTool->m_original->GetFill() );
06646 a2dGetCmdh()->SetStroke( editTool->m_original->GetStroke() );
06647
06648 if ( wxDynamicCast( editTool->m_original.Get(), a2dText ) )
06649 {
06650 a2dText* text = wxDynamicCast( editTool->m_original.Get(), a2dText );
06651 if ( text )
06652 a2dGetCmdh()->SetFont( text->GetFont() );
06653 }
06654 if ( wxDynamicCast( editTool->m_original.Get(), a2dPolylineL ) )
06655 {
06656 a2dPolylineL* poly = wxDynamicCast( editTool->m_original.Get(), a2dPolylineL );
06657 if ( poly )
06658 {
06659
06660 a2dGetCmdh()->SetLineBegin( poly->GetBegin() );
06661 a2dGetCmdh()->SetLineEnd( poly->GetEnd() );
06662 a2dGetCmdh()->SetEndScaleX( poly->GetEndScaleX() );
06663 a2dGetCmdh()->SetEndScaleY( poly->GetEndScaleY() );
06664 }
06665 }
06666 if ( wxDynamicCast( editTool->m_original.Get(), a2dEndsLine ) )
06667 {
06668 a2dEndsLine* line = wxDynamicCast( editTool->m_original.Get(), a2dEndsLine );
06669 if ( line )
06670 {
06671 a2dGetCmdh()->SetLineBegin( line->GetBegin() );
06672 a2dGetCmdh()->SetLineEnd( line->GetEnd() );
06673 a2dGetCmdh()->SetEndScaleX( line->GetEndScaleX() );
06674 a2dGetCmdh()->SetEndScaleY( line->GetEndScaleY() );
06675 }
06676 }
06677 if ( editTool->m_original && editTool->m_original->GetContourWidth() != a2dGetCmdh()->GetContourWidthInDataBaseUnits() )
06678 {
06679 a2dGetCmdh()->SetContourWidthInDataBaseUnits( editTool->m_original->GetContourWidth() );
06680 editTool->m_contourwidth = editTool->m_original->GetContourWidth();
06681 editTool->m_original->SetContourWidth( editTool->m_contourwidth );
06682 }
06683 a2dPolylineL* poly = wxDynamicCast( editTool->m_original.Get(), a2dPolylineL );
06684 if ( poly && poly->GetPathType() != a2dGetCmdh()->GetPathType() )
06685 a2dGetCmdh()->SetPathType( poly->GetPathType() );
06686 a2dSLine* line = wxDynamicCast( editTool->m_canvasobject.Get(), a2dSLine );
06687 if ( line && line->GetPathType() != a2dGetCmdh()->GetPathType() )
06688 a2dGetCmdh()->SetPathType( line->GetPathType() );
06689 }
06690
06691 void a2dStToolEvtHandler::OnIdle( wxIdleEvent &event )
06692 {
06693 static wxDateTime lastTimeHere = wxDateTime::UNow();
06694
06695 if ( lastTimeHere + wxTimeSpan::Milliseconds( 100 ) > wxDateTime::UNow() )
06696 return;
06697
06698 lastTimeHere = wxDateTime::UNow();
06699
06700 a2dBaseTool* tool = m_stcontroller->GetFirstTool();
06701 if ( tool->GetActive() && tool->GetEvtHandlerEnabled() && tool->GetCanvasView())
06702 {
06703 tool->SetEvtHandlerEnabled(false);
06704 if ( wxDynamicCast( tool, a2dDrawPolylineLTool ) )
06705 {
06706 a2dDrawPolylineLTool* toolt = wxStaticCast( tool, a2dDrawPolylineLTool );
06707
06708 if ( toolt->GetSpline() != a2dGetCmdh()->GetSpline() )
06709 toolt->SetSpline( a2dGetCmdh()->GetSpline() );
06710 if ( toolt->GetLineBegin() != a2dGetCmdh()->GetLineBegin() )
06711 toolt->SetLineBegin( a2dGetCmdh()->GetLineBegin() );
06712 if ( toolt->GetLineEnd() != a2dGetCmdh()->GetLineEnd() )
06713 toolt->SetLineEnd( a2dGetCmdh()->GetLineEnd() );
06714 if ( toolt->GetEndScaleX() != a2dGetCmdh()->GetEndScaleX() )
06715 toolt->SetEndScaleX( a2dGetCmdh()->GetEndScaleX() );
06716 if ( toolt->GetEndScaleY() != a2dGetCmdh()->GetEndScaleY() )
06717 toolt->SetEndScaleY( a2dGetCmdh()->GetEndScaleY() );
06718 }
06719 if ( wxDynamicCast( tool, a2dDrawLineTool ) )
06720 {
06721 a2dDrawLineTool* toolt = wxStaticCast( tool, a2dDrawLineTool );
06722
06723 if ( toolt->GetAllowModifyTemplate() )
06724 {
06725 if ( toolt->GetLineBegin() != a2dGetCmdh()->GetLineBegin() )
06726 toolt->SetLineBegin( a2dGetCmdh()->GetLineBegin() );
06727 if ( toolt->GetLineEnd() != a2dGetCmdh()->GetLineEnd() )
06728 toolt->SetLineEnd( a2dGetCmdh()->GetLineEnd() );
06729 if ( toolt->GetEndScaleX() != a2dGetCmdh()->GetEndScaleX() )
06730 toolt->SetEndScaleX( a2dGetCmdh()->GetEndScaleX() );
06731 if ( toolt->GetEndScaleY() != a2dGetCmdh()->GetEndScaleY() )
06732 toolt->SetEndScaleY( a2dGetCmdh()->GetEndScaleY() );
06733 toolt->SetContourWidth( a2dGetCmdh()->GetContourWidth() );
06734 }
06735 }
06736 if ( wxDynamicCast( tool, a2dStDrawTool ) || wxDynamicCast( tool, a2dObjectEditTool ) )
06737 {
06738
06739 a2dStTool* sttool = wxDynamicCast( tool, a2dStTool );
06740 a2dStDrawTool* drawtool = wxDynamicCast( tool, a2dStDrawTool );
06741 a2dObjectEditTool* editTool = wxDynamicCast( tool, a2dObjectEditTool );
06742 a2dCanvasCommandProcessor* docCmdh = tool->GetCanvasCommandProcessor();
06743 a2dFill f = a2dGetCmdh()->GetFill();
06744 if ( ! tool->GetFill().IsSameAs( f ) )
06745 {
06746 tool->SetFill( f );
06747 if ( tool->GetBusy() )
06748 docCmdh->Submit( new a2dCommand_ChangeCanvasObjectStyle( sttool->m_original, f ));
06749 }
06750 a2dStroke s = a2dGetCmdh()->GetStroke();
06751 if ( ! tool->GetStroke().IsSameAs( s ) )
06752 {
06753 tool->SetStroke( s );
06754 if ( tool->GetBusy() )
06755 docCmdh->Submit( new a2dCommand_ChangeCanvasObjectStyle( sttool->m_original, s ));
06756 }
06757 if ( tool->GetLayer() != a2dGetCmdh()->GetLayer() )
06758 {
06759 tool->SetLayer( a2dGetCmdh()->GetLayer() );
06760 if ( drawtool && drawtool->m_original )
06761 {
06762 drawtool->m_original->SetLayer( a2dGetCmdh()->GetLayer() );
06763 }
06764 if ( editTool && editTool->m_original )
06765 {
06766 editTool->m_original->SetLayer( a2dGetCmdh()->GetLayer() );
06767 }
06768 }
06769 }
06770 if ( wxDynamicCast( tool, a2dDrawTextTool ) )
06771 {
06772 a2dDrawTextTool* textTool = wxDynamicCast( tool, a2dDrawTextTool );
06773 a2dFont font = a2dGetCmdh()->GetFont();
06774 if ( ! textTool->GetFont().IsSameAs( font ) )
06775 {
06776 textTool->SetFont( a2dGetCmdh()->GetFont() );
06777 }
06778 }
06779 if ( wxDynamicCast( tool, a2dObjectEditTool ) )
06780 {
06781 a2dObjectEditTool* editTool = wxDynamicCast( tool, a2dObjectEditTool );
06782 if ( wxDynamicCast( editTool->m_original.Get(), a2dText ) )
06783 {
06784 a2dText* text = wxDynamicCast( editTool->m_original.Get(), a2dText );
06785 if ( text )
06786 {
06787 text->SetFont( a2dGetCmdh()->GetFont() );
06788 a2dText* texteditobj = wxDynamicCast( editTool->m_canvasobject.Get(), a2dText );
06789 texteditobj->SetFont( a2dGetCmdh()->GetFont() );
06790 }
06791 }
06792 if ( wxDynamicCast( editTool->m_original.Get(), a2dPolylineL ) )
06793 {
06794 a2dPolylineL* poly = wxDynamicCast( editTool->m_original.Get(), a2dPolylineL );
06795 if ( poly )
06796 {
06797 if ( poly->GetSpline() != a2dGetCmdh()->GetSpline() )
06798 poly->SetSpline( a2dGetCmdh()->GetSpline() );
06799 if ( poly->GetBegin() != a2dGetCmdh()->GetLineBegin() )
06800 poly->SetBegin( a2dGetCmdh()->GetLineBegin() );
06801 if ( poly->GetEnd() != a2dGetCmdh()->GetLineEnd() )
06802 poly->SetEnd( a2dGetCmdh()->GetLineEnd() );
06803 if ( poly->GetEndScaleX() != a2dGetCmdh()->GetEndScaleX() )
06804 poly->SetEndScaleX( a2dGetCmdh()->GetEndScaleX() );
06805 if ( poly->GetEndScaleY() != a2dGetCmdh()->GetEndScaleY() )
06806 poly->SetEndScaleY( a2dGetCmdh()->GetEndScaleY() );
06807 }
06808 }
06809 if ( wxDynamicCast( editTool->m_original.Get(), a2dEndsLine ) )
06810 {
06811 a2dEndsLine* line = wxDynamicCast( editTool->m_original.Get(), a2dEndsLine );
06812 if ( line )
06813 {
06814 if ( line->GetBegin() != a2dGetCmdh()->GetLineBegin() )
06815 line->SetBegin( a2dGetCmdh()->GetLineBegin() );
06816 if ( line->GetEnd() != a2dGetCmdh()->GetLineEnd() )
06817 line->SetEnd( a2dGetCmdh()->GetLineEnd() );
06818 if ( line->GetEndScaleX() != a2dGetCmdh()->GetEndScaleX() )
06819 line->SetEndScaleX( a2dGetCmdh()->GetEndScaleX() );
06820 if ( line->GetEndScaleY() != a2dGetCmdh()->GetEndScaleY() )
06821 line->SetEndScaleY( a2dGetCmdh()->GetEndScaleY() );
06822 }
06823 }
06824 if ( editTool->m_original && editTool->m_original->GetContourWidth() != a2dGetCmdh()->GetContourWidthInDataBaseUnits() )
06825 {
06826 editTool->m_contourwidth = a2dGetCmdh()->GetContourWidthInDataBaseUnits();
06827 editTool->m_canvasobject->SetContourWidth( editTool->m_contourwidth );
06828 editTool->m_original->SetContourWidth( editTool->m_contourwidth );
06829 }
06830 a2dPolylineL* poly = wxDynamicCast( editTool->m_original.Get(), a2dPolylineL );
06831 if ( poly && poly->GetPathType() != a2dGetCmdh()->GetPathType() )
06832 poly->SetPathType( a2dGetCmdh()->GetPathType() );
06833 a2dSLine* line = wxDynamicCast( editTool->m_canvasobject.Get(), a2dSLine );
06834 if ( line && line->GetPathType() != a2dGetCmdh()->GetPathType() )
06835 line->SetPathType( a2dGetCmdh()->GetPathType() );
06836 }
06837 }
06838 tool->SetEvtHandlerEnabled(true);
06839
06840 event.Skip();
06841 }
06842
06843 void a2dStToolEvtHandler::OnComEvent( a2dComEvent& event )
06844 {
06845 bool baseContinue = true;
06846 if ( event.GetEventComId() == &a2dRecursiveEditTool::sm_toolStartEditObject )
06847 {
06848 a2dObjectEditTool* tool = wxDynamicCast( event.GetEventObject(), a2dObjectEditTool );
06849 if ( tool && tool->GetActive() && tool->GetEvtHandlerEnabled() && tool->GetCanvasView() )
06850 {
06851 TakeToCmdhFromEditedObject( tool );
06852
06853 tool->SetEvtHandlerEnabled(false);
06854
06855 a2dComEvent event( tool, tool->m_original, &a2dRecursiveEditTool::sm_toolStartEditObject );
06856 a2dDocviewGlobals->GetEventDistributer()->ProcessEvent( event );
06857
06858 tool->SetEvtHandlerEnabled(true);
06859 }
06860 }
06861
06862 if ( baseContinue &&
06863 ( wxDynamicCast( event.GetEventObject(), a2dStDrawTool ) )
06864 )
06865 {
06866
06867
06868 a2dStDrawTool* tool = wxDynamicCast( event.GetEventObject(), a2dStDrawTool );
06869
06870 if ( (m_options & a2dTakeToolstyleToNewObject) && event.GetEventComId() == &a2dStTool::sm_toolComEventAddObject )
06871 {
06872 a2dProperty *property = (a2dProperty *) event.GetProperty();
06873 a2dCanvasObject* obj = wxStaticCast( property->GetValue(), a2dCanvasObject );
06874
06875 a2dCanvasObject::PROPID_Fill->SetPropertyToObject( obj, tool->GetFill() );
06876 a2dCanvasObject::PROPID_Stroke->SetPropertyToObject( obj, tool->GetStroke() );
06877 a2dCanvasObject::PROPID_Layer->SetPropertyToObject( obj, tool->GetLayer() );
06878 }
06879 }
06880
06881
06882
06883
06884
06885
06886
06887
06888
06889
06890
06891
06892
06893
06894
06895
06896
06897
06898
06899
06900
06901
06902
06903
06904
06905
06906
06907
06908
06909
06910
06911
06912
06913
06914
06915
06916
06917
06918
06919
06920
06921
06922
06923
06924
06925
06926
06927
06928
06929
06930
06931
06932
06933
06934
06935
06936
06937
06938
06939
06940
06941
06942
06943
06944
06945
06946
06947
06948
06949
06950
06951
06952
06953
06954
06955
06956
06957
06958
06959
06960
06961
06962
06963
06964
06965
06966
06967
06968
06969
06970
06971
06972
06973
06974
06975
06976
06977
06978
06979
06980
06981
06982
06983
06984
06985
06986
06987
06988
06989
06990
06991
06992
06993
06994
06995
06996
06997
06998
06999
07000
07001
07002
07003
07004
07005
07006
07007
07008
07009
07010
07011
07012
07013
07014
07015
07016
07017
07018
07019
07020
07021
07022 a2dStTool* tool = wxDynamicCast( event.GetEventObject(), a2dStTool );
07023
07024 if ( tool && tool->GetActive() && tool->GetEvtHandlerEnabled() && tool->GetCanvasView())
07025 {
07026
07027
07028
07029
07030
07031
07032
07033
07034
07035
07036
07037
07038
07039
07040
07041
07042
07043
07044
07045
07046
07047 if ( event.GetEventComId() == &a2dCanvasView::sm_changedShowObject )
07048 {
07049
07050 }
07051 else
07052 event.Skip();
07053
07054 }
07055
07056 event.Skip();
07057
07058 }
07059
07060 void a2dStToolEvtHandler::OnDoEvent( a2dCommandProcessorEvent& event )
07061 {
07062 a2dBaseTool* tool = m_stcontroller->GetFirstTool();
07063 if ( tool->GetActive() && tool->GetEvtHandlerEnabled() && tool->GetCanvasView())
07064 {
07065
07066
07067
07068
07069
07070
07071
07072
07073
07074
07075
07076
07077
07078
07079
07080
07081
07082
07083
07084
07085
07086
07087
07088
07089
07090
07091
07092
07093
07094
07095
07096
07097 }
07098
07099 event.Skip();
07100
07101 }
07102
07103 void a2dStToolEvtHandler::OnUndoEvent( a2dCommandProcessorEvent& event )
07104 {
07105 event.Skip();
07106
07107 }
07108
07109 void a2dStToolEvtHandler::OnRedoEvent( a2dCommandProcessorEvent& event )
07110 {
07111 OnUndoEvent( event );
07112 event.Skip();
07113 }
07114
07115
07116
07117
07118
07119 A2D_BEGIN_EVENT_TABLE(a2dStToolFixedToolStyleEvtHandler, a2dToolEvtHandler )
07120 A2D_EVT_KEY_DOWN( a2dStToolFixedToolStyleEvtHandler::OnKeyDown)
07121 A2D_EVT_KEY_UP( a2dStToolFixedToolStyleEvtHandler::OnKeyUp)
07122 A2D_EVT_COM_EVENT( a2dStToolFixedToolStyleEvtHandler::OnComEvent )
07123 A2D_EVT_DO( a2dStToolFixedToolStyleEvtHandler::OnDoEvent )
07124 A2D_EVT_UNDO( a2dStToolFixedToolStyleEvtHandler::OnUndoEvent )
07125 A2D_EVT_REDO( a2dStToolFixedToolStyleEvtHandler::OnRedoEvent )
07126 A2D_END_EVENT_TABLE()
07127
07128 a2dStToolFixedToolStyleEvtHandler::a2dStToolFixedToolStyleEvtHandler( a2dStToolContr* controller )
07129 {
07130 m_stcontroller = controller;
07131 m_takeToolstyleToCmdhOnPush = false;
07132 }
07133
07134 a2dStToolFixedToolStyleEvtHandler::~a2dStToolFixedToolStyleEvtHandler()
07135 {
07136 }
07137
07138 void a2dStToolFixedToolStyleEvtHandler::OnKeyDown(wxKeyEvent& event)
07139 {
07140 a2dBaseTool* first = m_stcontroller->GetFirstTool();
07141 switch(event.GetKeyCode())
07142 {
07143 case 'Z':
07144 case 'z':
07145 {
07146 if ( !first || (first && !first->GetBusy()) )
07147 {
07148 if ( event.m_controlDown && event.m_shiftDown )
07149 first->GetCanvasDocument()->GetCommandProcessor()->Redo();
07150 else if ( event.m_controlDown )
07151 first->GetCanvasDocument()->GetCommandProcessor()->Undo();
07152 else
07153 event.Skip();
07154 }
07155 else
07156 event.Skip();
07157 break;
07158 }
07159 case 'Y':
07160 case 'y':
07161 {
07162 if ( !first || (first && !first->GetBusy()) )
07163 {
07164 if ( event.m_controlDown )
07165 first->GetCanvasDocument()->GetCommandProcessor()->Redo();
07166 else
07167 event.Skip();
07168 }
07169 else
07170 event.Skip();
07171 break;
07172 }
07173 default:
07174 event.Skip();
07175 }
07176 }
07177
07178 void a2dStToolFixedToolStyleEvtHandler::OnKeyUp(wxKeyEvent& event)
07179 {
07180 event.Skip();
07181 }
07182
07183 void a2dStToolFixedToolStyleEvtHandler::OnComEvent( a2dComEvent& event )
07184 {
07185 bool baseContinue = true;
07186 if ( baseContinue && wxDynamicCast( event.GetEventObject(), a2dStDrawTool ) )
07187 {
07188
07189
07190 a2dStDrawTool* tool = wxDynamicCast( event.GetEventObject(), a2dStDrawTool );
07191 if ( m_takeToolstyleToCmdhOnPush && event.GetEventComId() == &a2dStTool::sm_toolPushed )
07192 {
07193 a2dCentralCanvasCommandProcessor::PROPID_Fill->SetPropertyToObject( a2dGetCmdh(), tool->GetFill() );
07194 a2dCentralCanvasCommandProcessor::PROPID_Stroke->SetPropertyToObject( a2dGetCmdh(), tool->GetStroke() );
07195 }
07196 if ( event.GetEventComId() == &a2dStTool::sm_toolPoped )
07197 {
07198 tool->CloseCommandGroup();
07199 }
07200 if ( event.GetEventComId() == &a2dStTool::sm_toolComEventAddObject )
07201 {
07202 a2dProperty *property = (a2dProperty *) event.GetProperty();
07203 a2dCanvasObject* obj = wxStaticCast( property->GetValue(), a2dCanvasObject );
07204
07205 a2dCanvasObject::PROPID_Fill->SetPropertyToObject( obj, tool->GetFill() );
07206 a2dCanvasObject::PROPID_Stroke->SetPropertyToObject( obj, tool->GetStroke() );
07207 }
07208 }
07209
07210 event.Skip();
07211 }
07212
07213 void a2dStToolFixedToolStyleEvtHandler::OnDoEvent( a2dCommandProcessorEvent& event )
07214 {
07215
07216
07217
07218
07219
07220
07221 event.Skip();
07222 }
07223
07224 void a2dStToolFixedToolStyleEvtHandler::OnUndoEvent( a2dCommandProcessorEvent& event )
07225 {
07226 event.Skip();
07227
07228 }
07229
07230 void a2dStToolFixedToolStyleEvtHandler::OnRedoEvent( a2dCommandProcessorEvent& event )
07231 {
07232 event.Skip();
07233 }
07234
07235
07236
07237
07238
07239
07240
07241
07242
07243
07244
07245
07246 A2D_BEGIN_EVENT_TABLE(a2dDrawVPathTool,a2dStDrawTool)
07247 A2D_EVT_IDLE( a2dDrawVPathTool::OnIdle )
07248 A2D_EVT_CHAR( a2dDrawVPathTool::OnChar )
07249 A2D_EVT_MOUSE_EVENTS(a2dDrawVPathTool::OnMouseEvent)
07250 A2D_EVT_UNDO( a2dDrawVPathTool::OnUndoEvent )
07251 A2D_EVT_REDO( a2dDrawVPathTool::OnRedoEvent )
07252 A2D_END_EVENT_TABLE()
07253
07254 void a2dDrawVPathTool::AddSegment( a2dVpathSegment* segment )
07255 {
07256 if ( m_reverse )
07257 m_vpath->Add( segment );
07258 else
07259 m_vpath->Add( segment );
07260 }
07261
07262 a2dDrawVPathTool::a2dDrawVPathTool(a2dStToolContr* controller, a2dVectorPath* templateObject ):a2dStDrawTool(controller)
07263 {
07264 m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_PENCIL );
07265 m_toolBusyCursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_CROSS );
07266 m_contourwidth = a2dGetCmdh()->GetContourWidthInDataBaseUnits();
07267 m_segment = NULL;
07268
07269 m_canvasobject = (a2dCanvasObject*)0;
07270 m_vpath = (a2dVpath*) 0;
07271
07272 m_reverse = false;
07273 m_controlSet = false;
07274
07275 m_templateObject = templateObject;
07276 m_controlPoints = NULL;
07277 }
07278
07279 a2dDrawVPathTool::~a2dDrawVPathTool()
07280 {
07281 }
07282
07283 void a2dDrawVPathTool::OnIdle( wxIdleEvent &event )
07284 {
07285 if (m_pending && GetBusy())
07286 {
07287 RemoveAllDecorations();
07288
07289 a2dVectorPath* path = wxStaticCast( m_canvasobject.Get(), a2dVectorPath );
07290 a2dRect* around = NULL;
07291
07292 switch ( m_mode )
07293 {
07294 case 0:
07295 {
07296
07297 if ( m_segment && m_bezier )
07298 {
07299 m_controlPoints = new a2dPolylineL();
07300 m_controlPoints->AddPoint( m_segmentPrev->m_x1, m_segmentPrev->m_y1 );
07301 a2dVpathCBCurveSegment* seg = (a2dVpathCBCurveSegment*) m_segment;
07302 m_controlPoints->AddPoint( seg->m_x2, seg->m_y2 );
07303 m_controlPoints->AddPoint( seg->m_x3, seg->m_y3 );
07304 m_controlPoints->AddPoint( m_segment->m_x1, m_segment->m_y1 );
07305 m_controlPoints->SetVisible( true );
07306 m_controlPoints->SetFill( *a2dTRANSPARENT_FILL );
07307
07308 m_controlPoints->SetStroke( *wxRED, 0, a2dSTROKE_SOLID );
07309 AddDecorationObject( m_controlPoints );
07310 }
07311 break;
07312 }
07313 case 1:
07314 {
07315 around = new a2dRect( path->GetBboxMinX(), path->GetBboxMinY(), path->GetBboxWidth(), path->GetBboxHeight() );
07316 around->SetStroke( *wxRED, 0, a2dSTROKE_DOT_DASH );
07317 around->SetFill( *a2dTRANSPARENT_FILL );
07318 around->SetCanvasDocument( GetCanvasView()->GetCanvasDocument() );
07319 AddDecorationObject( around );
07320 break;
07321 }
07322 default:
07323 break;
07324 }
07325
07326 event.Skip();
07327 }
07328 else
07329 event.Skip();
07330 }
07331
07332 void a2dDrawVPathTool::OnUndoEvent( a2dCommandProcessorEvent& WXUNUSED(event) )
07333 {
07334 if (GetBusy() && !m_halted)
07335 {
07336
07337
07338 a2dVectorPath* path = wxStaticCast( m_canvasobject.Get(), a2dVectorPath );
07339 if ( ! path->IsEmpty() )
07340 {
07341 a2dVpathSegment& lastpoint = path->GetSegments()->Last();
07342
07343 CleanupToolObjects();
07344 GetCanvasView()->Update( a2dCANVIEW_UPDATE_OLDNEW );
07345 CreateToolObjects();
07346 m_vpath = wxStaticCast( m_canvasobject.Get(), a2dVectorPath )->GetSegments();
07347 m_segment = lastpoint.Clone();
07348 m_vpath->push_back( m_segment );
07349 }
07350 }
07351 }
07352
07353 void a2dDrawVPathTool::OnRedoEvent( a2dCommandProcessorEvent& event )
07354 {
07355 OnUndoEvent( event );
07356 }
07357
07358 void a2dDrawVPathTool::SetMode( int mode )
07359 {
07360 m_mode = mode;
07361 if (m_mode > 2) m_mode = 0;
07362
07363 if (!m_canvasobject)
07364 return;
07365
07366 m_pending = true;
07367 }
07368
07369 void a2dDrawVPathTool::OnChar(wxKeyEvent& event)
07370 {
07371 if (GetBusy() && m_canvasobject)
07372 {
07373 double shiftx;
07374 double shifty;
07375 GetKeyIncrement(&shiftx, &shifty, event.AltDown());
07376
07377 switch(event.GetKeyCode())
07378 {
07379 case WXK_TAB:
07380 {
07381 m_mode++;
07382 SetMode( m_mode );
07383 }
07384 break;
07385
07386 case WXK_UP:
07387 shiftx = 0;
07388 break;
07389
07390 case WXK_DOWN:
07391 shiftx = 0;
07392 shifty = -shifty;
07393 break;
07394
07395 case WXK_LEFT:
07396 shiftx = -shiftx;
07397 shifty = 0;
07398 break;
07399
07400 case WXK_RIGHT:
07401 shifty = 0;
07402 break;
07403
07404 default:
07405 {
07406 shiftx = 0;
07407 shifty = 0;
07408 event.Skip();
07409 }
07410 }
07411
07412 if ( event.m_controlDown )
07413 {
07414 m_segment->m_x1 += shiftx;
07415 m_segment->m_y1 += shifty;
07416 }
07417 else
07418 {
07419 double x = m_canvasobject->GetPosX();
07420 double y = m_canvasobject->GetPosY();
07421 m_canvasobject->SetPosXY( x + shiftx, y + shifty, true );
07422 a2dVectorPath* path = wxStaticCast( m_canvasobject.Get(), a2dVectorPath );
07423 path->EliminateMatrix();
07424 }
07425
07426 GetDisplayWindow()->WarpPointer( GetDrawer2D()->WorldToDeviceX( m_segment->m_x1 ), GetDrawer2D()->WorldToDeviceY( m_segment->m_y1 ) );
07427
07428 m_pending = true;
07429 }
07430 else
07431 event.Skip();
07432
07433 }
07434
07435 void a2dDrawVPathTool::OnMouseEvent(wxMouseEvent& event)
07436 {
07437 if (!m_active)
07438 {
07439 event.Skip();
07440 return;
07441 }
07442
07443 if ( GetBusy() )
07444 GetCanvasView()->SetCursor( m_toolBusyCursor );
07445 else
07446 GetCanvasView()->SetCursor( m_toolcursor );
07447
07448 m_x = event.GetX();
07449 m_y = event.GetY();
07450 MouseToToolWorld( m_x, m_y, m_xwprev, m_ywprev );
07451
07452 a2dRestrictionEngine *restrict = a2dCanvasGlobals->GetRestrictionEngine();
07453 if(restrict)
07454 restrict->RestrictPoint(m_xwprev, m_ywprev);
07455 if (event.LeftDown() && !GetBusy())
07456 {
07457 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
07458 if ( m_templateObject )
07459 {
07460 m_original = m_templateObject->TClone( clone_childs );
07461 m_original->Translate( m_xwprev, m_ywprev );
07462 m_original->EliminateMatrix();
07463 }
07464 else
07465 {
07466 m_original = new a2dVectorPath();
07467 m_original->SetContourWidth( m_contourwidth );
07468 m_original->SetStroke( m_stroke );
07469 m_original->SetFill( m_fill );
07470 m_original->SetLayer(m_layer);
07471 }
07472
07473 EnterBusyMode();
07474 AddCurrent( m_original );
07475 m_original->SetCanvasDocument( GetCanvasDocument() );
07476 a2dVectorPath* path = wxStaticCast( m_original.Get(), a2dVectorPath );
07477
07478
07479
07480
07481
07482
07483 path->Add( new a2dVpathSegment( m_xwprev, m_ywprev, a2dPATHSEG_MOVETO ) );
07484
07485
07486
07487 a2dVectorPath* pathedit = wxStaticCast( m_canvasobject.Get(), a2dVectorPath );
07488 m_vpath = pathedit->GetSegments();
07489 m_segmentPrev = new a2dVpathSegment( m_xwprev, m_ywprev, a2dPATHSEG_MOVETO );
07490 m_vpath->Add( m_segmentPrev );
07491 m_segment = new a2dVpathCBCurveSegment( m_xwprev,m_ywprev, m_xwprev,m_ywprev, m_xwprev,m_ywprev );
07492 m_vpath->Add( m_segment );
07493
07494
07495 a2dDocviewGlobals->RecordF( this, _T("polygon") );
07496 a2dDocviewGlobals->RecordF( this, _T("addpoint %f %f"), m_xwprev, m_ywprev );
07497
07498 m_prev_x = m_xwprev;
07499 m_prev_y = m_ywprev;
07500 m_contrmid_x = m_xwprev;
07501 m_contrmid_y = m_ywprev;
07502 m_pending = true;
07503 m_controlSet = false;
07504 m_endSegment = false;
07505 m_bezier = false;
07506 if(restrict)
07507 restrict->SetRestrictPoint( m_xwprev, m_ywprev );
07508 }
07509 else if (event.LeftDown() && GetBusy())
07510 {
07511 if ( m_segmentPrev->m_x1 == m_xwprev && m_segmentPrev->m_y1 == m_ywprev )
07512 m_controlSet = false;
07513 else if ( !m_bezier && !m_endSegment )
07514 {
07515 m_controlSet = true;
07516 m_contrmid_x = m_xwprev;
07517 m_contrmid_y = m_ywprev;
07518 }
07519 }
07520 else if (event.LeftUp() && GetBusy() )
07521 {
07522 if ( m_segmentPrev->m_x1 == m_xwprev && m_segmentPrev->m_y1 == m_ywprev )
07523 {
07524 }
07525 else if ( m_bezier && !m_controlSet )
07526 {
07527 m_controlSet = true;
07528 m_contrmid_x = m_xwprev;
07529 m_contrmid_y = m_ywprev;
07530 m_endSegment = true;
07531 }
07532 else if ( m_bezier && m_controlSet && !m_endSegment )
07533 {
07534 m_endSegment = true;
07535 }
07536 else if ( !m_bezier || ( m_bezier && m_endSegment) )
07537 {
07538 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
07539 int x = GetDrawer2D()->WorldToDeviceX(m_prev_x);
07540 int y = GetDrawer2D()->WorldToDeviceY(m_prev_y);
07541 if ( abs(m_x-x) >=3 || abs(m_y-y) >= 3)
07542 {
07543
07544
07545
07546
07547
07548
07549
07550 a2dVectorPath* path = wxStaticCast( m_original.Get(), a2dVectorPath );
07551 path->Add( m_segment->Clone() );
07552
07553 m_segmentPrev = m_segment;
07554
07555 m_segment = new a2dVpathCBCurveSegment( m_xwprev,m_ywprev, m_xwprev,m_ywprev, m_xwprev,m_ywprev );
07556
07557 m_vpath->Add(m_segment);
07558 m_prev_x = m_xwprev;
07559 m_prev_y = m_ywprev;
07560 m_controlSet = false;
07561 m_endSegment = false;
07562 m_bezier = false;
07563 }
07564 m_pending = true;
07565 if(restrict)
07566 restrict->SetRestrictPoint( m_xwprev, m_ywprev );
07567 }
07568 }
07569 else if (event.Moving() && GetBusy())
07570 {
07571 m_segment->m_x1 = m_xwprev;
07572 m_segment->m_y1 = m_ywprev;
07573 m_canvasobject->SetPending( true );
07574 m_original->SetPending( true );
07575 m_pending = true;
07576 event.Skip();
07577 }
07578 else if (event.Dragging() && GetBusy())
07579 {
07580 m_bezier = true;
07581 if ( !m_endSegment )
07582 {
07583 double dx = m_xwprev - m_contrmid_x;
07584 double dy = m_ywprev - m_contrmid_y;
07585 a2dVpathCBCurveSegment* seg = (a2dVpathCBCurveSegment*) m_segment;
07586 if ( !m_controlSet )
07587 {
07588 seg->m_x2 = m_xwprev;
07589 seg->m_y2 = m_ywprev;
07590 }
07591 else
07592 {
07593 seg->m_x2 = m_contrmid_x - dx;
07594 seg->m_y2 = m_contrmid_y - dy;
07595 }
07596 seg->m_x3 = m_xwprev;
07597 seg->m_y3 = m_ywprev;
07598 seg->m_x1 = m_xwprev+1;
07599 seg->m_y1 = m_ywprev+1;
07600 }
07601 else
07602 {
07603 m_segment->m_x1 = m_xwprev;
07604 m_segment->m_y1 = m_ywprev;
07605 }
07606 m_canvasobject->SetPending( true );
07607 m_pending = true;
07608 event.Skip();
07609 }
07610 else if (event.LeftDClick() && GetBusy())
07611 {
07612 a2dGetCmdh()->SetLastXyEntry( m_xwprev, m_ywprev );
07613 a2dDocviewGlobals->RecordF( this, _T("end") );
07614 FinishBusyMode();
07615 }
07616 else
07617 event.Skip();
07618 }