Share more code between selection tools.
This commit is contained in:
parent
c243c7e1b8
commit
57acce9e55
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 KiCad Developers, see AUTHORS.TXT for contributors.
|
||||
* Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.TXT for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -21,10 +21,18 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <bitmaps.h>
|
||||
#include <widgets/ui_common.h>
|
||||
#include <collector.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tool/actions.h>
|
||||
#include <tool/selection_tool.h>
|
||||
#include <view/view.h>
|
||||
#include <eda_draw_frame.h>
|
||||
|
||||
|
||||
SELECTION_TOOL::SELECTION_TOOL() :
|
||||
SELECTION_TOOL::SELECTION_TOOL( const std::string& aName ) :
|
||||
TOOL_INTERACTIVE( aName ),
|
||||
m_additive( false ),
|
||||
m_subtractive( false ),
|
||||
m_exclusive_or( false ),
|
||||
|
@ -73,3 +81,325 @@ void SELECTION_TOOL::setModifiersState( bool aShiftState, bool aCtrlState, bool
|
|||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
int SELECTION_TOOL::UpdateMenu( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
ACTION_MENU* actionMenu = aEvent.Parameter<ACTION_MENU*>();
|
||||
CONDITIONAL_MENU* conditionalMenu = dynamic_cast<CONDITIONAL_MENU*>( actionMenu );
|
||||
|
||||
if( conditionalMenu )
|
||||
conditionalMenu->Evaluate( selection() );
|
||||
|
||||
if( actionMenu )
|
||||
actionMenu->UpdateAll();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SELECTION_TOOL::AddItemToSel( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
AddItemToSel( aEvent.Parameter<EDA_ITEM*>() );
|
||||
selection().SetIsHover( false );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void SELECTION_TOOL::AddItemToSel( EDA_ITEM* aItem, bool aQuietMode )
|
||||
{
|
||||
if( aItem )
|
||||
{
|
||||
select( aItem );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
if( !aQuietMode )
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int SELECTION_TOOL::AddItemsToSel( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
AddItemsToSel( aEvent.Parameter<EDA_ITEMS*>(), false );
|
||||
selection().SetIsHover( false );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void SELECTION_TOOL::AddItemsToSel( EDA_ITEMS* aList, bool aQuietMode )
|
||||
{
|
||||
if( aList )
|
||||
{
|
||||
for( EDA_ITEM* item : *aList )
|
||||
select( item );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
if( !aQuietMode )
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int SELECTION_TOOL::RemoveItemFromSel( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
RemoveItemFromSel( aEvent.Parameter<EDA_ITEM*>() );
|
||||
selection().SetIsHover( false );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void SELECTION_TOOL::RemoveItemFromSel( EDA_ITEM* aItem, bool aQuietMode )
|
||||
{
|
||||
if( aItem )
|
||||
{
|
||||
unselect( aItem );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
if( !aQuietMode )
|
||||
m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int SELECTION_TOOL::RemoveItemsFromSel( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
RemoveItemsFromSel( aEvent.Parameter<EDA_ITEMS*>(), false );
|
||||
selection().SetIsHover( false );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void SELECTION_TOOL::RemoveItemsFromSel( EDA_ITEMS* aList, bool aQuietMode )
|
||||
{
|
||||
if( aList )
|
||||
{
|
||||
for( EDA_ITEM* item : *aList )
|
||||
unselect( item );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
if( !aQuietMode )
|
||||
m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SELECTION_TOOL::RemoveItemsFromSel( std::vector<KIID>* aList, bool aQuietMode )
|
||||
{
|
||||
EDA_ITEMS removeItems;
|
||||
|
||||
for( EDA_ITEM* item : selection() )
|
||||
{
|
||||
if( alg::contains( *aList, item->m_Uuid ) )
|
||||
removeItems.push_back( item );
|
||||
}
|
||||
|
||||
RemoveItemsFromSel( &removeItems, aQuietMode );
|
||||
}
|
||||
|
||||
|
||||
void SELECTION_TOOL::BrightenItem( EDA_ITEM* aItem )
|
||||
{
|
||||
highlight( aItem, BRIGHTENED );
|
||||
}
|
||||
|
||||
|
||||
void SELECTION_TOOL::UnbrightenItem( EDA_ITEM* aItem )
|
||||
{
|
||||
unhighlight( aItem, BRIGHTENED );
|
||||
}
|
||||
|
||||
|
||||
void SELECTION_TOOL::onDisambiguationExpire( wxTimerEvent& aEvent )
|
||||
{
|
||||
// If there is a multiple selection then it's more likely that we're seeing a paused drag
|
||||
// than a long-click.
|
||||
if( selection().GetSize() >= 2 )
|
||||
return;
|
||||
|
||||
m_toolMgr->ProcessEvent( EVENTS::DisambiguatePoint );
|
||||
}
|
||||
|
||||
|
||||
int SELECTION_TOOL::SelectionMenu( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
COLLECTOR* collector = aEvent.Parameter<COLLECTOR*>();
|
||||
|
||||
if( !doSelectionMenu( collector ) )
|
||||
collector->m_MenuCancelled = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool SELECTION_TOOL::doSelectionMenu( COLLECTOR* aCollector )
|
||||
{
|
||||
EDA_UNITS userUnits = getEditFrame<EDA_DRAW_FRAME>()->GetUserUnits();
|
||||
EDA_ITEM* current = nullptr;
|
||||
SELECTION highlightGroup;
|
||||
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( 100, aCollector->GetCount() );
|
||||
ACTION_MENU menu( true );
|
||||
|
||||
for( int i = 0; i < limit; ++i )
|
||||
{
|
||||
EDA_ITEM* item = ( *aCollector )[i];
|
||||
wxString menuText;
|
||||
|
||||
if( i < 9 )
|
||||
{
|
||||
#ifdef __WXMAC__
|
||||
menuText = wxString::Format( "%s\t%d",
|
||||
item->GetSelectMenuText( userUnits ),
|
||||
i + 1 );
|
||||
#else
|
||||
menuText = wxString::Format( "&%d %s\t%d",
|
||||
i + 1,
|
||||
item->GetSelectMenuText( userUnits ),
|
||||
i + 1 );
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
menuText = item->GetSelectMenuText( userUnits );
|
||||
}
|
||||
|
||||
menu.Add( menuText, i + 1, item->GetMenuImage() );
|
||||
}
|
||||
|
||||
menu.AppendSeparator();
|
||||
menu.Add( _( "Select &All\tA" ), limit + 1, BITMAPS::INVALID_BITMAP );
|
||||
|
||||
if( !expandSelection && aCollector->HasAdditionalItems() )
|
||||
menu.Add( _( "&Expand Selection\tE" ), limit + 2, BITMAPS::INVALID_BITMAP );
|
||||
|
||||
if( aCollector->m_MenuTitle.Length() )
|
||||
{
|
||||
menu.SetTitle( aCollector->m_MenuTitle );
|
||||
menu.SetIcon( BITMAPS::info );
|
||||
menu.DisplayTitle( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
menu.DisplayTitle( false );
|
||||
}
|
||||
|
||||
SetContextMenu( &menu, CMENU_NOW );
|
||||
|
||||
while( TOOL_EVENT* evt = Wait() )
|
||||
{
|
||||
if( evt->Action() == TA_CHOICE_MENU_UPDATE )
|
||||
{
|
||||
if( selectAll )
|
||||
{
|
||||
for( int i = 0; i < aCollector->GetCount(); ++i )
|
||||
unhighlight( ( *aCollector )[i], BRIGHTENED, &highlightGroup );
|
||||
}
|
||||
else if( current )
|
||||
{
|
||||
unhighlight( current, BRIGHTENED, &highlightGroup );
|
||||
}
|
||||
|
||||
int id = *evt->GetCommandId();
|
||||
|
||||
// User has pointed an item, so show it in a different way
|
||||
if( id > 0 && id <= limit )
|
||||
{
|
||||
current = ( *aCollector )[id - 1];
|
||||
highlight( current, BRIGHTENED, &highlightGroup );
|
||||
}
|
||||
else
|
||||
{
|
||||
current = nullptr;
|
||||
}
|
||||
|
||||
// User has pointed on the "Select All" option
|
||||
if( id == limit + 1 )
|
||||
{
|
||||
for( int i = 0; i < aCollector->GetCount(); ++i )
|
||||
highlight( ( *aCollector )[i], BRIGHTENED, &highlightGroup );
|
||||
|
||||
selectAll = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
selectAll = false;
|
||||
}
|
||||
}
|
||||
else if( evt->Action() == TA_CHOICE_MENU_CHOICE )
|
||||
{
|
||||
if( selectAll )
|
||||
{
|
||||
for( int i = 0; i < aCollector->GetCount(); ++i )
|
||||
unhighlight( ( *aCollector )[i], BRIGHTENED, &highlightGroup );
|
||||
}
|
||||
else if( current )
|
||||
{
|
||||
unhighlight( current, BRIGHTENED, &highlightGroup );
|
||||
}
|
||||
|
||||
OPT<int> id = evt->GetCommandId();
|
||||
|
||||
// User has selected the "Select All" option
|
||||
if( id == limit + 1 )
|
||||
{
|
||||
selectAll = true;
|
||||
current = nullptr;
|
||||
}
|
||||
// User has selected the "Expand Selection" option
|
||||
else if( id == limit + 2 )
|
||||
{
|
||||
selectAll = false;
|
||||
current = nullptr;
|
||||
expandSelection = true;
|
||||
}
|
||||
// User has selected an item, so this one will be returned
|
||||
else if( id && ( *id > 0 ) && ( *id <= limit ) )
|
||||
{
|
||||
selectAll = false;
|
||||
current = ( *aCollector )[*id - 1];
|
||||
}
|
||||
// User has cancelled the menu (either by <esc> or clicking out of it)
|
||||
else
|
||||
{
|
||||
selectAll = false;
|
||||
current = nullptr;
|
||||
}
|
||||
}
|
||||
else if( evt->Action() == TA_CHOICE_MENU_CLOSED )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while( expandSelection );
|
||||
|
||||
getView()->Remove( &highlightGroup );
|
||||
|
||||
if( selectAll )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if( current )
|
||||
{
|
||||
aCollector->Empty();
|
||||
aCollector->Append( current );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -22,14 +22,13 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <bitmaps.h>
|
||||
#include <core/typeinfo.h>
|
||||
#include <core/kicad_algo.h>
|
||||
#include <geometry/shape_compound.h>
|
||||
#include <ee_actions.h>
|
||||
#include <ee_collectors.h>
|
||||
#include <ee_selection_tool.h>
|
||||
#include <eeschema_id.h> // For MAX_SELECT_ITEM_IDS
|
||||
#include <eeschema_id.h>
|
||||
#include <symbol_edit_frame.h>
|
||||
#include <lib_item.h>
|
||||
#include <symbol_viewer_frame.h>
|
||||
|
@ -62,6 +61,7 @@
|
|||
#include <view/view_controls.h>
|
||||
#include <wx/log.h>
|
||||
|
||||
|
||||
SELECTION_CONDITION EE_CONDITIONS::SingleSymbol = []( const SELECTION& aSel )
|
||||
{
|
||||
if( aSel.GetSize() == 1 )
|
||||
|
@ -123,7 +123,7 @@ SELECTION_CONDITION EE_CONDITIONS::SingleNonExcludedMarker = []( const SELECTION
|
|||
|
||||
|
||||
EE_SELECTION_TOOL::EE_SELECTION_TOOL() :
|
||||
TOOL_INTERACTIVE( "eeschema.InteractiveSelection" ),
|
||||
SELECTION_TOOL( "eeschema.InteractiveSelection" ),
|
||||
m_frame( nullptr ),
|
||||
m_nonModifiedCursor( KICURSOR::ARROW ),
|
||||
m_isSymbolEditor( false ),
|
||||
|
@ -288,7 +288,9 @@ void EE_SELECTION_TOOL::Reset( RESET_REASON aReason )
|
|||
m_convert = symbolEditFrame->GetConvert();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_isSymbolViewer = symbolViewerFrame != nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -302,21 +304,6 @@ void EE_SELECTION_TOOL::Reset( RESET_REASON aReason )
|
|||
}
|
||||
|
||||
|
||||
int EE_SELECTION_TOOL::UpdateMenu( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
ACTION_MENU* actionMenu = aEvent.Parameter<ACTION_MENU*>();
|
||||
CONDITIONAL_MENU* conditionalMenu = dynamic_cast<CONDITIONAL_MENU*>( actionMenu );
|
||||
|
||||
if( conditionalMenu )
|
||||
conditionalMenu->Evaluate( m_selection );
|
||||
|
||||
if( actionMenu )
|
||||
actionMenu->UpdateAll();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const KICAD_T movableSymbolItems[] =
|
||||
{
|
||||
LIB_SHAPE_T,
|
||||
|
@ -768,13 +755,6 @@ int EE_SELECTION_TOOL::disambiguateCursor( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
void EE_SELECTION_TOOL::onDisambiguationExpire( wxTimerEvent& aEvent )
|
||||
{
|
||||
if( m_selection.GetSize() < 2 )
|
||||
m_toolMgr->ProcessEvent( EVENTS::DisambiguatePoint );
|
||||
}
|
||||
|
||||
|
||||
void EE_SELECTION_TOOL::OnIdle( wxIdleEvent& aEvent )
|
||||
{
|
||||
if( m_frame->ToolStackIsEmpty() && !m_multiple )
|
||||
|
@ -847,9 +827,7 @@ void EE_SELECTION_TOOL::narrowSelection( EE_COLLECTOR& collector, const VECTOR2I
|
|||
|
||||
// Apply some ugly heuristics to avoid disambiguation menus whenever possible
|
||||
if( collector.GetCount() > 1 && !m_skip_heuristics )
|
||||
{
|
||||
GuessSelectionCandidates( collector, aWhere );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -908,6 +886,7 @@ bool EE_SELECTION_TOOL::selectPoint( EE_COLLECTOR& aCollector, const VECTOR2I& a
|
|||
if( aSubtract || ( aExclusiveOr && aCollector[i]->IsSelected() ) )
|
||||
{
|
||||
aCollector[i]->ClearFlags( flags );
|
||||
|
||||
if( !aCollector[i]->HasFlag( STARTPOINT ) && !aCollector[i]->HasFlag( ENDPOINT ) )
|
||||
{
|
||||
unselect( aCollector[i] );
|
||||
|
@ -1325,6 +1304,7 @@ bool EE_SELECTION_TOOL::selectMultiple()
|
|||
if( m_subtractive || ( m_exclusive_or && aItem->IsSelected() ) )
|
||||
{
|
||||
aItem->ClearFlags( flags );
|
||||
|
||||
if( !aItem->HasFlag( STARTPOINT ) && !aItem->HasFlag( ENDPOINT ) )
|
||||
{
|
||||
unselect( aItem );
|
||||
|
@ -1487,118 +1467,6 @@ int EE_SELECTION_TOOL::SelectConnection( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
int EE_SELECTION_TOOL::AddItemToSel( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
AddItemToSel( aEvent.Parameter<EDA_ITEM*>() );
|
||||
m_selection.SetIsHover( false );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void EE_SELECTION_TOOL::AddItemToSel( EDA_ITEM* aItem, bool aQuietMode )
|
||||
{
|
||||
if( aItem )
|
||||
{
|
||||
select( aItem );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
if( !aQuietMode )
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int EE_SELECTION_TOOL::AddItemsToSel( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
AddItemsToSel( aEvent.Parameter<EDA_ITEMS*>(), false );
|
||||
m_selection.SetIsHover( false );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void EE_SELECTION_TOOL::AddItemsToSel( EDA_ITEMS* aList, bool aQuietMode )
|
||||
{
|
||||
if( aList )
|
||||
{
|
||||
for( EDA_ITEM* item : *aList )
|
||||
select( item );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
if( !aQuietMode )
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int EE_SELECTION_TOOL::RemoveItemFromSel( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
RemoveItemFromSel( aEvent.Parameter<EDA_ITEM*>() );
|
||||
m_selection.SetIsHover( false );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void EE_SELECTION_TOOL::RemoveItemFromSel( EDA_ITEM* aItem, bool aQuietMode )
|
||||
{
|
||||
if( aItem )
|
||||
{
|
||||
unselect( aItem );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
if( !aQuietMode )
|
||||
m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int EE_SELECTION_TOOL::RemoveItemsFromSel( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
RemoveItemsFromSel( aEvent.Parameter<EDA_ITEMS*>(), false );
|
||||
m_selection.SetIsHover( false );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void EE_SELECTION_TOOL::RemoveItemsFromSel( EDA_ITEMS* aList, bool aQuietMode )
|
||||
{
|
||||
if( aList )
|
||||
{
|
||||
for( EDA_ITEM* item : *aList )
|
||||
unselect( item );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
if( !aQuietMode )
|
||||
m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EE_SELECTION_TOOL::RemoveItemsFromSel( std::vector<KIID>* aList, bool aQuietMode )
|
||||
{
|
||||
EDA_ITEMS removeItems;
|
||||
|
||||
for( EDA_ITEM* item : m_selection )
|
||||
{
|
||||
if( alg::contains( *aList, item->m_Uuid ) )
|
||||
removeItems.push_back( item );
|
||||
}
|
||||
|
||||
RemoveItemsFromSel( &removeItems, aQuietMode );
|
||||
}
|
||||
|
||||
|
||||
void EE_SELECTION_TOOL::BrightenItem( EDA_ITEM* aItem )
|
||||
{
|
||||
highlight( aItem, BRIGHTENED );
|
||||
}
|
||||
|
||||
|
||||
void EE_SELECTION_TOOL::UnbrightenItem( EDA_ITEM* aItem )
|
||||
{
|
||||
unhighlight( aItem, BRIGHTENED );
|
||||
}
|
||||
|
||||
|
||||
int EE_SELECTION_TOOL::ClearSelection( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
ClearSelection();
|
||||
|
@ -1618,7 +1486,7 @@ void EE_SELECTION_TOOL::RebuildSelection()
|
|||
for( LIB_ITEM& item : start->GetDrawItems() )
|
||||
{
|
||||
if( item.IsSelected() )
|
||||
select( static_cast<EDA_ITEM*>( &item ) );
|
||||
select( &item );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1649,182 +1517,6 @@ void EE_SELECTION_TOOL::RebuildSelection()
|
|||
}
|
||||
|
||||
|
||||
int EE_SELECTION_TOOL::SelectionMenu( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
EE_COLLECTOR* collector = aEvent.Parameter<EE_COLLECTOR*>();
|
||||
|
||||
if( !doSelectionMenu( collector ) )
|
||||
collector->m_MenuCancelled = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool EE_SELECTION_TOOL::doSelectionMenu( EE_COLLECTOR* aCollector )
|
||||
{
|
||||
EDA_ITEM* current = nullptr;
|
||||
bool selectAll = false;
|
||||
bool expandSelection = false;
|
||||
|
||||
do
|
||||
{
|
||||
/// The user has requested the full, non-limited list of selection items
|
||||
if( expandSelection )
|
||||
aCollector->Combine();
|
||||
|
||||
expandSelection = false;
|
||||
|
||||
int limit = std::min( 100, aCollector->GetCount() );
|
||||
ACTION_MENU menu( true );
|
||||
|
||||
for( int i = 0; i < limit; ++i )
|
||||
{
|
||||
EDA_ITEM* item = ( *aCollector )[i];
|
||||
wxString text = item->GetSelectMenuText( m_frame->GetUserUnits() );
|
||||
wxString menuText;
|
||||
|
||||
if( i < 9 )
|
||||
{
|
||||
#ifdef __WXMAC__
|
||||
menuText = wxString::Format( "%s\t%d", text, i + 1 );
|
||||
#else
|
||||
menuText = wxString::Format( "&%d %s\t%d", i + 1, text, i + 1 );
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
menuText = text;
|
||||
}
|
||||
|
||||
menu.Add( menuText, i + 1, item->GetMenuImage() );
|
||||
}
|
||||
|
||||
menu.AppendSeparator();
|
||||
menu.Add( _( "Select &All\tA" ), limit + 1, BITMAPS::INVALID_BITMAP );
|
||||
|
||||
if( !expandSelection && aCollector->HasAdditionalItems() )
|
||||
menu.Add( _( "&Expand Selection\tE" ), limit + 2, BITMAPS::INVALID_BITMAP );
|
||||
|
||||
if( aCollector->m_MenuTitle.Length() )
|
||||
{
|
||||
menu.SetTitle( aCollector->m_MenuTitle );
|
||||
menu.SetIcon( BITMAPS::info );
|
||||
menu.DisplayTitle( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
menu.DisplayTitle( false );
|
||||
}
|
||||
|
||||
SetContextMenu( &menu, CMENU_NOW );
|
||||
|
||||
while( TOOL_EVENT* evt = Wait() )
|
||||
{
|
||||
if( evt->Action() == TA_CHOICE_MENU_UPDATE )
|
||||
{
|
||||
if( selectAll )
|
||||
{
|
||||
for( int i = 0; i < aCollector->GetCount(); ++i )
|
||||
unhighlight( ( *aCollector )[i], BRIGHTENED );
|
||||
}
|
||||
else if( current )
|
||||
{
|
||||
unhighlight( current, BRIGHTENED );
|
||||
}
|
||||
|
||||
int id = *evt->GetCommandId();
|
||||
|
||||
// User has pointed an item, so show it in a different way
|
||||
if( id > 0 && id <= limit )
|
||||
{
|
||||
current = ( *aCollector )[id - 1];
|
||||
highlight( current, BRIGHTENED );
|
||||
}
|
||||
else
|
||||
{
|
||||
current = nullptr;
|
||||
}
|
||||
|
||||
// User has pointed on the "Select All" option
|
||||
if( id == limit + 1 )
|
||||
{
|
||||
for( int i = 0; i < aCollector->GetCount(); ++i )
|
||||
highlight( ( *aCollector )[i], BRIGHTENED );
|
||||
|
||||
selectAll = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
selectAll = false;
|
||||
}
|
||||
}
|
||||
else if( evt->Action() == TA_CHOICE_MENU_CHOICE )
|
||||
{
|
||||
if( selectAll )
|
||||
{
|
||||
for( int i = 0; i < aCollector->GetCount(); ++i )
|
||||
unhighlight( ( *aCollector )[i], BRIGHTENED );
|
||||
}
|
||||
else if( current )
|
||||
{
|
||||
unhighlight( current, BRIGHTENED );
|
||||
}
|
||||
|
||||
OPT<int> id = evt->GetCommandId();
|
||||
|
||||
// User has selected the "Select All" option
|
||||
if( id == limit + 1 )
|
||||
{
|
||||
selectAll = true;
|
||||
current = nullptr;
|
||||
}
|
||||
else if( id == limit + 2 )
|
||||
{
|
||||
selectAll = false;
|
||||
current = nullptr;
|
||||
expandSelection = true;
|
||||
}
|
||||
// User has selected an item, so this one will be returned
|
||||
else if( id && ( *id > 0 ) && ( *id <= limit ) )
|
||||
{
|
||||
selectAll = false;
|
||||
current = ( *aCollector )[*id - 1];
|
||||
}
|
||||
// User has cancelled the menu (either by <esc> or clicking out of it)
|
||||
else
|
||||
{
|
||||
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;
|
||||
else if( current )
|
||||
{
|
||||
unhighlight( current, BRIGHTENED );
|
||||
|
||||
getView()->UpdateItems();
|
||||
m_frame->GetCanvas()->Refresh();
|
||||
|
||||
aCollector->Empty();
|
||||
aCollector->Append( current );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool EE_SELECTION_TOOL::Selectable( const EDA_ITEM* aItem, const VECTOR2I* aPos,
|
||||
bool checkVisibilityOnly ) const
|
||||
{
|
||||
|
@ -1902,7 +1594,7 @@ void EE_SELECTION_TOOL::ClearSelection()
|
|||
return;
|
||||
|
||||
while( m_selection.GetSize() )
|
||||
unhighlight( (EDA_ITEM*) m_selection.Front(), SELECTED, &m_selection );
|
||||
unhighlight( m_selection.Front(), SELECTED, &m_selection );
|
||||
|
||||
getView()->Update( &m_selection );
|
||||
|
||||
|
@ -1926,7 +1618,7 @@ void EE_SELECTION_TOOL::unselect( EDA_ITEM* aItem )
|
|||
}
|
||||
|
||||
|
||||
void EE_SELECTION_TOOL::highlight( EDA_ITEM* aItem, int aMode, EE_SELECTION* aGroup )
|
||||
void EE_SELECTION_TOOL::highlight( EDA_ITEM* aItem, int aMode, SELECTION* aGroup )
|
||||
{
|
||||
KICAD_T itemType = aItem->Type();
|
||||
|
||||
|
@ -1959,7 +1651,7 @@ void EE_SELECTION_TOOL::highlight( EDA_ITEM* aItem, int aMode, EE_SELECTION* aGr
|
|||
}
|
||||
|
||||
|
||||
void EE_SELECTION_TOOL::unhighlight( EDA_ITEM* aItem, int aMode, EE_SELECTION* aGroup )
|
||||
void EE_SELECTION_TOOL::unhighlight( EDA_ITEM* aItem, int aMode, SELECTION* aGroup )
|
||||
{
|
||||
KICAD_T itemType = aItem->Type();
|
||||
|
||||
|
@ -1981,13 +1673,13 @@ void EE_SELECTION_TOOL::unhighlight( EDA_ITEM* aItem, int aMode, EE_SELECTION* a
|
|||
if( SCH_ITEM* sch_item = dynamic_cast<SCH_ITEM*>( aItem ) )
|
||||
{
|
||||
sch_item->RunOnChildren(
|
||||
[&]( SCH_ITEM* aChild )
|
||||
{
|
||||
if( aMode == SELECTED )
|
||||
aChild->ClearSelected();
|
||||
else if( aMode == BRIGHTENED )
|
||||
aChild->ClearBrightened();
|
||||
} );
|
||||
[&]( SCH_ITEM* aChild )
|
||||
{
|
||||
if( aMode == SELECTED )
|
||||
aChild->ClearSelected();
|
||||
else if( aMode == BRIGHTENED )
|
||||
aChild->ClearBrightened();
|
||||
} );
|
||||
}
|
||||
|
||||
if( itemType == SCH_PIN_T || itemType == SCH_FIELD_T || itemType == SCH_SHEET_PIN_T )
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
};
|
||||
|
||||
|
||||
class EE_SELECTION_TOOL : public SELECTION_TOOL, public TOOL_INTERACTIVE
|
||||
class EE_SELECTION_TOOL : public SELECTION_TOOL
|
||||
{
|
||||
public:
|
||||
EE_SELECTION_TOOL();
|
||||
|
@ -66,8 +66,6 @@ public:
|
|||
/// @copydoc TOOL_BASE::Reset()
|
||||
void Reset( RESET_REASON aReason ) override;
|
||||
|
||||
int UpdateMenu( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* The main loop.
|
||||
*/
|
||||
|
@ -106,27 +104,6 @@ public:
|
|||
bool aCheckLocked = false, bool aAdd = false, bool aSubtract = false,
|
||||
bool aExclusiveOr = false );
|
||||
|
||||
int AddItemToSel( const TOOL_EVENT& aEvent );
|
||||
void AddItemToSel( EDA_ITEM* aItem, bool aQuietMode = false );
|
||||
int AddItemsToSel( const TOOL_EVENT& aEvent );
|
||||
void AddItemsToSel( EDA_ITEMS* aList, bool aQuietMode = false );
|
||||
|
||||
int RemoveItemFromSel( const TOOL_EVENT& aEvent );
|
||||
void RemoveItemFromSel( EDA_ITEM* aItem, bool aQuietMode = false );
|
||||
int RemoveItemsFromSel( const TOOL_EVENT& aEvent );
|
||||
void RemoveItemsFromSel( EDA_ITEMS* aList, bool aQuietMode = false );
|
||||
|
||||
/**
|
||||
* A safer version of RemoveItemsFromSel( EDA_ITEMS ) which doesn't require the items to
|
||||
* still exist.
|
||||
*/
|
||||
void RemoveItemsFromSel( std::vector<KIID>* aList, bool aQuietMode = false );
|
||||
|
||||
void BrightenItem( EDA_ITEM* aItem );
|
||||
void UnbrightenItem( EDA_ITEM* aItem );
|
||||
|
||||
void SelectHighlightItem( EDA_ITEM* aItem ) { highlight( aItem, SELECTED ); }
|
||||
|
||||
///< Find (but don't select) node under cursor
|
||||
EDA_ITEM* GetNode( VECTOR2I aPosition );
|
||||
|
||||
|
@ -158,14 +135,6 @@ public:
|
|||
*/
|
||||
void GuessSelectionCandidates( EE_COLLECTOR& collector, const VECTOR2I& aPos );
|
||||
|
||||
/**
|
||||
* Show a popup menu to trim the COLLECTOR passed as aEvent's parameter down to a single
|
||||
* item.
|
||||
*
|
||||
* @note This routine **does not** modify the selection.
|
||||
*/
|
||||
int SelectionMenu( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Rebuild the selection from the EDA_ITEMs' selection flags.
|
||||
*
|
||||
|
@ -187,6 +156,9 @@ public:
|
|||
bool CollectHits( EE_COLLECTOR& aCollector, const VECTOR2I& aWhere,
|
||||
const KICAD_T* aFilterList = EE_COLLECTOR::AllItems );
|
||||
|
||||
protected:
|
||||
SELECTION& selection() override { return m_selection; }
|
||||
|
||||
private:
|
||||
OPT_TOOL_EVENT autostartEvent( TOOL_EVENT* aEvent, EE_GRID_HELPER& aGrid, SCH_ITEM* aItem );
|
||||
|
||||
|
@ -227,22 +199,6 @@ private:
|
|||
*/
|
||||
bool selectMultiple();
|
||||
|
||||
/**
|
||||
* Allow the selection of a single item from a list via pop-up menu. The items are
|
||||
* highlighted on the canvas when hovered in the menu. The collector is trimmed to
|
||||
* the picked item.
|
||||
*
|
||||
* @return true if an item was picked
|
||||
*/
|
||||
bool doSelectionMenu( EE_COLLECTOR* aItems );
|
||||
|
||||
/**
|
||||
* Start the process to show our disambiguation menu once the user has kept
|
||||
* the mouse down for the minimum time
|
||||
* @param aEvent
|
||||
*/
|
||||
void onDisambiguationExpire( wxTimerEvent& aEvent );
|
||||
|
||||
/**
|
||||
* Handle disambiguation actions including displaying the menu.
|
||||
*/
|
||||
|
@ -253,14 +209,14 @@ private:
|
|||
*
|
||||
* @param aItem is an item to be selected.
|
||||
*/
|
||||
void select( EDA_ITEM* aItem );
|
||||
void select( EDA_ITEM* aItem ) override;
|
||||
|
||||
/**
|
||||
* Take necessary action mark an item as unselected.
|
||||
*
|
||||
* @param aItem is an item to be unselected.
|
||||
*/
|
||||
void unselect( EDA_ITEM* aItem );
|
||||
void unselect( EDA_ITEM* aItem ) override;
|
||||
|
||||
/**
|
||||
* Highlight the item visually.
|
||||
|
@ -269,7 +225,7 @@ private:
|
|||
* @param aHighlightMode should be either SELECTED or BRIGHTENED
|
||||
* @param aGroup is the group to add the item to in the BRIGHTENED mode.
|
||||
*/
|
||||
void highlight( EDA_ITEM* aItem, int aHighlightMode, EE_SELECTION* aGroup = nullptr );
|
||||
void highlight( EDA_ITEM* aItem, int aHighlightMode, SELECTION* aGroup = nullptr ) override;
|
||||
|
||||
/**
|
||||
* Unhighlight the item visually.
|
||||
|
@ -278,7 +234,7 @@ private:
|
|||
* @param aHighlightMode should be either SELECTED or BRIGHTENED
|
||||
* @param aGroup is the group to remove the item from.
|
||||
*/
|
||||
void unhighlight( EDA_ITEM* aItem, int aHighlightMode, EE_SELECTION* aGroup = nullptr );
|
||||
void unhighlight( EDA_ITEM* aItem, int aHighlightMode, SELECTION* aGroup = nullptr ) override;
|
||||
|
||||
/**
|
||||
* Set the reference point to the anchor of the top-left item.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017 Jon Evans <jon@craftyjon.com>
|
||||
* Copyright (C) 2017-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2017-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* 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
|
||||
|
@ -21,7 +21,6 @@
|
|||
#include <limits>
|
||||
#include <functional>
|
||||
using namespace std::placeholders;
|
||||
|
||||
#include <bitmaps.h>
|
||||
#include <eda_item.h>
|
||||
#include <gerber_collectors.h>
|
||||
|
@ -112,25 +111,9 @@ private:
|
|||
|
||||
|
||||
GERBVIEW_SELECTION_TOOL::GERBVIEW_SELECTION_TOOL() :
|
||||
TOOL_INTERACTIVE( "gerbview.InteractiveSelection" ),
|
||||
SELECTION_TOOL( "gerbview.InteractiveSelection" ),
|
||||
m_frame( nullptr )
|
||||
{
|
||||
m_preliminary = true;
|
||||
}
|
||||
|
||||
|
||||
int GERBVIEW_SELECTION_TOOL::UpdateMenu( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
ACTION_MENU* actionMenu = aEvent.Parameter<ACTION_MENU*>();
|
||||
CONDITIONAL_MENU* conditionalMenu = dynamic_cast<CONDITIONAL_MENU*>( actionMenu );
|
||||
|
||||
if( conditionalMenu )
|
||||
conditionalMenu->Evaluate( m_selection );
|
||||
|
||||
if( actionMenu )
|
||||
actionMenu->UpdateAll();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -160,7 +143,6 @@ bool GERBVIEW_SELECTION_TOOL::Init()
|
|||
void GERBVIEW_SELECTION_TOOL::Reset( RESET_REASON aReason )
|
||||
{
|
||||
m_frame = getEditFrame<GERBVIEW_FRAME>();
|
||||
m_preliminary = true;
|
||||
|
||||
if( aReason == TOOL_BASE::MODEL_RELOAD )
|
||||
{
|
||||
|
@ -235,11 +217,11 @@ GERBVIEW_SELECTION& GERBVIEW_SELECTION_TOOL::GetSelection()
|
|||
}
|
||||
|
||||
|
||||
bool GERBVIEW_SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere, bool aOnDrag )
|
||||
bool GERBVIEW_SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere )
|
||||
{
|
||||
EDA_ITEM* item = nullptr;
|
||||
EDA_ITEM* item = nullptr;
|
||||
GERBER_COLLECTOR collector;
|
||||
EDA_ITEM* model = getModel<EDA_ITEM>();
|
||||
EDA_ITEM* model = getModel<EDA_ITEM>();
|
||||
|
||||
collector.Collect( model, GERBER_COLLECTOR::AllItems, wxPoint( aWhere.x, aWhere.y ) );
|
||||
|
||||
|
@ -252,16 +234,10 @@ bool GERBVIEW_SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere, bool aOnDrag
|
|||
|
||||
if( collector.GetCount() > 1 )
|
||||
{
|
||||
if( aOnDrag )
|
||||
Wait( TOOL_EVENT( TC_ANY, TA_MOUSE_UP, BUT_LEFT ) );
|
||||
doSelectionMenu( &collector );
|
||||
|
||||
item = disambiguationMenu( &collector );
|
||||
|
||||
if( item )
|
||||
{
|
||||
collector.Empty();
|
||||
collector.Append( item );
|
||||
}
|
||||
if( collector.m_MenuCancelled )
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !m_additive && !m_subtractive && !m_exclusive_or )
|
||||
|
@ -289,18 +265,6 @@ bool GERBVIEW_SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere, bool aOnDrag
|
|||
}
|
||||
|
||||
|
||||
bool GERBVIEW_SELECTION_TOOL::selectCursor( bool aSelectAlways )
|
||||
{
|
||||
if( aSelectAlways || m_selection.Empty() )
|
||||
{
|
||||
clearSelection();
|
||||
selectPoint( getViewControls()->GetCursorPosition( false ) );
|
||||
}
|
||||
|
||||
return !m_selection.Empty();
|
||||
}
|
||||
|
||||
|
||||
void GERBVIEW_SELECTION_TOOL::setTransitions()
|
||||
{
|
||||
Go( &GERBVIEW_SELECTION_TOOL::UpdateMenu, ACTIONS::updateMenu.MakeEvent() );
|
||||
|
@ -402,93 +366,6 @@ void GERBVIEW_SELECTION_TOOL::clearSelection()
|
|||
}
|
||||
|
||||
|
||||
EDA_ITEM* GERBVIEW_SELECTION_TOOL::disambiguationMenu( GERBER_COLLECTOR* aCollector )
|
||||
{
|
||||
EDA_ITEM* current = nullptr;
|
||||
KIGFX::VIEW_GROUP highlightGroup;
|
||||
ACTION_MENU menu( true );
|
||||
|
||||
highlightGroup.SetLayer( LAYER_SELECT_OVERLAY );
|
||||
getView()->Add( &highlightGroup );
|
||||
|
||||
int limit = std::min( 10, aCollector->GetCount() );
|
||||
|
||||
for( int i = 0; i < limit; ++i )
|
||||
{
|
||||
wxString text;
|
||||
EDA_ITEM* item = ( *aCollector )[i];
|
||||
text = item->GetSelectMenuText( m_frame->GetUserUnits() );
|
||||
menu.Add( text, i + 1, item->GetMenuImage() );
|
||||
}
|
||||
|
||||
if( aCollector->m_MenuTitle.Length() )
|
||||
{
|
||||
menu.SetTitle( aCollector->m_MenuTitle );
|
||||
menu.SetIcon( BITMAPS::info );
|
||||
menu.DisplayTitle( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
menu.DisplayTitle( false );
|
||||
}
|
||||
|
||||
SetContextMenu( &menu, CMENU_NOW );
|
||||
|
||||
while( TOOL_EVENT* evt = Wait() )
|
||||
{
|
||||
if( evt->Action() == TA_CHOICE_MENU_UPDATE )
|
||||
{
|
||||
if( current )
|
||||
{
|
||||
current->ClearBrightened();
|
||||
getView()->Hide( current, false );
|
||||
highlightGroup.Remove( current );
|
||||
getView()->MarkTargetDirty( KIGFX::TARGET_OVERLAY );
|
||||
}
|
||||
|
||||
int id = *evt->GetCommandId();
|
||||
|
||||
// User has pointed an item, so show it in a different way
|
||||
if( id > 0 && id <= limit )
|
||||
{
|
||||
current = ( *aCollector )[id - 1];
|
||||
current->SetBrightened();
|
||||
getView()->Hide( current, true );
|
||||
highlightGroup.Add( current );
|
||||
getView()->MarkTargetDirty( KIGFX::TARGET_OVERLAY );
|
||||
}
|
||||
else
|
||||
{
|
||||
current = nullptr;
|
||||
}
|
||||
}
|
||||
else if( evt->Action() == TA_CHOICE_MENU_CHOICE )
|
||||
{
|
||||
OPT<int> id = evt->GetCommandId();
|
||||
|
||||
// User has selected an item, so this one will be returned
|
||||
if( id && ( *id > 0 ) )
|
||||
current = ( *aCollector )[*id - 1];
|
||||
else
|
||||
current = nullptr;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( current && current->IsBrightened() )
|
||||
{
|
||||
current->ClearBrightened();
|
||||
getView()->Hide( current, false );
|
||||
getView()->MarkTargetDirty( KIGFX::TARGET_OVERLAY );
|
||||
}
|
||||
|
||||
getView()->Remove( &highlightGroup );
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
|
||||
bool GERBVIEW_SELECTION_TOOL::selectable( const EDA_ITEM* aItem ) const
|
||||
{
|
||||
GERBVIEW_FRAME* frame = getEditFrame<GERBVIEW_FRAME>();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017 Jon Evans <jon@craftyjon.com>
|
||||
* Copyright (C) 2017-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2017-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* 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
|
||||
|
@ -43,7 +43,7 @@ namespace KIGFX
|
|||
/**
|
||||
* Selection tool for GerbView, based on the one in Pcbnew
|
||||
*/
|
||||
class GERBVIEW_SELECTION_TOOL : public SELECTION_TOOL, public TOOL_INTERACTIVE
|
||||
class GERBVIEW_SELECTION_TOOL : public SELECTION_TOOL
|
||||
{
|
||||
public:
|
||||
GERBVIEW_SELECTION_TOOL();
|
||||
|
@ -55,9 +55,6 @@ public:
|
|||
/// @copydoc TOOL_BASE::Reset()
|
||||
void Reset( RESET_REASON aReason ) override;
|
||||
|
||||
// called to rebuild a CONDITIONAL_MENU before opening it:
|
||||
int UpdateMenu( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* The main loop.
|
||||
*/
|
||||
|
@ -79,40 +76,24 @@ public:
|
|||
///< Sets up handlers for various events.
|
||||
void setTransitions() override;
|
||||
|
||||
protected:
|
||||
SELECTION& selection() override { return m_selection; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* Select an item pointed by the parameter aWhere. If there is more than one item at that
|
||||
* place, there is a menu displayed that allows one to choose the item.
|
||||
*
|
||||
* @param aWhere is the place where the item should be selected.
|
||||
* @param aAllowDisambiguation decides what to do in case of disambiguation. If true, then
|
||||
* a menu is shown, otherwise function finishes without selecting anything.
|
||||
* @return True if an item was selected, false otherwise.
|
||||
*/
|
||||
bool selectPoint( const VECTOR2I& aWhere, bool aOnDrag = false );
|
||||
|
||||
/**
|
||||
* Select an item under the cursor unless there is something already selected or
|
||||
* \a aSelectAlways is true.
|
||||
*
|
||||
* @param aSelectAlways forces to select an item even if there is an item already selected.
|
||||
* @return true if eventually there is an item selected, false otherwise.
|
||||
*/
|
||||
bool selectCursor( bool aSelectAlways = false );
|
||||
bool selectPoint( const VECTOR2I& aWhere );
|
||||
|
||||
/**
|
||||
* Clear the current selection.
|
||||
*/
|
||||
void clearSelection();
|
||||
|
||||
/**
|
||||
* Handle the menu that allows one to select one of many items in case
|
||||
* there is more than one item at the selected point (@see selectCursor()).
|
||||
*
|
||||
* @param aItems contains list of items that are displayed to the user.
|
||||
*/
|
||||
EDA_ITEM* disambiguationMenu( GERBER_COLLECTOR* aItems );
|
||||
|
||||
/**
|
||||
* Check conditions for an item to be selected.
|
||||
*
|
||||
|
@ -125,14 +106,14 @@ private:
|
|||
*
|
||||
* @param aItem is an item to be selected.
|
||||
*/
|
||||
void select( EDA_ITEM* aItem );
|
||||
void select( EDA_ITEM* aItem ) override;
|
||||
|
||||
/**
|
||||
* Take necessary action mark an item as unselected.
|
||||
*
|
||||
* @param aItem is an item to be unselected.
|
||||
*/
|
||||
void unselect( EDA_ITEM* aItem );
|
||||
void unselect( EDA_ITEM* aItem ) override;
|
||||
|
||||
/**
|
||||
* Mark item as selected, but does not add it to the #ITEMS_PICKED_LIST.
|
||||
|
@ -148,10 +129,33 @@ private:
|
|||
*/
|
||||
void unselectVisually( EDA_ITEM* aItem );
|
||||
|
||||
GERBVIEW_FRAME* m_frame; // Pointer to the parent frame.
|
||||
GERBVIEW_SELECTION m_selection; // Current state of selection.
|
||||
/**
|
||||
* Highlight the item visually.
|
||||
*
|
||||
* @param aItem is an item to be be highlighted.
|
||||
* @param aHighlightMode should be either SELECTED or BRIGHTENED
|
||||
* @param aGroup is the group to add the item to in the BRIGHTENED mode.
|
||||
*/
|
||||
void highlight( EDA_ITEM* aItem, int aHighlightMode, SELECTION* aGroup = nullptr ) override
|
||||
{
|
||||
// Currently not used in GerbView
|
||||
};
|
||||
|
||||
bool m_preliminary; // Determines if the selection is preliminary or final.
|
||||
/**
|
||||
* Unhighlight the item visually.
|
||||
*
|
||||
* @param aItem is an item to be be highlighted.
|
||||
* @param aHighlightMode should be either SELECTED or BRIGHTENED
|
||||
* @param aGroup is the group to remove the item from.
|
||||
*/
|
||||
void unhighlight( EDA_ITEM* aItem, int aHighlightMode, SELECTION* aGroup = nullptr ) override
|
||||
{
|
||||
// Currently not used in GerbView
|
||||
};
|
||||
|
||||
private:
|
||||
GERBVIEW_FRAME* m_frame; // Pointer to the parent frame.
|
||||
GERBVIEW_SELECTION m_selection; // Current state of selection.
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 KiCad Developers, see AUTHORS.TXT for contributors.
|
||||
* Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.TXT for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -29,14 +29,87 @@
|
|||
#include <tool/tool_interactive.h>
|
||||
#include <wx/timer.h>
|
||||
|
||||
class SELECTION_TOOL : public wxEvtHandler
|
||||
class COLLECTOR;
|
||||
|
||||
|
||||
class SELECTION_TOOL : public TOOL_INTERACTIVE, public wxEvtHandler
|
||||
{
|
||||
public:
|
||||
SELECTION_TOOL();
|
||||
SELECTION_TOOL( const std::string& aName );
|
||||
~SELECTION_TOOL(){};
|
||||
|
||||
/**
|
||||
* Update a menu's state based on the current selection. The menu is passed in aEvent's
|
||||
* parameter.
|
||||
*/
|
||||
int UpdateMenu( const TOOL_EVENT& aEvent );
|
||||
|
||||
int AddItemToSel( const TOOL_EVENT& aEvent );
|
||||
void AddItemToSel( EDA_ITEM* aItem, bool aQuietMode = false );
|
||||
int AddItemsToSel( const TOOL_EVENT& aEvent );
|
||||
void AddItemsToSel( EDA_ITEMS* aList, bool aQuietMode = false );
|
||||
|
||||
int RemoveItemFromSel( const TOOL_EVENT& aEvent );
|
||||
void RemoveItemFromSel( EDA_ITEM* aItem, bool aQuietMode = false );
|
||||
int RemoveItemsFromSel( const TOOL_EVENT& aEvent );
|
||||
void RemoveItemsFromSel( EDA_ITEMS* aList, bool aQuietMode = false );
|
||||
|
||||
/**
|
||||
* A safer version of RemoveItemsFromSel( EDA_ITEMS ) which doesn't require the items to
|
||||
* still exist.
|
||||
*/
|
||||
void RemoveItemsFromSel( std::vector<KIID>* aList, bool aQuietMode = false );
|
||||
|
||||
void BrightenItem( EDA_ITEM* aItem );
|
||||
void UnbrightenItem( EDA_ITEM* aItem );
|
||||
|
||||
/**
|
||||
* Show a popup menu to trim the COLLECTOR passed as aEvent's parameter down to a single
|
||||
* item.
|
||||
*
|
||||
* @note This routine **does not** modify the selection.
|
||||
*/
|
||||
int SelectionMenu( const TOOL_EVENT& aEvent );
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Return a reference to the selection.
|
||||
*/
|
||||
virtual SELECTION& selection() = 0;
|
||||
|
||||
/**
|
||||
* Start the process to show our disambiguation menu once the user has kept the mouse down
|
||||
* for the minimum time.
|
||||
* @param aEvent
|
||||
*/
|
||||
void onDisambiguationExpire( wxTimerEvent& aEvent );
|
||||
|
||||
/**
|
||||
* Take necessary action mark an item as selected.
|
||||
*/
|
||||
virtual void select( EDA_ITEM* aItem ) = 0;
|
||||
|
||||
/**
|
||||
* Take necessary action mark an item as unselected.
|
||||
*/
|
||||
virtual void unselect( EDA_ITEM* aItem ) = 0;
|
||||
|
||||
/**
|
||||
* Highlight the item visually.
|
||||
*
|
||||
* @param aHighlightMode should be either SELECTED or BRIGHTENED
|
||||
* @param aGroup is the group to add the item to in the BRIGHTENED mode.
|
||||
*/
|
||||
virtual void highlight( EDA_ITEM* aItem, int aHighlightMode, SELECTION* aGroup = nullptr ) = 0;
|
||||
|
||||
/**
|
||||
* Unhighlight the item visually.
|
||||
*
|
||||
* @param aHighlightMode should be either SELECTED or BRIGHTENED
|
||||
* @param aGroup is the group to remove the item from.
|
||||
*/
|
||||
virtual void unhighlight( EDA_ITEM* aItem, int aHighlightMode, SELECTION* aGroup = nullptr ) = 0;
|
||||
|
||||
/**
|
||||
* Set the configuration of m_additive, m_subtractive, m_exclusive_or, m_skip_heuristics
|
||||
* from the state of modifier keys SHIFT, CTRL, ALT and depending on the OS
|
||||
|
@ -48,6 +121,9 @@ protected:
|
|||
*/
|
||||
virtual bool ctrlClickHighlights() { return false; }
|
||||
|
||||
bool doSelectionMenu( COLLECTOR* aCollector );
|
||||
|
||||
protected:
|
||||
bool m_additive; // Items should be added to sel (instead of replacing)
|
||||
bool m_subtractive; // Items should be removed from sel
|
||||
bool m_exclusive_or; // Items' selection state should be toggled
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 CERN
|
||||
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -23,7 +23,6 @@
|
|||
*/
|
||||
|
||||
|
||||
#include <bitmaps.h>
|
||||
#include <view/view.h>
|
||||
#include <view/view_controls.h>
|
||||
#include <preview_items/selection_area.h>
|
||||
|
@ -41,16 +40,12 @@
|
|||
|
||||
#include "pl_editor_frame.h"
|
||||
|
||||
/**
|
||||
* The maximum number of items in the clarify selection context menu. The current
|
||||
* setting of 40 is arbitrary.
|
||||
*/
|
||||
#define MAX_SELECT_ITEM_IDS 40
|
||||
|
||||
#define HITTEST_THRESHOLD_PIXELS 3
|
||||
|
||||
|
||||
PL_SELECTION_TOOL::PL_SELECTION_TOOL() :
|
||||
TOOL_INTERACTIVE( "plEditor.InteractiveSelection" ),
|
||||
SELECTION_TOOL( "plEditor.InteractiveSelection" ),
|
||||
m_frame( nullptr )
|
||||
{
|
||||
}
|
||||
|
@ -85,21 +80,6 @@ void PL_SELECTION_TOOL::Reset( RESET_REASON aReason )
|
|||
}
|
||||
|
||||
|
||||
int PL_SELECTION_TOOL::UpdateMenu( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
ACTION_MENU* actionMenu = aEvent.Parameter<ACTION_MENU*>();
|
||||
CONDITIONAL_MENU* conditionalMenu = dynamic_cast<CONDITIONAL_MENU*>( actionMenu );
|
||||
|
||||
if( conditionalMenu )
|
||||
conditionalMenu->Evaluate( m_selection );
|
||||
|
||||
if( actionMenu )
|
||||
actionMenu->UpdateAll();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int PL_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
// Main loop: keep receiving events
|
||||
|
@ -248,12 +228,6 @@ int PL_SELECTION_TOOL::disambiguateCursor( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
void PL_SELECTION_TOOL::onDisambiguationExpire( wxTimerEvent& aEvent )
|
||||
{
|
||||
m_toolMgr->ProcessEvent( EVENTS::DisambiguatePoint );
|
||||
}
|
||||
|
||||
|
||||
PL_SELECTION& PL_SELECTION_TOOL::GetSelection()
|
||||
{
|
||||
return m_selection;
|
||||
|
@ -280,9 +254,7 @@ void PL_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere, bool* aSelectionCan
|
|||
|
||||
// Apply some ugly heuristics to avoid disambiguation menus whenever possible
|
||||
if( collector.GetCount() > 1 && !m_skip_heuristics )
|
||||
{
|
||||
guessSelectionCandidates( collector, aWhere );
|
||||
}
|
||||
|
||||
// If still more than one item we're going to have to ask the user.
|
||||
if( collector.GetCount() > 1 )
|
||||
|
@ -386,8 +358,8 @@ bool PL_SELECTION_TOOL::selectMultiple()
|
|||
*/
|
||||
bool windowSelection = width >= 0 ? true : false;
|
||||
|
||||
m_frame->GetCanvas()->SetCurrentCursor(
|
||||
windowSelection ? KICURSOR::SELECT_WINDOW : KICURSOR::SELECT_LASSO );
|
||||
m_frame->GetCanvas()->SetCurrentCursor( windowSelection ? KICURSOR::SELECT_WINDOW
|
||||
: KICURSOR::SELECT_LASSO );
|
||||
|
||||
if( evt->IsCancelInteractive() || evt->IsActivate() )
|
||||
{
|
||||
|
@ -473,100 +445,6 @@ bool PL_SELECTION_TOOL::selectMultiple()
|
|||
}
|
||||
|
||||
|
||||
int PL_SELECTION_TOOL::AddItemToSel( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
AddItemToSel( aEvent.Parameter<EDA_ITEM*>() );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void PL_SELECTION_TOOL::AddItemToSel( EDA_ITEM* aItem, bool aQuietMode )
|
||||
{
|
||||
if( aItem )
|
||||
{
|
||||
select( aItem );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
if( !aQuietMode )
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int PL_SELECTION_TOOL::AddItemsToSel( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
AddItemsToSel( aEvent.Parameter<EDA_ITEMS*>(), false );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void PL_SELECTION_TOOL::AddItemsToSel( EDA_ITEMS* aList, bool aQuietMode )
|
||||
{
|
||||
if( aList )
|
||||
{
|
||||
for( EDA_ITEM* item : *aList )
|
||||
select( item );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
if( !aQuietMode )
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int PL_SELECTION_TOOL::RemoveItemFromSel( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
RemoveItemFromSel( aEvent.Parameter<EDA_ITEM*>() );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void PL_SELECTION_TOOL::RemoveItemFromSel( EDA_ITEM* aItem, bool aQuietMode )
|
||||
{
|
||||
if( aItem )
|
||||
{
|
||||
unselect( aItem );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
if( !aQuietMode )
|
||||
m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int PL_SELECTION_TOOL::RemoveItemsFromSel( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
RemoveItemsFromSel( aEvent.Parameter<EDA_ITEMS*>(), false );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void PL_SELECTION_TOOL::RemoveItemsFromSel( EDA_ITEMS* aList, bool aQuietMode )
|
||||
{
|
||||
if( aList )
|
||||
{
|
||||
for( EDA_ITEM* item : *aList )
|
||||
unselect( item );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
if( !aQuietMode )
|
||||
m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PL_SELECTION_TOOL::BrightenItem( EDA_ITEM* aItem )
|
||||
{
|
||||
highlight( aItem, BRIGHTENED );
|
||||
}
|
||||
|
||||
|
||||
void PL_SELECTION_TOOL::UnbrightenItem( EDA_ITEM* aItem )
|
||||
{
|
||||
unhighlight( aItem, BRIGHTENED );
|
||||
}
|
||||
|
||||
|
||||
int PL_SELECTION_TOOL::ClearSelection( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
ClearSelection();
|
||||
|
@ -589,160 +467,13 @@ void PL_SELECTION_TOOL::RebuildSelection()
|
|||
}
|
||||
|
||||
|
||||
int PL_SELECTION_TOOL::SelectionMenu( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
COLLECTOR* collector = aEvent.Parameter<COLLECTOR*>();
|
||||
|
||||
if( !doSelectionMenu( collector ) )
|
||||
collector->m_MenuCancelled = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool PL_SELECTION_TOOL::doSelectionMenu( COLLECTOR* aCollector )
|
||||
{
|
||||
EDA_ITEM* current = nullptr;
|
||||
ACTION_MENU menu( true );
|
||||
|
||||
// ID limit is `MAX_SELECT_ITEM_IDS+1` because the last item is "select all"
|
||||
// and the first item has ID of 1.
|
||||
int limit = std::min( MAX_SELECT_ITEM_IDS + 1, aCollector->GetCount() );
|
||||
|
||||
for( int i = 0; i < limit; ++i )
|
||||
{
|
||||
wxString text;
|
||||
EDA_ITEM* item = ( *aCollector )[i];
|
||||
text = item->GetSelectMenuText( m_frame->GetUserUnits() );
|
||||
|
||||
wxString menuText = wxString::Format( "&%d. %s\t%d", i + 1, text, i + 1 );
|
||||
menu.Add( menuText, i + 1, item->GetMenuImage() );
|
||||
}
|
||||
|
||||
menu.AppendSeparator();
|
||||
menu.Add( _( "Select &All\tA" ), limit + 1, BITMAPS::INVALID_BITMAP );
|
||||
|
||||
if( aCollector->m_MenuTitle.Length() )
|
||||
{
|
||||
menu.SetTitle( aCollector->m_MenuTitle );
|
||||
menu.SetIcon( BITMAPS::info );
|
||||
menu.DisplayTitle( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
menu.DisplayTitle( false );
|
||||
}
|
||||
|
||||
SetContextMenu( &menu, CMENU_NOW );
|
||||
|
||||
bool selectAll = false;
|
||||
|
||||
while( TOOL_EVENT* evt = Wait() )
|
||||
{
|
||||
if( evt->Action() == TA_CHOICE_MENU_UPDATE )
|
||||
{
|
||||
if( selectAll )
|
||||
{
|
||||
for( int i = 0; i < aCollector->GetCount(); ++i )
|
||||
unhighlight( ( *aCollector )[i], BRIGHTENED );
|
||||
}
|
||||
else if( current )
|
||||
{
|
||||
unhighlight( current, BRIGHTENED );
|
||||
}
|
||||
|
||||
int id = *evt->GetCommandId();
|
||||
|
||||
// User has pointed an item, so show it in a different way
|
||||
if( id > 0 && id <= limit )
|
||||
{
|
||||
current = ( *aCollector )[id - 1];
|
||||
highlight( current, BRIGHTENED );
|
||||
}
|
||||
else
|
||||
{
|
||||
current = nullptr;
|
||||
}
|
||||
|
||||
if( id == limit + 1 )
|
||||
{
|
||||
for( int i = 0; i < aCollector->GetCount(); ++i )
|
||||
highlight( ( *aCollector )[i], BRIGHTENED );
|
||||
|
||||
selectAll = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
selectAll = false;
|
||||
}
|
||||
}
|
||||
else if( evt->Action() == TA_CHOICE_MENU_CHOICE )
|
||||
{
|
||||
if( selectAll )
|
||||
{
|
||||
for( int i = 0; i < aCollector->GetCount(); ++i )
|
||||
unhighlight( ( *aCollector )[i], BRIGHTENED );
|
||||
}
|
||||
else if( current )
|
||||
{
|
||||
unhighlight( current, BRIGHTENED );
|
||||
}
|
||||
|
||||
OPT<int> id = evt->GetCommandId();
|
||||
|
||||
// User has selected an item, so this one will be returned
|
||||
if( id == limit + 1 )
|
||||
{
|
||||
selectAll = true;
|
||||
current = nullptr;
|
||||
}
|
||||
else if( id && ( *id > 0 ) && ( *id <= limit ) )
|
||||
{
|
||||
selectAll = false;
|
||||
current = ( *aCollector )[*id - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
selectAll = false;
|
||||
current = nullptr;
|
||||
}
|
||||
}
|
||||
else if( evt->Action() == TA_CHOICE_MENU_CLOSED )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
getView()->UpdateItems();
|
||||
m_frame->GetCanvas()->Refresh();
|
||||
}
|
||||
|
||||
if( selectAll )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if( current )
|
||||
{
|
||||
unhighlight( current, BRIGHTENED );
|
||||
|
||||
getView()->UpdateItems();
|
||||
m_frame->GetCanvas()->Refresh();
|
||||
|
||||
aCollector->Empty();
|
||||
aCollector->Append( current );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void PL_SELECTION_TOOL::ClearSelection()
|
||||
{
|
||||
if( m_selection.Empty() )
|
||||
return;
|
||||
|
||||
while( m_selection.GetSize() )
|
||||
unhighlight( (EDA_ITEM*) m_selection.Front(), SELECTED, &m_selection );
|
||||
unhighlight( m_selection.Front(), SELECTED, &m_selection );
|
||||
|
||||
getView()->Update( &m_selection );
|
||||
|
||||
|
@ -766,7 +497,7 @@ void PL_SELECTION_TOOL::unselect( EDA_ITEM* aItem )
|
|||
}
|
||||
|
||||
|
||||
void PL_SELECTION_TOOL::highlight( EDA_ITEM* aItem, int aMode, PL_SELECTION* aGroup )
|
||||
void PL_SELECTION_TOOL::highlight( EDA_ITEM* aItem, int aMode, SELECTION* aGroup )
|
||||
{
|
||||
if( aMode == SELECTED )
|
||||
aItem->SetSelected();
|
||||
|
@ -780,7 +511,7 @@ void PL_SELECTION_TOOL::highlight( EDA_ITEM* aItem, int aMode, PL_SELECTION* aGr
|
|||
}
|
||||
|
||||
|
||||
void PL_SELECTION_TOOL::unhighlight( EDA_ITEM* aItem, int aMode, PL_SELECTION* aGroup )
|
||||
void PL_SELECTION_TOOL::unhighlight( EDA_ITEM* aItem, int aMode, SELECTION* aGroup )
|
||||
{
|
||||
if( aMode == SELECTED )
|
||||
aItem->ClearSelected();
|
||||
|
@ -800,7 +531,7 @@ bool PL_SELECTION_TOOL::selectionContains( const VECTOR2I& aPoint ) const
|
|||
VECTOR2I margin = getView()->ToWorld( VECTOR2I( GRIP_MARGIN, GRIP_MARGIN ), false );
|
||||
|
||||
// Check if the point is located within any of the currently selected items bounding boxes
|
||||
for( auto item : m_selection )
|
||||
for( EDA_ITEM* item : m_selection )
|
||||
{
|
||||
BOX2I itemBox = item->ViewBBox();
|
||||
itemBox.Inflate( margin.x, margin.y ); // Give some margin for gripping an item
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 CERN
|
||||
* Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -40,7 +40,7 @@ namespace KIGFX
|
|||
}
|
||||
|
||||
|
||||
class PL_SELECTION_TOOL : public SELECTION_TOOL, public TOOL_INTERACTIVE
|
||||
class PL_SELECTION_TOOL : public SELECTION_TOOL
|
||||
{
|
||||
public:
|
||||
PL_SELECTION_TOOL();
|
||||
|
@ -52,8 +52,6 @@ public:
|
|||
/// @copydoc TOOL_INTERACTIVE::Reset()
|
||||
void Reset( RESET_REASON aReason ) override;
|
||||
|
||||
int UpdateMenu( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* The main loop.
|
||||
*/
|
||||
|
@ -81,19 +79,6 @@ public:
|
|||
*/
|
||||
void SelectPoint( const VECTOR2I& aWhere, bool* aSelectionCancelledFlag = nullptr );
|
||||
|
||||
int AddItemToSel( const TOOL_EVENT& aEvent );
|
||||
void AddItemToSel( EDA_ITEM* aItem, bool aQuietMode = false );
|
||||
int AddItemsToSel( const TOOL_EVENT& aEvent );
|
||||
void AddItemsToSel( EDA_ITEMS* aList, bool aQuietMode = false );
|
||||
|
||||
int RemoveItemFromSel( const TOOL_EVENT& aEvent );
|
||||
void RemoveItemFromSel( EDA_ITEM* aItem, bool aQuietMode = false );
|
||||
int RemoveItemsFromSel( const TOOL_EVENT& aEvent );
|
||||
void RemoveItemsFromSel( EDA_ITEMS* aList, bool aQuietMode = false );
|
||||
|
||||
void BrightenItem( EDA_ITEM* aItem );
|
||||
void UnbrightenItem( EDA_ITEM* aItem );
|
||||
|
||||
int ClearSelection( const TOOL_EVENT& aEvent );
|
||||
void ClearSelection();
|
||||
|
||||
|
@ -103,13 +88,8 @@ public:
|
|||
*/
|
||||
void RebuildSelection();
|
||||
|
||||
/**
|
||||
* Shows a popup menu to trim the COLLECTOR passed as aEvent's parameter down to a single
|
||||
* item.
|
||||
*
|
||||
* @note This routine **does not** modify the selection.
|
||||
*/
|
||||
int SelectionMenu( const TOOL_EVENT& aEvent );
|
||||
protected:
|
||||
SELECTION& selection() override { return m_selection; }
|
||||
|
||||
private:
|
||||
/**
|
||||
|
@ -125,22 +105,6 @@ private:
|
|||
*/
|
||||
void guessSelectionCandidates( COLLECTOR& collector, const VECTOR2I& aWhere );
|
||||
|
||||
/**
|
||||
* Allow the selection of a single item from a list via pop-up menu. The items are
|
||||
* highlighted on the canvas when hovered in the menu. The collector is trimmed to
|
||||
* the picked item.
|
||||
*
|
||||
* @return true if an item was picked.
|
||||
*/
|
||||
bool doSelectionMenu( COLLECTOR* aItems );
|
||||
|
||||
/**
|
||||
* Start the process to show our disambiguation menu once the user has kept
|
||||
* the mouse down for the minimum time
|
||||
* @param aEvent
|
||||
*/
|
||||
void onDisambiguationExpire( wxTimerEvent& aEvent );
|
||||
|
||||
/**
|
||||
* Handle disambiguation actions including displaying the menu.
|
||||
*/
|
||||
|
@ -151,14 +115,14 @@ private:
|
|||
*
|
||||
* @param aItem is an item to be selected.
|
||||
*/
|
||||
void select( EDA_ITEM* aItem );
|
||||
void select( EDA_ITEM* aItem ) override;
|
||||
|
||||
/**
|
||||
* Take necessary action mark an item as unselected.
|
||||
*
|
||||
* @param aItem is an item to be unselected.
|
||||
*/
|
||||
void unselect( EDA_ITEM* aItem );
|
||||
void unselect( EDA_ITEM* aItem ) override;
|
||||
|
||||
/**
|
||||
* Highlight the item visually.
|
||||
|
@ -167,7 +131,7 @@ private:
|
|||
* @param aHighlightMode should be either SELECTED or BRIGHTENED
|
||||
* @param aGroup is the group to add the item to in the BRIGHTENED mode.
|
||||
*/
|
||||
void highlight( EDA_ITEM* aItem, int aHighlightMode, PL_SELECTION* aGroup = nullptr );
|
||||
void highlight( EDA_ITEM* aItem, int aHighlightMode, SELECTION* aGroup = nullptr ) override;
|
||||
|
||||
/**
|
||||
* Unhighlight the item visually.
|
||||
|
@ -176,7 +140,7 @@ private:
|
|||
* @param aHighlightMode should be either SELECTED or BRIGHTENED
|
||||
* @param aGroup is the group to remove the item from.
|
||||
*/
|
||||
void unhighlight( EDA_ITEM* aItem, int aHighlightMode, PL_SELECTION* aGroup = nullptr );
|
||||
void unhighlight( EDA_ITEM* aItem, int aHighlightMode, SELECTION* aGroup = nullptr ) override;
|
||||
|
||||
/**
|
||||
* @return True if the given point is contained in any of selected items' bounding box.
|
||||
|
|
|
@ -57,12 +57,12 @@ private:
|
|||
void update() override
|
||||
{
|
||||
PCB_SELECTION_TOOL* selTool = getToolManager()->GetTool<PCB_SELECTION_TOOL>();
|
||||
BOARD* board = selTool->GetBoard();
|
||||
BOARD* board = static_cast<BOARD*>( getToolManager()->GetModel() );
|
||||
|
||||
const auto& selection = selTool->GetSelection();
|
||||
|
||||
wxString check = board->GroupsSanityCheck();
|
||||
wxCHECK_RET( check == wxEmptyString, _( "Group is in inconsistent state:" ) + wxS( " " )+ check );
|
||||
wxCHECK_RET( check == wxEmptyString, _( "Group is in inconsistent state:" ) + wxS( " " ) + check );
|
||||
|
||||
BOARD::GroupLegalOpsField legalOps = board->GroupLegalOps( selection );
|
||||
|
||||
|
|
|
@ -51,7 +51,6 @@ using namespace std::placeholders;
|
|||
#include <preview_items/selection_area.h>
|
||||
#include <painter.h>
|
||||
#include <router/router_tool.h>
|
||||
#include <bitmaps.h>
|
||||
#include <pcbnew_settings.h>
|
||||
#include <tool/tool_event.h>
|
||||
#include <tool/tool_manager.h>
|
||||
|
@ -61,7 +60,6 @@ using namespace std::placeholders;
|
|||
#include <tools/pcb_actions.h>
|
||||
#include <connectivity/connectivity_data.h>
|
||||
#include <footprint_viewer_frame.h>
|
||||
#include <id.h>
|
||||
#include <wx/event.h>
|
||||
#include <wx/timer.h>
|
||||
#include <wx/log.h>
|
||||
|
@ -107,8 +105,9 @@ public:
|
|||
|
||||
|
||||
PCB_SELECTION_TOOL::PCB_SELECTION_TOOL() :
|
||||
PCB_TOOL_BASE( "pcbnew.InteractiveSelection" ),
|
||||
SELECTION_TOOL( "pcbnew.InteractiveSelection" ),
|
||||
m_frame( nullptr ),
|
||||
m_isFootprintEditor( false ),
|
||||
m_nonModifiedCursor( KICURSOR::ARROW ),
|
||||
m_enteredGroup( nullptr ),
|
||||
m_priv( std::make_unique<PRIV>() )
|
||||
|
@ -138,7 +137,7 @@ PCB_SELECTION_TOOL::~PCB_SELECTION_TOOL()
|
|||
|
||||
bool PCB_SELECTION_TOOL::Init()
|
||||
{
|
||||
auto frame = getEditFrame<PCB_BASE_FRAME>();
|
||||
PCB_BASE_FRAME* frame = getEditFrame<PCB_BASE_FRAME>();
|
||||
|
||||
if( frame && ( frame->IsType( FRAME_FOOTPRINT_VIEWER )
|
||||
|| frame->IsType( FRAME_FOOTPRINT_VIEWER_MODAL ) ) )
|
||||
|
@ -199,6 +198,7 @@ bool PCB_SELECTION_TOOL::Init()
|
|||
void PCB_SELECTION_TOOL::Reset( RESET_REASON aReason )
|
||||
{
|
||||
m_frame = getEditFrame<PCB_BASE_FRAME>();
|
||||
m_isFootprintEditor = m_frame->IsType( FRAME_FOOTPRINT_EDITOR );
|
||||
|
||||
if( m_enteredGroup )
|
||||
ExitGroup();
|
||||
|
@ -228,12 +228,6 @@ void PCB_SELECTION_TOOL::Reset( RESET_REASON aReason )
|
|||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::onDisambiguationExpire( wxTimerEvent& aEvent )
|
||||
{
|
||||
m_toolMgr->ProcessEvent( EVENTS::DisambiguatePoint );
|
||||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::OnIdle( wxIdleEvent& aEvent )
|
||||
{
|
||||
if( m_frame->ToolStackIsEmpty() && !m_multiple )
|
||||
|
@ -298,7 +292,9 @@ int PCB_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
|
||||
// Single click? Select single object
|
||||
if( m_highlight_modifier && brd_editor )
|
||||
{
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::highlightNet, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_frame->FocusOnItem( nullptr );
|
||||
|
@ -392,9 +388,11 @@ int PCB_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
ZONE* zone = static_cast<ZONE*>( item );
|
||||
|
||||
if( !zone->HitTestForCorner( location, accuracy * 2 ) &&
|
||||
!zone->HitTestForEdge( location, accuracy ) )
|
||||
if( !zone->HitTestForCorner( location, accuracy * 2 )
|
||||
&& !zone->HitTestForEdge( location, accuracy ) )
|
||||
{
|
||||
remove.insert( zone );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -561,7 +559,7 @@ PCB_SELECTION& PCB_SELECTION_TOOL::RequestSelection( CLIENT_SELECTION_FILTER aCl
|
|||
|
||||
for( std::pair<EDA_ITEM* const, DISPOSITION> itemDisposition : itemDispositions )
|
||||
{
|
||||
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( itemDisposition.first );
|
||||
EDA_ITEM* item = itemDisposition.first;
|
||||
DISPOSITION disposition = itemDisposition.second;
|
||||
|
||||
if( disposition == BEFORE )
|
||||
|
@ -570,7 +568,7 @@ PCB_SELECTION& PCB_SELECTION_TOOL::RequestSelection( CLIENT_SELECTION_FILTER aCl
|
|||
|
||||
for( std::pair<EDA_ITEM* const, DISPOSITION> itemDisposition : itemDispositions )
|
||||
{
|
||||
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( itemDisposition.first );
|
||||
EDA_ITEM* item = itemDisposition.first;
|
||||
DISPOSITION disposition = itemDisposition.second;
|
||||
|
||||
// Note that we must re-highlight even previously-highlighted items
|
||||
|
@ -975,30 +973,6 @@ int PCB_SELECTION_TOOL::ClearSelection( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
int PCB_SELECTION_TOOL::SelectItems( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
std::vector<BOARD_ITEM*>* items = aEvent.Parameter<std::vector<BOARD_ITEM*>*>();
|
||||
|
||||
if( items )
|
||||
{
|
||||
// Perform individual selection of each item before processing the event.
|
||||
for( BOARD_ITEM* item : *items )
|
||||
select( item );
|
||||
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int PCB_SELECTION_TOOL::SelectItem( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
AddItemToSel( aEvent.Parameter<BOARD_ITEM*>() );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int PCB_SELECTION_TOOL::SelectAll( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
KIGFX::VIEW* view = getView();
|
||||
|
@ -1028,7 +1002,7 @@ int PCB_SELECTION_TOOL::SelectAll( const TOOL_EVENT& aEvent )
|
|||
FilterCollectorForHierarchy( collection, true );
|
||||
|
||||
for( EDA_ITEM* item : collection )
|
||||
select( static_cast<BOARD_ITEM*>( item ) );
|
||||
select( item );
|
||||
|
||||
m_frame->GetCanvas()->ForceRefresh();
|
||||
|
||||
|
@ -1036,70 +1010,6 @@ int PCB_SELECTION_TOOL::SelectAll( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::AddItemToSel( BOARD_ITEM* aItem, bool aQuietMode )
|
||||
{
|
||||
if( aItem )
|
||||
{
|
||||
select( aItem );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
if( !aQuietMode )
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int PCB_SELECTION_TOOL::UnselectItems( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
std::vector<BOARD_ITEM*>* items = aEvent.Parameter<std::vector<BOARD_ITEM*>*>();
|
||||
|
||||
if( items )
|
||||
{
|
||||
// Perform individual unselection of each item before processing the event
|
||||
for( auto item : *items )
|
||||
unselect( item );
|
||||
|
||||
m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int PCB_SELECTION_TOOL::UnselectItem( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
RemoveItemFromSel( aEvent.Parameter<BOARD_ITEM*>() );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::RemoveItemFromSel( BOARD_ITEM* aItem, bool aQuietMode )
|
||||
{
|
||||
if( aItem )
|
||||
{
|
||||
unselect( aItem );
|
||||
|
||||
if( !aQuietMode )
|
||||
{
|
||||
// Inform other potentially interested tools
|
||||
m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::BrightenItem( BOARD_ITEM* aItem )
|
||||
{
|
||||
highlight( aItem, BRIGHTENED );
|
||||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::UnbrightenItem( BOARD_ITEM* aItem )
|
||||
{
|
||||
unhighlight( aItem, BRIGHTENED );
|
||||
}
|
||||
|
||||
|
||||
void connectedItemFilter( const VECTOR2I&, GENERAL_COLLECTOR& aCollector,
|
||||
PCB_SELECTION_TOOL* sTool )
|
||||
{
|
||||
|
@ -1110,6 +1020,7 @@ void connectedItemFilter( const VECTOR2I&, GENERAL_COLLECTOR& aCollector,
|
|||
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() ) )
|
||||
|
@ -1151,9 +1062,7 @@ int PCB_SELECTION_TOOL::expandConnection( const TOOL_EVENT& aEvent )
|
|||
FOOTPRINT* footprint = static_cast<FOOTPRINT*>( item );
|
||||
|
||||
for( PAD* pad : footprint->Pads() )
|
||||
{
|
||||
startItems.push_back( pad );
|
||||
}
|
||||
}
|
||||
else if( BOARD_CONNECTED_ITEM::ClassOf( item ) )
|
||||
{
|
||||
|
@ -2139,7 +2048,7 @@ void PCB_SELECTION_TOOL::ClearSelection( bool aQuietMode )
|
|||
return;
|
||||
|
||||
while( m_selection.GetSize() )
|
||||
unhighlight( static_cast<BOARD_ITEM*>( m_selection.Front() ), SELECTED, &m_selection );
|
||||
unhighlight( m_selection.Front(), SELECTED, &m_selection );
|
||||
|
||||
view()->Update( &m_selection );
|
||||
|
||||
|
@ -2172,7 +2081,7 @@ void PCB_SELECTION_TOOL::RebuildSelection()
|
|||
if( parent && parent->IsSelected() )
|
||||
return SEARCH_RESULT::CONTINUE;
|
||||
|
||||
highlight( (BOARD_ITEM*) item, SELECTED, &m_selection );
|
||||
highlight( item, SELECTED, &m_selection );
|
||||
}
|
||||
|
||||
if( item == m_enteredGroup )
|
||||
|
@ -2199,167 +2108,6 @@ void PCB_SELECTION_TOOL::RebuildSelection()
|
|||
}
|
||||
|
||||
|
||||
int PCB_SELECTION_TOOL::SelectionMenu( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
GENERAL_COLLECTOR* collector = aEvent.Parameter<GENERAL_COLLECTOR*>();
|
||||
|
||||
doSelectionMenu( collector );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool PCB_SELECTION_TOOL::doSelectionMenu( GENERAL_COLLECTOR* aCollector )
|
||||
{
|
||||
BOARD_ITEM* current = nullptr;
|
||||
PCB_SELECTION highlightGroup;
|
||||
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 )
|
||||
{
|
||||
wxString text;
|
||||
BOARD_ITEM* item = ( *aCollector )[i];
|
||||
text = item->GetSelectMenuText( m_frame->GetUserUnits() );
|
||||
|
||||
wxString menuText = wxString::Format( wxT( "&%d. %s\t%d" ), i + 1, text, i + 1 );
|
||||
menu.Add( menuText, i + 1, item->GetMenuImage() );
|
||||
}
|
||||
|
||||
menu.AppendSeparator();
|
||||
menu.Add( _( "Select &All\tA" ), limit + 1, BITMAPS::INVALID_BITMAP );
|
||||
|
||||
if( !expandSelection && aCollector->HasAdditionalItems() )
|
||||
menu.Add( _( "&Expand Selection\tE" ), limit + 2, BITMAPS::INVALID_BITMAP );
|
||||
|
||||
if( aCollector->m_MenuTitle.Length() )
|
||||
{
|
||||
menu.SetTitle( aCollector->m_MenuTitle );
|
||||
menu.SetIcon( BITMAPS::info );
|
||||
menu.DisplayTitle( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
menu.DisplayTitle( false );
|
||||
}
|
||||
|
||||
SetContextMenu( &menu, CMENU_NOW );
|
||||
|
||||
while( TOOL_EVENT* evt = Wait() )
|
||||
{
|
||||
if( evt->Action() == TA_CHOICE_MENU_UPDATE )
|
||||
{
|
||||
if( selectAll )
|
||||
{
|
||||
for( int i = 0; i < aCollector->GetCount(); ++i )
|
||||
unhighlight( ( *aCollector )[i], BRIGHTENED, &highlightGroup );
|
||||
}
|
||||
else if( current )
|
||||
{
|
||||
unhighlight( current, BRIGHTENED, &highlightGroup );
|
||||
}
|
||||
|
||||
int id = *evt->GetCommandId();
|
||||
|
||||
// User has pointed an item, so show it in a different way
|
||||
if( id > 0 && id <= limit )
|
||||
{
|
||||
current = ( *aCollector )[id - 1];
|
||||
highlight( current, BRIGHTENED, &highlightGroup );
|
||||
}
|
||||
else
|
||||
{
|
||||
current = nullptr;
|
||||
}
|
||||
|
||||
// User has pointed on the "Select All" option
|
||||
if( id == limit + 1 )
|
||||
{
|
||||
for( int i = 0; i < aCollector->GetCount(); ++i )
|
||||
highlight( ( *aCollector )[i], BRIGHTENED, &highlightGroup );
|
||||
selectAll = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
selectAll = false;
|
||||
}
|
||||
}
|
||||
else if( evt->Action() == TA_CHOICE_MENU_CHOICE )
|
||||
{
|
||||
if( selectAll )
|
||||
{
|
||||
for( int i = 0; i < aCollector->GetCount(); ++i )
|
||||
unhighlight( ( *aCollector )[i], BRIGHTENED, &highlightGroup );
|
||||
}
|
||||
else if( current )
|
||||
{
|
||||
unhighlight( current, BRIGHTENED, &highlightGroup );
|
||||
}
|
||||
|
||||
OPT<int> id = evt->GetCommandId();
|
||||
|
||||
// User has selected the "Select All" option
|
||||
if( id == limit + 1 )
|
||||
{
|
||||
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 ) )
|
||||
{
|
||||
selectAll = false;
|
||||
current = ( *aCollector )[*id - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
selectAll = false;
|
||||
current = nullptr;
|
||||
}
|
||||
}
|
||||
else if( evt->Action() == TA_CHOICE_MENU_CLOSED )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while( expandSelection );
|
||||
|
||||
getView()->Remove( &highlightGroup );
|
||||
|
||||
if( selectAll )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if( current )
|
||||
{
|
||||
aCollector->Empty();
|
||||
aCollector->Append( current );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool PCB_SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibilityOnly ) const
|
||||
{
|
||||
const RENDER_SETTINGS* settings = getView()->GetPainter()->GetSettings();
|
||||
|
@ -2606,7 +2354,7 @@ bool PCB_SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibili
|
|||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::select( BOARD_ITEM* aItem )
|
||||
void PCB_SELECTION_TOOL::select( EDA_ITEM* aItem )
|
||||
{
|
||||
if( aItem->IsSelected() )
|
||||
return;
|
||||
|
@ -2623,13 +2371,13 @@ void PCB_SELECTION_TOOL::select( BOARD_ITEM* aItem )
|
|||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::unselect( BOARD_ITEM* aItem )
|
||||
void PCB_SELECTION_TOOL::unselect( EDA_ITEM* aItem )
|
||||
{
|
||||
unhighlight( aItem, SELECTED, &m_selection );
|
||||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::highlight( BOARD_ITEM* aItem, int aMode, PCB_SELECTION* aGroup )
|
||||
void PCB_SELECTION_TOOL::highlight( EDA_ITEM* aItem, int aMode, SELECTION* aGroup )
|
||||
{
|
||||
if( aGroup )
|
||||
aGroup->Add( aItem );
|
||||
|
@ -2644,7 +2392,7 @@ void PCB_SELECTION_TOOL::highlight( BOARD_ITEM* aItem, int aMode, PCB_SELECTION*
|
|||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::highlightInternal( BOARD_ITEM* aItem, int aMode, bool aUsingOverlay )
|
||||
void PCB_SELECTION_TOOL::highlightInternal( EDA_ITEM* aItem, int aMode, bool aUsingOverlay )
|
||||
{
|
||||
if( aMode == SELECTED )
|
||||
aItem->SetSelected();
|
||||
|
@ -2673,7 +2421,7 @@ void PCB_SELECTION_TOOL::highlightInternal( BOARD_ITEM* aItem, int aMode, bool a
|
|||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::unhighlight( BOARD_ITEM* aItem, int aMode, PCB_SELECTION* aGroup )
|
||||
void PCB_SELECTION_TOOL::unhighlight( EDA_ITEM* aItem, int aMode, SELECTION* aGroup )
|
||||
{
|
||||
if( aGroup )
|
||||
aGroup->Remove( aItem );
|
||||
|
@ -2687,7 +2435,7 @@ void PCB_SELECTION_TOOL::unhighlight( BOARD_ITEM* aItem, int aMode, PCB_SELECTIO
|
|||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::unhighlightInternal( BOARD_ITEM* aItem, int aMode, bool aUsingOverlay )
|
||||
void PCB_SELECTION_TOOL::unhighlightInternal( EDA_ITEM* aItem, int aMode, bool aUsingOverlay )
|
||||
{
|
||||
if( aMode == SELECTED )
|
||||
aItem->ClearSelected();
|
||||
|
@ -3104,7 +2852,7 @@ void PCB_SELECTION_TOOL::FilterCollectorForFreePads( GENERAL_COLLECTOR& aCollect
|
|||
{
|
||||
BOARD_ITEM* item = aCollector[i];
|
||||
|
||||
if( !IsFootprintEditor() && item->Type() == PCB_PAD_T
|
||||
if( !m_isFootprintEditor && item->Type() == PCB_PAD_T
|
||||
&& !frame()->Settings().m_AllowFreePads )
|
||||
{
|
||||
if( !aCollector.HasItem( item->GetParent() ) )
|
||||
|
@ -3141,21 +2889,6 @@ int PCB_SELECTION_TOOL::updateSelection( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
int PCB_SELECTION_TOOL::UpdateMenu( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
ACTION_MENU* actionMenu = aEvent.Parameter<ACTION_MENU*>();
|
||||
CONDITIONAL_MENU* conditionalMenu = dynamic_cast<CONDITIONAL_MENU*>( actionMenu );
|
||||
|
||||
if( conditionalMenu )
|
||||
conditionalMenu->Evaluate( m_selection );
|
||||
|
||||
if( actionMenu )
|
||||
actionMenu->UpdateAll();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::setTransitions()
|
||||
{
|
||||
Go( &PCB_SELECTION_TOOL::UpdateMenu, ACTIONS::updateMenu.MakeEvent() );
|
||||
|
@ -3164,10 +2897,10 @@ void PCB_SELECTION_TOOL::setTransitions()
|
|||
Go( &PCB_SELECTION_TOOL::CursorSelection, PCB_ACTIONS::selectionCursor.MakeEvent() );
|
||||
Go( &PCB_SELECTION_TOOL::ClearSelection, PCB_ACTIONS::selectionClear.MakeEvent() );
|
||||
|
||||
Go( &PCB_SELECTION_TOOL::SelectItem, PCB_ACTIONS::selectItem.MakeEvent() );
|
||||
Go( &PCB_SELECTION_TOOL::SelectItems, PCB_ACTIONS::selectItems.MakeEvent() );
|
||||
Go( &PCB_SELECTION_TOOL::UnselectItem, PCB_ACTIONS::unselectItem.MakeEvent() );
|
||||
Go( &PCB_SELECTION_TOOL::UnselectItems, PCB_ACTIONS::unselectItems.MakeEvent() );
|
||||
Go( &PCB_SELECTION_TOOL::AddItemToSel, PCB_ACTIONS::selectItem.MakeEvent() );
|
||||
Go( &PCB_SELECTION_TOOL::AddItemsToSel, PCB_ACTIONS::selectItems.MakeEvent() );
|
||||
Go( &PCB_SELECTION_TOOL::RemoveItemFromSel, PCB_ACTIONS::unselectItem.MakeEvent() );
|
||||
Go( &PCB_SELECTION_TOOL::RemoveItemsFromSel, PCB_ACTIONS::unselectItems.MakeEvent() );
|
||||
Go( &PCB_SELECTION_TOOL::SelectionMenu, PCB_ACTIONS::selectionMenu.MakeEvent() );
|
||||
|
||||
Go( &PCB_SELECTION_TOOL::filterSelection, PCB_ACTIONS::filterSelection.MakeEvent() );
|
||||
|
|
|
@ -61,7 +61,7 @@ typedef void (*CLIENT_SELECTION_FILTER)( const VECTOR2I&, GENERAL_COLLECTOR&, PC
|
|||
* - takes into account high-contrast & layer visibility settings
|
||||
* - invokes InteractiveEdit tool when user starts to drag selected items
|
||||
*/
|
||||
class PCB_SELECTION_TOOL : public SELECTION_TOOL, public PCB_TOOL_BASE
|
||||
class PCB_SELECTION_TOOL : public SELECTION_TOOL
|
||||
{
|
||||
public:
|
||||
PCB_SELECTION_TOOL();
|
||||
|
@ -75,6 +75,11 @@ public:
|
|||
|
||||
void OnIdle( wxIdleEvent& aEvent );
|
||||
|
||||
bool IsFootprintEditor()
|
||||
{
|
||||
return m_isFootprintEditor;
|
||||
}
|
||||
|
||||
/**
|
||||
* The main loop.
|
||||
*/
|
||||
|
@ -103,26 +108,9 @@ public:
|
|||
int ClearSelection( const TOOL_EVENT& aEvent );
|
||||
void ClearSelection( bool aQuietMode = false );
|
||||
|
||||
///< Item selection event handler.
|
||||
int SelectItem( const TOOL_EVENT& aEvent );
|
||||
void AddItemToSel( BOARD_ITEM* aItem, bool aQuietMode = false );
|
||||
|
||||
///< Select all items on the board
|
||||
int SelectAll( const TOOL_EVENT& aEvent );
|
||||
|
||||
///< Multiple item selection event handler
|
||||
int SelectItems( const TOOL_EVENT& aEvent );
|
||||
|
||||
///< Item unselection event handler.
|
||||
int UnselectItem( const TOOL_EVENT& aEvent );
|
||||
void RemoveItemFromSel( BOARD_ITEM* aItem, bool aQuietMode = false );
|
||||
|
||||
///< Multiple item unselection event handler
|
||||
int UnselectItems( const TOOL_EVENT& aEvent );
|
||||
|
||||
void BrightenItem( BOARD_ITEM* aItem );
|
||||
void UnbrightenItem( BOARD_ITEM* aItem );
|
||||
|
||||
/**
|
||||
* Handle finding an item. Does not do the actual searching, is called
|
||||
* by the find dialog.
|
||||
|
@ -136,7 +124,7 @@ public:
|
|||
*
|
||||
* @param aItem is an item to be selected.
|
||||
*/
|
||||
void select( BOARD_ITEM* aItem );
|
||||
void select( EDA_ITEM* aItem ) override;
|
||||
|
||||
/**
|
||||
* Check conditions for an item to be selected.
|
||||
|
@ -154,14 +142,6 @@ public:
|
|||
*/
|
||||
void GuessSelectionCandidates( GENERAL_COLLECTOR& aCollector, const VECTOR2I& aWhere ) const;
|
||||
|
||||
/**
|
||||
* Show a popup menu to trim the COLLECTOR passed as aEvent's parameter down to a single
|
||||
* item.
|
||||
*
|
||||
* @note This routine **does not** modify the selection.
|
||||
*/
|
||||
int SelectionMenu( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Rebuild the selection from the EDA_ITEMs' selection flags.
|
||||
*
|
||||
|
@ -184,11 +164,6 @@ public:
|
|||
///< Zoom the screen to fit the bounding box for cross probing/selection sync.
|
||||
void zoomFitCrossProbeBBox( EDA_RECT bbox );
|
||||
|
||||
BOARD* GetBoard() const
|
||||
{
|
||||
return board();
|
||||
}
|
||||
|
||||
void EnterGroup();
|
||||
|
||||
/**
|
||||
|
@ -218,8 +193,35 @@ public:
|
|||
void FilterCollectedItems( GENERAL_COLLECTOR& aCollector, bool aMultiSelect );
|
||||
|
||||
protected:
|
||||
KIGFX::PCB_VIEW* view() const
|
||||
{
|
||||
return static_cast<KIGFX::PCB_VIEW*>( getView() );
|
||||
}
|
||||
|
||||
KIGFX::VIEW_CONTROLS* controls() const
|
||||
{
|
||||
return getViewControls();
|
||||
}
|
||||
|
||||
PCB_BASE_EDIT_FRAME* frame() const
|
||||
{
|
||||
return getEditFrame<PCB_BASE_EDIT_FRAME>();
|
||||
}
|
||||
|
||||
BOARD* board() const
|
||||
{
|
||||
return getModel<BOARD>();
|
||||
}
|
||||
|
||||
PCB_DRAW_PANEL_GAL* canvas() const
|
||||
{
|
||||
return static_cast<PCB_DRAW_PANEL_GAL*>( frame()->GetCanvas() );
|
||||
}
|
||||
|
||||
virtual bool ctrlClickHighlights() override;
|
||||
|
||||
SELECTION& selection() override { return m_selection; }
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
|
@ -258,23 +260,6 @@ private:
|
|||
*/
|
||||
bool selectMultiple();
|
||||
|
||||
/**
|
||||
* Allow the selection of a single item from a list via pop-up menu.
|
||||
*
|
||||
* The items are highlighted on the canvas when hovered in the menu. The collector is
|
||||
* trimmed to the picked item.
|
||||
*
|
||||
* @return true if an item was picked
|
||||
*/
|
||||
bool doSelectionMenu( GENERAL_COLLECTOR* aItems );
|
||||
|
||||
/**
|
||||
* Start the process to show our disambiguation menu once the user has kept
|
||||
* the mouse down for the minimum time
|
||||
* @param aEvent
|
||||
*/
|
||||
void onDisambiguationExpire( wxTimerEvent& aEvent );
|
||||
|
||||
/**
|
||||
* Handle disambiguation actions including displaying the menu.
|
||||
*/
|
||||
|
@ -357,7 +342,7 @@ private:
|
|||
*
|
||||
* @param aItem is an item to be unselected.
|
||||
*/
|
||||
void unselect( BOARD_ITEM* aItem );
|
||||
void unselect( EDA_ITEM* aItem ) override;
|
||||
|
||||
/**
|
||||
* Highlight the item visually.
|
||||
|
@ -366,7 +351,7 @@ private:
|
|||
* @param aHighlightMode should be either SELECTED or BRIGHTENED
|
||||
* @param aGroup is the group to add the item to in the BRIGHTENED mode.
|
||||
*/
|
||||
void highlight( BOARD_ITEM* aItem, int aHighlightMode, PCB_SELECTION* aGroup = nullptr );
|
||||
void highlight( EDA_ITEM* aItem, int aHighlightMode, SELECTION* aGroup = nullptr ) override;
|
||||
|
||||
/**
|
||||
* Unhighlight the item visually.
|
||||
|
@ -375,7 +360,7 @@ private:
|
|||
* @param aHighlightMode should be either SELECTED or BRIGHTENED
|
||||
* @param aGroup is the group to remove the item from.
|
||||
*/
|
||||
void unhighlight( BOARD_ITEM* aItem, int aHighlightMode, PCB_SELECTION* aGroup = nullptr );
|
||||
void unhighlight( EDA_ITEM* aItem, int aHighlightMode, SELECTION* aGroup = nullptr ) override;
|
||||
|
||||
/**
|
||||
* @return True if the given point is contained in any of selected items' bounding box.
|
||||
|
@ -389,20 +374,17 @@ private:
|
|||
*/
|
||||
int updateSelection( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Pass the selection to a conditional menu for updating.
|
||||
*/
|
||||
int UpdateMenu( const TOOL_EVENT& aEvent );
|
||||
|
||||
const GENERAL_COLLECTORS_GUIDE getCollectorsGuide() const;
|
||||
|
||||
private:
|
||||
void highlightInternal( BOARD_ITEM* aItem, int aHighlightMode, bool aUsingOverlay );
|
||||
void highlightInternal( EDA_ITEM* aItem, int aHighlightMode, bool aUsingOverlay );
|
||||
|
||||
void unhighlightInternal( BOARD_ITEM* aItem, int aHighlightMode, bool aUsingOverlay );
|
||||
void unhighlightInternal( EDA_ITEM* aItem, int aHighlightMode, bool aUsingOverlay );
|
||||
|
||||
private:
|
||||
PCB_BASE_FRAME* m_frame; // Pointer to the parent frame
|
||||
bool m_isFootprintEditor;
|
||||
|
||||
PCB_SELECTION m_selection; // Current state of selection
|
||||
|
||||
SELECTION_FILTER_OPTIONS m_filter;
|
||||
|
|
|
@ -191,7 +191,7 @@ public:
|
|||
|
||||
|
||||
PCB_SELECTION_TOOL::PCB_SELECTION_TOOL() :
|
||||
PCB_TOOL_BASE( "pcbnew.InteractiveSelection" ),
|
||||
SELECTION_TOOL( "pcbnew.InteractiveSelection" ),
|
||||
m_frame( NULL ),
|
||||
m_enteredGroup( NULL ),
|
||||
m_nonModifiedCursor( KICURSOR::ARROW ),
|
||||
|
@ -283,56 +283,12 @@ int PCB_SELECTION_TOOL::ClearSelection( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
int PCB_SELECTION_TOOL::SelectItems( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int PCB_SELECTION_TOOL::SelectItem( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int PCB_SELECTION_TOOL::SelectAll( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::AddItemToSel( BOARD_ITEM* aItem, bool aQuietMode )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int PCB_SELECTION_TOOL::UnselectItems( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int PCB_SELECTION_TOOL::UnselectItem( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::RemoveItemFromSel( BOARD_ITEM* aItem, bool aQuietMode )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::BrightenItem( BOARD_ITEM* aItem )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::UnbrightenItem( BOARD_ITEM* aItem )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int PCB_SELECTION_TOOL::expandConnection( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
return 0;
|
||||
|
@ -425,52 +381,12 @@ void PCB_SELECTION_TOOL::RebuildSelection()
|
|||
}
|
||||
|
||||
|
||||
int PCB_SELECTION_TOOL::SelectionMenu( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool PCB_SELECTION_TOOL::doSelectionMenu( GENERAL_COLLECTOR* aCollector )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool PCB_SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibilityOnly ) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::select( BOARD_ITEM* aItem )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::unselect( BOARD_ITEM* aItem )
|
||||
{
|
||||
}
|
||||
|
||||
void PCB_SELECTION_TOOL::highlight( BOARD_ITEM* aItem, int aMode, PCB_SELECTION* aGroup )
|
||||
{
|
||||
}
|
||||
|
||||
void PCB_SELECTION_TOOL::highlightInternal( BOARD_ITEM* aItem, int aMode, bool aUsingOverlay )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::unhighlight( BOARD_ITEM* aItem, int aMode, PCB_SELECTION* aGroup )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::unhighlightInternal( BOARD_ITEM* aItem, int aMode, bool aUsingOverlay )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool PCB_SELECTION_TOOL::selectionContains( const VECTOR2I& aPoint ) const
|
||||
{
|
||||
return false;
|
||||
|
@ -490,12 +406,6 @@ int PCB_SELECTION_TOOL::updateSelection( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
int PCB_SELECTION_TOOL::UpdateMenu( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::setTransitions()
|
||||
{
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue