Added handling keyboard events for the Tool framework.

This commit is contained in:
Maciej Suminski 2013-08-21 17:37:27 +02:00
parent 5adba827a6
commit 89a138c09e
14 changed files with 224 additions and 145 deletions

View File

@ -1017,5 +1017,6 @@ void EDA_DRAW_FRAME::UseGalCanvas( bool aEnable )
m_auimgr.GetPane( wxT( "DrawFrameGal" ) ).Show( aEnable );
m_auimgr.Update();
m_galCanvas->SetFocus();
m_galCanvasActive = aEnable;
}

View File

@ -1334,7 +1334,6 @@ void EDA_DRAW_PANEL::OnKeyEvent( wxKeyEvent& event )
Screen->SetMousePosition( pos );
GetParent()->GeneralControl( &DC, pos, localkey );
}

View File

@ -96,6 +96,7 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
Connect( wxEVT_MIDDLE_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_MIDDLE_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_MOUSEWHEEL, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_CHAR_HOOK, wxEventHandler( EDA_DRAW_PANEL_GAL::skipEvent ), NULL, this );
Connect( wxEVT_KEY_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_KEY_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
}
@ -209,3 +210,10 @@ void EDA_DRAW_PANEL_GAL::onEvent( wxEvent& aEvent )
m_eventDispatcher->DispatchWxEvent( aEvent );
}
}
void EDA_DRAW_PANEL_GAL::skipEvent( wxEvent& aEvent )
{
// This is necessary for CHAR_HOOK event to generate KEY_UP and KEY_DOWN events
aEvent.Skip();
}

View File

@ -56,13 +56,12 @@ CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
// Mouse events are skipped to the parent
Connect( wxEVT_MOTION, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_LEFT_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
#if defined _WIN32 || defined _WIN64
Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
#endif

View File

@ -70,13 +70,12 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
// Mouse events are skipped to the parent
Connect( wxEVT_MOTION, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_LEFT_UP, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_MIDDLE_UP, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
#if defined _WIN32 || defined _WIN64
Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
#endif

View File

@ -103,17 +103,16 @@ KiGfx::VIEW* TOOL_DISPATCHER::getView()
}
int TOOL_DISPATCHER::decodeModifiers( wxEvent& aEvent )
int TOOL_DISPATCHER::decodeModifiers( const wxKeyboardState* aState ) const
{
wxMouseEvent* me = static_cast<wxMouseEvent*>( &aEvent );
int mods = 0;
if( me->ControlDown() )
mods |= MB_ModCtrl;
if( me->AltDown() )
mods |= MB_ModAlt;
if( me->ShiftDown() )
mods |= MB_ModShift;
if( aState->ControlDown() )
mods |= MD_ModCtrl;
if( aState->AltDown() )
mods |= MD_ModAlt;
if( aState->ShiftDown() )
mods |= MD_ModShift;
return mods;
}
@ -128,7 +127,7 @@ bool TOOL_DISPATCHER::handleMouseButton ( wxEvent& aEvent, int aIndex, bool aMot
bool up = type == st->upEvent;
bool down = type == st->downEvent;
int mods = decodeModifiers( aEvent );
int mods = decodeModifiers( static_cast<wxMouseEvent*>( &aEvent ) );
int args = st->button | mods;
if( down )
@ -148,7 +147,8 @@ bool TOOL_DISPATCHER::handleMouseButton ( wxEvent& aEvent, int aIndex, bool aMot
{
wxLongLong t = wxGetLocalTimeMillis();
if( t - st->downTimestamp < DragTimeThreshold && st->dragMaxDelta < DragDistanceThreshold )
if( t - st->downTimestamp < DragTimeThreshold &&
st->dragMaxDelta < DragDistanceThreshold )
isClick = true;
else
evt = TOOL_EVENT( TC_Mouse, TA_MouseUp, args );
@ -205,7 +205,11 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent &aEvent )
int type = aEvent.GetEventType();
if( type == wxEVT_MOTION )
// Mouse handling
if( type == wxEVT_MOTION || type == wxEVT_MOUSEWHEEL ||
type == wxEVT_LEFT_DOWN || type == wxEVT_LEFT_UP ||
type == wxEVT_MIDDLE_DOWN || type == wxEVT_MIDDLE_UP ||
type == wxEVT_RIGHT_DOWN || type == wxEVT_RIGHT_UP )
{
wxMouseEvent* me = static_cast<wxMouseEvent*>( &aEvent );
pos = getView()->ToWorld( VECTOR2D( me->GetX(), me->GetY() ) );
@ -214,7 +218,6 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent &aEvent )
motion = true;
m_lastMousePos = pos;
}
}
for( unsigned int i = 0; i < m_buttons.size(); i++ )
buttonEvents |= handleMouseButton( aEvent, i, motion );
@ -224,6 +227,20 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent &aEvent )
evt = TOOL_EVENT( TC_Mouse, TA_MouseMotion );
evt->SetMousePosition( pos );
}
}
// Keyboard handling
else if( type == wxEVT_KEY_UP || type == wxEVT_KEY_DOWN )
{
wxKeyEvent* ke = static_cast<wxKeyEvent*>( &aEvent );
int key = ke->GetKeyCode();
int mods = decodeModifiers( ke );
if( type == wxEVT_KEY_UP )
evt = TOOL_EVENT( TC_Keyboard, TA_KeyUp, key | mods );
else
evt = TOOL_EVENT( TC_Keyboard, TA_KeyDown, key | mods );
}
if( evt )
m_toolMgr->ProcessEvent( *evt );

