Commit d213a260 authored by Maciej Suminski's avatar Maciej Suminski

Smarter selection algorithm (does not allow to select both whole MODULE and...

Smarter selection algorithm (does not allow to select both whole MODULE and its parts at the same time).
Cancel event works better (selection box does not appear after cancelling the selection tool).
Removed blinking selection box effect.
Model is accessed in more appropriate way (getModel() method).
parent f2b4c7a1
...@@ -69,9 +69,10 @@ void SELECTION_TOOL::Reset() ...@@ -69,9 +69,10 @@ void SELECTION_TOOL::Reset()
int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) int SELECTION_TOOL::Main( TOOL_EVENT& aEvent )
{ {
bool dragging = false; bool dragging = false;
m_board = static_cast<PCB_BASE_FRAME*>( m_toolMgr->GetEditFrame() )->GetBoard(); bool allowMultiple = true;
BOARD* board = getModel<BOARD>( PCB_T );
if( !m_board ) if( !board )
return 0; return 0;
// Main loop: keep receiving events // Main loop: keep receiving events
...@@ -91,6 +92,10 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) ...@@ -91,6 +92,10 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent )
if( evt->IsClick( MB_Left ) ) if( evt->IsClick( MB_Left ) )
selectSingle( evt->Position() ); selectSingle( evt->Position() );
// unlock the multiple selection box
if( evt->IsMouseUp( MB_Left ) )
allowMultiple = true;
// drag with LMB? Select multiple objects (or at least draw a selection box) or drag them // drag with LMB? Select multiple objects (or at least draw a selection box) or drag them
if( evt->IsDrag( MB_Left ) ) if( evt->IsDrag( MB_Left ) )
{ {
...@@ -101,14 +106,14 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) ...@@ -101,14 +106,14 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent )
{ {
// If nothings has been selected or user wants to select more // If nothings has been selected or user wants to select more
// draw the selection box // draw the selection box
selectMultiple(); if( allowMultiple )
allowMultiple = !selectMultiple();
} }
else else
{ {
// Now user wants to drag the selected items // Now user wants to drag the selected items
m_toolMgr->InvokeTool( "pcbnew.InteractiveMove" ); m_toolMgr->InvokeTool( "pcbnew.InteractiveMove" );
} }
} }
else if( dragging ) else if( dragging )
{ {
...@@ -223,17 +228,24 @@ BOARD_ITEM* SELECTION_TOOL::pickSmallestComponent( GENERAL_COLLECTOR* aCollector ...@@ -223,17 +228,24 @@ BOARD_ITEM* SELECTION_TOOL::pickSmallestComponent( GENERAL_COLLECTOR* aCollector
} }
void SELECTION_TOOL::selectMultiple() bool SELECTION_TOOL::selectMultiple()
{ {
OPT_TOOL_EVENT evt; OPT_TOOL_EVENT evt;
VIEW* v = getView(); VIEW* v = getView();
bool cancelled = false;
// Those 2 lines remove the blink-in-the-random-place effect
m_selArea->SetOrigin( VECTOR2I( 0, 0 ) );
m_selArea->SetEnd( VECTOR2I( 0, 0 ) );
v->Add( m_selArea ); v->Add( m_selArea );
while( evt = Wait() ) while( evt = Wait() )
{ {
if( evt->IsCancel() ) if( evt->IsCancel() )
{
cancelled = true;
break; break;
}
if( evt->IsDrag( MB_Left ) ) if( evt->IsDrag( MB_Left ) )
{ {
...@@ -269,12 +281,15 @@ void SELECTION_TOOL::selectMultiple() ...@@ -269,12 +281,15 @@ void SELECTION_TOOL::selectMultiple()
m_selectedItems.insert( item ); m_selectedItems.insert( item );
} }
} }
handleModules();
break; break;
} }
} }
v->Remove( m_selArea ); v->Remove( m_selArea );
return cancelled;
} }
...@@ -337,8 +352,10 @@ BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector ) ...@@ -337,8 +352,10 @@ BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector )
} }
bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem )
{ {
BOARD* board = getModel<BOARD>( PCB_T );
switch( aItem->Type() ) switch( aItem->Type() )
{ {
case PCB_VIA_T: case PCB_VIA_T:
...@@ -347,17 +364,17 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const ...@@ -347,17 +364,17 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
LAYER_NUM top, bottom; LAYER_NUM top, bottom;
static_cast<const SEGVIA*>( aItem )->ReturnLayerPair( &top, &bottom ); static_cast<const SEGVIA*>( aItem )->ReturnLayerPair( &top, &bottom );
return ( m_board->IsLayerVisible( top ) || return ( board->IsLayerVisible( top ) ||
m_board->IsLayerVisible( bottom ) ); board->IsLayerVisible( bottom ) );
} }
break; break;
case PCB_PAD_T: case PCB_PAD_T:
// Pads are supposed to be on top, bottom or both at the same time (THT) // Pads are supposed to be on top, bottom or both at the same time (THT)
if( aItem->IsOnLayer( LAYER_N_FRONT ) && m_board->IsLayerVisible( LAYER_N_FRONT ) ) if( aItem->IsOnLayer( LAYER_N_FRONT ) && board->IsLayerVisible( LAYER_N_FRONT ) )
return true; return true;
if( aItem->IsOnLayer( LAYER_N_BACK ) && m_board->IsLayerVisible( LAYER_N_BACK ) ) if( aItem->IsOnLayer( LAYER_N_BACK ) && board->IsLayerVisible( LAYER_N_BACK ) )
return true; return true;
return false; return false;
...@@ -369,6 +386,28 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const ...@@ -369,6 +386,28 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
break; break;
} }
// All other items // All other items are selected only if the layer on which they exist is visible
return m_board->IsLayerVisible( aItem->GetLayer() ); return board->IsLayerVisible( aItem->GetLayer() );
}
void SELECTION_TOOL::handleModules()
{
std::set<BOARD_ITEM*>::iterator it, it_end;
for( it = m_selectedItems.begin(), it_end = m_selectedItems.end(); it != it_end; )
{
BOARD_ITEM* parent = (*it)->GetParent();
// Do not allow to select MODULE and it's parts at the same time
if( parent != NULL && parent->IsSelected() )
{
(*it)->ClearSelected();
m_selectedItems.erase( it++ );
}
else
{
++it;
}
}
} }
...@@ -87,8 +87,10 @@ private: ...@@ -87,8 +87,10 @@ private:
/** /**
* Function selectMultiple() * Function selectMultiple()
* Handles drawing a selection box that allows to select many items at the same time. * Handles drawing a selection box that allows to select many items at the same time.
*
* @return true if the function was cancelled (ie. CancelEvent was received).
*/ */
void selectMultiple(); bool selectMultiple();
/** /**
* Function disambiguationMenu() * Function disambiguationMenu()
...@@ -127,10 +129,13 @@ private: ...@@ -127,10 +129,13 @@ private:
* *
* @return True if the item fulfills conditions to be selected. * @return True if the item fulfills conditions to be selected.
*/ */
bool selectable( const BOARD_ITEM* aItem ) const; bool selectable( const BOARD_ITEM* aItem );
/// Currently used PCB /**
BOARD* m_board; * Prevents from selecting both MODULEs and it's parts at the same time. The right way is
* to select a MODULE *or* some of it's parts.
*/
void handleModules();
/// Container storing currently selected items /// Container storing currently selected items
std::set<BOARD_ITEM*> m_selectedItems; std::set<BOARD_ITEM*> m_selectedItems;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment