|
|
|
@ -1,3 +1,27 @@ |
|
|
|
/*
|
|
|
|
* This program source code file is part of KiCad, a free EDA CAD application. |
|
|
|
* |
|
|
|
* Copyright (C) 2013 CERN |
|
|
|
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch> |
|
|
|
* |
|
|
|
* This program is free software; you can redistribute it and/or |
|
|
|
* modify it under the terms of the GNU General Public License |
|
|
|
* as published by the Free Software Foundation; either version 2 |
|
|
|
* of the License, or (at your option) any later version. |
|
|
|
* |
|
|
|
* This program is distributed in the hope that it will be useful, |
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
|
|
* GNU General Public License for more details. |
|
|
|
* |
|
|
|
* You should have received a copy of the GNU General Public License |
|
|
|
* along with this program; if not, you may find one here: |
|
|
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
|
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
|
|
|
* or you may write to the Free Software Foundation, Inc., |
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|
|
|
*/ |
|
|
|
|
|
|
|
#include <wx/wx.h>
|
|
|
|
#include <wx/event.h>
|
|
|
|
|
|
|
|
@ -19,12 +43,12 @@ using boost::optional; |
|
|
|
|
|
|
|
struct TOOL_DISPATCHER::ButtonState |
|
|
|
{ |
|
|
|
|
|
|
|
ButtonState (TOOL_MouseButtons aButton, const wxEventType& aDownEvent, const wxEventType & aUpEvent, bool aTriggerMenu = false) : |
|
|
|
button(aButton), |
|
|
|
downEvent(aDownEvent), |
|
|
|
upEvent(aUpEvent), |
|
|
|
triggerContextMenu(aTriggerMenu) |
|
|
|
ButtonState( TOOL_MouseButtons aButton, const wxEventType& aDownEvent, |
|
|
|
const wxEventType & aUpEvent, bool aTriggerMenu = false) : |
|
|
|
button( aButton ), |
|
|
|
downEvent( aDownEvent ), |
|
|
|
upEvent( aUpEvent ), |
|
|
|
triggerContextMenu( aTriggerMenu ) |
|
|
|
{}; |
|
|
|
|
|
|
|
bool dragging; |
|
|
|
@ -47,119 +71,123 @@ struct TOOL_DISPATCHER::ButtonState |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
TOOL_DISPATCHER::TOOL_DISPATCHER( TOOL_MANAGER *aToolMgr, PCB_BASE_FRAME *aEditFrame ): |
|
|
|
m_toolMgr(aToolMgr), |
|
|
|
m_editFrame(aEditFrame) |
|
|
|
{ |
|
|
|
|
|
|
|
m_buttons.push_back(new ButtonState(MB_Left, wxEVT_LEFT_DOWN, wxEVT_LEFT_UP)); |
|
|
|
m_buttons.push_back(new ButtonState(MB_Right, wxEVT_RIGHT_DOWN, wxEVT_RIGHT_UP, true)); |
|
|
|
m_buttons.push_back(new ButtonState(MB_Middle, wxEVT_MIDDLE_DOWN, wxEVT_MIDDLE_UP)); |
|
|
|
|
|
|
|
ResetState(); |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
TOOL_DISPATCHER::TOOL_DISPATCHER( TOOL_MANAGER *aToolMgr, PCB_BASE_FRAME *aEditFrame ) : |
|
|
|
m_toolMgr(aToolMgr), m_editFrame(aEditFrame) |
|
|
|
{ |
|
|
|
m_buttons.push_back( new ButtonState( MB_Left, wxEVT_LEFT_DOWN, wxEVT_LEFT_UP ) ); |
|
|
|
m_buttons.push_back( new ButtonState( MB_Right, wxEVT_RIGHT_DOWN, wxEVT_RIGHT_UP, true ) ); |
|
|
|
m_buttons.push_back( new ButtonState( MB_Middle, wxEVT_MIDDLE_DOWN, wxEVT_MIDDLE_UP ) ); |
|
|
|
|
|
|
|
ResetState(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
TOOL_DISPATCHER::~TOOL_DISPATCHER() |
|
|
|
{ |
|
|
|
BOOST_FOREACH(ButtonState *st, m_buttons) |
|
|
|
BOOST_FOREACH( ButtonState* st, m_buttons ) |
|
|
|
delete st; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void TOOL_DISPATCHER::ResetState() |
|
|
|
{ |
|
|
|
BOOST_FOREACH(ButtonState *st, m_buttons) |
|
|
|
BOOST_FOREACH( ButtonState* st, m_buttons ) |
|
|
|
st->Reset(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
KiGfx::VIEW* TOOL_DISPATCHER::getView() |
|
|
|
{ |
|
|
|
return m_editFrame->GetGalCanvas()->GetView(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int TOOL_DISPATCHER::decodeModifiers( wxEvent& aEvent ) |
|
|
|
{ |
|
|
|
wxMouseEvent *me = static_cast<wxMouseEvent*> (&aEvent); |
|
|
|
int mods = 0; |
|
|
|
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( me->ControlDown() ) |
|
|
|
mods |= MB_ModCtrl; |
|
|
|
if( me->AltDown() ) |
|
|
|
mods |= MB_ModAlt; |
|
|
|
if( me->ShiftDown() ) |
|
|
|
mods |= MB_ModShift; |
|
|
|
|
|
|
|
return mods; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool TOOL_DISPATCHER::handleMouseButton ( wxEvent& aEvent, int aIndex, bool aMotion ) |
|
|
|
{ |
|
|
|
ButtonState *st = m_buttons[aIndex]; |
|
|
|
ButtonState* st = m_buttons[aIndex]; |
|
|
|
wxEventType type = aEvent.GetEventType(); |
|
|
|
optional<TOOL_EVENT> evt; |
|
|
|
|
|
|
|
bool up = type == st->upEvent; |
|
|
|
bool down = type == st->downEvent; |
|
|
|
|
|
|
|
int mods = decodeModifiers(aEvent); |
|
|
|
int mods = decodeModifiers( aEvent ); |
|
|
|
int args = st->button | mods; |
|
|
|
|
|
|
|
if(down) |
|
|
|
if( down ) |
|
|
|
{ |
|
|
|
st->downTimestamp = wxGetLocalTimeMillis(); |
|
|
|
st->dragOrigin = m_lastMousePos; |
|
|
|
st->dragMaxDelta = 0; |
|
|
|
st->pressed = true; |
|
|
|
evt = TOOL_EVENT (TC_Mouse, TA_MouseDown, args ); |
|
|
|
} else if (up) |
|
|
|
evt = TOOL_EVENT( TC_Mouse, TA_MouseDown, args ); |
|
|
|
} |
|
|
|
else if ( up ) |
|
|
|
{ |
|
|
|
bool isClick = false; |
|
|
|
st->pressed = false; |
|
|
|
|
|
|
|
if(st->dragging) |
|
|
|
if( st->dragging ) |
|
|
|
{ |
|
|
|
wxLongLong t = wxGetLocalTimeMillis(); |
|
|
|
|
|
|
|
if( t - st->downTimestamp < DragTimeThreshold && st->dragMaxDelta < DragDistanceThreshold ) |
|
|
|
isClick = true; |
|
|
|
else |
|
|
|
evt = TOOL_EVENT (TC_Mouse, TA_MouseUp, args ); |
|
|
|
} else |
|
|
|
evt = TOOL_EVENT( TC_Mouse, TA_MouseUp, args ); |
|
|
|
} |
|
|
|
else |
|
|
|
isClick = true; |
|
|
|
|
|
|
|
|
|
|
|
if(isClick) |
|
|
|
if( isClick ) |
|
|
|
{ |
|
|
|
if(st -> triggerContextMenu && !mods) |
|
|
|
if( st -> triggerContextMenu && !mods ) |
|
|
|
{} |
|
|
|
// evt = TOOL_EVENT (TC_Command, TA_ContextMenu );
|
|
|
|
// evt = TOOL_EVENT( TC_Command, TA_ContextMenu );
|
|
|
|
else |
|
|
|
evt = TOOL_EVENT (TC_Mouse, TA_MouseClick, args ); |
|
|
|
evt = TOOL_EVENT( TC_Mouse, TA_MouseClick, args ); |
|
|
|
} |
|
|
|
|
|
|
|
st->dragging = false; |
|
|
|
} |
|
|
|
|
|
|
|
if(st->pressed && aMotion) |
|
|
|
if( st->pressed && aMotion ) |
|
|
|
{ |
|
|
|
st->dragging = true; |
|
|
|
double dragPixelDistance = getView()->ToScreen(m_lastMousePos - st->dragOrigin, false).EuclideanNorm(); |
|
|
|
st->dragMaxDelta = std::max(st->dragMaxDelta, dragPixelDistance); |
|
|
|
double dragPixelDistance = getView()->ToScreen( m_lastMousePos - st->dragOrigin, false ).EuclideanNorm(); |
|
|
|
st->dragMaxDelta = std::max( st->dragMaxDelta, dragPixelDistance ); |
|
|
|
|
|
|
|
wxLongLong t = wxGetLocalTimeMillis(); |
|
|
|
|
|
|
|
if( t - st->downTimestamp > DragTimeThreshold || st->dragMaxDelta > DragDistanceThreshold ) |
|
|
|
{ |
|
|
|
evt = TOOL_EVENT (TC_Mouse, TA_MouseDrag, args ); |
|
|
|
evt->SetMouseDragOrigin(st->dragOrigin); |
|
|
|
evt->SetMouseDelta(m_lastMousePos - st->dragOrigin); |
|
|
|
evt = TOOL_EVENT( TC_Mouse, TA_MouseDrag, args ); |
|
|
|
evt->SetMouseDragOrigin( st->dragOrigin ); |
|
|
|
evt->SetMouseDelta( m_lastMousePos - st->dragOrigin ); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if(evt) |
|
|
|
if( evt ) |
|
|
|
{ |
|
|
|
evt->SetMousePosition(m_lastMousePos); |
|
|
|
evt->SetMousePosition( m_lastMousePos ); |
|
|
|
m_toolMgr->ProcessEvent( *evt ); |
|
|
|
|
|
|
|
return true; |
|
|
|
@ -168,7 +196,8 @@ bool TOOL_DISPATCHER::handleMouseButton ( wxEvent& aEvent, int aIndex, bool aMot |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
void TOOL_DISPATCHER::DispatchWxEvent(wxEvent &aEvent) |
|
|
|
|
|
|
|
void TOOL_DISPATCHER::DispatchWxEvent( wxEvent &aEvent ) |
|
|
|
{ |
|
|
|
bool motion = false, buttonEvents = false; |
|
|
|
VECTOR2D pos; |
|
|
|
@ -178,37 +207,38 @@ void TOOL_DISPATCHER::DispatchWxEvent(wxEvent &aEvent) |
|
|
|
|
|
|
|
if( type == wxEVT_MOTION ) |
|
|
|
{ |
|
|
|
wxMouseEvent *me = static_cast<wxMouseEvent*> (&aEvent); |
|
|
|
pos = getView()->ToWorld ( VECTOR2D( me->GetX(), me->GetY() )); |
|
|
|
if(pos != m_lastMousePos) |
|
|
|
wxMouseEvent *me = static_cast<wxMouseEvent*>(&aEvent ); |
|
|
|
pos = getView()->ToWorld( VECTOR2D( me->GetX(), me->GetY() ) ); |
|
|
|
if( pos != m_lastMousePos ) |
|
|
|
{ |
|
|
|
motion = true; |
|
|
|
m_lastMousePos = pos; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
for(unsigned int i = 0; i < m_buttons.size(); i++) |
|
|
|
buttonEvents |= handleMouseButton(aEvent, i, motion); |
|
|
|
for( unsigned int i = 0; i < m_buttons.size(); i++ ) |
|
|
|
buttonEvents |= handleMouseButton( aEvent, i, motion ); |
|
|
|
|
|
|
|
if(!buttonEvents && motion) |
|
|
|
if( !buttonEvents && motion ) |
|
|
|
{ |
|
|
|
evt = TOOL_EVENT (TC_Mouse, TA_MouseMotion ); |
|
|
|
evt->SetMousePosition(pos); |
|
|
|
evt->SetMousePosition( pos ); |
|
|
|
} |
|
|
|
|
|
|
|
if(evt) |
|
|
|
if( evt ) |
|
|
|
m_toolMgr->ProcessEvent( *evt ); |
|
|
|
|
|
|
|
aEvent.Skip(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
void TOOL_DISPATCHER::DispatchWxCommand(wxCommandEvent &aEvent) |
|
|
|
|
|
|
|
void TOOL_DISPATCHER::DispatchWxCommand( wxCommandEvent &aEvent ) |
|
|
|
{ |
|
|
|
bool activateTool = false; |
|
|
|
std::string toolName; |
|
|
|
|
|
|
|
switch (aEvent.GetId()) |
|
|
|
switch ( aEvent.GetId() ) |
|
|
|
{ |
|
|
|
case ID_SELECTION_TOOL: |
|
|
|
toolName = "pcbnew.InteractiveSelection"; |
|
|
|
@ -216,9 +246,9 @@ void TOOL_DISPATCHER::DispatchWxCommand(wxCommandEvent &aEvent) |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
if(activateTool) |
|
|
|
if( activateTool ) |
|
|
|
{ |
|
|
|
TOOL_EVENT evt ( TC_Command, TA_ActivateTool, toolName ); |
|
|
|
m_toolMgr->ProcessEvent(evt); |
|
|
|
m_toolMgr->ProcessEvent( evt ); |
|
|
|
} |
|
|
|
} |
|
|
|
} |