KiCad PCB EDA Suite
TOOL_DISPATCHER Class Reference

#include <tool_dispatcher.h>

Inheritance diagram for TOOL_DISPATCHER:

Classes

struct  BUTTON_STATE
 < Stores information about a mouse button state More...
 

Public Member Functions

 TOOL_DISPATCHER (TOOL_MANAGER *aToolMgr)
 
virtual ~TOOL_DISPATCHER ()
 
virtual void ResetState ()
 Bring the dispatcher to its initial state. More...
 
virtual void DispatchWxEvent (wxEvent &aEvent)
 Process wxEvents (mostly UI events), translate them to TOOL_EVENTs, and make tools handle those. More...
 
OPT< TOOL_EVENTGetToolEvent (wxKeyEvent *aKeyEvent, bool *aSpecialKeyFlag)
 Map a wxWidgets key event to a TOOL_EVENT. More...
 

Private Member Functions

bool handleMouseButton (wxEvent &aEvent, int aIndex, bool aMotion)
 Saves the state of key modifiers (Alt, Ctrl and so on). More...
 
KIGFX::VIEWgetView ()
 Instance of tool manager that cooperates with the dispatcher. More...
 

Static Private Member Functions

static int decodeModifiers (const wxKeyboardState *aState)
 Stores all the information regarding a mouse button state. More...
 

Private Attributes

VECTOR2D m_lastMousePos
 The last mouse cursor position (in world coordinates). More...
 
std::vector< BUTTON_STATE * > m_buttons
 Returns the instance of VIEW, used by the application. More...
 
TOOL_MANAGERm_toolMgr
 

Static Private Attributes

static const int MouseButtonCount = 3
 < Number of mouse buttons that is handled in events. More...
 
static const int DragTimeThreshold = 300
 The distance threshold for mouse cursor that distinguishes between a single mouse click and a beginning of drag event (expressed in screen pixels). More...
 
static const int DragDistanceThreshold = 8
 Handles mouse related events (click, motion, dragging). More...
 

Detailed Description

  • takes wx events,
  • fixes all wx quirks (mouse warping, panning, ordering problems, etc)
  • translates coordinates to world space
  • low-level input conditioning (drag/click threshold), updating mouse position during view auto-scroll/pan.
  • issues TOOL_EVENTS to the tool manager

Definition at line 51 of file tool_dispatcher.h.

Constructor & Destructor Documentation

◆ TOOL_DISPATCHER()

TOOL_DISPATCHER::TOOL_DISPATCHER ( TOOL_MANAGER aToolMgr)
Parameters
aToolMgrtool manager instance the events will be sent to.

Definition at line 126 of file tool_dispatcher.cpp.

126  :
127  m_toolMgr( aToolMgr )
128 {
129  m_buttons.push_back( new BUTTON_STATE( BUT_LEFT, wxEVT_LEFT_DOWN,
130  wxEVT_LEFT_UP, wxEVT_LEFT_DCLICK ) );
131  m_buttons.push_back( new BUTTON_STATE( BUT_RIGHT, wxEVT_RIGHT_DOWN,
132  wxEVT_RIGHT_UP, wxEVT_RIGHT_DCLICK ) );
133  m_buttons.push_back( new BUTTON_STATE( BUT_MIDDLE, wxEVT_MIDDLE_DOWN,
134  wxEVT_MIDDLE_UP, wxEVT_MIDDLE_DCLICK ) );
135 
136  ResetState();
137 }
virtual void ResetState()
Bring the dispatcher to its initial state.
std::vector< BUTTON_STATE * > m_buttons
Returns the instance of VIEW, used by the application.
TOOL_MANAGER * m_toolMgr

References BUT_LEFT, BUT_MIDDLE, BUT_RIGHT, m_buttons, and ResetState().

◆ ~TOOL_DISPATCHER()

TOOL_DISPATCHER::~TOOL_DISPATCHER ( )
virtual