View File

@ -44,9 +44,13 @@ struct FlagString
static const std::string flag2string( int flag, const FlagString* exps )
{
std::string rv;
for( int i = 0; exps[i].str.length(); i++ )
{
if( exps[i].flag & flag )
rv += exps[i].str + " ";
}
return rv;
}
@ -57,6 +61,7 @@ const std::string TOOL_EVENT::Format() const
const FlagString categories[] = {
{ TC_Mouse, "mouse" },
{ TC_Keyboard, "keyboard" },
{ TC_Command, "command" },
{ TC_Message, "message" },
{ TC_View, "view" },
@ -70,6 +75,8 @@ const std::string TOOL_EVENT::Format() const
{ TA_MouseDrag, "drag" },
{ TA_MouseMotion, "motion" },
{ TA_MouseWheel, "wheel" },
{ TA_KeyUp, "key-up" },
{ TA_KeyDown, "key-down" },
{ TA_ViewRefresh, "view-refresh" },
{ TA_ViewZoom, "view-zoom" },
{ TA_ViewPan, "view-pan" },
@ -87,9 +94,13 @@ const std::string TOOL_EVENT::Format() const
{ MB_Left, "left" },
{ MB_Right, "right" },
{ MB_Middle, "middle" },
{ MB_ModShift, "shift" },
{ MB_ModCtrl, "ctrl" },
{ MB_ModAlt, "alt" },
{ 0, "" }
};
const FlagString modifiers[] = {
{ MD_ModShift, "shift" },
{ MD_ModCtrl, "ctrl" },
{ MD_ModAlt, "alt" },
{ 0, "" }
};
@ -102,7 +113,20 @@ const std::string TOOL_EVENT::Format() const
{
ev += " btns: ";
ev += flag2string( m_mouseButtons, buttons );
};
}
if( m_actions & TA_Keyboard )
{
char tmp[128];
sprintf( tmp, "key: %d", m_keyCode );
ev += tmp;
}
if( m_actions & ( TA_Mouse | TA_Keyboard ) )
{
ev += " mods: ";
ev += flag2string( m_modifiers, modifiers );
}
if( m_commandId )
{

View File

@ -53,11 +53,11 @@ WX_VIEW_CONTROLS::WX_VIEW_CONTROLS( VIEW* aView, wxWindow* aParentPanel ) :
}
void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& event )
void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent )
{
if( event.Dragging() && m_isDragPanning )
if( aEvent.Dragging() && m_isDragPanning )
{
VECTOR2D mousePoint( event.GetX(), event.GetY() );
VECTOR2D mousePoint( aEvent.GetX(), aEvent.GetY() );
VECTOR2D d = m_dragStartPoint - mousePoint;
VECTOR2D delta = m_view->ToWorld( d, false );
@ -65,19 +65,19 @@ void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& event )
m_parentPanel->Refresh();
}
event.Skip();
aEvent.Skip();
}
void WX_VIEW_CONTROLS::onWheel( wxMouseEvent& event )
void WX_VIEW_CONTROLS::onWheel( wxMouseEvent& aEvent )
{
const double wheelPanSpeed = 0.001;
if( event.ControlDown() || event.ShiftDown() )
if( aEvent.ControlDown() || aEvent.ShiftDown() )
{
// Scrolling
VECTOR2D scrollVec = m_view->ToWorld( m_view->GetScreenPixelSize() *
( (double) event.GetWheelRotation() * wheelPanSpeed ), false );
( (double) aEvent.GetWheelRotation() * wheelPanSpeed ), false );
double scrollSpeed;
if( abs( scrollVec.x ) > abs( scrollVec.y ) )
@ -85,8 +85,8 @@ void WX_VIEW_CONTROLS::onWheel( wxMouseEvent& event )
else
scrollSpeed = scrollVec.y;
VECTOR2D delta( event.ControlDown() ? -scrollSpeed : 0.0,
event.ShiftDown() ? -scrollSpeed : 0.0 );
VECTOR2D delta( aEvent.ControlDown() ? -scrollSpeed : 0.0,
aEvent.ShiftDown() ? -scrollSpeed : 0.0 );
m_view->SetCenter( m_view->GetCenter() + delta );
m_parentPanel->Refresh();
@ -103,41 +103,41 @@ void WX_VIEW_CONTROLS::onWheel( wxMouseEvent& event )
// Set scaling speed depending on scroll wheel event interval
if( timeDiff < 500 && timeDiff > 0 )
{
zoomScale = ( event.GetWheelRotation() > 0.0 ) ? 2.05 - timeDiff / 500 :
zoomScale = ( aEvent.GetWheelRotation() > 0.0 ) ? 2.05 - timeDiff / 500 :
1.0 / ( 2.05 - timeDiff / 500 );
}
else
{
zoomScale = ( event.GetWheelRotation() > 0.0 ) ? 1.05 : 0.95;
zoomScale = ( aEvent.GetWheelRotation() > 0.0 ) ? 1.05 : 0.95;
}
VECTOR2D anchor = m_view->ToWorld( VECTOR2D( event.GetX(), event.GetY() ) );
VECTOR2D anchor = m_view->ToWorld( VECTOR2D( aEvent.GetX(), aEvent.GetY() ) );
m_view->SetScale( m_view->GetScale() * zoomScale, anchor );
m_parentPanel->Refresh();
}
event.Skip();
aEvent.Skip();
}
void WX_VIEW_CONTROLS::onButton( wxMouseEvent& event )
void WX_VIEW_CONTROLS::onButton( wxMouseEvent& aEvent )
{
if( event.MiddleDown() )
if( aEvent.MiddleDown() )
{
m_isDragPanning = true;
m_dragStartPoint = VECTOR2D( event.GetX(), event.GetY() );
m_dragStartPoint = VECTOR2D( aEvent.GetX(), aEvent.GetY() );
m_lookStartPoint = m_view->GetCenter();
}
else if( event.MiddleUp() )
else if( aEvent.MiddleUp() )
{
m_isDragPanning = false;
}
event.Skip();
aEvent.Skip();
}
void WX_VIEW_CONTROLS::onEnter( wxMouseEvent& event )
void WX_VIEW_CONTROLS::onEnter( wxMouseEvent& aEvent )
{
m_parentPanel->SetFocus();
}

View File

@ -115,6 +115,7 @@ protected:
void onPaint( wxPaintEvent& WXUNUSED( aEvent ) );
void onSize( wxSizeEvent& aEvent );
void onEvent( wxEvent& aEvent );
void skipEvent( wxEvent& aEvent );
KiGfx::GAL* m_gal; ///< Interface for drawing objects on a 2D-surface
KiGfx::VIEW* m_view; ///< Stores view settings (scale, center, etc.)

View File

@ -30,6 +30,7 @@
#include <tool/tool_event.h>
#include <wx/event.h>
#include <wx/kbdstate.h>
class TOOL_MANAGER;
class PCB_BASE_FRAME;
@ -70,20 +71,17 @@ private:
static const int DragDistanceThreshold = 8;
bool handleMouseButton( wxEvent& aEvent, int aIndex, bool aMotion );
bool handleKeys ( wxEvent& aEvent );
bool handlePopupMenu( wxEvent& aEvent );
int decodeModifiers( wxEvent& aEvent );
KiGfx::VIEW* getView();
int decodeModifiers( const wxKeyboardState* aState ) const;
struct ButtonState;
TOOL_MANAGER* m_toolMgr;
PCB_BASE_FRAME* m_editFrame;
VECTOR2D m_lastMousePos;
std::vector<ButtonState*> m_buttons;
KiGfx::VIEW* getView();
TOOL_MANAGER* m_toolMgr;
PCB_BASE_FRAME* m_editFrame;
};
#endif

View File

