00001 /*! \file wx/canvas/tools.h 00002 \brief base classes for tools and controller on top of the tools. 00003 00004 a2dToolContr gets event from a2dCanvasView before it handles the event itself. 00005 a2dToolContr has a stack of tools (a2dToolList) that contains one or more tools (a2dBaseTool). 00006 The tool first in the list is the active tool, which gets the events first. 00007 Tools are in general for modifying drawings interactive. 00008 00009 \author Klaas Holwerda 00010 00011 Copyright: 2001-2004 (c) Klaas Holwerda 00012 00013 Licence: wxWidgets Licence 00014 00015 RCS-ID: $Id: tools.h,v 1.28 2009/06/03 17:38:12 titato Exp $ 00016 */ 00017 00018 #ifndef __A2DCANVASTOOLS_H__ 00019 #define __A2DCANVASTOOLS_H__ 00020 00021 #ifndef WX_PRECOMP 00022 #include "wx/wx.h" 00023 #endif 00024 00025 #include "wx/event.h" 00026 00027 #include "wx/canvas/candefs.h" 00028 #include "wx/general/smrtptr.h" 00029 #include "wx/general/smrtptr.inl" 00030 #include "wx/canvas/objlist.h" 00031 00032 //---------------------------------------------------------------------------- 00033 // decls 00034 //---------------------------------------------------------------------------- 00035 //initalization 00036 00037 class A2DCANVASDLLEXP a2dBaseTool; 00038 00039 #if defined(WXART2D_USINGDLL) 00040 template class A2DCANVASDLLEXP a2dSmrtPtr< a2dBaseTool >; 00041 template class A2DCANVASDLLEXP std::allocator<class a2dSmrtPtr<class a2dBaseTool> >; 00042 template class A2DCANVASDLLEXP std::allocator< std::_List_nod<class a2dSmrtPtr<class a2dBaseTool>, std::allocator<class a2dSmrtPtr<class a2dBaseTool> > >::_Node >; 00043 template class A2DCANVASDLLEXP std::allocator< std::_List_ptr<class a2dSmrtPtr<class a2dBaseTool>, std::allocator<class a2dSmrtPtr<class a2dBaseTool> > >::_Nodeptr >; 00044 template class A2DCANVASDLLEXP std::list<class a2dSmrtPtr<class a2dBaseTool> >::iterator; 00045 template class A2DCANVASDLLEXP std::list<class a2dSmrtPtr<class a2dBaseTool> >; 00046 template class A2DCANVASDLLEXP a2dlist<class a2dSmrtPtr<class a2dBaseTool> >; 00047 template class A2DCANVASDLLEXP a2dSmrtPtrList<a2dBaseTool>; 00048 #endif 00049 00050 // it is used in editor/mastertool.h 00051 typedef a2dSmrtPtr<a2dBaseTool> a2dBaseToolPtr; 00052 00053 //! list for a2dBaseTool's 00054 /*! 00055 used as list of tools in a2dToolContr. 00056 */ 00057 class A2DCANVASDLLEXP a2dToolList: public a2dSmrtPtrList<a2dBaseTool> 00058 { 00059 public: 00060 a2dToolList(); 00061 00062 ~a2dToolList(); 00063 00064 00065 //!Clone everything ( Clones objects also) in a new created list 00066 a2dToolList* Clone( a2dObject::CloneOptions options ) const; 00067 00068 }; 00069 00070 //!The a2dToolContr is the base class for Tool controller classes. 00071 /*! 00072 A tool controller handles redirection of events from the a2dCanvas/a2dCanvasView Events to the 00073 tools that are maintained by a controller. 00074 The controller is derived from wxEvtHandler, and there for can be (un)plugged into a 00075 a2dCanvasView window. 00076 It then intercepts all events on the canvas window, and sents them to the active tool. 00077 The controller has a list of tools, only the active tool will react on the events. 00078 More then one tool may be active, in which case skipped events will be handled by 00079 later tools in the tool list. In the end skipped events in all tools 00080 are handled by a2dCanvasView itself. 00081 \sa a2dBaseTool 00082 \sa a2dCanvasView 00083 \sa a2dCanvas 00084 00085 \ingroup tools 00086 */ 00087 class A2DCANVASDLLEXP a2dToolContr: public a2dEvtHandler 00088 { 00089 public: 00090 00091 //!\param view view where the controller takes events from 00092 a2dToolContr(a2dCanvasView* view); 00093 00094 //! destructor 00095 virtual ~a2dToolContr(); 00096 00097 //!sets the a2dCanvasView on which the controller will work. 00098 /*! \param view the new canvas view to work on, if NULL this a2dToolContr 00099 will be disabled, and the controller will be popped out of a previous a2dCanvas. 00100 */ 00101 void SetCanvasView(a2dCanvasView* view); 00102 00103 //!Get the a2dCanvasView object that the controller is plugged into 00104 a2dCanvasView* GetCanvasView(){ return m_view; } 00105 00106 //! all tools currently on the tool stack will be terminated and poped ( forced ) 00107 /*! 00108 Use this when the document of the view of this controller is changed. 00109 */ 00110 void StopAllTools(); 00111 00112 //! Toolcontroller can be re-initialized 00113 /*! 00114 After changing a document on a view, and StopAllTools() was called, this function 00115 can be used to bring the controller back into a wanted state. 00116 The default does nothing. 00117 */ 00118 virtual void ReStart(); 00119 00120 //! can be used by a2dCanvas or a2dCanvasView to disable this class 00121 /*! 00122 for events, and also pops all tools from the tool stack. 00123 */ 00124 void Disable(); 00125 00126 //!get currently used eventhandler (always the first in the list) 00127 a2dBaseTool *GetFirstTool() const; 00128 00129 //! return reference to tool list 00130 const a2dToolList& GetToolList() const { return m_tools; } 00131 00132 //!process an event for the object, if the event is not handled by 00133 /*! the class itself through a static event table, 00134 it will be sent to the first tool via ToolsProcessEvent(). 00135 */ 00136 bool ProcessEvent(wxEvent& event); 00137 00138 //! push/pop tool: 00139 /*! add a tool on top of the already existing ones 00140 Calls first tools start, and if this returned true the tool will be pushed. 00141 \return true if tool its ToolStart() returned true; 00142 */ 00143 virtual bool PushTool( a2dBaseTool *handler ); 00144 00145 //!remove first tool on the tool stack 00146 /*! 00147 Calls first the tool its StopTool() which prepares the tool for stopping. 00148 Calling StopTool() within a tool, automatically result in the tool to be poped by the controller, 00149 using this function. This happens within the event processing chain. 00150 00151 \param poped the tool which is poped from the stack. 00152 \param force If AllowPop() return false, the PopTool is not done, unless force is true. 00153 00154 \remark the tool is removed from the stack, tools are reference counted so 00155 if you want to preserve it, you can. 00156 00157 \return true if a tool was available for poping. 00158 */ 00159 virtual bool PopTool( a2dBaseToolPtr& poped, bool force = true ); 00160 00161 //!append a tool to the list, this tool will recieve an event if the other skipped the event to process. */ 00162 void AppendTool(a2dBaseTool *handler); 00163 00164 //!enable the tool with the given name 00165 /*!\param tool: classname of the tool 00166 \param disableothers: if true other tools in the tool list are disabled 00167 */ 00168 bool EnableTool(const wxString& tool , bool disableothers); 00169 00170 //!enable the given tool 00171 /*!\param tool: pointer to the tool 00172 \param disableothers: if true other tools in the tool list are disabled 00173 */ 00174 bool EnableTool(a2dBaseTool* tool , bool disableothers); 00175 00176 //!disable the tool with the given name 00177 /*!Disabling a tool means that it will not receive any events. 00178 \param tool: classname of the tool 00179 */ 00180 bool DisableTool(const wxString& tool ); 00181 00182 //!disable the tool with the given name 00183 /*!Disabling a tool means that it will not receive any events. 00184 \param tool: pointer to the tool 00185 */ 00186 bool DisableTool(a2dBaseTool* tool ); 00187 00188 //!search for the tools in the tool list with the given name. 00189 /*!\param tool: classname of the tool */ 00190 a2dBaseTool* SearchTool(const wxString& tool ); 00191 00192 //!(de)activate the first tool in the list. 00193 /*! (de)activates the first tool on the stack, and deactivates all others 00194 */ 00195 void ActivateTop( bool active ); 00196 00197 //!Activate the tool with the given name 00198 /*!\remark DIS activating a tool means it will skip mouse events 00199 \remark it will still receive other events like Onpaint Onchar. 00200 \param tool: pointer to the tool 00201 \param disableothers: if true other tools in the tool list are made inactive 00202 */ 00203 bool Activate(const wxString& tool, bool disableothers); 00204 00205 //! start editing object using existing corridor to object 00206 /*! 00207 Start editing the object within the coordinate system defined by the corridor set by for instance 00208 a2dIterC::SetCorridorPath() Parent of startobject is defined as last object in corridor. 00209 00210 The corridor is used to calculate the editworld matrix, meaning relative to what coordinates system 00211 the editing takes place. This becomes important when editing children of objects directly. 00212 00213 \remark if a corridor is not set in the a2dCanvasDocument, the ShowObject() of the a2dCanvasView is used. 00214 00215 \remark at the top level (ShowObject of view) the editorWorld is always a2dIDENTITY_MATRIX 00216 else it depends on the structure of the document. 00217 */ 00218 virtual bool StartEditingObject( a2dCanvasObject* objectToEdit ); 00219 00220 //! start editing object using iteration context to define corridor. 00221 /*! 00222 The editcopy created of the objectToEdit is used to capture the corridor to that object. 00223 */ 00224 virtual bool StartEditingObject( a2dCanvasObject* objectToEdit, a2dIterC& ic ); 00225 00226 //! trigger restart editing (after undo event or when changing editing mode ) 00227 /*! 00228 An editing tool on a a2dCanvasObject can be restarted in derived controller. 00229 */ 00230 virtual bool TriggerReStartEdit( wxUint16 editmode ); 00231 00232 //! define corridor for the controller its first tool 00233 bool SetCorridor( const a2dCorridor& corridor ); 00234 00235 //! render the tool chain 00236 /*! 00237 A tool chain gets rendered when a2dCanvasView is updating areas that are changed in a document. 00238 */ 00239 virtual void Render(); 00240 00241 //!set snap on or off. 00242 /*! 00243 When snapping is on, tools will respect this, and drawing will be on the snap grid. 00244 */ 00245 void SetSnap( bool doSnap ); 00246 00247 //!get current snap setting ( true or false ). 00248 inline bool GetSnap() { return m_snap; } 00249 00250 protected: 00251 00252 //! Event not handled in this class are redirected to the chain of tools. 00253 /*! 00254 When there are tools in the tools chain, the first tools receives the event first. 00255 00256 If you derive a class from this controller class here, you might not want to use the 00257 base event handling for some type of events, even if you do not handle it 00258 yourself in your static event callback. 00259 Normally handling an event in the baseclass is achieved with event.Skip(). 00260 ( e.g in OnMouse or OnChar ). 00261 But by calling ToolsProcessEvent() function here directly, skipping is not needed, and the event 00262 will directly go to the first available tool. 00263 00264 \remark If new tools are pushed while handling the event in the currently available tools, 00265 and the event itself was skipped ( not handled ), it will be redirect to the pushed tools. 00266 This is in a recursive manner, so there may be a chain of extra pushed tools. 00267 00268 \remark If a tool is stopped ( \see GetStopTool() ), it is poped from the tools stack. 00269 And if the event is not processed yet, it is sent to the next/new first tool. 00270 More tools can be stopped in a chain of tools as a respons to one and the same event. 00271 00272 \see ProcessEvent 00273 00274 \param event the event which will be sent to the tools. 00275 00276 \return true if the event was processed and event.Skip() was not called. 00277 */ 00278 bool ToolsProcessEvent(wxEvent& event); 00279 00280 //! a2dCanvas its a2dView being closed means disable this controller 00281 void OnCloseView( a2dCloseViewEvent& event ); 00282 00283 void OnSetDocument( a2dViewEvent& event ); 00284 00285 //! sets the focus to the display window. 00286 void OnEnter( wxMouseEvent & WXUNUSED(event) ); 00287 00288 //!window Onpaint is received here before the window Onpaint where this controller is plugged into. 00289 /*!In general a flag is set to do the job in Onidle time after the window itself is repainted */ 00290 void OnPaint( wxPaintEvent &event ); 00291 00292 void OnIdle( wxIdleEvent &event ); 00293 00294 //!tool list 00295 a2dToolList m_tools; 00296 00297 //!a2dCanvasView where tool is plugged into 00298 a2dCanvasView* m_view; 00299 00300 //! set when poping a tool is in progress. 00301 //! This is used to prevent recursive calls from event sent around in the poping process. 00302 bool m_bussyPoping; 00303 00304 //!snap is on or off 00305 bool m_snap; 00306 00307 private: 00308 00309 00310 A2D_DECLARE_EVENT_TABLE() 00311 DECLARE_CLASS(a2dToolContr) 00312 }; 00313 00314 #if defined(WXART2D_USINGDLL) 00315 template class A2DCANVASDLLEXP a2dSmrtPtr<a2dToolContr>; 00316 #endif 00317 00318 //----------------------------------------------------------- 00319 // tool modifier on action 00320 //----------------------------------------------------------- 00321 00322 class A2DCANVASDLLEXP a2dToolFunctor; 00323 00324 typedef a2dSmrtPtr<a2dToolFunctor> a2dToolFunctorPtr; 00325 00326 //!The a2dBaseTool is used to derive tools from that are controlled by 00327 /*! a a2dToolContr derived class. 00328 00329 The basetool does not implement default behaviour for events in many cases, instead it is possible to set m_eventHandler to take 00330 care of action which are the same for a set of tools. a2dBaseTool::ProcessEvent() first redirect incoming events to 00331 m_eventHandler, and if not handled there it goes to the tools its own event handler. 00332 00333 - wxEventType sm_toolPushed sent from controller just after this tool is pushed, 00334 the tool is the first on the stack. This event can be used to have a master tool push extra tools. 00335 00336 - a2dComEvent( GetFirstTool(), poped, &sm_toolPoped ) sent from controller to tool when some 00337 other tool is poped from the tool stack. This can be used to control style settings for this tool, 00338 based on the last active tool on the top of the tool stack. E.g When style is changed when editing 00339 a primitive, the tool that was used to draw this primitive and started the editing tool, normally wants to take over this style. 00340 This function is called just after a tool was poped from the stack. 00341 00342 - a2dComEvent( GetFirstTool(), poped, &sm_toolBeforePoped ) sent from controller when a new tool is pushed, 00343 while the current tool is on the stack. This can be used to control halting or stopping of the current tool. 00344 E.g. When a tool allows Zooming while busy, you halt the tool here, but while the new tool is totataly independent, 00345 one may terminate the current tool action and close its command group. This function is called just before the new 00346 tool is indeed pushed on the stack. 00347 00348 \sa a2dToolContr 00349 00350 \ingroup tools 00351 */ 00352 class A2DCANVASDLLEXP a2dBaseTool: public a2dEvtHandler 00353 { 00354 public: 00355 00356 //! sent to new first tool when tool was pushed 00357 static const wxEventType sm_toolPushed; 00358 //! sent to new first tool when last first tool was poped 00359 static const wxEventType sm_toolPoped; 00360 //! sent to current firsttool so it can pop itself based on the tool to push. 00361 //! Allows the current first tool to react on a the pushing of the new tool. 00362 static const wxEventType sm_toolBeforePush; 00363 //! return id after a sm_toolBeforePush, to tell current tool needs to be poped. 00364 static const wxEventType sm_toolDoPopBeforePush; 00365 //! not yet used. 00366 static const wxEventType sm_toolComEvent; 00367 00368 //! events recieved from controller processed here 00369 /*! 00370 first m_eventHandler is tried, if not set or not processed, try object itself. 00371 */ 00372 bool ProcessEvent( wxEvent& event ); 00373 00374 //! to reroute events to this event handler 00375 void SetEvtHandler( a2dEvtHandler* handler ) { m_eventHandler = handler; } 00376 00377 a2dEvtHandler* GetEventHandler() 00378 { 00379 if ( m_eventHandler ) 00380 return m_eventHandler; 00381 return this; 00382 } 00383 00384 //!construct a new tool for the given controller. 00385 a2dBaseTool(a2dToolContr* controller); 00386 00387 //! constructor initializing partly from other tool 00388 a2dBaseTool( const a2dBaseTool& other, CloneOptions options ); 00389 00390 //!destructor 00391 virtual ~a2dBaseTool(); 00392 00393 inline a2dBaseTool* TClone( CloneOptions options ) { return (a2dBaseTool*) Clone( options ); } 00394 00395 //!called to initiate while pushing tool to toolcontroller 00396 /*! It also resets the m_stop flag to false. 00397 */ 00398 virtual bool StartTool( a2dBaseTool* currenttool ); 00399 00400 //!Only one action of the tool, after that it will ask the controller to stop this tool. 00401 void SetOneShot() { m_oneshot=true; } 00402 00403 //!Is Zooming while the tool is busy Save. 00404 /*!If so, the active tool will redraw itself in the new Mapping state */ 00405 virtual bool ZoomSave()=0; 00406 00407 //! tells if a tool can be poped from the stack. 00408 /*! 00409 The controller tests if a tool is allowed to be poped from the stack. 00410 When a tool returns false here, that tool will stay on the stack until controller 00411 is destructed. 00412 */ 00413 virtual bool AllowPop() { return true; } 00414 00415 //! call to stop a tool, internal and external. 00416 /*! The stop flag within the tool will be set, triggering deletion of the tool 00417 from the outside by the a2dToolContr. Stopping one tool often means activating 00418 another which is on the tool stack of the a2dToolContr. Therefore the tools 00419 are really stopped and removed from the tool stack from the outside. 00420 00421 After this call the tool must be left in a state that allows the controller to pop the tool. 00422 00423 Override DoStopTool() function, if there is cleaning up to do before stopping a tool. 00424 Understand that stopping the tool is something else then (de)activating a tool. 00425 A tool can be de-activated, but still in action or at least on the toolstack. 00426 Stopping a tools really removes the tool from the stack by the controller. 00427 00428 To prevent poping the tool from the outside before it is really stopped, 00429 m_bussyStopping is incremented, when recursive calling this function. 00430 GetStopTool() only returns true when all recursive StopTool() calls have returned. 00431 00432 \remark If a tool can not be stopped right now, the function should return false. 00433 00434 \remark Stopping a tools will indirectly lead to the a2dToolContr Popping the 00435 tool from the stack, and that action at least de-activates the tool just stopped. 00436 So indirectly SetActive( false ) is called on this tool, when it is really stopped. 00437 00438 \param abort if true the tool is calling AbortBusyMode() instead FinishBusyMode(), 00439 the effect is that the tool does directly Undo what it was doing, but not yet did finish. 00440 */ 00441 void StopTool( bool abort = false ); 00442 00443 //!checked by controller to see if the tool needs to be stopped e.g. after a oneshot. 00444 /*! or when wanted. 00445 The stop flag is in general set after a tool has received and handled an event 00446 which should stop the tool. A tool should not stop itself, since the tool will be deleted. 00447 The StopTool() function is called in such a case to trigger the stopping of the tool. 00448 */ 00449 bool GetStopTool(); 00450 00451 //!is the tool active? 00452 /*! A tool is "active", when it receives mouse input. Usually this is only the top tool 00453 on the tool stack. This is something completely different then "busy". 00454 A tool is "busy", when it currently focuses on editing a specific object. 00455 Toolstates change like this: 00456 1. Created 00457 2. Pushed on the tool stack -> set active 00458 3. User clicks on an object to edit -> set busy 00459 4. User starts a different tool (e.g. zoom) -> busy but not active (halted) 00460 5. subtool is stopped -> set active again (and busy) 00461 6. User continues editing the object selected in 3. -> still busy 00462 7. User finishes editing the object selected in 3. -> no longer busy, but still active 00463 "One-shot" tools are stopped in this situations, other tools continue. 00464 8. User clicks on a different object, repeat step 3..7 -> busy again 00465 9. User stops tool (end tool menu or ESC or 2x double-click ...) -> stopped 00466 10 Tool gets popped from the tool stack 00467 */ 00468 bool GetActive() { return m_active; } 00469 00470 //!set the tool active or inactive. 00471 /*! 00472 If the tool needs initializing after it was inactive for a while, 00473 override this function to re-initialize the tool. 00474 This function can be used to distribute its settings for style etc. to the documents 00475 \see a2dCanvasDocument::GetCanvasCommandProcessor(). 00476 The default implementation sets fill, stroke to the commandprocessor, 00477 but only when m_doSetStyleToCommandProc is true. 00478 If you need more complicated behaviour just override. 00479 */ 00480 virtual void SetActive( bool active = true ); 00481 00482 //! Check if the tool is busy editing a distinct object */ 00483 /*! \see GetActive for a discription of various tool states */ 00484 bool GetBusy() { return m_busy; } 00485 00486 //! Called when the user selects a distinct object for editing */ 00487 /*! \see GetActive for a discription of various tool states 00488 You should call the base class (this) version at the END of your function 00489 */ 00490 virtual bool EnterBusyMode(); 00491 00492 //! Called when the user finishes editing a distinct object */ 00493 /*! \see EnterBusyMode, \see GetActive 00494 You should call the base class (this) version at the END of your function 00495 */ 00496 virtual void FinishBusyMode( bool closeCommandGroup = true ); 00497 00498 //! Called when the user aborts editing a distinct object */ 00499 /*! \see EnterBusyMode 00500 This is supposed to undo aeverything the tool did since entering busy mode 00501 */ 00502 virtual void AbortBusyMode(); 00503 00504 //!set fill if used inside a tool 00505 void SetFill( const a2dFill& fill); 00506 00507 //!get the current fill 00508 /*! 00509 Return the current fill 00510 */ 00511 const a2dFill& GetFill() const { return m_fill; } 00512 00513 //!set stroke if used inside a tool 00514 void SetStroke( const a2dStroke& stroke); 00515 00516 //!get the current stroke 00517 /*! 00518 Return the current stroke 00519 */ 00520 const a2dStroke& GetStroke() const { return m_stroke; } 00521 00522 //! layer set for the object that is drawn using a tool 00523 void SetLayer(wxUint16 layer); 00524 00525 //!layer set for new objects. 00526 inline wxUint16 GetLayer() { return m_layer; } 00527 00528 //!when true anotation will be shown, if used inside a tool 00529 /*! tools can show text when in action (e.g radius of the circle that is drawn) 00530 This is called anotation. 00531 The flag set by this function can be used to enable or disable the anotation. 00532 */ 00533 void SetShowAnotation( bool show ) { m_anotate = show; } 00534 00535 //! font to use for anotation 00536 void SetAnotationFont( const wxFont& font ) { m_annotateFont = font; } 00537 00538 //! Sets cursor which the tool should use when started 00539 /*! 00540 You may change the predefined cursor which the tool uses when it 00541 becomes active. 00542 00543 \remark 00544 Many tools are using more than one cursor. These cursors indicate 00545 the status of the tool (busy etc.) and only the busy cursor can be 00546 changed currently. 00547 This cursor only indicate that the tool is active. 00548 00549 \param cursor the tool cursor 00550 */ 00551 void SetCursorType(const wxCursor& cursor) { m_toolcursor = cursor; } 00552 00553 //! Sets cursor which the tool should use when busy 00554 /*! 00555 You may change the predefined cursor which the tool uses when it 00556 becomes busy. 00557 00558 \param cursor the tool cursor 00559 */ 00560 void SetBusyCursorType(const wxCursor& cursor) { m_toolBusyCursor = cursor; } 00561 00562 //!what cursor is used when tool is started 00563 wxCursor GetCursorType(){ return m_toolcursor; } 00564 00565 //!what cursor is used when tool is busy 00566 wxCursor GetBusyCursorType(){ return m_toolBusyCursor; } 00567 00568 //! general integer to set operation modes for a tool (e.g the way it draws) 00569 /*! tools most check the mode and handle in accordance 00570 In general Tab should be used to tab/switch/circle between modes 00571 understood by a tool. 00572 */ 00573 virtual void SetMode( int mode ) { m_mode = mode; } 00574 00575 //! can be used to modify the behaviour of the derived tool. 00576 /*! 00577 Tools may have several ways of doing the same or simular things. 00578 This integer can be used to set this mode, it depends on the implementation 00579 what happens. 00580 */ 00581 int GetMode() { return m_mode; } 00582 00583 //! a tool is set pending when it needs to be redrawn. 00584 void SetPending( bool pending = true ) { m_pending = pending; } 00585 00586 //! return if the tool is set pending for redraw. 00587 bool GetPending() { return m_pending; } 00588 00589 //! render the tool chain 00590 /*! 00591 A tool chain gets rendered when a2dCanvasView is updating areas that are changed in a document. 00592 */ 00593 virtual void Render() {}; 00594 00595 //! to get the tool controller to which this tool is attached. 00596 a2dToolContr *GetToolController() { 00597 return m_controller; 00598 } 00599 //! Access to the tool controllers drawer 00600 a2dCanvasView *GetCanvasView() { 00601 return m_controller->GetCanvasView(); 00602 } 00603 //! Access to the tool controllers drawers drawer2d 00604 a2dDrawer2D *GetDrawer2D(); 00605 00606 //! Access to the tool controllers drawers canvas 00607 wxWindow* GetDisplayWindow(); 00608 00609 //!Returns a pointer to the document 00610 a2dCanvasDocument *GetCanvasDocument(); 00611 00612 //!Returns a pointer to the command processor associated with this document 00613 a2dCanvasCommandProcessor *GetCanvasCommandProcessor(); 00614 00615 //!called when starting an editing operation (e.g. on mouse down) 00616 /*!\param restart add a hint to the command group name, that this tool was restarted */ 00617 virtual void OpenCommandGroup( bool restart ); 00618 //!called when starting an editing operation with another than the default name 00619 virtual void OpenCommandGroupNamed( const wxString &name ); 00620 //!called when ending an editing operation (e.g. mouse up) 00621 virtual void CloseCommandGroup(); 00622 //!return the command group name for commands of a derived class 00623 /*!this defaults to the class name */ 00624 virtual wxString GetCommandGroupName(); 00625 00626 //! return the command group that is open else NULL. 00627 a2dCommandGroup* GetCommandgroup() { return m_commandgroup; } 00628 00629 //! to get the current mouse menu of the tool 00630 /*! see also RightMouseClick() 00631 /return NULL if no menu is set, else the menu. 00632 */ 00633 wxMenu* GetMousePopupMenu() { return m_mousemenu; } 00634 00635 //! to set the current mouse menu of the tool 00636 /*! see also RightMouseClick() 00637 NULL sets the menu to non. 00638 */ 00639 void SetMousePopupMenu( wxMenu* mousemenu ); 00640 00641 //! parent object relative to which the actions take place. 00642 /*! 00643 Tools can do there work on child objects of some parent a2dCanvasObject. 00644 In such cases the context of the tool is set with SetCorridor(), and the last object in the corridor 00645 is the m_parentobject. 00646 */ 00647 a2dCanvasObject* GetParentObject() { return m_parentobject; } 00648 00649 //! Add an editcopy object to the tool/document 00650 void AddEditobject( a2dCanvasObject *object ); 00651 //! Remove an editcopy object to the tool/document 00652 void RemoveEditobject( a2dCanvasObject *object ); 00653 00654 //! Add a decoration object to be rendered by the tool. 00655 /*! Decoration object are rendered by the tool in the style they have. 00656 They are used to add extra drawings to the actual tool object to clarify editing and drawing.*/ 00657 void AddDecorationObject( a2dCanvasObject *object ); 00658 00659 //! remove all object that were added as decorations. 00660 void RemoveAllDecorations(); 00661 00662 //! Switches ignorance of pending objects on and off. 00663 /*! 00664 If set to <code>true</code> pending objects won't be updated. 00665 This method is used by several tools (i.e. a2dDragTool) to avoid updates 00666 while the tool is working. 00667 00668 \see GetUpdatesPending() 00669 00670 \param onoff <code>true</code> to ignore pending objects, else <code>false</code> 00671 */ 00672 void SetIgnorePendingObjects( bool onoff ); 00673 00674 //!get setting of ignore pending objects /sa GetUpdatesPending() 00675 bool GetIgnorePendingObjects() { return m_ignorePendingObjects; } 00676 00677 //! get reference to the corridor list 00678 a2dCorridor& GetCorridor() { return m_corridor; } 00679 00680 //! set a corridor from a list of objects 00681 void SetCorridor( const a2dCorridor& corridor ); 00682 00683 void SetContourWidth(double width); 00684 00685 //!get the Contour width of the shape 00686 double GetContourWidth() const { return m_contourwidth; } 00687 00688 //! context like corridor and parentobject are reset 00689 void ResetContext(); 00690 00691 protected: 00692 00693 //! default handler for a2dComEvent event 00694 /*! 00695 Event id a2dCanvasView::sm_changedShowObject makes the tools corridor change to keep the tool active. 00696 In derived tools one can implement different behaviour if needed. 00697 */ 00698 void OnComEvent( a2dComEvent& event ); 00699 00700 //! when a view is removed from a document, the tool becomes invalid and will be stopped 00701 void OnRemoveView( a2dDocumentEvent& event ); 00702 00703 void OnDoEvent( a2dCommandProcessorEvent& event ); 00704 void OnUndoEvent( a2dCommandProcessorEvent& event ); 00705 void OnRedoEvent( a2dCommandProcessorEvent& event ); 00706 00707 //! called on mouse events 00708 void OnMouseEvent(wxMouseEvent& event); 00709 //! called on key events 00710 void OnChar(wxKeyEvent& event); 00711 //! called on keydown events 00712 void OnKeyDown(wxKeyEvent& event); 00713 //! called on keyup events 00714 void OnKeyUp(wxKeyEvent& event); 00715 00716 //! to do tool specific stuff to stop a tool. Called from StopTool(). 00717 virtual void DoStopTool( bool abort ); 00718 00719 //! cursor to use 00720 wxCursor m_toolcursor; 00721 00722 //! cursor to use when the tool is busy doing something. 00723 wxCursor m_toolBusyCursor; 00724 00725 //! under control of this toolcontroller, to give me events. 00726 a2dToolContr* m_controller; 00727 00728 //! tool is operational 00729 bool m_active; 00730 00731 //! if > 0, the tool is in the process of stopping, which means it can not be poped yet by controller. 00732 wxUint8 m_bussyStopping; 00733 00734 //! when set called before own event handler 00735 /*! 00736 To be able to change the behaviour in a central location for all tools, one can set this event handler. 00737 The default handler is the tool itself. 00738 */ 00739 a2dSmrtPtr<a2dEvtHandler> m_eventHandler; 00740 00741 //!if set ignore all setting for pendingobjects 00742 bool m_ignorePendingObjects; 00743 00744 //! used in tools that can do nested editing/drawing. 00745 //! the corridor is a copy of the a2dCanvasObject in the a2dDocument that form the corridor path. 00746 //! re-activating a tool, this list can be used to re-instantiate the corridor path for the tool. 00747 a2dCorridor m_corridor; 00748 00749 private: 00750 00751 //!tool is busy with something (can not interrupt/stop it) 00752 /*! This is private, because it should only be changed by Enter/Finish/AbortBusyMode 00753 */ 00754 bool m_busy; 00755 public: 00756 //! if a tool is deactivated while m_busy is true, this flag is set 00757 bool m_halted; 00758 00759 //! set when tool needs an redraw (after a a2dCanvas Repaint etc.) 00760 /*! this result in redrawing the tool ( e.g after a change ) */ 00761 bool m_pending; 00762 00763 //! do it only once 00764 bool m_oneshot; 00765 00766 //! stop the tool 00767 bool m_stop; 00768 00769 //!fill for new object 00770 a2dFill m_fill; 00771 00772 //!stroke for new object 00773 a2dStroke m_stroke; 00774 00775 //! if != 0 the polygon is contoured at distance m_contourwidth/2 00776 double m_contourwidth; 00777 00778 //!layer for a new object 00779 wxUint16 m_layer; 00780 00781 //!used to save the a2dCanvas mouse event setting. 00782 /*! when tool is destroyed the original mouse event setting is set for a2dCanvas. */ 00783 bool m_canvas_mouseevents_restore; 00784 00785 //!when true anotation will be shown, if used inside a tool 00786 bool m_anotate; 00787 00788 //! font to use for anotation 00789 wxFont m_annotateFont; 00790 00791 //! general operation mode setting for a tool. 00792 int m_mode; 00793 00794 //!the command group of the command processor 00795 a2dCommandGroup *m_commandgroup; 00796 00797 //!popup menu 00798 wxMenu *m_mousemenu; 00799 00800 //! ( if needed ) parent a2dCanvasObject relative to which the tool actions take place. 00801 a2dCanvasObjectPtr m_parentobject; 00802 00803 public: 00804 static a2dPropertyIdBool* PROPID_Oneshot; 00805 static a2dPropertyIdBool* PROPID_Stop; 00806 static a2dPropertyIdFill* PROPID_Fill; 00807 static a2dPropertyIdStroke* PROPID_Stroke; 00808 static a2dPropertyIdUint16* PROPID_Layer; 00809 00810 DECLARE_PROPERTIES() 00811 00812 public: 00813 A2D_DECLARE_EVENT_TABLE() 00814 DECLARE_CLASS( a2dBaseTool ) 00815 00816 }; 00817 00818 00819 //----------------------------------------------------------- 00820 // tool event handler 00821 //----------------------------------------------------------- 00822 00823 //! To implement behaviour on a set of tools. 00824 /*! 00825 A a2dToolEvtHandler is/can be set to a a2dBaseTool as an event handler in between the tool its own event handler. 00826 This is the easiest way to make a whole set of tools behave to a certain model. 00827 00828 \ingroup tools 00829 00830 */ 00831 class A2DCANVASDLLEXP a2dToolEvtHandler: public a2dEvtHandler 00832 { 00833 A2D_DECLARE_EVENT_TABLE() 00834 00835 public: 00836 00837 //! 00838 a2dToolEvtHandler(); 00839 00840 void OnComEvent( a2dComEvent& event ); 00841 00842 //! event recieved from tools processed here 00843 bool ProcessEvent( wxEvent& event ); 00844 00845 }; 00846 00847 #endif //__A2DCANVASTOOLS_H__ 00848