Definition at line 140 of file tool_dispatcher.cpp.

141 {
142  for( BUTTON_STATE* st : m_buttons )
143  delete st;
144 }
std::vector< BUTTON_STATE * > m_buttons
Returns the instance of VIEW, used by the application.

References m_buttons.

Member Function Documentation

◆ decodeModifiers()

static int TOOL_DISPATCHER::decodeModifiers ( const wxKeyboardState *  aState)
inlinestaticprivate

Stores all the information regarding a mouse button state.

Definition at line 95 of file tool_dispatcher.h.

References MD_ALT, MD_CTRL, and MD_SHIFT.

Referenced by DispatchWxEvent(), GetToolEvent(), and handleMouseButton().

◆ DispatchWxEvent()

void TOOL_DISPATCHER::DispatchWxEvent ( wxEvent &  aEvent)
virtual

Process wxEvents (mostly UI events), translate them to TOOL_EVENTs, and make tools handle those.

Parameters
aEventis the wxWidgets event to be processed.

Definition at line 425 of file tool_dispatcher.cpp.

426 {
427  bool motion = false;
428  bool buttonEvents = false;
429  VECTOR2D pos;
430  OPT<TOOL_EVENT> evt;
431  bool keyIsEscape = false; // True if the keypress was the escape key
432  bool keyIsSpecial = false; // True if the key is a special key code
433  wxWindow* focus = wxWindow::FindFocus();
434 
435  // Required in win32 to ensure wxTimer events get scheduled in between other events
436  // Or else we may stall them out entirely and never get them during actions like rapid
437  // mouse moves.
439 
440  wxEventType type = aEvent.GetEventType();
441 
442  // Sometimes there is no window that has the focus (it happens when another PCB_BASE_FRAME
443  // is opened and is iconized on Windows).
444  // In this case, give the focus to the parent frame (GAL canvas itself does not accept the
445  // focus when iconized for some obscure reason)
446  if( focus == nullptr )
447  {
448  wxWindow* holderWindow = dynamic_cast<wxWindow*>( m_toolMgr->GetToolHolder() );
449 
450 #if defined( _WIN32 )
451  // Mouse events may trigger regardless of window status (windows feature)
452  // However we need to avoid focus fighting (especially modals)
453  if( holderWindow && KIPLATFORM::UI::IsWindowActive( holderWindow ) )
454 #else
455  if( holderWindow )
456 #endif
457  {
458  holderWindow->SetFocus();
459  }
460  }
461 
462  if( isMouseClick( type ) )
463  {
465  m_toolMgr->GetToolHolder()->GetToolCanvas()->SetFocus();
466  }
467 
468  // Mouse handling
469  // Note: wxEVT_LEFT_DOWN event must always be skipped.
470  if( type == wxEVT_MOTION || type == wxEVT_MOUSEWHEEL ||
471 #if wxCHECK_VERSION( 3, 1, 0 ) || defined( USE_OSX_MAGNIFY_EVENT )
472  type == wxEVT_MAGNIFY ||
473 #endif
474  isMouseClick( type ) ||
475  // Event issued when mouse retains position in screen coordinates,
476  // but changes in world coordinates (e.g. autopanning)
478  {
479  wxMouseEvent* me = static_cast<wxMouseEvent*>( &aEvent );
480  int mods = decodeModifiers( me );
481 
482  if( m_toolMgr->GetViewControls() )
483  {
485 
486  if( pos != m_lastMousePos )
487  {
488  motion = true;
489  m_lastMousePos = pos;
490  }
491  }
492 
493  for( unsigned int i = 0; i < m_buttons.size(); i++ )
494  buttonEvents |= handleMouseButton( aEvent, i, motion );
495 
496  if( m_toolMgr->GetViewControls() )
497  {
498  if( !buttonEvents && motion )
499  {
500  evt = TOOL_EVENT( TC_MOUSE, TA_MOUSE_MOTION, mods );
501  evt->SetMousePosition( pos );
502  }
503  }
504  }
505  else if( type == wxEVT_CHAR_HOOK || type == wxEVT_CHAR )
506  {
507  wxKeyEvent* ke = static_cast<wxKeyEvent*>( &aEvent );
508 
509  wxLogTrace( kicadTraceKeyEvent, "TOOL_DISPATCHER::DispatchWxEvent %s", dump( *ke ) );
510 
511  // Do not process wxEVT_CHAR_HOOK for a shift-modified key, as ACTION_MANAGER::RunHotKey
512  // will run the un-shifted key and that's not what we want. Wait to get the translated
513  // key from wxEVT_CHAR.
514  // See https://gitlab.com/kicad/code/kicad/-/issues/1809
515  if( type == wxEVT_CHAR_HOOK && ke->GetModifiers() == wxMOD_SHIFT )
516  {
517  aEvent.Skip();
518  return;
519  }
520 
521  keyIsEscape = ( ke->GetKeyCode() == WXK_ESCAPE );
522 
523  if( KIUI::IsInputControlFocused( focus ) )
524  {
525  bool enabled = KIUI::IsInputControlEditable( focus );
526 
527  // Never process key events for tools when a text entry has focus
528  if( enabled )
529  {
530  aEvent.Skip();
531  return;
532  }
533  // Even if not enabled, allow a copy out
534  else if( ke->GetModifiers() == wxMOD_CONTROL && ke->GetKeyCode() == 'C' )
535  {
536  aEvent.Skip();
537  return;
538  }
539  }
540 
541  evt = GetToolEvent( ke, &keyIsSpecial );
542  }
543  else if( type == wxEVT_MENU_OPEN || type == wxEVT_MENU_CLOSE || type == wxEVT_MENU_HIGHLIGHT )
544  {
545  //
546  // wxWidgets has several issues that we have to work around:
547  //
548  // 1) wxWidgets 3.0.x Windows has a bug where wxEVT_MENU_OPEN and wxEVT_MENU_HIGHLIGHT
549  // events are not captured by the ACTON_MENU menus. So we forward them here.
550  // (FWIW, this one is fixed in wxWidgets 3.1.x.)
551  //
552  // 2) wxWidgets doesn't pass the menu pointer for wxEVT_MENU_HIGHLIGHT events. So we
553  // store the menu pointer from the wxEVT_MENU_OPEN call.
554  //
555  // 3) wxWidgets has no way to tell whether a command is from a menu selection or a
556  // hotkey. So we keep track of menu highlighting so we can differentiate.
557  //
558 
559  static ACTION_MENU* currentMenu;
560 
561  wxMenuEvent& menuEvent = *dynamic_cast<wxMenuEvent*>( &aEvent );
562 
563  if( type == wxEVT_MENU_OPEN )
564  {
565  currentMenu = dynamic_cast<ACTION_MENU*>( menuEvent.GetMenu() );
566 
567  if( currentMenu )
568  currentMenu->OnMenuEvent( menuEvent );
569  }
570  else if( type == wxEVT_MENU_HIGHLIGHT )
571  {
572  if( currentMenu )
573  currentMenu->OnMenuEvent( menuEvent );
574  }
575  else if( type == wxEVT_MENU_CLOSE )
576  {
577  if( currentMenu )
578  currentMenu->OnMenuEvent( menuEvent );
579 
580  currentMenu = nullptr;
581  }
582 
583  aEvent.Skip();
584  }
585 
586  bool handled = false;
587 
588  if( evt )
589  {
590  wxLogTrace( kicadTraceToolStack, "TOOL_DISPATCHER::DispatchWxEvent %s", evt->Format() );
591 
592  handled = m_toolMgr->ProcessEvent( *evt );
593 
594  wxLogTrace( kicadTraceToolStack, "TOOL_DISPATCHER::DispatchWxEvent - Handled: %s %s",
595  ( handled ? "true" : "false" ), evt->Format() );
596  }
597 
598  // pass the event to the GUI, it might still be interested in it
599  // Note wxEVT_CHAR_HOOK event is already skipped for special keys not used by KiCad
600  // and wxEVT_LEFT_DOWN must be always Skipped.
601  //
602  // On OS X, key events are always meant to be caught. An uncaught key event is assumed
603  // to be a user input error by OS X (as they are pressing keys in a context where nothing
604  // is there to catch the event). This annoyingly makes OS X beep and/or flash the screen
605  // in Pcbnew and the footprint editor any time a hotkey is used. The correct procedure is
606  // to NOT pass wxEVT_CHAR events to the GUI under OS X.
607  //
608  // On Windows, avoid to call wxEvent::Skip for special keys because some keys
609  // (PAGE_UP, PAGE_DOWN) have predefined actions (like move thumbtrack cursor), and we do
610  // not want these actions executed (most are handled by KiCad)
611 
612  if( !evt || type == wxEVT_LEFT_DOWN )
613  aEvent.Skip();
614 
615  // Not handled wxEVT_CHAR must be Skipped (sent to GUI).
616  // Otherwise accelerators and shortcuts in main menu or toolbars are not seen.
617  // Escape key presses are never skipped by the handler since they correspond to tool cancel
618  // events, and if they aren't skipped then they are propagated to other frames (which we
619  // don't want).
620  if( (type == wxEVT_CHAR || type == wxEVT_CHAR_HOOK)
621  && !keyIsSpecial
622  && !handled
623  && !keyIsEscape )
624  aEvent.Skip();
625 
626  wxLogTrace( kicadTraceToolStack, "TOOL_DISPATCHER::DispatchWxEvent - Wx event skipped: %s",
627  ( aEvent.GetSkipped() ? "true" : "false" ) );
628 }
static int decodeModifiers(const wxKeyboardState *aState)
Stores all the information regarding a mouse button state.
virtual VECTOR2D GetMousePosition(bool aWorldCoordinates=true) const =0
Return the current mouse pointer position.
bool IsInputControlEditable(wxWindow *aControl)
Check if a input control has focus.
Definition: ui_common.cpp:250
static const wxEventType EVT_REFRESH_MOUSE
Defines the structure of a menu based on ACTIONs.
Definition: action_menu.h:48
bool IsInputControlFocused(wxWindow *aFocus=nullptr)
Check if a input control has focus.
Definition: ui_common.cpp:217
bool IsWindowActive(wxWindow *aWindow)
Check to see if the given window is the currently active window (e.g.
Definition: gtk/ui.cpp:50
wxString dump(const wxArrayString &aArray)
Debug helper for printing wxArrayString contents.
virtual wxWindow * GetToolCanvas() const =0
Canvas access.
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagate an event to tools that requested events of matching type(s).
void ForceTimerMessagesToBeCreatedIfNecessary()
Forces wxTimers to fire more promptly on Win32.
Definition: gtk/app.cpp:88
Generic, UI-independent tool event.
Definition: tool_event.h:152
VECTOR2D m_lastMousePos
The last mouse cursor position (in world coordinates).
std::vector< BUTTON_STATE * > m_buttons
Returns the instance of VIEW, used by the application.
void OnMenuEvent(wxMenuEvent &aEvent)
TOOLS_HOLDER * GetToolHolder() const
Definition: tool_manager.h:294
KIGFX::VIEW_CONTROLS * GetViewControls() const
Definition: tool_manager.h:285
OPT< TOOL_EVENT > GetToolEvent(wxKeyEvent *aKeyEvent, bool *aSpecialKeyFlag)
Map a wxWidgets key event to a TOOL_EVENT.
static bool isMouseClick(wxEventType type)
const wxChar *const kicadTraceKeyEvent
Flag to enable wxKeyEvent debug tracing.
const wxChar *const kicadTraceToolStack
Flag to enable tracing of the tool handling stack.
boost::optional< T > OPT
Definition: optional.h:7
bool handleMouseButton(wxEvent &aEvent, int aIndex, bool aMotion)
Saves the state of key modifiers (Alt, Ctrl and so on).
TOOL_MANAGER * m_toolMgr

References decodeModifiers(), dump(), KIGFX::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE, KIPLATFORM::APP::ForceTimerMessagesToBeCreatedIfNecessary(), KIGFX::VIEW_CONTROLS::GetMousePosition(), TOOLS_HOLDER::GetToolCanvas(), GetToolEvent(), TOOL_MANAGER::GetToolHolder(), TOOL_MANAGER::GetViewControls(), handleMouseButton(), KIUI::IsInputControlEditable(), KIUI::IsInputControlFocused(), isMouseClick(), KIPLATFORM::UI::IsWindowActive(), kicadTraceKeyEvent, kicadTraceToolStack, m_buttons, m_lastMousePos, m_toolMgr, ACTION_MENU::OnMenuEvent(), TOOL_MANAGER::ProcessEvent(), TA_MOUSE_MOTION, and TC_MOUSE.

Referenced by FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME(), EDA_3D_CANVAS::OnEvent(), EDA_DRAW_PANEL_GAL::OnEvent(), PANEL_PREVIEW_3D_MODEL::OnMenuEvent(), EDA_BASE_FRAME::OnMenuEvent(), CVPCB_MAINFRAME::setupEventHandlers(), KICAD_MANAGER_FRAME::setupTools(), and SYMBOL_EDIT_FRAME::SYMBOL_EDIT_FRAME().

◆ GetToolEvent()

OPT< TOOL_EVENT > TOOL_DISPATCHER::GetToolEvent ( wxKeyEvent *  aKeyEvent,
bool *  aSpecialKeyFlag 
)

Map a wxWidgets key event to a TOOL_EVENT.

Definition at line 345 of file tool_dispatcher.cpp.

346 {
347  OPT<TOOL_EVENT> evt;
348  int key = aKeyEvent->GetKeyCode();
349  int unicode_key = aKeyEvent->GetUnicodeKey();
350 
351  // This wxEVT_CHAR_HOOK event can be ignored: not useful in Kicad
352  if( isKeyModifierOnly( key ) )
353  {
354  aKeyEvent->Skip();
355  return evt;
356  }
357 
358  wxLogTrace( kicadTraceKeyEvent, "TOOL_DISPATCHER::GetToolEvent %s", dump( *aKeyEvent ) );
359 
360  // if the key event must be skipped, skip it here if the event is a wxEVT_CHAR_HOOK
361  // and do nothing.
362  *keyIsSpecial = isKeySpecialCode( key );
363 
364  if( aKeyEvent->GetEventType() == wxEVT_CHAR_HOOK )
365  key = translateSpecialCode( key );
366 
367  int mods = decodeModifiers( aKeyEvent );
368 
369  if( mods & MD_CTRL )
370  {
371  // wxWidgets maps key codes related to Ctrl+letter handled by CHAR_EVT
372  // (http://docs.wxwidgets.org/trunk/classwx_key_event.html):
373  // char events for ASCII letters in this case carry codes corresponding to the ASCII
374  // value of Ctrl-Latter, i.e. 1 for Ctrl-A, 2 for Ctrl-B and so on until 26 for Ctrl-Z.
375  // They are remapped here to be more easy to handle in code
376  // Note also on OSX wxWidgets has a different behavior and the mapping is made
377  // only for ctrl+'A' to ctlr+'Z' (unicode code return 'A' to 'Z').
378  // Others OS return WXK_CONTROL_A to WXK_CONTROL_Z, and Ctrl+'M' returns the same code as
379  // the return key, so the remapping does not use the unicode key value.
380 #ifdef __APPLE__
381  if( unicode_key >= 'A' && unicode_key <= 'Z' && key >= WXK_CONTROL_A && key <= WXK_CONTROL_Z )
382 #else
383  (void) unicode_key; //not used: avoid compil warning
384 
385  if( key >= WXK_CONTROL_A && key <= WXK_CONTROL_Z )
386 #endif
387  key += 'A' - 1;
388  }
389 
390 #ifdef __APPLE__
391  if( mods & MD_ALT )
392  {
393  // OSX maps a bunch of commonly used extended-ASCII characters onto the keyboard
394  // using the ALT key. Since we use ALT for some of our hotkeys, we need to map back
395  // to the underlying keys. The kVK_ANSI_* values come from Apple and are said to be
396  // hardware independent.
397  switch( aKeyEvent->GetRawKeyCode() )
398  {
399  case /* kVK_ANSI_1 */ 0x12: key = '1'; break;
400  case /* kVK_ANSI_2 */ 0x13: key = '2'; break;
401  case /* kVK_ANSI_3 */ 0x14: key = '3'; break;
402  case /* kVK_ANSI_4 */ 0x15: key = '4'; break;
403  case /* kVK_ANSI_6 */ 0x16: key = '6'; break;
404  case /* kVK_ANSI_5 */ 0x17: key = '5'; break;
405  case /* kVK_ANSI_Equal */ 0x18: key = '='; break;
406  case /* kVK_ANSI_9 */ 0x19: key = '9'; break;
407  case /* kVK_ANSI_7 */ 0x1A: key = '7'; break;
408  case /* kVK_ANSI_Minus */ 0x1B: key = '-'; break;
409  case /* kVK_ANSI_8 */ 0x1C: key = '8'; break;
410  case /* kVK_ANSI_0 */ 0x1D: key = '0'; break;
411  default: ;
412  }
413  }
414 #endif
415 
416  if( key == WXK_ESCAPE ) // ESC is the special key for canceling tools
418  else
419  evt = TOOL_EVENT( TC_KEYBOARD, TA_KEY_PRESSED, key | mods );
420 
421  return evt;
422 }
static int decodeModifiers(const wxKeyboardState *aState)
Stores all the information regarding a mouse button state.
int translateSpecialCode(int aKeyCode)
static bool isKeyModifierOnly(int aKeyCode)
wxString dump(const wxArrayString &aArray)
Debug helper for printing wxArrayString contents.
bool isKeySpecialCode(int aKeyCode)
Generic, UI-independent tool event.
Definition: tool_event.h:152
const wxChar *const kicadTraceKeyEvent
Flag to enable wxKeyEvent debug tracing.
boost::optional< T > OPT
Definition: optional.h:7

References decodeModifiers(), dump(), isKeyModifierOnly(), isKeySpecialCode(), kicadTraceKeyEvent, MD_ALT, MD_CTRL, TA_CANCEL_TOOL, TA_KEY_PRESSED, TC_COMMAND, TC_KEYBOARD, and translateSpecialCode().

Referenced by DispatchWxEvent().

◆ getView()

KIGFX::VIEW * TOOL_DISPATCHER::getView ( )
private

Instance of tool manager that cooperates with the dispatcher.

Definition at line 154 of file tool_dispatcher.cpp.

155 {
156  return m_toolMgr->GetView();
157 }
KIGFX::VIEW * GetView() const
Definition: tool_manager.h:283
TOOL_MANAGER * m_toolMgr

References TOOL_MANAGER::GetView(), and m_toolMgr.

Referenced by handleMouseButton().

◆ handleMouseButton()

bool TOOL_DISPATCHER::handleMouseButton ( wxEvent &  aEvent,
int  aIndex,
bool  aMotion 
)
private

Saves the state of key modifiers (Alt, Ctrl and so on).

Definition at line 160 of file tool_dispatcher.cpp.

161 {
162  BUTTON_STATE* st = m_buttons[aIndex];
163  wxEventType type = aEvent.GetEventType();
164  OPT<TOOL_EVENT> evt;
165  bool isClick = false;
166 
167 // bool up = type == st->upEvent;
168 // bool down = type == st->downEvent;
169  bool up = false, down = false;
170  bool dblClick = type == st->dblClickEvent;
171  bool state = st->GetState();
172 
173  if( !dblClick )
174  {
175  // Sometimes the dispatcher does not receive mouse button up event, so it stays
176  // in the dragging mode even if the mouse button is not held anymore
177  if( st->pressed && !state )
178  up = true;
179  // Don't apply same logic to down events as it kills touchpad tapping
180  else if( !st->pressed && type == st->downEvent )
181  down = true;
182  }
183 
184  int mods = decodeModifiers( static_cast<wxMouseEvent*>( &aEvent ) );
185  int args = st->button | mods;
186 
187  if( down ) // Handle mouse button press
188  {
189  st->downTimestamp = wxGetLocalTimeMillis();
190 
191  if( !st->pressed ) // save the drag origin on the first click only
192  st->dragOrigin = m_lastMousePos;
193 
194  st->downPosition = m_lastMousePos;
195  st->dragMaxDelta = 0;
196  st->pressed = true;
197  evt = TOOL_EVENT( TC_MOUSE, TA_MOUSE_DOWN, args );
198  }
199  else if( up ) // Handle mouse button release
200  {
201  st->pressed = false;
202 
203  if( st->dragging )
204  {
205  wxLongLong t = wxGetLocalTimeMillis();
206 
207  // Determine if it was just a single click or beginning of dragging
208  if( t - st->downTimestamp < DragTimeThreshold &&
209  st->dragMaxDelta < DragDistanceThreshold )
210  isClick = true;
211  else
212  evt = TOOL_EVENT( TC_MOUSE, TA_MOUSE_UP, args );
213  }
214  else
215  isClick = true;
216 
217  if( isClick )
218  evt = TOOL_EVENT( TC_MOUSE, TA_MOUSE_CLICK, args );
219 
220  st->dragging = false;
221  }
222  else if( dblClick )
223  {
224  evt = TOOL_EVENT( TC_MOUSE, TA_MOUSE_DBLCLICK, args );
225  }
226 
227  if( st->pressed && aMotion )
228  {
229  st->dragging = true;
230  double dragPixelDistance =
231  getView()->ToScreen( m_lastMousePos - st->dragOrigin, false ).EuclideanNorm();
232  st->dragMaxDelta = std::max( st->dragMaxDelta, dragPixelDistance );
233 
234  wxLongLong t = wxGetLocalTimeMillis();
235 
236  if( t - st->downTimestamp > DragTimeThreshold || st->dragMaxDelta > DragDistanceThreshold )
237  {
238  evt = TOOL_EVENT( TC_MOUSE, TA_MOUSE_DRAG, args );
239  evt->setMouseDragOrigin( st->dragOrigin );
240  evt->setMouseDelta( m_lastMousePos - st->dragOrigin );
241  }
242  }
243 
244  if( evt )
245  {
246  evt->SetMousePosition( isClick ? st->downPosition : m_lastMousePos );
247  m_toolMgr->ProcessEvent( *evt );
248 
249  return true;
250  }
251 
252  return false;
253 }
static int decodeModifiers(const wxKeyboardState *aState)
Stores all the information regarding a mouse button state.
static const int DragDistanceThreshold
Handles mouse related events (click, motion, dragging).
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagate an event to tools that requested events of matching type(s).
Generic, UI-independent tool event.
Definition: tool_event.h:152
VECTOR2D m_lastMousePos
The last mouse cursor position (in world coordinates).
VECTOR2D ToScreen(const VECTOR2D &aCoord, bool aAbsolute=true) const
Convert a world space point/vector to a point/vector in screen space coordinates.
Definition: view.cpp:471
std::vector< BUTTON_STATE * > m_buttons
Returns the instance of VIEW, used by the application.
boost::optional< T > OPT
Definition: optional.h:7
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition: vector2d.h:293
static const int DragTimeThreshold
The distance threshold for mouse cursor that distinguishes between a single mouse click and a beginni...
KIGFX::VIEW * getView()
Instance of tool manager that cooperates with the dispatcher.
TOOL_MANAGER * m_toolMgr

References TOOL_DISPATCHER::BUTTON_STATE::button, TOOL_DISPATCHER::BUTTON_STATE::dblClickEvent, decodeModifiers(), down, TOOL_DISPATCHER::BUTTON_STATE::downEvent, TOOL_DISPATCHER::BUTTON_STATE::downPosition, TOOL_DISPATCHER::BUTTON_STATE::downTimestamp, DragDistanceThreshold, TOOL_DISPATCHER::BUTTON_STATE::dragging, TOOL_DISPATCHER::BUTTON_STATE::dragMaxDelta, TOOL_DISPATCHER::BUTTON_STATE::dragOrigin, DragTimeThreshold, VECTOR2< T >::EuclideanNorm(), TOOL_DISPATCHER::BUTTON_STATE::GetState(), getView(), m_buttons, m_lastMousePos, m_toolMgr, TOOL_DISPATCHER::BUTTON_STATE::pressed, TOOL_MANAGER::ProcessEvent(), TA_MOUSE_CLICK, TA_MOUSE_DBLCLICK, TA_MOUSE_DOWN, TA_MOUSE_DRAG, TA_MOUSE_UP, TC_MOUSE, KIGFX::VIEW::ToScreen(), and up.

Referenced by DispatchWxEvent().

◆ ResetState()

void TOOL_DISPATCHER::ResetState ( )
virtual

Bring the dispatcher to its initial state.

Definition at line 147 of file tool_dispatcher.cpp.

148 {
149  for( BUTTON_STATE* st : m_buttons )
150  st->Reset();
151 }
std::vector< BUTTON_STATE * > m_buttons
Returns the instance of VIEW, used by the application.

References m_buttons.

Referenced by TOOL_DISPATCHER().

Member Data Documentation

◆ DragDistanceThreshold

const int TOOL_DISPATCHER::DragDistanceThreshold = 8
staticprivate

Handles mouse related events (click, motion, dragging).

Definition at line 89 of file tool_dispatcher.h.

Referenced by handleMouseButton().

◆ DragTimeThreshold

const int TOOL_DISPATCHER::DragTimeThreshold = 300
staticprivate

The distance threshold for mouse cursor that distinguishes between a single mouse click and a beginning of drag event (expressed in screen pixels).

Definition at line 85 of file tool_dispatcher.h.

Referenced by handleMouseButton().

◆ m_buttons

std::vector<BUTTON_STATE*> TOOL_DISPATCHER::m_buttons
private

Returns the instance of VIEW, used by the application.

Definition at line 118 of file tool_dispatcher.h.

Referenced by DispatchWxEvent(), handleMouseButton(), ResetState(), TOOL_DISPATCHER(), and ~TOOL_DISPATCHER().

◆ m_lastMousePos

VECTOR2D TOOL_DISPATCHER::m_lastMousePos
private

The last mouse cursor position (in world coordinates).

State of mouse buttons.

Definition at line 112 of file tool_dispatcher.h.

Referenced by DispatchWxEvent(), and handleMouseButton().

◆ m_toolMgr

TOOL_MANAGER* TOOL_DISPATCHER::m_toolMgr
private

Definition at line 124 of file tool_dispatcher.h.

Referenced by DispatchWxEvent(), getView(), and handleMouseButton().

◆ MouseButtonCount

const int TOOL_DISPATCHER::MouseButtonCount = 3
staticprivate

< Number of mouse buttons that is handled in events.

The time threshold for a mouse button press that distinguishes between a single mouse click and a beginning of drag event (expressed in milliseconds).

Definition at line 81 of file tool_dispatcher.h.


The documentation for this class was generated from the following files: