ADDED: Expand selection in context menu
Break out the context menu with heuristically limited choices being appended to the main list rather than re-selecting Fixes https://gitlab.com/kicad/code/kicad/issues/4799
This commit is contained in:
parent
84b02e51f1
commit
7cea4b23f1
|
@ -525,7 +525,7 @@ bool EE_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere, const KICAD_T* aFil
|
|||
// If still more than one item we're going to have to ask the user.
|
||||
if( collector.GetCount() > 1 )
|
||||
{
|
||||
collector.m_MenuTitle = _( "Clarify Selection" );
|
||||
collector.m_MenuTitle = wxEmptyString;
|
||||
// Must call selectionMenu via RunAction() to avoid event-loop contention
|
||||
m_toolMgr->RunAction( EE_ACTIONS::selectionMenu, true, &collector );
|
||||
|
||||
|
@ -603,7 +603,7 @@ void EE_SELECTION_TOOL::GuessSelectionCandidates( EE_COLLECTOR& collector, const
|
|||
EDA_ITEM* item = collector[ i ];
|
||||
|
||||
if( !item->HitTest( (wxPoint) aPos, 0 ) )
|
||||
collector.Remove( item );
|
||||
collector.Transfer( item );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -614,7 +614,7 @@ void EE_SELECTION_TOOL::GuessSelectionCandidates( EE_COLLECTOR& collector, const
|
|||
EDA_ITEM* other = collector[ ( i + 1 ) % 2 ];
|
||||
|
||||
if( item->Type() != SCH_SHEET_T && other->Type() == SCH_SHEET_T )
|
||||
collector.Remove( other );
|
||||
collector.Transfer( other );
|
||||
}
|
||||
|
||||
// Prefer a symbol to a pin or the opposite, when both a symbol and a pin are selected
|
||||
|
@ -631,9 +631,9 @@ void EE_SELECTION_TOOL::GuessSelectionCandidates( EE_COLLECTOR& collector, const
|
|||
if( item->Type() == SCH_COMPONENT_T && other->Type() == SCH_PIN_T )
|
||||
{
|
||||
if( !m_isLibEdit && m_frame->eeconfig()->m_Selection.select_pin_selects_symbol )
|
||||
collector.Remove( other );
|
||||
collector.Transfer( other );
|
||||
else
|
||||
collector.Remove( item );
|
||||
collector.Transfer( item );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -644,7 +644,7 @@ void EE_SELECTION_TOOL::GuessSelectionCandidates( EE_COLLECTOR& collector, const
|
|||
EDA_ITEM* other = collector[ ( i + 1 ) % 2 ];
|
||||
|
||||
if( item->Type() == SCH_FIELD_T && other->Type() == SCH_COMPONENT_T )
|
||||
collector.Remove( other );
|
||||
collector.Transfer( other );
|
||||
}
|
||||
|
||||
// No need for multiple wires at a single point; if there's a junction select that;
|
||||
|
@ -665,9 +665,9 @@ void EE_SELECTION_TOOL::GuessSelectionCandidates( EE_COLLECTOR& collector, const
|
|||
for( int j = collector.GetCount() - 1; j >= 0; --j )
|
||||
{
|
||||
if( junction && collector[ j ]->Type() != SCH_JUNCTION_T )
|
||||
collector.Remove( j );
|
||||
collector.Transfer( j );
|
||||
else if( !junction && j > 0 )
|
||||
collector.Remove( j );
|
||||
collector.Transfer( j );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1102,10 +1102,19 @@ int EE_SELECTION_TOOL::SelectionMenu( const TOOL_EVENT& aEvent )
|
|||
bool EE_SELECTION_TOOL::doSelectionMenu( EE_COLLECTOR* aCollector )
|
||||
{
|
||||
EDA_ITEM* current = nullptr;
|
||||
ACTION_MENU menu( true );
|
||||
bool selectAll = false;
|
||||
bool expandSelection = false;
|
||||
|
||||
int limit = std::min( MAX_SELECT_ITEM_IDS, aCollector->GetCount() );
|
||||
do
|
||||
{
|
||||
/// The user has requested the full, non-limited list of selection items
|
||||
if( expandSelection )
|
||||
aCollector->Combine();
|
||||
|
||||
expandSelection = false;
|
||||
|
||||
int limit = std::min( 9, aCollector->GetCount() );
|
||||
ACTION_MENU menu( true );
|
||||
|
||||
for( int i = 0; i < limit; ++i )
|
||||
{
|
||||
|
@ -1120,11 +1129,20 @@ bool EE_SELECTION_TOOL::doSelectionMenu( EE_COLLECTOR* aCollector )
|
|||
menu.AppendSeparator();
|
||||
menu.Add( _( "Select &All\tA" ), limit + 1, net_highlight_schematic_xpm );
|
||||
|
||||
if( aCollector->m_MenuTitle.Length() )
|
||||
menu.SetTitle( aCollector->m_MenuTitle );
|
||||
if( !expandSelection && aCollector->HasAdditionalItems() )
|
||||
menu.Add( _( "&Expand Selection\tE" ), limit + 2, nullptr );
|
||||
|
||||
if( aCollector->m_MenuTitle.Length() )
|
||||
{
|
||||
menu.SetTitle( aCollector->m_MenuTitle );
|
||||
menu.SetIcon( info_xpm );
|
||||
menu.DisplayTitle( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
menu.DisplayTitle( false );
|
||||
}
|
||||
|
||||
SetContextMenu( &menu, CMENU_NOW );
|
||||
|
||||
while( TOOL_EVENT* evt = Wait() )
|
||||
|
@ -1195,13 +1213,16 @@ bool EE_SELECTION_TOOL::doSelectionMenu( EE_COLLECTOR* aCollector )
|
|||
selectAll = false;
|
||||
current = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
else if( evt->Action() == TA_CHOICE_MENU_CLOSED )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
getView()->UpdateItems();
|
||||
m_frame->GetCanvas()->Refresh();
|
||||
}
|
||||
} while( expandSelection );
|
||||
|
||||
if( selectAll )
|
||||
return true;
|
||||
|
|
|
@ -55,7 +55,8 @@ class EDA_ITEM;
|
|||
class COLLECTOR
|
||||
{
|
||||
protected:
|
||||
std::vector<EDA_ITEM*> m_List;
|
||||
std::vector<EDA_ITEM*> m_List; // Primary list of most likely items
|
||||
std::vector<EDA_ITEM*> m_BackupList; // Secondary list with items removed by heuristics
|
||||
|
||||
const KICAD_T* m_ScanTypes;
|
||||
INSPECTOR_FUNC m_inspector;
|
||||
|
@ -148,6 +149,51 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the collector has heuristic backup items
|
||||
* @return true if Combine() can run to bring secondary items into the list
|
||||
*/
|
||||
bool HasAdditionalItems()
|
||||
{
|
||||
return !m_BackupList.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-combines the backup list into the main list of the collector
|
||||
*/
|
||||
void Combine()
|
||||
{
|
||||
std::copy( m_BackupList.begin(), m_BackupList.end(), std::back_inserter( m_List ) );
|
||||
m_BackupList.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the item at \a aIndex (first position is 0) to the backup list
|
||||
* @param aIndex The index into the list.
|
||||
*/
|
||||
void Transfer( int aIndex )
|
||||
{
|
||||
m_BackupList.push_back( m_List[aIndex] );
|
||||
m_List.erase( m_List.begin() + aIndex );
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the item aItem (if exists in the collector) to the backup list
|
||||
* @param aItem the item to be moved.
|
||||
*/
|
||||
void Transfer( EDA_ITEM* aItem )
|
||||
{
|
||||
for( size_t i = 0; i < m_List.size(); i++ )
|
||||
{
|
||||
if( m_List[i] == aItem )
|
||||
{
|
||||
m_List.erase( m_List.begin() + i );
|
||||
m_BackupList.push_back( aItem );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function operator[int]
|
||||
* is used for read only access and returns the object at \a aIndex.
|
||||
|
|
|
@ -210,6 +210,9 @@ protected:
|
|||
///> Checks if any of submenus contains a TOOL_ACTION with a specific ID.
|
||||
OPT_TOOL_EVENT findToolAction( int aId );
|
||||
|
||||
bool m_isForcedPosition;
|
||||
wxPoint m_forcedPosition;
|
||||
|
||||
bool m_dirty; // Menu requires update before display
|
||||
|
||||
bool m_titleDisplayed;
|
||||
|
|
|
@ -280,7 +280,7 @@ void PL_SELECTION_TOOL::guessSelectionCandidates( COLLECTOR& collector, const VE
|
|||
EDA_ITEM* other = collector[ ( i + 1 ) % 2 ];
|
||||
|
||||
if( item->HitTest( (wxPoint) aPos, 0 ) && !other->HitTest( (wxPoint) aPos, 0 ) )
|
||||
collector.Remove( other );
|
||||
collector.Transfer( other );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -585,7 +585,9 @@ bool PL_SELECTION_TOOL::doSelectionMenu( COLLECTOR* aCollector )
|
|||
current = ( *aCollector )[*id - 1];
|
||||
else
|
||||
current = NULL;
|
||||
|
||||
}
|
||||
else if( evt->Action() == TA_CHOICE_MENU_CLOSED )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -461,7 +461,7 @@ bool SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere, bool aOnDrag,
|
|||
if( aOnDrag )
|
||||
Wait( TOOL_EVENT( TC_ANY, TA_MOUSE_UP, BUT_LEFT ) );
|
||||
|
||||
if( !doSelectionMenu( &collector, _( "Clarify Selection" ) ) )
|
||||
if( !doSelectionMenu( &collector, wxEmptyString ) )
|
||||
{
|
||||
if( aSelectionCancelledFlag )
|
||||
*aSelectionCancelledFlag = true;
|
||||
|
@ -1487,13 +1487,22 @@ bool SELECTION_TOOL::doSelectionMenu( GENERAL_COLLECTOR* aCollector, const wxStr
|
|||
{
|
||||
BOARD_ITEM* current = nullptr;
|
||||
PCBNEW_SELECTION highlightGroup;
|
||||
ACTION_MENU menu( true );
|
||||
bool selectAll = false;
|
||||
bool expandSelection = false;
|
||||
|
||||
highlightGroup.SetLayer( LAYER_SELECT_OVERLAY );
|
||||
getView()->Add( &highlightGroup );
|
||||
|
||||
do
|
||||
{
|
||||
/// The user has requested the full, non-limited list of selection items
|
||||
if( expandSelection )
|
||||
aCollector->Combine();
|
||||
|
||||
expandSelection = false;
|
||||
|
||||
int limit = std::min( 9, aCollector->GetCount() );
|
||||
ACTION_MENU menu( true );
|
||||
|
||||
for( int i = 0; i < limit; ++i )
|
||||
{
|
||||
|
@ -1508,11 +1517,18 @@ bool SELECTION_TOOL::doSelectionMenu( GENERAL_COLLECTOR* aCollector, const wxStr
|
|||
menu.AppendSeparator();
|
||||
menu.Add( _( "Select &All\tA" ), limit + 1, net_highlight_xpm );
|
||||
|
||||
if( aTitle.Length() )
|
||||
menu.SetTitle( aTitle );
|
||||
if( !expandSelection && aCollector->HasAdditionalItems() )
|
||||
menu.Add( _( "&Expand Selection\tE" ), limit + 2, nullptr );
|
||||
|
||||
if( aTitle.Length() )
|
||||
{
|
||||
menu.SetTitle( aTitle );
|
||||
menu.SetIcon( info_xpm );
|
||||
menu.DisplayTitle( true );
|
||||
}
|
||||
else
|
||||
menu.DisplayTitle( false );
|
||||
|
||||
SetContextMenu( &menu, CMENU_NOW );
|
||||
|
||||
while( TOOL_EVENT* evt = Wait() )
|
||||
|
@ -1566,6 +1582,12 @@ bool SELECTION_TOOL::doSelectionMenu( GENERAL_COLLECTOR* aCollector, const wxStr
|
|||
selectAll = true;
|
||||
current = nullptr;
|
||||
}
|
||||
else if( id == limit + 2 )
|
||||
{
|
||||
expandSelection = true;
|
||||
selectAll = false;
|
||||
current = nullptr;
|
||||
}
|
||||
// User has selected an item, so this one will be returned
|
||||
else if( id && ( *id > 0 ) && ( *id <= limit ) )
|
||||
{
|
||||
|
@ -1577,10 +1599,14 @@ bool SELECTION_TOOL::doSelectionMenu( GENERAL_COLLECTOR* aCollector, const wxStr
|
|||
selectAll = false;
|
||||
current = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
else if( evt->Action() == TA_CHOICE_MENU_CLOSED )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while( expandSelection );
|
||||
|
||||
getView()->Remove( &highlightGroup );
|
||||
|
||||
if( selectAll )
|
||||
|
@ -2420,7 +2446,7 @@ void SELECTION_TOOL::GuessSelectionCandidates( GENERAL_COLLECTOR& aCollector,
|
|||
{
|
||||
for( BOARD_ITEM* item : rejected )
|
||||
{
|
||||
aCollector.Remove( item );
|
||||
aCollector.Transfer( item );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue