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...
 
std::optional< 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 DragTimeThreshold = 300
 < The time threshold for a mouse button press that distinguishes between a single mouse click and a beginning of drag event (expressed in milliseconds). 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 127 of file tool_dispatcher.cpp.

127 :
128 m_toolMgr( aToolMgr )
129{
130 m_sysDragMinX = wxSystemSettings::GetMetric( wxSYS_DRAG_X );
131 m_sysDragMinY = wxSystemSettings::GetMetric( wxSYS_DRAG_Y );
132
135
136 m_buttons.push_back( new BUTTON_STATE( BUT_LEFT, wxEVT_LEFT_DOWN,
137 wxEVT_LEFT_UP, wxEVT_LEFT_DCLICK ) );
138 m_buttons.push_back( new BUTTON_STATE( BUT_RIGHT, wxEVT_RIGHT_DOWN,
139 wxEVT_RIGHT_UP, wxEVT_RIGHT_DCLICK ) );
140 m_buttons.push_back( new BUTTON_STATE( BUT_MIDDLE, wxEVT_MIDDLE_DOWN,
141 wxEVT_MIDDLE_UP, wxEVT_MIDDLE_DCLICK ) );
142 m_buttons.push_back( new BUTTON_STATE( BUT_AUX1, wxEVT_AUX1_DOWN,
143 wxEVT_AUX1_UP, wxEVT_AUX1_DCLICK ) );
144 m_buttons.push_back( new BUTTON_STATE( BUT_AUX2, wxEVT_AUX2_DOWN,
145 wxEVT_AUX2_UP, wxEVT_AUX2_DCLICK ) );
146
147 ResetState();
148}
static const int DragDistanceThreshold
Mininum distance before drag is activated in the X axis.
virtual void ResetState()
Bring the dispatcher to its initial state.
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
std::vector< BUTTON_STATE * > m_buttons
Returns the instance of VIEW, used by the application.
@ BUT_AUX1
Definition: tool_event.h:130
@ BUT_MIDDLE
Definition: tool_event.h:129
@ BUT_LEFT
Definition: tool_event.h:127
@ BUT_RIGHT
Definition: tool_event.h:128
@ BUT_AUX2
Definition: tool_event.h:131

References BUT_AUX1, BUT_AUX2, 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 151 of file tool_dispatcher.cpp.

152{
153 for( BUTTON_STATE* st : m_buttons )
154 delete st;
155}

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 98 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 420 of file tool_dispatcher.cpp.

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

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()

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

Map a wxWidgets key event to a TOOL_EVENT.

Definition at line 340 of file tool_dispatcher.cpp.

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

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

166{
167 return m_toolMgr->GetView();
168}
KIGFX::VIEW * GetView() const
Definition: tool_manager.h:285

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

172{
173 BUTTON_STATE* st = m_buttons[aIndex];
174 wxEventType type = aEvent.GetEventType();
175 std::optional<TOOL_EVENT> evt;
176 bool isClick = false;
177
178// bool up = type == st->upEvent;
179// bool down = type == st->downEvent;
180 bool up = false, down = false;
181 bool dblClick = type == st->dblClickEvent;
182 bool state = st->GetState();
183
184 if( !dblClick )
185 {
186 // Sometimes the dispatcher does not receive mouse button up event, so it stays
187 // in the dragging mode even if the mouse button is not held anymore
188 if( st->pressed && !state )
189 up = true;
190 // Don't apply same logic to down events as it kills touchpad tapping
191 else if( !st->pressed && type == st->downEvent )
192 down = true;
193 }
194
195 int mods = decodeModifiers( static_cast<wxMouseEvent*>( &aEvent ) );
196 int args = st->button | mods;
197
198 if( down ) // Handle mouse button press
199 {
200 st->downTimestamp = wxGetLocalTimeMillis();
201
202 if( !st->pressed ) // save the drag origin on the first click only
203 {
204 st->dragOrigin = m_lastMousePos;
205 st->dragOriginScreen = m_lastMousePosScreen;
206 }
207
208 st->downPosition = m_lastMousePos;
209 st->pressed = true;
210 evt = TOOL_EVENT( TC_MOUSE, TA_MOUSE_DOWN, args );
211 }
212 else if( up ) // Handle mouse button release
213 {
214 st->pressed = false;
215
216 if( st->dragging )
217 evt = TOOL_EVENT( TC_MOUSE, TA_MOUSE_UP, args );
218 else
219 isClick = true;
220
221 if( isClick )
222 evt = TOOL_EVENT( TC_MOUSE, TA_MOUSE_CLICK, args );
223
224 st->dragging = false;
225 }
226 else if( dblClick )
227 {
228 evt = TOOL_EVENT( TC_MOUSE, TA_MOUSE_DBLCLICK, args );
229 }
230
231 if( st->pressed && aMotion )
232 {
233 if( !st->dragging )
234 {
235#ifdef __WXMAC__
236 if( wxGetLocalTimeMillis() - st->downTimestamp > DragTimeThreshold )
237 st->dragging = true;
238#endif
239 VECTOR2D offset = m_lastMousePosScreen - st->dragOriginScreen;
240
241 if( abs( offset.x ) > m_sysDragMinX || abs( offset.y ) > m_sysDragMinY )
242 st->dragging = true;
243
244 }
245
246 if( st->dragging )
247 {
248 evt = TOOL_EVENT( TC_MOUSE, TA_MOUSE_DRAG, args );
249 evt->setMouseDragOrigin( st->dragOrigin );
250 evt->setMouseDelta( m_lastMousePos - st->dragOrigin );
251 }
252 }
253
254 if( evt )
255 {
256 evt->SetMousePosition( isClick ? st->downPosition : m_lastMousePos );
257 m_toolMgr->ProcessEvent( *evt );
258
259 return true;
260 }
261
262 return false;
263}
static const int DragTimeThreshold
< The time threshold for a mouse button press that distinguishes between a single mouse click and a b...
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:401
@ TA_MOUSE_CLICK
Definition: tool_event.h:62
@ TA_MOUSE_UP
Definition: tool_event.h:64
@ TA_MOUSE_DRAG
Definition: tool_event.h:66
@ TA_MOUSE_DOWN
Definition: tool_event.h:65
@ TA_MOUSE_DBLCLICK
Definition: tool_event.h:63

References std::abs(), 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 158 of file tool_dispatcher.cpp.

159{
160 for( BUTTON_STATE* st : m_buttons )
161 st->Reset();
162}

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 87 of file tool_dispatcher.h.

Referenced by TOOL_DISPATCHER().

◆ DragTimeThreshold

const int TOOL_DISPATCHER::DragTimeThreshold = 300
staticprivate

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

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 82 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 124 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 121 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 90 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 92 of file tool_dispatcher.h.

Referenced by handleMouseButton(), and TOOL_DISPATCHER().

◆ m_toolMgr

TOOL_MANAGER* TOOL_DISPATCHER::m_toolMgr
private

Definition at line 130 of file tool_dispatcher.h.

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


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