@ -40,28 +40,35 @@ class TOOL_MANAGER;
*/
enum TOOL_EventCategory
{
TC_None = 0x0,
TC_Mouse = 0x1,
TC_Command = 0x2,
TC_Message = 0x4,
TC_View = 0x8,
TC_None = 0x00,
TC_Mouse = 0x01,
TC_Keyboard = 0x02,
TC_Command = 0x04,
TC_Message = 0x08,
TC_View = 0x10,
TC_Any = 0xffffffff
};
enum TOOL_Actions
{
TA_None = 0x0,
TA_MouseClick = 0x1,
TA_MouseUp = 0x2,
TA_MouseDown = 0x4,
TA_MouseDrag = 0x8,
TA_MouseMotion = 0x10,
TA_MouseWheel = 0x20,
TA_Mouse = 0x3f,
TA_ViewRefresh = 0x40,
TA_ViewZoom = 0x80,
TA_ViewPan = 0x100,
TA_ViewDirty = 0x200,
// UI input events
TA_None = 0x0000,
TA_MouseClick = 0x0001,
TA_MouseUp = 0x0002,
TA_MouseDown = 0x0004,
TA_MouseDrag = 0x0008,
TA_MouseMotion = 0x0010,
TA_MouseWheel = 0x0020,
TA_Mouse = 0x003f,
TA_KeyUp = 0x0040,
TA_KeyDown = 0x0080,
TA_Keyboard = TA_KeyUp | TA_KeyDown,
// View related events
TA_ViewRefresh = 0x0100,
TA_ViewZoom = 0x0200,
TA_ViewPan = 0x0400,
TA_ViewDirty = 0x0800,
TA_ChangeLayer = 0x1000,
// Tool cancel event. Issued automagically when the user hits escape or selects End Tool from the context menu.
@ -86,13 +93,16 @@ enum TOOL_MouseButtons
MB_Right = 0x2,
MB_Middle = 0x4,
MB_ButtonMask = MB_Left | MB_Right | MB_Middle,
MB_ModShift = 0x8,
MB_ModCtrl = 0x10,
MB_ModAlt = 0x20,
MB_ModifierMask = MB_ModShift | MB_ModCtrl | MB_ModAlt,
MB_Any = 0xffffffff
};
enum TOOL_Modifiers
{
MD_ModShift = 0x1000,
MD_ModCtrl = 0x2000,
MD_ModAlt = 0x4000,
MD_ModifierMask = MD_ModShift | MD_ModCtrl | MD_ModAlt,
};
// Defines when a context menu is opened.
enum TOOL_ContextMenuTrigger
@ -115,19 +125,35 @@ public:
TOOL_EVENT( TOOL_EventCategory aCategory = TC_None, TOOL_Actions aAction = TA_None ) :
m_category( aCategory ),
m_actions( aAction ),
m_mouseButtons( 0 ) {}
m_mouseButtons( 0 ),
m_keyCode( 0 ),
m_modifiers( 0 ) {}
TOOL_EVENT( TOOL_EventCategory aCategory, TOOL_Actions aAction, int aExtraParam ) :
m_category( aCategory ),
m_actions( aAction )
{
if( aCategory == TC_Mouse )
m_mouseButtons = aExtraParam;
{
m_mouseButtons = aExtraParam & MB_ButtonMask;
}
else if( aCategory == TC_Keyboard )
{
m_keyCode = aExtraParam & ~MD_ModifierMask; // Filter out modifiers
}
else if ( aCategory == TC_Command )
{
m_commandId = aExtraParam;
}
TOOL_EVENT( TOOL_EventCategory aCategory, TOOL_Actions aAction, const std::string& aExtraParam ):
if( aCategory & ( TC_Mouse | TC_Keyboard ) )
{
m_modifiers = aExtraParam & MD_ModifierMask;
}
}
TOOL_EVENT( TOOL_EventCategory aCategory, TOOL_Actions aAction,
const std::string& aExtraParam ) :
m_category( aCategory ),
m_actions( aAction ),
m_mouseButtons( 0 )
@ -193,9 +219,14 @@ public:
return m_actions == TA_CancelTool;
}
bool Modifier( int aMask = MB_ModifierMask ) const
bool Modifier( int aMask = MD_ModifierMask ) const
{
return ( m_mouseButtons & aMask );
return ( m_modifiers & aMask );
}
int KeyCode() const
{
return m_keyCode;
}
void Ignore();
@ -250,6 +281,8 @@ private:
VECTOR2D m_mouseDragOrigin;
int m_mouseButtons;
int m_keyCode;
int m_modifiers;
boost::optional<int> m_commandId;
boost::optional<std::string> m_commandStr;
};

View File

@ -52,10 +52,10 @@ public:
WX_VIEW_CONTROLS( VIEW* aView, wxWindow* aParentPanel );
~WX_VIEW_CONTROLS() {};
void onWheel( wxMouseEvent& event );
void onMotion( wxMouseEvent& event );
void onButton( wxMouseEvent& event );
void onEnter( wxMouseEvent& event );
void onWheel( wxMouseEvent& aEvent );
void onMotion( wxMouseEvent& aEvent );
void onButton( wxMouseEvent& aEvent );
void onEnter( wxMouseEvent& aEvent );
void SetEventDispatcher( TOOL_DISPATCHER *aEventDispatcher );

View File

@ -69,7 +69,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent )
// Main loop: keep receiving events
while( OPT_TOOL_EVENT evt = Wait() )
{
m_additive = evt->Modifier( MB_ModShift );
m_additive = evt->Modifier( MD_ModShift );
if( evt->IsCancel() )
return 0;