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

int m_sysDragMinX
 Maximum distance before drag is activated in the Y axis. More...
 
int m_sysDragMinY
 Handles mouse related events (click, motion, dragging). More...
 
VECTOR2D m_lastMousePos
 The last mouse cursor position (in world coordinates). More...
 
VECTOR2D m_lastMousePosScreen
 State of mouse buttons. 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
 Mininum distance before drag is activated in the X axis. 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_sysDragMinX = wxSystemSettings::GetMetric( wxSYS_DRAG_X );
130  m_sysDragMinY = wxSystemSettings::GetMetric( wxSYS_DRAG_Y );
131 
134 
135  m_buttons.push_back( new BUTTON_STATE( BUT_LEFT, wxEVT_LEFT_DOWN,
136  wxEVT_LEFT_UP, wxEVT_LEFT_DCLICK ) );
137  m_buttons.push_back( new BUTTON_STATE( BUT_RIGHT, wxEVT_RIGHT_DOWN,
138  wxEVT_RIGHT_UP, wxEVT_RIGHT_DCLICK ) );
139  m_buttons.push_back( new BUTTON_STATE( BUT_MIDDLE, wxEVT_MIDDLE_DOWN,
140  wxEVT_MIDDLE_UP, wxEVT_MIDDLE_DCLICK ) );
141 
142  ResetState();
143 }
static const int DragDistanceThreshold
Mininum distance before drag is activated in the X axis.
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.
int m_sysDragMinX
Maximum distance before drag is activated in the Y axis.
int m_sysDragMinY
Handles mouse related events (click, motion, dragging).
TOOL_MANAGER * m_toolMgr

References BUT_LEFT, BUT_MIDDLE, BUT_RIGHT, DragDistanceThreshold, m_buttons, m_sysDragMinX, m_sysDragMinY, and ResetState().

◆ ~TOOL_DISPATCHER()

TOOL_DISPATCHER::~TOOL_DISPATCHER ( )
virtual

Definition at line 146 of file tool_dispatcher.cpp.

147 {
148  for( BUTTON_STATE* st : m_buttons )
149  delete st;
150 }
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 101 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 430 of file tool_dispatcher.cpp.

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

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

References decodeModifiers(), dump(), ignore_unused(), 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 160 of file tool_dispatcher.cpp.

161 {
162  return m_toolMgr->GetView();
163 }
KIGFX::VIEW * GetView() const
Definition: tool_manager.h:283
TOOL_MANAGER * m_toolMgr

References TOOL_MANAGER::GetView(), and m_toolMgr.

◆ 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 166 of file tool_dispatcher.cpp.

