Refactor SELECTION, SELECTION_CONDITIONS, and context menus to common

SELECTION now holds EDA_ITEMs not BOARD_ITEMs so various places had to
change to casting the selected items to BOARD_ITEMs.

Fixed compilation warnings on clang (Tom)
This commit is contained in:
Jon Evans 2017-02-27 22:04:44 -05:00 committed by Tomasz Włostowski
parent 0afb249447
commit fd4e2b042c
26 changed files with 434 additions and 306 deletions

View File

@ -301,6 +301,11 @@ set( COMMON_SRCS
tool/context_menu.cpp
tool/actions.cpp
tool/common_tools.cpp
tool/grid_menu.cpp
tool/zoom_menu.cpp
tool/tool_menu.cpp
tool/conditional_menu.cpp
tool/selection_conditions.cpp
geometry/seg.cpp
geometry/shape.cpp

View File

@ -22,7 +22,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "conditional_menu.h"
#include <tool/conditional_menu.h>
#include <tool/context_menu.h>
void CONDITIONAL_MENU::AddItem( const TOOL_ACTION& aAction, const SELECTION_CONDITION& aCondition,

View File

@ -23,11 +23,11 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "grid_menu.h"
#include <tool/grid_menu.h>
#include <id.h>
#include <draw_frame.h>
#include <class_base_screen.h>
#include <tools/pcb_actions.h>
#include <tool/actions.h>
#include <bitmaps.h>
#include <functional>

View File

@ -22,9 +22,9 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "selection_conditions.h"
#include "selection_tool.h"
#include <class_board_connected_item.h>
#include <tool/selection.h>
#include <tool/selection_conditions.h>
#include <functional>
using namespace std::placeholders;
@ -36,35 +36,6 @@ bool SELECTION_CONDITIONS::NotEmpty( const SELECTION& aSelection )
}
bool SELECTION_CONDITIONS::OnlyConnectedItems( const SELECTION& aSelection )
{
if( aSelection.Empty() )
return false;
for( const auto &item : aSelection )
{
auto type = item->Type();
if( type != PCB_PAD_T && type != PCB_VIA_T && type != PCB_TRACE_T && type != PCB_ZONE_T )
return false;
}
return true;
}
SELECTION_CONDITION SELECTION_CONDITIONS::SameNet( bool aAllowUnconnected )
{
return std::bind( &SELECTION_CONDITIONS::sameNetFunc, _1, aAllowUnconnected );
}
SELECTION_CONDITION SELECTION_CONDITIONS::SameLayer()
{
return std::bind( &SELECTION_CONDITIONS::sameLayerFunc, _1 );
}
SELECTION_CONDITION SELECTION_CONDITIONS::HasType( KICAD_T aType )
{
return std::bind( &SELECTION_CONDITIONS::hasTypeFunc, _1, aType );
@ -107,72 +78,6 @@ SELECTION_CONDITION SELECTION_CONDITIONS::LessThan( int aNumber )
}
bool SELECTION_CONDITIONS::sameNetFunc( const SELECTION& aSelection, bool aAllowUnconnected )
{
if( aSelection.Empty() )
return false;
int netcode = -1; // -1 stands for 'net code is not yet determined'
for( const auto& aitem : aSelection )
{
int current_netcode = -1;
const BOARD_CONNECTED_ITEM* item =
dynamic_cast<const BOARD_CONNECTED_ITEM*>( aitem );
if( item )
{
current_netcode = item->GetNetCode();
}
else
{
if( !aAllowUnconnected )
return false;
else
// if it is not a BOARD_CONNECTED_ITEM, treat it as if there was no net assigned
current_netcode = 0;
}
assert( current_netcode >= 0 );
if( netcode < 0 )
{
netcode = current_netcode;
if( netcode == NETINFO_LIST::UNCONNECTED && !aAllowUnconnected )
return false;
}
else if( netcode != current_netcode )
{
return false;
}
}
return true;
}
bool SELECTION_CONDITIONS::sameLayerFunc( const SELECTION& aSelection )
{
if( aSelection.Empty() )
return false;
LSET layerSet;
layerSet.set();
for( const auto& item : aSelection )
{
layerSet &= item->GetLayerSet();
if( !layerSet.any() ) // there are no common layers left
return false;
}
return true;
}
bool SELECTION_CONDITIONS::hasTypeFunc( const SELECTION& aSelection, KICAD_T aType )
{
for( const auto& item : aSelection )

View File

@ -21,14 +21,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "tool_menu.h"
#include <draw_frame.h>
#include <tool/tool_menu.h>
#include <tool/tool_interactive.h>
#include <tool/context_menu.h>
#include "pcb_actions.h"
#include "zoom_menu.h"
#include "grid_menu.h"
#include "selection_tool.h" // For SELECTION
#include <tool/actions.h>
#include <tool/zoom_menu.h>
#include <tool/grid_menu.h>
#include <tool/selection.h>
TOOL_MENU::TOOL_MENU( TOOL_INTERACTIVE& aTool ) :

View File

@ -22,11 +22,11 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "zoom_menu.h"
#include <tool/zoom_menu.h>
#include <id.h>
#include <draw_frame.h>
#include <class_base_screen.h>
#include <tools/pcb_actions.h>
#include <tool/actions.h>
#include <bitmaps.h>
#include <functional>

141
include/tool/selection.h Normal file
View File

@ -0,0 +1,141 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013-2017 CERN
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* 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 Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __SELECTION_H
#define __SELECTION_H
#include <set>
#include <base_struct.h>
#include <view/view_group.h>
class SELECTION : public KIGFX::VIEW_GROUP
{
public:
using ITER = std::set<EDA_ITEM*>::iterator;
using CITER = std::set<EDA_ITEM*>::const_iterator;
ITER begin() { return m_items.begin(); }
ITER end() { return m_items.end(); }
CITER begin() const { return m_items.cbegin(); }
CITER end() const { return m_items.cend(); }
virtual void Add( EDA_ITEM* aItem )
{
m_items.insert( aItem );
}
virtual void Remove( EDA_ITEM *aItem )
{
m_items.erase( aItem );
}
virtual void Clear() override
{
m_items.clear();
}
virtual unsigned int GetSize() const override
{
return m_items.size();
}
virtual KIGFX::VIEW_ITEM* GetItem( unsigned int idx ) const override
{
auto iter = m_items.begin();
std::advance( iter, idx );
return *iter;
}
bool Contains( EDA_ITEM* aItem ) const
{
return m_items.find( aItem ) != m_items.end();
}
/// Checks if there is anything selected
bool Empty() const
{
return ( m_items.size() == 0 );
}
/// Returns the number of selected parts
int Size() const
{
return m_items.size();
}
const std::set<EDA_ITEM*> GetItems() const
{
return m_items;
}
/// Returns the center point of the selection area bounding box.
VECTOR2I GetCenter() const;
EDA_ITEM* operator[]( const int index ) const
{
if( index < 0 || (unsigned int) index >= m_items.size() )
return nullptr;
auto iter = m_items.begin();
std::advance( iter, index );
return *iter;
}
EDA_ITEM* Front() const
{
if ( !m_items.size() )
return nullptr;
return *m_items.begin();
}
std::set<EDA_ITEM*>& Items()
{
return m_items;
}
virtual const VIEW_GROUP::ITEMS updateDrawList() const override;
private:
/// Set of selected items
std::set<EDA_ITEM*> m_items;
// mute hidden overloaded virtual function warnings
using VIEW_GROUP::Add;
using VIEW_GROUP::Remove;
};
enum SELECTION_LOCK_FLAGS
{
SELECTION_UNLOCKED = 0,
SELECTION_LOCK_OVERRIDE = 1,
SELECTION_LOCKED = 2
};
#endif

View File

@ -29,7 +29,7 @@
#include <core/typeinfo.h>
#include <vector>
struct SELECTION;
#include <tool/selection.h>
///> Functor type that checks a specific condition for selected items.
typedef std::function<bool (const SELECTION&)> SELECTION_CONDITION;
@ -66,33 +66,6 @@ public:
*/
static bool NotEmpty( const SELECTION& aSelection );
/**
* Function OnlyConnectedItems
* Tests if selection contains exclusively connected items (pads, tracks, vias, zones).
* @param aSelection is the selection to be tested.
* @return True if there are only connected items connected.
*/
static bool OnlyConnectedItems( const SELECTION& aSelection );
/**
* Function SameNet
* Creates a functor that tests if selection contains items belonging to the same net or are
* unconnected if aAllowUnconnected == true.
* @param aAllowUnconnected determines if unconnected items (with no net code assigned) should
* be treated as connected to the same net.
* @return Functor testing if selected items are belonging to the same net.
*/
static SELECTION_CONDITION SameNet( bool aAllowUnconnected = false );
/**
* Function SameLayer
* Creates a functor that tests if selection contains items that belong exclusively to the same
* layer. In case of items belonging to multiple layers, it is enough to have a single common
* layer with other items.
* @return Functor testing if selected items share at least one common layer.
*/
static SELECTION_CONDITION SameLayer();
/**
* Function HasType
* Creates a functor that tests if among the selected items there is at least one of a given type.
@ -154,12 +127,6 @@ public:
static SELECTION_CONDITION LessThan( int aNumber );
private:
///> Helper function used by SameNet()
static bool sameNetFunc( const SELECTION& aSelection, bool aAllowUnconnected );
///> Helper function used by SameLayer()
static bool sameLayerFunc( const SELECTION& aSelection );
///> Helper function used by HasType()
static bool hasTypeFunc( const SELECTION& aSelection, KICAD_T aType );

View File

@ -24,8 +24,8 @@
#ifndef TOOLS_TOOL_MENU__H_
#define TOOLS_TOOL_MENU__H_
#include "conditional_menu.h"
#include "pcb_tool.h"
#include <tool/conditional_menu.h>
#include <tool/tool_event.h>
#include <vector>
#include <memory>

View File

@ -291,8 +291,7 @@ set( PCBNEW_CLASS_SRCS
tools/selection_tool.cpp
tools/selection_area.cpp
tools/selection_conditions.cpp
tools/conditional_menu.cpp
tools/pcb_selection_conditions.cpp
tools/bright_box.cpp
tools/edit_points.cpp
tools/edit_constraints.cpp
@ -310,10 +309,7 @@ set( PCBNEW_CLASS_SRCS
tools/zoom_tool.cpp
tools/tools_common.cpp
tools/tool_event_utils.cpp
tools/tool_menu.cpp
tools/grid_menu.cpp
tools/zoom_menu.cpp
tools/size_menu.cpp
footprint_preview_panel.cpp

View File

@ -27,7 +27,7 @@
#include <boost/optional.hpp>
#include <layers_id_colors_and_visibility.h>
struct SELECTION;
class SELECTION;
class COMMIT;
class PCB_BASE_FRAME;

View File

@ -46,12 +46,13 @@ using namespace std::placeholders;
#include <tool/context_menu.h>
#include <tool/tool_manager.h>
#include <tool/tool_settings.h>
#include <tool/grid_menu.h>
#include <tool/zoom_menu.h>
#include <tools/pcb_actions.h>
#include <tools/size_menu.h>
#include <tools/selection_tool.h>
#include <tools/edit_tool.h>
#include <tools/grid_menu.h>
#include <tools/zoom_menu.h>
#include <tools/tool_event_utils.h>
#include <ratsnest_data.h>

View File

@ -675,7 +675,7 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
preview.Add( item );
}
BOARD_ITEM* firstItem = preview.Front();
BOARD_ITEM* firstItem = static_cast<BOARD_ITEM*>( preview.Front() );
m_view->Add( &preview );
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
@ -696,7 +696,7 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
delta = cursorPos - firstItem->GetPosition();
for( auto item : preview )
item->Move( wxPoint( delta.x, delta.y ) );
static_cast<BOARD_ITEM*>( item )->Move( wxPoint( delta.x, delta.y ) );
m_view->Update( &preview );
}
@ -712,7 +712,7 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
for( auto item : preview )
{
item->Rotate( rotationPoint, rotationAngle );
static_cast<BOARD_ITEM*>( item )->Rotate( rotationPoint, rotationAngle );
}
m_view->Update( &preview );
@ -720,7 +720,7 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
else if( evt->IsAction( &PCB_ACTIONS::flip ) )
{
for( auto item : preview )
item->Flip( wxPoint( cursorPos.x, cursorPos.y ) );
static_cast<BOARD_ITEM*>( item )->Flip( wxPoint( cursorPos.x, cursorPos.y ) );
m_view->Update( &preview );
}
@ -807,7 +807,7 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
}
if( converted )
converted->SetLayer( item->GetLayer() );
converted->SetLayer( static_cast<BOARD_ITEM*>( item )->GetLayer() );
delete item;
item = converted;

View File

@ -28,7 +28,7 @@
#include <tools/pcb_tool.h>
#include <boost/optional.hpp>
#include "tool_menu.h"
#include <tool/tool_menu.h>
namespace KIGFX
{

View File

@ -273,7 +273,7 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
if( selection.Empty() )
break;
BOARD_ITEM* curr_item = selection.Front();
BOARD_ITEM* curr_item = static_cast<BOARD_ITEM*>( selection.Front() );
if( m_dragging && evt->Category() == TC_MOUSE )
{
@ -285,7 +285,7 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
// Drag items to the current cursor position
for( auto item : selection )
item->Move( movement + m_offset );
static_cast<BOARD_ITEM*>( item )->Move( movement + m_offset );
updateRatsnest( true );
}
@ -378,7 +378,8 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
// So, instead, reset the position manually
for( auto item : selection )
{
item->SetPosition( item->GetPosition() - totalMovement );
BOARD_ITEM* i = static_cast<BOARD_ITEM*>( item );
i->SetPosition( i->GetPosition() - totalMovement );
// And what about flipping and rotation?
// for now, they won't be undone, but maybe that is how
@ -395,7 +396,7 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
if( m_dragging )
{
// Update dragging offset (distance between cursor and the first dragged item)
m_offset = selection.Front()->GetPosition() - modPoint;
m_offset = static_cast<BOARD_ITEM*>( selection.Front() )->GetPosition() - modPoint;
getView()->Update( &selection );
updateRatsnest( true );
}
@ -454,7 +455,7 @@ int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
else if( selection.Size() == 1 ) // Properties are displayed when there is only one item selected
{
// Display properties dialog
BOARD_ITEM* item = selection.Front();
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selection.Front() );
// Some of properties dialogs alter pointers, so we should deselect them
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
@ -495,7 +496,7 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
for( auto item : selection )
{
m_commit->Modify( item );
item->Rotate( rotatePoint, rotateAngle );
static_cast<BOARD_ITEM*>( item )->Rotate( rotatePoint, rotateAngle );
}
if( !m_dragging )
@ -640,7 +641,7 @@ int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
for( auto item : selection )
{
m_commit->Modify( item );
item->Flip( flipPoint );
static_cast<BOARD_ITEM*>( item )->Flip( flipPoint );
}
if( !m_dragging )
@ -719,8 +720,8 @@ int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
{
m_commit->Modify( item );
item->Move( translation );
item->Rotate( rotPoint, rotation );
static_cast<BOARD_ITEM*>( item )->Move( translation );
static_cast<BOARD_ITEM*>( item )->Rotate( rotPoint, rotation );
if( !m_dragging )
getView()->Update( item, KIGFX::GEOMETRY );
@ -760,7 +761,7 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
for( auto item : selection )
{
if( item )
old_items.push_back( item );
old_items.push_back( static_cast<BOARD_ITEM*>( item ) );
}
for( unsigned i = 0; i < old_items.size(); ++i )
@ -835,7 +836,7 @@ private:
BOARD_ITEM* getNthItemToArray( int n ) const override
{
return m_selection[n];
return static_cast<BOARD_ITEM*>( m_selection[n] );
}
BOARD* getBoard() const override
@ -951,10 +952,10 @@ void EDIT_TOOL::updateRatsnest( bool aRedraw )
for( auto item : selection )
{
ratsnest->Update( item );
ratsnest->Update( static_cast<BOARD_ITEM*>( item ) );
if( aRedraw )
ratsnest->AddSimple( item );
ratsnest->AddSimple( static_cast<BOARD_ITEM*>( item ) );
}
}
@ -963,7 +964,7 @@ wxPoint EDIT_TOOL::getModificationPoint( const SELECTION& aSelection )
{
if( aSelection.Size() == 1 )
{
return aSelection.Front()->GetPosition() - m_offset;
return static_cast<BOARD_ITEM*>( aSelection.Front() )->GetPosition() - m_offset;
}
else
{

View File

@ -39,7 +39,7 @@
#include "pcb_actions.h"
#include "selection_tool.h"
#include "selection_conditions.h"
#include "pcb_selection_conditions.h"
#include "edit_tool.h"
// Pad tools

View File

@ -199,8 +199,8 @@ private:
// lines like this make me really think about a better name for SELECTION_CONDITIONS class
bool mergeEnabled = ( SELECTION_CONDITIONS::MoreThan( 1 ) &&
/*SELECTION_CONDITIONS::OnlyType( PCB_ZONE_AREA_T ) &&*/
SELECTION_CONDITIONS::SameNet( true ) &&
SELECTION_CONDITIONS::SameLayer() )( selTool->GetSelection() );
PCB_SELECTION_CONDITIONS::SameNet( true ) &&
PCB_SELECTION_CONDITIONS::SameLayer() )( selTool->GetSelection() );
Enable( getMenuId( PCB_ACTIONS::zoneMerge ), mergeEnabled );
}
@ -523,8 +523,9 @@ int PCB_EDITOR_CONTROL::modifyLockSelected( MODIFY_MODE aMode )
bool modified = false;
for( auto item : selection )
for( auto i : selection )
{
auto item = static_cast<BOARD_ITEM*>( i );
bool prevState = item->IsLocked();
switch( aMode )
@ -923,7 +924,7 @@ int PCB_EDITOR_CONTROL::CrossProbePcbToSch( const TOOL_EVENT& aEvent )
const SELECTION& selection = selTool->GetSelection();
if( selection.Size() == 1 )
m_frame->SendMessageToEESCHEMA( selection.Front() );
m_frame->SendMessageToEESCHEMA( static_cast<BOARD_ITEM*>( selection.Front() ) );
return 0;
}

