void TOOL_BASE::updateStartItem( const TOOL_EVENT& aEvent, bool aIgnorePads )
{
    int tl = getView()->GetTopLayer();
    VECTOR2I cp = controls()->GetCursorPosition( !aEvent.Modifier( MD_SHIFT ) );
    VECTOR2I p;

    controls()->ForceCursorPosition( false );
    m_gridHelper->SetUseGrid( !aEvent.Modifier( MD_ALT ) );
    m_gridHelper->SetSnap( !aEvent.Modifier( MD_SHIFT ) );

    bool snapEnabled = true;

    if( aEvent.IsMotion() || aEvent.IsClick() )
    {
        snapEnabled = !aEvent.Modifier( MD_SHIFT );
        p = aEvent.Position();
    }
    else
    {
        p = cp;
    }

    m_startItem = pickSingleItem( p, -1, -1, aIgnorePads );

    if( !snapEnabled && m_startItem && !m_startItem->Layers().Overlaps( tl ) )
        m_startItem = nullptr;

    m_startSnapPoint = snapToItem( snapEnabled, m_startItem, p );

    if( checkSnap( m_startItem ) )
    {
        controls()->ForceCursorPosition( true, m_startSnapPoint );
    }
}
void TOOL_BASE::updateEndItem( const TOOL_EVENT& aEvent )
{
    int layer;
    bool snapEnabled = !aEvent.Modifier( MD_SHIFT );
    m_gridHelper->SetUseGrid( !aEvent.Modifier( MD_ALT ) );
    m_gridHelper->SetSnap( snapEnabled );

    controls()->ForceCursorPosition( false );
    VECTOR2I mousePos = controls()->GetMousePosition();

    if( m_router->Settings().Mode() != RM_MarkObstacles &&
        ( m_router->GetCurrentNets().empty() || m_router->GetCurrentNets().front() < 0 ) )
    {
        m_endSnapPoint = snapToItem( snapEnabled, nullptr, mousePos );
        controls()->ForceCursorPosition( true, m_endSnapPoint );
        m_endItem = nullptr;

        return;
    }

    if( m_router->IsPlacingVia() )
        layer = -1;
    else
        layer = m_router->GetCurrentLayer();

    ITEM* endItem = nullptr;

    std::vector<int> nets = m_router->GetCurrentNets();

    for( int net : nets )
    {
        endItem = pickSingleItem( mousePos, net, layer, false, { m_startItem } );

        if( endItem )
            break;
    }

    if( checkSnap( endItem ) )
    {
        m_endItem = endItem;
        m_endSnapPoint = snapToItem( snapEnabled, endItem, mousePos );
    } else {
        m_endItem = nullptr;
        m_endSnapPoint = m_gridHelper->Align( mousePos );
    }

    controls()->ForceCursorPosition( true, m_endSnapPoint );

    if( m_endItem )
    {
        wxLogTrace( "PNS", "%s, layer : %d", m_endItem->KindStr().c_str(), m_endItem->Layers().Start() );
    }
}
void PNS_TOOL_BASE::updateEndItem( TOOL_EVENT& aEvent )
{
    VECTOR2I mp = m_ctls->GetMousePosition();
    VECTOR2I p = getView()->ToWorld( mp );
    VECTOR2I cp = m_ctls->GetCursorPosition();
    int layer;
    bool snapEnabled = !aEvent.Modifier( MD_SHIFT );

    m_router->EnableSnapping( snapEnabled );

    if( m_router->GetCurrentNets().empty() || m_router->GetCurrentNets().front() < 0 )
    {
        m_endItem = NULL;
        m_endSnapPoint = cp;
        return;
    }

    bool dummy;

    if( m_router->IsPlacingVia() )
        layer = -1;
    else
        layer = m_router->GetCurrentLayer();

    PNS_ITEM* endItem = NULL;

    std::vector<int> nets = m_router->GetCurrentNets();

    for( int net : nets )
    {
        endItem = pickSingleItem( p, net, layer );

        if( endItem )
            break;
    }

    if( endItem )
    {
        VECTOR2I cursorPos = snapToItem( endItem, p, dummy );
        m_ctls->ForceCursorPosition( true, cursorPos );
        m_endItem = endItem;
        m_endSnapPoint = cursorPos;
    }
    else
    {
        m_endItem = NULL;
        m_endSnapPoint = cp;
        m_ctls->ForceCursorPosition( false );
    }

    if( m_endItem )
    {
        wxLogTrace( "PNS", "%s, layer : %d", m_endItem->KindStr().c_str(), m_endItem->Layers().Start() );
    }
}
bool TOOL_MANAGER::dispatchStandardEvents( const TOOL_EVENT& aEvent )
{
    if( aEvent.Action() == TA_KEY_PRESSED )
    {
        // Check if there is a hotkey associated
        if( m_actionMgr->RunHotKey( aEvent.Modifier() | aEvent.KeyCode() ) )
            return false;                 // hotkey event was handled so it does not go any further
    }

    return true;
}
void PNS_TOOL_BASE::updateStartItem( TOOL_EVENT& aEvent )
{
    int tl = getView()->GetTopLayer();
    VECTOR2I cp = m_ctls->GetCursorPosition();
    VECTOR2I p;

    PNS_ITEM* startItem = NULL;
    bool snapEnabled = true;

    if( aEvent.IsMotion() || aEvent.IsClick() )
    {
        snapEnabled = !aEvent.Modifier( MD_SHIFT );
        p = aEvent.Position();
    }
    else
    {
        p = cp;
    }

    startItem = pickSingleItem( p );
    m_router->EnableSnapping( snapEnabled );

    if( !snapEnabled && startItem && !startItem->Layers().Overlaps( tl ) )
        startItem = NULL;

    if( startItem && startItem->Net() >= 0 )
    {
        bool dummy;
        VECTOR2I psnap = snapToItem( startItem, p, dummy );

        if( snapEnabled )
        {
            m_startSnapPoint = psnap;
            m_ctls->ForceCursorPosition( true, psnap );
        }
        else
        {
            m_startSnapPoint = cp;
            m_ctls->ForceCursorPosition( false );
        }

        m_startItem = startItem;
    }
    else
    {
        m_startItem = NULL;
        m_startSnapPoint = cp;
        m_ctls->ForceCursorPosition( false );
    }
}