wxArt2D
mastertoolgroups3.cpp
1 /*! \file editor/src/mastertoolgroups.cpp
2  \author Klaas Holwerda
3  \date Created 22/04/2012
4 
5  Copyright: 2012-2012 (c) Klaas Holwerda
6 
7  Licence: wxWidgets Licence
8 
9  RCS-ID: $Id: mastertoolgroups.cpp,v 1.13 2009/04/23 19:35:23 titato Exp $
10 */
11 
12 #include "a2dprec.h"
13 
14 #ifdef __BORLANDC__
15 #pragma hdrstop
16 #endif
17 
18 #ifndef WX_PRECOMP
19 #include "wx/wx.h"
20 #endif
21 
22 #include "wx/canvas/canmod.h"
23 //#include "wx/filename.h"
24 
25 #include <float.h>
26 #include "wx/canvas/sttool.h"
27 #include "wx/canvas/sttool2.h"
29 
30 //----------------------------------------------------------------------------
31 // a2dMasterTagGroups3
32 //----------------------------------------------------------------------------
33 
34 bool a2dMasterTagGroups3::m_selectMoreAtShift = false;
35 
36 IMPLEMENT_CLASS( a2dMasterTagGroups3 , a2dMasterDrawBase )
37 
38 BEGIN_EVENT_TABLE( a2dMasterTagGroups3 , a2dMasterDrawBase )
39  EVT_MOUSE_EVENTS( a2dMasterTagGroups3 ::OnMouseEvent )
40  EVT_CHAR( a2dMasterTagGroups3 ::OnChar )
41  EVT_KEY_DOWN( a2dMasterTagGroups3 ::OnKeyDown )
42  EVT_KEY_UP( a2dMasterTagGroups3 ::OnKeyUp )
43  EVT_COM_EVENT( a2dMasterTagGroups3::OnComEvent )
44 END_EVENT_TABLE()
45 
46 a2dMasterTagGroups3 ::a2dMasterTagGroups3 ( a2dStToolContr* controller ):
47  m_timer( this ),
48  m_AllowDoubleClickModifier( true ),
49  m_shiftWasDown( false ),
50  m_ctrlWasDown( false ),
51  m_altWasDown( false ),
52  m_generatePinsNonWire( true ),
53  m_generatePinsAlsoNonWireMode( true ),
54 
55  a2dMasterDrawBase( controller )
56 {
57  m_selectedObjects = NULL;
58  controller->SetDefaultBehavior( controller->GetDefaultBehavior() | wxTC_NoDefaultKeys | wxTC_NoDefaultMouseActions );
59  m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_Select );
60  m_drawWire = false;
61  a2dCanvasGlobals->ConnectEvent( a2dEVT_COM_EVENT, this );
62 }
63 
64 a2dMasterTagGroups3 ::~a2dMasterTagGroups3 ()
65 {
66  a2dCanvasGlobals->DisconnectEvent( a2dEVT_COM_EVENT, this );
67  if ( m_selectedObjects )
68  delete m_selectedObjects;
69 }
70 
71 wxString a2dMasterTagGroups3 ::GetToolString() const
72 {
73  wxString str = GetClassInfo()->GetClassName();
74  if ( m_drawWire )
75  return str + " Wires";
76  if ( m_dlgOrEdit )
77  return str + " Dlg";
78  return str;
79 }
80 
82 {
83 }
84 
86 {
88  m_toolBusy = false;
89 }
90 
92 {
94 
95  if ( selected )
96  {
97  DeselectAll();
98  }
99  if( GetBusy() && m_dragStarted )
100  {
101  switch( m_mode )
102  {
103  case mode_zoom:
104  case mode_select:
105  case mode_cntrlselect:
106  {
107  break;
108  }
109  default:
110  break;
111  }
112  }
113 
115 }
116 
118 {
119  a2dStTool::SetActive( active );
120  m_pending = true;
121 
122  if ( active )
123  {
124  //depending on keys and mouse position mode is decided.
125  //(is also called when other tool was poped from stack).
126  wxPoint mouspos = m_stcontroller->GetMousePosition();
127  m_x = mouspos.x;
128  m_y = mouspos.y;
130  SetToolMode( false, false, false );
131  SelectedStatus();
132  }
133 }
134 
135 void a2dMasterTagGroups3::OnComEvent( a2dComEvent& event )
136 {
137  if ( GetEvtHandlerEnabled() )
138  {
139  a2dSignal comId = event.GetId();
140 
141  if ( event.GetId() == a2dBaseTool::sig_toolPoped )
142  {
144 
145  a2dProperty* prop = ( a2dProperty* ) event.GetProperty();
146  a2dDrawWirePolylineLTool* wiretool = wxDynamicCast( prop->GetValue(), a2dDrawWirePolylineLTool );
147  if ( wiretool )
148  {
149  m_endSegmentMode = wiretool->GetEndSegmentMode();
150  a2dCanvasGlobals->GetHabitat()->SetEndSegmentMode( m_endSegmentMode );
151  }
152  a2dDragNewTool* dragnewtool = wxDynamicCast( prop->GetValue(), a2dDragNewTool );
153  if ( dragnewtool )
154  {
155  }
156  }
157 
158  if (
159  comId == a2dHabitat::sig_changedFill ||
160  comId == a2dHabitat::sig_changedStroke ||
161  comId == a2dHabitat::sig_changedLayer
162  )
163  {
164  a2dStTool* tool = wxDynamicCast( this, a2dStTool );
165  if ( tool && tool->GetActive() && tool->GetEvtHandlerEnabled() && tool->GetDrawingPart() )
166  {
167  bool OnSelected = false;
168 
169  if ( !m_dlgOrEditModal )
170  {
171  a2dCanvasObjectList objects;
173  if ( objects.size() > 0 )
174  OnSelected = true;
175  }
176  else
177  {
178  if ( /*IsShowm_styleDlg &&*/ m_modehit && m_modehit->GetSelected() )
179  {
180  a2dCanvasObjectList objects;
182  if ( objects.size() > 0 )
183  OnSelected = true;
184  }
185  }
186  if ( !OnSelected )
187  {
188  //m_styleDlg->GetFill()
189  //m_styleDlg->GetStroke()
190 
192  a2dFill f = GetDrawing()->GetHabitat()->GetFill();
193  if ( comId == a2dHabitat::sig_changedFill && ! tool->GetFill().IsSameAs( f ) )
194  {
195  if ( m_modehit )
196  docCmdh->Submit( new a2dCommand_ChangeCanvasObjectStyle( m_modehit, f ) );
197  }
198  a2dStroke s = GetDrawing()->GetHabitat()->GetStroke();
199  if ( comId == a2dHabitat::sig_changedStroke && ! tool->GetStroke().IsSameAs( s ) )
200  {
201  if ( m_modehit )
202  docCmdh->Submit( new a2dCommand_ChangeCanvasObjectStyle( m_modehit, s ) );
203  }
204  }
205  else
206  {
208  a2dFill f = GetDrawing()->GetHabitat()->GetFill();
209  if ( comId == a2dHabitat::sig_changedFill )
210  {
211  docCmdh->Submit( new a2dCommand_SetFillStrokeMask( tool->GetDrawingPart()->GetShowObject() ) );
212  }
213  a2dStroke s = GetDrawing()->GetHabitat()->GetStroke();
214  if ( comId == a2dHabitat::sig_changedStroke )
215  {
216  docCmdh->Submit( new a2dCommand_SetFillStrokeMask( tool->GetDrawingPart()->GetShowObject() ) );
217  }
218  wxUint16 layer = GetDrawing()->GetHabitat()->GetLayer();
219  if ( comId == a2dHabitat::sig_changedLayer )
220  {
221  docCmdh->Submit( new a2dCommand_SetLayerMask( tool->GetDrawingPart()->GetShowObject(), layer ) );
222  }
223  }
224  }
225  }
226 
227 
228  if (
229  comId == a2dHabitat::sig_changedTextFill ||
230  comId == a2dHabitat::sig_changedTextStroke
231  )
232  {
233  a2dStTool* tool = wxDynamicCast( this, a2dStTool );
234  if ( tool && tool->GetActive() && tool->GetEvtHandlerEnabled() && tool->GetDrawingPart() )
235  {
236  bool OnSelected = false;
237 
238  if ( !m_dlgOrEditModal )
239  {
240  a2dCanvasObjectList objects;
242  if ( objects.size() > 0 )
243  OnSelected = true;
244  }
245  else
246  {
247  if ( /*IsShowm_styleDlg &&*/ m_modehit && m_modehit->GetSelected() )
248  {
249  a2dCanvasObjectList objects;
251  if ( objects.size() > 0 )
252  OnSelected = true;
253  }
254  }
255  if ( !OnSelected )
256  {
257  //m_styleDlg->GetFill()
258  //m_styleDlg->GetStroke()
259  if ( m_modehit )
260  {
262  a2dFill f = GetDrawing()->GetHabitat()->GetTextFill();
263  if ( comId == a2dHabitat::sig_changedTextFill && ! m_modehit->GetFill().IsSameAs( f ) )
264  {
265  docCmdh->Submit( new a2dCommand_ChangeCanvasObjectStyle( m_modehit, f ) );
266  }
267  a2dStroke s = GetDrawing()->GetHabitat()->GetTextStroke();
268  if ( comId == a2dHabitat::sig_changedTextStroke && ! m_modehit->GetStroke().IsSameAs( s ) )
269  {
270  docCmdh->Submit( new a2dCommand_ChangeCanvasObjectStyle( m_modehit, s ) );
271  }
272  }
273  }
274  else
275  {
277  a2dFill f = GetDrawing()->GetHabitat()->GetTextFill();
278  if ( comId == a2dHabitat::sig_changedTextFill )
279  {
280  docCmdh->Submit( new a2dCommand_SetFillStrokeMask( tool->GetDrawingPart()->GetShowObject() ) );
281  }
282  a2dStroke s = GetDrawing()->GetHabitat()->GetTextStroke();
283  if ( comId == a2dHabitat::sig_changedTextStroke )
284  {
285  docCmdh->Submit( new a2dCommand_SetFillStrokeMask( tool->GetDrawingPart()->GetShowObject() ) );
286  }
287  }
288  }
289  }
290  event.Skip();
291 
292  }
293 
294 
295  event.Skip();
296 }
297 
298 void a2dMasterTagGroups3::OnChar( wxKeyEvent& event )
299 {
300  //wxLogDebug(wxT("key %d"), event.GetKeyCode());
302 
304 
305  if ( selected )
306  {
307  event.Skip();
308  }
309  else if( GetBusy() && m_dragStarted )
310  {
311  switch( m_mode )
312  {
313  case mode_zoom:
314  case mode_select:
315  case mode_cntrlselect:
316  {
317  break;
318  }
319  default:
320  event.Skip();
321  break;
322  }
323  }
324  else
325  event.Skip();
326 }
327 
328 void a2dMasterTagGroups3 ::OnKeyDown( wxKeyEvent& event )
329 {
330  if ( !m_active )
331  {
332  event.Skip();
333  return;
334  }
335 
336  switch( event.GetKeyCode() )
337  {
338  case 'w':
339  case 'W':
340  {
341  m_drawWire = !m_drawWire;
342  SetToolMode( event.m_controlDown, event.m_shiftDown, event.AltDown() );
343  break;
344  }
345  default:
346  if ( event.m_controlDown || event.m_shiftDown || event.AltDown() )
347  SetToolMode( event.m_controlDown, event.m_shiftDown, event.AltDown() );
348  event.Skip();
349  }
350 }
351 
352 void a2dMasterTagGroups3 ::OnKeyUp( wxKeyEvent& event )
353 {
354  if ( !m_active )
355  {
356  event.Skip();
357  return;
358  }
359 
360  switch( event.GetKeyCode() )
361  {
362  case 'w':
363  case 'W':
364  {
365  SetToolMode( event.m_controlDown, event.m_shiftDown, event.AltDown() );
366  break;
367  }
368  default:
369  if ( !event.m_controlDown || !event.m_shiftDown || !event.AltDown() )
370  SetToolMode( event.m_controlDown, event.m_shiftDown, event.AltDown() );
371  event.Skip();
372  }
373 }
374 
375 bool a2dMasterTagGroups3::SetWireCursor( a2dWirePolylineL* wire, const a2dHitEvent& hitinfo, bool ctrl, bool shift, bool alt )
376 {
377  a2dHit how2;
378  int i;
379  float minDist = FLT_MAX;
380  for( i = 0; i < hitinfo.m_extended.size(); i++ )
381  {
382  a2dWirePolylineL* wire2 = wxDynamicCast( hitinfo.m_extended[i].GetObject(), a2dWirePolylineL );
383  if( wire2 && hitinfo.m_extended[i].GetHitType().m_distance < minDist && hitinfo.m_extended[i].GetHitType().IsStrokeHit() )
384  //if( wire2 && hitinfo.m_extended[i].GetHitType().m_distance < minDist && hitinfo.m_extended[i].GetHitType().IsDirectStrokeHit() )
385  {
386  wire = wire2;
387  how2 = hitinfo.m_extended[i].GetHitType();
388  minDist = how2.m_distance;
389  }
390  }
391 
392  if ( wire )
393  {
394  // wire editing mode
395  // check, where the wire was hit:
396  m_modehit = wire;
397  m_modehitinfo = how2;
398  if ( !alt )
399  {
400  switch( how2.m_stroke2 )
401  {
402  case a2dHit::stroke2_vertex:
403  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireVertex ) );
404  SetStateString( _("drag to move vertex on the wire"), STAT_toolHelp );
405  m_mode = mode_editwire_vertex;
406  break;
407  case a2dHit::stroke2_edgehor:
408  case a2dHit::stroke2_edgevert:
409  case a2dHit::stroke2_edgeother:
410  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_WireSegmentInsert ) );
411  SetStateString( _("drag to insert vertex on the wire"), STAT_toolHelp );
412  m_mode = mode_editwire_segmentinsert;
413  break;
414  default:
415  m_modehit = NULL;
416  m_modehitinfo = a2dHit();
417  }
418  }
419  else
420  {
421  switch( how2.m_stroke2 )
422  {
423  case a2dHit::stroke2_vertex:
424  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireDeleteVertex ) );
425  SetStateString( _("click to remove vertex from wire"), STAT_toolHelp );
426  m_mode = mode_editwire_vertex;
427  break;
428  case a2dHit::stroke2_edgehor:
429  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireSegmentHorizontal ) );
430  SetStateString( _("drag to move segment of the wire"), STAT_toolHelp );
431  m_mode = mode_editwire_segmenthorizontal;
432  break;
433  case a2dHit::stroke2_edgevert:
434  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireSegmentVertical ) );
435  SetStateString( _("drag to move segment of the wire"), STAT_toolHelp );
436  m_mode = mode_editwire_segmentvertical;
437  break;
438  case a2dHit::stroke2_edgeother:
439  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireSegment ) );
440  SetStateString( _("drag to move segment, Alt key to insert a vertex on wire"), STAT_toolHelp );
441  m_mode = mode_editwire_segment;
442  break;
443  default:
444  m_modehit = NULL;
445  m_modehitinfo = a2dHit();
446  }
447  }
448  }
449  return true;
450 }
451 
452 void a2dMasterTagGroups3::SetToolMode( bool ctrl, bool shift, bool alt )
453 {
454  a2dCanvasObject* hit = m_modehit;
455  if ( !m_dragStarted )
456  {
457  //GetDrawingPart()->Update( a2dCANVIEW_UPDATE_PENDING );
458  a2dIterC ic( GetDrawingPart() );
459  ic.SetLayer( wxLAYER_ALL );
460  ic.SetObjectFilter( new a2dCanvasObjectFilterLayerMask( wxLAYER_ALL, a2dCanvasOFlags::VISIBLE | a2dCanvasOFlags::SELECTABLE ) );
461  m_hitinfo = a2dHitEvent( m_xwprev, m_ywprev, false, a2dCANOBJHITOPTION_NONE, true );
462  m_hitinfo.m_option = a2dCANOBJHITOPTION_LAYERS;// | a2dCANOBJHITOPTION_ALL;
463  //at the top level the group its matrix is to be ignored.
464  //Since it is normally NOT ignored within a2dCanvasObject, force an inverse.
465  m_hitinfo.m_xyRelToChildren = true;
466 
467  m_mode = mode_none;
468  m_modehit = 0;
469  m_modehitinfo = a2dHit();
470  hit = GetDrawingPart()->GetShowObject()->ChildIsHitWorld( ic, m_hitinfo, true );
471  GetDrawing()->GetHabitat()->GetConnectionGenerator()->SetPinsToBeginState( GetDrawingPart()->GetShowObject() );
472  }
473  a2dPin* pin = NULL;
474  if ( hit )
475  {
476  pin = wxDynamicCast( hit, a2dPin );
477  if ( pin && pin->GetParent() == GetDrawingPart()->GetShowObject() )
478  pin = NULL;
479  }
480 
481  if ( !pin && !ctrl && shift )
482  {
483  if ( hit )
484  {
485  m_modehit = hit;
486  SetStateString( _("click to select, double click to edit"), STAT_toolHelp );
487  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
488  }
489  else
490  {
491  m_modehit = NULL;
492  SetStateString( _("click on object or drag rectangle to select extra objects"), STAT_toolHelp );
493  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW ) );
494  }
495  m_mode = mode_select;
496  }
497  /*
498  else if ( !pin && ctrl && shift )
499  {
500  if ( hit )
501  {
502  m_modehit = hit;
503  SetStateString( _("click to select"), STAT_toolHelp );
504  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
505  }
506  else
507  {
508  m_modehit = NULL;
509  SetStateString( _("move to object and click to select"), STAT_toolHelp );
510  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW ) );
511  }
512  m_mode = mode_cntrlselect;
513  }
514  */
515  else
516  {
517  if ( hit )
518  {
519  // Check if there is pin
520  // This has highest priority
521  a2dHit how2;
522 
524 
525  bool drawWireAtempt = false;
526 
527  if ( wire && wire->GetSelected() )
528  {
529  if ( m_drawWire )
530  {
531  if ( ctrl )
532  drawWireAtempt = true;
533  else
534  drawWireAtempt = false;
535  }
536  else
537  {
538  if ( ctrl )
539  drawWireAtempt = true;
540  else
541  drawWireAtempt = false;
542  }
543  }
544  else
545  drawWireAtempt = ( m_drawWire && !ctrl ) || ( !m_drawWire && ctrl );
546 
547  if ( wire )
548  {
549  if ( drawWireAtempt )
550  {
551  a2dRestrictionEngine* restrict = GetDrawing()->GetHabitat()->GetRestrictionEngine();
552  if( restrict && ( m_hitinfo.m_how.m_stroke2 == a2dHit::stroke2_edgehor || m_hitinfo.m_how.m_stroke2 == a2dHit::stroke2_edgevert ) )
553  {
554  restrict->RestrictPoint( m_xwprev, m_ywprev );
555  GetDrawing()->GetHabitat()->SetLastXyEntry( m_xwprev, m_ywprev );
556  }
557  // We do generate pins, but in case of restricted point, we might not succeed since the hit is not anymore on the wire.
558  GetDrawing()->GetHabitat()->GetConnectionGenerator()->
560  }
561  else
562  {
563  wire->RemovePins( true, true );
564  }
565 
566  //we did hit a wire, still a pin at this location, can be on a wire or any other object, depending on drawing order.
567  pin = GetDrawing()->GetHabitat()->GetConnectionGenerator()->
568  SearchPinForStartWire( GetDrawingPart()->GetShowObject(), m_xwprev, m_ywprev, a2dPinClass::Any, GetHitMargin() );
569 
570  if( pin )
571  {
572  GetDrawingPart()->ToolWorldToMouse( m_xwprev, m_ywprev, m_generatedPinX, m_generatedPinY );
573  // if in draw wire mode, we must be able to start a wire on a pin
574  // Else we just drag pins, if not connected to a normal object ( so a wire to wire pin ).
575  if ( m_dragStarted && !pin->IsTemporaryPin() )
576  {
577  if ( !drawWireAtempt &&
578  ( pin->GetParent()->IsConnect() && !pin->FindNonWirePin() )
579  )
580  {
581  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
582  SetStateString( _("drag the pin and reroute wires"), STAT_toolHelp );
583  m_mode = mode_move_pin;
584  m_modehit = pin;
585  }
586  if ( !drawWireAtempt &&
587  ( ( pin->GetParent()->IsConnect() && pin->FindNonWirePin() ) || !pin->GetParent()->IsConnect() )
588  )
589  {
590  if ( pin->GetConnectedPinsNr() <= 1 )
591  {
592  // wire drawing mode
593  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
594  SetStateString( _("drag to rewire"), STAT_toolHelp );
595  m_mode = mode_rewire_pin;
596  if ( !pin->GetParent()->IsConnect() )
597  m_modehit = pin->FindWirePin();
598  }
599  else
600  {
601  // wire drawing mode
602  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
603  SetStateString( _("draw a wire from pin"), STAT_toolHelp );
604  m_mode = mode_drawwire;
605  m_modehit = pin;
606  }
607  }
608  }
609  // If we know we are on an object pin, or at least a wire pin on that location, we can
610  // start a wire without need of the drawWireAtempt.
611  // So we can start multiple wires on a normal pin.
612  else if ( !pin->IsTemporaryPin() &&
613  ( ( pin->GetParent()->IsConnect() && pin->FindNonWirePin() ) || !pin->GetParent()->IsConnect() )
614  )
615  {
616  if ( pin->GetConnectedPinsNr() <= 1 )
617  {
618  // wire drawing mode
619  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
620  SetStateString( _("draw a wire from pin, or drag to rewire"), STAT_toolHelp );
621  m_mode = mode_drawwire;
622  }
623  else
624  {
625  // wire drawing mode
626  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
627  SetStateString( _("draw a wire from pin"), STAT_toolHelp );
628  m_mode = mode_drawwire;
629  }
630  m_modehit = pin;
631  }
632  else if (!m_dragStarted && !drawWireAtempt )
633  {
634  // wire drawing mode
635  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
636  SetStateString( _("Drag the pin or start a wire with a click"), STAT_toolHelp );
637  m_mode = mode_drawwire;
638  m_modehit = pin;
639  }
640  else if ( drawWireAtempt || !m_dragStarted )
641  {
642  // wire drawing mode
643  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
644  SetStateString( _("start a wire with a click"), STAT_toolHelp );
645  m_mode = mode_drawwire;
646  m_modehit = pin;
647  }
648  }
649  else
650  {
651  if ( ! drawWireAtempt )
652  {
653  // a wire is not draggabble, but it might be editable, in that case we can drag segments and vertexes.
654  if( hit->GetEditable() )
655  {
656  SetWireCursor( wire, m_hitinfo, ctrl, shift, alt );
657 /* We do not really want to drag wire do we, anyway connect object are !GetDraggable()?
658  if ( hit->GetSelected() )
659  {
660  m_modehit = hit;
661  if ( event.ControlDown() && event.ShiftDown() )
662  {
663  m_mode = mode_copymulti;
664  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Copy ) );
665  }
666  else //no shift no control
667  {
668  m_mode = mode_dragmulti;
669  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
670  }
671  }
672  else
673  {
674  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
675  m_mode = mode_select;
676  m_modehit = hit;
677  }
678 */
679  }
680  else
681  {
682  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
683  SetStateString( _("click to select object"), STAT_toolHelp );
684  m_mode = mode_select;
685  m_modehit = hit;
686  }
687  }
688  }
689 
690  }
691  else //not a wire
692  {
693  if ( !pin && !shift )
694  {
695  //While moving event, there is no wire nor pin yet, therefore we can just feedback possible pin connection, based on the
696  // m_connectionGenerator.
697  if ( m_generatePinsNonWire && ( m_generatePinsAlsoNonWireMode || drawWireAtempt ) )
698  {
699  GetDrawing()->GetHabitat()->GetConnectionGenerator()->
701  }
702 
703  pin = GetDrawing()->GetHabitat()->GetConnectionGenerator()->
704  SearchPinForStartWire( GetDrawingPart()->GetShowObject(), m_xwprev, m_ywprev, a2dPinClass::Any, GetHitMargin() );
705 
706  if ( pin )
707  {
709  if ( wire && wire->GetSelected() )
710  pin = NULL;
711  }
712  }
713 
714  // if not editing a wire, if pin start a wire draw
715  if( pin )
716  {
717  GetDrawingPart()->ToolWorldToMouse( m_xwprev, m_ywprev, m_generatedPinX, m_generatedPinY );
718  if ( m_dragStarted && !pin->IsTemporaryPin() )
719  {
720  if ( !drawWireAtempt &&
721  ( pin->GetParent()->IsConnect() && !pin->FindNonWirePin() ) )
722  {
723  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
724  m_mode = mode_move_pin;
725  SetStateString( _("drag the pin and reroute wires"), STAT_toolHelp );
726  m_modehit = pin;
727  }
728  else if ( pin->GetParent()->IsConnect() && !pin->IsConnectedTo() )
729  {
730  // rewire pin mode
731  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
732  SetStateString( _("Rewire this pin"), STAT_toolHelp );
733  m_mode = mode_rewire_pin;
734  m_modehit = pin;
735  }
736  else if ( pin->GetParent()->IsConnect() && !pin->FindNonWirePin() )
737  {
738  // wire drawing mode
739  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
740  SetStateString( _("draw a wire from this pin"), STAT_toolHelp );
741  m_mode = mode_drawwire;
742  m_modehit = pin;
743  }
744  else if ( !pin->GetParent()->IsConnect() && pin->IsConnectedTo() )
745  {
746  // rewire pin mode
747  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
748  SetStateString( _("Rewire this pin"), STAT_toolHelp );
749  m_mode = mode_rewire_pin;
750  m_modehit = pin;
751  }
752  else
753  {
754  m_mode = mode_drawwire;
755  m_modehit = pin;
756  }
757  }
758  else if ( !m_dragStarted )//&& !pin->IsTemporaryPin() ) we can have generated pins on NON wire objects also.
759  {
760  // wire drawing mode
761  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
762  SetStateString( _("draw a wire from this pin"), STAT_toolHelp );
763  m_mode = mode_drawwire;
764  m_modehit = pin;
765  }
766  }
767  else
768  {
769  if( hit->GetDraggable() )
770  {
771  if ( hit->GetSelected() )
772  {
773  m_modehit = hit;
774  if ( ctrl && shift )
775  {
776  m_mode = mode_copymulti;
777  SetStateString( _("drag to copy selected objects"), STAT_toolHelp );
778  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Copy ) );
779  }
780  else //no shift no control
781  {
782  SetStateString( _("drag to move selected objects, double click to edit"), STAT_toolHelp );
783  m_mode = mode_dragmulti;
784  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
785  }
786  }
787  else
788  {
789  if ( !m_dragStarted )
790  {
791  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
792  SetStateString( _("click to select object, double click to edit"), STAT_toolHelp );
793  m_mode = mode_select;
794  m_modehit = hit;
795  }
796  else
797  {
798  m_mode = mode_drag;
799  m_modehit = hit;
800  SetStateString( _("drag to move object"), STAT_toolHelp );
801  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
802  }
803  }
804  }
805  else
806  {
807  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
808  SetStateString( _("can not drag this object, double click to edit"), STAT_toolHelp );
809  m_mode = mode_select;
810  m_modehit = hit;
811  }
812  }
813  }
814  }
815  else
816  {
817  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW ) );
818  SetStateString( _("click on object, drag rectangle to select objects"), STAT_toolHelp );
819  m_mode = mode_select;
820  m_modehit = hit;
821  }
822  }
823 }
824 
825 void a2dMasterTagGroups3::OnMouseEvent( wxMouseEvent& event )
826 {
827  //MouseDump( event, "OnM " );
828  //wxLogDebug( "%d %d %d %d ", m_x, m_y, m_dragstartx, m_dragstarty );
829 
830  m_shiftWasDown = event.ShiftDown();
831  m_ctrlWasDown = event.ControlDown();
832  m_altWasDown = event.AltDown();
833 
834  if ( !m_active )
835  {
836  event.Skip();
837  return;
838  }
839  m_x = event.GetX();
840  m_y = event.GetY();
841 
843 
844  SelectedStatus();
845 
846  if ( event.LeftDClick() &&
847  !m_toolBusy //&&
848  //no need !( event.ControlDown() || event.ShiftDown() )
849  )
850  {
851  m_hadDoubleClick = true;
852  a2dPin* pin = wxDynamicCast( m_modehit, a2dPin );
853  // if in draw wire mode a double click is on a pin, but edit style should be on wire.
854  if( pin )
855  m_modehit = pin->GetParent();
856 
857  // If selection did take place at LeftDown, undo that one here, as if it did not happen,
858  // since it should not have happened at Double Click.
859  if ( !m_shiftWasDown && !m_modehitLastSelectState )
860  DeselectAll();
861  else if ( m_modehit && m_modehitLastSelectState )
862  {
863  if ( m_selectedObjects )
864  {
865  forEachIn( a2dCanvasObjectList, m_selectedObjects )
866  {
867  a2dCanvasObject* obj = *iter;
868  obj->SetSelected( true );
869  }
870  delete m_selectedObjects;
871  m_selectedObjects = NULL;
872  }
873  m_modehit->SetSelected( m_modehitLastSelectState );
874  SetLastSelected( m_modehit, m_modehitLastSelectState );
875  }
876 
877  bool moreSelectedObjects = m_parentobject->GetChildObjectList()->CollectObjects( NULL, "", a2dCanvasOFlags::SELECTED ) > 1;
878  bool singleedit = false;
879  if ( m_AllowDoubleClickModifier && m_shiftWasDown && !moreSelectedObjects )
880  singleedit = true;
881 
882  EditDlgOrHandles( m_modehit, singleedit, m_drawWire );
883  }
884  else if ( event.Dragging() && m_toolBusy && !m_dragStarted )
885  {
886  //we assume dragging starts for real if 5 pixels shift.
887  if ( abs( m_x - m_dragstartx ) >= 5 || abs( m_y - m_dragstarty ) >= 5 )
888  {
889  m_dragStarted = true;
890  // If selection did take place at LeftDown, undo that here, as if it did not happen,
891  // since it should not have happened at drag.
892  if ( m_modehit )
893  {
894  if ( m_selectedObjects )
895  {
896  forEachIn( a2dCanvasObjectList, m_selectedObjects )
897  {
898  a2dCanvasObject* obj = *iter;
899  obj->SetSelected( true );
900  }
901  delete m_selectedObjects;
902  m_selectedObjects = NULL;
903  }
904  m_modehit->SetSelected( m_modehitLastSelectState );
905  SetLastSelected( m_modehit, m_modehitLastSelectState );
906  }
907  SetToolMode( m_ctrlWasDown, m_shiftWasDown, m_altWasDown );
908  m_toolBusy = false;
909  switch( m_mode )
910  {
911  case mode_none:
912  {
913  m_dragStarted = false;
914  m_toolBusy = false;
915  break;
916  }
917  case mode_drawwire:
918  {
919  m_dragStarted = false;
920  m_toolBusy = false;
921  break;
922  }
923  case mode_cntrlselect:
924  DeselectAll();
925  m_toolBusy = true;
926  event.Skip();
927  break;
928  case mode_select:
929  break;
930  case mode_dragmulti:
931  {
932  m_dragStarted = false;
933  PushDragMultiTool( m_modehit );
934  //event.Skip();
935  break;
936  }
937  case mode_copymulti:
938  {
939  m_dragStarted = false;
940  PushCopyMultiTool( m_modehit );
941  //event.Skip();
942  break;
943  }
944  case mode_drag:
945  {
946  m_dragStarted = false;
947  PushDragTool( m_modehit );
948  //event.Skip();
949  break;
950  }
951  case mode_copy:
952  {
953  m_dragStarted = false;
954  PushCopyTool( m_modehit );
955  //event.Skip();
956  break;
957  }
958  case mode_move_pin:
959  {
960  m_dragStarted = false;
961  PushMovePinTool( m_modehit );
962  wxMouseEvent mouseevent( wxEVT_LEFT_DOWN );
963  InitMouseEvent( mouseevent, m_dragstartx, m_dragstarty, event );
964  m_stcontroller->GetFirstTool()->ProcessEvent( mouseevent );
965  break;
966  }
967  case mode_rewire_pin:
968  {
969  m_dragStarted = false;
970  PushRewirePinTool( m_modehit );
971  wxMouseEvent mouseevent( wxEVT_LEFT_DOWN );
972  InitMouseEvent( mouseevent, m_dragstartx, m_dragstarty, event );
973  m_stcontroller->GetFirstTool()->ProcessEvent( mouseevent );
974  break;
975  }
976  case mode_editwire_vertex:
977  {
978  m_dragStarted = false;
979  PushEditWireVertexTool( m_modehit, m_modehitinfo.m_index );
980  wxMouseEvent mouseevent( wxEVT_LEFT_DOWN );
981  InitMouseEvent( mouseevent, m_dragstartx, m_dragstarty, event );
982  m_stcontroller->GetFirstTool()->ProcessEvent( mouseevent );
983  break;
984  }
985  case mode_editwire_segmenthorizontal:
986  {
987  m_dragStarted = false;
988  PushEditWireSegmentHorizontalTool( m_modehit, m_modehitinfo.m_index );
989  wxMouseEvent mouseevent( wxEVT_LEFT_DOWN );
990  InitMouseEvent( mouseevent, m_dragstartx, m_dragstarty, event );
991  m_stcontroller->GetFirstTool()->ProcessEvent( mouseevent );
992  break;
993  }
994  case mode_editwire_segmentvertical:
995  {
996  m_dragStarted = false;
997  PushEditWireSegmentVerticalTool( m_modehit, m_modehitinfo.m_index );
998  wxMouseEvent mouseevent( wxEVT_LEFT_DOWN );
999  InitMouseEvent( mouseevent, m_dragstartx, m_dragstarty, event );
1000  m_stcontroller->GetFirstTool()->ProcessEvent( mouseevent );
1001  break;
1002  }
1003  case mode_editwire_segmentinsert:
1004  {
1005  m_dragStarted = false;
1006  PushEditWireSegmentInsertTool( m_modehit, m_modehitinfo.m_index );
1007  wxMouseEvent mouseevent( wxEVT_LEFT_DOWN );
1008  InitMouseEvent( mouseevent, m_dragstartx, m_dragstarty, event );
1009  m_stcontroller->GetFirstTool()->ProcessEvent( mouseevent );
1010  break;
1011  }
1012  case mode_editwire_segment:
1013  {
1014  m_dragStarted = false;
1015  PushEditSegmentTool( m_modehit, m_modehitinfo.m_index );
1016  wxMouseEvent mouseevent( wxEVT_LEFT_DOWN );
1017  InitMouseEvent( mouseevent, m_dragstartx, m_dragstarty, event );
1018  m_stcontroller->GetFirstTool()->ProcessEvent( mouseevent );
1019  break;
1020  }
1021 
1022  default:
1023  m_toolBusy = true;
1024  break;
1025  }
1026  }
1027  }
1028  else if ( event.Dragging() && m_toolBusy && m_dragStarted )
1029  {
1030  }
1031  else if ( event.Moving() && !m_toolBusy )
1032  {
1033  SetToolMode( m_ctrlWasDown, m_shiftWasDown, m_altWasDown );
1034  event.Skip();
1035  }
1036  else if( event.LeftDown() && !m_toolBusy )
1037  {
1038  if ( m_selectedObjects )
1039  {
1040  delete m_selectedObjects;
1041  m_selectedObjects = NULL;
1042  }
1043 
1044  //preserve selecte state for double click or drag if it happens
1045  m_modehitLastSelectState = false;
1046  if ( m_modehit )
1047  m_modehitLastSelectState = m_modehit->GetSelected();
1048 
1049  SetStateString( "" );
1050  m_dragStarted = false;
1051  m_xprev = m_x;
1052  m_yprev = m_y;
1053  m_dragstartx = m_x;
1054  m_dragstarty = m_y;
1055 
1056  if( !m_modehit )
1057  {
1058  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
1059  m_mode = mode_select;
1060  event.Skip();
1061  m_toolBusy = false;
1062  return;
1063  }
1064 
1065  switch( m_mode )
1066  {
1067  case mode_select:
1068  case mode_dragmulti:
1069  case mode_copymulti:
1070  case mode_editwire_segmenthorizontal:
1071  case mode_editwire_segmentvertical:
1072  case mode_editwire_segmentinsert:
1073  case mode_editwire_segment:
1074  m_toolBusy = true;
1075 
1076  if ( m_shiftWasDown )
1077  {
1078  if ( m_modehit && m_modehit->GetSelectable() )
1079  {
1080  if ( m_modehit->IsSelected() )
1081  {
1082  m_modehit->SetSelected( false );
1083  if ( m_modehit->GetSelected2() )
1084  {
1085  SetLastSelected( m_modehit, false );
1086  SetLastSelected( GetTopLeftSelected(), true );
1087  }
1088  }
1089  else
1090  {
1091  m_modehit->SetSelected( true );
1092  SetLastSelected( m_modehit, true );
1093  }
1094  }
1095  }
1096  else
1097  {
1098  if ( m_selectMoreAtShift || !m_modehit )
1099  {
1100  m_selectedObjects = m_parentobject->GetChildObjectList()->Clone( a2dCanvasOFlags::SELECTED, a2dObject::clone_flat );
1101  DeselectAll();
1102  }
1103  if ( m_modehit && m_modehit->GetSelectable() )
1104  {
1105  if ( m_drawWire )
1106  {
1107  m_modehit->SetSelected( true );
1108  SetLastSelected( m_modehit, true );
1109  }
1110  else //is conflicting with starting a wire
1111  {
1112  m_modehit->SetSelected( !m_modehitLastSelectState );
1113  SetLastSelected( m_modehit, !m_modehitLastSelectState );
1114  }
1115  }
1116  }
1117 
1118  break;
1119  case mode_move_pin:
1120  m_toolBusy = true;
1121  break;
1122  case mode_rewire_pin:
1123  m_toolBusy = true;
1124  break;
1125  case mode_drawwire:
1126  m_toolBusy = true;
1127  break;
1128  case mode_editwire_vertex:
1129  {
1130  if ( m_altWasDown )
1131  {
1132  PushEditWireVertexTool( m_modehit, m_modehitinfo.m_index );
1133  event.Skip();
1134  }
1135  else
1136  {
1137  m_toolBusy = true;
1138  }
1139  break;
1140  }
1141  default:
1142  // not know until a drag started or not.
1143  m_mode = mode_none;
1144  m_toolBusy = true;
1145  event.Skip();
1146  }
1147  }
1148  else if( event.LeftUp() && m_toolBusy && m_dragStarted )
1149  {
1150  m_toolBusy = false;
1151  m_dragStarted = false; //end of drag
1152  m_mode = mode_none;
1153  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
1154  }
1155  else if( event.LeftUp() && m_toolBusy )
1156  {
1157  //m_timer.Start( a2dDoubleClickWait, true );
1158  m_toolBusy = false;
1159  m_dragStarted = false; //never started but still
1160 
1161  if ( m_mode == mode_drawwire )
1162  {
1163  m_toolBusy = false;
1164 
1165  //When pin was generated on a wire at mouse moving), use it here.
1166  a2dPin* pin = wxDynamicCast( m_modehit, a2dPin );
1167  // if in draw wire mode, we must be able to start a wire on a pin
1168  if( pin )
1169  {
1170  // wire drawing mode
1171  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
1172  m_mode = mode_drawwire;
1173  m_modehit = pin;
1174  PushDrawWireTool( m_modehit );
1175 
1176  wxMouseEvent mouseevent( wxEVT_LEFT_DOWN );
1177  mouseevent.m_x = m_generatedPinX;
1178  mouseevent.m_y = m_generatedPinY;
1179  mouseevent.m_controlDown = true;
1180  mouseevent.m_leftDown = true;
1181  mouseevent.SetEventObject(this);
1182  mouseevent.SetId( GetDrawingPart()->GetDisplayWindow()->GetId() );
1183  m_stcontroller->GetFirstTool()->ProcessEvent( mouseevent );
1184 
1185  wxMouseEvent mouseevent2( wxEVT_LEFT_UP );
1186  mouseevent2.m_x = m_generatedPinX;
1187  mouseevent2.m_y = m_generatedPinY;
1188  mouseevent2.m_controlDown = true;
1189  mouseevent2.m_leftDown = true;
1190  mouseevent2.SetEventObject(this);
1191  mouseevent2.SetId( GetDrawingPart()->GetDisplayWindow()->GetId() );
1192  m_stcontroller->GetFirstTool()->ProcessEvent( mouseevent2 );
1193  }
1194  }
1195  }
1196  else if( event.RightDown() && !GetBusy() )
1197  {
1198  PushZoomTool();
1199  event.Skip();
1200  }
1201  else
1202  {
1203  event.Skip();
1204  }
1205 }
1206 
1207 
1208 
1209 
1210 IMPLEMENT_CLASS( a2dMasterSingleClick , a2dMasterDrawBase )
1211 
1212 BEGIN_EVENT_TABLE( a2dMasterSingleClick , a2dMasterDrawBase )
1213  EVT_MOUSE_EVENTS( a2dMasterSingleClick ::OnMouseEvent )
1214  EVT_CHAR( a2dMasterSingleClick ::OnChar )
1215  EVT_KEY_DOWN( a2dMasterSingleClick ::OnKeyDown )
1216  EVT_KEY_UP( a2dMasterSingleClick ::OnKeyUp )
1217  EVT_COM_EVENT( a2dMasterSingleClick::OnComEvent )
1218 END_EVENT_TABLE()
1219 
1220 a2dMasterSingleClick ::a2dMasterSingleClick ( a2dStToolContr* controller ): a2dMasterDrawBase( controller )
1221 {
1222  controller->SetDefaultBehavior( controller->GetDefaultBehavior() | wxTC_NoDefaultKeys | wxTC_NoDefaultMouseActions );
1223  m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_Select );
1224  m_drawWire = false;
1225  a2dCanvasGlobals->ConnectEvent( a2dEVT_COM_EVENT, this );
1226 }
1227 
1228 a2dMasterSingleClick ::~a2dMasterSingleClick ()
1229 {
1230  a2dCanvasGlobals->DisconnectEvent( a2dEVT_COM_EVENT, this );
1231 }
1232 
1233 wxString a2dMasterSingleClick ::GetToolString() const
1234 {
1235  wxString str = GetClassInfo()->GetClassName();
1236  if ( m_drawWire )
1237  return str + " Wires";
1238  if ( m_dlgOrEdit )
1239  return str + " Dlg";
1240  return str;
1241 }
1242 
1244 {
1245 }
1246 
1248 {
1250  m_toolBusy = false;
1251 }
1252 
1254 {
1256 
1257  if ( selected )
1258  {
1259  DeselectAll();
1260  }
1261  if( GetBusy() && m_dragStarted )
1262  {
1263  switch( m_mode )
1264  {
1265  case mode_zoom:
1266  case mode_select:
1267  case mode_cntrlselect:
1268  {
1269  break;
1270  }
1271  default:
1272  break;
1273  }
1274  }
1275 
1277 }
1278 
1280 {
1281  a2dStTool::SetActive( active );
1282  m_pending = true;
1283 
1284  if ( active )
1285  {
1286  m_mode = mode_select;
1287  m_modehit = NULL;
1288  }
1289 }
1290 
1291 void a2dMasterSingleClick::PushEditTool( a2dCanvasObject* hit )
1292 {
1294 
1295  tool->SetShowAnotation( m_anotate );
1296  tool->SetOneShot();
1297  tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditSegment ) );
1298  tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditSegment ) );
1299 
1300  if ( hit )
1301  {
1302 
1303  }
1304  //tool->SetEvtHandler( m_eventHandler );
1305 
1306  m_stcontroller->PushTool( tool );
1307  tool->StartToEdit( hit );
1308 }
1309 
1310 void a2dMasterSingleClick::OnComEvent( a2dComEvent& event )
1311 {
1312  if ( GetEvtHandlerEnabled() )
1313  {
1314  a2dSignal comId = event.GetId();
1315 
1316  if ( event.GetId() == a2dBaseTool::sig_toolPoped )
1317  {
1318  }
1319 
1321  if ( tool && tool->GetActive() && tool->GetEvtHandlerEnabled() && tool->GetDrawingPart() )
1322  {
1323  bool OnSelected = false;
1324 
1325  if ( /*IsShownm_styleDlg &&*/ m_modehit )
1326  {
1327  a2dCanvasObjectList objects;
1328  m_parentobject->CollectObjects( &objects, wxT( "" ), a2dCanvasOFlags::SELECTED );
1329  if ( objects.size() > 0 )
1330  OnSelected = true;
1331  }
1332  if ( !OnSelected )
1333  {
1335  a2dFill f = GetDrawing()->GetHabitat()->GetFill();
1336  if ( comId == a2dHabitat::sig_changedFill && ! tool->GetFill().IsSameAs( f ) )
1337  {
1338  if ( m_modehit )
1339  docCmdh->Submit( new a2dCommand_ChangeCanvasObjectStyle( m_modehit, f ) );
1340  }
1341  a2dStroke s = GetDrawing()->GetHabitat()->GetStroke();
1342  if ( comId == a2dHabitat::sig_changedStroke && ! tool->GetStroke().IsSameAs( s ) )
1343  {
1344  if ( m_modehit )
1345  docCmdh->Submit( new a2dCommand_ChangeCanvasObjectStyle( m_modehit, s ) );
1346  }
1347  }
1348  else
1349  {
1350  if (
1351  comId == a2dHabitat::sig_changedFill ||
1352  comId == a2dHabitat::sig_changedStroke ||
1353  comId == a2dHabitat::sig_changedLayer
1354  )
1355  {
1357  a2dFill f = GetDrawing()->GetHabitat()->GetFill();
1358  if ( comId == a2dHabitat::sig_changedFill )
1359  {
1360  docCmdh->Submit( new a2dCommand_SetFillStrokeMask( tool->GetDrawingPart()->GetShowObject() ) );
1361  }
1362  a2dStroke s = GetDrawing()->GetHabitat()->GetStroke();
1363  if ( comId == a2dHabitat::sig_changedStroke )
1364  {
1365  docCmdh->Submit( new a2dCommand_SetFillStrokeMask( tool->GetDrawingPart()->GetShowObject() ) );
1366  }
1367  wxUint16 layer = GetDrawing()->GetHabitat()->GetLayer();
1368  if ( comId == a2dHabitat::sig_changedLayer )
1369  {
1370  docCmdh->Submit( new a2dCommand_SetLayerMask( tool->GetDrawingPart()->GetShowObject(), layer ) );
1371  }
1372  }
1373  }
1374  }
1375  }
1376 
1377 
1378  event.Skip();
1379 }
1380 
1381 void a2dMasterSingleClick::OnChar( wxKeyEvent& event )
1382 {
1383  //wxLogDebug(wxT("key %d"), event.GetKeyCode());
1385 
1387 
1388  if ( selected )
1389  {
1390  event.Skip();
1391  }
1392  else if( GetBusy() && m_dragStarted )
1393  {
1394  switch( m_mode )
1395  {
1396  case mode_zoom:
1397  case mode_select:
1398  case mode_cntrlselect:
1399  {
1400  break;
1401  }
1402  default:
1403  event.Skip();
1404  break;
1405  }
1406  }
1407  else
1408  event.Skip();
1409 }
1410 
1411 void a2dMasterSingleClick ::OnKeyDown( wxKeyEvent& event )
1412 {
1413  if ( !m_active )
1414  {
1415  event.Skip();
1416  return;
1417  }
1418 
1419  switch( event.GetKeyCode() )
1420  {
1421  case 'w':
1422  case 'W':
1423  {
1424  m_drawWire = !m_drawWire;
1425  SetToolMode( event.m_controlDown, event.m_shiftDown, event.AltDown() );
1426  break;
1427  }
1428  default:
1429  if ( event.m_controlDown || event.m_shiftDown || event.AltDown() )
1430  SetToolMode( event.m_controlDown, event.m_shiftDown, event.AltDown() );
1431  event.Skip();
1432  }
1433 }
1434 
1435 void a2dMasterSingleClick ::OnKeyUp( wxKeyEvent& event )
1436 {
1437  if ( !m_active )
1438  {
1439  event.Skip();
1440  return;
1441  }
1442 
1443  switch( event.GetKeyCode() )
1444  {
1445  case 'w':
1446  case 'W':
1447  {
1448  SetToolMode( event.m_controlDown, event.m_shiftDown, event.AltDown() );
1449  break;
1450  }
1451  default:
1452  if ( !event.m_controlDown || !event.m_shiftDown || !event.AltDown() )
1453  SetToolMode( event.m_controlDown, event.m_shiftDown, event.AltDown() );
1454  event.Skip();
1455  }
1456 }
1457 
1458 bool a2dMasterSingleClick::SetWireCursor( a2dWirePolylineL* wire, const a2dHitEvent& hitinfo, bool ctrl, bool shift, bool alt )
1459 {
1460  a2dHit how2;
1461  int i;
1462  float minDist = FLT_MAX;
1463  for( i = 0; i < hitinfo.m_extended.size(); i++ )
1464  {
1465  a2dWirePolylineL* wire2 = wxDynamicCast( hitinfo.m_extended[i].GetObject(), a2dWirePolylineL );
1466  if( wire2 && hitinfo.m_extended[i].GetHitType().m_distance < minDist && hitinfo.m_extended[i].GetHitType().IsStrokeHit() )
1467  //if( wire2 && hitinfo.m_extended[i].GetHitType().m_distance < minDist && hitinfo.m_extended[i].GetHitType().IsDirectStrokeHit() )
1468  {
1469  wire = wire2;
1470  how2 = hitinfo.m_extended[i].GetHitType();
1471  minDist = how2.m_distance;
1472  }
1473  }
1474 
1475  if ( wire )
1476  {
1477  // wire editing mode
1478  // check, where the wire was hit:
1479  m_modehit = wire;
1480  m_modehitinfo = how2;
1481  if ( !alt )
1482  {
1483  switch( how2.m_stroke2 )
1484  {
1485  case a2dHit::stroke2_vertex:
1486  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireVertex ) );
1487  SetStateString( _("drag to move vertex on the wire"), STAT_toolHelp );
1488  m_mode = mode_editwire_vertex;
1489  break;
1490  case a2dHit::stroke2_edgehor:
1491  case a2dHit::stroke2_edgevert:
1492  case a2dHit::stroke2_edgeother:
1493  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_WireSegmentInsert ) );
1494  SetStateString( _("drag to insert vertex on the wire"), STAT_toolHelp );
1495  m_mode = mode_editwire_segmentinsert;
1496  break;
1497  default:
1498  m_modehit = NULL;
1499  m_modehitinfo = a2dHit();
1500  }
1501  }
1502  else
1503  {
1504  switch( how2.m_stroke2 )
1505  {
1506  case a2dHit::stroke2_vertex:
1507  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireDeleteVertex ) );
1508  SetStateString( _("click to remove vertex from wire"), STAT_toolHelp );
1509  m_mode = mode_editwire_vertex;
1510  break;
1511  case a2dHit::stroke2_edgehor:
1512  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireSegmentHorizontal ) );
1513  SetStateString( _("drag to move segment of the wire"), STAT_toolHelp );
1514  m_mode = mode_editwire_segmenthorizontal;
1515  break;
1516  case a2dHit::stroke2_edgevert:
1517  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireSegmentVertical ) );
1518  SetStateString( _("drag to move segment of the wire"), STAT_toolHelp );
1519  m_mode = mode_editwire_segmentvertical;
1520  break;
1521  case a2dHit::stroke2_edgeother:
1522  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireSegment ) );
1523  SetStateString( _("drag to move segment, Alt key to insert a vertex on wire"), STAT_toolHelp );
1524  m_mode = mode_editwire_segment;
1525  break;
1526  default:
1527  m_modehit = NULL;
1528  m_modehitinfo = a2dHit();
1529  }
1530  }
1531  }
1532  return true;
1533 }
1534 
1535 void a2dMasterSingleClick::SetToolMode( bool ctrl, bool shift, bool alt )
1536 {
1537  a2dCanvasObject* hit = m_modehit;
1538  if ( !m_dragStarted )
1539  {
1540  //GetDrawingPart()->Update( a2dCANVIEW_UPDATE_PENDING );
1541  a2dIterC ic( GetDrawingPart() );
1542  ic.SetLayer( wxLAYER_ALL );
1543  ic.SetObjectFilter( new a2dCanvasObjectFilterLayerMask( wxLAYER_ALL, a2dCanvasOFlags::VISIBLE | a2dCanvasOFlags::SELECTABLE ) );
1544  m_hitinfo = a2dHitEvent( m_xwprev, m_ywprev, false, a2dCANOBJHITOPTION_NONE, true );
1545  m_hitinfo.m_option = a2dCANOBJHITOPTION_LAYERS;
1546  //at the top level the group its matrix is to be ignored.
1547  //Since it is normally NOT ignored within a2dCanvasObject, force an inverse.
1548  m_hitinfo.m_xyRelToChildren = true;
1549 
1550  m_mode = mode_none;
1551  m_modehit = 0;
1552  m_modehitinfo = a2dHit();
1553  hit = GetDrawingPart()->GetShowObject()->ChildIsHitWorld( ic, m_hitinfo, true );
1554  GetDrawing()->GetHabitat()->GetConnectionGenerator()->SetPinsToBeginState( GetDrawingPart()->GetShowObject() );
1555  }
1556  a2dPin* pin = NULL;
1557  if ( hit )
1558  {
1559  pin = wxDynamicCast( hit, a2dPin );
1560  if ( pin )
1561  pin = wxDynamicCast( hit, a2dPin );
1562  }
1563 
1564  if ( !pin && !ctrl && shift )
1565  {
1566  if ( hit )
1567  {
1568  m_modehit = hit;
1569  SetStateString( _("click to select"), STAT_toolHelp );
1570  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
1571  }
1572  else
1573  {
1574  m_modehit = NULL;
1575  SetStateString( _("move to object and click to select"), STAT_toolHelp );
1576  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW ) );
1577  }
1578  m_mode = mode_select;
1579  }
1580  else
1581  {
1582  if ( hit )
1583  {
1584  // Check if there is pin
1585  // This has highest priority
1586  a2dHit how2;
1587 
1589 
1590  bool drawWireAtempt = false;
1591 
1592  if ( wire && wire->GetSelected() )
1593  {
1594  if ( m_drawWire )
1595  {
1596  if ( ctrl )
1597  drawWireAtempt = true;
1598  else
1599  drawWireAtempt = false;
1600  }
1601  else
1602  {
1603  if ( ctrl )
1604  drawWireAtempt = true;
1605  else
1606  drawWireAtempt = false;
1607  }
1608  }
1609  else
1610  drawWireAtempt = ( m_drawWire && !ctrl ) || ( !m_drawWire && ctrl );
1611 
1612  if ( wire && wire->GetSelected() && drawWireAtempt )
1613  {
1614  m_modehit = wire;
1615  m_mode = mode_edit;
1616  //SetWireCursor( wire, m_hitinfo, ctrl, shift, alt );
1617  }
1618  else if ( wire )
1619  {
1620  if ( drawWireAtempt )
1621  {
1622  GetDrawing()->GetHabitat()->GetConnectionGenerator()->
1623  GeneratePinsToConnect( GetDrawingPart(), wire, a2dPinClass::Any, a2d_GeneratePinsForStartWire, m_xwprev, m_ywprev );
1624  }
1625  else
1626  wire->RemovePins( true, true );
1627 
1628 
1629  //we did hit a wire, still a pin at this location, can be of a wire or anay other object, depending on drawing order.
1630  pin = GetDrawing()->GetHabitat()->GetConnectionGenerator()->
1631  SearchPinForStartWire( GetDrawingPart()->GetShowObject(), m_xwprev, m_ywprev, a2dPinClass::Any, GetHitMargin() );
1632 
1633 
1634 
1635 
1636  if( pin )
1637  {
1638  // if in draw wire mode, we must be able to start a wire on a pin
1639  // Else we just drag pins, if not connected to a normal object ( so a wire to wire pin ).
1640  if ( m_dragStarted && !pin->IsTemporaryPin() )
1641  {
1642  if ( !drawWireAtempt && ( pin->GetParent()->IsConnect() && !pin->FindNonWirePin() ) )
1643  {
1644  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
1645  SetStateString( _("drag the pin and reroute wires"), STAT_toolHelp );
1646  m_mode = mode_move_pin;
1647  m_modehit = pin;
1648  }
1649  if ( ! drawWireAtempt &&
1650  ( ( pin->GetParent()->IsConnect() && pin->FindNonWirePin() ) || !pin->GetParent()->IsConnect() )
1651  )
1652  {
1653  if ( pin->GetConnectedPinsNr() <= 1 )
1654  {
1655  // wire drawing mode
1656  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
1657  SetStateString( _("drag to rewire"), STAT_toolHelp );
1658  m_mode = mode_rewire_pin;
1659  if ( !pin->GetParent()->IsConnect() )
1660  m_modehit = pin->FindWirePin();
1661  }
1662  else
1663  {
1664  // wire drawing mode
1665  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
1666  SetStateString( _("draw a wire from pin"), STAT_toolHelp );
1667  m_mode = mode_drawwire;
1668  m_modehit = pin;
1669  }
1670  }
1671  }
1672  // If we know we are on an object pin, or at least a wire pin on that location, we can
1673  // start a wire without extra Ctrl
1674  // So we can start multiple wires on a normal pin.
1675  else if ( !pin->IsTemporaryPin() &&
1676  ( ( pin->GetParent()->IsConnect() && pin->FindNonWirePin() ) || !pin->GetParent()->IsConnect() )
1677  )
1678  {
1679  if ( pin->GetConnectedPinsNr() <= 1 )
1680  {
1681  // wire drawing mode
1682  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
1683  SetStateString( _("draw a wire from pin, or drag to rewire"), STAT_toolHelp );
1684  m_mode = mode_drawwire;
1685  }
1686  else
1687  {
1688  // wire drawing mode
1689  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
1690  SetStateString( _("draw a wire from pin"), STAT_toolHelp );
1691  m_mode = mode_drawwire;
1692  }
1693  m_modehit = pin;
1694  }
1695  else if (!m_dragStarted && !drawWireAtempt )
1696  {
1697  // wire drawing mode
1698  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
1699  SetStateString( _("Drag the pin or start a wire with a click"), STAT_toolHelp );
1700  m_mode = mode_drawwire;
1701  m_modehit = pin;
1702  }
1703  else if ( drawWireAtempt || !m_dragStarted )
1704  {
1705  // wire drawing mode
1706  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
1707  SetStateString( _("start a wire with a click"), STAT_toolHelp );
1708  m_mode = mode_drawwire;
1709  m_modehit = pin;
1710  }
1711  }
1712  else
1713  {
1714  if ( drawWireAtempt )
1715  {
1716  // wire drawing mode
1717  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
1718  SetStateString( _("draw a wire"), STAT_toolHelp );
1719  m_mode = mode_drawwire;
1720  m_modehit = pin;
1721  }
1722  else
1723  {
1724  if ( !shift )
1725  {
1726  SetWireCursor( wire, m_hitinfo, ctrl, shift, alt );
1727  }
1728  else
1729  {
1730  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
1731  SetStateString( _("click to select or deselect"), STAT_toolHelp );
1732  m_mode = mode_select;
1733  m_modehit = hit;
1734  }
1735  }
1736  }
1737 
1738  }
1739  else //not a wire
1740  {
1741  if ( !pin && !shift )
1742  {
1743  //While moving event, there is no wire nor pin yet, therefore we can just feedback possible pin connection, based on the
1744  // m_connectionGenerator.
1745  if ( drawWireAtempt )
1746  {
1747  GetDrawing()->GetHabitat()->GetConnectionGenerator()->
1749  }
1750 
1751  pin = GetDrawing()->GetHabitat()->GetConnectionGenerator()->
1752  SearchPinForStartWire( GetDrawingPart()->GetShowObject(), m_xwprev, m_ywprev, a2dPinClass::Any, GetHitMargin() );
1753 
1754  if ( pin )
1755  {
1757  if ( wire && wire->GetSelected() )
1758  pin = NULL;
1759  }
1760  }
1761 
1762  // if not editing a wire, if pin start a wire draw
1763  if( pin )
1764  {
1765  if ( m_dragStarted && !pin->IsTemporaryPin() )
1766  {
1767  if ( !drawWireAtempt &&
1768  ( pin->GetParent()->IsConnect() && !pin->FindNonWirePin() ) )
1769  {
1770  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
1771  m_mode = mode_move_pin;
1772  SetStateString( _("drag the pin and reroute wires"), STAT_toolHelp );
1773  m_modehit = pin;
1774  }
1775  else if ( pin->GetParent()->IsConnect() && !pin->IsConnectedTo() )
1776  {
1777  // rewire pin mode
1778  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
1779  SetStateString( _("Rewire this pin"), STAT_toolHelp );
1780  m_mode = mode_rewire_pin;
1781  m_modehit = pin;
1782  }
1783  else if ( pin->GetParent()->IsConnect() && !pin->FindNonWirePin() )
1784  {
1785  // wire drawing mode
1786  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
1787  SetStateString( _("draw a wire from this pin"), STAT_toolHelp );
1788  m_mode = mode_drawwire;
1789  m_modehit = pin;
1790  }
1791  else if ( !pin->GetParent()->IsConnect() && pin->IsConnectedTo() )
1792  {
1793  // rewire pin mode
1794  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
1795  SetStateString( _("Rewire this pin"), STAT_toolHelp );
1796  m_mode = mode_rewire_pin;
1797  m_modehit = pin;
1798  }
1799  else
1800  {
1801  m_mode = mode_drawwire;
1802  m_modehit = pin;
1803  }
1804  }
1805  else if ( !m_dragStarted )//&& !pin->IsTemporaryPin() ) we can have generated pins on NON wire objects also.
1806  {
1807  // wire drawing mode
1808  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
1809  SetStateString( _("draw a wire from this pin"), STAT_toolHelp );
1810  m_mode = mode_drawwire;
1811  m_modehit = pin;
1812  }
1813  }
1814  else
1815  {
1816  if ( !shift )
1817  {
1818  if( hit->GetDraggable() )
1819  {
1820  if ( hit->GetSelected() )
1821  {
1822  m_modehit = hit;
1823  if ( ctrl && shift )
1824  {
1825  m_mode = mode_copymulti;
1826  SetStateString( _("drag to copy selected objects"), STAT_toolHelp );
1827  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Copy ) );
1828  }
1829  else //no shift no control
1830  {
1831  SetStateString( _("drag to move selected objects"), STAT_toolHelp );
1832  m_mode = mode_dragmulti;
1833  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
1834  }
1835  }
1836  else
1837  {
1838  if ( !m_dragStarted )
1839  {
1840  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
1841  SetStateString( _("click to select object, double click to edit"), STAT_toolHelp );
1842  m_mode = mode_edit;
1843  m_modehit = hit;
1844  }
1845  else
1846  {
1847  m_mode = mode_drag;
1848  m_modehit = hit;
1849  SetStateString( _("drag to move object"), STAT_toolHelp );
1850  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
1851  }
1852  }
1853  }
1854  }
1855  else
1856  {
1857  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select2 ) );
1858  SetStateString( _("click to (de)select, double click for dlg"), STAT_toolHelp );
1859  m_mode = mode_select;
1860  m_modehit = hit;
1861  }
1862  }
1863  }
1864  }
1865  else
1866  {
1867  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW ) );
1868  SetStateString( _("click on object, to edit or drag"), STAT_toolHelp );
1869  m_mode = mode_select;
1870  m_modehit = hit;
1871  }
1872  }
1873 }
1874 
1875 void a2dMasterSingleClick ::OnMouseEvent( wxMouseEvent& event )
1876 {
1877  MouseDump( event, "OnM " );
1878 
1879  if ( !m_active )
1880  {
1881  event.Skip();
1882  return;
1883  }
1884  m_x = event.GetX();
1885  m_y = event.GetY();
1886 
1888 
1889  a2dBoundingBox bbox;
1891  forEachIn( a2dCanvasObjectList, objects )
1892  {
1893  a2dCanvasObject* obj = *iter;
1894  if ( obj->GetRelease() || !obj->IsVisible() || !obj->GetSelected() )
1895  continue;
1896  bbox.Expand( obj->GetBbox() );
1897  }
1898 
1899  if ( 0 )//|| bbox.GetValid() )
1900  {
1901  double unitScale = GetDrawing()->GetUnitsScale();
1902  wxString state, form;
1903  form = m_stcontroller->GetFormat() + " " + m_stcontroller->GetFormat();
1904  state.Printf( form, bbox.GetMinX()*unitScale, bbox.GetMinY()*unitScale );
1905  SetStateString( state, 10 );
1906  form = _T("width = ") + m_stcontroller->GetFormat() + _T(" height = ") + m_stcontroller->GetFormat();
1907  state.Printf( form, bbox.GetWidth()*unitScale, bbox.GetHeight()*unitScale );
1908  SetStateString( state, 11 );
1909  }
1910 
1911  if ( event.LeftDClick() &&
1912  !m_toolBusy //&&
1913  //noneed !( event.ControlDown() || event.ShiftDown() )
1914  )
1915  {
1916  m_hadDoubleClick = true;
1917  a2dCanvasObject* hit = m_modehit; //reuse from the LeftDown event.
1918  if ( hit )
1919  {
1920  if ( m_dlgOrEdit && ! hit->GetFixedStyle() && !event.ShiftDown() ||
1921  !m_dlgOrEdit && ! hit->GetFixedStyle() && event.ShiftDown()
1922  )
1923  {
1924  if ( !m_dlgOrEditModal )
1926  else
1927  {
1928  a2dStyleDialog styleDlg( GetDrawing()->GetHabitat(), NULL, wxDEFAULT_DIALOG_STYLE | wxDIALOG_NO_PARENT | wxMINIMIZE_BOX | wxMAXIMIZE_BOX, true );
1929  styleDlg.SetFill( hit->GetFill() );
1930  styleDlg.SetStroke( hit->GetStroke() );
1931  if ( styleDlg.ShowModal() == wxID_OK )
1932  {
1933  hit->SetFill( styleDlg.GetFill() );
1934  hit->SetStroke( styleDlg.GetStroke() );
1935  }
1936  }
1937  }
1938  else
1939  {
1941  m_modehit = hit;
1942 
1943  if ( (wire && wire->GetSelected() ) || (wire && !m_drawWire ) || !wire )
1944  {
1945  hit->SetSelected( m_modehitLastSelectState );
1946  SetLastSelected( hit, m_modehitLastSelectState );
1947  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
1948  m_mode = mode_edit;
1949  PushEditTool( m_modehit );
1950  }
1951  }
1952  }
1953  }
1954  else if ( event.Dragging() && m_toolBusy && !m_dragStarted )
1955  {
1956  //we assume dragging starts for real if 5 pixels shift.
1957  if ( abs( m_x - m_dragstartx ) >= 5 || abs( m_y - m_dragstarty ) >= 5 )
1958  {
1959  m_dragStarted = true;
1960  SetToolMode( event.ControlDown(), event.ShiftDown(), event.AltDown() );
1961  m_toolBusy = false;
1962  switch( m_mode )
1963  {
1964  case mode_none:
1965  {
1966  m_dragStarted = false;
1967  m_toolBusy = false;
1968  break;
1969  }
1970  case mode_dragmulti:
1971  {
1972  m_dragStarted = false;
1973  PushDragMultiTool( m_modehit );
1974  //event.Skip();
1975  break;
1976  }
1977  case mode_copymulti:
1978  {
1979  m_dragStarted = false;
1980  PushCopyMultiTool( m_modehit );
1981  //event.Skip();
1982  break;
1983  }
1984  case mode_drawwire:
1985  {
1986  m_dragStarted = false;
1987  m_toolBusy = false;
1988  break;
1989  }
1990  case mode_drag:
1991  {
1992  m_dragStarted = false;
1993  PushDragTool( m_modehit );
1994  //event.Skip();
1995  break;
1996  }
1997  case mode_move_pin:
1998  {
1999  m_dragStarted = false;
2000  PushMovePinTool( m_modehit );
2001  wxMouseEvent mouseevent( wxEVT_LEFT_DOWN );
2002  InitMouseEvent( mouseevent, m_dragstartx, m_dragstarty, event );
2003  m_stcontroller->GetFirstTool()->ProcessEvent( mouseevent );
2004  break;
2005  }
2006  case mode_rewire_pin:
2007  {
2008  m_dragStarted = false;
2009  PushRewirePinTool( m_modehit );
2010  wxMouseEvent mouseevent( wxEVT_LEFT_DOWN );
2011  InitMouseEvent( mouseevent, m_dragstartx, m_dragstarty, event );
2012  m_stcontroller->GetFirstTool()->ProcessEvent( mouseevent );
2013  break;
2014  }
2015  case mode_editwire_vertex:
2016  {
2017  m_dragStarted = false;
2018  PushEditWireVertexTool( m_modehit, m_modehitinfo.m_index );
2019  wxMouseEvent mouseevent( wxEVT_LEFT_DOWN );
2020  InitMouseEvent( mouseevent, m_dragstartx, m_dragstarty, event );
2021  m_stcontroller->GetFirstTool()->ProcessEvent( mouseevent );
2022  break;
2023  }
2024  case mode_editwire_segmenthorizontal:
2025  {
2026  m_dragStarted = false;
2027  PushEditWireSegmentHorizontalTool( m_modehit, m_modehitinfo.m_index );
2028  wxMouseEvent mouseevent( wxEVT_LEFT_DOWN );
2029  InitMouseEvent( mouseevent, m_dragstartx, m_dragstarty, event );
2030  m_stcontroller->GetFirstTool()->ProcessEvent( mouseevent );
2031  break;
2032  }
2033  case mode_editwire_segmentvertical:
2034  {
2035  m_dragStarted = false;
2036  PushEditWireSegmentVerticalTool( m_modehit, m_modehitinfo.m_index );
2037  wxMouseEvent mouseevent( wxEVT_LEFT_DOWN );
2038  InitMouseEvent( mouseevent, m_dragstartx, m_dragstarty, event );
2039  m_stcontroller->GetFirstTool()->ProcessEvent( mouseevent );
2040  break;
2041  }
2042  case mode_editwire_segmentinsert:
2043  {
2044  m_dragStarted = false;
2045  PushEditWireSegmentInsertTool( m_modehit, m_modehitinfo.m_index );
2046  wxMouseEvent mouseevent( wxEVT_LEFT_DOWN );
2047  InitMouseEvent( mouseevent, m_dragstartx, m_dragstarty, event );
2048  m_stcontroller->GetFirstTool()->ProcessEvent( mouseevent );
2049  break;
2050  }
2051  case mode_editwire_segment:
2052  {
2053  m_dragStarted = false;
2054  PushEditSegmentTool( m_modehit, m_modehitinfo.m_index );
2055  wxMouseEvent mouseevent( wxEVT_LEFT_DOWN );
2056  InitMouseEvent( mouseevent, m_dragstartx, m_dragstarty, event );
2057  m_stcontroller->GetFirstTool()->ProcessEvent( mouseevent );
2058  break;
2059  }
2060  default:
2061  m_toolBusy = true;
2062  break;
2063  }
2064  }
2065  }
2066  else if ( event.Dragging() && m_toolBusy && m_dragStarted )
2067  {
2068  }
2069  else if ( event.Moving() && !m_toolBusy )
2070  {
2071  SetToolMode( event.ControlDown(), event.ShiftDown(), event.AltDown() );
2072  event.Skip();
2073  }
2074  else if( event.LeftDown() && !m_toolBusy )
2075  {
2076  SetStateString( "" );
2077  m_dragStarted = false;
2078  m_xprev = m_x;
2079  m_yprev = m_y;
2080  m_dragstartx = m_x;
2081  m_dragstarty = m_y;
2082 
2083  if( !m_modehit )
2084  {
2085  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
2086  m_mode = mode_select;
2087  event.Skip();
2088  m_toolBusy = false;
2089  return;
2090  }
2091 
2092  switch( m_mode )
2093  {
2094  case mode_edit:
2095  m_toolBusy = true;
2096  break;
2097  case mode_select:
2098  m_toolBusy = true;
2099  break;
2100  case mode_move_pin:
2101  m_toolBusy = true;
2102  break;
2103  case mode_rewire_pin:
2104  m_toolBusy = true;
2105  break;
2106  case mode_drawwire:
2107  m_toolBusy = true;
2108  break;
2109  case mode_editwire_vertex:
2110  {
2111  if ( event.AltDown() )
2112  {
2113  PushEditWireVertexTool( m_modehit, m_modehitinfo.m_index );
2114  event.Skip();
2115  }
2116  else
2117  m_toolBusy = true;
2118  break;
2119  }
2120  case mode_editwire_segmenthorizontal:
2121  case mode_editwire_segmentvertical:
2122  case mode_editwire_segmentinsert:
2123  case mode_editwire_segment:
2124  m_toolBusy = true;
2125  break;
2126  default:
2127  // not know until a drag started or not.
2128  m_mode = mode_none;
2129  m_toolBusy = true;
2130  event.Skip();
2131  }
2132  }
2133  else if( event.LeftUp() && m_toolBusy && m_dragStarted )
2134  {
2135  m_toolBusy = false;
2136  m_dragStarted = false; //end of drag
2137  m_mode = mode_none;
2138  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
2139  }
2140  else if( event.LeftUp() && m_toolBusy )
2141  {
2142  m_toolBusy = false;
2143  m_dragStarted = false; //never started but still
2144 
2145  //reserve for double click if it happens
2146  m_modehitLastSelectState = false;
2147  if ( m_modehit )
2148  m_modehitLastSelectState = m_modehit->GetSelected();
2149 
2150  if ( m_mode == mode_select || ( m_mode == mode_drawwire && event.ShiftDown() ) )
2151  {
2152  if ( !m_modehit )
2153  DeselectAll();
2154  if ( m_modehit && m_modehit->GetSelectable() )
2155  {
2156  m_modehit->SetSelected( !m_modehitLastSelectState );
2157  SetLastSelected( m_modehit, !m_modehitLastSelectState );
2158  }
2159  }
2160  else if ( m_mode == mode_drawwire ) //&& event.ControlDown() )
2161  {
2162  m_toolBusy = false;
2163  //When pin was generated on a wire at mouse moving), use it here.
2164  a2dPin* pin = wxDynamicCast( m_modehit, a2dPin );
2165  // if in draw wire mode, we must be able to start a wire on a pin
2166  if( pin )
2167  {
2168  // wire drawing mode
2169  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
2170  m_mode = mode_drawwire;
2171  m_modehit = pin;
2172  PushDrawWireTool( m_modehit );
2173 
2174  wxMouseEvent mouseevent( wxEVT_LEFT_DOWN );
2175  mouseevent.m_x = m_dragstartx;
2176  mouseevent.m_y = m_dragstarty;
2177  mouseevent.m_controlDown = true;
2178  mouseevent.m_leftDown = true;
2179  mouseevent.SetEventObject(this);
2180  mouseevent.SetId( GetDrawingPart()->GetDisplayWindow()->GetId() );
2181  m_stcontroller->GetFirstTool()->ProcessEvent( mouseevent );
2182 
2183  wxMouseEvent mouseevent2( wxEVT_LEFT_UP );
2184  mouseevent2.m_x = m_dragstartx;
2185  mouseevent2.m_y = m_dragstarty;
2186  mouseevent2.m_controlDown = true;
2187  mouseevent2.m_leftDown = true;
2188  mouseevent2.SetEventObject(this);
2189  mouseevent2.SetId( GetDrawingPart()->GetDisplayWindow()->GetId() );
2190  m_stcontroller->GetFirstTool()->ProcessEvent( mouseevent2 );
2191  }
2192  }
2193  else if ( !m_dragStarted && m_mode == mode_edit )
2194  {
2195  m_toolBusy = false;
2196  a2dCanvasObject* hit = m_modehit;
2197  a2dPin* pin = wxDynamicCast( m_modehit, a2dPin );
2198 
2199  if ( hit && !pin )
2200  {
2201  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Edit ) );
2202  PushEditTool( m_modehit );
2203  }
2204  /*
2205  if ( m_dlgOrEdit && ! hit->GetFixedStyle() && !event.ShiftDown() ||
2206  !m_dlgOrEdit && ! hit->GetFixedStyle() && event.ShiftDown()
2207  )
2208  {
2209  if ( !m_dlgOrEditModal )
2210  GetDrawing()->GetCanvasCommandProcessor()->ShowDlgStyle( true );
2211  else
2212  {
2213  a2dStyleDialog styleDlg( NULL, wxDEFAULT_DIALOG_STYLE | wxDIALOG_NO_PARENT | wxMINIMIZE_BOX | wxMAXIMIZE_BOX, true );
2214  styleDlg.SetFill( hit->GetFill() );
2215  styleDlg.SetStroke( hit->GetStroke() );
2216  if ( styleDlg.ShowModal() == wxID_OK )
2217  {
2218  if ( !hit->GetSelected() )
2219  {
2220  hit->SetFill( styleDlg.GetFill() );
2221  hit->SetStroke( styleDlg.GetStroke() );
2222  }
2223  else
2224  GetDrawing()->GetCanvasCommandProcessor()->Submit( new a2dCommand_SetFillStrokeMask( GetDrawingPart()->GetShowObject() ) );
2225  }
2226  }
2227  }
2228  else
2229  {
2230  a2dWirePolylineL* wire = wxDynamicCast( hit, a2dWirePolylineL );
2231  m_modehit = hit;
2232 
2233  if ( (wire && wire->GetSelected() ) || (wire && !m_drawWire ) || !wire )
2234  {
2235  hit->SetSelected( m_modehitLastSelectState );
2236  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
2237  m_mode = mode_edit;
2238  PushEditTool( m_modehit );
2239  }
2240  }
2241  */
2242  }
2243 
2244  SetToolMode( event.ControlDown(), event.ShiftDown(), event.AltDown() );
2245  }
2246  else if( event.RightDown() && !GetBusy() )
2247  {
2248  PushZoomTool();
2249  event.Skip();
2250  }
2251  else
2252  {
2253  event.Skip();
2254  }
2255 }
a2dStroke GetTextStroke() const
get the current text stroke
Definition: canglob.cpp:1025
a2dPin * FindNonWirePin(a2dCanvasObjectFlagsMask mask=a2dCanvasOFlags::ALL)
Definition: canpin.cpp:1012
a2dHit m_how
return in which way the object was hit (stroke, fill, ...)
Definition: canobj.h:301
virtual void SetActive(bool active=true)
set the tool active or inactive.
double GetHeight() const
returns height of the boundingbox
Definition: bbox.cpp:334
#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
wxUint16 GetLayer() const
layer set for new objects.
Definition: canglob.h:930
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
Interactive drag a new object into a drawing.
Definition: sttool.h:1189
bool m_dragStarted
used to indicate that a first drag event has arrived.
Definition: sttool.h:374
static const a2dSignal sig_changedFill
when active drawing is set, this signal is send to the drawing.
Definition: canglob.h:1187
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
bool GetActive()
is the tool active?
Definition: tools.h:497
a2dCanvasCommandProcessor * GetCanvasCommandProcessor()
Returns a pointer to the command processor associated with this document.
Definition: tools.cpp:976
bool GetEditable() const
get if the object may be edited
Definition: canobj.h:1584
The a2dBaseTool is used to derive tools from that are controlled by.
Definition: tools.h:379
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 DoStopTool(bool abort)
to do tool specific stuff to stop a tool. Called from StopTool().
Definition: mastertool.cpp:900
int m_x
x of mouse in device
Definition: sttool.h:352
double GetHitMargin()
Definition: tools.cpp:983
a2dPin is used in a2dCanvasObject to add pins to it.
Definition: canpin.h:233
stack based tools for drawing and editing in a faster manner, but with less document feedback...
wxPoint GetMousePosition()
return mouse position in device coordinates
Definition: sttool.h:631
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
generate pins, given Connect/wire pinclass
Definition: connectgen.h:48
a2dDrawingPart * GetDrawingPart()
Access to the tool controllers drawer.
Definition: tools.h:632
int m_dragstarty
y of mouse in device at start drag
Definition: sttool.h:371
void ConnectEvent(wxEventType type, wxEvtHandler *eventSink)
Definition: gen.cpp:876
a2dStToolContr * m_stcontroller
controller for canvas
Definition: sttool.h:391
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
a command processor specially designed to work with a a2dCanvasDocument
Definition: drawing.h:1046
void DoStopTool(bool abort)
to do tool specific stuff to stop a tool. Called from StopTool().
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
float m_distance
For margin hits, the distance from the stroke center in fractions of the margin.
Definition: polyver.h:93
set layer of objects which fit the mask
Definition: drawing.h:2891
a2dCanvasObject is the base class for Canvas Objects.
Definition: canobj.h:371
property to hold a a2dObjectPtr smart pointer type variable to be associated with a a2dObject ...
Definition: gen.h:2199
wxUint32 GetConnectedPinsNr() const
Get the number of connected pins.
Definition: canpin.cpp:738
a2dPin * FindWirePin(a2dCanvasObjectFlagsMask mask=a2dCanvasOFlags::ALL)
Definition: canpin.cpp:1029
a2dCanvasObjectList * GetChildObjectList()
get the list where the child objects are stored in.
Definition: canobj.cpp:2551
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
void AbortBusyMode()
Called when the user aborts editing a distinct object */.
void DoStopTool(bool abort)
to do tool specific stuff to stop a tool. Called from StopTool().
bool ProcessEvent(wxEvent &event)
events recieved from controller processed here
Definition: tools.cpp:668
used to change style of canvas objects in a a2dCanvasDocument
Definition: drawing.h:2201
bool IsVisible() const
get visibility (rendering depends on layer settings also)
Definition: canobj.h:1316
master tool using tags to groups object
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
void Expand(const a2dPoint2D &, const a2dPoint2D &)
expand boundingbox width two points
Definition: bbox.cpp:155
double GetMinX() const
get minimum X of the boundingbox
Definition: bbox.cpp:304
#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
const a2dStroke & GetStroke() const
get the current stroke
Definition: canglob.h:797
The a2dStToolContr is a Tool Controller specialized for working with a2dCanvasView.
Definition: sttool.h:485
wxWindow * GetDisplayWindow()
Access to the tool controllers drawers canvas.
Definition: tools.cpp:964
static const a2dCanvasObjectFlagsMask SELECTABLE
Definition: candefs.h:182
#define EVT_COM_EVENT(func)
static wxEvtHandler for communication event
Definition: gen.h:564
void Render()
implement rendering
Interactive drawing of a polyline wire.
Definition: sttool.h:1930
a2dCanvasObject * GetShowObject() const
return pointer of then currently shown object on the drawer.
Definition: drawer.h:680
objects which fit the mask are given a new fill and stroke style
Definition: drawing.h:3480
Restriction engine for editing restrictions like snapping.
Definition: restrict.h:88
int CollectObjects(a2dCanvasObjectList *total, const wxString &type=wxT(""), a2dCanvasObjectFlagsMask mask=a2dCanvasOFlags::ALL, const a2dPropertyId *id=NULL, const a2dBoundingBox &bbox=wxNonValidBbox)
Copy objects fitting the given filter to the total list.
Definition: objlist.cpp:663
int m_yprev
previous y of mouse in device
Definition: sttool.h:360
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
void SetEndSegmentMode(a2dNextSeg mode)
a2dDrawWirePolylineLTool segment mode initilization
Definition: canglob.h:965
bool IsSelected() const
Is the object selected flag set.
Definition: canobj.h:1610
void RemovePins(bool NotConnected=false, bool onlyTemporary=false, bool now=false)
Remove all a2dPin children.
Definition: canobj.cpp:6504
This tool is for editing a single object.
Definition: edit.h:73
a2dFill GetTextFill() const
get the current text fill
Definition: canglob.cpp:1032
a2dCanvasObject * ChildIsHitWorld(a2dIterC &ic, a2dHitEvent &hitEvent, bool filterSelectableLayers=false)
Do hittest on children.
Definition: canobj.cpp:3289
bool IsTemporaryPin() const
return true if this pin is a temporary pin
Definition: canpin.h:433
void SetLastXyEntry(double x, double y)
set last mouse X position in world coordinates, as set by tools.
Definition: canglob.h:774
void AbortBusyMode()
Called when the user aborts editing a distinct object */.
double m_xwprev
x world coordinates old or new value of mouse
Definition: sttool.h:363
void InitMouseEvent(wxMouseEvent &eventnew, int x, int y, wxMouseEvent &event)
Definition: mastertool.cpp:370
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
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
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
const a2dStroke & GetStroke() const
get the current stroke
Definition: tools.h:551
const a2dFill & GetFill() const
get the current fill
Definition: canglob.h:804
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
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
static const a2dCanvasObjectFlagsMask VISIBLE
Definition: candefs.h:186
static const a2dSignal sig_toolPoped
sent to new first tool when last first tool was poped
Definition: tools.h:386
int m_y
y of mouse in device
Definition: sttool.h:354
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
bool GetRelease() const
get release flag
Definition: gen.h:1350
a2dCanvasCommandProcessor * GetCanvasCommandProcessor()
get a pointer to the command processor
Definition: drawing.cpp:375
double GetWidth() const
returns width of the boundingbox
Definition: bbox.cpp:328
a2dBaseTool * GetFirstTool() const
get currently used eventhandler (always the first in the list)
Definition: tools.cpp:91
const a2dFill & GetFill() const
get the current fill
Definition: tools.h:542
Master tool for objects graphics slecting and dragging.
a2dStTool(a2dStToolContr *controller)
Definition: sttool.cpp:982
see a2dComEvent
Definition: gen.h:371
a2dCanvasObject * Find(a2dCanvasObject *obj) const
return the object if it is part of the list
Definition: objlist.cpp:553
bool GetSelectable() const
is the object selectable flag set
Definition: canobj.h:1648
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 ...
virtual void SetActive(bool active=true)
set the tool active or inactive.
a2dCanvasObjectList * Clone(a2dObject::CloneOptions options) const
Clone everything ( Clones objects also) in a new created list.
Definition: objlist.cpp:173
double GetMinY() const
get minimum Y of the boundingbox
Definition: bbox.cpp:310
bool GetSelected2() const
is the object selected2 flag set
Definition: canobj.h:1629
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
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 SetCursorType(const wxCursor &cursor)
Sets cursor which the tool should use when started.
Definition: tools.h:582
bool GetBusy()
Check if the tool is busy editing a distinct object */.
Definition: tools.h:513
int CollectObjects(a2dCanvasObjectList *total, const wxString &classname=wxT(""), a2dCanvasObjectFlagsMask mask=a2dCanvasOFlags::ALL, const a2dPropertyId *id=0, const a2dBoundingBox &bbox=wxNonValidBbox) const
Copy objects with the right conditions to the total list.
Definition: canobj.cpp:4495
void Render()
implement rendering
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
int m_xprev
previous x of mouse in device
Definition: sttool.h:357
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
void ToolWorldToMouse(double xWorld, double yWorld, int &x, int &y)
Definition: drawer.cpp:1114
A pointer class, that automatically calls SmrtPtrOwn/SmrtPtrRelease.
Definition: a2dlist.h:20
virtual void SetActive(bool active=true)
set the tool active or inactive.
Definition: sttool.cpp:1099
bool DisconnectEvent(wxEventType type, wxEvtHandler *eventSink)
Definition: gen.cpp:902
bool GetDraggable() const
get if the object can be dragged
Definition: canobj.h:1676
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
virtual bool RestrictPoint(double &x, double &y, wxUint32 sourceRequired=snapToAll, bool ignoreEngine=false)
Restrict a single point of a line or polyline.
Definition: restrict.cpp:227
void SetFill(const a2dFill &fill)
Set a fill for the object which will be used instead of the layer fill.
Definition: canobj.cpp:2874
void StartToEdit(a2dCanvasObject *startObject)
start editing this object
Definition: edit.cpp:1445
mastertoolgroups3.cpp Source File -- Sun Oct 12 2014 17:04:22 -- Sun Oct 12 2014 -- 1.8.5 -- wxArt2D -- . -- Main Page Reference Documentation