wxArt2D
mastertool.cpp
1 /*! \file editor/src/mastertool.cpp
2  \author Michael S�gtrop
3  \date Created 02/06/2004
4 
5  Copyright: 2004-2004 (c) Michael S�gtrop
6 
7  Licence: wxWidgets Licence
8 
9  RCS-ID: $Id: mastertool.cpp,v 1.109 2009/08/07 20:31:32 titato Exp $
10 */
11 
12 // This file contains master tools. This are tools that customize GUI behaviour
13 // by intercepting events and then deligating work to other tools
14 
15 #include "a2dprec.h"
16 
17 #ifdef __BORLANDC__
18 #pragma hdrstop
19 #endif
20 
21 #ifndef WX_PRECOMP
22 #include "wx/wx.h"
23 #endif
24 
25 #include "wx/canvas/canmod.h"
26 //#include "wx/filename.h"
27 
28 #include <float.h>
29 #include "wx/canvas/sttool.h"
30 #include "wx/canvas/sttool2.h"
31 #include "wx/canvas/mastertool.h"
32 #include <wx/general/id.inl>
33 #include <wx/regex.h>
34 #include <algorithm>
35 
36 
37 IMPLEMENT_CLASS( a2dSimpleEditPolygonTool, a2dStTool )
38 
39 BEGIN_EVENT_TABLE( a2dSimpleEditPolygonTool, a2dStTool )
40  EVT_MOUSE_EVENTS( a2dSimpleEditPolygonTool::OnMouseEvent )
41  EVT_CHAR( a2dSimpleEditPolygonTool::OnChar )
42 END_EVENT_TABLE()
43 
44 a2dSimpleEditPolygonTool::a2dSimpleEditPolygonTool( a2dStToolContr* controller, a2dCanvasObject* hit, int index, int count, Action action )
45  :
46  a2dStTool( controller )
47 {
48  m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW );
49  m_original = hit;
50  m_index = index;
51  m_count = count;
52  m_action = action;
53  m_preserve_RouteWhenDrag = false;
54 
55  m_mode = 1;
56  GetDrawingPart()->SetMouseEvents( false );
57 }
58 
59 a2dSimpleEditPolygonTool::~a2dSimpleEditPolygonTool()
60 {
61  if ( GetDrawingPart() )
62  GetDrawingPart()->SetMouseEvents( true );
63 }
64 
66 {
68  m_preserve_RouteWhenDrag = GetDrawing()->GetHabitat()->GetConnectionGenerator()->GetRouteWhenDrag();
69  GetDrawing()->GetHabitat()->GetConnectionGenerator()->SetRouteWhenDrag( true );
70 
72  return false;
73 
75  return true;
76 }
77 
78 void a2dSimpleEditPolygonTool::FinishBusyMode()
79 {
80  if ( GetDrawingPart() )
81  {
83  }
84 
85  wxASSERT( GetBusy() );
86 
87  // The pin which is edited may reconnect
88  if( m_action == action_movevertex )
89  {
90  /*
91  if( m_index == 0 )
92  data.m_allowreconnectbegin = true;
93  else if( m_index == m_count - 1 )
94  data.m_allowreconnectend = true;
95  */
96  m_original->SetAlgoSkip( true );
97  m_canvasobject->SetAlgoSkip( true );
98  double hitDistance = GetHitMargin();
99 
100  a2dPinPtr pin = m_handle->GetPin();
101  if ( pin )
102  {
103  a2dPin* pinother = pin->GetPinClass()->GetConnectionGenerator()->
104  SearchPinForFinishWire( GetDrawingPart()->GetShowObject(), pin, NULL, hitDistance );
105 
106  if ( pinother && ! pin->IsConnectedTo( pinother ) )
107  {
108  GetDrawing()->GetCanvasCommandProcessor()->Submit( new a2dCommand_ConnectPins( pin, pinother ), true );
109  }
110  }
111 
112  m_original->SetAlgoSkip( false );
113  m_canvasobject->SetAlgoSkip( false );
114  }
115 
117  GetDrawing()->GetHabitat()->GetConnectionGenerator()->SetRouteWhenDrag( m_preserve_RouteWhenDrag );
118 
120 }
121 
123 {
124  if ( GetDrawingPart() )
126 
127  GetDrawing()->GetHabitat()->GetConnectionGenerator()->SetRouteWhenDrag( m_preserve_RouteWhenDrag );
129 }
130 
132 {
133  if ( GetDrawingPart() )
135 
136  a2dStTool::DoStopTool( abort );
137 }
138 
139 void a2dSimpleEditPolygonTool::OnChar( wxKeyEvent& event )
140 {
141  event.Skip();
142 }
143 
144 void a2dSimpleEditPolygonTool::OnMouseEvent( wxMouseEvent& event )
145 {
146  if ( !m_active )
147  {
148  event.Skip();
149  return;
150  }
151  m_x = event.GetX();
152  m_y = event.GetY();
153 
154  //to world coordinates to do hit test in world coordinates
155  double xw;
156  double yw;
157 
158  xw = GetDrawer2D()->DeviceToWorldX( m_x );
159  yw = GetDrawer2D()->DeviceToWorldY( m_y );
160 
161  if ( ( event.LeftDown() || event.Dragging() ) && !GetBusy() )
162  {
163  if ( !EnterBusyMode() )
164  return; //not editable object
165 
166  //we generate some help handles, which get events sent to them via the event corridor to m_canvasobject.
167 
168  // m_original->StartEdit() did add m_canvasobject as an editcopy, so eventually those temporary handles will
169  // be deleted when m_canvasobject is released.
171  a2dPolylineL* original = wxDynamicCast( poly->GetOriginal(), a2dPolylineL );
172  a2dVertexList::iterator iter = poly->GetSegments()->begin();
173  a2dVertexList::iterator iterorg = original->GetSegments()->begin();
174 
175  int index = poly->FindSegmentIndex( a2dPoint2D( xw, yw ), GetHitMargin() );
176  if ( index != -1 )
177  {
178  iter = poly->GetSegmentAtIndex( index );
179  iterorg = original->GetSegmentAtIndex( index );
180 
181  switch( m_action )
182  {
183  case action_movevertex:
184  m_handle = new a2dPolyHandleL( poly, iter, iterorg, poly->GetSegments(), original->GetSegments(), wxT( "__index__" ) );
185  poly->Append( m_handle );
186  break;
187 
188  case action_movesegment:
189  m_handle = new a2dPolyHandleL( poly, iter, iterorg, poly->GetSegments(), original->GetSegments(), xw, yw, wxT( "__segment__" ) );
190  poly->Append( m_handle );
191  break;
192 
193  case action_insertvertex:
194  if ( event.AltDown() )
195  m_handle = new a2dPolyHandleL( poly, iter, iterorg, poly->GetSegments(), original->GetSegments(), xw, yw, wxT( "__segment__" ) );
196  else
197  m_handle = new a2dPolyHandleL( poly, iter, iterorg, poly->GetSegments(), original->GetSegments(), xw, yw, wxT( "__insert__" ) );
198  poly->Append( m_handle );
199  break;
200 
201  default:
202  wxASSERT( 0 );
203  }
205  m_handle->SetLayer( poly->GetLayer() );
206  m_handle->SetPreRenderAsChild( false );
207  poly->SetVisiblechilds( true );
208  poly->SetChildrenOnSameLayer( true );
210  poly->SetPending( true );
211 
212 
214  polyg->SetHandleToIndex( m_handle, m_index );
215 
216  bool isHit;
218  GetDrawingPart()->ProcessCanvasObjectEvent( event, isHit, xw, yw, 5 );
219 
220  GetDrawing()->GetHabitat()->GetConnectionGenerator()->RerouteWires( false );
221 
222  }
223  }
224 
225  /*
226  pin.FindConnectablePin( tool->GetDrawingPart()->GetShowObject(), 1.0, false );
227  if( event.Dragging() && m_action == action_movevertex )
228  {
229  a2dWirePolyline *wire =
230  a2dPin *FindEdnPin();
231  a2dPin tmp(
232  m_canvasobject, wxT("end"),
233  m_thePinClassMap ? *m_thePinClassMap->m_wireEnd : a2dPinClass::Standard,
234  m_xwprev, m_ywprev
235  );
236  a2dIterC ic( GetDrawingPart() );
237  GetDrawingPart()->GetShowObject()->EditFeedback( ic, &a2dPin::sm_feedbackGeneratePin, &tmp, 2, 0, m_xw, m_yw );
238  }
239  */
240 
241  else if( ( event.LeftDown() || event.LeftUp() || event.Dragging() ) && GetBusy() && m_handle )
242  {
245 
246  bool isHit;
247  if ( event.LeftDown() )
249  GetDrawingPart()->ProcessCanvasObjectEvent( event, isHit, xw, yw, 5 );
250 
251  GetDrawing()->GetHabitat()->GetConnectionGenerator()->RerouteWires( false );
252  }
253 
254  if( event.LeftUp() && GetBusy() )
255  {
256  FinishBusyMode();
257  }
258 }
259 
261 {
262  a2dRefMap refs;
263 
264  // Clone the original object
266  if ( !m_canvasobject )
267  return false; //not editable object
268 
269  //drag is comming so first create wires where there are non.
270  a2dCanvasObjectList dragList;
271  dragList.push_back( m_original );
272 
273  PrepareForRewire( dragList, true, false, false, true, &refs );
274 
275  // only now we call this, earlier not possible, because clones of connectedwires not setup yet.
276  refs.LinkReferences();
277 
278  // Set the visibility of the original dragged object and the original connected wires
281 
282  m_pending = true;
283 
284  return true;
285 }
286 
288 {
289  GetDrawing()->GetHabitat()->GetConnectionGenerator()->RerouteWires( true );
291 }
292 
293 //----------------------------------------------------------------------------
294 // a2dMasterDrawBase
295 //----------------------------------------------------------------------------
296 
297 IMPLEMENT_CLASS( a2dMasterDrawBase, a2dStTool )
298 
299 BEGIN_EVENT_TABLE( a2dMasterDrawBase, a2dStTool )
300  EVT_MOUSE_EVENTS( a2dMasterDrawBase::OnMouseEvent )
301  EVT_CHAR( a2dMasterDrawBase::OnChar )
302  EVT_KEY_DOWN( a2dMasterDrawBase::OnKeyDown )
303  EVT_KEY_UP( a2dMasterDrawBase::OnKeyUp )
304 END_EVENT_TABLE()
305 
306 a2dMasterDrawBase::a2dMasterDrawBase( a2dStToolContr* controller ):
307  m_dlgOrEdit( false ),
308  m_dlgOrEditModal( false ),
309  m_escapeToStopFirst( true ),
310  a2dStTool( controller )
311 {
312  m_generatedPinX = 0;
313  m_generatedPinY = 0;
314  m_styleDlgSimple = false;
315  m_hadDoubleClick = false;
316  m_dragStarted = false;
317  m_toolBusy = false;
318  m_select_undo = false;
319  m_lateconnect = true;
320  m_wiringMode = a2d_StartGenerateSearchFinish;
321 
322  m_fastTools = false;
323  m_spaceDown = false;
324  m_vertexSegmentEdit = false;
325  m_movePin = false;
326  m_allowMultiEdit = true;
327  m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_Select );
328  m_mode = mode_none;
329  m_canvasobject = 0;
330  m_modehit = 0;
331  m_endSegmentMode = a2dCanvasGlobals->GetHabitat()->GetEndSegmentMode();
332 
333  controller->SetDefaultBehavior( controller->GetDefaultBehavior() | wxTC_NoDefaultKeys | wxTC_NoDefaultMouseActions );
334 
335  m_eventHandler = new a2dStToolFixedToolStyleEvtHandler( controller );
336 
337  if ( GetDrawingPart()->GetDrawer2D()->HasAlpha() || GetDrawingPart()->GetTrippleBufHasAlpha() )
338  {
339  SetFill( a2dFill( wxColour( 66, 159, 235, 150 ) ) );
340  SetStroke( a2dStroke( wxColour( 66, 159, 235, 165 ), 2, a2dSTROKE_LONG_DASH ) );
341  m_selectFill = a2dFill( wxColour( 233, 15, 23, 150 ) );
342  m_selectStroke = a2dStroke( wxColour( 255, 59, 25, 255 ), 2, a2dSTROKE_LONG_DASH );
343  }
344  else
345  {
346  SetFill( *a2dTRANSPARENT_FILL );
347  SetStroke( a2dStroke( *wxBLACK, 2, a2dSTROKE_LONG_DASH ) );
348  m_selectFill = *a2dTRANSPARENT_FILL;
349  m_selectStroke = a2dStroke( *wxRED, 2, a2dSTROKE_LONG_DASH );
350  }
351 }
352 
354 {
355 }
356 
357 void a2dMasterDrawBase::SetLastSelected( a2dCanvasObject* lastSelect, bool onOff )
358 {
361  objects->SetSpecificFlags( false, a2dCanvasOFlags::SELECTED2 );
362  if ( lastSelect )
363  {
364  lastSelect->SetSelected2( onOff );
365  lastSelect->SetPending( true );
366  }
368 }
369 
370 void a2dMasterDrawBase::InitMouseEvent(wxMouseEvent& eventnew,
371  int x, int y,
372  wxMouseEvent& event )
373 {
374  eventnew.m_x = x;
375  eventnew.m_y = y;
376 
377  eventnew.m_shiftDown = event.m_shiftDown;
378  eventnew.m_controlDown = event.m_controlDown;
379  eventnew.m_leftDown = event.m_leftDown;
380  eventnew.m_middleDown = event.m_middleDown;
381  eventnew.m_rightDown = event.m_rightDown;
382  eventnew.m_altDown = event.m_altDown;
383  eventnew.SetEventObject(this);
384  eventnew.SetId( event.GetId());
385 
386 }
387 
389 {
391  if ( selected )
392  {
393  a2dAffineMatrix mat = selected->GetTransform();
394  if ( right )
395  GetCanvasCommandProcessor()->Submit( new a2dCommand_RotateMask( GetDrawingPart()->GetShowObject(), 90 ) );
396  else
397  GetCanvasCommandProcessor()->Submit( new a2dCommand_RotateMask( GetDrawingPart()->GetShowObject(), -90 ) );
398  return true;
399  }
400 
401  return false;
402 }
403 
404 void a2dMasterDrawBase::MouseDump( wxMouseEvent& event, wxString strinfo )
405 {
406  int x = event.GetX();
407  int y = event.GetY();
408  double xwprev, ywprev;
409  GetDrawingPart()->MouseToToolWorld( x, y, xwprev, ywprev );
410 
411  if ( event.LeftDown() )
412  strinfo << "LeftDown";
413  if ( event.LeftUp() )
414  strinfo << "LeftUp";
415  if ( event.LeftDClick() )
416  strinfo << "LeftDoubleClick";
417  if ( event.RightDClick() )
418  strinfo << "RightDoubleClick";
419  if ( event.Dragging() )
420  strinfo << "Dragging";
421  if ( event.Moving() )
422  strinfo << "Moving";
423 
424  if ( event.ShiftDown() )
425  strinfo << " s ";
426  if ( event.ControlDown() )
427  strinfo << " c ";
428  if ( event.AltDown() )
429  strinfo << " a ";
430 
431  wxLogDebug( strinfo );
432 
433 }
434 
435 void a2dMasterDrawBase::PushZoomTool()
436 {
438  if ( m_fastTools )
439  tool = new a2dZoomFast( GetStToolContr() );
440  else
441  tool = new a2dZoomTool( GetStToolContr() );
442 
443  tool->SetShowAnotation( m_anotate );
444  tool->SetOneShot();
445  tool->SetFill( m_fill );
446  tool->SetStroke( m_stroke );
447  m_controller->PushTool( tool );
448 }
449 
451 {
452  m_endSegmentMode = mode;
453 }
454 
455 void a2dMasterDrawBase::PushDrawWireTool( a2dCanvasObject* WXUNUSED( hit ) )
456 {
458  tool->SetEndSegmentMode( m_endSegmentMode );
459  tool->SetWiringMode( m_wiringMode );
460  tool->SetOneShot();
461  m_controller->PushTool( tool );
462 }
463 
464 void a2dMasterDrawBase::PushDragTool( a2dCanvasObject* hit )
465 {
466  SelectHitObject( hit );
468  if ( m_fastTools )
469  tool = new a2dDragTool( GetStToolContr(), NULL, m_xwprev, m_ywprev );
470  else
471  tool = new a2dDragTool( GetStToolContr(), NULL, m_xwprev, m_ywprev );
472 
473  // object without pins normal snap behaviour is in place, else only snap pins to target features.
474  if ( hit->HasPins() )
476 
477  tool->SetShowAnotation( m_anotate );
478  tool->SetOneShot();
479  tool->SetLateConnect( m_lateconnect );
480  tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
481  tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
482  tool->SetDeleteOnOutsideDrop( true );
483  m_controller->PushTool( tool );
484 
485  tool->StartDragging( m_x, m_y, hit );
486 }
487 
488 void a2dMasterDrawBase::PushDragMultiTool( a2dCanvasObject* hit, bool onlyKeys )
489 {
491  if ( m_fastTools )
492  tool = new a2dFastDragMultiTool( GetStToolContr() );
493  else
494  tool = new a2dDragMultiTool( GetStToolContr() );
495 
496  // object without pins normal snap behaviour is in place, else only snap pins to target features.
497  if ( hit->HasPins() )
499 
500  tool->SetShowAnotation( m_anotate );
501  tool->SetOneShot();
502  tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
503  tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
504  m_controller->PushTool( tool );
505  a2dDragMultiTool* mdt = wxDynamicCast( tool.Get(), a2dDragMultiTool );
506  if ( mdt )
507  {
508  mdt->SetOnlyKeys( onlyKeys );
509  mdt->SetLateConnect( m_lateconnect );
510  mdt->StartDragging( m_x, m_y, hit );
511  }
513  if ( mdt2 )
514  mdt2->StartDragging( m_x, m_y, hit );
515 }
516 
517 void a2dMasterDrawBase::PushCopyTool( a2dCanvasObject* hit )
518 {
519  SelectHitObject( hit );
521  if ( m_fastTools )
522  tool = new a2dCopyTool( GetStToolContr() );
523  else
524  tool = new a2dCopyTool( GetStToolContr() );
525 
526  tool->SetShowAnotation( m_anotate );
527  tool->SetOneShot();
528  tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
529  tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
530  tool->SetDeleteOnOutsideDrop( true );
531  m_controller->PushTool( tool );
532 }
533 
534 void a2dMasterDrawBase::PushCopyMultiTool( a2dCanvasObject* hit )
535 {
537  if ( m_fastTools )
538  tool = new a2dFastCopyMultiTool( GetStToolContr() );
539  else
540  tool = new a2dCopyMultiTool( GetStToolContr() );
541 
542  tool->SetShowAnotation( m_anotate );
543  tool->SetOneShot();
544  tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Copy ) );
545  tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Copy ) );
546  m_controller->PushTool( tool );
547  a2dCopyMultiTool* mdt = wxDynamicCast( tool.Get(), a2dCopyMultiTool );
548  if ( mdt )
549  mdt->StartDragging( m_x, m_y, hit );
551  if ( mdt2 )
552  mdt2->StartDragging( m_x, m_y, hit );
553 }
554 
555 void a2dMasterDrawBase::PushSelectTool()
556 {
558  if ( m_fastTools )
559  {
560  tool = new a2dFastSelect( GetStToolContr() );
561  ( ( a2dFastSelect* )tool.Get() )->SetShiftIsAdd();
562  }
563  else
564  {
565  tool = new a2dSelectTool( GetStToolContr() );
566  ( ( a2dSelectTool* )tool.Get() )->SetShiftIsAdd();
567  }
568 
569  tool->SetShowAnotation( m_anotate );
570  tool->SetOneShot();
571  tool->SetFill( m_selectFill );
572  tool->SetStroke( m_selectStroke );
573 
574  m_controller->PushTool( tool );
575 }
576 
577 void a2dMasterDrawBase::PushDeSelectTool()
578 {
580  if ( m_fastTools )
581  {
582  tool = new a2dFastSelect2( GetStToolContr() );
583  ( ( a2dFastSelect2* )tool.Get() )->SetSelectMode( false );
584  }
585  else
586  {
587  tool = new a2dFastSelect2( GetStToolContr() );
588  ( ( a2dFastSelect2* )tool.Get() )->SetSelectMode( false );
589  }
590  tool->SetShowAnotation( m_anotate );
591  tool->SetOneShot();
592  tool->SetFill( m_selectFill );
593  tool->SetStroke( m_selectStroke );
594 
595  m_controller->PushTool( tool );
596 }
597 
598 void a2dMasterDrawBase::PushEditWireVertexTool( a2dCanvasObject* hit, int vertex )
599 {
601  SelectHitObject( hit );
602  a2dSimpleEditPolygonTool* tool = new a2dSimpleEditPolygonTool( GetStToolContr(), hit, vertex, poly->GetSegments()->size(), a2dSimpleEditPolygonTool::action_movevertex );
603 
604  tool->SetShowAnotation( m_anotate );
605  tool->SetOneShot();
606  tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditVertex ) );
607  tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditVertex ) );
608  m_controller->PushTool( tool );
609 }
610 
611 void a2dMasterDrawBase::PushEditSegmentTool( a2dCanvasObject* hit, int segment )
612 {
614  SelectHitObject( hit );
615  a2dSimpleEditPolygonTool* tool = new a2dSimpleEditPolygonTool( GetStToolContr(), hit, segment, poly->GetSegments()->size(), a2dSimpleEditPolygonTool::action_movesegment );
616 
617  tool->SetShowAnotation( m_anotate );
618  tool->SetOneShot();
619  tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireSegment ) );
620  tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireSegment ) );
621  m_controller->PushTool( tool );
622 }
623 
624 void a2dMasterDrawBase::PushEditWireSegmentHorizontalTool( a2dCanvasObject* hit, int segment )
625 {
627  SelectHitObject( hit );
628  a2dSmrtPtr<a2dSimpleEditPolygonTool> tool = new a2dSimpleEditPolygonTool( GetStToolContr(), hit, segment, poly->GetSegments()->size(), a2dSimpleEditPolygonTool::action_movesegment );
629 
630  tool->SetShowAnotation( m_anotate );
631  tool->SetOneShot();
632  tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireSegmentHorizontal ) );
633  tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireSegmentHorizontal ) );
634  m_controller->PushTool( tool );
635 }
636 
637 void a2dMasterDrawBase::PushEditWireSegmentVerticalTool( a2dCanvasObject* hit, int segment )
638 {
640  SelectHitObject( hit );
641  a2dSmrtPtr<a2dSimpleEditPolygonTool> tool = new a2dSimpleEditPolygonTool( GetStToolContr(), hit, segment, poly->GetSegments()->size(), a2dSimpleEditPolygonTool::action_movesegment );
642 
643  tool->SetShowAnotation( m_anotate );
644  tool->SetOneShot();
645  tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireSegmentVertical ) );
646  tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireSegmentVertical ) );
647  m_controller->PushTool( tool );
648 }
649 
650 void a2dMasterDrawBase::PushEditWireSegmentInsertTool( a2dCanvasObject* hit, int segment )
651 {
653  SelectHitObject( hit );
654  a2dSmrtPtr<a2dSimpleEditPolygonTool> tool = new a2dSimpleEditPolygonTool( GetStToolContr(), hit, segment, poly->GetSegments()->size(), a2dSimpleEditPolygonTool::action_insertvertex );
655 
656  tool->SetShowAnotation( m_anotate );
657  tool->SetOneShot();
658  tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_WireSegmentInsert ) );
659  tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_WireSegmentInsert ) );
660  m_controller->PushTool( tool );
661 }
662 
663 void a2dMasterDrawBase::PushEditTool( a2dCanvasObject* hit )
664 {
665  SelectHitObject( hit );
666 
668 
669  tool->SetShowAnotation( m_anotate );
670  tool->SetOneShot();
671  tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditSegment ) );
672  tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditSegment ) );
673 
674  if ( hit )
675  {
676 
677  }
678  //tool->SetEvtHandler( m_eventHandler );
679 
680  m_stcontroller->PushTool( tool );
681  tool->StartToEdit( hit );
682 }
683 
684 void a2dMasterDrawBase::PushMultiEditTool( a2dCanvasObject* hit )
685 {
687 
688  tool->SetShowAnotation( m_anotate );
689  tool->StartEditingSelected();
690  tool->SetOneShot();
691  tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditSegment ) );
692  tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditSegment ) );
693  m_stcontroller->PushTool( tool );
694 }
695 
696 void a2dMasterDrawBase::PushMovePinTool( a2dCanvasObject* hit )
697 {
698  a2dPin* hitpin = wxStaticCast( hit, a2dPin );
700 
701  tool->SetShowAnotation( m_anotate );
702  tool->SetOneShot();
703  tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
704  tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
705  m_controller->PushTool( tool );
706 }
707 
708 void a2dMasterDrawBase::PushRewirePinTool( a2dCanvasObject* hit )
709 {
710  a2dPin* hitpin = wxStaticCast( hit, a2dPin );
711  a2dPin* wirePin = NULL;
712  if ( hitpin->GetParent()->IsConnect() )
713  wirePin = hitpin;
714  else
715  {
716  wirePin = hitpin->FindWirePin( a2dCanvasOFlags::SELECTED );
717  if ( !wirePin )
718  wirePin = hitpin->FindWirePin();
719  }
720 
722 
723  tool->SetShowAnotation( m_anotate );
724  tool->SetOneShot();
725  tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
726  tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
727  m_controller->PushTool( tool );
728 }
729 
730 void a2dMasterDrawBase::EditDlgOrHandles( a2dCanvasObject* hit, bool modifier, bool noHandleEditForWire )
731 {
732  if ( hit )
733  {
734  if ( m_dlgOrEdit && ! hit->GetFixedStyle() && !modifier )
735  {
736  /*
737  ClassXXX* xxx = wxDynamicCast( hit, ClassXXX );
738  if ( xxx )
739  {
740  hit->SetSelected( m_modehitLastSelectState );
741  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
742  m_mode = mode_edit;
743  PushEditTool( hit );
744  }
745  else */ if ( !m_dlgOrEditModal )
747  else if ( m_styleDlgSimple )
748  {
749  bool hitSel = hit->GetSelected();
750  hit->SetSelected( true );
751 
752  a2dExtFill eFi;
753  a2dExtStroke eSt;
754  a2dTextChanges eFo;
755  wxUint32 nrst = 0;
756  wxUint32 nrfi = 0;
757  wxUint32 nrfo = 0;
758  bool showStyleDlg = false;
759  bool showFontDlg = false;
760  bool withFill = false;
761 
763  a2dCanvasObjectList textobjects, primitiveobjects;
764 
765  //filter objects
766  forEachIn( a2dCanvasObjectList, objects )
767  {
768  a2dCanvasObject* obj = *iter;
769  a2dText* text = wxDynamicCast( obj, a2dText );
770 
771  if ( text )
772  textobjects.push_back( obj );
773  else
774  primitiveobjects.push_back( obj );
775  }
776 
777  if( wxDynamicCast( hit, a2dText ) ) // Text
778  {
779  showFontDlg = true;
780  objects = &textobjects;
781  }
782  else // Primitive
783  {
784  showStyleDlg = true;
785  objects = &primitiveobjects;
786  }
787 
788  //optional can be resolved with SetFixedStyle() on certain ta wires (TaPin.cpp)
789  //we do not want Tawire for Taco's to change in style, other ta wires are okay.
790  // a2dWirePolylineL* wire = wxDynamicCast( hit, a2dWirePolylineL );
791  //if ( wire && ( wire->GetStartPinClass() == a2dPin::XXXPinClass ) )
792  // showStyleDlg = false;
793 
794  nrst = a2dSetExtStroke( eSt, objects, a2dCanvasOFlags::SELECTED, GetDrawing()->GetLayerSetup() );
795  nrfi = a2dSetExtFill( eFi, objects, a2dCanvasOFlags::SELECTED, GetDrawing()->GetLayerSetup() );
796  nrfo = a2dSetTextChanges( eFo, objects, a2dCanvasOFlags::SELECTED, GetDrawing()->GetLayerSetup() );
797 
798  if ( nrst + nrfi == 0 )
799  {
800  //eFi.Set( hit->GetFill() );
801  //eSt.Set( hit->GetStroke() );
802  //withFill = true; // we want to be able to choose a fill
803  showStyleDlg = false;
804  }
805  else
806  withFill = 0 != nrfi;
807 
808  if( showFontDlg )
809  {
810  GetDrawingPart()->PushCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_WAIT ) );
811  a2dTextPropDlgExt dlg( GetDrawing()->GetHabitat(), NULL, false, withFill, eFo.GetFontInfoList(), false );
812  dlg.SetUnitsScale( GetDrawing()->GetUnitsScale() );
813  dlg.SetExtFill(eFi);
814  dlg.SetExtStroke(eSt);
815  dlg.SetExtFont(eFo);
816  //dlg.SetCustomColors( XXX.GetCustomColors());
817  if ( wxID_OK == dlg.ShowModal() )
818  {
819  eSt = dlg.GetExtStroke(); // get edited ExtStroke from dialog
820  eFi = dlg.GetExtFill(); // get edited ExtFill from dialog
821  eFo = dlg.GetExtFont(); // get edited ExtFont from dialog
822 
823  if ( !hit->GetSelected() )
824  {
825  hit->SetFill( eFi.Get( hit->GetFill() ) );
826  hit->SetStroke( eSt.Get( hit->GetStroke() ) );
827  //hit->SetFont( eFo.Get( hit->GetFont() ) ); //todo
828  }
829  else
830  {
832  GetDrawing()->GetCanvasCommandProcessor()->Submit( new a2dCommand_SetTextChangesMask( GetDrawingPart()->GetShowObject(), eFo, eFo.GetAlignment(), a2dCanvasOFlags::BIN2 ) );
833  }
834  }
835  // XXX.SetCustomColors(dlg.GetCustomColors());
837  }
838  else if ( showStyleDlg )
839  {
840  a2dDialogStyle dlg( NULL, false, withFill, false );
841  dlg.SetUnitsScale( GetDrawing()->GetUnitsScale() );
842  dlg.SetExtFill(eFi);
843  dlg.SetExtStroke(eSt);
844  //dlg.SetCustomColors( XXX.GetCustomColors());
845 
846  if ( wxID_OK == dlg.ShowModal() )
847  {
848  eSt = dlg.GetExtStroke(); // get edited ExtStroke from dialog
849  eFi = dlg.GetExtFill(); // get edited ExtFill from dialog
850 
851  if ( !hit->GetSelected() )
852  {
853  hit->SetFill( eFi.Get( hit->GetFill() ) );
854  hit->SetStroke( eSt.Get( hit->GetStroke() ) );
855  }
856  else
858  }
859  //XXX.SetCustomColors(dlg.GetCustomColors());
860  }
861  hit->SetSelected( hitSel );
862  objects->SetSpecificFlags( false, a2dCanvasOFlags::BIN2 );
863  }
864  else
865  {
866  a2dStyleDialog styleDlg( GetDrawing()->GetHabitat(), NULL, wxDEFAULT_DIALOG_STYLE | wxDIALOG_NO_PARENT | wxMINIMIZE_BOX | wxMAXIMIZE_BOX, true );
867  styleDlg.SetFill( hit->GetFill() );
868  styleDlg.SetStroke( hit->GetStroke() );
869  if ( styleDlg.ShowModal() == wxID_OK )
870  {
871  if ( !hit->GetSelected() )
872  {
873  hit->SetFill( styleDlg.GetFill() );
874  hit->SetStroke( styleDlg.GetStroke() );
875  }
876  else
878  }
879  }
880  }
881  else
882  {
884  if ( (wire && wire->GetSelected() ) || (wire && !noHandleEditForWire ) || !wire )
885  {
886  hit->SetSelected( m_modehitLastSelectState );
887  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
888  m_mode = mode_edit;
889  PushEditTool( hit );
890  }
891  }
892  }
893 }
894 
896 {
897  return true;
898 }
899 
901 {
902  a2dStTool::DoStopTool( abort );
903 }
904 
905 void a2dMasterDrawBase::OnChar( wxKeyEvent& event )
906 {
907  switch( event.GetKeyCode() )
908  {
909  case WXK_DELETE:
910  {
911  wxASSERT( m_parentobject == GetDrawingPart()->GetShowObject() );
912 
914 
915  GetDrawing()->GetHabitat()->GetConnectionGenerator()->SetPinsToBeginState( GetDrawingPart()->GetShowObject() );
916 
917  break;
918  }
919  case WXK_SPACE:
920  {
922  break;
923  }
924  default:
925  event.Skip();
926  }
927 
928 
930 
931  if ( selected )
932  {
933  switch( event.GetKeyCode() )
934  {
935  case WXK_ESCAPE:
936  {
937  DeselectAll();
938  break;
939  }
940  default:
941  event.Skip();
942  }
943  }
944  else
945  event.Skip();
946 
947 }
948 
949 
950 void a2dMasterDrawBase::OnKeyDown( wxKeyEvent& event )
951 {
952  //wxLogDebug(wxT("key %d"), event.GetKeyCode());
954 
955  switch( event.GetKeyCode() )
956  {
957  case WXK_ESCAPE:
958  {
959  if ( m_escapeToStopFirst && first && first->AllowPop() )
960  {
961  first->StopTool( true );
962  return;
963  }
964  }
965  break;
966  default:;
967  }
968 
969  if ( !m_active )
970  {
971  event.Skip();
972  return;
973  }
974 
975  //wxLogDebug(wxT("key %d"), event.GetKeyCode());
976 
977  switch( event.GetKeyCode() )
978  {
979  case WXK_CONTROL:
980  {
981  if ( !first || ( first && !first->GetBusy() ) )
982  {
983  if ( !wxDynamicCast( first.Get(), a2dDragTool ) )
984  {
985  //a2dDragTool* drag = new a2dDragTool(m_stcontroller);
986  //m_stcontroller->PushTool(drag);
987  //drag->SetOneShot();
988  }
989  }
990  }
991  break;
992  case 'p':
993  case 'P':
994  {
995  m_vertexSegmentEdit = true;
996  break;
997  }
998  case 'o':
999  case 'O':
1000  {
1001  m_movePin = true;
1002  break;
1003  }
1004  case 'Z':
1005  case 'z':
1006  {
1007  if ( !first || ( first && !first->GetBusy() ) )
1008  PushZoomTool();
1009  else
1010  event.Skip();
1011 
1012  break;
1013  }
1014  case 'r':
1015  case 'R':
1016  {
1017  GetDrawing()->GetHabitat()->GetConnectionGenerator()->RotateRouteMethod();
1018  break;
1019  }
1020  case 't':
1021  case 'T':
1022  {
1023  GetDrawing()->GetHabitat()->GetConnectionGenerator()->SetRouteWhenDrag( !GetDrawing()->GetHabitat()->GetConnectionGenerator()->GetRouteWhenDrag() );
1024  break;
1025  }
1026  case WXK_NUMPAD_ENTER:
1027  {
1029  break;
1030  }
1031  case WXK_NUMPAD_ADD:
1032  {
1033  if ( event.m_controlDown )
1035  else
1037  break;
1038  }
1039  case WXK_NUMPAD_SUBTRACT:
1040  {
1041  if ( event.m_controlDown )
1043  else
1045  break;
1046  }
1047  case WXK_SPACE:
1048  {
1049  m_spaceDown = true;
1050  m_mode = mode_zoom;
1051  m_modehit = NULL;
1052  event.Skip();
1053  break;
1054  }
1055  case WXK_UP:
1056  case WXK_DOWN:
1057  case WXK_LEFT:
1058  case WXK_RIGHT:
1059  {
1061  if ( selected )
1062  {
1063  int oldthres = 0;
1064  a2dRestrictionEngine* restrict = GetDrawing()->GetHabitat()->GetRestrictionEngine();
1065  if( restrict )
1066  {
1067  oldthres = restrict->GetSnapThresHold();
1068  restrict->SetSnapThresHold( 0 );
1069  }
1070  PushDragMultiTool( selected, true );
1072  if( restrict )
1073  restrict->SetSnapThresHold( oldthres );
1074  }
1075  break;
1076  }
1077  default:
1078  event.Skip();
1079  }
1080 }
1081 
1082 void a2dMasterDrawBase::OnKeyUp( wxKeyEvent& event )
1083 {
1084  if ( !m_active )
1085  {
1086  event.Skip();
1087  return;
1088  }
1089 
1090  switch( event.GetKeyCode() )
1091  {
1092  case 'p':
1093  case 'P':
1094  {
1095  m_vertexSegmentEdit = false;
1096  break;
1097  }
1098  case 'o':
1099  case 'O':
1100  {
1101  m_movePin = false;
1102  break;
1103  }
1104  default:
1105  event.Skip();
1106  }
1107 }
1108 
1109 
1110 void a2dMasterDrawBase::OnMouseEvent( wxMouseEvent& event )
1111 {
1112  if ( !m_active )
1113  {
1114  event.Skip();
1115  return;
1116  }
1117 /*
1118  m_x = event.GetX();
1119  m_y = event.GetY();
1120 
1121  GetDrawingPart()->MouseToToolWorld( m_x, m_y, m_xwprev, m_ywprev );
1122 */
1123  if( event.LeftDown() )//&& !GetBusy() )
1124  {
1125  // decide tool depending on mode
1126  switch( m_mode )
1127  {
1128  case mode_none:
1129  event.Skip();
1130  break;
1131  case mode_zoom:
1132  PushZoomTool();
1133  event.Skip();
1134  break;
1135  case mode_select:
1136  PushSelectTool();
1137  event.Skip();
1138  break;
1139  case mode_drag:
1140  PushDragTool( m_modehit );
1141  event.Skip();
1142  break;
1143  case mode_copy:
1144  PushCopyTool( m_modehit );
1145  event.Skip();
1146  break;
1147  case mode_dragmulti:
1148  PushDragMultiTool( m_modehit );
1149  event.Skip();
1150  break;
1151  case mode_copymulti:
1152  PushCopyMultiTool( m_modehit );
1153  event.Skip();
1154  break;
1155 
1156  case mode_move_pin:
1157  PushMovePinTool( m_modehit );
1158  event.Skip();
1159  break;
1160 
1161  case mode_drawwire:
1162  PushDrawWireTool( m_modehit );
1163  event.Skip();
1164  break;
1165  case mode_editwire_vertex:
1166  PushEditWireVertexTool( m_modehit, m_modehitinfo.m_index );
1167  event.Skip();
1168  break;
1169  case mode_editwire_segmenthorizontal:
1170  PushEditWireSegmentHorizontalTool( m_modehit, m_modehitinfo.m_index );
1171  event.Skip();
1172  break;
1173  case mode_editwire_segmentvertical:
1174  PushEditWireSegmentVerticalTool( m_modehit, m_modehitinfo.m_index );
1175  event.Skip();
1176  break;
1177  case mode_editwire_segmentinsert:
1178  PushEditWireSegmentInsertTool( m_modehit, m_modehitinfo.m_index );
1179  event.Skip();
1180  break;
1181  case mode_editwire_segment:
1182  PushEditSegmentTool( m_modehit, m_modehitinfo.m_index );
1183  event.Skip();
1184  break;
1185 
1186  default:
1187  m_mode = mode_none;
1188  event.Skip();
1189  }
1190  }
1191  else
1192  {
1193  event.Skip();
1194  }
1195 
1196 }
1197 
1198 void a2dMasterDrawBase::SelectHitObject( a2dCanvasObject* hit )
1199 {
1200  if ( m_select_undo )
1201  {
1202  OpenCommandGroupNamed( _( "Select" ) );
1203  DeselectAll();
1205  new a2dCommand_SetFlag( hit, a2dCanvasOFlags::SELECTED, true ) );
1207  }
1208  else
1209  {
1210  DeselectAll(); //delselect all needs last (selected2) to set also.
1211  hit->SetSelected( true );
1212  hit->SetSelected2( true );
1213  }
1214 }
1215 
1216 a2dCanvasObject* a2dMasterDrawBase::GetTopLeftSelected()
1217 {
1218  double xmin, ymax;
1219  xmin = DBL_MAX;
1220  ymax = DBL_MIN;
1221  a2dCanvasObject* topLeft = 0;
1222 
1223  a2dBoundingBox bbox;
1225  forEachIn( a2dCanvasObjectList, objects )
1226  {
1227  a2dCanvasObject* obj = *iter;
1228  if ( obj->GetRelease() || !obj->IsVisible() || !obj->GetSelected() )
1229  continue;
1230 
1231  if ( !topLeft )
1232  {
1233  topLeft = obj;
1234  xmin = obj->GetBboxMinX();
1235  ymax = obj->GetBboxMaxY();
1236  }
1237  else
1238  {
1239  if ( obj->GetBboxMinX() < xmin )
1240  {
1241  topLeft = obj;
1242  xmin = obj->GetBboxMinX();
1243  ymax = obj->GetBboxMaxY();
1244  }
1245  else if ( obj->GetBboxMinX() == xmin )
1246  {
1247  if ( obj->GetBboxMaxY() < ymax )
1248  {
1249  topLeft = obj;
1250  ymax = obj->GetBboxMaxY();
1251  }
1252  }
1253  }
1254  }
1255  return topLeft;
1256 }
1257 
1258 void a2dMasterDrawBase::SelectedStatus()
1259 {
1261 
1262  if ( bbox.GetValid() )
1263  {
1264  double unitScale = GetDrawing()->GetUnitsScale();
1265  wxString state, form;
1266  form = m_stcontroller->GetFormat() + " " + m_stcontroller->GetFormat();
1267  state.Printf( form, bbox.GetMinX()*unitScale, bbox.GetMinY()*unitScale );
1268  SetStateString( state, 10 );
1269  form = _T("width = ") + m_stcontroller->GetFormat() + _T(" height = ") + m_stcontroller->GetFormat();
1270  state.Printf( form, bbox.GetWidth()*unitScale, bbox.GetHeight()*unitScale );
1271  SetStateString( state, 11 );
1272  }
1273 }
1274 
1275 //----------------------------------------------------------------------------
1276 // a2dMasterDrawSelectFirst
1277 //----------------------------------------------------------------------------
1278 
1279 IMPLEMENT_CLASS( a2dMasterDrawSelectFirst, a2dMasterDrawBase )
1280 
1281 BEGIN_EVENT_TABLE( a2dMasterDrawSelectFirst, a2dMasterDrawBase )
1282  EVT_MOUSE_EVENTS( a2dMasterDrawSelectFirst::OnMouseEvent )
1283  EVT_CHAR( a2dMasterDrawSelectFirst::OnChar )
1284  EVT_KEY_DOWN( a2dMasterDrawSelectFirst::OnKeyDown )
1285  EVT_KEY_UP( a2dMasterDrawSelectFirst::OnKeyUp )
1286 END_EVENT_TABLE()
1287 
1288 a2dMasterDrawSelectFirst::a2dMasterDrawSelectFirst( a2dStToolContr* controller ): a2dMasterDrawBase( controller )
1289 {
1290  controller->SetDefaultBehavior( controller->GetDefaultBehavior() | wxTC_NoDefaultKeys | wxTC_NoDefaultMouseActions );
1291 }
1292 
1293 a2dMasterDrawSelectFirst::~a2dMasterDrawSelectFirst()
1294 {
1295 }
1296 
1297 void a2dMasterDrawSelectFirst::OnChar( wxKeyEvent& event )
1298 {
1299  switch( event.GetKeyCode() )
1300  {
1301  case WXK_SPACE:
1302  {
1303  break;
1304  }
1305  default:
1306  event.Skip();
1307  }
1308 }
1309 
1310 void a2dMasterDrawSelectFirst::OnKeyDown( wxKeyEvent& event )
1311 {
1312  if ( !m_active )
1313  {
1314  event.Skip();
1315  return;
1316  }
1317 
1318  //wxLogDebug(wxT("key %d"), event.GetKeyCode());
1320 
1321  switch( event.GetKeyCode() )
1322  {
1323  case WXK_SPACE:
1324  {
1325  m_spaceDown = true;
1326  m_mode = mode_zoom;
1327  m_modehit = NULL;
1328  break;
1329  }
1330  case WXK_CONTROL:
1331  {
1332  m_mode = mode_copy;
1333  m_modehit = NULL;
1334  break;
1335  }
1336  case WXK_SHIFT:
1337  {
1338  //DecideMode( m_modehit, true, false );
1339  break;
1340  }
1341  default:
1342  event.Skip();
1343  }
1344 }
1345 
1346 void a2dMasterDrawSelectFirst::OnKeyUp( wxKeyEvent& event )
1347 {
1348  if ( !m_active )
1349  {
1350  event.Skip();
1351  return;
1352  }
1353 
1354  switch( event.GetKeyCode() )
1355  {
1356  case WXK_SPACE:
1357  {
1358  m_spaceDown = false;
1359  m_mode = mode_zoom;
1360  m_modehit = NULL;
1361  break;
1362  }
1363  case WXK_SHIFT:
1364  {
1365  //DecideMode( m_modehit, false, false );
1366  break;
1367  }
1368  default:
1369  event.Skip();
1370  }
1371 }
1372 
1373 
1374 void a2dMasterDrawSelectFirst::DecideMode( a2dCanvasObject* hit, const a2dHitEvent& hitinfo, bool shift, bool control )
1375 {
1376  // show cursor different depending on the object hit, and set mode for tool to push in case of leftdown.
1377  m_mode = mode_select;
1378  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
1379  m_modehit = 0;
1380  m_modehitinfo = a2dHit();
1381 
1382  if ( m_spaceDown )
1383  {
1384  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Zoom ) );
1385  m_mode = mode_zoom;
1386  }
1387  else if( hit )
1388  {
1389  m_mode = mode_none;
1390  m_modehit = hit;
1391  GetDrawing()->GetHabitat()->GetConnectionGenerator()->SetPinsToBeginState( GetDrawingPart()->GetShowObject() );
1392  // Check if there is an unconnected pin
1393  // This has highest priority
1394  a2dPin* pin = NULL;
1395  a2dWirePolylineL* wire = 0;
1396  a2dHit how2;
1397 
1398  if ( m_vertexSegmentEdit )
1399  {
1400  int i;
1401  float minDist = FLT_MAX;
1402  for( i = 0; i < hitinfo.m_extended.size(); i++ )
1403  {
1404  a2dWirePolylineL* wire2 = wxDynamicCast( hitinfo.m_extended[i].GetObject(), a2dWirePolylineL );
1405  if( wire2 && hitinfo.m_extended[i].GetHitType().m_distance < minDist && hitinfo.m_extended[i].GetHitType().IsDirectStrokeHit() )
1406  {
1407  wire = wire2;
1408  how2 = hitinfo.m_extended[i].GetHitType();
1409  minDist = how2.m_distance;
1410  }
1411  }
1412 
1413  if ( wire )
1414  {
1415  // wire editing mode
1416  // check, where the wire was hit:
1417  m_modehit = wire;
1418  m_modehitinfo = how2;
1419  switch( how2.m_stroke2 )
1420  {
1421  case a2dHit::stroke2_vertex:
1422  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireVertex ) );
1423  m_mode = mode_editwire_vertex;
1424  break;
1425  case a2dHit::stroke2_edgehor:
1426  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireSegmentHorizontal ) );
1427  m_mode = mode_editwire_segmenthorizontal;
1428  break;
1429  case a2dHit::stroke2_edgevert:
1430  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireSegmentVertical ) );
1431  m_mode = mode_editwire_segmentvertical;
1432  break;
1433  case a2dHit::stroke2_edgeother:
1434  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_WireSegmentInsert ) );
1435  m_mode = mode_editwire_segmentinsert;
1436  break;
1437  default:
1438  assert( 0 );
1439  m_modehit = 0;
1440  m_modehitinfo = a2dHit();
1441  }
1442  }
1443  }
1444 
1445  // if not editing a wire, search for pins
1446  if ( m_mode == mode_none )
1447  {
1448  if ( !shift && !control )
1449  {
1450  //there is no wire nor pin yet, therefore we can just feedback possible pin connection, based on the
1451  // m_connectionGenerator.
1452  GetDrawing()->GetHabitat()->GetConnectionGenerator()->
1453  GeneratePinsToConnect( GetDrawingPart(), GetDrawingPart()->GetShowObject(), a2dPinClass::Any, a2d_GeneratePinsForStartWire, m_xwprev, m_ywprev );
1454 
1455  pin = GetDrawing()->GetHabitat()->GetConnectionGenerator()->
1456  SearchPinForStartWire( GetDrawingPart()->GetShowObject(), m_xwprev, m_ywprev, a2dPinClass::Any, GetHitMargin() );
1457  }
1458 
1459  if( pin )
1460  {
1461  if ( m_movePin )
1462  {
1463  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
1464  m_mode = mode_move_pin;
1465  m_modehit = pin;
1466  }
1467  else
1468  {
1469  // wire drawing mode
1470  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
1471  m_mode = mode_drawwire;
1472  m_modehit = pin;
1473  }
1474  }
1475  else
1476  {
1477  if ( !shift && hit->GetDraggable() && hit->GetSelected() )
1478  {
1479  if ( control )
1480  {
1481  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Copy ) );
1482  // copy selected mode
1483  m_mode = mode_copymulti;
1484  }
1485  else
1486  {
1487  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
1488  m_mode = mode_dragmulti;
1489  }
1490  }
1491  else if ( shift && hit->GetDraggable() )
1492  {
1493  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
1494  m_mode = mode_select;
1495  }
1496  else
1497  m_mode = mode_select;
1498 
1499  }
1500 
1501  }
1502  }
1503  else
1504  GetDrawingPart()->SetCursor( m_toolcursor );
1505 }
1506 
1507 void a2dMasterDrawSelectFirst::OnMouseEvent( wxMouseEvent& event )
1508 {
1509  if ( !m_active )
1510  {
1511  event.Skip();
1512  return;
1513  }
1514  m_x = event.GetX();
1515  m_y = event.GetY();
1516 
1518 
1520  a2dIterC ic( GetDrawingPart() );
1521  ic.SetLayer( wxLAYER_ALL );
1522  ic.SetObjectFilter( new a2dCanvasObjectFilterLayerMask( wxLAYER_ALL, a2dCanvasOFlags::VISIBLE | a2dCanvasOFlags::SELECTABLE ) );
1523  a2dHitEvent hitinfo( m_xwprev, m_ywprev, false, a2dCANOBJHITOPTION_NONE, true );
1525  if ( event.ShiftDown() && event.ControlDown() )
1527  //at the top level the group its matrix is to be ignored.
1528  //Since it is normally NOT ignored within a2dCanvasObject, force an inverse.
1529  hitinfo.m_xyRelToChildren = true;
1530  a2dCanvasObject* hit = GetDrawingPart()->GetShowObject()->ChildIsHitWorld( ic, hitinfo, true );
1531 
1532  // if left double click and hit on a selected object, go and edit it
1533  if ( hit && event.LeftDClick() && !GetBusy() )
1534  {
1535  int i = 0;
1536  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW ) );
1537  m_modehit = hit;
1539  forEachIn( a2dCanvasObjectList, objects )
1540  {
1541  a2dCanvasObject* obj = *iter;
1542  if ( obj->GetSelected() )
1543  i++;
1544  }
1545 
1546  if ( i <= 1 )
1547  {
1548  m_mode = mode_edit;
1549  PushEditTool( m_modehit );
1550  }
1551  else
1552  {
1553  m_mode = mode_multiedit;
1554  PushMultiEditTool( m_modehit );
1555  }
1556  }
1557  else if ( event.Moving() && !GetBusy() )
1558  {
1559  DecideMode( hit, hitinfo, event.ShiftDown(), event.ControlDown() );
1560  event.Skip();
1561  }
1562  else if( event.LeftDown() && !GetBusy() )
1563  {
1564  // decide tool depending on mode
1565  switch( m_mode )
1566  {
1567  case mode_none:
1568  event.Skip();
1569  break;
1570  case mode_dragmulti:
1571  PushDragMultiTool( NULL );//m_modehit );
1572  event.Skip();
1573  break;
1574  case mode_copymulti:
1575  PushCopyMultiTool( NULL );// m_modehit );
1576  event.Skip();
1577  break;
1578  event.Skip();
1579  break;
1580  case mode_zoomdrag:
1581  break;
1582  case mode_zoom:
1583  case mode_select:
1584  event.Skip();
1585  break;
1586  case mode_drag:
1587  case mode_copy:
1588  break;
1589  case mode_move_pin:
1590  case mode_drawwire:
1591  case mode_editwire_vertex:
1592  case mode_editwire_segmenthorizontal:
1593  case mode_editwire_segmentvertical:
1594  case mode_editwire_segmentinsert:
1595  case mode_editwire_segment:
1596  event.Skip();
1597  break;
1598 
1599  default:
1600  m_mode = mode_none;
1601  event.Skip();
1602  }
1603 
1604  }
1605  else if( event.RightDown() && !GetBusy() )
1606  {
1607  PushZoomTool();
1608  event.Skip();
1609  }
1610  else
1611  {
1612  event.Skip();
1613  }
1614 }
1615 
1616 //----------------------------------------------------------------------------
1617 // a2dMasterDrawZoomFirst
1618 //----------------------------------------------------------------------------
1619 
1620 IMPLEMENT_CLASS( a2dMasterDrawZoomFirst, a2dMasterDrawBase )
1621 
1622 BEGIN_EVENT_TABLE( a2dMasterDrawZoomFirst, a2dMasterDrawBase )
1623  EVT_MOUSE_EVENTS( a2dMasterDrawZoomFirst::OnMouseEvent )
1624  EVT_CHAR( a2dMasterDrawZoomFirst::OnChar )
1625  EVT_KEY_DOWN( a2dMasterDrawZoomFirst::OnKeyDown )
1626  EVT_KEY_UP( a2dMasterDrawZoomFirst::OnKeyUp )
1627 END_EVENT_TABLE()
1628 
1629 a2dMasterDrawZoomFirst::a2dMasterDrawZoomFirst( a2dStToolContr* controller ): a2dMasterDrawBase( controller )
1630 {
1631  controller->SetDefaultBehavior( controller->GetDefaultBehavior() | wxTC_NoDefaultKeys | wxTC_NoDefaultMouseActions );
1632  m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_Zoom );
1633 }
1634 
1635 a2dMasterDrawZoomFirst::~a2dMasterDrawZoomFirst()
1636 {
1637 }
1638 
1640 {
1641 }
1642 
1644 {
1646  m_toolBusy = false;
1647 }
1648 
1650 {
1652 
1653  if ( selected )
1654  {
1655  DeselectAll();
1656  }
1657  if( GetBusy() && m_dragStarted )
1658  {
1659  switch( m_mode )
1660  {
1661  case mode_zoom:
1662  case mode_select:
1663  case mode_cntrlselect:
1664  {
1665  a2dRect* rec = wxStaticCast( m_canvasobject.Get(), a2dRect );
1669  break;
1670  }
1671  default:
1672  break;
1673  }
1674  }
1675 
1677 }
1678 
1679 void a2dMasterDrawZoomFirst::OnChar( wxKeyEvent& event )
1680 {
1681  //wxLogDebug(wxT("key %d"), event.GetKeyCode());
1683 
1685 
1686  if ( selected )
1687  {
1688  event.Skip();
1689  }
1690  else if( GetBusy() && m_dragStarted )
1691  {
1692  switch( m_mode )
1693  {
1694  case mode_zoom:
1695  case mode_select:
1696  case mode_cntrlselect:
1697  {
1698  a2dRect* rec = wxStaticCast( m_canvasobject.Get(), a2dRect );
1701  FinishBusyMode();
1703  break;
1704  }
1705  default:
1706  event.Skip();
1707  break;
1708  }
1709  }
1710  else
1711  event.Skip();
1712 }
1713 
1714 void a2dMasterDrawZoomFirst::OnKeyDown( wxKeyEvent& event )
1715 {
1716  if ( !m_active )
1717  {
1718  event.Skip();
1719  return;
1720  }
1721 
1722  //wxLogDebug(wxT("key %d"), event.GetKeyCode());
1724 
1725  switch( event.GetKeyCode() )
1726  {
1727  case WXK_SPACE:
1728  {
1729  m_spaceDown = true;
1730  m_mode = mode_zoom;
1731  m_modehit = NULL;
1732  break;
1733  }
1734  default:
1735  event.Skip();
1736  }
1737 
1738 }
1739 
1740 void a2dMasterDrawZoomFirst::OnKeyUp( wxKeyEvent& event )
1741 {
1742  if ( !m_active )
1743  {
1744  event.Skip();
1745  return;
1746  }
1747 
1748  switch( event.GetKeyCode() )
1749  {
1750  case WXK_SPACE:
1751  {
1752  m_spaceDown = false;
1753  m_mode = mode_zoom;
1754  m_modehit = NULL;
1755  break;
1756  }
1757  default:
1758  event.Skip();
1759  }
1760 
1761 }
1762 
1763 void a2dMasterDrawZoomFirst::OnMouseEvent( wxMouseEvent& event )
1764 {
1765  if ( !m_active )
1766  {
1767  event.Skip();
1768  return;
1769  }
1770  m_x = event.GetX();
1771  m_y = event.GetY();
1772 
1774 
1775  //GetDrawingPart()->Update( a2dCANVIEW_UPDATE_PENDING );
1776  a2dIterC ic( GetDrawingPart() );
1777  ic.SetLayer( wxLAYER_ALL );
1778  ic.SetObjectFilter( new a2dCanvasObjectFilterLayerMask( wxLAYER_ALL, a2dCanvasOFlags::VISIBLE | a2dCanvasOFlags::SELECTABLE ) );
1779  a2dHitEvent hitinfo( m_xwprev, m_ywprev, false, a2dCANOBJHITOPTION_NONE, true );
1781  //at the top level the group its matrix is to be ignored.
1782  //Since it is normally NOT ignored within a2dCanvasObject, force an inverse.
1783  hitinfo.m_xyRelToChildren = true;
1784 
1785  if ( event.LeftDClick() && !m_toolBusy && !GetBusy() )
1786  {
1787  a2dCanvasObject* hit = m_modehit; //reuse from the LeftDown event.
1788  if ( hit )
1789  {
1790  hit->SetSelected( m_modehitLastSelectState );
1791  int i = 0;
1792  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
1793  m_modehit = hit;
1795  forEachIn( a2dCanvasObjectList, objects )
1796  {
1797  a2dCanvasObject* obj = *iter;
1798  if ( obj->GetSelected() )
1799  i++;
1800  }
1801 
1802  if ( i > 1 && m_allowMultiEdit )
1803  {
1804  m_mode = mode_multiedit;
1805  PushMultiEditTool( m_modehit );
1806  }
1807  else
1808  {
1809  /*
1810  if ( event.ControlDown() )
1811  {
1812  wxURI uri = hit->GetURI();
1813  wxString link = uri.BuildURI();
1814  if ( !link.IsEmpty() )
1815  {
1816  wxString file = link;
1817  wxString scheme = uri.GetScheme();
1818  if ( scheme == wxT( "file" ) )
1819  {
1820  wxRegEx reVolume( wxT("^\\/[a-fA-F].*$") );
1821  file = uri.GetPath();
1822  if ( reVolume.Matches( file ) )
1823  file = file.Mid( 1 );
1824  }
1825 
1826  if ( !::wxFileExists( file ) )
1827  {
1828  file = *( a2dGeneralGlobals->GetVariablesHash().GetVariableString( wxT( "APPLICATION_DATA" ) ) ) + wxFileName::GetPathSeparator() + file;
1829  if ( !::wxFileExists( file ) )
1830  {
1831  //a2dGeneralGlobals->ReportErrorF( a2dError_FileCouldNotOpen, _( "Sorry, could not open file %s" ), file.c_str() );
1832  a2dDocumentPtr doc;
1833  a2dError res = a2dDocviewGlobals->GetDocviewCommandProcessor()->FileNew( doc );
1834  doc->SetTitle( file, true );
1835  doc->SetFilename( wxFileName( file ), true );
1836  return;
1837  }
1838  }
1839  a2dDocumentPtr doc;
1840  a2dDocviewGlobals->GetDocviewCommandProcessor()->FileOpenCheck( doc, file, true );
1841  }
1842  }
1843  else
1844  */
1845  {
1846  m_mode = mode_edit;
1847  PushEditTool( m_modehit );
1848  }
1849  }
1850  }
1851  }
1852  else if ( event.Dragging() && m_toolBusy && !m_dragStarted && !event.AltDown() )
1853  {
1854  if ( abs( m_x - m_dragstartx ) >= 5 || abs( m_y - m_dragstarty ) >= 5 )
1855  {
1856  a2dCanvasObject* hit = m_modehit; //use last hit at LeftDown
1857  if ( event.ControlDown() && !event.ShiftDown() )
1858  {
1859  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
1860  m_mode = mode_cntrlselect;
1861  }
1862  else if ( !event.ControlDown() && event.ShiftDown() )
1863  {
1864  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
1865  m_mode = mode_select;
1866  }
1867  else
1868  {
1869  if( hit && hit->GetDraggable() && hit->GetSelected() )
1870  {
1871  if ( event.ControlDown() && event.ShiftDown() )
1872  {
1873  m_mode = mode_copymulti;
1874  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Copy ) );
1875  }
1876  else //no shift no control
1877  {
1878  m_mode = mode_dragmulti;
1879  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
1880  }
1881  }
1882  else
1883  {
1884  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Zoom ) );
1885  m_mode = mode_zoom;
1886  m_modehit = hit;//NULL;
1887  }
1888  }
1889 
1890  switch( m_mode )
1891  {
1892  case mode_zoom:
1893  case mode_select:
1894  case mode_cntrlselect:
1895  {
1896  m_dragStarted = true;
1898  GetDrawingPart()->SetOverlayDrawStyle( RenderLAYERED );
1900 
1901  a2dRect* rec = new a2dRect( m_xwprev, m_ywprev , 0, 0, 0 );
1902  m_canvasobject = rec;
1903  if ( m_mode == mode_select || m_mode == mode_cntrlselect )
1904  {
1905  rec->SetFill( m_selectFill );
1906  rec->SetStroke( m_selectStroke );
1907  }
1908  else
1909  {
1910  rec->SetFill( m_fill );
1911  rec->SetStroke( m_stroke );
1912  }
1915  if ( GetDrawingPart()->GetTrippleBuf() )
1916  GetDrawingPart()->AddOverlayObject( rec );
1917  else
1918  GetDrawingPart()->AddOverlayObject( rec );
1919  //AddDecorationObject( rec );
1920  GetDrawing()->SetIgnorePendingObjects( false );
1921  GetDrawingPart()->AddOverlayAreas( true );
1922  m_pending = true;
1923  event.Skip();
1924  EnterBusyMode();
1925  break;
1926  }
1927  case mode_dragmulti:
1928  {
1929  m_dragStarted = true;
1930  PushDragMultiTool( m_modehit );
1931  event.Skip();
1932  break;
1933  }
1934  case mode_copymulti:
1935  {
1936  m_dragStarted = true;
1937  PushCopyMultiTool( m_modehit );
1938  event.Skip();
1939  break;
1940  }
1941  default:
1942  break;
1943  }
1944  }
1945  }
1946  else if ( event.Dragging() && m_toolBusy && m_dragStarted )
1947  {
1948  switch( m_mode )
1949  {
1950  case mode_zoom:
1951  case mode_select:
1952  case mode_cntrlselect:
1953  {
1954  a2dRect* rec = wxStaticCast( m_canvasobject.Get(), a2dRect );
1955 
1957 
1959  rec->SetWidth( m_xwprev - rec->GetPosX() );
1960  rec->SetHeight( m_ywprev - rec->GetPosY() );
1961  rec->SetPending( true );
1962  GetDrawing()->SetIgnorePendingObjects( false );
1963  GetDrawingPart()->AddOverlayAreas( true );
1964  //m_pending = true;
1965  break;
1966  }
1967  default:
1968  break;
1969  }
1970  }
1971 /*
1972  else if ( event.Moving() && !GetBusy() && event.AltDown() )
1973  {
1974  // show cursor different depending on the object hit, and set mode for tool to push in case of leftdown.
1975  m_mode = mode_none;
1976  m_modehit = 0;
1977  m_modehitinfo = a2dHit();
1978  a2dCanvasObject* hit = GetDrawingPart()->GetShowObject()->ChildIsHitWorld( ic, hitinfo, true );
1979 
1980  if( hit && hit->GetDraggable() && hit->GetSelected() )
1981  {
1982  m_modehit = hit;
1983  if( event.ControlDown() )
1984  {
1985  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Copy ) );
1986  m_mode = mode_copymulti;
1987  }
1988  else
1989  {
1990  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
1991  m_mode = mode_dragmulti;
1992  }
1993  }
1994  event.Skip();
1995  }
1996 */
1997  else if ( event.Moving() && !GetBusy() )
1998  {
1999  m_mode = mode_none;
2000  m_modehit = 0;
2001  m_modehitinfo = a2dHit();
2002 
2003  if ( event.ControlDown() && !event.ShiftDown() )
2004  {
2005  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
2006  a2dCanvasObject* hit = GetDrawingPart()->GetShowObject()->ChildIsHitWorld( ic, hitinfo, true );
2007  GetDrawing()->GetHabitat()->GetConnectionGenerator()->SetPinsToBeginState( GetDrawingPart()->GetShowObject() );
2008  if ( hit )
2009  m_modehit = hit;
2010  m_mode = mode_cntrlselect;
2011  }
2012  else if ( !event.ControlDown() && event.ShiftDown() )
2013  {
2014  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
2015  a2dCanvasObject* hit = GetDrawingPart()->GetShowObject()->ChildIsHitWorld( ic, hitinfo, true );
2016  GetDrawing()->GetHabitat()->GetConnectionGenerator()->SetPinsToBeginState( GetDrawingPart()->GetShowObject() );
2017  if ( hit )
2018  m_modehit = hit;
2019  m_mode = mode_select;
2020  }
2021  else
2022  {
2023  a2dCanvasObject* hit = GetDrawingPart()->GetShowObject()->ChildIsHitWorld( ic, hitinfo, true );
2024  GetDrawing()->GetHabitat()->GetConnectionGenerator()->SetPinsToBeginState( GetDrawingPart()->GetShowObject() );
2025  if ( hit )
2026  {
2027  // Check if there is an unconnected pin
2028  // This has highest priority
2029  a2dPin* pin = NULL;
2030  a2dWirePolylineL* wire = 0;
2031  a2dHit how2;
2032 
2033  if ( m_vertexSegmentEdit )
2034  {
2035  int i;
2036  float minDist = FLT_MAX;
2037  for( i = 0; i < hitinfo.m_extended.size(); i++ )
2038  {
2039  a2dWirePolylineL* wire2 = wxDynamicCast( hitinfo.m_extended[i].GetObject(), a2dWirePolylineL );
2040  if( wire2 && hitinfo.m_extended[i].GetHitType().m_distance < minDist && hitinfo.m_extended[i].GetHitType().IsDirectStrokeHit() )
2041  {
2042  wire = wire2;
2043  how2 = hitinfo.m_extended[i].GetHitType();
2044  minDist = how2.m_distance;
2045  }
2046  }
2047 
2048  if ( wire )
2049  {
2050  // wire editing mode
2051  // check, where the wire was hit:
2052  m_modehit = wire;
2053  m_modehitinfo = how2;
2054  switch( how2.m_stroke2 )
2055  {
2056  case a2dHit::stroke2_vertex:
2057  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireVertex ) );
2058  m_mode = mode_editwire_vertex;
2059  break;
2060  case a2dHit::stroke2_edgehor:
2061  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireSegmentHorizontal ) );
2062  m_mode = mode_editwire_segmenthorizontal;
2063  break;
2064  case a2dHit::stroke2_edgevert:
2065  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireSegmentVertical ) );
2066  m_mode = mode_editwire_segmentvertical;
2067  break;
2068  case a2dHit::stroke2_edgeother:
2069  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_WireSegmentInsert ) );
2070  m_mode = mode_editwire_segmentinsert;
2071  break;
2072  default:
2073  assert( 0 );
2074  m_modehit = 0;
2075  m_modehitinfo = a2dHit();
2076  }
2077  }
2078  }
2079 
2080  // if not editing a wire, search for pins
2081  if ( m_mode == mode_none )
2082  {
2083  if ( !event.ShiftDown() && !event.ControlDown() )
2084  {
2085  //there is no wire nor pin yet, therefore we can just feedback possible pin connection, based on the
2086  // m_connectionGenerator.
2087  GetDrawing()->GetHabitat()->GetConnectionGenerator()->
2089 
2090  pin = GetDrawing()->GetHabitat()->GetConnectionGenerator()->
2091  SearchPinForStartWire( GetDrawingPart()->GetShowObject(), m_xwprev, m_ywprev, a2dPinClass::Any, GetHitMargin() );
2092 
2093  if ( pin )
2094  {
2096  if ( wire && wire->GetSelected() || m_vertexSegmentEdit )
2097  pin = NULL;
2098  }
2099  }
2100 
2101  if( pin )
2102  {
2103  if ( m_movePin )
2104  {
2105  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
2106  m_mode = mode_move_pin;
2107  m_modehit = pin;
2108  }
2109  else
2110  {
2111  // wire drawing mode
2112  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
2113  m_mode = mode_drawwire;
2114  m_modehit = pin;
2115  }
2116  }
2117  else
2118  {
2119  if( hit->GetDraggable() && hit->GetSelected() )
2120  {
2121  m_modehit = hit;
2122  if ( event.ControlDown() && event.ShiftDown() )
2123  {
2124  m_mode = mode_copymulti;
2125  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Copy ) );
2126  }
2127  else //no shift no control
2128  {
2129  m_mode = mode_dragmulti;
2130  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
2131  }
2132  }
2133  else
2134  {
2135  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Zoom ) );
2136  m_mode = mode_zoom;
2137  m_modehit = hit;
2138  }
2139  }
2140  }
2141  }
2142  else
2143  GetDrawingPart()->SetCursor( m_toolcursor );
2144  }
2145  event.Skip();
2146  }
2147  else if( event.LeftDown() && !GetBusy() )
2148  {
2149  a2dCanvasObject* hit = m_modehit;
2150 
2151  m_dragStarted = false;
2152  m_xprev = m_x;
2153  m_yprev = m_y;
2154  m_dragstartx = m_x;
2155  m_dragstarty = m_y;
2156  m_toolBusy = true;
2157 
2158  if( !hit )
2159  {
2160  m_mode = mode_none;
2161  event.Skip();
2162  return;
2163  }
2164 
2165  switch( m_mode )
2166  {
2167  case mode_drag:
2168  case mode_copy:
2169  case mode_dragmulti:
2170  case mode_copymulti:
2171  m_mode = mode_none;
2172  event.Skip();
2173  break;
2174 
2175  case mode_move_pin:
2176  case mode_drawwire:
2177  case mode_editwire_vertex:
2178  case mode_editwire_segmenthorizontal:
2179  case mode_editwire_segmentvertical:
2180  case mode_editwire_segmentinsert:
2181  case mode_editwire_segment:
2182  event.Skip();
2183  break;
2184 
2185  default:
2186  m_mode = mode_none;
2187  event.Skip();
2188  }
2189  }
2190  else if( event.LeftUp() && GetBusy() && m_dragStarted )
2191  {
2192  m_toolBusy = false;
2193  m_dragStarted = false;
2194  switch( m_mode )
2195  {
2196  case mode_zoom:
2197  {
2198  a2dRect* rec = wxStaticCast( m_canvasobject.Get(), a2dRect );
2199 
2200  double w = GetDrawer2D()->WorldToDeviceXRel( rec->GetWidth() );
2201  double h = GetDrawer2D()->WorldToDeviceYRel( rec->GetHeight() );
2202 
2204  double x1 = rec->GetBbox().GetMinX();
2205 
2206  double y1 = rec->GetBbox().GetMinY();
2207 
2208  //Get the current window size to put on zoomstack
2209  a2dBoundingBox* bbox = new a2dBoundingBox( GetDrawer2D()->GetVisibleMinX(),
2210  GetDrawer2D()->GetVisibleMinY(),
2211  GetDrawer2D()->GetVisibleMaxX(),
2212  GetDrawer2D()->GetVisibleMaxY()
2213  );
2214 
2215  m_stcontroller->GetZoomList().Insert( bbox );
2216  GetDrawer2D()->SetMappingWidthHeight( x1, y1, fabs( rec->GetWidth() ), fabs( rec->GetHeight() ) );
2217 
2218  FinishBusyMode();
2220 
2221  event.Skip();
2222  break;
2223  }
2224  case mode_select:
2225  {
2226  SetIgnorePendingObjects( false );
2227 
2228  a2dRect* rec = wxStaticCast( m_canvasobject.Get(), a2dRect );
2231 
2235  .x1( rec->GetBbox().GetMinX() )
2236  .y1( rec->GetBbox().GetMinY() )
2237  .x2( rec->GetBbox().GetMaxX() )
2238  .y2( rec->GetBbox().GetMaxY() )
2239  )
2240  );
2241  FinishBusyMode();
2243  event.Skip();
2244  break;
2245  }
2246  case mode_cntrlselect:
2247  {
2248  DeselectAll();
2249  SetIgnorePendingObjects( false );
2250 
2251  a2dRect* rec = wxStaticCast( m_canvasobject.Get(), a2dRect );
2254 
2258  .x1( rec->GetBbox().GetMinX() )
2259  .y1( rec->GetBbox().GetMinY() )
2260  .x2( rec->GetBbox().GetMaxX() )
2261  .y2( rec->GetBbox().GetMaxY() )
2262  )
2263  );
2264  FinishBusyMode();
2266  event.Skip();
2267  break;
2268  }
2269  default:
2270  break;
2271  }
2272  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Zoom ) );
2273  }
2274  else if( event.LeftUp() && m_toolBusy )
2275  {
2276  m_toolBusy = false;
2277  //reserve for double click if it happens
2278  m_modehitLastSelectState = false;
2279  if ( m_modehit )
2280  m_modehitLastSelectState = m_modehit->GetSelected();
2281 
2282 
2283  if ( event.ControlDown() )
2284  {
2285  DeselectAll();
2286  if ( m_modehit && m_modehit->GetSelectable() )
2287  m_modehit->SetSelected( true );
2288  }
2289  else if ( event.ShiftDown() )
2290  {
2291  if ( m_modehit && m_modehit->GetSelectable() )
2292  m_modehit->SetSelected( true );
2293  }
2294  else
2295  {
2296  if ( !m_modehit )
2297  DeselectAll();
2298  else
2299  {
2300  if ( m_modehit->GetSelected() )
2301  {
2302  if ( m_mode == mode_none && m_modehit->GetSelectable() )
2303  m_modehit->SetSelected( ! m_modehit->GetSelected() );
2304  }
2305  else
2306  {
2307  if ( m_mode == mode_none && m_modehit->GetSelectable() )
2308  {
2310  if ( selected )
2311  {
2312  DeselectAll();
2313  m_modehit->SetSelected( true );
2314  }
2315  else
2316  {
2317  m_modehit->SetSelected( true );
2318  }
2319  }
2320  }
2321  }
2322  }
2323  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Zoom ) );
2324  }
2325  else if( event.RightDown() && !GetBusy() )
2326  {
2327  PushZoomTool();
2328  event.Skip();
2329  }
2330  else
2331  {
2332  event.Skip();
2333  }
2334 }
2335 
2336 //----------------------------------------------------------------------------
2337 // a2dToolProperty
2338 //----------------------------------------------------------------------------
2339 
2340 const long SUBMASTER_PUSHTOOL = wxNewId();
2341 const long SUBMASTER_MENUTOOL_DRAG = wxNewId();
2342 const long SUBMASTER_MENUTOOL_REC = wxNewId();
2343 const long SUBMASTER_MENUTOOL_EDIT = wxNewId();
2344 
2345 //----------------------------------------------------------------------------
2346 // a2dSubDrawMasterTool
2347 //----------------------------------------------------------------------------
2348 
2349 IMPLEMENT_DYNAMIC_CLASS( a2dSubDrawMasterTool, a2dStTool )
2350 
2351 BEGIN_EVENT_TABLE( a2dSubDrawMasterTool, a2dStTool )
2352  EVT_MOUSE_EVENTS( a2dSubDrawMasterTool::OnMouseEvent )
2353  EVT_CHAR( a2dSubDrawMasterTool::OnChar )
2354 END_EVENT_TABLE()
2355 
2356 a2dSubDrawMasterTool::a2dSubDrawMasterTool( a2dStToolContr* controller ): a2dStTool( controller )
2357 {
2358  m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW );
2359  m_mode = 0;
2360  m_canvasobject = 0;
2361 
2362  m_mousemenu = new wxMenu( _( "Tool menu" ), ( long )0 );
2363 
2364  a2dSmrtPtr<a2dDragTool> tool = new a2dDragTool( controller );
2365  tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW ) );
2366  tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_HAND ) );
2367  tool->SetDeleteOnOutsideDrop( false );
2368  AppendTool( tool, new wxMenuItem( m_mousemenu, SUBMASTER_MENUTOOL_DRAG, _( "drag" ), _( "pushes drag tool" ) ), 'd' );
2369 
2370  a2dSmrtPtr<a2dRecursiveEditTool> edit = new a2dRecursiveEditTool( controller );
2371  edit->SetCorridor( m_corridor );
2372  AppendTool( edit, new wxMenuItem( m_mousemenu, SUBMASTER_MENUTOOL_EDIT, _( "edit" ), _( "pushes edit tool" ) ), 'e' );
2373 
2374  a2dSmrtPtr<a2dDrawRectangleTool> drawrec = new a2dDrawRectangleTool( controller );
2375  drawrec->SetEditAtEnd( true );
2376  AppendTool( drawrec, new wxMenuItem( m_mousemenu, SUBMASTER_MENUTOOL_REC, _( "draw rectangle" ), _( "pushes draw rectangle tool" ) ), 'r' );
2377 
2378  m_curTool = drawrec;
2379 }
2380 
2381 a2dSubDrawMasterTool::~a2dSubDrawMasterTool()
2382 {
2383 }
2384 
2385 void a2dSubDrawMasterTool::OnPostPushTool()
2386 {
2387  m_curTool->SetCorridor( m_corridor );
2388  m_controller->PushTool( m_curTool );
2389 }
2390 
2391 void a2dSubDrawMasterTool::AppendTool( a2dBaseTool* tool, wxMenuItem* menuItem, wxChar key )
2392 {
2393  //SetProperty( new a2dToolProperty( PROPID_toolMenu, tool, menuItem, key ) );
2394  m_mousemenu->Append( menuItem );
2395 }
2396 
2398 {
2399  return true;
2400 }
2401 
2403 {
2404  a2dStTool::DoStopTool( abort );
2405 }
2406 
2407 void a2dSubDrawMasterTool::OnChar( wxKeyEvent& WXUNUSED( event ) )
2408 {
2409  //switch( event.GetKeyCode() )
2410  //{
2411  //}
2412 }
2413 
2414 void a2dSubDrawMasterTool::OnMouseEvent( wxMouseEvent& event )
2415 {
2416  if ( !m_active )
2417  {
2418  event.Skip();
2419  return;
2420  }
2421  m_x = event.GetX();
2422  m_y = event.GetY();
2423 
2424  //to world coordinates to do hit test in world coordinates
2425  double xw;
2426  double yw;
2427 
2428  xw = GetDrawer2D()->DeviceToWorldX( m_x );
2429  yw = GetDrawer2D()->DeviceToWorldY( m_y );
2430 
2431  a2dHitEvent hitinfo( xw, yw, false, a2dCANOBJHITOPTION_LAYERS, true );
2432  a2dCanvasObject* hit = GetDrawingPart()->IsHitWorld( hitinfo, wxLAYER_ALL );
2433 
2434  if ( event.Moving() && !GetBusy() )
2435  {
2436  if( hit )
2437  {
2438  a2dHit how2;
2439  }
2440  }
2441  else if( event.LeftDown() && !GetBusy() )
2442  {
2443  }
2444  else
2445  {
2446  event.Skip();
2447  }
2448 }
2449 
2450 void a2dSubDrawMasterTool::PushToolFromMouseMenu( wxCommandEvent& event )
2451 {
2452  /*
2453  a2dToolProperty *property = wxStaticCast( event.m_callbackUserData, a2dToolProperty );
2454  if ( property->GetMenuItem()->GetId() == event.GetId() )
2455  {
2456  a2dSmrtPtr< a2dBaseTool > tool;
2457  if ( m_controller->GetFirstTool() != this )
2458  m_controller->PopTool( tool );
2459 
2460  property->GetToolObject()->SetCorridor( m_corridor );
2461  m_controller->PushTool( property->GetToolObject() );
2462  }
2463  */
2464 }
2465 
2466 IMPLEMENT_CLASS( a2dGraphicsMasterTool, a2dMasterDrawBase )
2467 
2468 BEGIN_EVENT_TABLE( a2dGraphicsMasterTool, a2dMasterDrawBase )
2469  EVT_MOUSE_EVENTS( a2dGraphicsMasterTool::OnMouseEvent )
2470  EVT_CHAR( a2dGraphicsMasterTool::OnChar )
2471  EVT_KEY_DOWN( a2dGraphicsMasterTool::OnKeyDown )
2472 END_EVENT_TABLE()
2473 
2474 a2dGraphicsMasterTool::a2dGraphicsMasterTool( a2dStToolContr* controller ): a2dMasterDrawBase( controller )
2475 {
2476  m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW );
2477  m_mode = mode_none;
2478  m_canvasobject = 0;
2479  m_modehit = 0;
2480 
2481  controller->SetDefaultBehavior( controller->GetDefaultBehavior() | wxTC_NoDefaultKeys | wxTC_NoDefaultMouseActions );
2482 }
2483 
2484 a2dGraphicsMasterTool::~a2dGraphicsMasterTool()
2485 {
2486 }
2487 
2488 void a2dGraphicsMasterTool::OnMouseEvent( wxMouseEvent& event )
2489 {
2490  if ( !m_active )
2491  {
2492  event.Skip();
2493  return;
2494  }
2495  m_x = event.GetX();
2496  m_y = event.GetY();
2497 
2498  //to world coordinates to do hit test in world coordinates
2499  double xw;
2500  double yw;
2501 
2502  xw = GetDrawer2D()->DeviceToWorldX( m_x );
2503  yw = GetDrawer2D()->DeviceToWorldY( m_y );
2504 
2505  if ( event.Moving() && !GetBusy() && !event.ShiftDown() && !event.ControlDown() )
2506  {
2507  GetDrawing()->GetHabitat()->GetConnectionGenerator()->SetPinsToBeginState( GetDrawingPart()->GetShowObject() );
2508 
2509  //there is no wire nor pin yet, therefore we can just feedback possible pin connection, based on the
2510  // m_connectionGenerator.
2511  double hitDistance = GetHitMargin();
2512 
2513  //GetDrawing()->GetHabitat()->GetConnectionGenerator()->
2514  // SearchPinForStartWire( GetDrawingPart()->GetShowObject(), a2d_StartWire, xw, yw, a2dPinClass::Any, hitDistance );
2515  }
2516 
2517  //!todo this can be a specialized hit on pin in connection generator.
2518  // and if not hit on a correct pin, do a hitworld to see other objects like wires.
2519  // Or do a connection generator for pin hit, on specific object, instead of root.
2520  a2dHitEvent hitinfo( xw, yw, false, a2dCANOBJHITOPTION_NONE, true );
2521  a2dCanvasObject* hit = GetDrawingPart()->IsHitWorld( hitinfo, wxLAYER_ALL );
2522 
2523  /* TO DEBUG
2524  if( hit )
2525  {
2526  wxLogDebug( hit->GetClassInfo()->GetClassName() );
2527  switch( how.m_hit )
2528  {
2529  case a2dHit::hit_none:
2530  wxLogDebug( "Hit NoHit" );
2531  break;
2532  case a2dHit::hit_stroke:
2533  wxLogDebug( "Hit Stroke" );
2534  break;
2535  case a2dHit::hit_fill:
2536  wxLogDebug( "Hit Fill" );
2537  break;
2538  default:
2539  wxLogDebug( "Hit ?" );
2540  break;
2541  }
2542 
2543  switch( how.m_stroke2 )
2544  {
2545  case a2dHit::stroke2_none:
2546  wxLogDebug( "Stroke None" );
2547  break;
2548  case a2dHit::stroke2_vertex:
2549  wxLogDebug( "Stroke Vertex" );
2550  break;
2551  case a2dHit::stroke2_edgehor:
2552  wxLogDebug( "Stroke Horizontal" );
2553  break;
2554  case a2dHit::stroke2_edgevert:
2555  wxLogDebug( "Stroke Vertical" );
2556  break;
2557  case a2dHit::stroke2_edgeother:
2558  wxLogDebug( "Stroke Other" );
2559  break;
2560  }
2561  }
2562  else
2563  wxLogDebug( "NoHit" );
2564  */
2565 
2566  if ( event.Moving() && !GetBusy() )
2567  {
2568  m_mode = mode_none;
2569  m_modehit = 0;
2570  m_modehitinfo = a2dHit();
2571 
2572  GetDrawing()->GetHabitat()->GetConnectionGenerator()->SetPinsToBeginState( GetDrawingPart()->GetShowObject() );
2573  if( hit )
2574  {
2575  a2dHit how2;
2576 
2577  // Check if there is an unconnected pin
2578  // This has highest priority
2579 
2580  a2dPin* pin = NULL;
2581  if ( !event.ShiftDown() && !event.ControlDown() )
2582  {
2583  GetDrawing()->GetHabitat()->GetConnectionGenerator()->SetPinsToBeginState( GetDrawingPart()->GetShowObject() );
2584 
2585  //there is no wire nor pin yet, therefore we can just feedback possible pin connection, based on the
2586  // m_connectionGenerator.
2587 
2588  GetDrawing()->GetHabitat()->GetConnectionGenerator()->
2589  GeneratePinsToConnect( GetDrawingPart(), hit, a2dPinClass::Any, a2d_GeneratePinsForStartWire, xw, yw );
2590 
2591  pin = GetDrawing()->GetHabitat()->GetConnectionGenerator()->
2592  SearchPinForStartWire( GetDrawingPart()->GetShowObject(), xw, yw, a2dPinClass::Any, GetHitMargin() );
2593 
2594  if ( pin )
2595  {
2597  if ( wire && wire->GetSelected() || m_vertexSegmentEdit )
2598  pin = NULL;
2599  }
2600  }
2601 
2602  /* INSTEAD OFF?
2603  a2dPin *pin = 0;
2604  {
2605  //First try to find object pins which are not of connection/wire objects
2606  int i;
2607  float minDist = FLT_MAX;
2608  for( i=0; i< hitinfo.m_extended.size(); i++ )
2609  {
2610  a2dPin *pin2 = wxDynamicCast( hitinfo.m_extended[i].GetObject(), a2dPin );
2611  if(
2612  pin2 &&
2613  !pin2->ConnectedTo() &&
2614  pin2->GetPinClass() && pin2->GetPinClass()->IsObjectPin() &&
2615  hitinfo.m_extended[i].GetHitType().m_distance < minDist
2616  )
2617  {
2618  pin = pin2;
2619  how2 = hitinfo.m_extended[i].GetHitType();
2620  minDist = how2.m_distance;
2621  }
2622  }
2623  if ( !pin )
2624  //Now try to find object pins which are of connection/wire objects
2625  for( i=0; i< hitinfo.m_extended.size(); i++ )
2626  {
2627  a2dPin *pin2 = wxDynamicCast( hitinfo.m_extended[i].GetObject(), a2dPin );
2628  if(
2629  pin2 &&
2630  !pin2->ConnectedTo() &&
2631  pin2->GetPinClass() && !pin2->GetPinClass()->IsObjectPin() ) &&
2632  hitinfo.m_extended[i].GetHitType().m_distance < minDist
2633  )
2634  {
2635  pin = pin2;
2636  how2 = hitinfo.m_extended[i].GetHitType();
2637  minDist = how2.m_distance;
2638  }
2639  }
2640  }
2641  */
2642 
2643  // Check if there is a wire
2644  a2dWirePolylineL* wire = 0;
2645  if( !pin )
2646  {
2647  int i;
2648  float minDist = FLT_MAX;
2649  for( i = 0; i < hitinfo.m_extended.size(); i++ )
2650  {
2651  a2dWirePolylineL* wire2 = wxDynamicCast( hitinfo.m_extended[i].GetObject(), a2dWirePolylineL );
2652  if( wire2 && hitinfo.m_extended[i].GetHitType().m_distance < minDist && hitinfo.m_extended[i].GetHitType().IsDirectStrokeHit() )
2653  {
2654  wire = wire2;
2655  how2 = hitinfo.m_extended[i].GetHitType();
2656  minDist = how2.m_distance;
2657  }
2658  }
2659  }
2660 
2661  if( pin )
2662  {
2663  // wire drawing mode
2664  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
2665  m_mode = mode_drawwire;
2666  m_modehit = pin;
2667  }
2668  else if ( wire && event.ShiftDown() )
2669  {
2670  // wire editing mode
2671  // check, where the wire was hit:
2672  m_modehit = wire;
2673  m_modehitinfo = how2;
2674  switch( how2.m_stroke2 )
2675  {
2676  case a2dHit::stroke2_vertex:
2677  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireVertex ) );
2678  m_mode = mode_editwire_vertex;
2679  break;
2680  case a2dHit::stroke2_edgehor:
2681  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireSegmentHorizontal ) );
2682  m_mode = mode_editwire_segmenthorizontal;
2683  break;
2684  case a2dHit::stroke2_edgevert:
2685  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireSegmentVertical ) );
2686  m_mode = mode_editwire_segmentvertical;
2687  break;
2688  case a2dHit::stroke2_edgeother:
2689  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_WireSegmentInsert ) );
2690  m_mode = mode_editwire_segmentinsert;
2691  break;
2692  default:
2693  assert( 0 );
2694  m_modehit = 0;
2695  m_modehitinfo = a2dHit();
2696  }
2697  }
2698  else if ( !event.ShiftDown() && hit->GetDraggable() &&
2699  ( hitinfo.m_how.IsInsideHit() ||
2700  wxDynamicCast( hit, a2dPolylineL )
2701  )
2702  )
2703  {
2704  if( !event.ControlDown() )
2705  {
2706  if( hit->GetSelected() )
2707  {
2708  // drag selected mode
2709  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
2710  m_mode = mode_dragmulti;
2711  m_modehit = hit;
2712  }
2713  else
2714  {
2715  // drag mode
2716  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
2717  m_mode = mode_drag;
2718  m_modehit = hit;
2719  }
2720  }
2721  else
2722  {
2723  if( hit->GetSelected() )
2724  {
2725  // copy selected mode
2726  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Copy ) );
2727  m_mode = mode_copymulti;
2728  m_modehit = hit;
2729  }
2730  else
2731  {
2732  // drag mode
2733  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Copy ) );
2734  m_mode = mode_copy;
2735  m_modehit = hit;
2736  }
2737  }
2738  }
2739  else if ( event.ShiftDown() && hitinfo.m_how.IsInsideHit() )
2740  {
2741  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW ) );
2742  m_mode = mode_select;
2743  m_modehit = hit;
2744  }
2745  else
2746  {
2747  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW ) );
2748  m_mode = mode_select;
2749  m_modehit = hit;
2750  }
2751  }
2752  else
2753  {
2754  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW ) );
2755  m_mode = mode_select;
2756  m_modehit = hit;
2757  }
2758  event.Skip();
2759  }
2760  else if( event.LeftDown() && !GetBusy() )
2761  {
2762  switch( m_mode )
2763  {
2764  case mode_none:
2765  event.Skip();
2766  break;
2767  case mode_select:
2768  case mode_drag:
2769  case mode_dragmulti:
2770  case mode_copy:
2771  case mode_copymulti:
2772  case mode_drawwire:
2773  case mode_editwire_vertex:
2774  case mode_editwire_segmenthorizontal:
2775  case mode_editwire_segmentvertical:
2776  case mode_editwire_segmentinsert:
2777  case mode_editwire_segment:
2778  event.Skip();
2779  break;
2780  default:
2781  event.Skip();
2782  }
2783  }
2784  else
2785  {
2786  event.Skip();
2787  }
2788 }
2789 
2790 void a2dGraphicsMasterTool::SelectHitObject( a2dCanvasObject* hit )
2791 {
2792  OpenCommandGroupNamed( _( "Select" ) );
2793 
2794  if ( m_select_undo )
2795  {
2796  OpenCommandGroupNamed( _( "Select" ) );
2797  DeselectAll();
2799  new a2dCommand_SetFlag( hit, a2dCanvasOFlags::SELECTED, true ) );
2801  }
2802  else
2803  {
2804  DeselectAll();
2805  hit->SetSelected( true );
2806  }
2807 
2808 /*
2809  a2dTagVecProperty* hittagged = a2dCanvasObject::PROPID_Tags->GetPropertyListOnly( hit );
2810  if ( hittagged )
2811  {
2812  if ( !hit->GetSelected() )
2813  {
2814  // find other and select
2815  a2dTag tag = hittagged->Last();
2816  a2dCanvasObject* ret = NULL;
2817  for( a2dCanvasObjectList::iterator iter = m_parentobject->GetChildObjectList()->begin(); iter != m_parentobject->GetChildObjectList()->end(); ++iter )
2818  {
2819  a2dCanvasObjectList::value_type obj = *iter;
2820  a2dTagVecProperty* tagsp = a2dCanvasObject::PROPID_Tags->GetPropertyListOnly( obj );
2821  if ( tagsp )
2822  {
2823  tagsp->PushTag( tag );
2824  GetCanvasCommandProcessor()->Submit(
2825  new a2dCommand_SetFlag( obj, a2dCanvasOFlags::SELECTED, true ) );
2826  }
2827  }
2828  }
2829  }
2830  else
2831  {
2832  a2dTag tag;
2833  a2dCanvasObject* tagged = FindTaggedObject();
2834  if ( tagged && tagged->GetSelected() )
2835  {
2836  // find other and select
2837  a2dTagVecProperty* tagsp = a2dCanvasObject::PROPID_Tags->GetPropertyListOnly( tagged );
2838  tag = tagsp->Last();
2839  }
2840  else
2841  tag = a2dNewTag();
2842 
2843  a2dCanvasObject::PROPID_Tags->SetPropertyToObject( hit, a2dTagVec() );
2844  a2dTagVecProperty* tagsp = a2dCanvasObject::PROPID_Tags->GetPropertyListOnly( hit );
2845  tagsp->PushTag( tag );
2846 
2847  GetCanvasCommandProcessor()->Submit(
2848  new a2dCommand_SetFlag( hit, a2dCanvasOFlags::SELECTED, true ) );
2849 
2850  }
2851 */
2853 }
static const a2dCanvasObjectFlagsMask SELECTED2
Definition: candefs.h:181
a2dHit m_how
return in which way the object was hit (stroke, fill, ...)
Definition: canobj.h:301
void PushCursor(const wxCursor &cursor)
push a cursor on the cursor stack, and set display cursor to new back being cursor.
Definition: drawer.cpp:1052
int WorldToDeviceXRel(double x) const
convert x relative from world to device coordinates
Definition: drawer2d.h:460
void SetEndSegmentMode(a2dNextSeg mode)
Definition: mastertool.cpp:450
wxPoint2DDouble a2dPoint2D
this to define if coordinate numbers are integer or doubles
Definition: artglob.h:47
double GetHeight() const
returns height of the boundingbox
Definition: bbox.cpp:334
a2dCanvasObjectPtr m_canvasobject
This is the object currently edited.
Definition: sttool.h:381
bool SetSpecificFlags(bool setOrClear, a2dCanvasObjectFlagsMask which, const wxString &classname=wxT(""), a2dCanvasObjectFlagsMask whichobjects=a2dCanvasOFlags::ALL, const a2dBoundingBox &bbox=wxNonValidBbox, const a2dAffineMatrix &tworld=a2dIDENTITY_MATRIX)
set all given bit flags at once recursive for all objects in given boundingbox
Definition: objlist.cpp:519
#define wxDynamicCast(obj, className)
Define wxDynamicCast so that it will give a compiler error for unrelated types.
Definition: gen.h:75
Base class for all types of strokes, understood by a2dDrawer2D classes.
Definition: stylebase.h:378
unsigned int m_index
For edge/vertex hits the index of the edge / vertex.
Definition: polyver.h:89
a2dCanvasObjectPtr m_parentobject
( if needed ) parent a2dCanvasObject relative to which the tool actions take place.
Definition: tools.h:854
bool m_dragStarted
used to indicate that a first drag event has arrived.
Definition: sttool.h:374
bool RotateObject90LeftRight(bool right)
rotate object of first tool on the stack, when appropriate.
Definition: mastertool.cpp:388
bool m_pending
set when tool needs an redraw (after a a2dCanvas Repaint etc.)
Definition: tools.h:814
bool PushTool(a2dBaseTool *tool)
specialize to keep first tool on the stack active
Definition: sttool.cpp:451
Drag Selected canvasObjects.
Definition: sttool2.h:208
~a2dMasterDrawBase()
destructor
Definition: mastertool.cpp:353
a2dCanvasCommandProcessor * GetCanvasCommandProcessor()
Returns a pointer to the command processor associated with this document.
Definition: tools.cpp:976
The a2dBaseTool is used to derive tools from that are controlled by.
Definition: tools.h:379
void ClearCorridorPath(bool uncapture)
Reset all corridor paths and uncapture object.
Definition: drawer.cpp:1549
void SetShowAnotation(bool show)
when true anotation will be shown, if used inside a tool
Definition: tools.h:564
no special options
Definition: canobj.h:79
virtual void AdjustRenderOptions()
Adjust the rendering options to the needs of this tool.
Definition: sttool.cpp:1214
wxCursor m_toolcursor
cursor to use
Definition: tools.h:768
master tools are tools on top of other tools.
class to map references to objects stored in XML, in order to make the connection later on...
Definition: gen.h:3462
virtual a2dCanvasObject * StartEdit(a2dBaseTool *tool, wxUint16 editmode, wxEditStyle editstyle=wxEDITSTYLE_COPY, a2dRefMap *refs=NULL)
create an editcopy and initialize editing of the editcopy
Definition: canobj.cpp:1640
void SetIgnorePendingObjects(bool onoff)
Switches ignorance of pending objects on and off.
Definition: tools.cpp:628
static const a2dCanvasObjectFlagsMask BIN2
Definition: candefs.h:193
virtual void DoStopTool(bool abort)
to do tool specific stuff to stop a tool. Called from StopTool().
Definition: mastertool.cpp:900
void SetFill(const a2dFill &fill)
set fill if used inside a tool
Definition: tools.cpp:812
int m_x
x of mouse in device
Definition: sttool.h:352
double GetHitMargin()
Definition: tools.cpp:983
void SetSelected2(bool selected)
Set the object selected2 flag if allowed.
Definition: canobj.h:1639
a2dCanvasObjectPtr m_original
This is the original object selected for editing.
Definition: sttool.h:388
a2dPin is used in a2dCanvasObject to add pins to it.
Definition: canpin.h:233
polygon defined with list of points.
Definition: polygon.h:45
stack based tools for drawing and editing in a faster manner, but with less document feedback...
Master tool for objects graphics slecting and dragging nd zooming.
Definition: mastertool.h:429
a2dDrawing * GetRoot() const
get a2dCanvasDocument of the object.
Definition: canobj.h:952
The a2dStTool is used to derive tools from.
Definition: sttool.h:115
void SetOneShot()
Only one action of the tool, after that it will ask the controller to stop this tool.
Definition: tools.h:430
Simple (handle-less) wire editing tool intended as sub-tool for master tools.
Definition: mastertool.h:47
generate pins, given Connect/wire pinclass
Definition: connectgen.h:48
a2dDrawingPart * GetDrawingPart()
Access to the tool controllers drawer.
Definition: tools.h:632
wxZoomList & GetZoomList()
Get zoom stack list, that is use to store zooming areas.
Definition: sttool.h:616
int m_dragstarty
y of mouse in device at start drag
Definition: sttool.h:371
virtual bool Update(UpdateMode mode)
Update the state of the object according to its current position etc.
Definition: canobj.cpp:5149
used to connect two pins
Definition: drawing.h:2411
virtual void OpenCommandGroupNamed(const wxString &name)
called when starting an editing operation with another than the default name
Definition: tools.cpp:876
void Zoomin2()
zoom in two half the current visible area
Definition: sttool.cpp:406
Interactive Zooming.
Definition: sttool.h:849
a2dStToolContr * m_stcontroller
controller for canvas
Definition: sttool.h:391
void OnMouseEvent(wxMouseEvent &event)
a2dDrawing * GetDrawing()
Returns a pointer to the drawing.
Definition: tools.cpp:969
void Update(unsigned int how=(a2dCANVIEW_UPDATE_ALL|a2dCANVIEW_UPDATE_BLIT), wxObject *hintObject=NULL)
see OnUpdate
Definition: drawer.cpp:1744
bool m_anotate
when true anotation will be shown, if used inside a tool
Definition: tools.h:839
virtual void SetPending(bool pending)
set this object pending for update
Definition: canobj.cpp:2585
void ZoomIn2AtMouse()
zoom in two half the current visible area at mouse position
Definition: sttool.cpp:431
object hit should not have select flag set
Definition: canobj.h:90
bool m_active
tool is operational
Definition: tools.h:777
a2dPin * IsConnectedTo(a2dPin *pin=a2dAnyPin) const
Return the pin to which this pin is connected.
Definition: canpin.cpp:751
int m_dragstartx
x of mouse in device at start drag
Definition: sttool.h:369
double m_ywprev
y world coordinates old or new value of mouse
Definition: sttool.h:366
int GetSnapThresHold() const
used to snap vertexes to a pin or point like snapping features in objects.
Definition: restrict.h:177
void ZoomOut2AtMouse()
zoom out two times the current visible area at mouse position
Definition: sttool.cpp:417
virtual void FinishBusyMode(bool closeCommandGroup=true)
Called when the user finishes editing a distinct object */.
Definition: sttool.cpp:1161
float m_distance
For margin hits, the distance from the stroke center in fractions of the margin.
Definition: polyver.h:93
double GetWidth() const
return width
Definition: canprim.h:337
double GetBboxMinX()
get minimum X of the boundingbox in world coordinates relative to its parents
Definition: canobj.h:676
Interactive Zooming.
Definition: sttool2.h:69
a2dCanvasObject is the base class for Canvas Objects.
Definition: canobj.h:371
bool GetRouteWhenDrag()
route also while dragging object
Definition: connectgen.h:341
void Render()
implement rendering
a2dPin * FindWirePin(a2dCanvasObjectFlagsMask mask=a2dCanvasOFlags::ALL)
Definition: canpin.cpp:1029
a2dDrawingPart * GetDrawingPart()
Get the a2dDrawingPart object that the controller is plugged into.
Definition: tools.h:104
void Zoomout()
show all on canvas
Definition: sttool.cpp:378
for changing boolean values inside canvas objects
Definition: drawing.h:1585
double GetBboxMaxY()
get maximum Y of the boundingbox in world coordinates relative to its parents
Definition: canobj.h:694
Interactive drawing of a Rectangle.
Definition: sttool.h:807
void SetWidth(double w)
set width of rectangle
Definition: canprim.h:328
a2dCanvasObjectList * GetChildObjectList()
get the list where the child objects are stored in.
Definition: canobj.cpp:2551
virtual void DoStopTool(bool abort)
to do tool specific stuff to stop a tool. Called from StopTool().
Definition: mastertool.cpp:131
handle holds a pointer to a polygon/polyline segment
Definition: polygon.h:713
bool GetSelected() const
is the object selected flag set
Definition: canobj.h:1603
void SetSelected(bool selected)
Set the object selected flag if allowed.
Definition: canobj.h:1620
a2dStroke m_stroke
stroke for new object
Definition: tools.h:826
bool ProcessEvent(wxEvent &event)
events recieved from controller processed here
Definition: tools.cpp:668
bool IsVisible() const
get visibility (rendering depends on layer settings also)
Definition: canobj.h:1316
void Zoomout2()
zoom out two times the current visible area
Definition: sttool.cpp:395
void RotateRouteMethod()
cycle through routing methods
Definition: connectgen.cpp:74
void SetLateConnect(bool lateconnect)
defines if an object will try to connect at the end of a drag
Definition: sttool.h:1036
bool m_preserve_select
preserve the a2dCANVAS_SELECT flag after editing.
Definition: mastertool.h:95
a2dNextSeg GetEndSegmentMode()
a2dDrawWirePolylineLTool segment mode initilization
Definition: canglob.h:962
int WorldToDeviceYRel(double y) const
convert y relative from world to device coordinates
Definition: drawer2d.h:465
void SetHeight(double h)
set height of rectangle
Definition: canprim.h:334
static const a2dCanvasObjectFlagsMask PENDING
Definition: candefs.h:194
general style dialog to edit a2dCanvasObject style
Definition: styledialg.h:60
a2dWirePolylineL is a polyline that adjusts itself when the objects it connects move ...
Definition: wire.h:42
bool m_xyRelToChildren
is set, m_x and m_y are supplied relative to the child objects ( object matrix m_world already applie...
Definition: canobj.h:297
wxUint32 m_option
the way to hit/traverse the document.
Definition: canobj.h:299
a2dDrawer2D * GetDrawer2D()
Access to the tool controllers drawers drawer2d.
Definition: tools.cpp:959
Interactive (De)selection Selection of an Object(s).
Definition: sttool2.h:166
a2dText is an abstract base class.
Definition: cantext.h:93
void SetEditAtEnd(bool editatend)
flag for setting editing tool after drawing a primitive.
Definition: sttool.h:185
virtual bool EnterBusyMode()
starts a new action (e.g drawing something ) in a tool that is already pushed.
Definition: mastertool.cpp:65
double DeviceToWorldY(double y) const
convert y from device to world coordinates
Definition: drawer2d.h:439
bool GetValid() const
returns true if boundingbox is calculated properly and therefore its valid flag is set...
Definition: bbox.cpp:299
double GetMinX() const
get minimum X of the boundingbox
Definition: bbox.cpp:304
virtual void AbortBusyMode()
Called when the user aborts editing a distinct object */.
Definition: mastertool.cpp:122
command on selected objects
Definition: drawing.h:2471
a2dFill m_fill
fill for new object
Definition: tools.h:823
void AddPendingUpdateArea(a2dCanvasObject *obj, wxUint8 id=0, bool refsalso=true)
add pending update for the area that is the boundingbox of the given object
Definition: drawer.cpp:2891
int m_index
Index of vertex / segment, that is edited.
Definition: mastertool.h:81
void SetIgnorePendingObjects(bool onoff)
Switches ignorance of pending objects on and off.
Definition: drawing.cpp:432
Interactive drag an object.
Definition: sttool.h:1012
#define forEachIn(listtype, list)
easy iteration for a2dlist
Definition: a2dlist.h:111
a2dExtendedResult m_extended
extended result information with e.g path to lead to the nested object hit
Definition: canobj.h:303
delete objects which fit the mask
Definition: drawing.h:2937
polyline defined with list of points.
Definition: polygon.h:332
The a2dStToolContr is a Tool Controller specialized for working with a2dCanvasView.
Definition: sttool.h:485
virtual void DoStopTool(bool abort)
to do tool specific stuff to stop a tool. Called from StopTool().
Definition: tools.cpp:796
void AddOverlayObject(a2dCanvasObject *obj)
add to list of overlay objects (must be children of m_top)
Definition: drawer.cpp:973
double GetPosX() const
get x position from affine matrix
Definition: canobj.h:527
static const a2dCanvasObjectFlagsMask SELECTABLE
Definition: candefs.h:182
a2dSmrtPtr< a2dPolyHandleL > m_handle
Definition: mastertool.h:91
void SetSnapSourceFeatures(wxUint32 snapSourceFeatures)
Definition: sttool.h:233
#define wxStaticCast(obj, className)
The wxWindows 2.4.2 wxStaticCast is buggy. It evaluates its argument twice.
Definition: gen.h:123
Interactive drawing of a polyline wire.
Definition: sttool.h:1930
a2dVertexListPtr GetSegments()
Get the list of points ( this is not a copy! )
Definition: polygon.h:219
bool IsInsideHit() const
true if this is a fill hit or an inside stroke hit (parent or child/member)
Definition: polyver.h:113
a2dCanvasObject * GetShowObject() const
return pointer of then currently shown object on the drawer.
Definition: drawer.h:680
void SetSpecificFlags(bool setOrClear, a2dCanvasObjectFlagsMask which)
set all bit flags in object that or true in mask to true or false
Definition: canobj.cpp:2645
wxMenu * m_mousemenu
popup menu
Definition: tools.h:851
void SetMouseEvents(bool onoff)
If not set do not process mouse events.
Definition: drawer.cpp:1081
objects which fit the mask are given a new fill and stroke style
Definition: drawing.h:3480
objects which fit the mask are given a new fill and stroke style
Definition: drawing.h:3525
int m_mode
general operation mode setting for a tool.
Definition: tools.h:845
void SetUpdatesPending(bool onoff)
Tells the document that an object has changed.
Definition: drawing.cpp:405
Restriction engine for editing restrictions like snapping.
Definition: restrict.h:88
wxUint16 GetLayer() const
Returns the layer index where this object is drawn upon.
Definition: canobj.h:2368
This tool does do a hit test on objects to edit, and then starts editing the object.
Definition: edit.h:226
bool HasPins(bool realcheck=false)
are there a2dPin derived children
Definition: canobj.cpp:6414
int m_yprev
previous y of mouse in device
Definition: sttool.h:360
Drag Selected canvasObjects.
Definition: sttool.h:2021
Master tool for objects+wires graphics.
Definition: mastertool.h:475
if set, respect layer order, hit testing is done per layer from the top.
Definition: canobj.h:82
static const a2dCanvasObjectFlagsMask SELECTED
Definition: candefs.h:180
virtual void DoStopTool(bool abort)
to do tool specific stuff to stop a tool. Called from StopTool().
a2dToolContr * m_controller
under control of this toolcontroller, to give me events.
Definition: tools.h:774
virtual void SetHandleToIndex(a2dPolyHandleL *handle, unsigned int index)
a handle in editing is updated to a segment at index given
Definition: polygon.cpp:840
a2dCorridor m_corridor
Definition: tools.h:795
This tool is for editing a single object.
Definition: edit.h:73
editing is completely controlled by tools. No handles are added
Definition: canobj.h:140
a2dCanvasObject * ChildIsHitWorld(a2dIterC &ic, a2dHitEvent &hitEvent, bool filterSelectableLayers=false)
Do hittest on children.
Definition: canobj.cpp:3289
void SetVisible(bool visible)
set if this object will visible (be rendered or not)
Definition: canobj.h:1303
Drag and Copy Selected canvasObjects.
Definition: sttool.h:2148
void DoStopTool(bool abort)
to do tool specific stuff to stop a tool. Called from StopTool().
void SetEndSegmentMode(a2dNextSeg mode)
Definition: sttool.cpp:5117
A 2x3 affine matrix class for 2D transformations.
Definition: afmatrix.h:53
makes a tool fixed in style.
Definition: sttool.h:2369
Master tool for objects graphics slecting and dragging nd zooming.
Definition: mastertool.h:390
virtual bool ZoomSave()
Is Zooming while the tool is busy Save.
Definition: mastertool.cpp:895
double m_xwprev
x world coordinates old or new value of mouse
Definition: sttool.h:363
a2dPinClass * GetPinClass() const
return the pin class of this pin
Definition: canpin.h:356
double GetMaxX() const
get maximum X of the boundingbox
Definition: bbox.cpp:316
void InitMouseEvent(wxMouseEvent &eventnew, int x, int y, wxMouseEvent &event)
Definition: mastertool.cpp:370
Interactive Selection of an Object.
Definition: sttool2.h:120
bool GetFixedStyle() const
Get object fixed style setting.
Definition: canobj.h:1590
bool ShowDlgStyle(bool onOff)
show style dialog or not, return true of changed from previous state
Definition: drawing.cpp:6095
double GetPosY() const
get y position from affine matrix
Definition: canobj.h:530
common stuff for several master tools
Definition: mastertool.h:167
virtual void AbortBusyMode()
Called when the user aborts editing a distinct object */.
Definition: sttool.cpp:1178
Interactive copy an object.
Definition: sttool.h:1253
while iterating a a2dCanvasDocument, this holds the context.
Definition: canobj.h:3212
struct for how a single object on one layer was hit
Definition: polyver.h:38
All updates of these modes force an update (e.g. update non-pending valid bounding boxes) ...
Definition: canobj.h:1107
a2dCanvasObject * GetOriginal()
if this is an editcopy, return the orginal else NULL
Definition: canobj.cpp:1876
a2dConnectionGenerator * GetConnectionGenerator() const
Get class for generating new connection objects between object and pins.
Definition: canglob.h:601
virtual bool Submit(a2dCommand *command, bool storeIt=true)
Definition: drawing.cpp:5966
for changing only the matrix of objects for which a certain mask was set
Definition: drawing.h:1857
void SetStroke(const wxColour &strokecolor, double width=0, a2dStrokeStyle style=a2dSTROKE_SOLID)
Set a stroke for the object which will be used instead of the layer stroke.
Definition: canobj.cpp:2924
void SetChildrenOnSameLayer(bool samelayer)
if set children are rendered on the same layer as this object.
Definition: canobj.h:1429
static const a2dCanvasObjectFlagsMask VISIBLE
Definition: candefs.h:186
int m_y
y of mouse in device
Definition: sttool.h:354
void SetCorridor(const a2dCorridor &corridor)
set a corridor from a list of objects
Definition: tools.cpp:900
a2dRestrictionEngine * GetRestrictionEngine()
Get restriction engine (grid snapping)
Definition: canglob.cpp:934
double GetUnitsScale()
this is the number that defines the physical dimension in meters / inch/ etc.
Definition: drawing.h:676
a2dConnectionGenerator * GetConnectionGenerator() const
Get class for generating new connection objects between object and pins.
Definition: canpin.h:723
bool GetRelease() const
get release flag
Definition: gen.h:1350
a2dCanvasCommandProcessor * GetCanvasCommandProcessor()
get a pointer to the command processor
Definition: drawing.cpp:375
double DeviceToWorldX(double x) const
convert x from device to world coordinates
Definition: drawer2d.h:437
virtual void CleanupToolObjects()
Cleanup the editcopy other tool objects (e.g. decorations)
Definition: sttool.cpp:1265
Interactive drag a a2dPin on a wire.
Definition: sttool.h:2547
double GetMaxY() const
get maximum Y of the boundingbox
Definition: bbox.cpp:322
double GetWidth() const
returns width of the boundingbox
Definition: bbox.cpp:328
a2dStToolContr * GetStToolContr()
return the staacked tool controller
Definition: sttool.h:174
virtual bool AllowPop()
tells if a tool can be poped from the stack.
Definition: tools.h:442
void SetStroke(const a2dStroke &stroke)
set stroke if used inside a tool
Definition: tools.cpp:817
a2dBaseTool * GetFirstTool() const
get currently used eventhandler (always the first in the list)
Definition: tools.cpp:91
select objects in a rectangle area
Definition: drawing.h:2488
a2dCanvasObject * IsHitWorld(double x, double y, int layer=wxLAYER_ALL, a2dHitOption option=a2dCANOBJHITOPTION_NONE, bool filterSelectableLayers=false)
do a hittest on the view at coordinates x,y
Definition: drawer.cpp:1565
void SetLateConnect(bool lateconnect)
defines if an object will try to connect at the end of a drag
Definition: sttool.h:2037
objects which fit the mask are given a new font and other text properties
Definition: drawing.h:3563
This tool does do a hit test on objects to edit, and then starts editing the object.
Definition: edit.h:286
a2dCanvasObject * Find(a2dCanvasObject *obj) const
return the object if it is part of the list
Definition: objlist.cpp:553
virtual bool ProcessCanvasObjectEvent(wxEvent &event, bool &isHit, double x, double y, int margin, int layer=wxLAYER_ALL)
Corridor and captured object event processing.
Definition: drawer.cpp:1304
void RemoveOverlayObject(a2dCanvasObject *obj)
remove from the list of overlay objects (must be children of m_top)
Definition: drawer.cpp:979
a2dPin * GetPin()
see SetPin()
Definition: polygon.h:789
bool GetSelectable() const
is the object selectable flag set
Definition: canobj.h:1648
Draw Master tool for object graphics.
Definition: mastertool.h:122
virtual bool PushTool(a2dBaseTool *handler)
push/pop tool:
Definition: tools.cpp:335
bool FindAndSetCorridorPath(a2dCanvasObject *findObject, bool capture)
Find the show-object child object, set the path to the given child object and capture it...
Definition: drawer.cpp:1516
a2dRect
Definition: canprim.h:440
The a2dBoundingBox class stores one a2dBoundingBox of a a2dCanvasObject.
Definition: bbox.h:39
virtual void SetPinsToBeginState(a2dCanvasObject *root, a2dCanvasObjectFlagsMask mask=a2dCanvasOFlags::VISIBLE)
set begin state of pins, before a tools starts asking feedback or after tool is finsihed ...
void SetRouteWhenDrag(bool routeWhenDrag)
route also while dragging object
Definition: connectgen.h:338
double GetMinY() const
get minimum Y of the boundingbox
Definition: bbox.cpp:310
virtual bool EnterBusyMode()
starts a new action (e.g drawing something ) in a tool that is already pushed.
Definition: sttool.cpp:1147
a2dConnectionGenerator * GetConnectionGenerator() const
Get class for generating new connection objects between object and pins.
Definition: sttool.h:217
static a2dPinClass * Any
used to ask for a new default pin on an object.
Definition: canpin.h:763
a2dCanvasGlobal * a2dCanvasGlobals
global a2dCanvasGlobal to have easy access to global settings
Definition: canglob.cpp:1234
all headers of the canvas module
Action m_action
what to edit (vertex, segment, ...)
Definition: mastertool.h:87
filter on this layer and mask.
Definition: canobj.h:2780
void MouseToToolWorld(int x, int y, double &xWorldLocal, double &yWorldLocal)
calculate world coordinates from devide coordinates
Definition: sttool.cpp:1622
void SetSnapThresHold(int thresHold)
used to snap vertexes to a pin or point like snapping features in objects.
Definition: restrict.h:180
void SetCursorType(const wxCursor &cursor)
Sets cursor which the tool should use when started.
Definition: tools.h:582
Drag and Copy Selected canvasObjects.
Definition: sttool2.h:274
bool GetBusy()
Check if the tool is busy editing a distinct object */.
Definition: tools.h:513
virtual bool CreateToolObjects()
Create the editcopy and other tool objects (e.g. decorations)
Definition: mastertool.cpp:260
void Append(a2dCanvasObject *obj)
append a a2dCanvasObject to the childobjects
Definition: canobj.cpp:6224
double GetHeight() const
return height
Definition: canprim.h:339
a2dCanvasObject * GetParent() const
get parent object of the pin
Definition: canpin.h:295
void SetBusyCursorType(const wxCursor &cursor)
Sets cursor which the tool should use when busy.
Definition: tools.h:591
void PopCursor()
pop a cursor from the cursor stack, and set display cursor to back
Definition: drawer.cpp:1059
void SetDeleteOnOutsideDrop(bool val)
If set to true, the dragged object is deleted if dropped outside of the window.
Definition: sttool.h:1031
virtual void SetLayer(wxUint16 layer)
set layer index where this object is drawn upon.
Definition: canobj.cpp:5920
bool m_renderOriginal
if yes, the original object is rendered in place
Definition: sttool.h:397
virtual bool ZoomSave()
Is Zooming while the tool is busy Save.
int m_xprev
previous x of mouse in device
Definition: sttool.h:357
Interactive Selection of an Object.
Definition: sttool.h:898
stack based tools controller and tools for drawing and editing.
virtual bool IsConnect() const
return true, if this object is used to connect other object&#39;s using rubberband like structures...
Definition: canobj.h:1831
virtual bool LinkReferences(bool ignoreNonResolved=false)
link references to their destination
Definition: gen.cpp:4862
virtual void CleanupToolObjects()
Cleanup the editcopy other tool objects (e.g. decorations)
Definition: mastertool.cpp:287
void StopTool(bool abort=false)
call to stop a tool, internal and external.
Definition: tools.cpp:785
void MouseToToolWorld(int x, int y, double &xWorldLocal, double &yWorldLocal)
Definition: drawer.cpp:1097
edit a copy of the original object
Definition: canobj.h:132
virtual void SetMappingWidthHeight(double vx1, double vy1, double width, double height)
Give the virtual size to be displayed, the mapping matrix will be calculated.
Definition: drawer2d.cpp:333
bool GetDraggable() const
get if the object can be dragged
Definition: canobj.h:1676
void AbortBusyMode()
Called when the user aborts editing a distinct object */.
void SetPreRenderAsChild(bool prerender)
If set, this object has a higher priority in rendering than other children objects.
Definition: canobj.h:1469
virtual void CloseCommandGroup()
called when ending an editing operation (e.g. mouse up)
Definition: tools.cpp:883
a2dBoundingBox & GetBbox()
get boundingbox in world coordinates exclusive stroke width relative to its parent ...
Definition: canobj.cpp:3175
structure to give as parameter to member functions of a2dCanvasObject
Definition: canobj.h:252
void SetFill(const a2dFill &fill)
Set a fill for the object which will be used instead of the layer fill.
Definition: canobj.cpp:2874
snap to pins in other objects
Definition: restrict.h:111
void StartToEdit(a2dCanvasObject *startObject)
start editing this object
Definition: edit.cpp:1445
const a2dFill * a2dTRANSPARENT_FILL
global a2dFill stock object for TRANSPARENT filling
mastertool.cpp Source File -- Sun Oct 12 2014 17:04:22 -- Sun Oct 12 2014 -- 1.8.5 -- wxArt2D -- . -- Main Page Reference Documentation