wxArt2D
tools.cpp
Go to the documentation of this file.
1 /*! \file canvas/src/tools.cpp
2  \author Klaas Holwerda
3 
4  Copyright: 2001-2004 (c) Klaas Holwerda
5 
6  Licence: wxWidgets Licence
7 
8  RCS-ID: $Id: tools.cpp,v 1.133 2009/06/03 17:38:13 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/canvas/canmod.h"
22 
23 #include "wx/canvas/tools.h"
24 
25 IMPLEMENT_CLASS( a2dBaseTool, a2dObject )
26 IMPLEMENT_CLASS( a2dToolContr, a2dObject )
27 
28 //----------------------------------------------------------------------------
29 // a2dToolList
30 //----------------------------------------------------------------------------
31 
33 {
34 }
35 
36 a2dToolList::~a2dToolList()
37 {
38 }
39 
41 {
42  a2dToolList* a = new a2dToolList();
43 
44  for( a2dToolList::const_iterator iter = begin(); iter != end(); ++iter )
45  {
46  a2dToolList::value_type toolobj = *iter;
47 
48  if ( options & a2dObject::clone_childs )
49  {
50  a2dBaseTool* objnew = wxStaticCast( toolobj->Clone( options ), a2dBaseTool );
51  a->push_back( objnew );
52  }
53  else
54  a->push_back( toolobj );
55  }
56 
57  return a;
58 }
59 
60 //----------------------------------------------------------------------------
61 // a2dToolContr
62 //----------------------------------------------------------------------------
63 
64 BEGIN_EVENT_TABLE( a2dToolContr, a2dObject )
65  EVT_PAINT( a2dToolContr::OnPaint )
66  EVT_IDLE( a2dToolContr::OnIdle )
67  EVT_ENTER_WINDOW( a2dToolContr::OnEnter )
68 END_EVENT_TABLE()
69 
71  :m_drawingPart( drawingPart )
72 {
73  SetSnap( false );
74  m_bussyPoping = false;
75 
76  if ( m_drawingPart )
77  {
78  if ( m_drawingPart->GetDrawing() && !m_drawingPart->GetDrawing()->GetCanvasCommandProcessor() )
79  m_drawingPart->GetDrawing()->CreateCommandProcessor();
80  m_drawingPart->SetCanvasToolContr( this );
81  SetEvtHandlerEnabled( true );
82  }
83  else
84  SetEvtHandlerEnabled( false );
85 }
86 
88 {
89 }
90 
92 {
93  return m_tools.size() ? m_tools.front() : NULL;
94 }
95 
97 {
98  //prevent deletion by drawer
100 
101  if ( m_drawingPart )
102  {
103  //disable the controller for the current drawer
105  SetEvtHandlerEnabled( false );
106  }
107 
108  m_drawingPart = drawingPart;
109 
110  if ( m_drawingPart )
111  {
113  SetEvtHandlerEnabled( true );
114  }
115  else
116  SetEvtHandlerEnabled( false );
117 }
118 
120 {
121 }
122 
123 void a2dToolContr::StopAllTools( bool abort )
124 {
126  a2dToolContr::PopTool( tool, abort );
127  while ( tool )
128  {
129  tool = NULL;
130  a2dToolContr::PopTool( tool, abort );
131  }
132 }
133 
135 {
136  SetEvtHandlerEnabled( false );
137  StopAllTools();
138  m_drawingPart = 0;
139 }
140 
141 void a2dToolContr::ActivateTop( bool active )
142 {
143  // first all other tools, and last the first tool, so its m_corridor will be set in the end.
144  for( a2dToolList::reverse_iterator iter = m_tools.rbegin(); iter != m_tools.rend(); ++iter )
145  {
146  a2dToolList::value_type toolobj = *iter;
147  if ( *iter == m_tools.front() )
148  toolobj->SetActive( active );
149  else
150  toolobj->SetActive( false );
151  }
152 }
153 
154 bool a2dToolContr::Activate( const wxString& tool, bool disableothers )
155 {
156  bool found = false;
157 
158  for( a2dToolList::iterator iter = m_tools.begin(); iter != m_tools.end(); ++iter )
159  {
160  a2dToolList::value_type toolobj = *iter;
161  if ( !tool.CmpNoCase( toolobj->GetClassInfo()->GetClassName() ) )
162  {
163  toolobj->SetActive( true );
164  found = true;
165  }
166  else if ( disableothers )
167  toolobj->SetActive( false );
168  }
169  return found;
170 }
171 
172 bool a2dToolContr::EnableTool( const wxString& tool, bool disableothers )
173 {
174  bool found = false;
175 
176  for( a2dToolList::iterator iter = m_tools.begin(); iter != m_tools.end(); ++iter )
177  {
178  a2dToolList::value_type toolobj = *iter;
179 
180  if ( !tool.CmpNoCase( toolobj->GetClassInfo()->GetClassName() ) )
181  {
182  toolobj->SetEvtHandlerEnabled( true );
183  found = true;
184  }
185  else if ( disableothers )
186  toolobj->SetEvtHandlerEnabled( false );
187  }
188  return found;
189 }
190 
191 bool a2dToolContr::EnableTool( a2dBaseTool* tool, bool disableothers )
192 {
193  bool found = false;
194  for( a2dToolList::iterator iter = m_tools.begin(); iter != m_tools.end(); ++iter )
195  {
196  a2dToolList::value_type toolobj = *iter;
197  if ( tool == toolobj )
198  {
199  toolobj->SetEvtHandlerEnabled( true );
200  found = true;
201  }
202  else if ( disableothers )
203  toolobj->SetEvtHandlerEnabled( false );
204  }
205  return found;
206 }
207 
208 bool a2dToolContr::DisableTool( const wxString& tool )
209 {
210  bool found = false;
211  for( a2dToolList::iterator iter = m_tools.begin(); iter != m_tools.end(); ++iter )
212  {
213  a2dToolList::value_type toolobj = *iter;
214  if ( !tool.CmpNoCase( toolobj->GetClassInfo()->GetClassName() ) )
215  {
216  toolobj->SetEvtHandlerEnabled( false );
217  found = true;
218  }
219  }
220  return found;
221 }
222 
224 {
225  bool found = false;
226  for( a2dToolList::iterator iter = m_tools.begin(); iter != m_tools.end(); ++iter )
227  {
228  a2dToolList::value_type toolobj = *iter;
229  if ( toolobj == tooldis )
230  {
231  tooldis->SetEvtHandlerEnabled( false );
232  found = true;
233  }
234  }
235  return found;
236 }
237 
238 a2dBaseTool* a2dToolContr::SearchTool( const wxString& toolsearch )
239 {
240  for( a2dToolList::iterator iter = m_tools.begin(); iter != m_tools.end(); ++iter )
241  {
242  a2dToolList::value_type toolobj = *iter;
243  if ( !toolsearch.CmpNoCase( toolobj->GetClassInfo()->GetClassName() ) )
244  return toolobj;
245  }
246  return ( a2dBaseTool* ) 0;
247 }
248 
249 bool a2dToolContr::ProcessEvent( wxEvent& event )
250 {
251  if ( !m_drawingPart )
252  {
253  return false;
254  }
255 
256  a2dObject* active = this;
257 
258  //the next is almost a copy of a2dObject::ProcessEvent
259  //The base class could not be used since in case of an event skip
260  //in a derived a2dToolContr class, the event would go directly to the a2dCanvas,
261  //without passing it to the tools first.
262 
263  //So the order here is:
264  //first test for static event tables in a derived controller class if event is skipped or !handled in there,
265  //Process the events down the chain of tools (each tool that skips the event means the next one is called)
266  //If still not processed, the event is redirected to the rest of the wxEvtHandler in the a2dCanvas window.
267  //This is in general the a2dCanvas window itself.
268  //In case a tool has stopped itself, the tool is poped of the stack, and if the event was not handled yet
269  //it is sent to the tool that is now first on the stack.
270 
271  // An event handler can be enabled or disabled
272  if ( active->GetEvtHandlerEnabled() )
273  {
275  {
277  PopTool( poped );
278  }
279 
280  if ( a2dObject::ProcessEvent( event ) )
281  return true;
282 
283  return ToolsProcessEvent( event );
284  }
285 
286  return false;
287 }
288 
289 bool a2dToolContr::ToolsProcessEvent( wxEvent& event )
290 {
291  bool handled = false;
292 
293  if ( GetFirstTool() )
294  {
295  //process event return false if event was skipped or not handled.
296  //the firstool redirects to the next tool on the stack etc.
297  //if not handled in any tool the next return false
298 
299  size_t nrTools = m_tools.size();
300 
301  // If a new tool was pushed, give the new tool a chance to process the event.
302  // This is a typical situation when the tool pushed a new tool while handling the event.
303  // The same event directly goes to that tool.
304  // This pushed tool can do the same itself, so repeat until no more pushed tools.
305 
306  a2dToolList::iterator iter = m_tools.begin();
307  while( !handled && iter != m_tools.end() )
308  {
309  a2dBaseTool* first = ( *iter ).Get();
310  iter++; // go to the next in case of a pop, we will be save.
311  handled = first->ProcessEvent( event );
312  if ( nrTools < m_tools.size() ) //there was a push
313  {
314  iter = m_tools.begin(); //start all over
315  nrTools = m_tools.size();
316  }
317  //was there a pop request?
318  if ( GetFirstTool()->GetStopTool() )
319  {
320  if ( !m_bussyPoping )
321  {
323  PopTool( poped );
324  iter = m_tools.begin();
325  }
326  }
327  //ready to go to the next tool where the iterator is on.
328  }
329 
330  return handled;
331  }
332  return false;
333 }
334 
336 {
337  a2dBaseToolPtr handlerres = handler;
338  //first allow the current first tool to react on a the pushing of the new tool.
339  if ( GetFirstTool() )
340  {
343  {
344  // if a push attempt must result in the current first tool to be stopped,
345  // we pop it directly.
347  if ( GetFirstTool()->GetStopTool() )
348  PopTool( poped );
349  }
350  }
351 
352  if ( handler->StartTool( GetFirstTool() ) )
353  {
354  ActivateTop( false );
355  m_tools.push_front( handler );
357  GetFirstTool()->ProcessEvent( event );
358  ActivateTop( true );
359  return true;
360  }
361  return false;
362 }
363 
365 {
366  m_bussyPoping = true;
367 
368  if ( GetFirstTool() && ( GetFirstTool()->AllowPop() || abort ) )
369  {
370  GetFirstTool()->StopTool( abort );
371  poped = GetFirstTool();
372  if ( poped )
373  {
374  //release the object from the tool list, but argument
375  //poped will keep a reference, so no delete, this is good, since we want to sent an event to the new
376  // first tool, with as parameter the the poped tool.
377  m_tools.ReleaseObject( poped );
378 
379  // inform new first tool, e.g. to take style of the poped tool.
380  if ( GetFirstTool() )
381  {
383  GetFirstTool()->ProcessEvent( event );
384  }
385  poped->SetActive( false );
386  }
387 
388  m_bussyPoping = false;
389  return true;
390  }
391  m_bussyPoping = false;
392  poped = NULL;
393  return false;
394 }
395 
397 {
398  m_tools.push_back( handler );
399 }
400 
401 void a2dToolContr::OnEnter( wxMouseEvent& event )
402 {
403  event.Skip( true );
404 }
405 
406 void a2dToolContr::OnPaint( wxPaintEvent& event )
407 {
408  if ( GetFirstTool() )
409  {
410  GetFirstTool()->ProcessEvent( event );
411  }
412 
413  //no skipping here (onPaint event is/should be handled)
414  event.Skip( false );
415 }
416 
417 void a2dToolContr::OnIdle( wxIdleEvent& event )
418 {
419  if ( GetFirstTool() )
420  {
421  GetFirstTool()->ProcessEvent( event );
422  }
423 }
424 
426 {
427  return false;
428 }
429 
431 {
432  return false;
433 }
434 
435 bool a2dToolContr::TriggerReStartEdit( wxUint16 editmode )
436 {
437  return false;
438 }
439 
441 {
442  for( a2dToolList::reverse_iterator iter = m_tools.rbegin(); iter != m_tools.rend(); ++iter )
443  ( *iter )->Render();
444 }
445 
446 bool a2dToolContr::SetCorridor( const a2dCorridor& corridor )
447 {
448  wxASSERT_MSG( GetFirstTool(), wxT( "No tool set in controller" ) );
449  GetFirstTool()->SetCorridor( corridor );
450  return true;
451 }
452 
453 void a2dToolContr::SetSnap( bool snap )
454 {
455  m_snap = snap;
456  a2dRestrictionEngine* restrict = a2dCanvasGlobals->GetHabitat()->GetRestrictionEngine();
458  restrict = m_drawingPart->GetDrawing()->GetHabitat()->GetRestrictionEngine();
459 
460  if( restrict )
461  restrict->SetSnap( m_snap );
462 }
463 
464 
465 /********************************************************************************
466 a2dBaseTool
467 ********************************************************************************/
468 
469 a2dPropertyIdBool* a2dBaseTool::PROPID_Oneshot = NULL;
470 a2dPropertyIdBool* a2dBaseTool::PROPID_Stop = NULL;
471 a2dPropertyIdFill* a2dBaseTool::PROPID_Fill = NULL;
472 a2dPropertyIdStroke* a2dBaseTool::PROPID_Stroke = NULL;
473 a2dPropertyIdUint16* a2dBaseTool::PROPID_Layer = NULL;
474 
475 INITIALIZE_PROPERTIES( a2dBaseTool, a2dObject )
476 {
477  A2D_PROPID_M( a2dPropertyIdBool, a2dBaseTool, Oneshot, false, m_oneshot );
478  A2D_PROPID_M( a2dPropertyIdBool, a2dBaseTool, Stop, false, m_stop );
479  A2D_PROPID_M( a2dPropertyIdUint16, a2dBaseTool, Layer, 0, m_layer );
480 
481  PROPID_Fill = new a2dPropertyIdFill( wxT( "Fill" ),
483  *a2dNullFILL,
484  static_cast < a2dPropertyIdFill::ConstGet >( &a2dBaseTool::GetFill ),
485  static_cast < a2dPropertyIdFill::ConstSet >( &a2dBaseTool::SetFill ) );
486  AddPropertyId( PROPID_Fill );
487 
488  PROPID_Stroke = new a2dPropertyIdStroke( wxT( "Stroke" ),
490  *a2dNullSTROKE,
491  static_cast < a2dPropertyIdStroke::ConstGet >( &a2dBaseTool::GetStroke ),
492  static_cast < a2dPropertyIdStroke::ConstSet >( &a2dBaseTool::SetStroke ) );
493  AddPropertyId( PROPID_Stroke );
494  return true;
495 }
496 
497 const a2dSignal a2dBaseTool::sig_toolPushed = wxNewId();
498 const a2dSignal a2dBaseTool::sig_toolPoped = wxNewId();
499 const a2dSignal a2dBaseTool::sig_toolBeforePush = wxNewId();
500 const a2dSignal a2dBaseTool::sig_toolDoPopBeforePush = wxNewId();
501 const a2dSignal a2dBaseTool::sig_toolComEvent = wxNewId();
502 
503 DEFINE_MENU_ITEMID( CmdMenu_NoMenu, wxTRANSLATE("No menu"), wxTRANSLATE("No Menu") )
504 
505 BEGIN_EVENT_TABLE( a2dBaseTool, a2dObject )
506  EVT_MOUSE_EVENTS( a2dBaseTool::OnMouseEvent )
507  EVT_CHAR( a2dBaseTool::OnChar )
508  EVT_KEY_DOWN( a2dBaseTool::OnKeyDown )
509  EVT_KEY_UP( a2dBaseTool::OnKeyUp )
510  EVT_COM_EVENT( a2dBaseTool::OnComEvent )
511  EVT_DO( a2dBaseTool::OnDoEvent )
512  EVT_UNDO( a2dBaseTool::OnUndoEvent )
513  EVT_REDO( a2dBaseTool::OnRedoEvent )
514 END_EVENT_TABLE()
515 
516 
517 a2dBaseTool::a2dBaseTool( a2dToolContr* controller, const a2dMenuIdItem& initiatingMenuId )
518  : m_initiatingMenuId( &initiatingMenuId )
519 {
520  m_mode = 0;
521 
522  m_anotate = true;
523 
524  m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW );
525  m_toolBusyCursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW );
526 
527  m_annotateFont = wxFont( 10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL );
528 
529  // drawing wifth this stroke and fill is based on layers style in document
530  m_fill = *a2dNullFILL;
531  m_stroke = *a2dNullSTROKE;
532  m_contourwidth = 0;
533 
534  m_layer = wxLAYER_DEFAULT;
535  m_controller = controller;
536  m_busy = false;
537  m_halted = false;
538  m_oneshot = false;
539  m_active = true;
540  m_stop = false;
541  m_bussyStopping = 0;
542  m_pending = false;
543  m_isEditTool = true;
544  m_canvas_mouseevents_restore = GetDrawingPart()->GetMouseEvents();
545 
546  m_mousemenu = NULL;
547 
548  m_corridor = a2dCorridor( *GetDrawingPart() );
549  if ( !m_corridor.empty() )
550  {
551  m_parentobject = m_corridor.back();
552  wxASSERT_MSG( m_parentobject->GetRoot() != 0 , wxT( "parentobject of tools has no drawing root set" ) );
553  }
554 
555  // the default event handler is just this object
556  m_eventHandler = NULL;
557 
558  m_ignorePendingObjects = false;
559 }
560 
561 a2dBaseTool::a2dBaseTool( const a2dBaseTool& other, CloneOptions options, a2dRefMap* refs )
562  : a2dObject( other, options, refs )
563 {
565  m_mode = other.m_mode;
566 
567  m_anotate = other.m_anotate;
568 
569  m_toolcursor = other.m_toolcursor;
571 
573 
574  // drawing wifth this stroke and fill is based on layers style in document
575  m_fill = other.m_fill;
576  m_stroke = other.m_stroke;
577  m_contourwidth = 0;
578 
579  m_layer = other.m_layer;
580  m_controller = other.m_controller;
581  m_busy = false;
582  m_halted = false;
583  m_oneshot = other.m_oneshot;
584  m_active = true;
585  m_stop = false;
586  m_bussyStopping = 0;
587  m_pending = false;
588  m_isEditTool = other.m_isEditTool;
589 
591 
592  m_mousemenu = NULL; //other.m_mousemenu;
593 
594  m_corridor = other.m_corridor;
595  if ( !m_corridor.empty() )
596  m_parentobject = m_corridor.back();
597 
598  // the default event handler is just this object
600 
602 
603 }
604 
606 {
607  if ( GetDrawingPart() )
609 
610  if( m_mousemenu )
611  delete m_mousemenu;
612 }
613 
614 wxString a2dBaseTool::GetToolString() const
615 {
616  return GetClassInfo()->GetClassName();
617 }
618 
620 {
622  if ( !m_corridor.empty() )
623  m_parentobject = m_corridor.back();
624  else
625  m_parentobject = NULL;
626 }
627 
629 {
630  m_ignorePendingObjects = onoff;
632 }
633 
634 void a2dBaseTool::SetMousePopupMenu( wxMenu* mousemenu )
635 {
636  if ( m_mousemenu )
637  delete m_mousemenu;
638  m_mousemenu = mousemenu;
639 }
640 
641 bool a2dBaseTool::StartTool( a2dBaseTool* WXUNUSED( currenttool ) )
642 {
643  m_stop = false;
644  GetDrawingPart()->SetCursor( m_toolcursor );
645  return true;
646 }
647 
648 void a2dBaseTool::SetActive( bool active )
649 {
650  m_active = active;
651  //reactivate this state for document.
652  if ( GetDrawing() )
654 
655  if ( GetDrawingPart() )
656  {
657  if ( active )
658  {
660  }
661  else
662  {
664  }
665  }
666 }
667 
668 bool a2dBaseTool::ProcessEvent( wxEvent& event )
669 {
670  if ( m_eventHandler )
671  {
672  bool processed = m_eventHandler->ProcessEvent( event );
673  if ( processed )
674  return processed;
675  }
676  return a2dObject::ProcessEvent( event );
677 }
678 
680 {
681  if ( GetDrawingPart() && event.GetId() == a2dDrawingPart::sig_changedShowObject )
682  {
683  if ( event.GetEventObject() == GetDrawingPart() )
684  {
685  // an existing corridor on a view will become invalid when the ShowObject changes.
686  // Most tools can handle a change in corridor, for those there is no need to remove them after a change
687  // in ShowObject.
688  a2dCanvasObject* newtop = wxStaticCast( event.GetProperty()->GetRefObject(), a2dCanvasObject );
689  if ( newtop )
690  {
691  a2dCorridor corridor;
692  corridor.Push( newtop );
693  SetCorridor( corridor );
694  }
695  else
696  StopTool();
697  }
698  event.Skip();
699  }
700  else if ( m_active && GetEvtHandlerEnabled() && GetDrawingPart() )
701  {
702  event.Skip();
703  }
704  else
705  event.Skip();
706 }
707 
708 void a2dBaseTool::OnDoEvent( a2dCommandProcessorEvent& event )
709 {
710  event.Skip();
711 }
712 
713 void a2dBaseTool::OnUndoEvent( a2dCommandProcessorEvent& event )
714 {
715  event.Skip();
716 }
717 
718 void a2dBaseTool::OnRedoEvent( a2dCommandProcessorEvent& event )
719 {
720  OnUndoEvent( event );
721  event.Skip();
722 }
723 
725 {
726  wxASSERT( !m_busy );
727  if ( m_isEditTool && !GetDrawingPart()->GetDrawing()->GetMayEdit() )
728  {
729  wxLogWarning( _T( "You may not edit this drawing" ) );
730  return false;
731  }
732 
733  m_busy = true;
734  m_pending = true;
735  OpenCommandGroup( false );
736  GetDrawingPart()->SetCursor( m_toolBusyCursor );
737  return true;
738 }
739 
740 bool a2dBaseTool::EnterBusyModeNoGroup()
741 {
742  wxASSERT( !m_busy );
743  if ( m_isEditTool && !GetDrawingPart()->GetDrawing()->GetMayEdit() )
744  {
745  wxLogWarning( _T( "You may not edit this drawing" ) );
746  return false;
747  }
748 
749  m_busy = true;
750  m_pending = true;
751  GetDrawingPart()->SetCursor( m_toolBusyCursor );
752  return true;
753 }
754 
755 void a2dBaseTool::FinishBusyMode( bool closeCommandGroup )
756 {
757  wxASSERT( m_busy );
758  m_busy = false;
759  m_pending = true;
760  if ( closeCommandGroup )
762  if( GetDrawingPart() )
763  {
764  GetDrawingPart()->SetCursor( m_toolcursor );
765  }
766  if( m_oneshot && !m_halted )
767  StopTool();
768 }
769 
771 {
772  wxASSERT( m_busy );
773  m_busy = false;
774  m_pending = true;
776  if( GetDrawingPart() )
777  {
778  GetDrawingPart()->SetCursor( m_toolcursor );
780  }
781  if ( m_oneshot )
782  StopTool();
783 }
784 
785 void a2dBaseTool::StopTool( bool abort )
786 {
787  m_bussyStopping++;
788  if ( !m_stop )
789  {
790  DoStopTool( abort );
791  m_stop = true;
792  }
793  m_bussyStopping--;
794 }
795 
796 void a2dBaseTool::DoStopTool( bool abort )
797 {
798  if ( m_busy )
799  {
800  if ( abort )
801  AbortBusyMode();
802  else
803  FinishBusyMode();
804  }
805 }
806 
808 {
809  return m_stop && m_bussyStopping == 0;
810 }
811 
812 void a2dBaseTool::SetFill( const a2dFill& fill )
813 {
814  m_fill = fill;
815 };
816 
817 void a2dBaseTool::SetStroke( const a2dStroke& stroke )
818 {
819  m_stroke = stroke;
820 };
821 
822 void a2dBaseTool::SetContourWidth( double width )
823 {
824  m_contourwidth = width;
825 }
826 
827 void a2dBaseTool::SetLayer( wxUint16 layer )
828 {
829  m_layer = layer;
830 }
831 
832 void a2dBaseTool::OnMouseEvent( wxMouseEvent& event )
833 {
834  event.Skip();
835 }
836 
837 void a2dBaseTool::OnKeyDown( wxKeyEvent& event )
838 {
839  event.Skip();
840 }
841 
842 void a2dBaseTool::OnKeyUp( wxKeyEvent& event )
843 {
844  event.Skip();
845 }
846 
847 void a2dBaseTool::OnChar( wxKeyEvent& event )
848 {
849  event.Skip();
850 }
851 
852 void a2dBaseTool::OpenCommandGroup( bool restart )
853 {
854  if ( restart )
855  {
856  if ( !m_commandgroup )
857  {
858  wxString name = GetCommandGroupName();
859 
860  if( restart )
861  name += _( " (continued)" );
862 
863  OpenCommandGroupNamed( name );
864  }
865  }
866  else
867  {
868  if ( !m_commandgroup )
869  {
870  wxString name = GetCommandGroupName();
871  OpenCommandGroupNamed( name );
872  }
873  }
874 }
875 
876 void a2dBaseTool::OpenCommandGroupNamed( const wxString& name )
877 {
878  wxASSERT_MSG( !m_commandgroup, wxT( "Unclosed command group" ) );
879 
881 }
882 
884 {
885  if ( m_commandgroup && this == m_controller->GetFirstTool() )
886  {
887  if( GetDrawingPart() )
888  {
890  }
891  m_commandgroup = 0;
892  }
893 }
894 
896 {
897  return GetClassInfo()->GetClassName();
898 }
899 
900 void a2dBaseTool::SetCorridor( const a2dCorridor& corridor )
901 {
902  m_corridor = corridor;
903  if ( m_corridor.empty() )
904  {
905  m_corridor.Push( GetDrawingPart()->GetShowObject() );
907  }
908  else
909  {
910  m_parentobject = m_corridor.back();
911  }
912  wxASSERT_MSG( m_parentobject->GetRoot() != 0 , wxT( "parentobject of tools has no drawing root set" ) );
913  GetDrawingPart()->SetCorridorPath( corridor );
914 }
915 
917 {
918  object->SetAlgoSkip( true );
921  wxASSERT_MSG( m_parentobject->GetRoot() != 0 , wxT( "parentobject of tools has no drawing root set" ) );
922  m_parentobject->Append( object );
923  object->SetSnapTo( false );
924 }
925 
927 {
928  // Usually shortly added, so scanning backwards is usually faster
930 }
931 
933 {
934  object->SetAlgoSkip( true );
937 
938  object->SetHitFlags( a2dCANOBJ_EVENT_NON );
939  wxASSERT_MSG( m_parentobject->GetRoot() != 0 , wxT( "parentobject of tools has no drawing root set" ) );
940  m_parentobject->Append( object );
941  object->SetSnapTo( false );
942 }
943 
945 {
946  a2dCanvasObjectList::iterator iter = m_parentobject->GetChildObjectList()->begin();
947  while( iter != m_parentobject->GetChildObjectList()->end() )
948  {
949  a2dCanvasObject* obj = *iter;
950  iter++;
951  if( obj->GetAlgoSkip() && a2dCanvasObject::PROPID_ToolDecoration->GetPropertyValue( obj ) )
953  }
954 
955  //first update the document, in order to get the right boundingboxes again ( also of the tool object )
957 }
958 
960 {
962 }
963 
965 {
966  return m_controller->GetDrawingPart()->GetDisplayWindow();
967 }
968 
970 {
971  if ( !GetDrawingPart() )
972  return NULL;
973  return GetDrawingPart()->GetDrawing();
974 }
975 
977 {
978  if ( !GetDrawingPart() || !GetDrawingPart()->GetShowObject() )
979  return NULL;
981 }
982 
984 {
985  if ( a2dPin::GetWorldBased() )
986  return GetDrawing()->GetHabitat()->GetPinSize()/2.0;
987  else
988  return GetDrawer2D()->DeviceToWorldXRel( GetDrawing()->GetHabitat()->GetPinSize()/2.0 );
989 }
990 
991 //-----------------------------------------------------------
992 // a2dToolEvtHandler
993 //-----------------------------------------------------------
994 
995 BEGIN_EVENT_TABLE( a2dToolEvtHandler, a2dObject )
996  EVT_COM_EVENT( a2dToolEvtHandler::OnComEvent )
997 END_EVENT_TABLE()
998 
1000 {
1001 }
1002 
1003 void a2dToolEvtHandler::OnComEvent( a2dComEvent& event )
1004 {
1005  event.Skip();
1006 }
1007 
1008 bool a2dToolEvtHandler::ProcessEvent( wxEvent& event )
1009 {
1010  if ( a2dObject::ProcessEvent( event ) )
1011  return true;
1012  return false;
1013 }
1014 
Display Part of a a2dDrawing, in which a2dCanvasObjects are shown.
Definition: drawer.h:470
Base class for all types of strokes, understood by a2dDrawer2D classes.
Definition: stylebase.h:378
bool DisableTool(const wxString &tool)
disable the tool with the given name
Definition: tools.cpp:208
a2dCanvasObjectPtr m_parentobject
( if needed ) parent a2dCanvasObject relative to which the tool actions take place.
Definition: tools.h:854
bool Activate(const wxString &tool, bool disableothers)
Activate the tool with the given name.
Definition: tools.cpp:154
bool m_pending
set when tool needs an redraw (after a a2dCanvas Repaint etc.)
Definition: tools.h:814
a2dCanvasCommandProcessor * GetCanvasCommandProcessor()
Returns a pointer to the command processor associated with this document.
Definition: tools.cpp:976
The a2dBaseTool is used to derive tools from that are controlled by.
Definition: tools.h:379
wxUint16 m_layer
layer for a new object
Definition: tools.h:832
void Push(a2dCanvasObject *object)
push object onto existing corridor
Definition: objlist.cpp:820
void ClearCorridorPath(bool uncapture)
Reset all corridor paths and uncapture object.
Definition: drawer.cpp:1549
wxCursor m_toolcursor
cursor to use
Definition: tools.h:768
bool m_isEditTool
if tool does change drawing
Definition: tools.h:798
a2dCommandGroup * m_commandgroup
the command group of the command processor
Definition: tools.h:848
class to map references to objects stored in XML, in order to make the connection later on...
Definition: gen.h:3462
transfer this property via a command processor
Definition: id.h:169
void SetIgnorePendingObjects(bool onoff)
Switches ignorance of pending objects on and off.
Definition: tools.cpp:628
a2dSmrtPtr< a2dObject > m_eventHandler
when set called before own event handler
Definition: tools.h:787
void OnComEvent(a2dComEvent &event)
default handler for a2dComEvent event
Definition: tools.cpp:679
list for a2dBaseTool&#39;s
Definition: tools.h:57
void SetFill(const a2dFill &fill)
set fill if used inside a tool
Definition: tools.cpp:812
void RemoveAllDecorations()
remove all object that were added as decorations.
Definition: tools.cpp:944
double m_contourwidth
if != 0 the polygon is contoured at distance m_contourwidth/2
Definition: tools.h:829
double GetHitMargin()
Definition: tools.cpp:983
a2dDrawingPart * m_drawingPart
a2dDrawingPart where tool is plugged into
Definition: tools.h:306
virtual void OpenCommandGroup(bool restart)
called when starting an editing operation (e.g. on mouse down)
Definition: tools.cpp:852
void AddDecorationObject(a2dCanvasObject *object)
Add a decoration object to be rendered by the tool.
Definition: tools.cpp:932
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
a2dDrawing * GetRoot() const
get a2dCanvasDocument of the object.
Definition: canobj.h:952
#define EVT_DO(func)
event sent from a2DocumentCommandProcessor when a command is initially done
Definition: comevt.h:795
When cloning, and this flag is set, the property is cloned deep, else not.
Definition: id.h:196
bool ProcessEvent(wxEvent &event)
event recieved from tools processed here
Definition: tools.cpp:1008
virtual wxString GetCommandGroupName()
return the command group name for commands of a derived class
Definition: tools.cpp:895
a2dDrawingPart * GetDrawingPart()
Access to the tool controllers drawer.
Definition: tools.h:632
store a menu Id generated by XRCID( menuIdString ) plus a menustring and helpstring ...
Definition: comevt.h:1563
virtual void OpenCommandGroupNamed(const wxString &name)
called when starting an editing operation with another than the default name
Definition: tools.cpp:876
void RemoveEditobject(a2dCanvasObject *object)
Remove an editcopy object to the tool/document.
Definition: tools.cpp:926
void SetSnap(bool doSnap)
set snap on or off.
Definition: tools.cpp:453
a2dDrawing * GetDrawing()
Returns a pointer to the drawing.
Definition: tools.cpp:969
if set, clone childs, otherwise ref-copy them
Definition: gen.h:1207
a command processor specially designed to work with a a2dCanvasDocument
Definition: drawing.h:1046
bool m_anotate
when true anotation will be shown, if used inside a tool
Definition: tools.h:839
#define EVT_REDO(func)
event sent from a2DocumentCommandProcessor when a command is redone
Definition: comevt.h:799
virtual void FinishBusyMode(bool closeCommandGroup=true)
Called when the user finishes editing a distinct object */.
Definition: tools.cpp:755
bool m_active
tool is operational
Definition: tools.h:777
void ActivateTop(bool active)
(de)activate the first tool in the list.
Definition: tools.cpp:141
bool SetCanvasToolContr(a2dToolContr *controller)
set toolcontroller ( reset with NULL )
Definition: drawer.cpp:785
a2dCanvasObject is the base class for Canvas Objects.
Definition: canobj.h:371
virtual void Render()
render the tool chain
Definition: tools.cpp:440
a2dDrawingPart * GetDrawingPart()
Get the a2dDrawingPart object that the controller is plugged into.
Definition: tools.h:104
#define A2D_PROPID_M(type, classname, propname, defaultval, mptr)
to define a get set property more easily
Definition: id.h:730
bool GetMouseEvents() const
return true if this a2dDrawingPart allows mouse events to be processed.
Definition: drawer.h:631
virtual a2dObject * GetRefObject() const
when a2dProperty, return its value else assert
Definition: gen.cpp:1976
a2dCanvasObjectList * GetChildObjectList()
get the list where the child objects are stored in.
Definition: canobj.cpp:2551
bool ProcessEvent(wxEvent &event)
process an event for the object, if the event is not handled by
Definition: tools.cpp:249
bool SetCorridor(const a2dCorridor &corridor)
define corridor for the controller its first tool
Definition: tools.cpp:446
a2dStroke m_stroke
stroke for new object
Definition: tools.h:826
bool ProcessEvent(wxEvent &event)
events recieved from controller processed here
Definition: tools.cpp:668
virtual bool EnterBusyMode()
Called when the user selects a distinct object for editing */.
Definition: tools.cpp:724
int ReleaseChild(a2dCanvasObject *obj, bool backwards=false, bool all=false, bool now=false, bool undoCommands=false)
remove the given object from the childobjects
Definition: canobj.cpp:6260
wxUint8 m_bussyStopping
if &gt; 0, the tool is in the process of stopping, which means it can not be poped yet by controller...
Definition: tools.h:780
static a2dPropertyIdRefObject * PROPID_ViewSpecific
Definition: canobj.h:2691
static const a2dSignal sig_toolComEvent
not yet used.
Definition: tools.h:393
virtual bool StartTool(a2dBaseTool *currenttool)
called to initiate while pushing tool to toolcontroller
Definition: tools.cpp:641
a2dDrawer2D * GetDrawer2D()
Access to the tool controllers drawers drawer2d.
Definition: tools.cpp:959
void OnEnter(wxMouseEvent &event)
sets the focus to the display window.
Definition: tools.cpp:401
a2dFill m_fill
fill for new object
Definition: tools.h:823
void SetIgnorePendingObjects(bool onoff)
Switches ignorance of pending objects on and off.
Definition: drawing.cpp:432
static const a2dSignal sig_changedShowObject
Definition: drawer.h:1513
void CommandGroupEnd(a2dCommandGroup *group)
End a command group.
Definition: comevt.cpp:1125
bool m_canvas_mouseevents_restore
used to save the a2dCanvas mouse event setting.
Definition: tools.h:836
void SetPropertyToObject(a2dObject *obj, const basetype &value, SetFlags setflags=set_none) const
Set the property in obj to value.
Definition: id.inl:238
wxWindow * GetDisplayWindow()
Access to the tool controllers drawers canvas.
Definition: tools.cpp:964
virtual void DoStopTool(bool abort)
to do tool specific stuff to stop a tool. Called from StopTool().
Definition: tools.cpp:796
#define EVT_COM_EVENT(func)
static wxEvtHandler for communication event
Definition: gen.h:564
a2dCommandGroup * CommandGroupBegin(const wxString &name)
Start a new command group.
Definition: comevt.cpp:1096
wxCursor m_toolBusyCursor
cursor to use when the tool is busy doing something.
Definition: tools.h:771
#define wxStaticCast(obj, className)
The wxWindows 2.4.2 wxStaticCast is buggy. It evaluates its argument twice.
Definition: gen.h:123
a2dSignal GetEventComIdReturn()
after proecssin the event, on return an id can be set to communicate back to sender.
Definition: gen.h:487
Drawing context abstraction.
Definition: drawer2d.h:177
static const a2dSignal sig_toolPushed
sent to new first tool when tool was pushed
Definition: tools.h:384
void StopAllTools(bool abort=true)
all tools currently on the tool stack will be terminated and poped ( forced )
Definition: tools.cpp:123
a2dCanvasObject * GetShowObject() const
return pointer of then currently shown object on the drawer.
Definition: drawer.h:680
bool m_oneshot
do it only once
Definition: tools.h:817
wxMenu * m_mousemenu
popup menu
Definition: tools.h:851
void SetMouseEvents(bool onoff)
If not set do not process mouse events.
Definition: drawer.cpp:1081
bool ToolsProcessEvent(wxEvent &event)
Event not handled in this class are redirected to the chain of tools.
Definition: tools.cpp:289
int m_mode
general operation mode setting for a tool.
Definition: tools.h:845
virtual bool Undo()
Undo one command or command group.
Definition: drawing.cpp:6023
int Release(a2dCanvasObjectFlagsMask mask=a2dCanvasOFlags::ALL, const wxString &classname=wxT(""), const a2dPropertyId *id=NULL, const wxString &name=wxT(""), bool now=true)
release only objects with the given mask and classname and has property named propertyname and object...
Definition: objlist.cpp:306
Restriction engine for editing restrictions like snapping.
Definition: restrict.h:88
void OnKeyUp(wxKeyEvent &event)
called on keyup events
Definition: tools.cpp:842
a2dDrawer2D * GetDrawer2D()
get the internal m_drawer2D that is used for rendering the document
Definition: drawer.h:1125
void SetLayer(wxUint16 layer)
layer set for the object that is drawn using a tool
Definition: tools.cpp:827
a2dToolContr * m_controller
under control of this toolcontroller, to give me events.
Definition: tools.h:774
void Disable()
can be used by a2dCanvas or a2dDrawingPart to disable this class
Definition: tools.cpp:134
void AppendTool(a2dBaseTool *handler)
append a tool to the list, this tool will recieve an event if the other skipped the event to process...
Definition: tools.cpp:396
const a2dFill * a2dNullFILL
global a2dFill stock object for defining NO filling
a2dCorridor m_corridor
Definition: tools.h:795
no hit will be reported
Definition: canobj.h:160
corridor as a direct event path to a a2dCanvasObject
Definition: objlist.h:313
void OnChar(wxKeyEvent &event)
called on key events
Definition: tools.cpp:847
void SetMousePopupMenu(wxMenu *mousemenu)
to set the current mouse menu of the tool
Definition: tools.cpp:634
const a2dStroke * a2dNullSTROKE
global a2dStroke stock object for NO stroking
To implement behaviour on a set of tools.
Definition: tools.h:884
virtual ~a2dBaseTool()
destructor
Definition: tools.cpp:605
a2dBaseTool(a2dToolContr *controller, const a2dMenuIdItem &initiatingMenuId=CmdMenu_NoMenu())
construct a new tool for the given controller.
bool m_stop
stop the tool
Definition: tools.h:820
while iterating a a2dCanvasDocument, this holds the context.
Definition: canobj.h:3212
void ResetContext()
context like corridor and parentobject are reset
Definition: tools.cpp:619
void OnKeyDown(wxKeyEvent &event)
called on keydown events
Definition: tools.cpp:837
bool m_halted
if a tool is deactivated while m_busy is true, this flag is set
Definition: tools.h:810
const a2dStroke & GetStroke() const
get the current stroke
Definition: tools.h:551
static const a2dSignal sig_toolPoped
sent to new first tool when last first tool was poped
Definition: tools.h:386
void SetCorridor(const a2dCorridor &corridor)
set a corridor from a list of objects
Definition: tools.cpp:900
a2dRestrictionEngine * GetRestrictionEngine()
Get restriction engine (grid snapping)
Definition: canglob.cpp:934
static const a2dSignal sig_toolBeforePush
Definition: tools.h:389
void AddEditobject(a2dCanvasObject *object)
Add an editcopy object to the tool/document.
Definition: tools.cpp:916
virtual bool TriggerReStartEdit(wxUint16 editmode)
trigger restart editing (after undo event or when changing editing mode )
Definition: tools.cpp:435
a2dCanvasCommandProcessor * GetCanvasCommandProcessor()
get a pointer to the command processor
Definition: drawing.cpp:375
void SetStroke(const a2dStroke &stroke)
set stroke if used inside a tool
Definition: tools.cpp:817
bool ReleaseObject(T *object)
release a certain object from the list
Definition: smrtptr.inl:118
a2dBaseTool * GetFirstTool() const
get currently used eventhandler (always the first in the list)
Definition: tools.cpp:91
static const a2dSignal sig_toolDoPopBeforePush
return id after a sig_toolBeforePush, to tell current tool needs to be poped.
Definition: tools.h:391
virtual void ReStart()
Toolcontroller can be re-initialized.
Definition: tools.cpp:119
a2dToolList * DoClone(a2dObject::CloneOptions options, a2dRefMap *refs) const
Clone everything ( Clones objects also) in a new created list.
Definition: tools.cpp:40
bool GetStopTool()
checked by controller to see if the tool needs to be stopped e.g. after a oneshot.
Definition: tools.cpp:807
void OnMouseEvent(wxMouseEvent &event)
called on mouse events
Definition: tools.cpp:832
virtual void AbortBusyMode()
Called when the user aborts editing a distinct object */.
Definition: tools.cpp:770
const a2dFill & GetFill() const
get the current fill
Definition: tools.h:542
a2dToolList m_tools
tool list
Definition: tools.h:303
Event sent to a2dCommandProcessor.
Definition: comevt.h:701
virtual ~a2dToolContr()
destructor
Definition: tools.cpp:87
see a2dComEvent
Definition: gen.h:371
const a2dMenuIdItem * m_initiatingMenuId
command which initiated the tool, used to seperate commands using the tool
Definition: tools.h:742
a2dBaseTool * SearchTool(const wxString &tool)
search for the tools in the tool list with the given name.
Definition: tools.cpp:238
virtual bool PushTool(a2dBaseTool *handler)
push/pop tool:
Definition: tools.cpp:335
base classes for tools and controller on top of the tools.
void SetDrawingPart(a2dDrawingPart *drawingPart)
sets the a2dDrawingPart on which the controller will work.
Definition: tools.cpp:96
wxFont m_annotateFont
font to use for anotation
Definition: tools.h:842
void SetCorridorPath(const a2dCorridor &corridor)
find object on the current corridor path.
Definition: drawer.cpp:1534
bool m_snap
snap is on or off
Definition: tools.h:313
bool EnableTool(const wxString &tool, bool disableothers)
enable the tool with the given name
Definition: tools.cpp:172
void OnPaint(wxPaintEvent &event)
window Onpaint is received here before the window Onpaint where this controller is plugged into...
Definition: tools.cpp:406
a2dDrawing * GetDrawing() const
get drawing via top object
Definition: drawer.cpp:726
static bool GetWorldBased()
get if pin sizes are in world coordinates, else it is in pixels.
Definition: canpin.h:319
bool AddPendingUpdatesOldNew()
adds current and future boundingbox of the objects with pending flag set, to the pendinglist of all a...
Definition: drawing.cpp:525
basetype GetPropertyValue(const a2dObject *obj) const
Get the property value in obj.
Definition: id.inl:325
a2dCanvasGlobal * a2dCanvasGlobals
global a2dCanvasGlobal to have easy access to global settings
Definition: canglob.cpp:1234
all headers of the canvas module
#define EVT_UNDO(func)
event sent from a2DocumentCommandProcessor when a command is undone
Definition: comevt.h:797
static a2dPropertyIdBool * PROPID_ToolDecoration
set for objects that act as tool decorations, when a tool is in action.
Definition: canobj.h:2675
virtual bool StartEditingObject(a2dCanvasObject *objectToEdit)
start editing object using existing corridor to object
Definition: tools.cpp:425
The a2dToolContr is the base class for Tool controller classes.
Definition: tools.h:87
This template class is for property ids with a known data type.
Definition: id.h:477
void SetSnap(bool snap)
enable all snapping features or not
Definition: restrict.h:189
bool m_bussyPoping
Definition: tools.h:310
void Append(a2dCanvasObject *obj)
append a a2dCanvasObject to the childobjects
Definition: canobj.cpp:6224
virtual void SetActive(bool active=true)
set the tool active or inactive.
Definition: tools.cpp:648
bool m_ignorePendingObjects
if set ignore all setting for pendingobjects
Definition: tools.h:790
void StopTool(bool abort=false)
call to stop a tool, internal and external.
Definition: tools.cpp:785
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
virtual void CloseCommandGroup()
called when ending an editing operation (e.g. mouse up)
Definition: tools.cpp:883
Contain one drawing as hierarchical tree of a2dCanvasObject&#39;s.
Definition: drawing.h:434
virtual bool PopTool(a2dBaseToolPtr &poped, bool force=true)
remove first tool on the tool stack
Definition: tools.cpp:364
#define a2dREFOBJECTPTR_KEEPALIVE
Definition: gen.h:1631
tools.cpp Source File -- Sun Oct 12 2014 17:04:26 -- Sun Oct 12 2014 -- 1.8.5 -- wxArt2D -- . -- Main Page Reference Documentation