167 {
168  BUTTON_STATE* st = m_buttons[aIndex];
169  wxEventType type = aEvent.GetEventType();
170  OPT<TOOL_EVENT> evt;
171  bool isClick = false;
172 
173 // bool up = type == st->upEvent;
174 // bool down = type == st->downEvent;
175  bool up = false, down = false;
176  bool dblClick = type == st->dblClickEvent;
177  bool state = st->GetState();
178 
179  if( !dblClick )
180  {
181  // Sometimes the dispatcher does not receive mouse button up event, so it stays
182  // in the dragging mode even if the mouse button is not held anymore
183  if( st->pressed && !state )
184  up = true;
185  // Don't apply same logic to down events as it kills touchpad tapping
186  else if( !st->pressed && type == st->downEvent )
187  down = true;
188  }
189 
190  int mods = decodeModifiers( static_cast<wxMouseEvent*>( &aEvent ) );
191  int args = st->button | mods;
192 
193  if( down ) // Handle mouse button press
194  {
195  st->downTimestamp = wxGetLocalTimeMillis();
196 
197  if( !st->pressed ) // save the drag origin on the first click only
198  {
199  st->dragOrigin = m_lastMousePos;
200  st->dragOriginScreen = m_lastMousePosScreen;
201  }
202 
203  st->downPosition = m_lastMousePos;
204  st->pressed = true;
205  evt = TOOL_EVENT( TC_MOUSE, TA_MOUSE_DOWN, args );
206  }
207  else if( up ) // Handle mouse button release
208  {
209  st->pressed = false;
210 
211  if( st->dragging )
212  evt = TOOL_EVENT( TC_MOUSE, TA_MOUSE_UP, args );
213  else
214  isClick = true;
215 
216  if( isClick )
217  evt = TOOL_EVENT( TC_MOUSE, TA_MOUSE_CLICK, args );
218 
219  st->dragging = false;
220  }
221  else if( dblClick )
222  {
223  evt = TOOL_EVENT( TC_MOUSE, TA_MOUSE_DBLCLICK, args );
224  }
225 
226  if( st->pressed && aMotion )
227  {
228  if( !st->dragging )
229  {
230 #ifdef __WXMAC__
231  if( wxGetLocalTimeMillis() - st->downTimestamp > DragTimeThreshold )
232  st->dragging = true;
233 #endif
234  VECTOR2D offset = m_lastMousePosScreen - st->dragOriginScreen;
235 
236  if( abs( offset.x ) > m_sysDragMinX || abs( offset.y ) > m_sysDragMinY )
237  st->dragging = true;
238 
239  }
240 
241  if( st->dragging )
242  {
243  evt = TOOL_EVENT( TC_MOUSE, TA_MOUSE_DRAG, args );
244  evt->setMouseDragOrigin( st->dragOrigin );
245  evt->setMouseDelta( m_lastMousePos - st->dragOrigin );
246  }
247  }
248 
249  if( evt )
250  {
251  evt->SetMousePosition( isClick ? st->downPosition : m_lastMousePos );
252  m_toolMgr->ProcessEvent( *evt );
253 
254  return true;
255  }
256 
257  return false;
258 }
static int decodeModifiers(const wxKeyboardState *aState)
Stores all the information regarding a mouse button state.
VECTOR2D m_lastMousePosScreen
State of mouse buttons.
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).
std::vector< BUTTON_STATE * > m_buttons
Returns the instance of VIEW, used by the application.
int m_sysDragMinX
Maximum distance before drag is activated in the Y axis.
boost::optional< T > OPT
Definition: optional.h:7
static const int DragTimeThreshold
The distance threshold for mouse cursor that distinguishes between a single mouse click and a beginni...
int m_sysDragMinY
Handles mouse related events (click, motion, dragging).
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, TOOL_DISPATCHER::BUTTON_STATE::dragging, TOOL_DISPATCHER::BUTTON_STATE::dragOrigin, TOOL_DISPATCHER::BUTTON_STATE::dragOriginScreen, DragTimeThreshold, TOOL_DISPATCHER::BUTTON_STATE::GetState(), m_buttons, m_lastMousePos, m_lastMousePosScreen, m_sysDragMinX, m_sysDragMinY, 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, up, VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by DispatchWxEvent().

◆ ResetState()

void TOOL_DISPATCHER::ResetState ( )
virtual

Bring the dispatcher to its initial state.

Definition at line 153 of file tool_dispatcher.cpp.

154 {
155  for( BUTTON_STATE* st : m_buttons )
156  st->Reset();
157 }
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

Mininum distance before drag is activated in the X axis.

Definition at line 90 of file tool_dispatcher.h.

Referenced by TOOL_DISPATCHER().

◆ 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).

System drag preferences take precedence if available

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 127 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).

The last mouse cursor position (in screen coordinates).

Definition at line 118 of file tool_dispatcher.h.

Referenced by DispatchWxEvent(), and handleMouseButton().

◆ m_lastMousePosScreen

VECTOR2D TOOL_DISPATCHER::m_lastMousePosScreen
private

State of mouse buttons.

Definition at line 124 of file tool_dispatcher.h.

Referenced by DispatchWxEvent(), and handleMouseButton().

◆ m_sysDragMinX

int TOOL_DISPATCHER::m_sysDragMinX
private

Maximum distance before drag is activated in the Y axis.

Definition at line 93 of file tool_dispatcher.h.

Referenced by handleMouseButton(), and TOOL_DISPATCHER().

◆ m_sysDragMinY

int TOOL_DISPATCHER::m_sysDragMinY
private

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

Definition at line 95 of file tool_dispatcher.h.

Referenced by handleMouseButton(), and TOOL_DISPATCHER().

◆ m_toolMgr

TOOL_MANAGER* TOOL_DISPATCHER::m_toolMgr
private

Definition at line 133 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: