Reworked selection passing mechanism in SELECTION_TOOL.

- The tools can now specify if the items in the selection must be editable/
deletable. This is groundwork to be able to select/delete DRC markers, which can't
otherwise be edited.
- Fixed disappearing of selected objects
This commit is contained in:
Tomasz Włostowski 2017-03-03 13:42:28 +01:00
parent 9e73c3117e
commit cc3d79f932
6 changed files with 175 additions and 122 deletions

View File

@ -35,6 +35,21 @@
class SELECTION : public KIGFX::VIEW_GROUP class SELECTION : public KIGFX::VIEW_GROUP
{ {
public: public:
SELECTION() {};
SELECTION( const SELECTION& aOther )
{
m_items = aOther.m_items;
m_isHover = aOther.m_isHover;
}
const SELECTION& operator= ( const SELECTION& aOther )
{
m_items = aOther.m_items;
m_isHover = aOther.m_isHover;
return *this;
}
using ITER = std::set<EDA_ITEM*>::iterator; using ITER = std::set<EDA_ITEM*>::iterator;
using CITER = std::set<EDA_ITEM*>::const_iterator; using CITER = std::set<EDA_ITEM*>::const_iterator;
@ -43,6 +58,16 @@ public:
CITER begin() const { return m_items.cbegin(); } CITER begin() const { return m_items.cbegin(); }
CITER end() const { return m_items.cend(); } CITER end() const { return m_items.cend(); }
void SetIsHover( bool aIsHover )
{
m_isHover = aIsHover;
}
bool IsHover() const
{
return m_isHover;
}
virtual void Add( EDA_ITEM* aItem ) virtual void Add( EDA_ITEM* aItem )
{ {
m_items.insert( aItem ); m_items.insert( aItem );
@ -122,12 +147,27 @@ public:
return m_items; return m_items;
} }
template<class T>
T* FirstOfKind() const
{
auto refType = T( nullptr ).Type();
for( auto item : m_items )
{
if( item->Type() == refType )
return static_cast<T*> ( item );
}
return nullptr;
}
virtual const VIEW_GROUP::ITEMS updateDrawList() const override; virtual const VIEW_GROUP::ITEMS updateDrawList() const override;
private: private:
/// Set of selected items /// Set of selected items
std::set<EDA_ITEM*> m_items; std::set<EDA_ITEM*> m_items;
bool m_isHover;
// mute hidden overloaded virtual function warnings // mute hidden overloaded virtual function warnings
using VIEW_GROUP::Add; using VIEW_GROUP::Add;
using VIEW_GROUP::Remove; using VIEW_GROUP::Remove;
@ -140,4 +180,18 @@ enum SELECTION_LOCK_FLAGS
SELECTION_LOCKED = 2 SELECTION_LOCKED = 2
}; };
// Selection type flags for RequestSelection()
enum SELECTION_TYPE_FLAGS
{
// Items that can be deleted (but not necessarily modified, eg. DRC markers)
SELECTION_DELETABLE = 1,
// Items that can be edited (moved, rotated, properties)
SELECTION_EDITABLE = 2,
// Remove pads without a host module
SELECTION_SANITIZE_PADS = 4,
// Request a hover-only selection
SELECTION_HOVER = 8,
SELECTION_DEFAULT = 0x7
};
#endif #endif

View File

@ -240,16 +240,16 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>(); PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
VECTOR2I originalCursorPos = controls->GetCursorPosition(); VECTOR2I originalCursorPos = controls->GetCursorPosition();
SELECTION& selection = m_selectionTool->GetSelection();
// Shall the selection be cleared at the end?
bool unselect = selection.Empty();
// Be sure that there is at least one item that we can modify. If nothing was selected before, // Be sure that there is at least one item that we can modify. If nothing was selected before,
// try looking for the stuff under mouse cursor (i.e. Kicad old-style hover selection) // try looking for the stuff under mouse cursor (i.e. Kicad old-style hover selection)
if( !hoverSelection() ) auto& selection = m_selectionTool->RequestSelection( SELECTION_DELETABLE );
if( selection.Empty() )
return 0; return 0;
bool unselect = selection.IsHover();
Activate(); Activate();
m_dragging = false; // Are selected items being dragged? m_dragging = false; // Are selected items being dragged?
@ -295,7 +295,7 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
{ {
if( !invokeInlineRouter() ) if( !invokeInlineRouter() )
{ {
m_selectionTool->SanitizeSelection(); selection = m_selectionTool->RequestSelection( SELECTION_DEFAULT );
if( selection.Empty() ) if( selection.Empty() )
break; break;
@ -434,13 +434,11 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent ) int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
{ {
SELECTION& selection = m_selectionTool->GetSelection();
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>(); PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
// Shall the selection be cleared at the end? const auto& selection = m_selectionTool->RequestSelection ( SELECTION_EDITABLE | SELECTION_DELETABLE );
bool unselect = selection.Empty();
if( !hoverSelection( false ) ) if( selection.Empty() )
return 0; return 0;
// Tracks & vias are treated in a special way: // Tracks & vias are treated in a special way:
@ -474,7 +472,7 @@ int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
item->SetFlags( flags ); item->SetFlags( flags );
} }
if( unselect ) if( selection.IsHover() )
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
return 0; return 0;
@ -483,15 +481,17 @@ int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent ) int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
{ {
const SELECTION& selection = m_selectionTool->GetSelection();
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>(); PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
// Shall the selection be cleared at the end? const auto& selection = m_selectionTool->RequestSelection();
bool unselect = selection.Empty();
if( !hoverSelection() || m_selectionTool->CheckLock() == SELECTION_LOCKED ) if( selection.Empty() )
return 0; return 0;
if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
return 0;
// Shall the selection be cleared at the end?
wxPoint rotatePoint = getModificationPoint( selection ); wxPoint rotatePoint = getModificationPoint( selection );
const int rotateAngle = TOOL_EVT_UTILS::GetEventRotationAngle( *editFrame, aEvent ); const int rotateAngle = TOOL_EVT_UTILS::GetEventRotationAngle( *editFrame, aEvent );
@ -506,7 +506,7 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
else else
updateRatsnest( true ); updateRatsnest( true );
if( unselect ) if( selection.IsHover() )
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
// TODO selectionModified // TODO selectionModified
@ -556,13 +556,14 @@ static void mirrorPadX( D_PAD& aPad, const wxPoint& aMirrorPoint )
int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent ) int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
{ {
const SELECTION& selection = m_selectionTool->GetSelection();
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>(); PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
// Shall the selection be cleared at the end? const auto& selection = m_selectionTool->RequestSelection();
bool unselect = selection.Empty();
if( !hoverSelection() || m_selectionTool->CheckLock() == SELECTION_LOCKED ) if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
return 0;
if( selection.Empty() )
return 0; return 0;
wxPoint mirrorPoint = getModificationPoint( selection ); wxPoint mirrorPoint = getModificationPoint( selection );
@ -617,7 +618,7 @@ int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
else else
updateRatsnest( true ); updateRatsnest( true );
if( unselect ) if( selection.IsHover() )
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
// TODO selectionModified // TODO selectionModified
@ -630,12 +631,12 @@ int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent ) int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
{ {
const SELECTION& selection = m_selectionTool->GetSelection(); const auto& selection = m_selectionTool->RequestSelection();
// Shall the selection be cleared at the end? if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
bool unselect = selection.Empty(); return 0;
if( !hoverSelection() || m_selectionTool->CheckLock() == SELECTION_LOCKED ) if( selection.Empty() )
return 0; return 0;
wxPoint flipPoint = getModificationPoint( selection ); wxPoint flipPoint = getModificationPoint( selection );
@ -651,7 +652,7 @@ int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
else else
updateRatsnest( true ); updateRatsnest( true );
if( unselect ) if( selection.IsHover() )
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
m_toolMgr->RunAction( PCB_ACTIONS::editModifiedSelection, true ); m_toolMgr->RunAction( PCB_ACTIONS::editModifiedSelection, true );
@ -663,7 +664,13 @@ int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent ) int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
{ {
if( !hoverSelection() || m_selectionTool->CheckLock() == SELECTION_LOCKED ) // get a copy instead of reference (as we're going to clear the selectio before removing items)
auto selection = m_selectionTool->RequestSelection( SELECTION_DELETABLE | SELECTION_SANITIZE_PADS );
if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
return 0;
if( selection.Empty() )
return 0; return 0;
// is this "alternative" remove? // is this "alternative" remove?
@ -673,14 +680,12 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
// in "alternative" mode, deletion is not just a simple list // in "alternative" mode, deletion is not just a simple list
// of selected items, it is: // of selected items, it is:
// - whole tracks, not just segments // - whole tracks, not just segments
if( isAlt ) if( isAlt && selection.IsHover() )
{ {
m_toolMgr->RunAction( PCB_ACTIONS::selectConnection, true ); m_toolMgr->RunAction( PCB_ACTIONS::selectConnection, true );
selection = m_selectionTool->RequestSelection( SELECTION_DELETABLE | SELECTION_SANITIZE_PADS );
} }
// Get a copy instead of a reference, as we are going to clear current selection
auto selection = m_selectionTool->GetSelection().GetItems();
// As we are about to remove items, they have to be removed from the selection first // As we are about to remove items, they have to be removed from the selection first
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
@ -697,14 +702,15 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent ) int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
{ {
const SELECTION& selection = m_selectionTool->GetSelection(); const auto& selection = m_selectionTool->RequestSelection();
// Shall the selection be cleared at the end? if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
bool unselect = selection.Empty();
if( !hoverSelection() || m_selectionTool->CheckLock() == SELECTION_LOCKED )
return 0; return 0;
if( selection.Empty() )
return 0;
wxPoint translation; wxPoint translation;
double rotation = 0; double rotation = 0;
@ -726,12 +732,12 @@ int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
static_cast<BOARD_ITEM*>( item )->Rotate( rotPoint, rotation ); static_cast<BOARD_ITEM*>( item )->Rotate( rotPoint, rotation );
if( !m_dragging ) if( !m_dragging )
getView()->Update( item, KIGFX::GEOMETRY ); getView()->Update( item );
} }
m_commit->Push( _( "Move exact" ) ); m_commit->Push( _( "Move exact" ) );
if( unselect ) if( selection.IsHover() )
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
m_toolMgr->RunAction( PCB_ACTIONS::editModifiedSelection, true ); m_toolMgr->RunAction( PCB_ACTIONS::editModifiedSelection, true );
@ -747,12 +753,10 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
bool increment = aEvent.IsAction( &PCB_ACTIONS::duplicateIncrement ); bool increment = aEvent.IsAction( &PCB_ACTIONS::duplicateIncrement );
// first, check if we have a selection, or try to get one
SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
SELECTION& selection = selTool->GetSelection();
// Be sure that there is at least one item that we can modify // Be sure that there is at least one item that we can modify
if( !hoverSelection() ) const auto& selection = m_selectionTool->RequestSelection( SELECTION_DELETABLE | SELECTION_SANITIZE_PADS );
if( selection.Empty() )
return 0; return 0;
// we have a selection to work on now, so start the tool process // we have a selection to work on now, so start the tool process
@ -880,12 +884,9 @@ private:
int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent ) int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent )
{ {
// first, check if we have a selection, or try to get one const auto& selection = m_selectionTool->RequestSelection();
SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
SELECTION& selection = selTool->GetSelection();
// pick up items under the cursor if needed if( selection.Empty() )
if( !hoverSelection() )
return 0; return 0;
// we have a selection to work on now, so start the tool process // we have a selection to work on now, so start the tool process
@ -899,14 +900,17 @@ int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent )
int EDIT_TOOL::ExchangeFootprints( const TOOL_EVENT& aEvent ) int EDIT_TOOL::ExchangeFootprints( const TOOL_EVENT& aEvent )
{ {
MODULE* mod = uniqueHoverSelection<MODULE>(); const auto& selection = m_selectionTool->RequestSelection();
if( selection.Empty() )
return 0;
MODULE* mod = selection.FirstOfKind<MODULE> ();
if( !mod ) if( !mod )
return 0; return 0;
auto& editFrame = *getEditFrame<PCB_EDIT_FRAME>(); frame()->SetCurItem( mod );
editFrame.SetCurItem( mod );
// Footprint exchange could remove modules, so they have to be // Footprint exchange could remove modules, so they have to be
// removed from the selection first // removed from the selection first
@ -914,13 +918,13 @@ int EDIT_TOOL::ExchangeFootprints( const TOOL_EVENT& aEvent )
// invoke the exchange dialog process // invoke the exchange dialog process
{ {
DIALOG_EXCHANGE_MODULE dialog( &editFrame, mod ); DIALOG_EXCHANGE_MODULE dialog( frame(), mod );
dialog.ShowQuasiModal(); dialog.ShowQuasiModal();
} }
// The current item can be deleted by exchange module, and the // The current item can be deleted by exchange module, and the
// selection is emptied, so remove current item from frame info area // selection is emptied, so remove current item from frame info area
editFrame.SetCurItem( nullptr ); frame()->SetCurItem( nullptr );
return 0; return 0;
} }
@ -947,7 +951,7 @@ void EDIT_TOOL::SetTransitions()
void EDIT_TOOL::updateRatsnest( bool aRedraw ) void EDIT_TOOL::updateRatsnest( bool aRedraw )
{ {
SELECTION& selection = m_selectionTool->GetSelection(); const SELECTION& selection = m_selectionTool->GetSelection();
RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest(); RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
ratsnest->ClearSimple(); ratsnest->ClearSimple();
@ -979,20 +983,14 @@ wxPoint EDIT_TOOL::getModificationPoint( const SELECTION& aSelection )
} }
} }
bool EDIT_TOOL::hoverSelection( bool aSanitize )
{
m_toolMgr->RunAction( PCB_ACTIONS::selectionCursor, true, aSanitize );
return !m_selectionTool->GetSelection().Empty();
}
int EDIT_TOOL::editFootprintInFpEditor( const TOOL_EVENT& aEvent ) int EDIT_TOOL::editFootprintInFpEditor( const TOOL_EVENT& aEvent )
{ {
SELECTION& selection = m_selectionTool->GetSelection(); const auto& selection = m_selectionTool->RequestSelection();
bool unselect = selection.Empty();
MODULE* mod = uniqueHoverSelection<MODULE>(); if( selection.Empty() )
return 0;
MODULE* mod = selection.FirstOfKind<MODULE>();
if( !mod ) if( !mod )
return 0; return 0;
@ -1015,8 +1013,20 @@ int EDIT_TOOL::editFootprintInFpEditor( const TOOL_EVENT& aEvent )
editor->Show( true ); editor->Show( true );
editor->Raise(); // Iconize( false ); editor->Raise(); // Iconize( false );
if( unselect ) if( selection.IsHover() )
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
return 0; return 0;
} }
template<class T>
T* EDIT_TOOL::uniqueSelected()
{
const auto selection = m_selectionTool->GetSelection();
if( selection.Size() != 1 )
return nullptr;
auto item = selection[0];
return dyn_cast<T*>( item );
}

View File

@ -176,17 +176,7 @@ private:
* @return pointer to the item (of type T), or nullptr if there isn't * @return pointer to the item (of type T), or nullptr if there isn't
* a single selected item, or it's not of the right type. * a single selected item, or it's not of the right type.
*/ */
template<class T> template<class T> T* uniqueSelected();
T* uniqueSelected()
{
const SELECTION& selection = m_selectionTool->GetSelection();
if( selection.Size() != 1 )
return nullptr;
auto item = selection[0];
return dyn_cast<T*>( item );
}
/** /**
* Function uniqueHoverSelection() * Function uniqueHoverSelection()

View File

@ -793,7 +793,7 @@ static bool mergeZones( BOARD_COMMIT& aCommit, std::vector<ZONE_CONTAINER *>& aO
int PCB_EDITOR_CONTROL::ZoneMerge( const TOOL_EVENT& aEvent ) int PCB_EDITOR_CONTROL::ZoneMerge( const TOOL_EVENT& aEvent )
{ {
SELECTION& selection = m_toolMgr->GetTool<SELECTION_TOOL>()->GetSelection(); const SELECTION& selection = m_toolMgr->GetTool<SELECTION_TOOL>()->GetSelection();
BOARD* board = getModel<BOARD>(); BOARD* board = getModel<BOARD>();
BOARD_COMMIT commit( m_frame ); BOARD_COMMIT commit( m_frame );

View File

@ -168,8 +168,7 @@ SELECTION_TOOL::SELECTION_TOOL() :
m_locked( true ), m_menu( *this ), m_locked( true ), m_menu( *this ),
m_priv( std::make_unique<PRIV>() ) m_priv( std::make_unique<PRIV>() )
{ {
// Do not leave uninitialized members:
m_preliminary = false;
} }
@ -201,7 +200,6 @@ void SELECTION_TOOL::Reset( RESET_REASON aReason )
{ {
m_frame = getEditFrame<PCB_BASE_FRAME>(); m_frame = getEditFrame<PCB_BASE_FRAME>();
m_locked = true; m_locked = true;
m_preliminary = true;
if( aReason == TOOL_BASE::MODEL_RELOAD ) if( aReason == TOOL_BASE::MODEL_RELOAD )
{ {
@ -255,8 +253,6 @@ int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
selectPoint( evt->Position() ); selectPoint( evt->Position() );
m_menu.ShowContextMenu( m_selection ); m_menu.ShowContextMenu( m_selection );
m_preliminary = emptySelection;
} }
// double click? Display the properties window // double click? Display the properties window
@ -273,14 +269,10 @@ int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
{ {
if( m_additive ) if( m_additive )
{ {
m_preliminary = false;
selectMultiple(); selectMultiple();
} }
else if( m_selection.Empty() ) else if( m_selection.Empty() )
{ {
m_preliminary = false;
// There is nothing selected, so try to select something // There is nothing selected, so try to select something
if( !selectCursor() ) if( !selectCursor() )
{ {
@ -317,9 +309,6 @@ int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
else if( evt->Action() == TA_CONTEXT_MENU_CLOSED ) else if( evt->Action() == TA_CONTEXT_MENU_CLOSED )
{ {
if( m_preliminary )
clearSelection();
m_menu.CloseContextMenu( evt ); m_menu.CloseContextMenu( evt );
} }
} }
@ -330,22 +319,32 @@ int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
return 0; return 0;
} }
SELECTION& SELECTION_TOOL::GetSelection() SELECTION& SELECTION_TOOL::GetSelection()
{ {
// The selected items list has been requested, so it is no longer preliminary return m_selection;
m_preliminary = false; }
auto items = m_selection.GetItems(); SELECTION& SELECTION_TOOL::RequestSelection( int aFlags )
{
if ( m_selection.Empty() )
{
m_toolMgr->RunAction( PCB_ACTIONS::selectionCursor, true, 0 );
m_selection.SetIsHover( true );
}
else
{
m_selection.SetIsHover( false );
}
// Filter out not modifiable items for( auto item : m_selection )
for( auto item : items )
{ {
if( !modifiable( static_cast<BOARD_ITEM*>( item ) ) ) if( ( aFlags & SELECTION_EDITABLE ) && item->Type() == PCB_MARKER_T )
{ {
m_selection.Remove( item ); unselect( static_cast<BOARD_ITEM *>( item ) );
} }
} }
if ( aFlags & SELECTION_SANITIZE_PADS )
SanitizeSelection();
return m_selection; return m_selection;
} }
@ -623,7 +622,6 @@ int SELECTION_TOOL::ClearSelection( const TOOL_EVENT& aEvent )
return 0; return 0;
} }
int SELECTION_TOOL::SelectItem( const TOOL_EVENT& aEvent ) int SELECTION_TOOL::SelectItem( const TOOL_EVENT& aEvent )
{ {
// Check if there is an item to be selected // Check if there is an item to be selected
@ -1329,16 +1327,6 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
return board()->IsLayerVisible( aItem->GetLayer() ); return board()->IsLayerVisible( aItem->GetLayer() );
} }
bool SELECTION_TOOL::modifiable( const BOARD_ITEM* aItem ) const
{
if( aItem->Type() == PCB_MARKER_T )
return false;
return true;
}
void SELECTION_TOOL::select( BOARD_ITEM* aItem ) void SELECTION_TOOL::select( BOARD_ITEM* aItem )
{ {
if( aItem->IsSelected() ) if( aItem->IsSelected() )
@ -1354,8 +1342,9 @@ void SELECTION_TOOL::select( BOARD_ITEM* aItem )
return; return;
} }
selectVisually( aItem );
m_selection.Add( aItem ); m_selection.Add( aItem );
selectVisually( aItem );
if( m_selection.Size() == 1 ) if( m_selection.Size() == 1 )
{ {
@ -1375,8 +1364,8 @@ void SELECTION_TOOL::unselect( BOARD_ITEM* aItem )
if( !aItem->IsSelected() ) if( !aItem->IsSelected() )
return; return;
unselectVisually( aItem );
m_selection.Remove( aItem ); m_selection.Remove( aItem );
unselectVisually( aItem );
if( m_selection.Empty() ) if( m_selection.Empty() )
{ {
@ -1386,7 +1375,7 @@ void SELECTION_TOOL::unselect( BOARD_ITEM* aItem )
} }
void SELECTION_TOOL::selectVisually( BOARD_ITEM* aItem ) const void SELECTION_TOOL::selectVisually( BOARD_ITEM* aItem )
{ {
// Hide the original item, so it is shown only on overlay // Hide the original item, so it is shown only on overlay
aItem->SetSelected(); aItem->SetSelected();
@ -1405,10 +1394,12 @@ void SELECTION_TOOL::selectVisually( BOARD_ITEM* aItem ) const
view()->Update( item, KIGFX::GEOMETRY ); view()->Update( item, KIGFX::GEOMETRY );
} ); } );
} }
view()->Update( &m_selection );
} }
void SELECTION_TOOL::unselectVisually( BOARD_ITEM* aItem ) const void SELECTION_TOOL::unselectVisually( BOARD_ITEM* aItem )
{ {
// Restore original item visibility // Restore original item visibility
aItem->ClearSelected(); aItem->ClearSelected();
@ -1427,6 +1418,8 @@ void SELECTION_TOOL::unselectVisually( BOARD_ITEM* aItem ) const
view()->Update( item, KIGFX::ALL ); view()->Update( item, KIGFX::ALL );
}); });
} }
view()->Update( &m_selection );
} }
@ -1791,7 +1784,7 @@ bool SELECTION_TOOL::SanitizeSelection()
select( item ); select( item );
// Inform other potentially interested tools // Inform other potentially interested tools
m_toolMgr->ProcessEvent( UnselectedEvent ); m_toolMgr->ProcessEvent( SelectedEvent );
} }
return true; return true;
@ -1843,10 +1836,10 @@ const BOX2I SELECTION::ViewBBox() const
eda_bbox.Merge( (*i)->GetBoundingBox() ); eda_bbox.Merge( (*i)->GetBoundingBox() );
} }
} }
return BOX2I( eda_bbox.GetOrigin(), eda_bbox.GetSize() ); return BOX2I( eda_bbox.GetOrigin(), eda_bbox.GetSize() );
} }
const KIGFX::VIEW_GROUP::ITEMS SELECTION::updateDrawList() const const KIGFX::VIEW_GROUP::ITEMS SELECTION::updateDrawList() const
{ {
std::vector<VIEW_ITEM*> items; std::vector<VIEW_ITEM*> items;

View File

@ -84,6 +84,15 @@ public:
*/ */
SELECTION& GetSelection(); SELECTION& GetSelection();
/**
* Function RequestSelection()
*
* Returns the current selection set, filtered according to aFlags.
* If the set is empty, performs the legacy-style hover selection.
*/
SELECTION& RequestSelection( int aFlags = SELECTION_DEFAULT );
inline TOOL_MENU& GetToolMenu() inline TOOL_MENU& GetToolMenu()
{ {
return m_menu; return m_menu;
@ -272,14 +281,14 @@ private:
* Marks item as selected, but does not add it to the ITEMS_PICKED_LIST. * Marks item as selected, but does not add it to the ITEMS_PICKED_LIST.
* @param aItem is an item to be be marked. * @param aItem is an item to be be marked.
*/ */
void selectVisually( BOARD_ITEM* aItem ) const; void selectVisually( BOARD_ITEM* aItem );
/** /**
* Function unselectVisually() * Function unselectVisually()
* Marks item as selected, but does not add it to the ITEMS_PICKED_LIST. * Marks item as selected, but does not add it to the ITEMS_PICKED_LIST.
* @param aItem is an item to be be marked. * @param aItem is an item to be be marked.
*/ */
void unselectVisually( BOARD_ITEM* aItem ) const; void unselectVisually( BOARD_ITEM* aItem );
/** /**
* Function selectionContains() * Function selectionContains()
@ -312,9 +321,6 @@ private:
/// Can other tools modify locked items. /// Can other tools modify locked items.
bool m_locked; bool m_locked;
/// Determines if the selection is preliminary or final.
bool m_preliminary;
/// Menu model displayed by the tool. /// Menu model displayed by the tool.
TOOL_MENU m_menu; TOOL_MENU m_menu;