View File

@ -0,0 +1,127 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* 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 Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "pcb_selection_conditions.h"
#include "selection_tool.h"
#include <class_board_connected_item.h>
#include <functional>
using namespace std::placeholders;
bool PCB_SELECTION_CONDITIONS::OnlyConnectedItems( const SELECTION& aSelection )
{
if( aSelection.Empty() )
return false;
for( const auto &item : aSelection )
{
auto type = item->Type();
if( type != PCB_PAD_T && type != PCB_VIA_T && type != PCB_TRACE_T && type != PCB_ZONE_T )
return false;
}
return true;
}
SELECTION_CONDITION PCB_SELECTION_CONDITIONS::SameNet( bool aAllowUnconnected )
{
return std::bind( &PCB_SELECTION_CONDITIONS::sameNetFunc, _1, aAllowUnconnected );
}
SELECTION_CONDITION PCB_SELECTION_CONDITIONS::SameLayer()
{
return std::bind( &PCB_SELECTION_CONDITIONS::sameLayerFunc, _1 );
}
bool PCB_SELECTION_CONDITIONS::sameNetFunc( const SELECTION& aSelection, bool aAllowUnconnected )
{
if( aSelection.Empty() )
return false;
int netcode = -1; // -1 stands for 'net code is not yet determined'
for( const auto& aitem : aSelection )
{
int current_netcode = -1;
const BOARD_CONNECTED_ITEM* item =
dynamic_cast<const BOARD_CONNECTED_ITEM*>( aitem );
if( item )
{
current_netcode = item->GetNetCode();
}
else
{
if( !aAllowUnconnected )
return false;
else
// if it is not a BOARD_CONNECTED_ITEM, treat it as if there was no net assigned
current_netcode = 0;
}
assert( current_netcode >= 0 );
if( netcode < 0 )
{
netcode = current_netcode;
if( netcode == NETINFO_LIST::UNCONNECTED && !aAllowUnconnected )
return false;
}
else if( netcode != current_netcode )
{
return false;
}
}
return true;
}
bool PCB_SELECTION_CONDITIONS::sameLayerFunc( const SELECTION& aSelection )
{
if( aSelection.Empty() )
return false;
LSET layerSet;
layerSet.set();
for( const auto& i : aSelection )
{
auto item = static_cast<BOARD_ITEM*>( i );
layerSet &= item->GetLayerSet();
if( !layerSet.any() ) // there are no common layers left
return false;
}
return true;
}

