Avoid selection disambiguation menu when possible.
Some actions, such as select trivial connection, don't need the user to choose which trace at a corner to start from -- either one will do. Same for moving a simple trace corner. Likewise, Edit in Footprint Editor shouldn't ask if you mean the footprint or the pad. Obviously it's the footprint. This change adds a CLIENT_SELECTION_FILTER which allows clients to do tool- or action-specific filtering of the selection before the disambiguation menu is run. It also removes some tool- and action-specific code which was in the selection_tool and shouldn't have been. Fixes: lp:1708869 * https://bugs.launchpad.net/kicad/+bug/1708869
This commit is contained in:
parent
17e6720bc9
commit
3f6af59cac
|
@ -42,6 +42,7 @@ using namespace std::placeholders;
|
|||
#include <hotkeys.h>
|
||||
#include <confirm.h>
|
||||
#include <bitmaps.h>
|
||||
#include <collectors.h>
|
||||
|
||||
#include <tool/context_menu.h>
|
||||
#include <tool/tool_manager.h>
|
||||
|
@ -980,10 +981,87 @@ void ROUTER_TOOL::performDragging( int aMode )
|
|||
}
|
||||
|
||||
|
||||
void ROUTER_TOOL::NeighboringSegmentFilter( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
|
||||
{
|
||||
/* If the collection contains a trivial line corner (two connected segments)
|
||||
* or a non-fanout-via (a via with no more than two connected segments), then
|
||||
* trim the collection down to a single item (which one won't matter since
|
||||
* they're all connected).
|
||||
*/
|
||||
|
||||
// First make sure we've got something that *might* match.
|
||||
int vias = aCollector.CountType( PCB_VIA_T );
|
||||
int traces = aCollector.CountType( PCB_TRACE_T );
|
||||
|
||||
if( vias > 1 || traces > 2 || vias + traces < 1 )
|
||||
return;
|
||||
|
||||
// Fetch first TRACK (via or trace) as our reference
|
||||
TRACK* reference = nullptr;
|
||||
|
||||
for( int i = 0; !reference && i < aCollector.GetCount(); i++ )
|
||||
reference = dynamic_cast<TRACK*>( aCollector[i] );
|
||||
|
||||
int refNet = reference->GetNetCode();
|
||||
|
||||
wxPoint refPoint;
|
||||
STATUS_FLAGS flags = reference->IsPointOnEnds( wxPoint( aPt.x, aPt.y ), -1 );
|
||||
|
||||
if( flags & STARTPOINT )
|
||||
refPoint = reference->GetStart();
|
||||
else if( flags & ENDPOINT )
|
||||
refPoint = reference->GetEnd();
|
||||
else
|
||||
return;
|
||||
|
||||
// Check all items to ensure that they are TRACKs which are co-terminus
|
||||
// with the reference, and on the same net. Ignore markers.
|
||||
for( int i = 0; i < aCollector.GetCount(); i++ )
|
||||
{
|
||||
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( aCollector[i] );
|
||||
|
||||
if( item->Type() == PCB_MARKER_T )
|
||||
continue;
|
||||
|
||||
TRACK* neighbor = dynamic_cast<TRACK*>( item );
|
||||
|
||||
if( !neighbor || neighbor->GetNetCode() != refNet )
|
||||
return;
|
||||
|
||||
if( neighbor->GetStart() != refPoint && neighbor->GetEnd() != refPoint )
|
||||
return;
|
||||
}
|
||||
|
||||
// Selection meets criteria; trim it to the reference item.
|
||||
for( int i = aCollector.GetCount()-1; i >= 0; i-- )
|
||||
{
|
||||
if( dynamic_cast<TRACK*>( aCollector[i] ) != reference )
|
||||
aCollector.Remove( i );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ROUTER_TOOL::CanInlineDrag()
|
||||
{
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionCursor, true, NeighboringSegmentFilter );
|
||||
const auto& selection = m_toolMgr->GetTool<SELECTION_TOOL>()->GetSelection();
|
||||
|
||||
if( selection.Size() == 1 )
|
||||
{
|
||||
const BOARD_CONNECTED_ITEM* item = static_cast<const BOARD_CONNECTED_ITEM*>( selection.Front() );
|
||||
if( item->Type() == PCB_TRACE_T || item->Type() == PCB_VIA_T )
|
||||
return true;
|
||||
}
|
||||
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionCursor ); // restore selection to unfiltered state
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
// Get the item under the cursor
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionCursor, true );
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionCursor, true, NeighboringSegmentFilter );
|
||||
const auto& selection = m_toolMgr->GetTool<SELECTION_TOOL>()->GetSelection();
|
||||
|
||||
if( selection.Size() != 1 )
|
||||
|
|
|
@ -36,6 +36,7 @@ public:
|
|||
|
||||
int RouteSingleTrace( const TOOL_EVENT& aEvent );
|
||||
int RouteDiffPair( const TOOL_EVENT& aEvent );
|
||||
bool CanInlineDrag();
|
||||
int InlineDrag( const TOOL_EVENT& aEvent );
|
||||
|
||||
// TODO make this private?
|
||||
|
@ -45,6 +46,10 @@ public:
|
|||
|
||||
void setTransitions() override;
|
||||
|
||||
// A filter for narrowing a collection representing a simple corner
|
||||
// or a non-fanout-via to a single TRACK item.
|
||||
static void NeighboringSegmentFilter( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector );
|
||||
|
||||
private:
|
||||
int mainLoop( PNS::ROUTER_MODE aMode );
|
||||
|
||||
|
|
|
@ -330,13 +330,10 @@ bool EDIT_TOOL::invokeInlineRouter( int aDragMode )
|
|||
return false;
|
||||
|
||||
// make sure we don't accidentally invoke inline routing mode while the router is already active!
|
||||
if ( theRouter->IsToolActive() )
|
||||
if( theRouter->IsToolActive() )
|
||||
return false;
|
||||
|
||||
TRACK* track = uniqueSelected<TRACK>();
|
||||
VIA* via = uniqueSelected<VIA>();
|
||||
|
||||
if( track || via )
|
||||
if( theRouter->CanInlineDrag() )
|
||||
{
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::routerInlineDrag, true, aDragMode );
|
||||
return true;
|
||||
|
@ -1087,9 +1084,21 @@ int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
void EDIT_TOOL::FootprintFilter( const VECTOR2I&, GENERAL_COLLECTOR& aCollector )
|
||||
{
|
||||
for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
|
||||
{
|
||||
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( aCollector[i] );
|
||||
|
||||
if( item->Type() != PCB_MODULE_T )
|
||||
aCollector.Remove( i );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int EDIT_TOOL::ExchangeFootprints( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
const auto& selection = m_selectionTool->RequestSelection();
|
||||
const auto& selection = m_selectionTool->RequestSelection( 0, FootprintFilter );
|
||||
|
||||
if( selection.Empty() )
|
||||
return 0;
|
||||
|
@ -1265,7 +1274,7 @@ bool EDIT_TOOL::updateModificationPoint( SELECTION& aSelection )
|
|||
|
||||
int EDIT_TOOL::editFootprintInFpEditor( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
const auto& selection = m_selectionTool->RequestSelection();
|
||||
const auto& selection = m_selectionTool->RequestSelection( 0, FootprintFilter );
|
||||
|
||||
if( selection.Empty() )
|
||||
return 0;
|
||||
|
@ -1357,15 +1366,3 @@ int EDIT_TOOL::cutToClipboard( const TOOL_EVENT& aEvent )
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
T* EDIT_TOOL::uniqueSelected()
|
||||
{
|
||||
auto& selection = m_selectionTool->RequestSelection( SELECTION_DEFAULT );
|
||||
|
||||
if( selection.Size() != 1 )
|
||||
return nullptr;
|
||||
|
||||
auto item = selection[0];
|
||||
return dyn_cast<T*>( item );
|
||||
}
|
||||
|
|
|
@ -136,6 +136,14 @@ public:
|
|||
///> Launches a tool to measure between points
|
||||
int MeasureTool( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Function FootprintFilter()
|
||||
*
|
||||
* A selection filter which prunes the selection to contain only items
|
||||
* of type PCB_MODULE_T
|
||||
*/
|
||||
static void FootprintFilter( const VECTOR2I&, GENERAL_COLLECTOR& aCollector );
|
||||
|
||||
///> Sets up handlers for various events.
|
||||
void setTransitions() override;
|
||||
|
||||
|
@ -197,38 +205,6 @@ private:
|
|||
*/
|
||||
bool hoverSelection( bool aSanitize = true );
|
||||
|
||||
/**
|
||||
* Function uniqueSelected()
|
||||
*
|
||||
* Get a single selected item of a certain type
|
||||
*
|
||||
* @tparam T type of item to select
|
||||
* @return pointer to the item (of type T), or nullptr if there isn't
|
||||
* a single selected item, or it's not of the right type.
|
||||
*/
|
||||
template<class T> T* uniqueSelected();
|
||||
|
||||
/**
|
||||
* Function uniqueHoverSelection()
|
||||
*
|
||||
* Get a single unique selection of an item, either from the
|
||||
* current selection, or from the items under cursor via
|
||||
* hoverSelection()
|
||||
*
|
||||
* @tparam T type of item to select
|
||||
* @return pointer to a selected item, or nullptr if none could
|
||||
* be found.
|
||||
*/
|
||||
template<class T>
|
||||
T* uniqueHoverSelection( bool aSanitize = true )
|
||||
{
|
||||
if( !hoverSelection( aSanitize ) )
|
||||
return nullptr;
|
||||
|
||||
T* item = uniqueSelected<T>();
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
std::unique_ptr<BOARD_COMMIT> m_commit;
|
||||
};
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <tool/tool_manager.h>
|
||||
#include <wx/progdlg.h>
|
||||
|
||||
#include "edit_tool.h"
|
||||
#include "selection_tool.h"
|
||||
#include "drawing_tool.h"
|
||||
#include "picker_tool.h"
|
||||
|
@ -958,7 +959,7 @@ static bool showLocalRatsnest( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition
|
|||
auto selectionTool = aToolMgr->GetTool<SELECTION_TOOL>();
|
||||
|
||||
aToolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||
aToolMgr->RunAction( PCB_ACTIONS::selectionCursor, true );
|
||||
aToolMgr->RunAction( PCB_ACTIONS::selectionCursor, true, EDIT_TOOL::FootprintFilter );
|
||||
|
||||
const SELECTION& selection = selectionTool->GetSelection();
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ using namespace std::placeholders;
|
|||
|
||||
#include <tool/tool_event.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <router/router_tool.h>
|
||||
#include <connectivity_data.h>
|
||||
|
||||
#include "selection_tool.h"
|
||||
|
@ -175,9 +176,12 @@ public:
|
|||
|
||||
SELECTION_TOOL::SELECTION_TOOL() :
|
||||
PCB_TOOL( "pcbnew.InteractiveSelection" ),
|
||||
m_frame( NULL ), m_additive( false ), m_subtractive( false ),
|
||||
m_frame( NULL ),
|
||||
m_additive( false ),
|
||||
m_subtractive( false ),
|
||||
m_multiple( false ),
|
||||
m_locked( true ), m_menu( *this ),
|
||||
m_locked( true ),
|
||||
m_menu( *this ),
|
||||
m_priv( std::make_unique<PRIV>() )
|
||||
{
|
||||
|
||||
|
@ -355,14 +359,13 @@ SELECTION& SELECTION_TOOL::GetSelection()
|
|||
}
|
||||
|
||||
|
||||
SELECTION& SELECTION_TOOL::RequestSelection( int aFlags )
|
||||
SELECTION& SELECTION_TOOL::RequestSelection( int aFlags, CLIENT_SELECTION_FILTER aClientFilter )
|
||||
{
|
||||
if( m_selection.Empty() )
|
||||
{
|
||||
if( aFlags & SELECTION_FORCE_UNLOCK )
|
||||
m_locked = false;
|
||||
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionCursor, true, 0 );
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionCursor, true, aClientFilter );
|
||||
m_selection.SetIsHover( true );
|
||||
m_selection.ClearReferencePoint();
|
||||
}
|
||||
|
@ -437,9 +440,9 @@ const GENERAL_COLLECTORS_GUIDE SELECTION_TOOL::getCollectorsGuide() const
|
|||
|
||||
|
||||
bool SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere, bool aOnDrag,
|
||||
bool* aSelectionCancelledFlag )
|
||||
bool* aSelectionCancelledFlag,
|
||||
CLIENT_SELECTION_FILTER aClientFilter )
|
||||
{
|
||||
BOARD_ITEM* item;
|
||||
auto guide = getCollectorsGuide();
|
||||
GENERAL_COLLECTOR collector;
|
||||
|
||||
|
@ -458,63 +461,66 @@ bool SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere, bool aOnDrag,
|
|||
|
||||
m_selection.ClearReferencePoint();
|
||||
|
||||
switch( collector.GetCount() )
|
||||
// Allow the client to do tool- or action-specific filtering to see if we
|
||||
// can get down to a single item
|
||||
if( aClientFilter )
|
||||
aClientFilter( aWhere, collector );
|
||||
|
||||
if( collector.GetCount() == 0 )
|
||||
{
|
||||
case 0:
|
||||
if( !m_additive && anyCollected )
|
||||
{
|
||||
clearSelection();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
case 1:
|
||||
if( collector.GetCount() == 1 )
|
||||
{
|
||||
toggleSelection( collector[0] );
|
||||
return true;
|
||||
}
|
||||
|
||||
default:
|
||||
// Apply some ugly heuristics to avoid disambiguation menus whenever possible
|
||||
guessSelectionCandidates( collector );
|
||||
// Apply some ugly heuristics to avoid disambiguation menus whenever possible
|
||||
guessSelectionCandidates( collector );
|
||||
|
||||
// Let's see if there is still disambiguation in selection..
|
||||
if( collector.GetCount() == 1 )
|
||||
{
|
||||
toggleSelection( collector[0] );
|
||||
return true;
|
||||
}
|
||||
else if( collector.GetCount() > 1 )
|
||||
{
|
||||
if( aOnDrag )
|
||||
{
|
||||
Wait( TOOL_EVENT( TC_ANY, TA_MOUSE_UP, BUT_LEFT ) );
|
||||
}
|
||||
if( collector.GetCount() == 1 )
|
||||
{
|
||||
toggleSelection( collector[0] );
|
||||
return true;
|
||||
}
|
||||
|
||||
item = disambiguationMenu( &collector );
|
||||
// Still more than one item. We're going to have to ask the user.
|
||||
if( aOnDrag )
|
||||
{
|
||||
Wait( TOOL_EVENT( TC_ANY, TA_MOUSE_UP, BUT_LEFT ) );
|
||||
}
|
||||
|
||||
if( item )
|
||||
{
|
||||
toggleSelection( item );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( aSelectionCancelledFlag )
|
||||
*aSelectionCancelledFlag = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
BOARD_ITEM* item = disambiguationMenu( &collector );
|
||||
|
||||
if( item )
|
||||
{
|
||||
toggleSelection( item );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( aSelectionCancelledFlag )
|
||||
*aSelectionCancelledFlag = true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool SELECTION_TOOL::selectCursor( bool aSelectAlways )
|
||||
bool SELECTION_TOOL::selectCursor( bool aSelectAlways, CLIENT_SELECTION_FILTER aClientFilter )
|
||||
{
|
||||
if( aSelectAlways || m_selection.Empty() )
|
||||
{
|
||||
clearSelection();
|
||||
selectPoint( getViewControls()->GetCursorPosition( false ) );
|
||||
selectPoint( getViewControls()->GetCursorPosition( false ), false, NULL, aClientFilter );
|
||||
}
|
||||
|
||||
return !m_selection.Empty();
|
||||
|
@ -703,11 +709,11 @@ SELECTION_LOCK_FLAGS SELECTION_TOOL::CheckLock()
|
|||
|
||||
int SELECTION_TOOL::CursorSelection( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
bool sanitize = (bool) aEvent.Parameter<intptr_t>();
|
||||
CLIENT_SELECTION_FILTER aClientFilter = aEvent.Parameter<CLIENT_SELECTION_FILTER>();
|
||||
|
||||
if( m_selection.Empty() ) // Try to find an item that could be modified
|
||||
{
|
||||
selectCursor( true );
|
||||
selectCursor( true, aClientFilter );
|
||||
|
||||
if( CheckLock() == SELECTION_LOCKED )
|
||||
{
|
||||
|
@ -716,9 +722,6 @@ int SELECTION_TOOL::CursorSelection( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
}
|
||||
|
||||
if( sanitize )
|
||||
SanitizeSelection();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -805,9 +808,24 @@ int SELECTION_TOOL::UnselectItem( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
void connectedTrackFilter( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
|
||||
{
|
||||
/* Narrow the collection down to a single TRACK item for a trivial
|
||||
* connection, or multiple TRACK items for non-trivial connections.
|
||||
*/
|
||||
for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
|
||||
{
|
||||
if( !dynamic_cast<TRACK*>( aCollector[i] ) )
|
||||
aCollector.Remove( i );
|
||||
}
|
||||
|
||||
ROUTER_TOOL::NeighboringSegmentFilter( aPt, aCollector );
|
||||
}
|
||||
|
||||
|
||||
int SELECTION_TOOL::selectConnection( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
if( !selectCursor() )
|
||||
if( !selectCursor( true, connectedTrackFilter ) )
|
||||
return 0;
|
||||
|
||||
// copy the selection, since we're going to iterate and modify
|
||||
|
@ -815,12 +833,10 @@ int SELECTION_TOOL::selectConnection( const TOOL_EVENT& aEvent )
|
|||
|
||||
for( auto item : selection )
|
||||
{
|
||||
// only TRACK items can be checked for trivial connections
|
||||
if( item->Type() == PCB_TRACE_T || item->Type() == PCB_VIA_T )
|
||||
{
|
||||
TRACK& trackItem = static_cast<TRACK&>( *item );
|
||||
selectAllItemsConnectedToTrack( trackItem );
|
||||
}
|
||||
TRACK* trackItem = dynamic_cast<TRACK*>( item );
|
||||
|
||||
if( trackItem )
|
||||
selectAllItemsConnectedToTrack( *trackItem );
|
||||
}
|
||||
|
||||
// Inform other potentially interested tools
|
||||
|
@ -831,25 +847,40 @@ int SELECTION_TOOL::selectConnection( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
void connectedItemFilter( const VECTOR2I&, GENERAL_COLLECTOR& aCollector )
|
||||
{
|
||||
/* Narrow the collection down to a single BOARD_CONNECTED_ITEM for each
|
||||
* represented net. All other items types are removed.
|
||||
*/
|
||||
std::set<int> representedNets;
|
||||
|
||||
for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
|
||||
{
|
||||
BOARD_CONNECTED_ITEM* item = dynamic_cast<BOARD_CONNECTED_ITEM*>( aCollector[i] );
|
||||
if( !item )
|
||||
aCollector.Remove( i );
|
||||
else if ( representedNets.count( item->GetNetCode() ) )
|
||||
aCollector.Remove( i );
|
||||
else
|
||||
representedNets.insert( item->GetNetCode() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int SELECTION_TOOL::selectCopper( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
if( !selectCursor() )
|
||||
if( !selectCursor( true, connectedItemFilter ) )
|
||||
return 0;
|
||||
|
||||
// copy the selection, since we're going to iterate and modify
|
||||
auto selection = m_selection.GetItems();
|
||||
|
||||
for( auto i : selection )
|
||||
for( auto item : selection )
|
||||
{
|
||||
auto item = static_cast<BOARD_ITEM*>( i );
|
||||
BOARD_CONNECTED_ITEM* connItem = dynamic_cast<BOARD_CONNECTED_ITEM*>( item );
|
||||
|
||||
// only connected items can be traversed in the ratsnest
|
||||
if( item->IsConnected() )
|
||||
{
|
||||
auto& connItem = static_cast<BOARD_CONNECTED_ITEM&>( *item );
|
||||
|
||||
selectAllItemsConnectedToItem( connItem );
|
||||
}
|
||||
if( connItem )
|
||||
selectAllItemsConnectedToItem( *connItem );
|
||||
}
|
||||
|
||||
// Inform other potentially interested tools
|
||||
|
|
|
@ -47,6 +47,8 @@ namespace KIGFX
|
|||
}
|
||||
|
||||
|
||||
typedef void (*CLIENT_SELECTION_FILTER)( const VECTOR2I&, GENERAL_COLLECTOR& );
|
||||
|
||||
/**
|
||||
* Class SELECTION_TOOL
|
||||
*
|
||||
|
@ -87,10 +89,12 @@ public:
|
|||
/**
|
||||
* Function RequestSelection()
|
||||
*
|
||||
* Returns the current selection set, filtered according to aFlags.
|
||||
* Returns the current selection set, filtered according to aFlags
|
||||
* and aClientFilter.
|
||||
* If the set is empty, performs the legacy-style hover selection.
|
||||
*/
|
||||
SELECTION& RequestSelection( int aFlags = SELECTION_DEFAULT );
|
||||
SELECTION& RequestSelection( int aFlags = SELECTION_DEFAULT,
|
||||
CLIENT_SELECTION_FILTER aClientFilter = NULL );
|
||||
|
||||
|
||||
inline TOOL_MENU& GetToolMenu()
|
||||
|
@ -148,19 +152,23 @@ private:
|
|||
* @param aOnDrag indicates whether a drag operation is being performed.
|
||||
* @param aSelectionCancelledFlag allows the function to inform its caller that a selection
|
||||
* was cancelled (for instance, by clicking outside of the disambiguation menu).
|
||||
* @param aClientFilter allows the client to perform tool- or action-specific filtering.
|
||||
* @return True if an item was selected, false otherwise.
|
||||
*/
|
||||
bool selectPoint( const VECTOR2I& aWhere, bool aOnDrag = false,
|
||||
bool* aSelectionCancelledFlag = NULL );
|
||||
bool* aSelectionCancelledFlag = NULL,
|
||||
CLIENT_SELECTION_FILTER aClientFilter = NULL );
|
||||
|
||||
/**
|
||||
* Function selectCursor()
|
||||
* Selects an item under the cursor unless there is something already selected or aSelectAlways
|
||||
* is true.
|
||||
* @param aSelectAlways forces to select an item even if there is an item already selected.
|
||||
* @param aClientFilter allows the client to perform tool- or action-specific filtering.
|
||||
* @return true if eventually there is an item selected, false otherwise.
|
||||
*/
|
||||
bool selectCursor( bool aSelectAlways = false );
|
||||
bool selectCursor( bool aSelectAlways = false,
|
||||
CLIENT_SELECTION_FILTER aClientFilter = NULL );
|
||||
|
||||
/**
|
||||
* Function selectMultiple()
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
#include <class_edge_mod.h>
|
||||
|
||||
#include <tools/pcb_actions.h>
|
||||
#include <router/router_tool.h>
|
||||
|
||||
#include "pcb_tool.h"
|
||||
#include <dialog_find.h>
|
||||
|
@ -344,3 +345,8 @@ void DIALOG_BLOCK_OPTIONS::ExecuteCommand( wxCommandEvent& event )
|
|||
void PCB_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ROUTER_TOOL::NeighboringSegmentFilter( const VECTOR2I&, GENERAL_COLLECTOR& )
|
||||
{
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue