wxArt2D
canpin.cpp
Go to the documentation of this file.
1 /*! \file canvas/src/canpin.cpp
2  \author Klaas Holwerda
3 
4  Copyright: 2000-2004 (c) Klaas Holwerda
5 
6  Licence: wxWidgets Licence
7 
8  RCS-ID: $Id: canprim.cpp,v 1.351 2009/07/24 16:35:01 titato Exp $
9 */
10 
11 #include "a2dprec.h"
12 
13 #ifdef __BORLANDC__
14 #pragma hdrstop
15 #endif
16 
17 #ifndef WX_PRECOMP
18 #include "wx/wx.h"
19 #endif
20 
21 #include <wx/wfstream.h>
22 #include <wx/module.h>
23 #include <wx/clipbrd.h>
24 
25 #include "wx/canvas/canobj.h"
26 #include "wx/canvas/canpin.h"
27 #include "wx/canvas/canglob.h"
28 #include "wx/canvas/drawer.h"
29 #include "wx/canvas/drawing.h"
30 #include "wx/canvas/wire.h"
31 #include "wx/canvas/cameleon.h"
32 
33 #include <algorithm>
34 
35 #if defined(__WXMSW__) && defined(__MEMDEBUG__)
36 #include <wx/msw/msvcrt.h>
37 #endif
38 
39 //----------------------------------------------------------------------------
40 // a2dHandle
41 //----------------------------------------------------------------------------
42 
43 a2dPropertyIdInt32* a2dHandle::PROPID_Width = NULL;
44 a2dPropertyIdInt32* a2dHandle::PROPID_Height = NULL;
45 a2dPropertyIdInt32* a2dHandle::PROPID_Radius = NULL;
46 
47 INITIALIZE_PROPERTIES( a2dHandle, a2dCanvasObject )
48 {
49 /*
50  PROPID_Width = new a2dPropertyIdInt32( wxT( "Width" ),
51  a2dPropertyId::flag_none, 0, static_cast < a2dPropertyIdInt32::Mptr >( &a2dHandle::m_width ) );
52  AddPropertyId( PROPID_Width );
53  PROPID_Height = new a2dPropertyIdInt32( wxT( "Height" ),
54  a2dPropertyId::flag_none, 0, static_cast < a2dPropertyIdInt32::Mptr >( &a2dHandle::m_height ) );
55  AddPropertyId( PROPID_Height );
56  PROPID_Radius = new a2dPropertyIdInt32( wxT( "Radius" ),
57  a2dPropertyId::flag_none, 0, static_cast < a2dPropertyIdInt32::Mptr >( &a2dHandle::m_radius ) );
58  AddPropertyId( PROPID_Radius );
59 */
60  return true;
61 }
62 
63 IMPLEMENT_DYNAMIC_CLASS( a2dHandle, a2dCanvasObject )
64 
65 const long a2dHandle::sm_HandleNoHit = wxGenNewId();
66 const long a2dHandle::sm_HandleHit = wxGenNewId();
67 bool a2dHandle::m_worldBased = false;
68 
69 BEGIN_EVENT_TABLE( a2dHandle, a2dCanvasObject )
70  EVT_CANVASOBJECT_MOUSE_EVENT( a2dHandle::OnCanvasObjectMouseEvent )
71  EVT_CANVASOBJECT_ENTER_EVENT( a2dHandle::OnEnterObject )
72  EVT_CANVASOBJECT_LEAVE_EVENT( a2dHandle::OnLeaveObject )
73 END_EVENT_TABLE()
74 
75 a2dHandle::a2dHandle()
76  : a2dCanvasObject()
77 {
78  m_parent = NULL;
79  m_flags.m_prerenderaschild = false;
80  m_width = GetHabitat()->GetHandleSize();
81  m_height = GetHabitat()->GetHandleSize();
82  m_radius = GetHabitat()->GetHandle()->GetRadius();
83  m_mode = sm_HandleNoHit;
84 }
85 
86 a2dHandle::a2dHandle( a2dCanvasObject* parent, double xc, double yc, const wxString& name,
87  double w, double h, double angle , double radius )
88  : a2dCanvasObject()
89 {
90  m_name = name;
91  m_parent = parent;
93 
94  Rotate( angle );
95  m_lworld.Translate( xc, yc );
96 
97  if ( w )
98  m_width = w;
99  else if ( parent && parent->GetRoot() )
100  m_width = parent->GetHabitat()->GetHandleSize();
101  else
102  m_width = a2dCanvasGlobals->GetHabitat()->GetHandleSize();
103  if ( h )
104  m_height = h;
105  else if ( parent && parent->GetRoot() )
106  m_height = parent->GetHabitat()->GetHandleSize();
107  else
108  m_height = a2dCanvasGlobals->GetHabitat()->GetHandleSize();
109 
110  m_radius = radius;
111  m_mode = sm_HandleNoHit;
112 
113  SetPending( true );
114 }
115 
116 void a2dHandle::Set( double xc, double yc, double w, double h, double angle, double radius )
117 {
118  m_flags.m_prerenderaschild = false;
119 
120  m_lworld.Identity();
121  Rotate( angle );
122  m_lworld.Translate( xc, yc );
123 
124  m_width = w;
125  m_height = h;
126  m_radius = radius;
127 
128  SetPending( true );
129 }
130 
131 void a2dHandle::Set2( double xc, double yc, const wxString& name )
132 {
133  m_flags.m_prerenderaschild = false;
134 
135  m_lworld.Identity();
136  m_lworld.Translate( xc, yc );
137 
138  if ( !name.IsEmpty() )
139  m_name = name;
140 
141  SetPending( true );
142 }
143 
144 a2dHandle::~a2dHandle()
145 {
146 }
147 
148 a2dHandle::a2dHandle( const a2dHandle& other, CloneOptions options, a2dRefMap* refs )
149  : a2dCanvasObject( other, options, refs )
150 {
151  m_width = other.m_width;
152  m_height = other.m_height;
153  m_radius = other.m_radius;
154  m_mode = other.m_mode;
155  m_parent = other.m_parent;
156  m_name = other.m_name;
157 
158 }
159 
161 {
162  m_parent = parent;
163 }
164 
166 {
167  return new a2dHandle( *this, options, refs );
168 };
169 
170 a2dBoundingBox a2dHandle::DoGetUnTransformedBbox( a2dBboxFlags WXUNUSED( flags ) ) const
171 {
172  a2dBoundingBox bbox;
173  bbox.Enlarge( 0 );
174  return bbox;
175 }
176 
177 bool a2dHandle::DoUpdate( UpdateMode mode, const a2dBoundingBox& childbox, const a2dBoundingBox& clipbox, const a2dBoundingBox& propbox )
178 {
179  if ( !m_bbox.GetValid() )
180  {
183  if ( m_worldBased )
184  m_worldExtend = wxMax( m_worldExtend, wxMax( m_width / 2.0, m_height / 2.0 ) );
185  else
186  m_pixelExtend = ( wxUint16 ) wxMax( m_pixelExtend, ( int ) wxMax( m_width / 2.0, m_height / 2.0 ) );
187  //assert( m_pixelExtend < 40 );
188  return true;
189  }
190  return false;
191 }
192 
193 void a2dHandle::DoRender( a2dIterC& ic, OVERLAP WXUNUSED( clipparent ) )
194 {
196  if ( !m_flags.m_selected )
197  {
198  ic.GetDrawer2D()->SetDrawerFill( GetHabitat()->GetHandle()->GetFill() );
199  ic.GetDrawer2D()->SetDrawerStroke( GetHabitat()->GetHandle()->GetStroke() );
200  }
201  else
202  {
203  ic.GetDrawer2D()->SetDrawerFill( GetHabitat()->GetSelectFill() );
204  ic.GetDrawer2D()->SetDrawerStroke( GetHabitat()->GetSelectStroke() );
205  }
206 
207  double x1 = 0;
208  double y1 = 0;
209  double dx = 0;
210  double dy = 0;
211  double dw = m_width;
212  double dh = m_height;
213  double dr = m_radius;
214  ic.GetTransform().TransformPoint( 0, 0, x1, y1 ); // the object position in absolute coordinates.
215  dx = ic.GetDrawer2D()->WorldToDeviceX( x1 );
216  dy = ic.GetDrawer2D()->WorldToDeviceY( y1 );
217 
218  if ( m_worldBased )
219  {
220  dw = fabs( ic.GetDrawer2D()->WorldToDeviceXRelNoRnd( dw ) );// + ic.GetWorldStrokeExtend();
221  dh = fabs( ic.GetDrawer2D()->WorldToDeviceYRelNoRnd( dh ) );// + ic.GetWorldStrokeExtend();
222  dr = fabs( ic.GetDrawer2D()->WorldToDeviceYRelNoRnd( dr ) );
223  }
224  else
225  {
226  dw = dw + ic.GetWorldStrokeExtend();
227  dh = dh + ic.GetWorldStrokeExtend();
228  }
229 
231 
232  if ( m_mode == sm_HandleHit )
233  {
235  ic.GetDrawer2D()->DrawLine( dx - dw / 2.0, dy, dx + dh / 2.0, dy );
236  ic.GetDrawer2D()->DrawLine( dx, dy + dh / 2.0, dx, dy - dh / 2.0 );
237  }
238  else if ( m_mode == sm_HandleNoHit )
239  {
240  ic.GetDrawer2D()->DrawCenterRoundedRectangle( dx, dy, dw, dh, dr );
241  }
242  else
243  {
244  //sofar un defined mode.
245 #ifdef __WXMSW__
246  ic.GetDrawer2D()->DrawCircle( dx, dy, _hypot( dw, dh ) );
247 #else
248  ic.GetDrawer2D()->DrawCircle( dx, dy, hypot( dw, dh ) );
249 #endif
250  }
251  ic.GetDrawer2D()->PopTransform();
252 
254 }
255 
257 {
258  //wxLogDebug(wxT("x=%12.6lf, y=%12.6lf"),x , y );
259  double xh, yh;
260  ic.GetTransform().TransformPoint( 0, 0, xh, yh );
261 
262  // Hit Tests are sometimes made for algorithmic purposes
263  // Then it might be hard to supply a drawer
264  // In this cases, the handle will appear to have zero size
265  // A better solution would be to have a drawer independent Device/World conversion scheme in the ic
266  double w = m_width;
267  double h = m_height;
268 
269  if ( m_worldBased )
270  {
271  w = w + ic.GetWorldStrokeExtend();
272  h = h + ic.GetWorldStrokeExtend();
273  }
274  else
275  {
276  w = fabs( ic.GetDrawer2D()->DeviceToWorldXRel( w ) ) + ic.GetWorldStrokeExtend();
277  h = fabs( ic.GetDrawer2D()->DeviceToWorldYRel( h ) ) + ic.GetWorldStrokeExtend();
278  }
279 
280  hitEvent.m_how = HitTestRectangle( hitEvent.m_x, hitEvent.m_y, xh - w / 2.0, yh - h / 2.0, xh + w / 2.0, yh + h / 2.0, 0 );
281  if ( hitEvent.m_how.IsHit() )
282  return hitEvent.m_how.IsHit();
283 
284  return hitEvent.m_how.IsHit();
285 }
286 
287 #if wxART2D_USE_CVGIO
288 void a2dHandle::DoSave( wxObject* parent, a2dIOHandlerXmlSerOut& out, a2dXmlSer_flag xmlparts , a2dObjectList* towrite )
289 {
290  a2dCanvasObject::DoSave( parent, out, xmlparts, towrite );
291  if ( xmlparts == a2dXmlSer_attrib )
292  {
293  out.WriteAttribute( wxT( "width" ), m_width );
294  out.WriteAttribute( wxT( "height" ), m_height );
295  if ( m_radius != 0.0 )
296  {
297  out.WriteAttribute( wxT( "radius" ), m_radius );
298  }
299  }
300  else
301  {
302  }
303 }
304 void a2dHandle::DoLoad( wxObject* parent, a2dIOHandlerXmlSerIn& parser, a2dXmlSer_flag xmlparts )
305 {
306  a2dCanvasObject::DoLoad( parent, parser, xmlparts );
307  if ( xmlparts == a2dXmlSer_attrib )
308  {
309  m_width = parser.RequireAttributeValueInt( wxT( "width" ) );
310  m_height = parser.RequireAttributeValueInt( wxT( "height" ) );
311  m_radius = parser.GetAttributeValueInt( wxT( "radius" ) );
312  m_name = parser.GetAttributeValue( wxT( "name" ), m_name );
313  }
314  else
315  {
316  }
317 }
318 #endif //wxART2D_USE_CVGIO
319 
321 {
322  // handles are always temporary
323  return true;
324 }
325 
326 void a2dHandle::OnCanvasObjectMouseEvent( a2dCanvasObjectMouseEvent& event )
327 {
328  if ( m_parent && !m_parent->GetEditingRender( ) )
329  {
330  event.Skip();
331  return;
332  }
333 /*
334  if ( ! (m_parent->GetBin2() && m_parent->GetBin() ) )
335  {
336  event.Skip();
337  return;
338  }
339 */
340  a2dIterC* ic = event.GetIterC();
341 
342  static double xprev;
343  static double yprev;
344  static bool pushed = false;
345 
346  double xw, yw;
347  xw = event.GetX();
348  yw = event.GetY();
349 
350  a2dRestrictionEngine* restrictEngine = GetHabitat()->GetRestrictionEngine();
351  /*
352  if (restrictEngine )
353  {
354  restrictEngine->SetShiftKeyDown( event.GetMouseEvent().ShiftDown() );
355  restrictEngine->SetAltKeyDown( event.GetMouseEvent().AltDown() );
356  }
357  */
358  // this is the absolute matrix relative to the parent object, so with out this handle its
359  // m_lworld included.
360  // a2dAffineMatrix atWorld = ic->GetTransform();
361 
362  if ( event.GetMouseEvent().LeftDown() )
363  {
364  ic->SetCorridorPath( true, this );
365  xprev = xw;
366  yprev = yw;
367  SetMode( sm_HandleHit );
368  pushed = true;
369  a2dHandleMouseEvent handleEvent( ic, this, xw, yw, event.GetMouseEvent() );
370  if ( m_parent )
371  m_parent->ProcessEvent( handleEvent );
372  }
373  else if ( event.GetMouseEvent().Dragging() )
374  {
375  double x, y;
376  x = xw - ( xprev - GetPosX() );
377  y = yw - ( yprev - GetPosY() );
378 
379  xprev = xw;
380  yprev = yw;
381  a2dHandleMouseEvent handleEvent( ic, this, xw, yw, event.GetMouseEvent() );
382  if ( m_parent )
383  m_parent->ProcessEvent( handleEvent );
384  }
385  else if ( event.GetMouseEvent().Moving() )
386  {
387  a2dHandleMouseEvent handleEvent( ic, this, xw, yw, event.GetMouseEvent() );
388  if ( m_parent )
389  m_parent->ProcessEvent( handleEvent );
390  }
391  else if ( event.GetMouseEvent().LeftUp() && ic->GetDrawingPart()->GetCaptured() )
392  {
393  SetMode( sm_HandleNoHit );
394  ic->SetCorridorPathToParent();
395  if ( pushed )
396  ic->GetDrawingPart()->PopCursor();
397  pushed = false;
398  a2dHandleMouseEvent handleEvent( ic, this, xw, yw, event.GetMouseEvent() );
399  if ( m_parent )
400  m_parent->ProcessEvent( handleEvent );
401  }
402  else
403  event.Skip();
404 }
405 
406 //#define _DEBUG_REPORTHIT
407 void a2dHandle::OnEnterObject( a2dCanvasObjectMouseEvent& event )
408 {
409  a2dIterC* ic = event.GetIterC();
410  m_mode = sm_HandleHit;
411  SetPending( true );
412 #ifdef _DEBUG_REPORTHIT
413  wxLogDebug( wxT( "hit = %s %p" ), wxT( "enter handle" ), this );
414 #endif
415 
416  double xw, yw;
417  xw = event.GetX();
418  yw = event.GetY();
419  a2dHandleMouseEvent handleEvent( ic, this, xw, yw, event.GetMouseEvent(), wxEVT_CANVASHANDLE_MOUSE_EVENT_ENTER );
420  if ( m_parent )
421  m_parent->ProcessEvent( handleEvent );
422 
423  //ic->GetDrawingPart()->PushCursor( GetHabitat()->GetCursor( a2dCURSOR_HandleEnter ) );
424 }
425 
426 void a2dHandle::OnLeaveObject( a2dCanvasObjectMouseEvent& event )
427 {
428  a2dIterC* ic = event.GetIterC();
429  m_mode = sm_HandleNoHit;
430  SetPending( true );
431 #ifdef _DEBUG_REPORTHIT
432  wxLogDebug( wxT( "hit = %s %p" ), wxT( "leave handle" ), this );
433 #endif
434 
435  double xw, yw;
436  xw = event.GetX();
437  yw = event.GetY();
438  a2dHandleMouseEvent handleEvent( ic, this, xw, yw, event.GetMouseEvent(), wxEVT_CANVASHANDLE_MOUSE_EVENT_LEAVE );
439  if ( m_parent )
440  m_parent->ProcessEvent( handleEvent );
441 
442  //ic->GetDrawingPart()->PopCursor();
443 }
444 
445 //----------------------------------------------------------------------------
446 // a2dPinClass
447 //----------------------------------------------------------------------------
448 
450 
452 
453 std::list< a2dPinClass* > a2dPinClass::m_allPinClasses;
454 
455 a2dPinClass::a2dPinClass( const wxString& name )
456 :m_flags(0)
457 {
458  m_name = name;
459  m_connectionGenerator = NULL;
460 }
461 
463 {
464 }
465 
467 {
468  std::list< a2dPinClass* >::iterator iter = m_canConnectTo.begin();
469  while( iter != m_canConnectTo.end() )
470  {
471  if ( ( *iter ) == pinClass )
472  iter = m_canConnectTo.erase( iter );
473  else
474  iter++;
475  }
476 }
477 
479 {
480  Standard = new a2dPinClass( wxT( "standard" ) );
481  Standard->AddConnect( a2dPinClass::Standard );
482  Standard->SetAngleLine( false );
483  m_allPinClasses.push_back( Standard );
484 
485  Any = new a2dPinClass( wxT( "anyPinClass" ) );
486  Any->AddConnect( a2dPinClass::Standard );
487  m_allPinClasses.push_back( Any );
488 }
489 
491 {
492  std::list< a2dPinClass* >::iterator iter;
493 
494  for( iter = m_allPinClasses.begin(); iter != m_allPinClasses.end(); ++iter )
495  delete ( *iter );
496  m_allPinClasses.clear();
497 }
498 
500 {
501  std::list< a2dPinClass* >::const_iterator iter;
502 
503  for( iter = m_canConnectTo.begin(); iter != m_canConnectTo.end(); ++iter )
504  {
505  if ( ( other == NULL || ( *iter ) == other ) )
506  return ( *iter );
507  }
508  return NULL;
509 }
510 
511 a2dPinClass* a2dPinClass::GetClassByName( const wxString& name )
512 {
513  std::list< a2dPinClass* >::iterator iter;
514 
515  for( iter = m_allPinClasses.begin(); iter != m_allPinClasses.end(); ++iter )
516  {
517  if ( ( *iter )->m_name == name )
518  return ( *iter );
519  }
520  return NULL;
521 }
522 
524 {
525  m_defPin = newpin;
526 }
527 
529 {
530  if ( !m_defPin )
531  {
532  m_defPin = new a2dPin( NULL, wxT( "templatePin" ), this, 0, 0, 0, a2dCanvasGlobals->GetHabitat()->GetPinSize(), a2dCanvasGlobals->GetHabitat()->GetPinSize() );
533  m_defPin->SetFill( *wxGREEN );
534  m_defPin->SetStroke( wxColour( 66, 159, 235 ), 0 );
535  }
536  return m_defPin;
537 }
538 
540 {
541  m_defCannotConnectPin = newpin;
542 }
543 
545 {
546  if ( !m_defCannotConnectPin )
547  {
548  m_defCannotConnectPin = new a2dPin( NULL, wxT( "templatePin" ), this, 0, 0, 0, a2dCanvasGlobals->GetHabitat()->GetPinSize(), a2dCanvasGlobals->GetHabitat()->GetPinSize() );
549  m_defCannotConnectPin->SetFill( wxColour( 255, 128, 128 ) );
550  m_defCannotConnectPin->SetStroke( *wxRED, 0 );
551  }
552  return m_defCannotConnectPin;
553 }
554 
556 {
557  m_defCanConnectPin = newpin;
558 }
559 
561 {
562  if ( !m_defCanConnectPin )
563  {
564  m_defCanConnectPin = new a2dPin( NULL, wxT( "templatePin" ), this, 0, 0, 0, a2dCanvasGlobals->GetHabitat()->GetPinSize(), a2dCanvasGlobals->GetHabitat()->GetPinSize() );
565  m_defCanConnectPin->SetFill( wxColour( 128, 255, 128 ) );
566  m_defCanConnectPin->SetStroke( *wxGREEN, 0 );
567  }
568  return m_defCanConnectPin;
569 }
570 
572 {
573  m_defParPin = newpin;
574 }
575 
577 {
578  if ( !m_defParPin )
579  {
580  m_defParPin = new a2dParPin( this, a2dCanvasGlobals->GetHabitat()->GetPinSize(), a2dCanvasGlobals->GetHabitat()->GetPinSize() );
581  }
582  return m_defParPin;
583 }
584 
585 //----------------------------------------------------------------------------
586 // a2dPin
587 //----------------------------------------------------------------------------
588 IMPLEMENT_DYNAMIC_CLASS( a2dPin, a2dCanvasObject )
589 
590 bool a2dPin::m_worldBased = false;
591 bool a2dPin::m_doRender = true;
592 
593 BEGIN_EVENT_TABLE( a2dPin, a2dCanvasObject )
594  EVT_CANVASOBJECT_ENTER_EVENT( a2dPin::OnEnterObject )
595  EVT_CANVASOBJECT_LEAVE_EVENT( a2dPin::OnLeaveObject )
596  EVT_CANVASOBJECT_MOUSE_EVENT( a2dPin::OnCanvasObjectMouseEvent )
597 END_EVENT_TABLE()
598 
599 const long a2dPin::sm_PinUnConnected = wxGenNewId();
600 const long a2dPin::sm_PinConnected = wxGenNewId();
601 const long a2dPin::sm_PinCanConnect = wxGenNewId();
602 const long a2dPin::sm_PinCannotConnect = wxGenNewId();
603 const long a2dPin::sm_PinCanConnectToPinClass = wxGenNewId();
604 
605 a2dPin::a2dPin()
606  : a2dCanvasObject()
607 {
608  m_parent = NULL;
609  m_flags.m_prerenderaschild = false;
610  m_width = a2dPinClass::Standard->GetPin()->GetWidth();
611  m_height = a2dPinClass::Standard->GetPin()->GetHeight();
612  //m_width = GetHabitat()->GetPinSize();
613  //m_height = GetHabitat()->GetPinSize();
614  m_radius = GetHabitat()->GetPin()->GetRadius();
615 
616  m_mode = sm_PinUnConnected;
617  m_pinclass = a2dPinClass::Standard;
618  m_RenderConnected = false;
619  m_dynamicPin = false;
620  m_temporaryPin = false;
621  m_internal = false;
622  m_objectPin = true;
623 }
624 
625 a2dPin::a2dPin( a2dCanvasObject* parent, const wxString& name, a2dPinClass* pinclass, double xc, double yc,
626  double angle , double w, double h, double radius )
627  : a2dCanvasObject()
628 {
629  m_name = name;
630  m_parent = parent;
631 
632  Rotate( angle );
633  m_lworld.Translate( xc, yc );
634 
635  m_radius = radius;
636 
637  m_width = w;
638  m_height = h;
639  if ( !w )
640  m_width = pinclass->GetPin()->GetWidth();
641 
642  if ( !h )
643  m_height = pinclass->GetPin()->GetHeight();
644 
646  m_name = name;
647  m_pinclass = pinclass;
648  m_flags.m_prerenderaschild = false;
649  m_RenderConnected = false;
650  m_dynamicPin = false;
651  m_temporaryPin = false;
652  m_internal = false;
653  m_objectPin = true;
654 
655  if ( m_parent )
656  {
657  m_parent->SetPending( true );
659  }
660 }
661 
662 
663 void a2dPin::Set( double xc, double yc, double angle, const wxString& name, bool dynamic )
664 {
666  m_flags.m_prerenderaschild = false;
667  m_lworld.Identity();
668  Rotate( angle );
669  m_lworld.Translate( xc, yc );
670 
671  SetPending( true );
672  if ( !name.IsEmpty() )
673  m_name = name;
674 }
675 
677 {
678  //disconnect from the connected pins (and object)
679  a2dPinList::iterator iter;
680  for ( iter = m_connectedPins.begin( ) ; iter != m_connectedPins.end( ) ; iter++ )
681  {
682  if ( (*iter ) )
683  (*iter)->Disconnect( this );
684  }
685  m_connectedPins.clear();
686 }
687 
688 a2dPin::a2dPinFlagsMask a2dPin::GetPinFlags() const
689 {
690  a2dPinFlagsMask oflags = a2dPin::NON;
691 
692  if ( m_dynamicPin ) oflags = oflags | a2dPin::dynamic;
693  if ( m_temporaryPin ) oflags = oflags | a2dPin::temporary;
694  if ( m_internal ) oflags = oflags | a2dPin::internal;
695  if ( m_objectPin ) oflags = oflags | a2dPin::objectPin;
696 
697  return oflags;
698 }
699 
700 void a2dPin::SetPinFlags( a2dPinFlagsMask which, bool value )
701 {
702  if ( value )
703  {
704  m_dynamicPin = 0 < (which & a2dPin::dynamic);
705  m_temporaryPin = 0 < (which & a2dPin::temporary);
706  m_internal = 0 < (which & a2dPin::internal);
707  m_objectPin = 0 < (which & a2dPin::objectPin);
708  }
709  else
710  {
711  m_dynamicPin = 0 > (which & a2dPin::dynamic);
712  m_temporaryPin = 0 > (which & a2dPin::temporary);
713  m_internal = 0 > (which & a2dPin::internal);
714  m_objectPin = 0 > (which & a2dPin::objectPin);
715  }
716 }
717 
718 void a2dPin::SetPinFlags( a2dPinFlagsMask which )
719 {
720  m_dynamicPin = 0 < (which & a2dPin::dynamic);
721  m_temporaryPin = 0 < (which & a2dPin::temporary);
722  m_internal = 0 < (which & a2dPin::internal);
723  m_objectPin = 0 < (which & a2dPin::objectPin);
724 }
725 
727 {
728  a2dPinList::iterator iter = m_connectedPins.begin();
729  while ( iter != m_connectedPins.end() )
730  {
731  if ( !(*iter ) )
732  iter = m_connectedPins.erase( iter );
733  else
734  iter++;
735  }
736 }
737 
739 {
740  wxUint32 connected = 0;
741  a2dPinList::const_iterator iter = m_connectedPins.begin();
742  while ( iter != m_connectedPins.end() )
743  {
744  if ( (*iter ) )
745  connected++;
746  iter++;
747  }
748  return connected;
749 }
750 
752 {
753  if ( pin )
754  {
755  a2dPinList::const_iterator iter;
756  iter = std::find( m_connectedPins.begin(), m_connectedPins.end(), pin );
757  bool found = false;
758  bool found2 = false;
759 
760  found = iter != m_connectedPins.end();
761  if ( found )
762  {
763  a2dPinList::const_iterator iter2;
764  for ( iter2 = pin->m_connectedPins.begin( ) ; iter2 != pin->m_connectedPins.end( ) ; iter2++ )
765  {
766  if ( *iter2 == this )
767  found2 = true;
768  }
769  wxASSERT_MSG( found2, _T( "connection not found in other pin" ) );
770  return (*iter);
771  }
772  return NULL;
773  }
774  else if ( m_connectedPins.empty() )
775  return NULL;
776  else
777  { //return first connected pin, empty items not counts as connected.
778  a2dPinList::const_iterator iter = m_connectedPins.begin();
779  while ( iter != m_connectedPins.end() )
780  {
781  if ( (*iter ) )
782  return (*iter);
783  iter++;
784  }
785  }
786  return NULL;
787 }
788 
789 bool a2dPin::Disconnect( a2dPin* pin, bool forceErase )
790 {
791  bool found = false;
792  a2dPinList::iterator iter = m_connectedPins.begin( );
793  while( iter != m_connectedPins.end( ) )
794  {
795  a2dPin* connectedPin = *iter;
796  if ( connectedPin && (connectedPin == pin || !pin) )
797  {
798  found = true;
799  bool found2 = false;
800  a2dPinList::iterator iter2 = connectedPin->m_connectedPins.begin( );
801  while( iter2 != connectedPin->m_connectedPins.end( ) )
802  {
803  if ( *iter2 == this )
804  {
805  (*iter2) = NULL;
806  if ( forceErase )
807  iter2 = connectedPin->m_connectedPins.erase( iter2 );
808  else
809  iter2++;
810  found2 = true;
811  }
812  else
813  iter2++;
814  }
815  connectedPin->m_mode = sm_PinUnConnected;
816  if ( connectedPin->IsConnectedTo() )
817  connectedPin->m_mode = sm_PinConnected;
818 
819  wxASSERT_MSG( found2, _T( "connection not found in other pin" ) );
820  (*iter) = NULL;
821  if ( forceErase )
822  iter = m_connectedPins.erase( iter );
823  else
824  iter++;
825  }
826  else
827  iter++;
828  }
830  if ( IsConnectedTo() )
832  return found;
833 }
834 
835 
837 {
838  a2dPinList::iterator iter = m_connectedPins.begin( );
839  while( iter != m_connectedPins.end( ) )
840  {
841  a2dPin* connectedPin = *iter;
842  if ( connectedPin && !connectedPin->GetRelease() )
843  {
844  bool found2 = false;
845  a2dPinList::iterator iter2 = m_connectedPins.begin( );
846  while( iter2 != m_connectedPins.end( ) )
847  {
848  a2dPin* connectedPinconnect = *iter2;
849 
850  if ( connectedPin != connectedPinconnect && !connectedPin->IsConnectedTo( connectedPinconnect ) )
851  {
852  if ( m_root->GetCommandProcessor() && undo )
853  m_root->GetCommandProcessor()->Submit( new a2dCommand_ConnectPins( connectedPin, connectedPinconnect ), true );
854  else
855  connectedPin->ConnectTo( connectedPinconnect );
856  }
857  iter2++;
858  }
859  }
860  iter++;
861  }
862 }
863 
864 void a2dPin::DuplicateConnectedPins( a2dPin* other, bool undo )
865 {
866  a2dPinList::iterator iter = other->m_connectedPins.begin( );
867  while( iter != other->m_connectedPins.end( ) )
868  {
869  a2dPin* connectedPin = *iter;
870  if ( connectedPin && !connectedPin->GetRelease() )
871  {
872  if ( connectedPin != this )
873  {
874  bool found2 = false;
875  a2dPinList::iterator iter2 = m_connectedPins.begin( );
876  while( iter2 != m_connectedPins.end( ) )
877  {
878  if ( *iter2 == connectedPin )
879  found2 = true;
880  iter2++;
881  }
882  if ( !found2 )
883  {
884  if ( undo )
885  m_root->GetCommandProcessor()->Submit( new a2dCommand_ConnectPins( this, connectedPin ), true );
886  else
887  ConnectTo( connectedPin );
888  }
889  }
890  }
891  iter++;
892  }
893 }
894 
896 {
897  a2dPinList::iterator iter = other->m_connectedPins.begin( );
898  while( iter != other->m_connectedPins.end( ) )
899  {
900  a2dPin* connectedPin = *iter;
901  if ( connectedPin && !connectedPin->GetRelease() && connectedPin != this )
902  {
903  bool found2 = false;
904  a2dPinList::iterator iter2 = m_connectedPins.begin( );
905  while( iter2 != m_connectedPins.end( ) )
906  {
907  if ( *iter2 == connectedPin )
908  Disconnect( connectedPin );
909  iter2++;
910  }
911  iter++;
912  }
913  else
914  iter++;
915  }
916 }
917 
918 void a2dPin::ConnectTo( a2dPin* connectto )
919 {
920  wxASSERT_MSG( connectto, _T( "connect pin should not be NULL" ) );
921  wxASSERT_MSG( connectto != this , _T( "connect pin should not be itself" ) );
922  if ( connectto != this )
923  {
924  //push in front, as it will be the first found when disconnecting it.
925  m_connectedPins.push_front( connectto );
926  connectto->m_connectedPins.push_front( this );
927  connectto->m_mode = sm_PinConnected;
929  }
930 }
931 
933 {
934  m_parent = parent;
935  if ( m_parent )
936  {
937  //No need m_parent->SetPending( true );
938  m_parent->SetHasPins( true );
940  if ( IsConnectedTo() )
942  }
943 }
944 
945 void a2dPin::SetPending( bool pending )
946 {
947  a2dCanvasObject::SetPending( pending );
948  //if ( m_parent && m_parent->IsConnect() )
949  // m_parent->SetPending( pending );
950 }
951 
953 {
955  tworld *= m_lworld;
956  return a2dPoint2D( tworld.GetValue( 2, 0 ), tworld.GetValue( 2, 1 ) );
957 }
958 
959 double a2dPin::GetAbsX() const
960 {
962  tworld *= m_lworld;
963  return tworld.GetValue( 2, 0 );
964 }
965 
966 double a2dPin::GetAbsY() const
967 {
969  tworld *= m_lworld;
970  return tworld.GetValue( 2, 1 );
971 }
972 
973 void a2dPin::SetAbsXY( double x, double y )
974 {
976  tworldInv.Invert();
977  double xt, yt;
978  tworldInv.TransformPoint( x, y, xt, yt );
979  SetPosXY( xt, yt );
980 
981  assert( fabs( x - GetAbsX() ) < 1e-3 );
982  assert( fabs( y - GetAbsY() ) < 1e-3 );
983 }
984 
985 void a2dPin::SetAbsXY( const a2dPoint2D& point )
986 {
987  SetAbsXY( point.m_x, point.m_y );
988 }
989 
990 double a2dPin::GetAbsAngle() const
991 {
993  tworld *= m_lworld;
994  return tworld.GetRotation();
995 }
996 
997 bool a2dPin::MayConnectTo( a2dPin* connectto )
998 {
999  // Check if both sides agree if they can connect or not.
1000  // If one can connect to the other, but the other is not allowed to connect to the one,
1001  // this indicates conflicting pin classes.
1002  wxASSERT_MSG( ( GetPinClass()->CanConnectTo( connectto->GetPinClass() ) != NULL ) == ( connectto->GetPinClass()->CanConnectTo( GetPinClass() ) != NULL )
1003  , wxT( "pinclass incompatible on both sides" ) );
1004 
1005  //!todo is a seperate task needed?
1006  return GetPinClass()->GetPinClassForTask( a2d_GeneratePinsForPinClass, m_parent, connectto->GetPinClass(), connectto ) != NULL;
1007 
1008  // Otherwise check if the pin classes are compatible
1009  return GetPinClass()->CanConnectTo( connectto->GetPinClass() ) != NULL;
1010 }
1011 
1013 {
1014  //return first connected non wire pin, empty items not count as connected.
1015  a2dPinList::const_iterator iter = m_connectedPins.begin();
1016  while ( iter != m_connectedPins.end() )
1017  {
1018  a2dCanvasObject* obj = *iter;
1019  if ( obj && !obj->GetRelease() )
1020  {
1021  if ( !obj->GetParent()->IsConnect() && obj->GetParent()->CheckMask( mask ) )
1022  return *iter;
1023  }
1024  iter++;
1025  }
1026  return NULL;
1027 }
1028 
1030 {
1031  //return first connected non wire pin, empty items not count as connected.
1032  a2dPinList::const_iterator iter = m_connectedPins.begin();
1033  while ( iter != m_connectedPins.end() )
1034  {
1035  a2dCanvasObject* obj = *iter;
1036  if ( obj && !obj->GetRelease() )
1037  {
1038  if ( obj->GetParent()->IsConnect() && obj->GetParent()->CheckMask( mask ) )
1039  return *iter;
1040  }
1041  iter++;
1042  }
1043  return NULL;
1044 }
1045 
1046 a2dPin* a2dPin::FindConnectablePin( a2dCanvasObject* root, double margin, bool autocreate )
1047 {
1048  //!todo One bad thing about this is, that the margin is given in world units
1049 
1050  // Check if the parent of this pin is a DIRECT child of the root given
1051  assert( root->Find( m_parent ) );
1052 
1053  // Go through the childs of the root and look for objects having pins
1054  a2dIterC ic;
1055  a2dIterCU icu( ic, root );
1056 
1057  for( a2dCanvasObjectList::iterator iter = root->GetChildObjectList()->begin(); iter != root->GetChildObjectList()->end(); ++iter )
1058  {
1059  a2dCanvasObject* obj = *iter;
1060  if( !obj->CheckMask( a2dCanvasOFlags::HasPins ) ) continue;
1061  if( obj == m_parent ) continue;
1062 
1063  // Check if obj has a pin that can connect to this pin
1064  a2dPin* rslt = obj->CanConnectWith( ic, this, margin, autocreate );
1065 
1066  if( rslt )
1067  return rslt;
1068  }
1069  return 0;
1070 }
1071 
1072 void a2dPin::AutoConnect( a2dCanvasObject* root, double margin )
1073 {
1074  // Check if this is an original object, not an editcopy
1075  wxASSERT( !PROPID_Original->GetPropertyValue( this ) );
1076 
1077  // First check if this pin is dislocated or unconnected
1078  if( IsDislocated() || !IsConnectedTo() )
1079  {
1080  a2dPin* rslt = FindConnectablePin( root, margin, true );
1081  if( rslt )
1082  {
1083  // Connect them
1084  GetRoot()->GetCanvasCommandProcessor()->Submit( new a2dCommand_ConnectPins( this, rslt ), true );
1085  }
1086  }
1087 }
1088 
1090 {
1091  double maxdx = GetHabitat()->GetCoordinateEpsilon();
1092  double maxdy = GetHabitat()->GetCoordinateEpsilon();
1093  a2dPin* found = NULL;
1094 
1095  a2dPoint2D thispos = GetAbsXY();
1096  a2dPinList::const_iterator iter;
1097  for ( iter = m_connectedPins.begin( ) ; iter != m_connectedPins.end( ) ; iter++ )
1098  {
1099  a2dPin* connectedPin = *iter;
1100  if ( !connectedPin || connectedPin->GetRelease() )
1101  continue;
1102  a2dPoint2D otherpos = connectedPin->GetAbsXY();
1103  double dx = fabs( thispos.m_x - otherpos.m_x );
1104  double dy = fabs( thispos.m_y - otherpos.m_y );
1105  if ( dx > maxdx || dy > maxdy )
1106  {
1107  found = connectedPin;
1108  maxdx = dx;
1109  maxdy = dy;
1110  }
1111  }
1112  return found;
1113 }
1114 
1115 bool a2dPin::IsSameLocation( a2dPin* other, double margin ) const
1116 {
1117  if ( ! margin )
1118  margin = GetHabitat()->GetCoordinateEpsilon();
1119 
1120  a2dPoint2D thispos = GetAbsXY();
1121  a2dPoint2D otherpos = other->GetAbsXY();
1122  if (
1123  fabs( thispos.m_x - otherpos.m_x ) < margin &&
1124  fabs( thispos.m_y - otherpos.m_y ) < margin
1125  )
1126  return true;
1127  return false;
1128 }
1129 
1130 a2dPin::a2dPin( const a2dPin& other, CloneOptions options, a2dRefMap* refs )
1131  : a2dCanvasObject( other, options, refs )
1132 {
1133  m_width = other.m_width;
1134  m_height = other.m_height;
1135  m_radius = other.m_radius;
1136  m_parent = other.m_parent;
1137  m_name = other.m_name;
1138 
1139  // wxLogDebug("Cloning pin %p into %p\n", &other, this );
1140  m_pinclass = other.m_pinclass;
1141  // Don't copy the m_connectedPins. The pins are mutally connected, and we can not copy that.
1143  m_RenderConnected = false;
1144  m_dynamicPin = other.m_dynamicPin;
1146  m_internal = other.m_internal;
1147  m_objectPin = other.m_objectPin;
1148 
1149  if( refs )
1150  {
1151  wxASSERT_MSG( refs, wxT( "for reconnect a2dRefMap needed" ) );
1152 
1153  a2dPinList::const_iterator iter;
1154  for ( iter = other.m_connectedPins.begin( ) ; iter != other.m_connectedPins.end( ) ; iter++ )
1155  {
1156  a2dPin* connectedPin = *iter;
1157  if ( connectedPin )
1158  {
1159  int id = connectedPin->GetUniqueSerializationId();
1160  wxASSERT( id != 0 );
1161  wxString resolveKey;
1162  resolveKey << id;
1163  refs->ResolveOrAddLink( this, resolveKey );
1164  }
1165  }
1166  }
1167 }
1168 
1170 {
1171  return new a2dPin( *this, options, refs );
1172 };
1173 
1174 a2dBoundingBox a2dPin::DoGetUnTransformedBbox( a2dBboxFlags WXUNUSED( flags ) ) const
1175 {
1176  a2dBoundingBox bbox;
1177  bbox.Enlarge( 0 );
1178 
1179  if( IsConnectedTo() )
1180  {
1181  // check if the pin is dislocated
1182  // This shouldn't happen, but show it, if it does happen
1183  if( IsDislocated() || m_RenderConnected )
1184  {
1185  bbox.Expand( 0, 0 );
1186  // bbox is in pixels, so use m_pixelExtend
1187  //bbox.Expand( -m_width, -m_height );
1188  //bbox.Expand( m_width, m_height );
1189  }
1190  }
1191  else
1192  {
1193  bbox.Expand( 0, 0 );
1194  // bbox is in pixels, so use m_pixelExtend
1195  //bbox.Expand( -m_width, -m_height );
1196  //bbox.Expand( m_width, m_height );
1197  }
1198 
1199  return bbox;
1200 }
1201 
1202 bool a2dPin::DoUpdate( UpdateMode WXUNUSED( mode ), const a2dBoundingBox& childbox, const a2dBoundingBox& clipbox, const a2dBoundingBox& propbox )
1203 {
1204  if ( !m_bbox.GetValid() )
1205  {
1208  m_bbox.MapBbox( m_lworld );
1209  //rotation indicator included
1210  if( m_pinclass && m_pinclass->HasAngleLine() )
1211  {
1212  if ( m_worldBased )
1213  m_worldExtend = wxMax( m_worldExtend, wxMax( m_width / 2.0, m_height / 2.0 ) );
1214  else
1215  m_pixelExtend = wxMax( m_pixelExtend, wxMax( m_width / 2.0, m_height / 2.0 ) );
1216  }
1217  else
1218  {
1219  if ( m_worldBased )
1220  m_worldExtend = wxMax( m_worldExtend, wxMax( m_width / 2.0, m_height / 2.0 ) );
1221  else
1222  m_pixelExtend = wxMax( m_pixelExtend, wxMax( m_width / 2.0, m_height / 2.0 ) );
1223  }
1224  //assert( m_pixelExtend < 40 );
1225  return true;
1226  }
1227  return false;
1228 }
1229 
1230 void a2dPin::OnCanvasObjectMouseEvent( a2dCanvasObjectMouseEvent& event )
1231 {
1232  // Call base, instead of a2dHandle, if skipped there,
1233 
1234  // just to debug stuff, differentiate.
1235  if ( event.GetMouseEvent().LeftDown() )
1236  {
1238  }
1239  else if ( event.GetMouseEvent().Dragging() )
1240  {
1242  }
1243  else if ( event.GetMouseEvent().Moving() )
1244  {
1246  }
1247  else if ( event.GetMouseEvent().LeftUp() )
1248  {
1250  }
1251  else
1252  {
1254  }
1255 }
1256 
1257 
1258 void a2dPin::OnEnterObject( a2dCanvasObjectMouseEvent& WXUNUSED( event ) )
1259 {
1260 }
1261 
1262 void a2dPin::OnLeaveObject( a2dCanvasObjectMouseEvent& WXUNUSED( event ) )
1263 {
1264 }
1265 
1267 {
1268  ic.GetDrawer2D()->SetDrawerStroke( GetHabitat()->GetHighLightStroke() );
1269  ic.GetDrawer2D()->SetDrawerFill( GetHabitat()->GetHighLightFill() );
1270 
1271  double x1;
1272  double y1;
1273  ic.GetTransform().TransformPoint( 0, 0, x1, y1 );
1274  int dx = ic.GetDrawer2D()->WorldToDeviceX( x1 );
1275  int dy = ic.GetDrawer2D()->WorldToDeviceY( y1 );
1276 
1278  ic.GetDrawer2D()->DrawCenterRoundedRectangle( dx, dy, m_width * 1.1, m_height * 1.1, m_radius );
1279  ic.GetDrawer2D()->PopTransform();
1280 }
1281 
1282 void a2dPin::DoRender( a2dIterC& ic, OVERLAP WXUNUSED( clipparent ) )
1283 {
1284  if ( !m_doRender )
1285  return;
1286 
1287  //if( ic.GetDrawStyle() == RenderWIREFRAME_SELECT || ic.GetDrawStyle() == RenderWIREFRAME_SELECT_INVERT )
1288  // return;
1289 
1291  return;
1292 
1293  double x1;
1294  double y1;
1295  ic.GetTransform().TransformPoint( 0, 0, x1, y1 );
1296  int dx = ic.GetDrawer2D()->WorldToDeviceX( x1 );
1297  int dy = ic.GetDrawer2D()->WorldToDeviceY( y1 );
1298 
1299  // Calculate handle size.
1300  double w2 = m_width / 2.0 ;
1301  double h2 = m_height / 2.0;
1302  double dr = m_radius;
1303 
1305  {
1306  // This is the mode of a pin that is hit by the mouse (set in OnEnter)
1307  //ic.GetDrawer2D()->SetDrawerStroke( a2dStroke( wxColour(12,34,78), 0.5) );
1308  //ic.GetDrawer2D()->SetDrawerFill( a2dFill( wxColour(244,2,2)) );
1309  // This is the mode of a pin that can be connected to a specific pinclass
1313  }
1314  else if ( m_mode == sm_PinCanConnect )
1315  {
1316  // This is the mode of a pin that can be connected
1320  }
1321  else if ( m_mode == sm_PinCannotConnect )
1322  {
1323  // This is the mode of a pin that cannot be connected
1327  }
1328 
1329 
1330  if ( m_worldBased )
1331  {
1332  w2 = fabs( ic.GetDrawer2D()->WorldToDeviceXRelNoRnd( w2 ) );// + ic.GetWorldStrokeExtend();
1333  h2 = fabs( ic.GetDrawer2D()->WorldToDeviceYRelNoRnd( h2 ) );// + ic.GetWorldStrokeExtend();
1334  dr = fabs( ic.GetDrawer2D()->WorldToDeviceYRelNoRnd( dr ) );
1335  }
1336  else
1337  {
1338  w2 = w2 + ic.GetWorldStrokeExtend();
1339  h2 = h2 + ic.GetWorldStrokeExtend();
1340  }
1341 
1342  //wxLogDebug(wxT("OUT2 %p"), this );
1344 
1345  if ( !IsConnectedTo() ) // not connected ?
1346  {
1347  if ( GetAlgoSkip() && m_parent->HasProperty( a2dCanvasObject::PROPID_ToolObject ) )
1349 
1350  if ( m_mode == sm_PinUnConnected )
1351  {
1352  // This is the usual mode of an unconnecting pin just sitting there
1353  ic.GetDrawer2D()->SetDrawerStroke( a2dStroke( *wxBLUE, 0 ) );
1354  // end of line one pixel short with wxDC
1355  if ( ic.GetDrawer2D()->GetDrawerStroke().GetPixelStroke() &&
1356  ic.GetDrawer2D()->GetDrawerStroke().GetWidth() == 0 )
1357  {
1358  ic.GetDrawer2D()->DrawLine( dx - w2, dy + h2, dx + w2 + 1, dy - h2 - 1 );
1359  ic.GetDrawer2D()->DrawLine( dx - w2, dy - h2, dx + w2 + 1, dy + h2 + 1 );
1360  }
1361  else
1362  {
1363  ic.GetDrawer2D()->DrawLine( dx - w2, dy + h2, dx + w2, dy - h2 );
1364  ic.GetDrawer2D()->DrawLine( dx - w2, dy - h2, dx + w2, dy + h2 );
1365  }
1366  if( m_pinclass && m_pinclass->HasAngleLine() )
1367  {
1368  int x2, y2;
1369  double ang;
1370  ang = ic.GetTransform().GetRotation();
1371  x2 = Round( dx + m_pinclass->GetPin()->GetWidth() * 3 * cos( wxDegToRad( ang ) ) );
1372  y2 = Round( dy - m_pinclass->GetPin()->GetWidth() * 3 * sin( wxDegToRad( ang ) ) );
1373 
1374  ic.GetDrawer2D()->DrawLine( dx, dy, x2, y2 );
1375  }
1376  }
1377  else if ( m_mode == sm_PinCanConnectToPinClass )
1378  {
1379  // This is the mode of a pin that is hit by the mouse (set in OnEnter)
1380  //ic.GetDrawer2D()->SetDrawerStroke( a2dStroke( wxColour(12,34,78), 0.5) );
1381  //ic.GetDrawer2D()->SetDrawerFill( a2dFill( wxColour(244,2,2)) );
1382  // This is the mode of a pin that can be connected to a specific pinclass
1383  ic.GetDrawer2D()->SetDrawerFill( m_pinclass->GetPinCanConnect()->GetFill() );
1384  ic.GetDrawer2D()->SetDrawerStroke( m_pinclass->GetPinCanConnect()->GetStroke() );
1385  ic.GetDrawer2D()->DrawCenterRoundedRectangle( dx, dy, w2, h2, dr );
1386  }
1387  else if ( m_mode == sm_PinCanConnect )
1388  {
1389  // This is the mode of a pin that can be connected
1390  //ic.GetDrawer2D()->SetDrawerFill( a2dFill( wxColour(12,134,228)) );
1391  //ic.GetDrawer2D()->SetDrawerStroke( a2dStroke( *wxBLUE, 1) );
1392  ic.GetDrawer2D()->SetDrawerFill( m_pinclass->GetPinCanConnect()->GetFill() );
1393  ic.GetDrawer2D()->SetDrawerStroke( m_pinclass->GetPinCanConnect()->GetStroke() );
1394  ic.GetDrawer2D()->DrawCenterRoundedRectangle( dx, dy, w2, h2, dr );
1395  }
1396  else if ( m_mode == sm_PinCannotConnect )
1397  {
1398  // This is the mode of a pin that cannot be connected
1400  ic.GetDrawer2D()->SetDrawerStroke( m_pinclass->GetPinCannotConnect()->GetStroke() );
1401  //ic.GetDrawer2D()->SetDrawerFill( a2dFill( wxColour(245,134,178)) );
1402  //ic.GetDrawer2D()->SetDrawerStroke( a2dStroke( wxColour(12,34,178), 1) );
1403  ic.GetDrawer2D()->DrawCenterRoundedRectangle( dx, dy, w2, h2, dr );
1404  }
1405 
1406  if ( GetAlgoSkip() && m_parent->HasProperty( a2dCanvasObject::PROPID_ToolObject ) )
1408  }
1409  else
1410  {
1411  // check if the pin is dislocated
1412  // This shouldn't happen, but show it, if it does happen
1413  if( IsDislocated() || m_RenderConnected )
1414  {
1416  ic.GetDrawer2D()->DrawCircle( dx , dy , (w2 + h2) / 2.0);
1417  }
1418  else
1419  {
1420  // This is the usual mode of a connected pin
1421  ic.GetDrawer2D()->SetDrawerFill( m_pinclass->GetPin()->GetFill() );
1422  ic.GetDrawer2D()->SetDrawerStroke( m_pinclass->GetPin()->GetStroke() );
1423  ic.GetDrawer2D()->DrawCircle( dx, dy, w2 / 2.0 );
1424  }
1425  }
1426  ic.GetDrawer2D()->PopTransform();
1427 }
1428 
1429 /*
1430 void a2dPin::RestoreConnectionsAfterCloning( a2dCanvasCommandProcessor* cp )
1431 {
1432  if( m_clonebrother )
1433  {
1434  wxASSERT( m_clonebrother->m_clonebrother == this );
1435 
1436  // Ok the clone original was connected
1437  // Check if this connected object was also cloned (might be a partial clone)
1438  // A partial clone means that only part of a group of connected objects was
1439  // cloned. On the outer side there will be no clone brothers in the original
1440  // objects, since those were not cloned.
1441 
1442  //iterate on connected pins in the original
1443  a2dPinList::const_iterator iterconp;
1444  for ( iterconp = m_clonebrother->GetConnectedPins().begin( ) ; iterconp != m_clonebrother->GetConnectedPins().end( ) ; iterconp++ )
1445  {
1446  a2dPin* pincother = *iterconp;
1447  if ( !pincother || pincother->GetRelease() )
1448  continue;
1449 
1450  if( pincother->m_clonebrother && !pincother->m_clonebrother->IsConnectedTo( this ) )
1451  {
1452  // The clone original should be properly connected
1453  assert( pincother->IsConnectedTo( m_clonebrother ) );
1454 
1455  // Connect the clone of the connection of the original with this
1456  // and vice versa
1457  if( cp )
1458  {
1459  cp->Submit( new a2dCommand_ConnectPins( this, pincother->m_clonebrother ), true );
1460  }
1461  else
1462  {
1463  //the orginal objects are found via the this its clone brother,
1464  // and the object connected to that orginal object did get a clonebrother too.
1465  // This makes it possible to restore the same connection in the cloned group.
1466  this->ConnectTo( pincother->m_clonebrother );
1467  }
1468  }
1469  }
1470  }
1471 }
1472 
1473 */
1474 
1475 #if wxART2D_USE_CVGIO
1476 void a2dPin::DoSave( wxObject* parent, a2dIOHandlerXmlSerOut& out, a2dXmlSer_flag xmlparts , a2dObjectList* towrite )
1477 {
1478  a2dCanvasObject::DoSave( parent, out, xmlparts, towrite );
1479  if ( xmlparts == a2dXmlSer_attrib )
1480  {
1481  out.WriteAttribute( wxT( "width" ), m_width );
1482  out.WriteAttribute( wxT( "height" ), m_height );
1483  if ( m_radius != 0.0 )
1484  {
1485  out.WriteAttribute( wxT( "radius" ), m_radius );
1486  }
1487  out.WriteAttribute( wxT( "pinclass" ), m_pinclass->GetName() );
1488  if ( GetConnectedPinsNr() == 1 )
1489  {
1490  a2dPinList::const_iterator iter;
1491  for ( iter = m_connectedPins.begin( ) ; iter != m_connectedPins.end( ) ; iter++ )
1492  {
1493  a2dPin* connectedPin = *iter;
1494  if ( connectedPin )
1495  {
1496  out.WriteAttribute( wxT( "resolveid" ), connectedPin->GetUniqueSerializationId() );
1497  wxASSERT_MSG( !m_temporaryPin, wxT( "temporary pins should have bin deleted" ) );
1498  break;
1499  }
1500  }
1501  }
1502  out.WriteAttribute( wxT( "RenderConnected" ), m_RenderConnected, true );
1503  out.WriteAttribute( wxT( "dynamicPin" ), m_dynamicPin, true );
1504  out.WriteAttribute( wxT( "internal" ), m_internal, true );
1505  }
1506  else
1507  {
1508  a2dPinList::const_iterator iter;
1509  if ( GetConnectedPinsNr() > 1 )
1510  {
1511  for ( iter = m_connectedPins.begin( ) ; iter != m_connectedPins.end( ) ; iter++ )
1512  {
1513  a2dPin* connectedPin = *iter;
1514  if ( connectedPin )
1515  {
1516  out.WriteStartElementAttributes( wxT( "connect" ) );
1517  out.WriteAttribute( wxT( "resolveid" ), connectedPin->GetUniqueSerializationId() );
1518  wxASSERT_MSG( !m_temporaryPin, wxT( "temporary pins should have bin deleted" ) );
1519  out.WriteEndAttributes( true);
1520  }
1521  }
1522  }
1523  }
1524 }
1525 
1526 void a2dPin::DoLoad( wxObject* parent, a2dIOHandlerXmlSerIn& parser, a2dXmlSer_flag xmlparts )
1527 {
1528  m_parent = wxStaticCast( parent, a2dCanvasObject );
1530 
1531  a2dCanvasObject::DoLoad( parent, parser, xmlparts );
1532 
1533  if ( xmlparts == a2dXmlSer_attrib )
1534  {
1535  m_width = parser.RequireAttributeValueInt( wxT( "width" ) );
1536  m_height = parser.RequireAttributeValueInt( wxT( "height" ) );
1537  m_radius = parser.GetAttributeValueInt( wxT( "radius" ) );
1538  m_name = parser.GetAttributeValue( wxT( "name" ), m_name );
1539 
1540  wxString pinclass = parser.RequireAttributeValue( wxT( "pinclass" ) );
1542  if( !m_pinclass )
1543  {
1545  wxString reference_name = GetName();
1546  a2dGeneralGlobals->ReportErrorF( a2dError_NoPinClass, _( "a2dPin with name %s \n Pin class %s not found (replaced with Standard)" ), reference_name.c_str(), pinclass.c_str() );
1547  }
1548  if ( parser.HasAttribute( wxT( "resolveid" ) ) )
1549  {
1550  wxString resolveid = parser.GetAttributeValue( wxT( "resolveid" ) );
1551  parser.ResolveOrAddLink( this, resolveid );
1552  }
1553 
1554  m_RenderConnected = parser.GetAttributeValueBool( wxT( "RenderConnected" ) );
1555  m_dynamicPin = parser.GetAttributeValueBool( wxT( "dynamicPin" ) );
1556  m_internal = parser.GetAttributeValueBool( wxT( "internal" ) );
1557  }
1558  else
1559  {
1560  while( parser.GetTagName() == wxT( "connect" ) )
1561  {
1562  parser.Require( START_TAG, wxT( "connect" ) );
1563  if ( parser.HasAttribute( wxT( "resolveid" ) ) )
1564  {
1565  wxString resolveid = parser.GetAttributeValue( wxT( "resolveid" ) );
1566  parser.ResolveOrAddLink( this, resolveid );
1567  }
1568  parser.Next();
1569  parser.Require( END_TAG, wxT( "connect" ) );
1570  parser.Next();
1571  }
1572  }
1573 }
1574 #endif //wxART2D_USE_CVGIO
1575 
1577 {
1578  //wxLogDebug(wxT("x=%12.6lf, y=%12.6lf"),x , y );
1579  double xh, yh;
1580  ic.GetTransform().TransformPoint( 0, 0, xh, yh );
1581 
1582  // Hit Tests are sometimes made for algorithmic purposes
1583  // Then it might be hard to supply a drawer
1584  // In this cases, the handle will appear to have zero size
1585  // A better solution would be to have a drawer independent Device/World conversion scheme in the ic
1586  double w = m_width;
1587  double h = m_height;
1588 
1589  if ( m_worldBased )
1590  {
1591  w = w + ic.GetWorldStrokeExtend();
1592  h = h + ic.GetWorldStrokeExtend();
1593  }
1594  else
1595  {
1596  w = fabs( ic.GetDrawer2D()->DeviceToWorldXRel( w ) ) + ic.GetWorldStrokeExtend();
1597  h = fabs( ic.GetDrawer2D()->DeviceToWorldYRel( h ) ) + ic.GetWorldStrokeExtend();
1598  }
1599 
1600  hitEvent.m_how = HitTestRectangle( hitEvent.m_x, hitEvent.m_y, xh - w / 2.0, yh - h / 2.0, xh + w / 2.0, yh + h / 2.0, 0 );
1601  if ( hitEvent.m_how.IsHit() )
1602  return hitEvent.m_how.IsHit();
1603 
1604  return hitEvent.m_how.IsHit();
1605 }
1606 
1608 {
1609  // pins are usual objects unlike handles, so skip the overload in a2dHandle
1611 }
1612 
1614 {
1615  return true;
1616 }
1617 
1619 {
1620  if( !other )
1621  return false;
1622 
1623  a2dPin* canvaspin = wxDynamicCast( other, a2dPin );
1624 
1625  if ( !canvaspin )
1626  {
1627  wxString reference_name = GetName();
1628  a2dGeneralGlobals->ReportErrorF( a2dError_LinkPin, _( "a2dPin with name %s \n Linked to wrong object type" ), reference_name.c_str() );
1629  return false;
1630  }
1631 
1632  if( !IsConnectedTo( canvaspin ) )
1633  {
1634  ConnectTo( canvaspin );
1635  }
1636  return true;
1637 }
1638 
1639 #ifdef _DEBUG
1640 
1641 void a2dPin::DoDump( int indent, wxString* line )
1642 {
1643  a2dCanvasObject::DoDump( indent, line );
1644  *line += wxString::Format( _T( " name=%s" ), GetName() );
1645  a2dPinList::const_iterator iter;
1646  for ( iter = m_connectedPins.begin( ) ; iter != m_connectedPins.end( ) ; iter++ )
1647  {
1648  a2dPin* connectedPin = *iter;
1649  if ( connectedPin )
1650  {
1651  *line += wxString::Format( _T( " cp=%p" ), connectedPin );
1652  }
1653  }
1654 }
1655 
1656 #endif
1657 
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
bool IsSameLocation(a2dPin *other, double margin=0) const
Check if this pin is at same location.
Definition: canpin.cpp:1115
bool GetAttributeValueBool(const wxString &attrib, bool defaultv=false)
Returns the boolean value of an attribute.
Definition: genxmlpars.cpp:537
wxPoint2DDouble a2dPoint2D
this to define if coordinate numbers are integer or doubles
Definition: artglob.h:47
a2dPin * IsDislocated() const
Definition: canpin.cpp:1089
double GetAbsY() const
get absolute Y position of the pin ( after applying the parent&#39;s matrix and its own matrix ) ...
Definition: canpin.cpp:966
A2DGENERALDLLEXP long wxGenNewId()
This function is like wxNewId, but it has its own ID set.
Definition: gen.cpp:92
#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
bool HasAttribute(const wxString &attrib)
Does the current tag have this attribute?
Definition: genxmlpars.cpp:560
wxString m_name
name of the handle
Definition: canpin.h:537
a2dHandle is used inside editing versions of a certain objects.
Definition: canpin.h:30
virtual bool IsTemporary_DontSave() const
Check if this is a temporary object, which should not be saved.
Definition: canobj.cpp:6365
virtual bool HasProperty(const a2dPropertyId *id, const wxString &stringvalue=wxEmptyString) const
Check if the object has a property with given id and string representation.
Definition: gen.cpp:1621
bool CanConnectWith(a2dIterC &ic, a2dCanvasObject *toConnect, bool autocreate)
check connect to other object
Definition: canobj.cpp:6790
mouse event sent from a2dCanvasObject to itself
Definition: canglob.h:223
void SetDrawStyle(a2dDrawStyle drawstyle)
set drawstyle to use for drawing,
Definition: drawer2d.cpp:557
static const a2dCanvasObjectFlagsMask HasPins
Definition: candefs.h:205
int WorldToDeviceY(double y) const
convert y from world to device coordinates
Definition: drawer2d.h:455
virtual bool AlwaysWriteSerializationId() const
If true, always write an id.
Definition: canpin.cpp:1613
virtual a2dObject * DoClone(CloneOptions options, a2dRefMap *refs) const
Definition: canpin.cpp:1169
virtual void PopTransform(void)
Recall the previously saved user-to-world transform off the matrix stack.
Definition: drawer2d.cpp:480
const a2dAffineMatrix & GetTransformMatrix() const
get the matrix used to position the object
Definition: canobj.h:500
XMLeventType Next()
Walks to next element and returns event type.
Definition: genxmlpars.cpp:422
bool DoIsHitWorld(a2dIterC &ic, a2dHitEvent &hitEvent)
Does hit test on the object (exclusif child objects)
Definition: canpin.cpp:256
void OnCanvasObjectMouseEvent(a2dCanvasObjectMouseEvent &event)
default handler for mouse events, sent to the object from the a2dDrawingPart.
Definition: canobj.cpp:2391
class to map references to objects stored in XML, in order to make the connection later on...
Definition: gen.h:3462
a2dDrawing * m_root
root group for rendering and accessing the canvas&#39;s also contains layer settings
Definition: canobj.h:2525
a2dCanvasOFlags m_flags
holds flags for objects
Definition: canobj.h:2528
static const long sm_PinCanConnectToPinClass
Pin can connect to supplied a2dPinClass.
Definition: canpin.h:505
#define EVT_CANVASOBJECT_ENTER_EVENT(func)
static event table macro for a2dCanvasObject mouse enter event
Definition: canglob.h:314
a2dHandle()
constructor
Definition: canpin.cpp:75
a2dPin is used in a2dCanvasObject to add pins to it.
Definition: canpin.h:233
void WriteStartElementAttributes(const wxString &name, bool newLine=true)
Writes start tag which has attributes.
Definition: genxmlpars.cpp:757
This is a class/type description for a2dPin&#39;s.
Definition: canpin.h:628
static a2dPropertyIdVoidPtr * PROPID_ToolObject
set for objects that act as tool object, when a tool is in action.
Definition: canobj.h:2678
Ref Counted base object.
Definition: gen.h:1045
static void InitializeStockPinClasses()
called to initialize static stockobjects
Definition: canpin.cpp:478
a2dDrawing * GetRoot() const
get a2dCanvasDocument of the object.
Definition: canobj.h:952
void Enlarge(const double Marge)
enlarge with the given amount
Definition: bbox.cpp:162
void AddConnect(a2dPinClass *pinClass)
add a connection pinclass, to which this pin can connect
Definition: canpin.h:651
a2dCanvasObject * GetCaptured() const
are events redirected to a captured corridor? if so return the captured object in it...
Definition: drawer.h:641
double wxDegToRad(double deg)
conversion from degrees to radians
Definition: artglob.cpp:30
double GetRadius() const
return radius
Definition: canpin.h:304
bool IsHit() const
true if this is a hit
Definition: polyver.h:107
used to connect two pins
Definition: drawing.h:2411
double DeviceToWorldYRel(double y) const
convert y relative from device to world coordinates
Definition: drawer2d.h:449
static bool m_worldBased
pins are world based or not.
Definition: canpin.h:556
~a2dPin()
destructor
Definition: canpin.cpp:676
double m_radius
radius of rectangle that will be rendered
Definition: canpin.h:143
int GetAttributeValueInt(const wxString &attrib, int defaultv=0)
Returns the integer value of an attribute.
Definition: genxmlpars.cpp:495
a2dPinClass * m_pinclass
The class defines to which other pins this pin can connect.
Definition: canpin.h:562
void SetDrawerStroke(const a2dStroke &stroke)
Used to set the current stroke.
Definition: drawer2d.cpp:565
Input and output handler for the XmlSer format.
Definition: genxmlpars.h:819
UpdateMode
Various mode flags for Update.
Definition: canobj.h:1091
bool GetPixelStroke() const
if the width is pixels or not.
Definition: stylebase.cpp:6335
double GetValue(int col, int row) const
get the value in the matrix at col,row
Definition: afmatrix.cpp:106
virtual void SetPending(bool pending)
set this object pending for update
Definition: canobj.cpp:2585
OVERLAP
Result of a a2dBoundingBox intersection or hittest.
Definition: bbox.h:24
a2dParPin points to a2dPort
Definition: cameleon.h:172
static const long sm_PinConnected
Pin is connected rendering mode.
Definition: canpin.h:499
a2dPin * IsConnectedTo(a2dPin *pin=a2dAnyPin) const
Return the pin to which this pin is connected.
Definition: canpin.cpp:751
virtual a2dObject * DoClone(CloneOptions options, a2dRefMap *refs) const
clone it
Definition: canpin.cpp:165
The base class for all drawable objects in a a2dCanvasDocument.
virtual void DoLoad(wxObject *parent, a2dIOHandlerXmlSerIn &parser, a2dXmlSer_flag xmlparts)
load object specific CVG data
Definition: canobj.cpp:5728
double m_height
height in pixels
Definition: canpin.h:543
void ReStoreFixedStyle()
when fixed drawing style is set, it can be overruled.
Definition: drawer2d.cpp:711
~a2dPinClass()
destructor
Definition: canpin.cpp:462
a2dPoint2D GetAbsXY() const
get absolute position of the pin ( after applying the parent&#39;s matrix and its own matrix ) ...
Definition: canpin.cpp:952
a2dCanvasObject is the base class for Canvas Objects.
Definition: canobj.h:371
int m_mode
modifies rendering
Definition: canpin.h:146
wxUint32 GetConnectedPinsNr() const
Get the number of connected pins.
Definition: canpin.cpp:738
a2dPin * FindWirePin(a2dCanvasObjectFlagsMask mask=a2dCanvasOFlags::ALL)
Definition: canpin.cpp:1029
a2dParPin * GetParPin()
Pin to use in a2dCameleonInst when creating a2dParPin from an a2dPort.
Definition: canpin.cpp:576
a2dCanvasObject * m_parent
what is the a2dCanvasObject that i am part of
Definition: canpin.h:553
virtual void SetParent(a2dCanvasObject *parent)
set parent object of the pin
Definition: canpin.cpp:932
void SetParent(a2dCanvasObject *parent)
set parent object of the pin
Definition: canpin.cpp:160
a2dPinClass * CanConnectTo(a2dPinClass *other=NULL) const
searches in the connection list for a given pin class
Definition: canpin.cpp:499
a2dCanvasObjectList * GetChildObjectList()
get the list where the child objects are stored in.
Definition: canobj.cpp:2551
void TransformPoint(double x, double y, double &tx, double &ty) const
Transform a point.
Definition: afmatrix.cpp:559
virtual void DrawCenterRoundedRectangle(double xc, double yc, double width, double height, double radius, bool pixelsize=false)
Draw CenterRoundedRectangle in world coordinates.
Definition: drawer2d.cpp:2040
double m_height
height in pixels
Definition: canpin.h:140
double GetRotation() const
return rotation
Definition: afmatrix.cpp:799
bool DoUpdate(UpdateMode mode, const a2dBoundingBox &childbox, const a2dBoundingBox &clipbox, const a2dBoundingBox &propbox)
Update derived Object specific things ( mainly boundingbox)
Definition: canpin.cpp:1202
bool HasAngleLine() const
is there an angle line on the pin
Definition: canpin.h:665
virtual a2dCanvasObject * GetParent() const
Definition: canobj.h:2126
bool m_selected
object is selected
Definition: candefs.h:235
void Set2(double xc, double yc, const wxString &name=wxT(""))
set basic parameters
Definition: canpin.cpp:131
bool DoIsHitWorld(a2dIterC &ic, a2dHitEvent &hitEvent)
Does hit test on the object (exclusif child objects)
Definition: canpin.cpp:1576
float m_worldExtend
world extend in world coordinates.
Definition: canobj.h:2545
a2dAffineMatrix m_lworld
used for positioning the object (x,y,ang,scale etc.)
Definition: canobj.h:2559
wxUint64 a2dCanvasObjectFlagsMask
mask flags for a2dCanvasObject
Definition: candefs.h:152
void SetDrawerFill(const a2dFill &fill)
Used to set the current fill.
Definition: drawer2d.cpp:621
void RemoveDuplicateConnectedPins(a2dPin *other)
pins connected to given other pin, will be removed on this pin.
Definition: canpin.cpp:895
bool Disconnect(a2dPin *pin=a2dAnyPin, bool forceErase=false)
Definition: canpin.cpp:789
a2dPin * GetPin()
get default pin for graph like structure
Definition: canpin.cpp:528
void ConnectTo(a2dPin *connectto)
connect this pin to the given pin
Definition: canpin.cpp:918
wxString m_name
name of pin class
Definition: canpin.h:731
bool GetValid() const
returns true if boundingbox is calculated properly and therefore its valid flag is set...
Definition: bbox.cpp:299
void Expand(const a2dPoint2D &, const a2dPoint2D &)
expand boundingbox width two points
Definition: bbox.cpp:155
a2dBoundingBox DoGetUnTransformedBbox(a2dBboxFlags flags=a2dCANOBJ_BBOX_NON) const
In derived object this should be overriden to calculate the boundingbox of the object without its chi...
Definition: canpin.cpp:1174
a2dlist< a2dDumbPtr< a2dPin > > m_connectedPins
to which a2dPin is this pin connected with other canvas objects its pins.
Definition: canpin.h:586
double GetHeight() const
return height
Definition: canpin.h:301
void Set(double xc, double yc, double angle=0, const wxString &name=wxT(""), bool dynamic=false)
set postion angle and name of the pin
Definition: canpin.cpp:663
virtual bool IsTemporary_DontSave() const
Check if this is a temporary object, which should not be saved.
Definition: canpin.cpp:320
bool DoUpdate(UpdateMode mode, const a2dBoundingBox &childbox, const a2dBoundingBox &clipbox, const a2dBoundingBox &propbox)
Update derived Object specific things ( mainly boundingbox)
Definition: canpin.cpp:177
double GetPosX() const
get x position from affine matrix
Definition: canobj.h:527
double GetCoordinateEpsilon() const
coordinates below this distance will be trated as equal
Definition: canglob.h:634
virtual void DoLoad(wxObject *parent, a2dIOHandlerXmlSerIn &parser, a2dXmlSer_flag xmlparts)
load object specific CVG data
Definition: canpin.cpp:1526
void SetAbsXY(double x, double y)
set the absolute X,Y position of the pin ( after applying the parent&#39;s matrix and its own matrix ) ...
Definition: canpin.cpp:973
a2dDrawer2D * GetDrawer2D() const
get current a2dDrawer2D
Definition: canobj.cpp:636
a2dBoundingBox DoGetUnTransformedBbox(a2dBboxFlags flags=a2dCANOBJ_BBOX_NON) const
In derived object this should be overriden to calculate the boundingbox of the object without its chi...
Definition: canpin.cpp:170
#define wxStaticCast(obj, className)
The wxWindows 2.4.2 wxStaticCast is buggy. It evaluates its argument twice.
Definition: gen.h:123
a2dCanvasObject * m_parent
what is the a2dCanvasObject that i am part of
Definition: canpin.h:150
void SetSpecificFlags(bool setOrClear, a2dCanvasObjectFlagsMask which)
set all bit flags in object that or true in mask to true or false
Definition: canobj.cpp:2645
#define EVT_CANVASOBJECT_MOUSE_EVENT(func)
static event table macro for a2dCanvasObject mouse event
Definition: canglob.h:312
virtual void SetPending(bool pending)
set this object pending for update
Definition: canpin.cpp:945
const a2dError a2dError_LinkPin
static a2dPinClass * GetClassByName(const wxString &name)
return the name of this pinclass.
Definition: canpin.cpp:511
A2DGENERALDLLEXP a2dSmrtPtr< a2dGeneralGlobal > a2dGeneralGlobals
a global pointer to get to global instance of important classes.
Definition: comevt.cpp:1148
virtual void DoSave(wxObject *parent, a2dIOHandlerXmlSerOut &out, a2dXmlSer_flag xmlparts, a2dObjectList *towrite)
write object specific CVGL data
Definition: canobj.cpp:5569
general event sent from a2dHandle to its parent a2dCanvasObject
Definition: canglob.h:273
virtual void DoSave(wxObject *parent, a2dIOHandlerXmlSerOut &out, a2dXmlSer_flag xmlparts, a2dObjectList *towrite)
write object specific CVGL data
Definition: canpin.cpp:1476
Restriction engine for editing restrictions like snapping.
Definition: restrict.h:88
static std::list< a2dPinClass * > m_allPinClasses
a linked lists of all a2dPinClass&#39;es, so that one can get a class by name
Definition: canpin.h:757
virtual void DrawHighLighted(a2dIterC &ic)
called by Render() if m_flags.m_HighLight is set
Definition: canpin.cpp:1266
int WorldToDeviceX(double x) const
convert x from world to device coordinates
Definition: drawer2d.h:453
bool m_temporaryPin
Definition: canpin.h:569
virtual void DrawLine(double x1, double y1, double x2, double y2)
Draw line in world coordinates.
Definition: drawer2d.cpp:2167
Input and output handler for the XmlSer format.
Definition: genxmlpars.h:862
bool CheckMask(a2dCanvasObjectFlagsMask mask) const
Compares all flags in object to the given mask and return true is the same.
Definition: canobj.cpp:2665
double m_radius
radius of rectangle that will be rendered
Definition: canpin.h:546
void CleanUpNonConnected()
Definition: canpin.cpp:726
double m_width
width in pixels
Definition: canpin.h:540
wxString RequireAttributeValue(const wxString &attrib)
Forces an attribute and returns its string value.
Definition: genxmlpars.cpp:461
a2dPin * GetPinCanConnect()
represents the pin styles for pins that can connect right now
Definition: canpin.cpp:560
Contains a2dDrawing Class to hold a drawing.
bool Identity(void)
Make into identity matrix.
Definition: afmatrix.cpp:256
void SetMode(int mode)
you may use it to modify rendering of the object depending on setting
Definition: canpin.h:95
void WriteEndAttributes(bool close=false)
&quot;Closes&quot; the start tag after writing all attributes (writes the &quot;&gt;&quot; or &quot;/&gt;&quot; bracket).
Definition: genxmlpars.cpp:837
virtual bool Submit(a2dCommand *command, bool storeIt=true)
next to the base class submit, it sets a2DocumentCommandProcessor for a2dCommand
Definition: comevt.cpp:842
bool m_internal
true when pin is internal to object border.
Definition: canpin.h:575
a2dPin()
constructor
Definition: canpin.cpp:605
A 2x3 affine matrix class for 2D transformations.
Definition: afmatrix.h:53
wxMouseEvent & GetMouseEvent()
return the original mouse event that was redirected to the a2dCanvasObject
Definition: canglob.h:243
a2dStroke GetDrawerStroke() const
get the current stroke
Definition: drawer2d.h:548
wxUint16 m_pixelExtend
Pixel extend.
Definition: canobj.h:2553
a2dPinClass * GetPinClass() const
return the pin class of this pin
Definition: canpin.h:356
void AutoConnect(a2dCanvasObject *root, double margin)
Try to connect this pin to another pin at the same location.
Definition: canpin.cpp:1072
double GetPosY() const
get y position from affine matrix
Definition: canobj.h:530
double GetWorldStrokeExtend()
Definition: canobj.h:3403
static void DeleteStockPinClasses()
called to delete all pin class objects
Definition: canpin.cpp:490
virtual void DoLoad(wxObject *parent, a2dIOHandlerXmlSerIn &parser, a2dXmlSer_flag xmlparts)
load object specific CVG data
Definition: canpin.cpp:304
bool m_objectPin
is true when pin is on an object instead of a wire/connect
Definition: canpin.h:578
while iterating a a2dCanvasDocument, this holds the context.
Definition: canobj.h:3212
const a2dError a2dError_NoPinClass
void SetParPin(a2dParPin *newpin)
Definition: canpin.cpp:571
double m_x
(world coordinates) hit point x as in a2dDrawingPart or any other top level
Definition: canobj.h:293
void DoRender(a2dIterC &ic, OVERLAP clipparent)
render derived object
Definition: canpin.cpp:193
void MapBbox(const a2dAffineMatrix &matrix)
Definition: bbox.cpp:445
a2dCommandProcessor * GetCommandProcessor() const
Returns a pointer to the command processor associated with this document.
Definition: drawing.h:549
void Set(double xc, double yc, double w, double h, double angle=0, double radius=0)
set all parameters
Definition: canpin.cpp:116
special a2dCanvasObject to make a multi view hierachy.
#define EVT_CANVASOBJECT_LEAVE_EVENT(func)
static event table macro for a2dCanvasObject mouse leave event
Definition: canglob.h:316
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
void DuplicateConnectedPins(a2dPin *other, bool undo=false)
pins connected to given other pin, will become part of this pin.
Definition: canpin.cpp:864
wxString GetName() const
get the name given to the pin.
Definition: canpin.h:322
wxString GetAttributeValue(const wxString &attrib, const wxString &defaultv=wxT(""))
Returns the value of an attribute.
Definition: genxmlpars.cpp:450
a2dRestrictionEngine * GetRestrictionEngine()
Get restriction engine (grid snapping)
Definition: canglob.cpp:934
int RequireAttributeValueInt(const wxString &attrib)
Forces an attribute and returns its integer value.
Definition: genxmlpars.cpp:508
double GetAbsAngle() const
get absolute angle of the pin ( after applying the parent its matrix and it own matrix ) ...
Definition: canpin.cpp:990
bool GetRelease() const
get release flag
Definition: gen.h:1350
double WorldToDeviceXRelNoRnd(double x) const
convert x relative from world to device coordinates (result not rounded to integer) ...
Definition: drawer2d.h:470
a2dCanvasCommandProcessor * GetCanvasCommandProcessor()
get a pointer to the command processor
Definition: drawing.cpp:375
wire classes for connecting objects.
a2dPinClass(const wxString &name)
constructor
Definition: canpin.cpp:455
An object of this class will update a a2dIterC with the required information.
Definition: canobj.h:3123
void Require(const XMLeventType &type, wxString name)
Forces a special tag.
Definition: genxmlpars.cpp:390
wxString GetTagName()
Returns name of the current XML tag.
Definition: genxmlpars.cpp:565
static a2dPinClass * Standard
Pins of this class can only connect to pins of the same class.
Definition: canpin.h:766
void SetPosXY(double x, double y, bool restrict=false)
set position to x,y
Definition: canobj.cpp:1624
static bool m_doRender
when set disables rending of pin objects
Definition: canpin.h:559
bool Translate(double x, double y)
Translate by dx, dy:
Definition: afmatrix.cpp:420
virtual bool LinkReference(a2dObject *other)
link a reference in the object to the given value
Definition: canpin.cpp:1618
virtual bool IsTemporary_DontSave() const
Check if this is a temporary object, which should not be saved.
Definition: canpin.cpp:1607
The a2dBoundingBox class stores one a2dBoundingBox of a a2dCanvasObject.
Definition: bbox.h:39
bool Invert(void)
Invert matrix.
Definition: afmatrix.cpp:197
void Rotate(double rotation)
Rotates this object clockwise.
Definition: canobj.cpp:2615
virtual bool MayConnectTo(a2dPin *connectto)
Is given pin allowed to connect to this pin.
Definition: canpin.cpp:997
bool m_RenderConnected
flag to render or not when connected
Definition: canpin.h:572
static const long sm_PinUnConnected
Pin is not connected rendering mode.
Definition: canpin.h:497
int m_mode
modifies rendering
Definition: canpin.h:549
void RemoveConnect(a2dPinClass *pinClass)
remove a connection pinclass
Definition: canpin.cpp:466
float GetWidth() const
Definition: stylebase.cpp:6281
void DuplicateConnectedToOtherPins(bool undo=false)
all connections to this pins, will become available in those connected pins too.
Definition: canpin.cpp:836
the a2dDrawingPart is a a2dView specially designed for displaying parts of a a2dDrawing. It uses a a2dDrawer2D to actually redraw things from the document, by giving that a2dDrawer2D as drawing context to the document, and telling the document to redraw a certain rectangular area. At that last is what this class is for. It optimizes the areas to be redrawn after object in the document were changed. To do that it combines redraw areas to a minimal set of redrawing areas. All the administration for this and the way things will be redrawn is from this view.
basetype GetPropertyValue(const a2dObject *obj) const
Get the property value in obj.
Definition: id.inl:325
static const long sm_PinCannotConnect
Pin can NOT be connected rendering mode.
Definition: canpin.h:503
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
#define Round(x)
round to integer such that e.g 2.5 &lt; x &lt; 3.5 becomes 3
Definition: artglob.h:60
virtual void DrawCircle(double x, double y, double radius)
Draw Circle in world coordinates.
Definition: drawer2d.cpp:2116
double WorldToDeviceYRelNoRnd(double y) const
convert y relative from world to device coordinates (result not rounded to integer) ...
Definition: drawer2d.h:475
bool m_prerenderaschild
as child this object will be rendered before the parent object itself when true (default) ...
Definition: candefs.h:289
a2dDrawingPart * GetDrawingPart() const
get current a2dDrawingPart
Definition: canobj.cpp:631
This template class is for property ids with a known data type.
Definition: id.h:477
a2dBoundingBox m_bbox
boundingbox in world coordinates
Definition: canobj.h:2539
a2dConnectionGeneratorPtr m_connectionGenerator
Use this connection generator for wires and pins.
Definition: canpin.h:752
void DoRender(a2dIterC &ic, OVERLAP clipparent)
render derived object
Definition: canpin.cpp:1282
a2dCanvasObject * Find(const wxString &objectname, const wxString &classname=wxT(""), a2dCanvasObjectFlagsMask mask=a2dCanvasOFlags::ALL, const a2dPropertyId *propid=NULL, const wxString &valueAsString=wxT(""), wxUint32 id=0) const
return the object which fits the filter.
Definition: canobj.cpp:4505
bool m_dynamicPin
set when this pin is a temporary pin for editing feedback
Definition: canpin.h:565
double GetAbsX() const
get absolute X position of the pin ( after applying the parent&#39;s matrix and its own matrix ) ...
Definition: canpin.cpp:959
const a2dAffineMatrix & GetTransform() const
Get the accumulated transform up to and including m_lworld of the current object. ...
Definition: canobj.cpp:663
a2dPin * GetPinCannotConnect()
represents the pin styles for pins that cannot connect right now
Definition: canpin.cpp:544
void PopCursor()
pop a cursor from the cursor stack, and set display cursor to back
Definition: drawer.cpp:1059
std::list< a2dPinClass * > m_canConnectTo
Definition: canpin.h:738
pins and handles
double m_width
width in pixels
Definition: canpin.h:137
void SetPinCannotConnect(a2dPin *newpin)
Definition: canpin.cpp:539
void SetAngleLine(bool value)
is there an angle line on the pin
Definition: canpin.h:668
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
double GetWidth() const
return width
Definition: canpin.h:298
list of a2dObject&#39;s
Definition: gen.h:3157
a2dDocumentRenderStyle GetDrawStyle()
get drawstyles used for drawing the document
Definition: canobj.h:3319
double m_y
(world coordinates) hit point y as in a2dDrawingPart or any other top level
Definition: canobj.h:295
virtual void DoSave(wxObject *parent, a2dIOHandlerXmlSerOut &out, a2dXmlSer_flag xmlparts, a2dObjectList *towrite)
write object specific CVGL data
Definition: canpin.cpp:288
void SetPin(a2dPin *newpin)
set default pin for graph like structure
Definition: canpin.cpp:523
double DeviceToWorldXRel(double x) const
convert x relative from device to world coordinates
Definition: drawer2d.h:444
CloneOptions
options for cloning
Definition: gen.h:1200
bool ResolveOrAddLink(a2dObject *obj, const wxString &id=wxT(""))
try to resolve an object referenced by obj using the LinkReference function
Definition: gen.cpp:4808
void SetCorridorPath(bool OnOff, a2dCanvasObject *captureObject=NULL)
to set corridor path ( also to captured object), its a2dCanvasOFlags::IsOnCorridorPath flag is set on...
Definition: canobj.cpp:739
void SetPinCanConnect(a2dPin *newpin)
Definition: canpin.cpp:555
structure to give as parameter to member functions of a2dCanvasObject
Definition: canobj.h:252
a2dPin * FindConnectablePin(a2dCanvasObject *root, double margin, bool autocreate)
Find a connectable pin.
Definition: canpin.cpp:1046
wxInt64 GetUniqueSerializationId() const
return a unique id for this object
Definition: gen.cpp:1450
void SetFill(const a2dFill &fill)
Set a fill for the object which will be used instead of the layer fill.
Definition: canobj.cpp:2874
virtual void PushIdentityTransform()
push no transform, to draw directly in device coordinates
Definition: drawer2d.cpp:469
static const long sm_PinCanConnect
Pin can be connected rendering mode.
Definition: canpin.h:501
const a2dFill * a2dTRANSPARENT_FILL
global a2dFill stock object for TRANSPARENT filling
general canvas module declarations and classes
wxString m_name
name of the handle
Definition: canpin.h:134
void OverRuleFixedStyle()
id style is FIXED, saves current style and sets style to a2dFILLED
Definition: drawer2d.cpp:697
canpin.cpp Source File -- Sun Oct 12 2014 17:04:14 -- Sun Oct 12 2014 -- 1.8.5 -- wxArt2D -- . -- Main Page Reference Documentation