View File

@ -0,0 +1,72 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* 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 Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef PCB_SELECTION_CONDITIONS_H_
#define PCB_SELECTION_CONDITIONS_H_
#include <tool/selection.h>
#include <tool/selection_conditions.h>
#include <class_board_item.h>
class PCB_SELECTION_CONDITIONS : public SELECTION_CONDITIONS
{
public:
/**
* Function OnlyConnectedItems
* Tests if selection contains exclusively connected items (pads, tracks, vias, zones).
* @param aSelection is the selection to be tested.
* @return True if there are only connected items connected.
*/
static bool OnlyConnectedItems( const SELECTION& aSelection );
/**
* Function SameNet
* Creates a functor that tests if selection contains items belonging to the same net or are
* unconnected if aAllowUnconnected == true.
* @param aAllowUnconnected determines if unconnected items (with no net code assigned) should
* be treated as connected to the same net.
* @return Functor testing if selected items are belonging to the same net.
*/
static SELECTION_CONDITION SameNet( bool aAllowUnconnected = false );
/**
* Function SameLayer
* Creates a functor that tests if selection contains items that belong exclusively to the same
* layer. In case of items belonging to multiple layers, it is enough to have a single common
* layer with other items.
* @return Functor testing if selected items share at least one common layer.
*/
static SELECTION_CONDITION SameLayer();
private:
///> Helper function used by SameNet()
static bool sameNetFunc( const SELECTION& aSelection, bool aAllowUnconnected );
///> Helper function used by SameLayer()
static bool sameLayerFunc( const SELECTION& aSelection );
};
#endif /* PCB_SELECTION_CONDITIONS_H_ */

