wxArt2D
mastertoolgroups.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 // a2dMasterTagGroups
32 //----------------------------------------------------------------------------
33 
34 IMPLEMENT_CLASS( a2dMasterTagGroups , a2dMasterDrawBase )
35 
36 BEGIN_EVENT_TABLE( a2dMasterTagGroups , a2dMasterDrawBase )
37  EVT_MOUSE_EVENTS( a2dMasterTagGroups ::OnMouseEvent )
38  EVT_CHAR( a2dMasterTagGroups ::OnChar )
39  EVT_KEY_DOWN( a2dMasterTagGroups ::OnKeyDown )
40  EVT_KEY_UP( a2dMasterTagGroups ::OnKeyUp )
41 END_EVENT_TABLE()
42 
43 a2dMasterTagGroups ::a2dMasterTagGroups ( a2dStToolContr* controller ): a2dMasterDrawBase( controller )
44 {
45  controller->SetDefaultBehavior( controller->GetDefaultBehavior() | wxTC_NoDefaultKeys | wxTC_NoDefaultMouseActions );
46  m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_Select );
47  m_drawWire = false;
48 }
49 
50 a2dMasterTagGroups ::~a2dMasterTagGroups ()
51 {
52 }
53 
55 {
56 }
57 
59 {
61  m_toolBusy = false;
62 }
63 
65 {
67 
68  if ( selected )
69  {
70  DeselectAll();
71  }
72  if( GetBusy() && m_dragStarted )
73  {
74  switch( m_mode )
75  {
76  case mode_zoom:
77  case mode_select:
78  case mode_cntrlselect:
79  {
80  break;
81  }
82  default:
83  break;
84  }
85  }
86 
88 }
89 
90 void a2dMasterTagGroups::OnChar( wxKeyEvent& event )
91 {
92  //wxLogDebug(wxT("key %d"), event.GetKeyCode());
94 
96 
97  if ( selected )
98  {
99  event.Skip();
100  }
101  else if( GetBusy() && m_dragStarted )
102  {
103  switch( m_mode )
104  {
105  case mode_zoom:
106  case mode_select:
107  case mode_cntrlselect:
108  {
109  break;
110  }
111  default:
112  event.Skip();
113  break;
114  }
115  }
116  else
117  event.Skip();
118 }
119 
120 void a2dMasterTagGroups ::OnKeyDown( wxKeyEvent& event )
121 {
122  if ( !m_active )
123  {
124  event.Skip();
125  return;
126  }
127 
128  switch( event.GetKeyCode() )
129  {
130  case 'w':
131  case 'W':
132  {
133  m_drawWire = !m_drawWire;
134  SetToolMode( event.m_controlDown, event.m_shiftDown );
135  break;
136  }
137  default:
138  if ( event.m_controlDown || event.m_shiftDown )
139  SetToolMode( event.m_controlDown, event.m_shiftDown );
140  event.Skip();
141  }
142 }
143 
144 void a2dMasterTagGroups ::OnKeyUp( wxKeyEvent& event )
145 {
146  if ( !m_active )
147  {
148  event.Skip();
149  return;
150  }
151 
152  switch( event.GetKeyCode() )
153  {
154  case 'w':
155  case 'W':
156  {
157  SetToolMode( event.m_controlDown, event.m_shiftDown );
158  break;
159  }
160  default:
161  if ( !event.m_controlDown || !event.m_shiftDown )
162  SetToolMode( event.m_controlDown, event.m_shiftDown );
163  event.Skip();
164  }
165 }
166 
167 bool a2dMasterTagGroups::SetWireCursor( a2dWirePolylineL* wire, const a2dHitEvent& hitinfo )
168 {
169  a2dHit how2;
170  int i;
171  float minDist = FLT_MAX;
172  for( i = 0; i < hitinfo.m_extended.size(); i++ )
173  {
174  a2dWirePolylineL* wire2 = wxDynamicCast( hitinfo.m_extended[i].GetObject(), a2dWirePolylineL );
175  if( wire2 && hitinfo.m_extended[i].GetHitType().m_distance < minDist && hitinfo.m_extended[i].GetHitType().IsStrokeHit() )
176  //if( wire2 && hitinfo.m_extended[i].GetHitType().m_distance < minDist && hitinfo.m_extended[i].GetHitType().IsDirectStrokeHit() )
177  {
178  wire = wire2;
179  how2 = hitinfo.m_extended[i].GetHitType();
180  minDist = how2.m_distance;
181  }
182  }
183 
184  if ( wire )
185  {
186  // wire editing mode
187  // check, where the wire was hit:
188  m_modehit = wire;
189  m_modehitinfo = how2;
190  switch( how2.m_stroke2 )
191  {
192  case a2dHit::stroke2_vertex:
193  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireVertex ) );
194  m_mode = mode_editwire_vertex;
195  break;
196  case a2dHit::stroke2_edgehor:
197  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireSegmentHorizontal ) );
198  m_mode = mode_editwire_segmenthorizontal;
199  break;
200  case a2dHit::stroke2_edgevert:
201  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireSegmentVertical ) );
202  m_mode = mode_editwire_segmentvertical;
203  break;
204  case a2dHit::stroke2_edgeother:
205  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_WireSegmentInsert ) );
206  m_mode = mode_editwire_segmentinsert;
207  break;
208  default:
209  m_modehit = NULL;
210  m_modehitinfo = a2dHit();
211  }
212  }
213  return true;
214 }
215 
216 void a2dMasterTagGroups::SetToolMode( bool ctrl, bool shift )
217 {
218  //GetDrawingPart()->Update( a2dCANVIEW_UPDATE_PENDING );
219  a2dIterC ic( GetDrawingPart() );
220  ic.SetLayer( wxLAYER_ALL );
221  ic.SetObjectFilter( new a2dCanvasObjectFilterLayerMask( wxLAYER_ALL, a2dCanvasOFlags::VISIBLE | a2dCanvasOFlags::SELECTABLE ) );
222  a2dHitEvent hitinfo( m_xwprev, m_ywprev, false, a2dCANOBJHITOPTION_NONE, true );
224  //at the top level the group its matrix is to be ignored.
225  //Since it is normally NOT ignored within a2dCanvasObject, force an inverse.
226  hitinfo.m_xyRelToChildren = true;
227 
228  m_mode = mode_none;
229  m_modehit = 0;
230  m_modehitinfo = a2dHit();
231  a2dCanvasObject* hit = GetDrawingPart()->GetShowObject()->ChildIsHitWorld( ic, hitinfo, true );
232  GetDrawing()->GetHabitat()->GetConnectionGenerator()->SetPinsToBeginState( GetDrawingPart()->GetShowObject() );
233 
234  if ( !ctrl && shift )
235  {
236  if ( hit )
237  {
238  m_modehit = hit;
239  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
240  }
241  else
242  {
243  m_modehit = NULL;
244  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW ) );
245  }
246  m_mode = mode_select;
247  }
248  else
249  {
250  if ( hit )
251  {
252  // Check if there is pin
253  // This has highest priority
254  a2dPin* pin = NULL;
255  a2dHit how2;
256 
258 
259  if ( wire && wire->GetSelected() && m_drawWire )
260  {
261  SetWireCursor( wire, hitinfo );
262  }
263  else if ( wire )
264  {
265  if ( m_drawWire || ( !m_drawWire && ctrl ) )
266  {
267  GetDrawing()->GetHabitat()->GetConnectionGenerator()->
269  }
270  else
271  wire->RemovePins( true, true );
272 
273 
274  //we did hit a wire, still a pin at this location, can be of a wire or anay other object, depending on drawing order.
275  pin = GetDrawing()->GetHabitat()->GetConnectionGenerator()->
276  SearchPinForStartWire( GetDrawingPart()->GetShowObject(), m_xwprev, m_ywprev, a2dPinClass::Any, GetHitMargin() );
277 
278  if( pin )
279  {
280  // if in draw wire mode, we must be able to start a wire on a pin
281  // Else we just drag pins, if not connected to a normal object ( so a wire to wire pin ).
282  if ( !pin->IsTemporaryPin() && !( m_drawWire || ( !m_drawWire && ctrl ) ) &&
283  ( pin->GetParent()->IsConnect() && !pin->FindNonWirePin() )
284  )
285  {
286  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
287  m_mode = mode_move_pin;
288  m_modehit = pin;
289  }
290  // If we know we are on an objects pins, or at least a wire pin on that location, we can
291  // start a wire without extra Ctrl or special m_drawWire mode.
292  // So we can start multiple wires on a normal pin.
293  else if ( !pin->IsTemporaryPin() &&
294  ( ( pin->GetParent()->IsConnect() && pin->FindNonWirePin() ) || !pin->GetParent()->IsConnect() )
295  )
296  {
297  // wire drawing mode
298  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
299  m_mode = mode_drawwire;
300  m_modehit = pin;
301  }
302  else if ( m_drawWire || ( !m_drawWire && ctrl ) )
303  {
304  // wire drawing mode
305  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
306  m_mode = mode_drawwire;
307  m_modehit = pin;
308  }
309  }
310  else
311  {
312  if ( m_drawWire || ( !m_drawWire && ctrl ) )
313  {
314  // wire drawing mode
315  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
316  m_mode = mode_drawwire;
317  m_modehit = pin;
318  }
319  else
320  {
321  // a wire is not draggabble, but it might be editable, in that case we can drag segments and vertexes.
322  if( hit->GetEditable() )
323  {
324  SetWireCursor( wire, hitinfo );
325 /* We do not really want to drag wire do we, anyway connect object are !GetDraggable()?
326  if ( hit->GetSelected() )
327  {
328  m_modehit = hit;
329  if ( event.ControlDown() && event.ShiftDown() )
330  {
331  m_mode = mode_copymulti;
332  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Copy ) );
333  }
334  else //no shift no control
335  {
336  m_mode = mode_dragmulti;
337  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
338  }
339  }
340  else
341  {
342  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
343  m_mode = mode_select;
344  m_modehit = hit;
345  }
346 */
347  }
348  else
349  {
350  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
351  m_mode = mode_select;
352  m_modehit = hit;
353  }
354  }
355  }
356 
357  }
358  else //not a wire
359  {
360  if ( !shift && !ctrl )
361  {
362  //While moving event, there is no wire nor pin yet, therefore we can just feedback possible pin connection, based on the
363  // m_connectionGenerator.
364  GetDrawing()->GetHabitat()->GetConnectionGenerator()->
366 
367  pin = GetDrawing()->GetHabitat()->GetConnectionGenerator()->
368  SearchPinForStartWire( GetDrawingPart()->GetShowObject(), m_xwprev, m_ywprev, a2dPinClass::Any, GetHitMargin() );
369 
370  if ( pin )
371  {
373  if ( wire && wire->GetSelected() )
374  pin = NULL;
375  }
376  }
377 
378  // if not editing a wire, search for pins first, in order to start a wire draw, if not a pin hit ....
379  if( pin )
380  {
381  // wire drawing mode
382  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
383  m_mode = mode_drawwire;
384  m_modehit = pin;
385  }
386  else
387  {
388  if( hit->GetDraggable() )
389  {
390  if ( hit->GetSelected() )
391  {
392  m_modehit = hit;
393  if ( ctrl && shift )
394  {
395  m_mode = mode_copymulti;
396  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Copy ) );
397  }
398  else //no shift no control
399  {
400  m_mode = mode_dragmulti;
401  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
402  }
403  }
404  else
405  {
406  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
407  m_mode = mode_select;
408  m_modehit = hit;
409  }
410  }
411  else
412  {
413  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
414  m_mode = mode_select;
415  m_modehit = hit;
416  }
417  }
418  }
419  }
420  else
421  {
422  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW ) );
423  m_mode = mode_select;
424  m_modehit = hit;
425  }
426  }
427 }
428 
429 void a2dMasterTagGroups::OnMouseEvent( wxMouseEvent& event )
430 {
431  //MouseDump( event, "OnM " );
432 
433  if ( !m_active )
434  {
435  event.Skip();
436  return;
437  }
438  m_x = event.GetX();
439  m_y = event.GetY();
440 
442 
443  if ( event.LeftDClick() && !m_toolBusy && !( event.ControlDown() || event.ShiftDown() ) )
444  {
445  m_hadDoubleClick = true;
446  a2dCanvasObject* hit = m_modehit; //reuse from the LeftDown event.
447  if ( hit )
448  {
450  m_modehit = hit;
451 
452  if ( (wire && wire->GetSelected() ) || (wire && !m_drawWire ) || !wire )
453  {
454  hit->SetSelected( m_modehitLastSelectState );
455  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
456  m_mode = mode_edit;
457  PushEditTool( m_modehit );
458  }
459  }
460  }
461  else if ( event.Dragging() && m_toolBusy && !m_dragStarted )
462  {
463  //we assume dragging starts for real if 5 pixels shift.
464  if ( abs( m_x - m_dragstartx ) >= 5 || abs( m_y - m_dragstarty ) >= 5 )
465  {
466  //use last hit
467  a2dPin* pin = wxDynamicCast( m_modehit, a2dPin );
468  if ( !pin && event.ControlDown() && !event.ShiftDown() )
469  {
470  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
471  m_mode = mode_cntrlselect;
472  m_dragStarted = true;
473  }
474  else if ( !event.ControlDown() && event.ShiftDown() )
475  {
476  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
477  m_mode = mode_select;
478  m_dragStarted = true;
479  }
480  else
481  {
482  if( m_modehit && m_modehit->GetDraggable() )
483  {
484  if ( m_modehit->GetSelected() )
485  {
486  // if in draw wire mode, we must be able to start a wire on a pin
487  if( pin && !pin->IsTemporaryPin() && ( !m_drawWire || event.ControlDown() ) )
488  {
490  if ( wire )
491  {
492  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
493  m_mode = mode_move_pin;
494  m_toolBusy = false;
495  }
496  }
497  else if ( event.ControlDown() && event.ShiftDown() )
498  {
499  m_dragStarted = true;
500  m_mode = mode_copymulti;
501  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Copy ) );
502  }
503  else //no shift no control
504  {
505  m_mode = mode_dragmulti;
506  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
507  }
508  }
509  else //draggable not selected
510  {
511  // if in draw wire mode, we must be able to start a wire on a pin
512  if( pin && !pin->IsTemporaryPin() && ( !m_drawWire || event.ControlDown() ) )
513  {
515  if ( wire )
516  {
517  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
518  m_mode = mode_move_pin;
519  m_toolBusy = false;
520  }
521  }
522  else
523  {
524  a2dHit how2;
525  a2dWirePolylineL* wire = wxDynamicCast( m_modehit, a2dWirePolylineL );
526  if ( wire )
527  {
528  m_dragStarted = true;
529  }
530  else
531  {
532  m_mode = mode_drag;
533  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
534  }
535  }
536  }
537  }
538  else if( m_modehit ) //not draggable
539  {
540  a2dWirePolylineL* wire = wxDynamicCast( m_modehit, a2dWirePolylineL );
541  a2dPin* pin = wxDynamicCast( m_modehit, a2dPin );
542  if ( wire )
543  {
544  m_dragStarted = true;
545  }
546  // if in draw wire mode, we must be able to start a wire on a pin
547  else if( pin && !pin->IsTemporaryPin() && ( !m_drawWire || event.ControlDown() ) )
548  {
550  if ( wire )
551  {
552  m_dragStarted = true;
553  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
554  m_mode = mode_move_pin;
555  m_toolBusy = false;
556  }
557  else
558  {
559  //a pin on a normal object, wait until LeftUp to decide mode_drawwire
560  }
561  }
562  else
563  {
564  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
565  m_mode = mode_select;
566  }
567  }
568  else
569  {
570  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
571  m_mode = mode_select;
572  }
573  }
574 
575  m_toolBusy = false;
576  switch( m_mode )
577  {
578  case mode_move_pin:
579  PushMovePinTool( m_modehit );
580  event.Skip();
581  break;
582  case mode_cntrlselect:
583  DeselectAll();
584  m_toolBusy = true;
585  event.Skip();
586  break;
587  case mode_select:
588  break;
589  case mode_dragmulti:
590  {
591  PushDragMultiTool( m_modehit );
592  //event.Skip();
593  break;
594  }
595  case mode_copymulti:
596  {
597  PushCopyMultiTool( m_modehit );
598  //event.Skip();
599  break;
600  }
601  case mode_drag:
602  {
603  PushDragTool( m_modehit );
604  //event.Skip();
605  break;
606  }
607  case mode_copy:
608  {
609  PushCopyTool( m_modehit );
610  //event.Skip();
611  break;
612  }
613  case mode_editwire_vertex:
614  {
615  PushEditWireVertexTool( m_modehit, m_modehitinfo.m_index );
616  wxMouseEvent mouseevent( wxEVT_LEFT_DOWN );
617  InitMouseEvent( mouseevent, m_dragstartx, m_dragstarty, event );
618  m_stcontroller->GetFirstTool()->ProcessEvent( mouseevent );
619  event.Skip();
620  break;
621  }
622  case mode_editwire_segmenthorizontal:
623  {
624  PushEditWireSegmentHorizontalTool( m_modehit, m_modehitinfo.m_index );
625  wxMouseEvent mouseevent( wxEVT_LEFT_DOWN );
626  InitMouseEvent( mouseevent, m_dragstartx, m_dragstarty, event );
627  m_stcontroller->GetFirstTool()->ProcessEvent( mouseevent );
628  event.Skip();
629  break;
630  }
631  case mode_editwire_segmentvertical:
632  {
633  PushEditWireSegmentVerticalTool( m_modehit, m_modehitinfo.m_index );
634  wxMouseEvent mouseevent( wxEVT_LEFT_DOWN );
635  InitMouseEvent( mouseevent, m_dragstartx, m_dragstarty, event );
636  m_stcontroller->GetFirstTool()->ProcessEvent( mouseevent );
637  event.Skip();
638  break;
639  }
640  case mode_editwire_segmentinsert:
641  {
642  PushEditWireSegmentInsertTool( m_modehit, m_modehitinfo.m_index );
643  wxMouseEvent mouseevent( wxEVT_LEFT_DOWN );
644  InitMouseEvent( mouseevent, m_dragstartx, m_dragstarty, event );
645  m_stcontroller->GetFirstTool()->ProcessEvent( mouseevent );
646  event.Skip();
647  break;
648  }
649  case mode_editwire_segment:
650  {
651  PushEditSegmentTool( m_modehit, m_modehitinfo.m_index );
652  wxMouseEvent mouseevent( wxEVT_LEFT_DOWN );
653  InitMouseEvent( mouseevent, m_dragstartx, m_dragstarty, event );
654  m_stcontroller->GetFirstTool()->ProcessEvent( mouseevent );
655  event.Skip();
656  break;
657  }
658  default:
659  m_toolBusy = true;
660  break;
661  }
662  }
663  }
664  else if ( event.Dragging() && m_toolBusy && m_dragStarted )
665  {
666  }
667  else if ( event.Moving() && !m_toolBusy )
668  {
669  SetToolMode( event.ControlDown(), event.ShiftDown() );
670  event.Skip();
671  }
672  else if( event.LeftDown() && !m_toolBusy )
673  {
674  m_dragStarted = false;
675  m_xprev = m_x;
676  m_yprev = m_y;
677  m_dragstartx = m_x;
678  m_dragstarty = m_y;
679 
680  if( !m_modehit )
681  {
682  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
683  m_mode = mode_select;
684  event.Skip();
685  m_toolBusy = false;
686  return;
687  }
688 
689  switch( m_mode )
690  {
691  case mode_cntrlselect:
692  DeselectAll();
693  m_toolBusy = true;
694  break;
695  case mode_select:
696  m_toolBusy = true;
697  break;
698 
699  case mode_drawwire:
700  m_toolBusy = true;
701 
702  break;
703  default:
704  // not know until a drag started or not.
705  m_toolBusy = true;
706  //event.Skip(); //dont't do base LeftDown, wait until drag start to decide.
707  }
708  }
709  else if ( event.LeftUp() && m_hadDoubleClick )
710  {
711  m_hadDoubleClick = false;
712  }
713  else if( event.LeftUp() && m_toolBusy && m_dragStarted )
714  {
715  m_toolBusy = false;
716  m_mode = mode_none;
717  m_dragStarted = false; //end of drag
718  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
719  }
720  else if( event.LeftUp() && m_toolBusy )
721  {
722  m_toolBusy = false;
723  m_mode = mode_none;
724  m_dragStarted = false; //never started but still
725 
726  //reserve for double click if it happens
727  m_modehitLastSelectState = false;
728  if ( m_modehit )
729  m_modehitLastSelectState = m_modehit->GetSelected();
730 
731  if ( !event.ControlDown() && !event.ShiftDown() || ( !m_drawWire && event.ControlDown() ) )
732  {
733  DeselectAll();
734  if ( m_modehit && m_modehit->GetSelectable() )
735  {
736  if ( m_drawWire )
737  m_modehit->SetSelected( true );
738  else //is conflicting with starting a wire
739  m_modehit->SetSelected( !m_modehitLastSelectState );
740  }
741 
742  // generate pins and draw a wire.
743  a2dWirePolylineL* wire = wxDynamicCast( m_modehit, a2dWirePolylineL );
744  if ( wire && m_drawWire )
745  {
746  GetDrawing()->GetHabitat()->GetConnectionGenerator()->
748  }
749  a2dPin* pin = NULL;
750  pin = GetDrawing()->GetHabitat()->GetConnectionGenerator()->
751  SearchPinForStartWire( GetDrawingPart()->GetShowObject(), m_xwprev, m_ywprev, a2dPinClass::Any, GetHitMargin() );
752 
753  // if in draw wire mode, we must be able to start a wire on a pin
754  if( pin )
755  {
756  // wire drawing mode
757  GetDrawingPart()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
758  m_mode = mode_drawwire;
759  m_modehit = pin;
760  PushDrawWireTool( m_modehit );
761  wxMouseEvent mouseevent( wxEVT_LEFT_DOWN );
762  InitMouseEvent( mouseevent, m_dragstartx, m_dragstarty, event );
763  m_stcontroller->GetFirstTool()->ProcessEvent( mouseevent );
764  event.Skip();
765  }
766  }
767  else if ( event.ShiftDown() )
768  {
769  if ( m_modehit && m_modehit->GetSelectable() )
770  {
771  if ( m_modehit->IsSelected() )
772  m_modehit->SetSelected( false );
773  else
774  m_modehit->SetSelected( true );
775  }
776  }
777  else
778  {
779  if ( !m_modehit )
780  DeselectAll();
781  else
782  {
783  if ( m_modehit->GetSelected() )
784  {
785  if ( m_mode == mode_none && m_modehit->GetSelectable() )
786  m_modehit->SetSelected( ! m_modehit->GetSelected() );
787  }
788  else
789  {
790  if ( m_mode == mode_none && m_modehit->GetSelectable() )
791  {
793  if ( selected )
794  {
795  DeselectAll();
796  m_modehit->SetSelected( true );
797  }
798  else
799  {
800  m_modehit->SetSelected( true );
801  }
802  }
803  }
804  }
805  }
806 
807  SetToolMode( event.ControlDown(), event.ShiftDown() );
808 
809  }
810  else if( event.RightDown() && !GetBusy() )
811  {
812  PushZoomTool();
813  event.Skip();
814  }
815  else
816  {
817  event.Skip();
818  }
819 }
820 
a2dPin * FindNonWirePin(a2dCanvasObjectFlagsMask mask=a2dCanvasOFlags::ALL)
Definition: canpin.cpp:1012
#define wxDynamicCast(obj, className)
Define wxDynamicCast so that it will give a compiler error for unrelated types.
Definition: gen.h:75
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 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
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...
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
a2dStToolContr * m_stcontroller
controller for canvas
Definition: sttool.h:391
a2dDrawing * GetDrawing()
Returns a pointer to the drawing.
Definition: tools.cpp:969
void Render()
implement rendering
bool m_active
tool is operational
Definition: tools.h:777
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
a2dCanvasObject is the base class for Canvas Objects.
Definition: canobj.h:371
a2dCanvasObjectList * GetChildObjectList()
get the list where the child objects are stored in.
Definition: canobj.cpp:2551
void DoStopTool(bool abort)
to do tool specific stuff to stop a tool. Called from StopTool().
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
bool ProcessEvent(wxEvent &event)
events recieved from controller processed here
Definition: tools.cpp:668
master tool using tags to groups object
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
a2dExtendedResult m_extended
extended result information with e.g path to lead to the nested object hit
Definition: canobj.h:303
The a2dStToolContr is a Tool Controller specialized for working with a2dCanvasView.
Definition: sttool.h:485
static const a2dCanvasObjectFlagsMask SELECTABLE
Definition: candefs.h:182
a2dCanvasObject * GetShowObject() const
return pointer of then currently shown object on the drawer.
Definition: drawer.h:680
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
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
void AbortBusyMode()
Called when the user aborts editing a distinct object */.
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
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
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
a2dConnectionGenerator * GetConnectionGenerator() const
Get class for generating new connection objects between object and pins.
Definition: canglob.h:601
static const a2dCanvasObjectFlagsMask VISIBLE
Definition: candefs.h:186
int m_y
y of mouse in device
Definition: sttool.h:354
a2dBaseTool * GetFirstTool() const
get currently used eventhandler (always the first in the list)
Definition: tools.cpp:91
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
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 ...
Master tool for objects graphics slecting and dragging.
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
bool GetBusy()
Check if the tool is busy editing a distinct object */.
Definition: tools.h:513
a2dCanvasObject * GetParent() const
get parent object of the pin
Definition: canpin.h:295
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
bool GetDraggable() const
get if the object can be dragged
Definition: canobj.h:1676
structure to give as parameter to member functions of a2dCanvasObject
Definition: canobj.h:252
mastertoolgroups.cpp Source File -- Sun Oct 12 2014 17:04:22 -- Sun Oct 12 2014 -- 1.8.5 -- wxArt2D -- . -- Main Page Reference Documentation