View File

@ -974,7 +974,7 @@ int PCBNEW_CONTROL::AppendBoard( const TOOL_EVENT& aEvent )
// Start dragging the appended board
SELECTION_TOOL* selectionTool = m_toolMgr->GetTool<SELECTION_TOOL>();
const SELECTION& selection = selectionTool->GetSelection();
VECTOR2D v( selection.Front()->GetPosition() );
VECTOR2D v( static_cast<BOARD_ITEM*>( selection.Front() )->GetPosition() );
getViewControls()->WarpCursor( v, true, true );
m_toolMgr->InvokeTool( "pcbnew.InteractiveEdit" );

View File

@ -133,8 +133,10 @@ int PLACEMENT_TOOL::AlignTop( const TOOL_EVENT& aEvent )
}
// Move the selected items
for( auto item : selection )
for( auto i : selection )
{
auto item = static_cast<BOARD_ITEM*>( i );
int difference = top - item->GetBoundingBox().GetY();
item->Move( wxPoint( 0, difference ) );
@ -168,8 +170,10 @@ int PLACEMENT_TOOL::AlignBottom( const TOOL_EVENT& aEvent )
}
// Move the selected items
for( auto item : selection )
for( auto i : selection )
{
auto item = static_cast<BOARD_ITEM*>( i );
int difference = bottom - item->GetBoundingBox().GetBottom();
item->Move( wxPoint( 0, difference ) );
@ -203,8 +207,10 @@ int PLACEMENT_TOOL::AlignLeft( const TOOL_EVENT& aEvent )
}
// Move the selected items
for( auto item : selection )
for( auto i : selection )
{
auto item = static_cast<BOARD_ITEM*>( i );
int difference = left - item->GetBoundingBox().GetX();
item->Move( wxPoint( difference, 0 ) );
@ -238,8 +244,10 @@ int PLACEMENT_TOOL::AlignRight( const TOOL_EVENT& aEvent )
}
// Move the selected items
for( auto item : selection )
for( auto i : selection )
{
auto item = static_cast<BOARD_ITEM*>( i );
int difference = right - item->GetBoundingBox().GetRight();
item->Move( wxPoint( difference, 0 ) );
@ -277,7 +285,7 @@ int PLACEMENT_TOOL::DistributeHorizontally( const TOOL_EVENT& aEvent )
std::vector<BOARD_ITEM*> itemsList;
for( auto item : selection )
itemsList.push_back( item );
itemsList.push_back( static_cast<BOARD_ITEM*>( item ) );
// Sort items by X coordinate
std::sort(itemsList.begin(), itemsList.end(), compareX );
@ -320,7 +328,7 @@ int PLACEMENT_TOOL::DistributeVertically( const TOOL_EVENT& aEvent )
std::vector<BOARD_ITEM*> itemsList;
for( auto item : selection )
itemsList.push_back( item );
itemsList.push_back( static_cast<BOARD_ITEM*>( item ) );
// Sort items by Y coordinate
std::sort( itemsList.begin(), itemsList.end(), compareY );

View File

@ -337,7 +337,7 @@ SELECTION& SELECTION_TOOL::GetSelection()
// Filter out not modifiable items
for( auto item : items )
{
if( !modifiable( item ) )
if( !modifiable( static_cast<BOARD_ITEM*>( item ) ) )
{
m_selection.Remove( item );
}
@ -506,7 +506,7 @@ bool SELECTION_TOOL::selectMultiple()
}
if( m_selection.Size() == 1 )
m_frame->SetCurItem( m_selection.Front() );
m_frame->SetCurItem( static_cast<BOARD_ITEM*>( m_selection.Front() ) );
else
m_frame->SetCurItem( NULL );
@ -687,8 +687,9 @@ int SELECTION_TOOL::selectCopper( const TOOL_EVENT& aEvent )
// copy the selection, since we're going to iterate and modify
auto selection = m_selection.GetItems();
for( auto item : selection )
for( auto i : selection )
{
auto item = static_cast<BOARD_ITEM*>( i );
// only connected items can be traversed in the ratsnest
if ( item->IsConnected() )
{
@ -751,8 +752,9 @@ int SELECTION_TOOL::selectNet( const TOOL_EVENT& aEvent )
// copy the selection, since we're going to iterate and modify
auto selection = m_selection.GetItems();
for( auto item : selection )
for( auto i : selection )
{
auto item = static_cast<BOARD_ITEM*>( i );
// only connected items get a net code
if( item->IsConnected() )
{
@ -794,19 +796,19 @@ int SELECTION_TOOL::selectSameSheet( const TOOL_EVENT& aEvent )
std::list<MODULE*> modList;
// store all modules that are on that sheet
for( MODULE* item = modules; item; item = item->Next() )
for( MODULE* mitem = modules; mitem; mitem = mitem->Next() )
{
if ( item != NULL && item->GetPath().Contains( sheetPath ) )
if ( mitem != NULL && mitem->GetPath().Contains( sheetPath ) )
{
modList.push_back( item );
modList.push_back( mitem );
}
}
//Generate a list of all pads, and of all nets they belong to.
std::list<int> netcodeList;
for( MODULE* mod : modList )
for( MODULE* mmod : modList )
{
for( D_PAD* pad = mod->Pads().GetFirst(); pad; pad = pad->Next() )
for( D_PAD* pad = mmod->Pads().GetFirst(); pad; pad = pad->Next() )
{
if( pad->IsConnected() )
{
@ -828,9 +830,9 @@ int SELECTION_TOOL::selectSameSheet( const TOOL_EVENT& aEvent )
{
std::list<BOARD_CONNECTED_ITEM*> netPads;
ratsnest->GetNetItems( netCode, netPads, (RN_ITEM_TYPE)( RN_PADS ) );
for( BOARD_CONNECTED_ITEM* item : netPads )
for( BOARD_CONNECTED_ITEM* mitem : netPads )
{
bool found = ( std::find( modList.begin(), modList.end(), item->GetParent() ) != modList.end() );
bool found = ( std::find( modList.begin(), modList.end(), mitem->GetParent() ) != modList.end() );
if( !found )
{
// if we cannot find the module of the pad in the modList
@ -1044,8 +1046,9 @@ int SELECTION_TOOL::filterSelection( const TOOL_EVENT& aEvent )
// copy selection items from the saved selection
// according to the dialog options
for( auto item : selection )
for( auto i : selection )
{
auto item = static_cast<BOARD_ITEM*>( i );
bool include = itemIsIncludedByFilter( *item, board, layerMask, opts );
if( include )
@ -1063,7 +1066,7 @@ void SELECTION_TOOL::clearSelection()
return;
for( auto item : m_selection )
unselectVisually( item );
unselectVisually( static_cast<BOARD_ITEM*>( item ) );
m_selection.Clear();
@ -1704,8 +1707,9 @@ bool SELECTION_TOOL::SanitizeSelection()
if( !m_editModules )
{
for( auto item : m_selection )
for( auto i : m_selection )
{
auto item = static_cast<BOARD_ITEM*>( i );
if( item->Type() == PCB_PAD_T )
{
MODULE* mod = static_cast<MODULE*>( item->GetParent() );
@ -1748,13 +1752,14 @@ bool SELECTION_TOOL::SanitizeSelection()
}
// TODO(JE) Only works for BOARD_ITEM
VECTOR2I SELECTION::GetCenter() const
{
VECTOR2I centre;
if( Size() == 1 )
{
centre = Front()->GetCenter();
centre = static_cast<BOARD_ITEM*>( Front() )->GetCenter();
}
else
{

View File

@ -31,9 +31,10 @@
#include <math/vector2d.h>
#include <tools/pcb_tool.h>
#include <tool/context_menu.h>
#include <tool/selection.h>
#include "selection_conditions.h"
#include "tool_menu.h"
#include <tools/pcb_selection_conditions.h>
#include <tool/tool_menu.h>
class PCB_BASE_FRAME;
class SELECTION_AREA;
@ -45,111 +46,6 @@ namespace KIGFX
class GAL;
}
struct SELECTION : public KIGFX::VIEW_GROUP
{
public:
using ITER = std::set<BOARD_ITEM*>::iterator;
using CITER = std::set<BOARD_ITEM*>::const_iterator;
ITER begin() { return m_items.begin(); }
ITER end() { return m_items.end(); }
CITER begin() const { return m_items.cbegin(); }
CITER end() const { return m_items.cend(); }
virtual void Add( BOARD_ITEM* aItem )
{
m_items.insert( aItem );
}
virtual void Remove( BOARD_ITEM *aItem )
{
m_items.erase( aItem );
}
virtual void Clear() override
{
m_items.clear();
}
virtual unsigned int GetSize() const override
{
return m_items.size();
}
virtual KIGFX::VIEW_ITEM* GetItem( unsigned int idx ) const override
{
auto iter = m_items.begin();
std::advance( iter, idx );
return *iter;
}
bool Contains( BOARD_ITEM* aItem ) const
{
return m_items.find( aItem ) != m_items.end();
}
/// Checks if there is anything selected
bool Empty() const
{
return ( m_items.size() == 0 );
}
/// Returns the number of selected parts
int Size() const
{
return m_items.size();
}
const std::set<BOARD_ITEM*> GetItems() const
{
return m_items;
}
/// Returns the center point of the selection area bounding box.
VECTOR2I GetCenter() const;
BOARD_ITEM* operator[]( const int index ) const
{
if( index < 0 || (unsigned int) index >= m_items.size() )
return nullptr;
auto iter = m_items.begin();
std::advance( iter, index );
return *iter;
}
BOARD_ITEM* Front() const
{
if ( !m_items.size() )
return nullptr;
return *m_items.begin();
}
std::set<BOARD_ITEM*>& Items()
{
return m_items;
}
virtual const VIEW_GROUP::ITEMS updateDrawList() const override;
private:
/// Set of selected items
std::set<BOARD_ITEM*> m_items;
// mute hidden overloaded virtual function warnings
using VIEW_GROUP::Add;
using VIEW_GROUP::Remove;
};
enum SELECTION_LOCK_FLAGS
{
SELECTION_UNLOCKED = 0,
SELECTION_LOCK_OVERRIDE = 1,
SELECTION_LOCKED = 2
};
/**
* Class SELECTION_TOOL