Multiple simplifications to GAL tools in PCBNew:
- Finalize transition to BOARD_COMMIT (removed all remaining uses of PICKED_ITEMS_LIST) and implicit view/ratsnest updates - Simplified SELECTION class, it now can be directly added to a VIEW - Removed unnecesary casts and templates - Introduced C++11 features (range based for, lambdas) where they improve code readability - Added non-undoable COMMITs, which can be used to propagate change notifications to interested listeners (e.g. ratsnest/view)
This commit is contained in:
parent
470ccafaeb
commit
27a10e8597
|
@ -672,16 +672,12 @@ void VIEW::draw( VIEW_ITEM* aItem, bool aImmediate )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void VIEW::draw( VIEW_GROUP* aGroup, bool aImmediate )
|
void VIEW::draw( VIEW_GROUP* aGroup, bool aImmediate )
|
||||||
{
|
{
|
||||||
std::set<VIEW_ITEM*>::const_iterator it;
|
for ( int i = 0; i < aGroup->GetSize(); i++)
|
||||||
|
draw( aGroup->GetItem(i), aImmediate );
|
||||||
for( it = aGroup->Begin(); it != aGroup->End(); ++it )
|
|
||||||
draw( *it, aImmediate );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct VIEW::unlinkItem
|
struct VIEW::unlinkItem
|
||||||
{
|
{
|
||||||
bool operator()( VIEW_ITEM* aItem )
|
bool operator()( VIEW_ITEM* aItem )
|
||||||
|
|
|
@ -49,35 +49,48 @@ VIEW_GROUP::VIEW_GROUP( VIEW* aView ) :
|
||||||
|
|
||||||
VIEW_GROUP::~VIEW_GROUP()
|
VIEW_GROUP::~VIEW_GROUP()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void VIEW_GROUP::Add( VIEW_ITEM* aItem )
|
void VIEW_GROUP::Add( VIEW_ITEM* aItem )
|
||||||
{
|
{
|
||||||
m_items.insert( aItem );
|
m_groupItems.push_back( aItem );
|
||||||
ViewUpdate();
|
ViewUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void VIEW_GROUP::Remove( VIEW_ITEM* aItem )
|
void VIEW_GROUP::Remove( VIEW_ITEM* aItem )
|
||||||
{
|
{
|
||||||
m_items.erase( aItem );
|
for ( auto iter = m_groupItems.begin(); iter != m_groupItems.end(); ++iter)
|
||||||
|
{
|
||||||
|
if ( aItem == *iter )
|
||||||
|
{
|
||||||
|
m_groupItems.erase( iter);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ViewUpdate();
|
ViewUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void VIEW_GROUP::Clear()
|
void VIEW_GROUP::Clear()
|
||||||
{
|
{
|
||||||
m_items.clear();
|
m_groupItems.clear();
|
||||||
ViewUpdate();
|
ViewUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned int VIEW_GROUP::GetSize() const
|
unsigned int VIEW_GROUP::GetSize() const
|
||||||
{
|
{
|
||||||
return m_items.size();
|
return m_groupItems.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VIEW_ITEM *VIEW_GROUP::GetItem(unsigned int idx) const
|
||||||
|
{
|
||||||
|
return m_groupItems[idx];
|
||||||
|
}
|
||||||
|
|
||||||
const BOX2I VIEW_GROUP::ViewBBox() const
|
const BOX2I VIEW_GROUP::ViewBBox() const
|
||||||
{
|
{
|
||||||
|
@ -92,8 +105,10 @@ void VIEW_GROUP::ViewDraw( int aLayer, GAL* aGal ) const
|
||||||
{
|
{
|
||||||
PAINTER* painter = m_view->GetPainter();
|
PAINTER* painter = m_view->GetPainter();
|
||||||
|
|
||||||
|
const auto drawList = updateDrawList();
|
||||||
|
|
||||||
// Draw all items immediately (without caching)
|
// Draw all items immediately (without caching)
|
||||||
for( VIEW_ITEM* item : m_items )
|
for ( auto item : drawList )
|
||||||
{
|
{
|
||||||
aGal->PushDepth();
|
aGal->PushDepth();
|
||||||
|
|
||||||
|
@ -127,31 +142,32 @@ void VIEW_GROUP::ViewGetLayers( int aLayers[], int& aCount ) const
|
||||||
|
|
||||||
void VIEW_GROUP::FreeItems()
|
void VIEW_GROUP::FreeItems()
|
||||||
{
|
{
|
||||||
for( VIEW_ITEM* item : m_items )
|
for (unsigned int i = 0 ; i < GetSize(); i++)
|
||||||
{
|
{
|
||||||
|
VIEW_ITEM *item = GetItem(i);
|
||||||
delete item;
|
delete item;
|
||||||
}
|
}
|
||||||
|
|
||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const VIEW_GROUP::ITEMS VIEW_GROUP::updateDrawList() const
|
||||||
void VIEW_GROUP::ItemsSetVisibility( bool aVisible )
|
|
||||||
{
|
{
|
||||||
std::set<VIEW_ITEM*>::const_iterator it, it_end;
|
return m_groupItems;
|
||||||
|
}
|
||||||
|
|
||||||
for( it = m_items.begin(), it_end = m_items.end(); it != it_end; ++it )
|
/*void VIEW_GROUP::ItemsSetVisibility( bool aVisible )
|
||||||
(*it)->ViewSetVisible( aVisible );
|
{
|
||||||
|
for (unsigned int i = 0 ; i < GetSize(); i++)
|
||||||
|
GetItem(i)->ViewSetVisible( aVisible );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void VIEW_GROUP::ItemsViewUpdate( VIEW_ITEM::VIEW_UPDATE_FLAGS aFlags )
|
void VIEW_GROUP::ItemsViewUpdate( VIEW_ITEM::VIEW_UPDATE_FLAGS aFlags )
|
||||||
{
|
{
|
||||||
std::set<VIEW_ITEM*>::const_iterator it, it_end;
|
for (unsigned int i = 0 ; i < GetSize(); i++)
|
||||||
|
GetItem(i)->ViewUpdate( aFlags );
|
||||||
for( it = m_items.begin(), it_end = m_items.end(); it != it_end; ++it )
|
}*/
|
||||||
(*it)->ViewUpdate( aFlags );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void VIEW_GROUP::updateBbox()
|
void VIEW_GROUP::updateBbox()
|
||||||
|
|
|
@ -109,6 +109,15 @@ public:
|
||||||
///> before the modification.
|
///> before the modification.
|
||||||
COMMIT& Modified( EDA_ITEM* aItem, EDA_ITEM* aCopy );
|
COMMIT& Modified( EDA_ITEM* aItem, EDA_ITEM* aCopy );
|
||||||
|
|
||||||
|
template<class Range>
|
||||||
|
COMMIT& StageItems( const Range& aRange, CHANGE_TYPE aChangeType )
|
||||||
|
{
|
||||||
|
for ( const auto& item : aRange )
|
||||||
|
Stage ( item, aChangeType );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///> Adds a change of the item aItem of type aChangeType to the change list.
|
///> Adds a change of the item aItem of type aChangeType to the change list.
|
||||||
COMMIT& Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType );
|
COMMIT& Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType );
|
||||||
|
|
||||||
|
@ -117,7 +126,7 @@ public:
|
||||||
COMMIT& Stage( const PICKED_ITEMS_LIST& aItems, UNDO_REDO_T aModFlag = UR_UNSPECIFIED );
|
COMMIT& Stage( const PICKED_ITEMS_LIST& aItems, UNDO_REDO_T aModFlag = UR_UNSPECIFIED );
|
||||||
|
|
||||||
///> Executes the changes.
|
///> Executes the changes.
|
||||||
virtual void Push( const wxString& aMessage ) = 0;
|
virtual void Push( const wxString& aMessage = wxT("A commit"), bool aCreateUndoEntry = true) = 0;
|
||||||
|
|
||||||
///> Revertes the commit by restoring the modifed items state.
|
///> Revertes the commit by restoring the modifed items state.
|
||||||
virtual void Revert() = 0;
|
virtual void Revert() = 0;
|
||||||
|
|
|
@ -40,13 +40,20 @@ namespace KIGFX
|
||||||
{
|
{
|
||||||
class VIEW_GROUP : public VIEW_ITEM
|
class VIEW_GROUP : public VIEW_ITEM
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
|
typedef std::vector<VIEW_ITEM *> ITEMS;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VIEW_GROUP( VIEW* aView = NULL );
|
VIEW_GROUP( VIEW* aView = NULL );
|
||||||
virtual ~VIEW_GROUP();
|
virtual ~VIEW_GROUP();
|
||||||
|
|
||||||
/// Helper typedefs
|
/**
|
||||||
typedef std::set<VIEW_ITEM*>::const_iterator const_iter;
|
* Function GetSize()
|
||||||
typedef std::set<VIEW_ITEM*>::iterator iter;
|
* Returns the number of stored items.
|
||||||
|
*
|
||||||
|
* @return Number of stored items.
|
||||||
|
*/
|
||||||
|
virtual unsigned int GetSize() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Add()
|
* Function Add()
|
||||||
|
@ -70,31 +77,8 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void Clear();
|
virtual void Clear();
|
||||||
|
|
||||||
/**
|
|
||||||
* Function Begin()
|
|
||||||
* Returns iterator to beginning.
|
|
||||||
*/
|
|
||||||
inline const_iter Begin() const
|
|
||||||
{
|
|
||||||
return m_items.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
virtual VIEW_ITEM *GetItem(unsigned int idx) const;
|
||||||
* Function End()
|
|
||||||
* Returns iterator to end.
|
|
||||||
*/
|
|
||||||
inline const_iter End() const
|
|
||||||
{
|
|
||||||
return m_items.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function GetSize()
|
|
||||||
* Returns the number of stored items.
|
|
||||||
*
|
|
||||||
* @return Number of stored items.
|
|
||||||
*/
|
|
||||||
virtual unsigned int GetSize() const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function ViewBBox()
|
* Function ViewBBox()
|
||||||
|
@ -157,7 +141,7 @@ public:
|
||||||
*
|
*
|
||||||
* @param aVisible decides if items should be visible or not.
|
* @param aVisible decides if items should be visible or not.
|
||||||
*/
|
*/
|
||||||
virtual void ItemsSetVisibility( bool aVisible );
|
//virtual void ItemsSetVisibility( bool aVisible );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function ItemsViewUpdate()
|
* Function ItemsViewUpdate()
|
||||||
|
@ -165,9 +149,12 @@ public:
|
||||||
*
|
*
|
||||||
* @param aFlags determines the way in which items will be updated.
|
* @param aFlags determines the way in which items will be updated.
|
||||||
*/
|
*/
|
||||||
virtual void ItemsViewUpdate( VIEW_ITEM::VIEW_UPDATE_FLAGS aFlags );
|
//virtual void ItemsViewUpdate( VIEW_ITEM::VIEW_UPDATE_FLAGS aFlags );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
virtual const ITEMS updateDrawList() const;
|
||||||
|
|
||||||
/// These functions cannot be used with VIEW_GROUP as they are intended only to work with
|
/// These functions cannot be used with VIEW_GROUP as they are intended only to work with
|
||||||
/// singular VIEW_ITEMs (there is only one-to-one relation between item/layer combination and
|
/// singular VIEW_ITEMs (there is only one-to-one relation between item/layer combination and
|
||||||
/// its group).
|
/// its group).
|
||||||
|
@ -195,12 +182,15 @@ protected:
|
||||||
/// Layer on which the group is drawn
|
/// Layer on which the group is drawn
|
||||||
int m_layer;
|
int m_layer;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// Container for storing VIEW_ITEMs
|
||||||
|
ITEMS m_groupItems;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateBbox();
|
void updateBbox();
|
||||||
|
|
||||||
/// Container for storing VIEW_ITEMs
|
|
||||||
std::set<VIEW_ITEM*> m_items;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace KIGFX
|
} // namespace KIGFX
|
||||||
|
|
||||||
#endif // VIEW_GROUP_H_
|
#endif // VIEW_GROUP_H_
|
||||||
|
|
|
@ -53,7 +53,7 @@ BOARD_COMMIT::~BOARD_COMMIT()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void BOARD_COMMIT::Push( const wxString& aMessage )
|
void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry)
|
||||||
{
|
{
|
||||||
// Objects potentially interested in changes:
|
// Objects potentially interested in changes:
|
||||||
PICKED_ITEMS_LIST undoList;
|
PICKED_ITEMS_LIST undoList;
|
||||||
|
@ -70,7 +70,6 @@ void BOARD_COMMIT::Push( const wxString& aMessage )
|
||||||
{
|
{
|
||||||
int changeType = ent.m_type & CHT_TYPE;
|
int changeType = ent.m_type & CHT_TYPE;
|
||||||
int changeFlags = ent.m_type & CHT_FLAGS;
|
int changeFlags = ent.m_type & CHT_FLAGS;
|
||||||
bool done = changeFlags & CHT_DONE;
|
|
||||||
BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( ent.m_item );
|
BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( ent.m_item );
|
||||||
|
|
||||||
// Module items need to be saved in the undo buffer before modification
|
// Module items need to be saved in the undo buffer before modification
|
||||||
|
@ -92,10 +91,13 @@ void BOARD_COMMIT::Push( const wxString& aMessage )
|
||||||
assert( ent.m_item->Type() == PCB_MODULE_T );
|
assert( ent.m_item->Type() == PCB_MODULE_T );
|
||||||
assert( ent.m_copy->Type() == PCB_MODULE_T );
|
assert( ent.m_copy->Type() == PCB_MODULE_T );
|
||||||
|
|
||||||
|
if ( aCreateUndoEntry )
|
||||||
|
{
|
||||||
ITEM_PICKER itemWrapper( ent.m_item, UR_CHANGED );
|
ITEM_PICKER itemWrapper( ent.m_item, UR_CHANGED );
|
||||||
itemWrapper.SetLink( ent.m_copy );
|
itemWrapper.SetLink( ent.m_copy );
|
||||||
undoList.PushItem( itemWrapper );
|
undoList.PushItem( itemWrapper );
|
||||||
frame->SaveCopyInUndoList( undoList, UR_CHANGED );
|
frame->SaveCopyInUndoList( undoList, UR_CHANGED );
|
||||||
|
}
|
||||||
|
|
||||||
savedModules.insert( ent.m_item );
|
savedModules.insert( ent.m_item );
|
||||||
static_cast<MODULE*>( ent.m_item )->SetLastEditTime();
|
static_cast<MODULE*>( ent.m_item )->SetLastEditTime();
|
||||||
|
@ -108,9 +110,10 @@ void BOARD_COMMIT::Push( const wxString& aMessage )
|
||||||
{
|
{
|
||||||
if( !m_editModules )
|
if( !m_editModules )
|
||||||
{
|
{
|
||||||
|
if ( aCreateUndoEntry )
|
||||||
undoList.PushItem( ITEM_PICKER( boardItem, UR_NEW ) );
|
undoList.PushItem( ITEM_PICKER( boardItem, UR_NEW ) );
|
||||||
|
|
||||||
if( !done )
|
if( !( changeFlags & CHT_DONE ) )
|
||||||
board->Add( boardItem );
|
board->Add( boardItem );
|
||||||
|
|
||||||
//ratsnest->Add( boardItem ); // TODO currently done by BOARD::Add()
|
//ratsnest->Add( boardItem ); // TODO currently done by BOARD::Add()
|
||||||
|
@ -126,7 +129,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage )
|
||||||
// modules inside modules are not supported yet
|
// modules inside modules are not supported yet
|
||||||
assert( boardItem->Type() != PCB_MODULE_T );
|
assert( boardItem->Type() != PCB_MODULE_T );
|
||||||
|
|
||||||
if( !done )
|
if( !( changeFlags & CHT_DONE ) )
|
||||||
board->m_Modules->Add( boardItem );
|
board->m_Modules->Add( boardItem );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,8 +139,10 @@ void BOARD_COMMIT::Push( const wxString& aMessage )
|
||||||
|
|
||||||
case CHT_REMOVE:
|
case CHT_REMOVE:
|
||||||
{
|
{
|
||||||
if( !m_editModules )
|
if( !m_editModules && aCreateUndoEntry )
|
||||||
|
{
|
||||||
undoList.PushItem( ITEM_PICKER( boardItem, UR_DELETED ) );
|
undoList.PushItem( ITEM_PICKER( boardItem, UR_DELETED ) );
|
||||||
|
}
|
||||||
|
|
||||||
switch( boardItem->Type() )
|
switch( boardItem->Type() )
|
||||||
{
|
{
|
||||||
|
@ -181,7 +186,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage )
|
||||||
{
|
{
|
||||||
view->Remove( boardItem );
|
view->Remove( boardItem );
|
||||||
|
|
||||||
if( !done )
|
if( !( changeFlags & CHT_DONE ) )
|
||||||
{
|
{
|
||||||
MODULE* module = static_cast<MODULE*>( boardItem->GetParent() );
|
MODULE* module = static_cast<MODULE*>( boardItem->GetParent() );
|
||||||
assert( module && module->Type() == PCB_MODULE_T );
|
assert( module && module->Type() == PCB_MODULE_T );
|
||||||
|
@ -206,7 +211,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage )
|
||||||
case PCB_ZONE_AREA_T:
|
case PCB_ZONE_AREA_T:
|
||||||
view->Remove( boardItem );
|
view->Remove( boardItem );
|
||||||
|
|
||||||
if( !done )
|
if( !( changeFlags & CHT_DONE ) )
|
||||||
board->Remove( boardItem );
|
board->Remove( boardItem );
|
||||||
|
|
||||||
//ratsnest->Remove( boardItem ); // currently done by BOARD::Remove()
|
//ratsnest->Remove( boardItem ); // currently done by BOARD::Remove()
|
||||||
|
@ -223,7 +228,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage )
|
||||||
|
|
||||||
view->Remove( module );
|
view->Remove( module );
|
||||||
|
|
||||||
if( !done )
|
if( !( changeFlags & CHT_DONE ) )
|
||||||
board->Remove( module );
|
board->Remove( module );
|
||||||
|
|
||||||
// Clear flags to indicate, that the ratsnest, list of nets & pads are not valid anymore
|
// Clear flags to indicate, that the ratsnest, list of nets & pads are not valid anymore
|
||||||
|
@ -240,7 +245,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage )
|
||||||
|
|
||||||
case CHT_MODIFY:
|
case CHT_MODIFY:
|
||||||
{
|
{
|
||||||
if( !m_editModules )
|
if( !m_editModules && aCreateUndoEntry )
|
||||||
{
|
{
|
||||||
ITEM_PICKER itemWrapper( boardItem, UR_CHANGED );
|
ITEM_PICKER itemWrapper( boardItem, UR_CHANGED );
|
||||||
assert( ent.m_copy );
|
assert( ent.m_copy );
|
||||||
|
@ -259,7 +264,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !m_editModules )
|
if( !m_editModules && aCreateUndoEntry )
|
||||||
frame->SaveCopyInUndoList( undoList, UR_UNSPECIFIED );
|
frame->SaveCopyInUndoList( undoList, UR_UNSPECIFIED );
|
||||||
|
|
||||||
if( TOOL_MANAGER* toolMgr = frame->GetToolManager() )
|
if( TOOL_MANAGER* toolMgr = frame->GetToolManager() )
|
||||||
|
|
|
@ -40,7 +40,7 @@ public:
|
||||||
BOARD_COMMIT( PCB_BASE_FRAME* aFrame );
|
BOARD_COMMIT( PCB_BASE_FRAME* aFrame );
|
||||||
virtual ~BOARD_COMMIT();
|
virtual ~BOARD_COMMIT();
|
||||||
|
|
||||||
virtual void Push( const wxString& aMessage ) override;
|
virtual void Push( const wxString& aMessage = wxT("A commit"), bool aCreateUndoEntry = true) override;
|
||||||
virtual void Revert() override;
|
virtual void Revert() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -54,10 +54,8 @@ DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParen
|
||||||
|
|
||||||
|
|
||||||
// Look for values that are common for every item that is selected
|
// Look for values that are common for every item that is selected
|
||||||
for( int i = 0; i < m_items.Size(); ++i )
|
for ( auto& item : m_items )
|
||||||
{
|
{
|
||||||
const BOARD_ITEM* item = m_items.Item<BOARD_ITEM>( i );
|
|
||||||
|
|
||||||
switch( item->Type() )
|
switch( item->Type() )
|
||||||
{
|
{
|
||||||
case PCB_TRACE_T:
|
case PCB_TRACE_T:
|
||||||
|
@ -212,10 +210,8 @@ bool DIALOG_TRACK_VIA_PROPERTIES::Apply( COMMIT& aCommit )
|
||||||
bool changeLock = m_lockedCbox->Get3StateValue() != wxCHK_UNDETERMINED;
|
bool changeLock = m_lockedCbox->Get3StateValue() != wxCHK_UNDETERMINED;
|
||||||
bool setLock = m_lockedCbox->Get3StateValue() == wxCHK_CHECKED;
|
bool setLock = m_lockedCbox->Get3StateValue() == wxCHK_CHECKED;
|
||||||
|
|
||||||
|
for ( auto item : m_items )
|
||||||
for( int i = 0; i < m_items.Size(); ++i )
|
|
||||||
{
|
{
|
||||||
BOARD_ITEM* item = m_items.Item<BOARD_ITEM>( i );
|
|
||||||
aCommit.Modify( item );
|
aCommit.Modify( item );
|
||||||
|
|
||||||
switch( item->Type() )
|
switch( item->Type() )
|
||||||
|
|
|
@ -50,6 +50,8 @@
|
||||||
#include <class_zone.h>
|
#include <class_zone.h>
|
||||||
#include <class_module.h>
|
#include <class_module.h>
|
||||||
|
|
||||||
|
#include <tools/selection_tool.h>
|
||||||
|
|
||||||
DRAWING_TOOL::DRAWING_TOOL() :
|
DRAWING_TOOL::DRAWING_TOOL() :
|
||||||
PCB_TOOL( "pcbnew.InteractiveDrawing" ), m_view( NULL ),
|
PCB_TOOL( "pcbnew.InteractiveDrawing" ), m_view( NULL ),
|
||||||
m_controls( NULL ), m_board( NULL ), m_frame( NULL ), m_lineWidth( 1 )
|
m_controls( NULL ), m_board( NULL ), m_frame( NULL ), m_lineWidth( 1 )
|
||||||
|
@ -163,7 +165,7 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
||||||
BOARD_COMMIT commit( m_frame );
|
BOARD_COMMIT commit( m_frame );
|
||||||
|
|
||||||
// Add a VIEW_GROUP that serves as a preview for the new item
|
// Add a VIEW_GROUP that serves as a preview for the new item
|
||||||
KIGFX::VIEW_GROUP preview( m_view );
|
SELECTION preview( m_view );
|
||||||
m_view->Add( &preview );
|
m_view->Add( &preview );
|
||||||
|
|
||||||
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
|
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
|
||||||
|
@ -326,7 +328,7 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
|
||||||
int maxThickness;
|
int maxThickness;
|
||||||
|
|
||||||
// Add a VIEW_GROUP that serves as a preview for the new item
|
// Add a VIEW_GROUP that serves as a preview for the new item
|
||||||
KIGFX::VIEW_GROUP preview( m_view );
|
SELECTION preview( m_view );
|
||||||
m_view->Add( &preview );
|
m_view->Add( &preview );
|
||||||
|
|
||||||
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
|
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
|
||||||
|
@ -527,23 +529,22 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
VECTOR2I cursorPos = m_controls->GetCursorPosition();
|
VECTOR2I cursorPos = m_controls->GetCursorPosition();
|
||||||
VECTOR2I delta = cursorPos - (*list.begin())->GetPosition();
|
VECTOR2I delta = cursorPos - list.front()->GetPosition();
|
||||||
|
|
||||||
// Add a VIEW_GROUP that serves as a preview for the new item
|
// Add a VIEW_GROUP that serves as a preview for the new item
|
||||||
KIGFX::VIEW_GROUP preview( m_view );
|
SELECTION preview( m_view );
|
||||||
BOARD_COMMIT commit( m_frame );
|
BOARD_COMMIT commit( m_frame );
|
||||||
|
|
||||||
// Build the undo list & add items to the current view
|
// Build the undo list & add items to the current view
|
||||||
for( auto it = list.begin(), itEnd = list.end(); it != itEnd; ++it )
|
for ( auto item : list )
|
||||||
{
|
{
|
||||||
KICAD_T type = (*it)->Type();
|
KICAD_T type = item->Type();
|
||||||
assert( type == PCB_LINE_T || type == PCB_TEXT_T );
|
assert( type == PCB_LINE_T || type == PCB_TEXT_T );
|
||||||
|
|
||||||
if( type == PCB_LINE_T || type == PCB_TEXT_T )
|
preview.Add( item );
|
||||||
preview.Add( *it );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOARD_ITEM* firstItem = static_cast<BOARD_ITEM*>( *preview.Begin() );
|
BOARD_ITEM* firstItem = preview.Front();
|
||||||
m_view->Add( &preview );
|
m_view->Add( &preview );
|
||||||
|
|
||||||
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
|
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
|
||||||
|
@ -561,8 +562,8 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
delta = cursorPos - firstItem->GetPosition();
|
delta = cursorPos - firstItem->GetPosition();
|
||||||
|
|
||||||
for( KIGFX::VIEW_GROUP::const_iter it = preview.Begin(), end = preview.End(); it != end; ++it )
|
for ( auto item : preview )
|
||||||
static_cast<BOARD_ITEM*>( *it )->Move( wxPoint( delta.x, delta.y ) );
|
item->Move( wxPoint( delta.x, delta.y ) );
|
||||||
|
|
||||||
preview.ViewUpdate();
|
preview.ViewUpdate();
|
||||||
}
|
}
|
||||||
|
@ -572,16 +573,16 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
|
||||||
// TODO it should be handled by EDIT_TOOL, so add items and select?
|
// TODO it should be handled by EDIT_TOOL, so add items and select?
|
||||||
if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
|
if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
|
||||||
{
|
{
|
||||||
for( KIGFX::VIEW_GROUP::const_iter it = preview.Begin(), end = preview.End(); it != end; ++it )
|
for ( auto item : preview )
|
||||||
static_cast<BOARD_ITEM*>( *it )->Rotate( wxPoint( cursorPos.x, cursorPos.y ),
|
item->Rotate( wxPoint( cursorPos.x, cursorPos.y ),
|
||||||
m_frame->GetRotationAngle() );
|
m_frame->GetRotationAngle() );
|
||||||
|
|
||||||
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
|
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
|
||||||
}
|
}
|
||||||
else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
|
else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
|
||||||
{
|
{
|
||||||
for( KIGFX::VIEW_GROUP::const_iter it = preview.Begin(), end = preview.End(); it != end; ++it )
|
for ( auto item : preview )
|
||||||
static_cast<BOARD_ITEM*>( *it )->Flip( wxPoint( cursorPos.x, cursorPos.y ) );
|
item->Flip( wxPoint( cursorPos.x, cursorPos.y ) );
|
||||||
|
|
||||||
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
|
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
|
||||||
}
|
}
|
||||||
|
@ -595,13 +596,10 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
|
||||||
else if( evt->IsClick( BUT_LEFT ) )
|
else if( evt->IsClick( BUT_LEFT ) )
|
||||||
{
|
{
|
||||||
// Place the drawing
|
// Place the drawing
|
||||||
PICKED_ITEMS_LIST picklist;
|
|
||||||
BOARD_ITEM_CONTAINER* parent = m_frame->GetModel();
|
BOARD_ITEM_CONTAINER* parent = m_frame->GetModel();
|
||||||
|
|
||||||
for( KIGFX::VIEW_GROUP::const_iter it = preview.Begin(); it != preview.End(); ++it )
|
for ( auto item : preview )
|
||||||
{
|
{
|
||||||
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( *it );
|
|
||||||
|
|
||||||
if( m_editModules )
|
if( m_editModules )
|
||||||
{
|
{
|
||||||
// Modules use different types for the same things,
|
// Modules use different types for the same things,
|
||||||
|
@ -745,7 +743,7 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic,
|
||||||
DRAWSEGMENT line45;
|
DRAWSEGMENT line45;
|
||||||
|
|
||||||
// Add a VIEW_GROUP that serves as a preview for the new item
|
// Add a VIEW_GROUP that serves as a preview for the new item
|
||||||
KIGFX::VIEW_GROUP preview( m_view );
|
SELECTION preview( m_view );
|
||||||
m_view->Add( &preview );
|
m_view->Add( &preview );
|
||||||
|
|
||||||
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
|
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
|
||||||
|
@ -928,7 +926,7 @@ bool DRAWING_TOOL::drawArc( DRAWSEGMENT*& aGraphic )
|
||||||
helperLine.SetWidth( 1 );
|
helperLine.SetWidth( 1 );
|
||||||
|
|
||||||
// Add a VIEW_GROUP that serves as a preview for the new item
|
// Add a VIEW_GROUP that serves as a preview for the new item
|
||||||
KIGFX::VIEW_GROUP preview( m_view );
|
SELECTION preview( m_view );
|
||||||
m_view->Add( &preview );
|
m_view->Add( &preview );
|
||||||
|
|
||||||
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
|
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
|
||||||
|
@ -1105,7 +1103,7 @@ int DRAWING_TOOL::drawZone( bool aKeepout )
|
||||||
BOARD_COMMIT commit( m_frame );
|
BOARD_COMMIT commit( m_frame );
|
||||||
|
|
||||||
// Add a VIEW_GROUP that serves as a preview for the new item
|
// Add a VIEW_GROUP that serves as a preview for the new item
|
||||||
KIGFX::VIEW_GROUP preview( m_view );
|
SELECTION preview( m_view );
|
||||||
m_view->Add( &preview );
|
m_view->Add( &preview );
|
||||||
|
|
||||||
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
|
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
|
||||||
|
|
|
@ -137,7 +137,7 @@ 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();
|
||||||
const SELECTION& selection = m_selectionTool->GetSelection();
|
SELECTION& selection = m_selectionTool->GetSelection();
|
||||||
|
|
||||||
// Shall the selection be cleared at the end?
|
// Shall the selection be cleared at the end?
|
||||||
bool unselect = selection.Empty();
|
bool unselect = selection.Empty();
|
||||||
|
@ -182,7 +182,7 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
else if( evt->IsAction( &COMMON_ACTIONS::editActivate )
|
else if( evt->IsAction( &COMMON_ACTIONS::editActivate )
|
||||||
|| evt->IsMotion() || evt->IsDrag( BUT_LEFT ) )
|
|| evt->IsMotion() || evt->IsDrag( BUT_LEFT ) )
|
||||||
{
|
{
|
||||||
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( 0 );
|
BOARD_ITEM* item = selection.Front();
|
||||||
|
|
||||||
if( m_dragging && evt->Category() == TC_MOUSE )
|
if( m_dragging && evt->Category() == TC_MOUSE )
|
||||||
{
|
{
|
||||||
|
@ -193,8 +193,8 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
totalMovement += movement;
|
totalMovement += movement;
|
||||||
|
|
||||||
// Drag items to the current cursor position
|
// Drag items to the current cursor position
|
||||||
for( unsigned int i = 0; i < selection.items.GetCount(); ++i )
|
for ( auto item : selection )
|
||||||
selection.Item<BOARD_ITEM>( i )->Move( movement + m_offset );
|
item->Move( movement + m_offset );
|
||||||
|
|
||||||
updateRatsnest( true );
|
updateRatsnest( true );
|
||||||
}
|
}
|
||||||
|
@ -216,10 +216,8 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
lockOverride = true;
|
lockOverride = true;
|
||||||
|
|
||||||
// Save items, so changes can be undone
|
// Save items, so changes can be undone
|
||||||
selection.ForAll<BOARD_ITEM>( [&](BOARD_ITEM* brd_item)
|
for ( auto item : selection )
|
||||||
{
|
m_commit->Modify( item );
|
||||||
m_commit->Modify( brd_item );
|
|
||||||
} );
|
|
||||||
|
|
||||||
m_cursor = controls->GetCursorPosition();
|
m_cursor = controls->GetCursorPosition();
|
||||||
|
|
||||||
|
@ -247,7 +245,7 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
|
selection.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
|
||||||
m_toolMgr->RunAction( COMMON_ACTIONS::editModifiedSelection, true );
|
m_toolMgr->RunAction( COMMON_ACTIONS::editModifiedSelection, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,9 +285,8 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
//editFrame->RestoreCopyFromUndoList( dummy );
|
//editFrame->RestoreCopyFromUndoList( dummy );
|
||||||
//
|
//
|
||||||
// So, instead, reset the position manually
|
// So, instead, reset the position manually
|
||||||
for( unsigned int i = 0; i < selection.items.GetCount(); ++i )
|
for( auto item : selection )
|
||||||
{
|
{
|
||||||
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
|
|
||||||
item->SetPosition( item->GetPosition() - totalMovement );
|
item->SetPosition( item->GetPosition() - totalMovement );
|
||||||
|
|
||||||
// And what about flipping and rotation?
|
// And what about flipping and rotation?
|
||||||
|
@ -307,8 +304,8 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
if( m_dragging )
|
if( m_dragging )
|
||||||
{
|
{
|
||||||
// Update dragging offset (distance between cursor and the first dragged item)
|
// Update dragging offset (distance between cursor and the first dragged item)
|
||||||
m_offset = selection.Item<BOARD_ITEM>( 0 )->GetPosition() - modPoint;
|
m_offset = selection.Front()->GetPosition() - modPoint;
|
||||||
selection.group->ViewUpdate( KIGFX::VIEW_ITEM::ALL );
|
selection.ViewUpdate( KIGFX::VIEW_ITEM::ALL );
|
||||||
updateRatsnest( true );
|
updateRatsnest( true );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -343,7 +340,7 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
|
int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
const SELECTION& selection = m_selectionTool->GetSelection();
|
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?
|
// Shall the selection be cleared at the end?
|
||||||
|
@ -366,7 +363,7 @@ int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
|
||||||
else if( selection.Size() == 1 ) // Properties are displayed when there is only one item selected
|
else if( selection.Size() == 1 ) // Properties are displayed when there is only one item selected
|
||||||
{
|
{
|
||||||
// Display properties dialog
|
// Display properties dialog
|
||||||
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( 0 );
|
BOARD_ITEM* item = selection.Front();
|
||||||
|
|
||||||
// Some of properties dialogs alter pointers, so we should deselect them
|
// Some of properties dialogs alter pointers, so we should deselect them
|
||||||
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
|
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
|
||||||
|
@ -403,9 +400,8 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
wxPoint rotatePoint = getModificationPoint( selection );
|
wxPoint rotatePoint = getModificationPoint( selection );
|
||||||
|
|
||||||
for( unsigned int i = 0; i < selection.items.GetCount(); ++i )
|
for ( auto item : selection )
|
||||||
{
|
{
|
||||||
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
|
|
||||||
m_commit->Modify( item );
|
m_commit->Modify( item );
|
||||||
item->Rotate( rotatePoint, editFrame->GetRotationAngle() );
|
item->Rotate( rotatePoint, editFrame->GetRotationAngle() );
|
||||||
}
|
}
|
||||||
|
@ -435,9 +431,8 @@ int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
wxPoint flipPoint = getModificationPoint( selection );
|
wxPoint flipPoint = getModificationPoint( selection );
|
||||||
|
|
||||||
for( unsigned int i = 0; i < selection.items.GetCount(); ++i )
|
for( auto item : selection )
|
||||||
{
|
{
|
||||||
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
|
|
||||||
m_commit->Modify( item );
|
m_commit->Modify( item );
|
||||||
item->Flip( flipPoint );
|
item->Flip( flipPoint );
|
||||||
}
|
}
|
||||||
|
@ -465,9 +460,8 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
|
||||||
// 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( COMMON_ACTIONS::selectionClear, true );
|
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
|
||||||
|
|
||||||
for( unsigned int i = 0; i < selection.items.GetCount(); ++i )
|
for( auto item : selection )
|
||||||
{
|
{
|
||||||
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
|
|
||||||
m_commit->Remove( item );
|
m_commit->Remove( item );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,9 +494,8 @@ int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
|
||||||
VECTOR2I rp = selection.GetCenter();
|
VECTOR2I rp = selection.GetCenter();
|
||||||
wxPoint rotPoint( rp.x, rp.y );
|
wxPoint rotPoint( rp.x, rp.y );
|
||||||
|
|
||||||
for( unsigned int i = 0; i < selection.items.GetCount(); ++i )
|
for( auto item : selection )
|
||||||
{
|
{
|
||||||
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
|
|
||||||
|
|
||||||
m_commit->Modify( item );
|
m_commit->Modify( item );
|
||||||
item->Move( translation );
|
item->Move( translation );
|
||||||
|
@ -532,7 +525,7 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
// first, check if we have a selection, or try to get one
|
// first, check if we have a selection, or try to get one
|
||||||
SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
||||||
const SELECTION& selection = selTool->GetSelection();
|
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() )
|
if( !hoverSelection() )
|
||||||
|
@ -543,10 +536,8 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
std::vector<BOARD_ITEM*> old_items;
|
std::vector<BOARD_ITEM*> old_items;
|
||||||
|
|
||||||
for( int i = 0; i < selection.Size(); ++i )
|
for ( auto item : selection )
|
||||||
{
|
{
|
||||||
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
|
|
||||||
|
|
||||||
if( item )
|
if( item )
|
||||||
old_items.push_back( item );
|
old_items.push_back( item );
|
||||||
}
|
}
|
||||||
|
@ -621,7 +612,7 @@ private:
|
||||||
|
|
||||||
BOARD_ITEM* getNthItemToArray( int n ) const override
|
BOARD_ITEM* getNthItemToArray( int n ) const override
|
||||||
{
|
{
|
||||||
return m_selection.Item<BOARD_ITEM>( n );
|
return m_selection[n];
|
||||||
}
|
}
|
||||||
|
|
||||||
BOARD* getBoard() const override
|
BOARD* getBoard() const override
|
||||||
|
@ -648,11 +639,11 @@ private:
|
||||||
true, new_item );
|
true, new_item );
|
||||||
}
|
}
|
||||||
|
|
||||||
void postPushAction( BOARD_ITEM* new_item ) override
|
void postPushAction( BOARD_ITEM* new_item ) //override
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void finalise() override
|
void finalise() // override
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -665,7 +656,7 @@ int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
// first, check if we have a selection, or try to get one
|
// first, check if we have a selection, or try to get one
|
||||||
SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
||||||
const SELECTION& selection = selTool->GetSelection();
|
SELECTION& selection = selTool->GetSelection();
|
||||||
|
|
||||||
// pick up items under the cursor if needed
|
// pick up items under the cursor if needed
|
||||||
if( !hoverSelection() )
|
if( !hoverSelection() )
|
||||||
|
@ -697,15 +688,13 @@ void EDIT_TOOL::SetTransitions()
|
||||||
|
|
||||||
void EDIT_TOOL::updateRatsnest( bool aRedraw )
|
void EDIT_TOOL::updateRatsnest( bool aRedraw )
|
||||||
{
|
{
|
||||||
const SELECTION& selection = m_selectionTool->GetSelection();
|
SELECTION& selection = m_selectionTool->GetSelection();
|
||||||
RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
|
RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
|
||||||
|
|
||||||
ratsnest->ClearSimple();
|
ratsnest->ClearSimple();
|
||||||
|
|
||||||
for( unsigned int i = 0; i < selection.items.GetCount(); ++i )
|
for( auto item : selection )
|
||||||
{
|
{
|
||||||
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
|
|
||||||
|
|
||||||
ratsnest->Update( item );
|
ratsnest->Update( item );
|
||||||
|
|
||||||
if( aRedraw )
|
if( aRedraw )
|
||||||
|
@ -718,7 +707,7 @@ wxPoint EDIT_TOOL::getModificationPoint( const SELECTION& aSelection )
|
||||||
{
|
{
|
||||||
if( aSelection.Size() == 1 )
|
if( aSelection.Size() == 1 )
|
||||||
{
|
{
|
||||||
return aSelection.Item<BOARD_ITEM>( 0 )->GetPosition() - m_offset;
|
return aSelection.Front()->GetPosition() - m_offset;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -759,7 +748,7 @@ bool EDIT_TOOL::hoverSelection( bool aSanitize )
|
||||||
|
|
||||||
int EDIT_TOOL::editFootprintInFpEditor( const TOOL_EVENT& aEvent )
|
int EDIT_TOOL::editFootprintInFpEditor( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
const SELECTION& selection = m_selectionTool->GetSelection();
|
SELECTION& selection = m_selectionTool->GetSelection();
|
||||||
bool unselect = selection.Empty();
|
bool unselect = selection.Empty();
|
||||||
|
|
||||||
if( !hoverSelection() )
|
if( !hoverSelection() )
|
||||||
|
|
|
@ -28,17 +28,11 @@
|
||||||
|
|
||||||
#include <math/vector2d.h>
|
#include <math/vector2d.h>
|
||||||
#include <tools/pcb_tool.h>
|
#include <tools/pcb_tool.h>
|
||||||
#include <view/view_group.h>
|
|
||||||
|
|
||||||
class BOARD_COMMIT;
|
class BOARD_COMMIT;
|
||||||
class BOARD_ITEM;
|
class BOARD_ITEM;
|
||||||
class SELECTION_TOOL;
|
class SELECTION_TOOL;
|
||||||
|
|
||||||
namespace KIGFX
|
|
||||||
{
|
|
||||||
class VIEW_GROUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class EDIT_TOOL
|
* Class EDIT_TOOL
|
||||||
*
|
*
|
||||||
|
@ -164,10 +158,10 @@ private:
|
||||||
{
|
{
|
||||||
const SELECTION& selection = m_selectionTool->GetSelection();
|
const SELECTION& selection = m_selectionTool->GetSelection();
|
||||||
|
|
||||||
if( selection.items.GetCount() != 1 )
|
if( selection.Size() != 1 )
|
||||||
return NULL;
|
return nullptr;
|
||||||
|
|
||||||
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( 0 );
|
auto item = selection[0];
|
||||||
return dyn_cast<T*>( item );
|
return dyn_cast<T*>( item );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -370,9 +370,9 @@ int MODULE_TOOLS::CopyItems( const TOOL_EVENT& aEvent )
|
||||||
// Create a temporary module that contains selected items to ease serialization
|
// Create a temporary module that contains selected items to ease serialization
|
||||||
MODULE module( m_board );
|
MODULE module( m_board );
|
||||||
|
|
||||||
for( int i = 0; i < selection.Size(); ++i )
|
for ( auto item : selection )
|
||||||
{
|
{
|
||||||
BOARD_ITEM* clone = static_cast<BOARD_ITEM*>( selection.Item<BOARD_ITEM>( i )->Clone() );
|
auto clone = static_cast<BOARD_ITEM *> ( item->Clone() );
|
||||||
|
|
||||||
// Do not add reference/value - convert them to the common type
|
// Do not add reference/value - convert them to the common type
|
||||||
if( TEXTE_MODULE* text = dyn_cast<TEXTE_MODULE*>( clone ) )
|
if( TEXTE_MODULE* text = dyn_cast<TEXTE_MODULE*>( clone ) )
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include <class_module.h>
|
#include <class_module.h>
|
||||||
#include <class_mire.h>
|
#include <class_mire.h>
|
||||||
#include <ratsnest_data.h>
|
#include <ratsnest_data.h>
|
||||||
|
#include <ratsnest_data.h>
|
||||||
#include <collectors.h>
|
#include <collectors.h>
|
||||||
#include <zones_functions_for_undo_redo.h>
|
#include <zones_functions_for_undo_redo.h>
|
||||||
#include <board_commit.h>
|
#include <board_commit.h>
|
||||||
|
@ -365,9 +366,8 @@ int PCB_EDITOR_CONTROL::modifyLockSelected( MODIFY_MODE aMode )
|
||||||
|
|
||||||
bool modified = false;
|
bool modified = false;
|
||||||
|
|
||||||
for( int i = 0; i < selection.Size(); ++i )
|
for ( auto item : selection )
|
||||||
{
|
{
|
||||||
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
|
|
||||||
bool prevState = item->IsLocked();
|
bool prevState = item->IsLocked();
|
||||||
|
|
||||||
switch( aMode )
|
switch( aMode )
|
||||||
|
@ -484,15 +484,15 @@ int PCB_EDITOR_CONTROL::PlaceTarget( const TOOL_EVENT& aEvent )
|
||||||
// Zone actions
|
// Zone actions
|
||||||
int PCB_EDITOR_CONTROL::ZoneFill( const TOOL_EVENT& aEvent )
|
int PCB_EDITOR_CONTROL::ZoneFill( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
auto selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
||||||
const SELECTION& selection = selTool->GetSelection();
|
const auto& selection = selTool->GetSelection();
|
||||||
RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
|
RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
|
||||||
|
|
||||||
for( int i = 0; i < selection.Size(); ++i )
|
for ( auto item : selection )
|
||||||
{
|
{
|
||||||
assert( selection.Item<BOARD_ITEM>( i )->Type() == PCB_ZONE_AREA_T );
|
assert( item->Type() == PCB_ZONE_AREA_T );
|
||||||
|
|
||||||
ZONE_CONTAINER* zone = selection.Item<ZONE_CONTAINER>( i );
|
ZONE_CONTAINER* zone = static_cast<ZONE_CONTAINER*> ( item );
|
||||||
m_frame->Fill_Zone( zone );
|
m_frame->Fill_Zone( zone );
|
||||||
zone->SetIsFilled( true );
|
zone->SetIsFilled( true );
|
||||||
ratsnest->Update( zone );
|
ratsnest->Update( zone );
|
||||||
|
@ -527,15 +527,16 @@ int PCB_EDITOR_CONTROL::ZoneFillAll( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
int PCB_EDITOR_CONTROL::ZoneUnfill( const TOOL_EVENT& aEvent )
|
int PCB_EDITOR_CONTROL::ZoneUnfill( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
auto selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
||||||
const SELECTION& selection = selTool->GetSelection();
|
const auto& selection = selTool->GetSelection();
|
||||||
RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
|
RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
|
||||||
|
|
||||||
for( int i = 0; i < selection.Size(); ++i )
|
for ( auto item : selection )
|
||||||
{
|
{
|
||||||
assert( selection.Item<BOARD_ITEM>( i )->Type() == PCB_ZONE_AREA_T );
|
assert( item->Type() == PCB_ZONE_AREA_T );
|
||||||
|
|
||||||
|
ZONE_CONTAINER* zone = static_cast<ZONE_CONTAINER*> ( item );
|
||||||
|
|
||||||
ZONE_CONTAINER* zone = selection.Item<ZONE_CONTAINER>( i );
|
|
||||||
zone->SetIsFilled( false );
|
zone->SetIsFilled( false );
|
||||||
zone->ClearFilledPolysList();
|
zone->ClearFilledPolysList();
|
||||||
ratsnest->Update( zone );
|
ratsnest->Update( zone );
|
||||||
|
@ -567,101 +568,104 @@ int PCB_EDITOR_CONTROL::ZoneUnfillAll( const TOOL_EVENT& aEvent )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool mergeZones ( BOARD_COMMIT& aCommit, std::vector<ZONE_CONTAINER *>& aOriginZones, std::vector<ZONE_CONTAINER *>& aMergedZones )
|
||||||
|
{
|
||||||
|
SHAPE_POLY_SET mergedOutlines = ConvertPolyListToPolySet( aOriginZones[0]->Outline()->m_CornersList );
|
||||||
|
|
||||||
|
for ( unsigned int i = 1; i < aOriginZones.size(); i++ )
|
||||||
|
{
|
||||||
|
SHAPE_POLY_SET areaToMergePoly = ConvertPolyListToPolySet( aOriginZones[i]->Outline()->m_CornersList );
|
||||||
|
|
||||||
|
mergedOutlines.BooleanAdd( areaToMergePoly, SHAPE_POLY_SET::PM_FAST );
|
||||||
|
}
|
||||||
|
|
||||||
|
mergedOutlines.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||||
|
|
||||||
|
// We should have one polygon with hole
|
||||||
|
// We can have 2 polygons with hole, if the 2 initial polygons have only one common corner
|
||||||
|
// and therefore cannot be merged (they are dectected as intersecting)
|
||||||
|
// but we should never have more than 2 polys
|
||||||
|
if( mergedOutlines.OutlineCount() > 1 )
|
||||||
|
{
|
||||||
|
wxLogMessage(wxT("BOARD::CombineAreas error: more than 2 polys after merging") );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( unsigned int i = 1; i < aOriginZones.size(); i++ )
|
||||||
|
{
|
||||||
|
aCommit.Remove( aOriginZones[i] );
|
||||||
|
}
|
||||||
|
|
||||||
|
aCommit.Modify ( aOriginZones[0] );
|
||||||
|
aMergedZones.push_back( aOriginZones[0] );
|
||||||
|
|
||||||
|
aOriginZones[0]->Outline()->m_CornersList = ConvertPolySetToPolyList( mergedOutlines );
|
||||||
|
aOriginZones[0]->SetLocalFlags( 1 );
|
||||||
|
aOriginZones[0]->Outline()->Hatch();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
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();
|
SELECTION& selection = m_toolMgr->GetTool<SELECTION_TOOL>()->GetSelection();
|
||||||
BOARD* board = getModel<BOARD>();
|
BOARD* board = getModel<BOARD>();
|
||||||
RN_DATA* ratsnest = board->GetRatsnest();
|
|
||||||
KIGFX::VIEW* view = getView();
|
|
||||||
BOARD_COMMIT commit( m_frame );
|
BOARD_COMMIT commit( m_frame );
|
||||||
|
|
||||||
if( selection.Size() < 2 )
|
if( selection.Size() < 2 )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
PICKED_ITEMS_LIST changes;
|
|
||||||
int netcode = -1;
|
int netcode = -1;
|
||||||
|
|
||||||
// Loop through all combinations
|
ZONE_CONTAINER *firstZone = nullptr;
|
||||||
for( int ia1 = 0; ia1 < selection.Size() - 1; ++ia1 )
|
std::vector<ZONE_CONTAINER *> toMerge, merged;
|
||||||
|
|
||||||
|
|
||||||
|
for ( auto item : selection )
|
||||||
{
|
{
|
||||||
ZONE_CONTAINER* curr_area = dynamic_cast<ZONE_CONTAINER*>( selection.Item<EDA_ITEM>( ia1 ) );
|
auto curr_area = dynamic_cast<ZONE_CONTAINER*>( item );
|
||||||
|
|
||||||
if( !curr_area )
|
if( !curr_area )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if( !firstZone )
|
||||||
|
firstZone = curr_area;
|
||||||
|
|
||||||
netcode = curr_area->GetNetCode();
|
netcode = curr_area->GetNetCode();
|
||||||
|
|
||||||
EDA_RECT b1 = curr_area->Outline()->GetBoundingBox();
|
if ( firstZone )
|
||||||
bool mod_ia1 = false;
|
|
||||||
|
|
||||||
for( int ia2 = selection.Size() - 1; ia2 > ia1; --ia2 )
|
|
||||||
{
|
{
|
||||||
ZONE_CONTAINER* area2 = dynamic_cast<ZONE_CONTAINER*>( selection.Item<EDA_ITEM>( ia2 ) );
|
if( firstZone->GetNetCode() != netcode )
|
||||||
|
|
||||||
if( !area2 )
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( area2->GetNetCode() != netcode )
|
if( curr_area->GetPriority() != firstZone->GetPriority() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( curr_area->GetPriority() != area2->GetPriority() )
|
if( curr_area->GetIsKeepout() != firstZone->GetIsKeepout() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( curr_area->GetIsKeepout() != area2->GetIsKeepout() )
|
if( curr_area->GetLayer() != firstZone->GetLayer() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( curr_area->GetLayer() != area2->GetLayer() )
|
if (! board->TestAreaIntersection( curr_area, firstZone ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
EDA_RECT b2 = area2->Outline()->GetBoundingBox();
|
toMerge.push_back(curr_area);
|
||||||
|
|
||||||
if( b1.Intersects( b2 ) )
|
|
||||||
{
|
|
||||||
EDA_ITEM* backup = curr_area->Clone();
|
|
||||||
bool ret = board->TestAreaIntersection( curr_area, area2 );
|
|
||||||
|
|
||||||
if( ret && board->CombineAreas( &changes, curr_area, area2 ) )
|
|
||||||
{
|
|
||||||
mod_ia1 = true;
|
|
||||||
selection.items.RemovePicker( ia2 );
|
|
||||||
|
|
||||||
ITEM_PICKER picker( curr_area, UR_CHANGED );
|
|
||||||
picker.SetLink( backup );
|
|
||||||
changes.PushItem( picker );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
delete backup;
|
toMerge.push_back(curr_area);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if( mod_ia1 )
|
|
||||||
--ia1; // if modified, we need to check it again
|
|
||||||
}
|
|
||||||
|
|
||||||
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
|
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
|
||||||
|
|
||||||
commit.Stage( changes );
|
if ( mergeZones( commit, toMerge, merged ) )
|
||||||
|
|
||||||
for( unsigned i = 0; i < changes.GetCount(); ++i )
|
|
||||||
{
|
|
||||||
ITEM_PICKER picker = changes.GetItemWrapper( i );
|
|
||||||
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( picker.GetItem() );
|
|
||||||
|
|
||||||
if( picker.GetStatus() == UR_DELETED )
|
|
||||||
{
|
|
||||||
view->Remove( item );
|
|
||||||
ratsnest->Remove( item );
|
|
||||||
}
|
|
||||||
else if( picker.GetStatus() == UR_CHANGED )
|
|
||||||
{
|
{
|
||||||
|
commit.Push( _( "Merge zones" ) );
|
||||||
|
for ( auto item : merged )
|
||||||
m_toolMgr->RunAction( COMMON_ACTIONS::selectItem, true, item );
|
m_toolMgr->RunAction( COMMON_ACTIONS::selectItem, true, item );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
commit.Push( _( "Merge zones" ) );
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -679,7 +683,7 @@ int PCB_EDITOR_CONTROL::CrossProbePcbToSch( const TOOL_EVENT& aEvent )
|
||||||
const SELECTION& selection = selTool->GetSelection();
|
const SELECTION& selection = selTool->GetSelection();
|
||||||
|
|
||||||
if( selection.Size() == 1 )
|
if( selection.Size() == 1 )
|
||||||
m_frame->SendMessageToEESCHEMA( selection.Item<BOARD_ITEM>( 0 ) );
|
m_frame->SendMessageToEESCHEMA( selection.Front() );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <tool/tool_interactive.h>
|
#include <tool/tool_interactive.h>
|
||||||
#include <wxPcbStruct.h>
|
#include <wxPcbStruct.h>
|
||||||
#include <class_board.h>
|
#include <class_board.h>
|
||||||
|
#include <view/view_group.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class PCB_TOOL
|
* Class PCB_TOOL
|
||||||
|
|
|
@ -740,7 +740,7 @@ static bool deleteItem( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
|
||||||
if( selection.Empty() )
|
if( selection.Empty() )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
bool canBeRemoved = ( selection.Item<EDA_ITEM>( 0 )->Type() != PCB_MODULE_T );
|
bool canBeRemoved = ( selection.Front()->Type() != PCB_MODULE_T );
|
||||||
|
|
||||||
if( canBeRemoved || IsOK( aToolMgr->GetEditFrame(), _( "Are you sure you want to delete item?" ) ) )
|
if( canBeRemoved || IsOK( aToolMgr->GetEditFrame(), _( "Are you sure you want to delete item?" ) ) )
|
||||||
aToolMgr->RunAction( COMMON_ACTIONS::remove, true );
|
aToolMgr->RunAction( COMMON_ACTIONS::remove, true );
|
||||||
|
@ -897,7 +897,7 @@ int PCBNEW_CONTROL::AppendBoard( const TOOL_EVENT& aEvent )
|
||||||
// Start dragging the appended board
|
// Start dragging the appended board
|
||||||
SELECTION_TOOL* selectionTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
SELECTION_TOOL* selectionTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
||||||
const SELECTION& selection = selectionTool->GetSelection();
|
const SELECTION& selection = selectionTool->GetSelection();
|
||||||
VECTOR2D v( selection.Item<BOARD_ITEM>( 0 )->GetPosition() );
|
VECTOR2D v( selection.Front()->GetPosition() );
|
||||||
getViewControls()->WarpCursor( v, true, true );
|
getViewControls()->WarpCursor( v, true, true );
|
||||||
m_toolMgr->InvokeTool( "pcbnew.InteractiveEdit" );
|
m_toolMgr->InvokeTool( "pcbnew.InteractiveEdit" );
|
||||||
|
|
||||||
|
|
|
@ -80,23 +80,22 @@ int PLACEMENT_TOOL::AlignTop( const TOOL_EVENT& aEvent )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
BOARD_COMMIT commit( getEditFrame<PCB_BASE_FRAME>() );
|
BOARD_COMMIT commit( getEditFrame<PCB_BASE_FRAME>() );
|
||||||
commit.Stage( selection.items, UR_CHANGED );
|
commit.StageItems( selection, CHT_MODIFY );
|
||||||
|
|
||||||
// Compute the highest point of selection - it will be the edge of alignment
|
// Compute the highest point of selection - it will be the edge of alignment
|
||||||
int top = selection.Item<BOARD_ITEM>( 0 )->GetBoundingBox().GetY();
|
int top = selection.Front()->GetBoundingBox().GetY();
|
||||||
|
|
||||||
for( int i = 1; i < selection.Size(); ++i )
|
for( int i = 1; i < selection.Size(); ++i )
|
||||||
{
|
{
|
||||||
int currentTop = selection.Item<BOARD_ITEM>( i )->GetBoundingBox().GetY();
|
int currentTop = selection[i]->GetBoundingBox().GetY();
|
||||||
|
|
||||||
if( top > currentTop ) // Y decreases when going up
|
if( top > currentTop ) // Y decreases when going up
|
||||||
top = currentTop;
|
top = currentTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move the selected items
|
// Move the selected items
|
||||||
for( int i = 0; i < selection.Size(); ++i )
|
for ( auto item : selection )
|
||||||
{
|
{
|
||||||
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
|
|
||||||
int difference = top - item->GetBoundingBox().GetY();
|
int difference = top - item->GetBoundingBox().GetY();
|
||||||
|
|
||||||
item->Move( wxPoint( 0, difference ) );
|
item->Move( wxPoint( 0, difference ) );
|
||||||
|
@ -116,23 +115,22 @@ int PLACEMENT_TOOL::AlignBottom( const TOOL_EVENT& aEvent )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
BOARD_COMMIT commit( getEditFrame<PCB_BASE_FRAME>() );
|
BOARD_COMMIT commit( getEditFrame<PCB_BASE_FRAME>() );
|
||||||
commit.Stage( selection.items, UR_CHANGED );
|
commit.StageItems( selection, CHT_MODIFY );
|
||||||
|
|
||||||
// Compute the lowest point of selection - it will be the edge of alignment
|
// Compute the lowest point of selection - it will be the edge of alignment
|
||||||
int bottom = selection.Item<BOARD_ITEM>( 0 )->GetBoundingBox().GetBottom();
|
int bottom = selection.Front()->GetBoundingBox().GetBottom();
|
||||||
|
|
||||||
for( int i = 1; i < selection.Size(); ++i )
|
for( int i = 1; i < selection.Size(); ++i )
|
||||||
{
|
{
|
||||||
int currentBottom = selection.Item<BOARD_ITEM>( i )->GetBoundingBox().GetBottom();
|
int currentBottom = selection[i]->GetBoundingBox().GetBottom();
|
||||||
|
|
||||||
if( bottom < currentBottom ) // Y increases when going down
|
if( bottom < currentBottom ) // Y increases when going down
|
||||||
bottom = currentBottom;
|
bottom = currentBottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move the selected items
|
// Move the selected items
|
||||||
for( int i = 0; i < selection.Size(); ++i )
|
for ( auto item : selection )
|
||||||
{
|
{
|
||||||
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
|
|
||||||
int difference = bottom - item->GetBoundingBox().GetBottom();
|
int difference = bottom - item->GetBoundingBox().GetBottom();
|
||||||
|
|
||||||
item->Move( wxPoint( 0, difference ) );
|
item->Move( wxPoint( 0, difference ) );
|
||||||
|
@ -152,23 +150,22 @@ int PLACEMENT_TOOL::AlignLeft( const TOOL_EVENT& aEvent )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
BOARD_COMMIT commit( getEditFrame<PCB_BASE_FRAME>() );
|
BOARD_COMMIT commit( getEditFrame<PCB_BASE_FRAME>() );
|
||||||
commit.Stage( selection.items, UR_CHANGED );
|
commit.StageItems( selection, CHT_MODIFY );
|
||||||
|
|
||||||
// Compute the leftmost point of selection - it will be the edge of alignment
|
// Compute the leftmost point of selection - it will be the edge of alignment
|
||||||
int left = selection.Item<BOARD_ITEM>( 0 )->GetBoundingBox().GetX();
|
int left = selection.Front()->GetBoundingBox().GetX();
|
||||||
|
|
||||||
for( int i = 1; i < selection.Size(); ++i )
|
for( int i = 1; i < selection.Size(); ++i )
|
||||||
{
|
{
|
||||||
int currentLeft = selection.Item<BOARD_ITEM>( i )->GetBoundingBox().GetX();
|
int currentLeft = selection[i]->GetBoundingBox().GetX();
|
||||||
|
|
||||||
if( left > currentLeft ) // X decreases when going left
|
if( left > currentLeft ) // X decreases when going left
|
||||||
left = currentLeft;
|
left = currentLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move the selected items
|
// Move the selected items
|
||||||
for( int i = 0; i < selection.Size(); ++i )
|
for ( auto item : selection )
|
||||||
{
|
{
|
||||||
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
|
|
||||||
int difference = left - item->GetBoundingBox().GetX();
|
int difference = left - item->GetBoundingBox().GetX();
|
||||||
|
|
||||||
item->Move( wxPoint( difference, 0 ) );
|
item->Move( wxPoint( difference, 0 ) );
|
||||||
|
@ -188,23 +185,22 @@ int PLACEMENT_TOOL::AlignRight( const TOOL_EVENT& aEvent )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
BOARD_COMMIT commit( getEditFrame<PCB_BASE_FRAME>() );
|
BOARD_COMMIT commit( getEditFrame<PCB_BASE_FRAME>() );
|
||||||
commit.Stage( selection.items, UR_CHANGED );
|
commit.StageItems( selection, CHT_MODIFY );
|
||||||
|
|
||||||
// Compute the rightmost point of selection - it will be the edge of alignment
|
// Compute the rightmost point of selection - it will be the edge of alignment
|
||||||
int right = selection.Item<BOARD_ITEM>( 0 )->GetBoundingBox().GetRight();
|
int right = selection.Front()->GetBoundingBox().GetRight();
|
||||||
|
|
||||||
for( int i = 1; i < selection.Size(); ++i )
|
for( int i = 1; i < selection.Size(); ++i )
|
||||||
{
|
{
|
||||||
int currentRight = selection.Item<BOARD_ITEM>( i )->GetBoundingBox().GetRight();
|
int currentRight = selection[i]->GetBoundingBox().GetRight();
|
||||||
|
|
||||||
if( right < currentRight ) // X increases when going right
|
if( right < currentRight ) // X increases when going right
|
||||||
right = currentRight;
|
right = currentRight;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move the selected items
|
// Move the selected items
|
||||||
for( int i = 0; i < selection.Size(); ++i )
|
for ( auto item : selection )
|
||||||
{
|
{
|
||||||
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
|
|
||||||
int difference = right - item->GetBoundingBox().GetRight();
|
int difference = right - item->GetBoundingBox().GetRight();
|
||||||
|
|
||||||
item->Move( wxPoint( difference, 0 ) );
|
item->Move( wxPoint( difference, 0 ) );
|
||||||
|
@ -236,26 +232,26 @@ int PLACEMENT_TOOL::DistributeHorizontally( const TOOL_EVENT& aEvent )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
BOARD_COMMIT commit( getEditFrame<PCB_BASE_FRAME>() );
|
BOARD_COMMIT commit( getEditFrame<PCB_BASE_FRAME>() );
|
||||||
commit.Stage( selection.items, UR_CHANGED );
|
commit.StageItems( selection, CHT_MODIFY );
|
||||||
|
|
||||||
// Prepare a list, so the items can be sorted by their X coordinate
|
// Prepare a list, so the items can be sorted by their X coordinate
|
||||||
std::list<BOARD_ITEM*> itemsList;
|
std::vector<BOARD_ITEM*> itemsList;
|
||||||
for( int i = 0; i < selection.Size(); ++i )
|
for ( auto item : selection )
|
||||||
itemsList.push_back( selection.Item<BOARD_ITEM>( i ) );
|
itemsList.push_back( item );
|
||||||
|
|
||||||
// Sort items by X coordinate
|
// Sort items by X coordinate
|
||||||
itemsList.sort( compareX );
|
std::sort(itemsList.begin(), itemsList.end(), compareX );
|
||||||
|
|
||||||
// Expected X coordinate for the next item (=minX)
|
// Expected X coordinate for the next item (=minX)
|
||||||
int position = (*itemsList.begin())->GetBoundingBox().Centre().x;
|
int position = itemsList.front()->GetBoundingBox().Centre().x;
|
||||||
|
|
||||||
// X coordinate for the last item
|
// X coordinate for the last item
|
||||||
const int maxX = (*itemsList.rbegin())->GetBoundingBox().Centre().x;
|
const int maxX = itemsList.back()->GetBoundingBox().Centre().x;
|
||||||
|
|
||||||
// Distance between items
|
// Distance between items
|
||||||
const int distance = ( maxX - position ) / ( itemsList.size() - 1 );
|
const int distance = ( maxX - position ) / ( itemsList.size() - 1 );
|
||||||
|
|
||||||
for( BOARD_ITEM* item : itemsList )
|
for( auto item : itemsList )
|
||||||
{
|
{
|
||||||
int difference = position - item->GetBoundingBox().Centre().x;
|
int difference = position - item->GetBoundingBox().Centre().x;
|
||||||
|
|
||||||
|
@ -278,15 +274,15 @@ int PLACEMENT_TOOL::DistributeVertically( const TOOL_EVENT& aEvent )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
BOARD_COMMIT commit( getEditFrame<PCB_BASE_FRAME>() );
|
BOARD_COMMIT commit( getEditFrame<PCB_BASE_FRAME>() );
|
||||||
commit.Stage( selection.items, UR_CHANGED );
|
commit.StageItems( selection, CHT_MODIFY );
|
||||||
|
|
||||||
// Prepare a list, so the items can be sorted by their Y coordinate
|
// Prepare a list, so the items can be sorted by their Y coordinate
|
||||||
std::list<BOARD_ITEM*> itemsList;
|
std::vector<BOARD_ITEM*> itemsList;
|
||||||
for( int i = 0; i < selection.Size(); ++i )
|
for ( auto item : selection )
|
||||||
itemsList.push_back( selection.Item<BOARD_ITEM>( i ) );
|
itemsList.push_back( item );
|
||||||
|
|
||||||
// Sort items by Y coordinate
|
// Sort items by Y coordinate
|
||||||
itemsList.sort( compareY );
|
std::sort(itemsList.begin(), itemsList.end(), compareY );
|
||||||
|
|
||||||
// Expected Y coordinate for the next item (=minY)
|
// Expected Y coordinate for the next item (=minY)
|
||||||
int position = (*itemsList.begin())->GetBoundingBox().Centre().y;
|
int position = (*itemsList.begin())->GetBoundingBox().Centre().y;
|
||||||
|
@ -297,7 +293,7 @@ int PLACEMENT_TOOL::DistributeVertically( const TOOL_EVENT& aEvent )
|
||||||
// Distance between items
|
// Distance between items
|
||||||
const int distance = ( maxY - position ) / ( itemsList.size() - 1 );
|
const int distance = ( maxY - position ) / ( itemsList.size() - 1 );
|
||||||
|
|
||||||
for( BOARD_ITEM* item : itemsList )
|
for( auto item : itemsList )
|
||||||
{
|
{
|
||||||
int difference = position - item->GetBoundingBox().Centre().y;
|
int difference = position - item->GetBoundingBox().Centre().y;
|
||||||
|
|
||||||
|
|
|
@ -249,7 +249,7 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
|
||||||
KIGFX::VIEW_CONTROLS* controls = getViewControls();
|
KIGFX::VIEW_CONTROLS* controls = getViewControls();
|
||||||
KIGFX::VIEW* view = getView();
|
KIGFX::VIEW* view = getView();
|
||||||
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
|
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
|
||||||
EDA_ITEM* item = selection.items.GetPickedItem( 0 );
|
auto item = selection.Front();
|
||||||
|
|
||||||
m_editPoints = EDIT_POINTS_FACTORY::Make( item, getView()->GetGAL() );
|
m_editPoints = EDIT_POINTS_FACTORY::Make( item, getView()->GetGAL() );
|
||||||
|
|
||||||
|
@ -295,7 +295,7 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
if( !modified )
|
if( !modified )
|
||||||
{
|
{
|
||||||
commit.Stage( selection.items, UR_CHANGED );
|
commit.StageItems( selection, CHT_MODIFY );
|
||||||
|
|
||||||
controls->ForceCursorPosition( false );
|
controls->ForceCursorPosition( false );
|
||||||
m_original = *m_editedPoint; // Save the original position
|
m_original = *m_editedPoint; // Save the original position
|
||||||
|
@ -851,7 +851,7 @@ bool POINT_EDITOR::addCornerCondition( const SELECTION& aSelection )
|
||||||
if( aSelection.Size() != 1 )
|
if( aSelection.Size() != 1 )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
BOARD_ITEM* item = aSelection.Item<BOARD_ITEM>( 0 );
|
auto item = aSelection.Front();
|
||||||
|
|
||||||
// Works only for zones and line segments
|
// Works only for zones and line segments
|
||||||
return item->Type() == PCB_ZONE_AREA_T ||
|
return item->Type() == PCB_ZONE_AREA_T ||
|
||||||
|
|
|
@ -41,9 +41,9 @@ bool SELECTION_CONDITIONS::OnlyConnectedItems( const SELECTION& aSelection )
|
||||||
if( aSelection.Empty() )
|
if( aSelection.Empty() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for( int i = 0; i < aSelection.Size(); ++i )
|
for ( const auto &item : aSelection )
|
||||||
{
|
{
|
||||||
KICAD_T type = aSelection.Item<EDA_ITEM>( i )->Type();
|
auto type = item->Type();
|
||||||
|
|
||||||
if( type != PCB_PAD_T && type != PCB_VIA_T && type != PCB_TRACE_T && type != PCB_ZONE_T )
|
if( type != PCB_PAD_T && type != PCB_VIA_T && type != PCB_TRACE_T && type != PCB_ZONE_T )
|
||||||
return false;
|
return false;
|
||||||
|
@ -114,12 +114,12 @@ bool SELECTION_CONDITIONS::sameNetFunc( const SELECTION& aSelection, bool aAllow
|
||||||
|
|
||||||
int netcode = -1; // -1 stands for 'net code is not yet determined'
|
int netcode = -1; // -1 stands for 'net code is not yet determined'
|
||||||
|
|
||||||
for( int i = 0; i < aSelection.Size(); ++i )
|
for ( const auto& aitem : aSelection )
|
||||||
{
|
{
|
||||||
int current_netcode = -1;
|
int current_netcode = -1;
|
||||||
|
|
||||||
const BOARD_CONNECTED_ITEM* item =
|
const BOARD_CONNECTED_ITEM* item =
|
||||||
dynamic_cast<const BOARD_CONNECTED_ITEM*>( aSelection.Item<EDA_ITEM>( i ) );
|
dynamic_cast<const BOARD_CONNECTED_ITEM*>( aitem );
|
||||||
|
|
||||||
if( item )
|
if( item )
|
||||||
{
|
{
|
||||||
|
@ -161,13 +161,8 @@ bool SELECTION_CONDITIONS::sameLayerFunc( const SELECTION& aSelection )
|
||||||
LSET layerSet;
|
LSET layerSet;
|
||||||
layerSet.set();
|
layerSet.set();
|
||||||
|
|
||||||
for( int i = 0; i < aSelection.Size(); ++i )
|
for ( const auto& item : aSelection )
|
||||||
{
|
{
|
||||||
const BOARD_ITEM* item = dynamic_cast<const BOARD_ITEM*>( aSelection.Item<EDA_ITEM>( i ) );
|
|
||||||
|
|
||||||
if( !item )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
layerSet &= item->GetLayerSet();
|
layerSet &= item->GetLayerSet();
|
||||||
|
|
||||||
if( !layerSet.any() ) // there are no common layers left
|
if( !layerSet.any() ) // there are no common layers left
|
||||||
|
@ -180,9 +175,9 @@ bool SELECTION_CONDITIONS::sameLayerFunc( const SELECTION& aSelection )
|
||||||
|
|
||||||
bool SELECTION_CONDITIONS::hasTypeFunc( const SELECTION& aSelection, KICAD_T aType )
|
bool SELECTION_CONDITIONS::hasTypeFunc( const SELECTION& aSelection, KICAD_T aType )
|
||||||
{
|
{
|
||||||
for( int i = 0; i < aSelection.Size(); ++i )
|
for ( const auto& item : aSelection )
|
||||||
{
|
{
|
||||||
if( aSelection.Item<EDA_ITEM>( i )->Type() == aType )
|
if( item->Type() == aType )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,9 +190,9 @@ bool SELECTION_CONDITIONS::onlyTypeFunc( const SELECTION& aSelection, KICAD_T aT
|
||||||
if( aSelection.Empty() )
|
if( aSelection.Empty() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for( int i = 0; i < aSelection.Size(); ++i )
|
for ( const auto& item : aSelection )
|
||||||
{
|
{
|
||||||
if( aSelection.Item<EDA_ITEM>( i )->Type() != aType )
|
if( item->Type() != aType )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,13 +205,13 @@ bool SELECTION_CONDITIONS::onlyTypesFunc( const SELECTION& aSelection, const std
|
||||||
if( aSelection.Empty() )
|
if( aSelection.Empty() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for( int i = 0; i < aSelection.Size(); ++i )
|
for ( const auto& item : aSelection )
|
||||||
{
|
{
|
||||||
bool valid = false;
|
bool valid = false;
|
||||||
|
|
||||||
for( std::vector<KICAD_T>::const_iterator it = aTypes.begin(); it != aTypes.end(); ++it )
|
for( std::vector<KICAD_T>::const_iterator it = aTypes.begin(); it != aTypes.end(); ++it )
|
||||||
{
|
{
|
||||||
if( aSelection.Item<EDA_ITEM>( i )->Type() == *it )
|
if( item->Type() == *it )
|
||||||
{
|
{
|
||||||
valid = true;
|
valid = true;
|
||||||
break;
|
break;
|
||||||
|
@ -236,14 +231,14 @@ bool SELECTION_CONDITIONS::onlyTypesFuncArr( const SELECTION& aSelection, const
|
||||||
if( aSelection.Empty() )
|
if( aSelection.Empty() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for( int i = 0; i < aSelection.Size(); ++i )
|
for ( const auto& item : aSelection )
|
||||||
{
|
{
|
||||||
bool valid = false;
|
bool valid = false;
|
||||||
const KICAD_T* type = aTypes;
|
const KICAD_T* type = aTypes;
|
||||||
|
|
||||||
while( *type != EOT )
|
while( *type != EOT )
|
||||||
{
|
{
|
||||||
if( aSelection.Item<EDA_ITEM>( i )->Type() == *type )
|
if( item->Type() == *type )
|
||||||
{
|
{
|
||||||
valid = true;
|
valid = true;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -80,7 +80,6 @@ SELECTION_TOOL::SELECTION_TOOL() :
|
||||||
|
|
||||||
SELECTION_TOOL::~SELECTION_TOOL()
|
SELECTION_TOOL::~SELECTION_TOOL()
|
||||||
{
|
{
|
||||||
delete m_selection.group;
|
|
||||||
delete m_contextMenu;
|
delete m_contextMenu;
|
||||||
delete m_selectMenu;
|
delete m_selectMenu;
|
||||||
delete m_zoomMenu;
|
delete m_zoomMenu;
|
||||||
|
@ -90,8 +89,6 @@ SELECTION_TOOL::~SELECTION_TOOL()
|
||||||
|
|
||||||
bool SELECTION_TOOL::Init()
|
bool SELECTION_TOOL::Init()
|
||||||
{
|
{
|
||||||
m_selection.group = new KIGFX::VIEW_GROUP;
|
|
||||||
|
|
||||||
m_selectMenu = new SELECT_MENU;
|
m_selectMenu = new SELECT_MENU;
|
||||||
m_selectMenu->SetTool( this );
|
m_selectMenu->SetTool( this );
|
||||||
|
|
||||||
|
@ -129,7 +126,7 @@ void SELECTION_TOOL::Reset( RESET_REASON aReason )
|
||||||
// Remove pointers to the selected items from containers
|
// Remove pointers to the selected items from containers
|
||||||
// without changing their properties (as they are already deleted
|
// without changing their properties (as they are already deleted
|
||||||
// while a new board is loaded)
|
// while a new board is loaded)
|
||||||
m_selection.clear();
|
m_selection.Clear();
|
||||||
getView()->GetPainter()->GetSettings()->SetHighlight( false );
|
getView()->GetPainter()->GetSettings()->SetHighlight( false );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -137,8 +134,8 @@ void SELECTION_TOOL::Reset( RESET_REASON aReason )
|
||||||
clearSelection();
|
clearSelection();
|
||||||
|
|
||||||
// Reinsert the VIEW_GROUP, in case it was removed from the VIEW
|
// Reinsert the VIEW_GROUP, in case it was removed from the VIEW
|
||||||
getView()->Remove( m_selection.group );
|
getView()->Remove( &m_selection );
|
||||||
getView()->Add( m_selection.group );
|
getView()->Add( &m_selection );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -301,24 +298,19 @@ int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const SELECTION& SELECTION_TOOL::GetSelection()
|
SELECTION& SELECTION_TOOL::GetSelection()
|
||||||
{
|
{
|
||||||
// The selected items list has been requested, so it is no longer preliminary
|
// The selected items list has been requested, so it is no longer preliminary
|
||||||
m_preliminary = false;
|
m_preliminary = false;
|
||||||
|
|
||||||
// Filter out not modifiable items
|
auto items = m_selection.GetItems();
|
||||||
for( int i = 0; i < m_selection.Size(); )
|
|
||||||
{
|
|
||||||
BOARD_ITEM* item = m_selection.Item<BOARD_ITEM>( i );
|
|
||||||
|
|
||||||
|
// Filter out not modifiable items
|
||||||
|
for ( auto item : items )
|
||||||
|
{
|
||||||
if( !modifiable( item ) )
|
if( !modifiable( item ) )
|
||||||
{
|
{
|
||||||
m_selection.items.RemovePicker( i );
|
m_selection.Remove( item );
|
||||||
m_selection.group->Remove( item );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
++i;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,7 +352,7 @@ bool SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere, bool aOnDrag )
|
||||||
GENERAL_COLLECTORS_GUIDE guide = m_frame->GetCollectorsGuide();
|
GENERAL_COLLECTORS_GUIDE guide = m_frame->GetCollectorsGuide();
|
||||||
GENERAL_COLLECTOR collector;
|
GENERAL_COLLECTOR collector;
|
||||||
|
|
||||||
collector.Collect( getModel<BOARD>(),
|
collector.Collect( board(),
|
||||||
m_editModules ? GENERAL_COLLECTOR::ModuleItems : GENERAL_COLLECTOR::AllBoardItems,
|
m_editModules ? GENERAL_COLLECTOR::ModuleItems : GENERAL_COLLECTOR::AllBoardItems,
|
||||||
wxPoint( aWhere.x, aWhere.y ), guide );
|
wxPoint( aWhere.x, aWhere.y ), guide );
|
||||||
|
|
||||||
|
@ -485,7 +477,7 @@ bool SELECTION_TOOL::selectMultiple()
|
||||||
}
|
}
|
||||||
|
|
||||||
if( m_selection.Size() == 1 )
|
if( m_selection.Size() == 1 )
|
||||||
m_frame->SetCurItem( m_selection.Item<BOARD_ITEM>( 0 ) );
|
m_frame->SetCurItem( m_selection.Front() );
|
||||||
else
|
else
|
||||||
m_frame->SetCurItem( NULL );
|
m_frame->SetCurItem( NULL );
|
||||||
|
|
||||||
|
@ -530,10 +522,8 @@ SELECTION_LOCK_FLAGS SELECTION_TOOL::CheckLock()
|
||||||
bool containsLocked = false;
|
bool containsLocked = false;
|
||||||
|
|
||||||
// Check if the selection contains locked items
|
// Check if the selection contains locked items
|
||||||
for( int i = 0; i < m_selection.Size(); ++i )
|
for ( const auto& item : m_selection )
|
||||||
{
|
{
|
||||||
BOARD_ITEM* item = m_selection.Item<BOARD_ITEM>( i );
|
|
||||||
|
|
||||||
switch( item->Type() )
|
switch( item->Type() )
|
||||||
{
|
{
|
||||||
case PCB_MODULE_T:
|
case PCB_MODULE_T:
|
||||||
|
@ -624,14 +614,14 @@ int SELECTION_TOOL::selectConnection( const TOOL_EVENT& aEvent )
|
||||||
if( !selectCursor( true ) )
|
if( !selectCursor( true ) )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
BOARD_CONNECTED_ITEM* item = m_selection.Item<BOARD_CONNECTED_ITEM>( 0 );
|
auto item = m_selection.Front();
|
||||||
clearSelection();
|
clearSelection();
|
||||||
|
|
||||||
if( item->Type() != PCB_TRACE_T && item->Type() != PCB_VIA_T )
|
if( item->Type() != PCB_TRACE_T && item->Type() != PCB_VIA_T )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int segmentCount;
|
int segmentCount;
|
||||||
TRACK* trackList = getModel<BOARD>()->MarkTrace( static_cast<TRACK*>( item ), &segmentCount,
|
TRACK* trackList = board()->MarkTrace( static_cast<TRACK*>( item ), &segmentCount,
|
||||||
NULL, NULL, true );
|
NULL, NULL, true );
|
||||||
|
|
||||||
if( segmentCount == 0 )
|
if( segmentCount == 0 )
|
||||||
|
@ -655,7 +645,7 @@ int SELECTION_TOOL::selectCopper( const TOOL_EVENT& aEvent )
|
||||||
if( !selectCursor( true ) )
|
if( !selectCursor( true ) )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
BOARD_CONNECTED_ITEM* item = m_selection.Item<BOARD_CONNECTED_ITEM>( 0 );
|
auto item = static_cast<BOARD_CONNECTED_ITEM*> ( m_selection.Front() );
|
||||||
clearSelection();
|
clearSelection();
|
||||||
|
|
||||||
if( item->Type() != PCB_TRACE_T && item->Type() != PCB_VIA_T )
|
if( item->Type() != PCB_TRACE_T && item->Type() != PCB_VIA_T )
|
||||||
|
@ -682,7 +672,10 @@ int SELECTION_TOOL::selectNet( const TOOL_EVENT& aEvent )
|
||||||
if( !selectCursor( true ) )
|
if( !selectCursor( true ) )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
BOARD_CONNECTED_ITEM* item = m_selection.Item<BOARD_CONNECTED_ITEM>( 0 );
|
auto item = dynamic_cast<BOARD_CONNECTED_ITEM*> ( m_selection.Front() );
|
||||||
|
|
||||||
|
if( !item )
|
||||||
|
return 0;
|
||||||
|
|
||||||
std::list<BOARD_CONNECTED_ITEM*> itemsList;
|
std::list<BOARD_CONNECTED_ITEM*> itemsList;
|
||||||
RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
|
RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
|
||||||
|
@ -752,19 +745,10 @@ void SELECTION_TOOL::clearSelection()
|
||||||
if( m_selection.Empty() )
|
if( m_selection.Empty() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
KIGFX::VIEW_GROUP::const_iter it, it_end;
|
for ( auto item : m_selection )
|
||||||
|
unselectVisually( item );
|
||||||
|
|
||||||
// Restore the initial properties
|
m_selection.Clear();
|
||||||
for( it = m_selection.group->Begin(), it_end = m_selection.group->End(); it != it_end; ++it )
|
|
||||||
{
|
|
||||||
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( *it );
|
|
||||||
|
|
||||||
item->ViewHide( false );
|
|
||||||
item->ClearSelected();
|
|
||||||
item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_selection.clear();
|
|
||||||
|
|
||||||
m_frame->SetCurItem( NULL );
|
m_frame->SetCurItem( NULL );
|
||||||
m_locked = true;
|
m_locked = true;
|
||||||
|
@ -904,8 +888,6 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOARD* board = getModel<BOARD>();
|
|
||||||
|
|
||||||
switch( aItem->Type() )
|
switch( aItem->Type() )
|
||||||
{
|
{
|
||||||
case PCB_VIA_T:
|
case PCB_VIA_T:
|
||||||
|
@ -915,15 +897,15 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
|
||||||
|
|
||||||
static_cast<const VIA*>( aItem )->LayerPair( &top, &bottom );
|
static_cast<const VIA*>( aItem )->LayerPair( &top, &bottom );
|
||||||
|
|
||||||
return board->IsLayerVisible( top ) || board->IsLayerVisible( bottom );
|
return board()->IsLayerVisible( top ) || board()->IsLayerVisible( bottom );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCB_MODULE_T:
|
case PCB_MODULE_T:
|
||||||
if( aItem->IsOnLayer( F_Cu ) && board->IsElementVisible( MOD_FR_VISIBLE ) )
|
if( aItem->IsOnLayer( F_Cu ) && board()->IsElementVisible( MOD_FR_VISIBLE ) )
|
||||||
return !m_editModules;
|
return !m_editModules;
|
||||||
|
|
||||||
if( aItem->IsOnLayer( B_Cu ) && board->IsElementVisible( MOD_BK_VISIBLE ) )
|
if( aItem->IsOnLayer( B_Cu ) && board()->IsElementVisible( MOD_BK_VISIBLE ) )
|
||||||
return !m_editModules;
|
return !m_editModules;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -934,7 +916,7 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
|
||||||
if( m_multiple && !m_editModules )
|
if( m_multiple && !m_editModules )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return aItem->ViewIsVisible() && board->IsLayerVisible( aItem->GetLayer() );
|
return aItem->ViewIsVisible() && board()->IsLayerVisible( aItem->GetLayer() );
|
||||||
|
|
||||||
case PCB_MODULE_EDGE_T:
|
case PCB_MODULE_EDGE_T:
|
||||||
case PCB_PAD_T:
|
case PCB_PAD_T:
|
||||||
|
@ -959,7 +941,7 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// All other items are selected only if the layer on which they exist is visible
|
// All other items are selected only if the layer on which they exist is visible
|
||||||
return board->IsLayerVisible( aItem->GetLayer() );
|
return board()->IsLayerVisible( aItem->GetLayer() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -975,27 +957,20 @@ bool SELECTION_TOOL::modifiable( const BOARD_ITEM* aItem ) const
|
||||||
void SELECTION_TOOL::select( BOARD_ITEM* aItem )
|
void SELECTION_TOOL::select( BOARD_ITEM* aItem )
|
||||||
{
|
{
|
||||||
if( aItem->IsSelected() )
|
if( aItem->IsSelected() )
|
||||||
return;
|
|
||||||
|
|
||||||
// Modules are treated in a special way - when they are selected, we have to mark
|
|
||||||
// all the parts that make the module as selected
|
|
||||||
if( aItem->Type() == PCB_MODULE_T )
|
|
||||||
{
|
{
|
||||||
MODULE* module = static_cast<MODULE*>( aItem );
|
return;
|
||||||
module->RunOnChildren( std::bind( &SELECTION_TOOL::selectVisually, this, _1 ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( aItem->Type() == PCB_PAD_T )
|
if( aItem->Type() == PCB_PAD_T )
|
||||||
{
|
{
|
||||||
MODULE* module = static_cast<MODULE*>( aItem->GetParent() );
|
MODULE* module = static_cast<MODULE*>( aItem->GetParent() );
|
||||||
|
|
||||||
if( m_selection.items.FindItem( module ) >= 0 )
|
if( m_selection.Contains( module ) )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
selectVisually( aItem );
|
selectVisually( aItem );
|
||||||
ITEM_PICKER picker( aItem );
|
m_selection.Add ( aItem );
|
||||||
m_selection.items.PushItem( picker );
|
|
||||||
|
|
||||||
if( m_selection.Size() == 1 )
|
if( m_selection.Size() == 1 )
|
||||||
{
|
{
|
||||||
|
@ -1015,19 +990,8 @@ void SELECTION_TOOL::unselect( BOARD_ITEM* aItem )
|
||||||
if( !aItem->IsSelected() )
|
if( !aItem->IsSelected() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Modules are treated in a special way - when they are selected, we have to
|
|
||||||
// unselect all the parts that make the module, not the module itself
|
|
||||||
if( aItem->Type() == PCB_MODULE_T )
|
|
||||||
{
|
|
||||||
MODULE* module = static_cast<MODULE*>( aItem );
|
|
||||||
module->RunOnChildren( std::bind( &SELECTION_TOOL::unselectVisually, this, _1 ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
unselectVisually( aItem );
|
unselectVisually( aItem );
|
||||||
|
m_selection.Remove( aItem );
|
||||||
int itemIdx = m_selection.items.FindItem( aItem );
|
|
||||||
if( itemIdx >= 0 )
|
|
||||||
m_selection.items.RemovePicker( itemIdx );
|
|
||||||
|
|
||||||
if( m_selection.Empty() )
|
if( m_selection.Empty() )
|
||||||
{
|
{
|
||||||
|
@ -1039,22 +1003,41 @@ void SELECTION_TOOL::unselect( BOARD_ITEM* aItem )
|
||||||
|
|
||||||
void SELECTION_TOOL::selectVisually( BOARD_ITEM* aItem ) const
|
void SELECTION_TOOL::selectVisually( BOARD_ITEM* aItem ) const
|
||||||
{
|
{
|
||||||
m_selection.group->Add( aItem );
|
|
||||||
|
|
||||||
// Hide the original item, so it is shown only on overlay
|
// Hide the original item, so it is shown only on overlay
|
||||||
aItem->ViewHide( true );
|
aItem->ViewHide( true );
|
||||||
aItem->SetSelected();
|
aItem->SetSelected();
|
||||||
|
|
||||||
|
// Modules are treated in a special way - when they are selected, we have to
|
||||||
|
// unselect all the parts that make the module, not the module itself
|
||||||
|
|
||||||
|
if( aItem->Type() == PCB_MODULE_T )
|
||||||
|
{
|
||||||
|
static_cast<MODULE*>( aItem )->RunOnChildren( [] ( BOARD_ITEM *item ) {
|
||||||
|
item->ViewHide( true );
|
||||||
|
item->SetSelected();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SELECTION_TOOL::unselectVisually( BOARD_ITEM* aItem ) const
|
void SELECTION_TOOL::unselectVisually( BOARD_ITEM* aItem ) const
|
||||||
{
|
{
|
||||||
m_selection.group->Remove( aItem );
|
|
||||||
|
|
||||||
// Restore original item visibility
|
// Restore original item visibility
|
||||||
aItem->ViewHide( false );
|
aItem->ViewHide( false );
|
||||||
aItem->ClearSelected();
|
aItem->ClearSelected();
|
||||||
aItem->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
|
aItem->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
|
||||||
|
|
||||||
|
// Modules are treated in a special way - when they are selected, we have to
|
||||||
|
// unselect all the parts that make the module, not the module itself
|
||||||
|
|
||||||
|
if( aItem->Type() == PCB_MODULE_T )
|
||||||
|
{
|
||||||
|
static_cast<MODULE*>( aItem )->RunOnChildren( [] ( BOARD_ITEM *item ) {
|
||||||
|
item->ViewHide( false );
|
||||||
|
item->ClearSelected();
|
||||||
|
item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1064,9 +1047,8 @@ bool SELECTION_TOOL::selectionContains( const VECTOR2I& aPoint ) const
|
||||||
VECTOR2D margin = getView()->ToWorld( VECTOR2D( GRIP_MARGIN, GRIP_MARGIN ), false );
|
VECTOR2D margin = getView()->ToWorld( VECTOR2D( GRIP_MARGIN, GRIP_MARGIN ), false );
|
||||||
|
|
||||||
// Check if the point is located within any of the currently selected items bounding boxes
|
// Check if the point is located within any of the currently selected items bounding boxes
|
||||||
for( unsigned int i = 0; i < m_selection.items.GetCount(); ++i )
|
for( auto item : m_selection )
|
||||||
{
|
{
|
||||||
BOARD_ITEM* item = m_selection.Item<BOARD_ITEM>( i );
|
|
||||||
BOX2I itemBox = item->ViewBBox();
|
BOX2I itemBox = item->ViewBBox();
|
||||||
itemBox.Inflate( margin.x, margin.y ); // Give some margin for gripping an item
|
itemBox.Inflate( margin.x, margin.y ); // Give some margin for gripping an item
|
||||||
|
|
||||||
|
@ -1382,10 +1364,8 @@ bool SELECTION_TOOL::SanitizeSelection()
|
||||||
|
|
||||||
if( !m_editModules )
|
if( !m_editModules )
|
||||||
{
|
{
|
||||||
for( unsigned int i = 0; i < m_selection.items.GetCount(); ++i )
|
for( auto item : m_selection )
|
||||||
{
|
{
|
||||||
BOARD_ITEM* item = m_selection.Item<BOARD_ITEM>( i );
|
|
||||||
|
|
||||||
if( item->Type() == PCB_PAD_T )
|
if( item->Type() == PCB_PAD_T )
|
||||||
{
|
{
|
||||||
MODULE* mod = static_cast<MODULE*>( item->GetParent() );
|
MODULE* mod = static_cast<MODULE*>( item->GetParent() );
|
||||||
|
@ -1400,7 +1380,7 @@ bool SELECTION_TOOL::SanitizeSelection()
|
||||||
}
|
}
|
||||||
|
|
||||||
// case 2: multi-item selection contains both the module and its pads - remove the pads
|
// case 2: multi-item selection contains both the module and its pads - remove the pads
|
||||||
if( mod && m_selection.items.FindItem( mod ) >= 0 )
|
if( mod && m_selection.Contains( mod ) )
|
||||||
rejected.insert( item );
|
rejected.insert( item );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1430,8 +1410,7 @@ bool SELECTION_TOOL::SanitizeSelection()
|
||||||
|
|
||||||
void SELECTION::clear()
|
void SELECTION::clear()
|
||||||
{
|
{
|
||||||
items.ClearItemsList();
|
m_items.clear();
|
||||||
group->Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1441,15 +1420,17 @@ VECTOR2I SELECTION::GetCenter() const
|
||||||
|
|
||||||
if( Size() == 1 )
|
if( Size() == 1 )
|
||||||
{
|
{
|
||||||
centre = Item<BOARD_ITEM>( 0 )->GetCenter();
|
centre = Front()->GetCenter();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EDA_RECT bbox = Item<BOARD_ITEM>( 0 )->GetBoundingBox();
|
EDA_RECT bbox = Front()->GetBoundingBox();
|
||||||
for( unsigned int i = 1; i < items.GetCount(); ++i )
|
auto i = m_items.begin();
|
||||||
|
++i;
|
||||||
|
|
||||||
|
for( ; i != m_items.end(); ++i )
|
||||||
{
|
{
|
||||||
BOARD_ITEM* item = Item<BOARD_ITEM>( i );
|
bbox.Merge( (*i)->GetBoundingBox() );
|
||||||
bbox.Merge( item->GetBoundingBox() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
centre = bbox.Centre();
|
centre = bbox.Centre();
|
||||||
|
@ -1462,3 +1443,25 @@ VECTOR2I SELECTION::GetCenter() const
|
||||||
const TOOL_EVENT SELECTION_TOOL::SelectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.selected" );
|
const TOOL_EVENT SELECTION_TOOL::SelectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.selected" );
|
||||||
const TOOL_EVENT SELECTION_TOOL::UnselectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.unselected" );
|
const TOOL_EVENT SELECTION_TOOL::UnselectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.unselected" );
|
||||||
const TOOL_EVENT SELECTION_TOOL::ClearedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.cleared" );
|
const TOOL_EVENT SELECTION_TOOL::ClearedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.cleared" );
|
||||||
|
|
||||||
|
SELECTION::SELECTION( KIGFX::VIEW *aView ) :
|
||||||
|
KIGFX::VIEW_GROUP ( aView )
|
||||||
|
{}
|
||||||
|
|
||||||
|
const KIGFX::VIEW_GROUP::ITEMS SELECTION::updateDrawList() const
|
||||||
|
{
|
||||||
|
std::vector<VIEW_ITEM *> items;
|
||||||
|
|
||||||
|
items.clear();
|
||||||
|
for ( auto item : m_items )
|
||||||
|
{
|
||||||
|
items.push_back( item );
|
||||||
|
if( item->Type() == PCB_MODULE_T )
|
||||||
|
{
|
||||||
|
MODULE* module = static_cast<MODULE*>( item );
|
||||||
|
module->RunOnChildren( [&] ( BOARD_ITEM *bitem ) { items.push_back(bitem); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
|
@ -26,10 +26,11 @@
|
||||||
#ifndef __SELECTION_TOOL_H
|
#ifndef __SELECTION_TOOL_H
|
||||||
#define __SELECTION_TOOL_H
|
#define __SELECTION_TOOL_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <math/vector2d.h>
|
#include <math/vector2d.h>
|
||||||
#include <tools/pcb_tool.h>
|
#include <tools/pcb_tool.h>
|
||||||
#include <tool/context_menu.h>
|
#include <tool/context_menu.h>
|
||||||
#include <class_undoredo_container.h>
|
|
||||||
|
|
||||||
#include "selection_conditions.h"
|
#include "selection_conditions.h"
|
||||||
#include "conditional_menu.h"
|
#include "conditional_menu.h"
|
||||||
|
@ -44,53 +45,109 @@ class GRID_MENU;
|
||||||
|
|
||||||
namespace KIGFX
|
namespace KIGFX
|
||||||
{
|
{
|
||||||
class VIEW_GROUP;
|
class GAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SELECTION
|
struct SELECTION : public KIGFX::VIEW_GROUP
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
/// Set of selected items
|
/// Set of selected items
|
||||||
PICKED_ITEMS_LIST items;
|
std::set<BOARD_ITEM *> m_items;
|
||||||
|
|
||||||
/// VIEW_GROUP that holds currently selected items
|
public:
|
||||||
KIGFX::VIEW_GROUP* group;
|
using ITER = std::set<BOARD_ITEM *>::iterator;
|
||||||
|
using CITER = std::set<BOARD_ITEM *>::const_iterator;
|
||||||
|
|
||||||
|
SELECTION( KIGFX::VIEW *aView = nullptr );
|
||||||
|
|
||||||
|
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();
|
||||||
|
while(idx--)
|
||||||
|
++iter;
|
||||||
|
|
||||||
|
return *iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Contains( BOARD_ITEM *aItem ) const
|
||||||
|
{
|
||||||
|
return m_items.find (aItem) != m_items.end();
|
||||||
|
}
|
||||||
|
|
||||||
/// Checks if there is anything selected
|
/// Checks if there is anything selected
|
||||||
bool Empty() const
|
bool Empty() const
|
||||||
{
|
{
|
||||||
return ( items.GetCount() == 0 );
|
return ( m_items.size() == 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the number of selected parts
|
/// Returns the number of selected parts
|
||||||
int Size() const
|
int Size() const
|
||||||
{
|
{
|
||||||
return items.GetCount();
|
return m_items.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Alias to make code shorter and clearer
|
const std::set<BOARD_ITEM *> GetItems() const
|
||||||
template <typename T>
|
|
||||||
T* Item( unsigned int aIndex ) const
|
|
||||||
{
|
{
|
||||||
return static_cast<T*>( items.GetPickedItem( aIndex ) );
|
return m_items;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the center point of the selection area bounding box.
|
/// Returns the center point of the selection area bounding box.
|
||||||
VECTOR2I GetCenter() const;
|
VECTOR2I GetCenter() const;
|
||||||
|
|
||||||
/// Runs a function on all selected items.
|
BOARD_ITEM *operator[] ( const int index ) const
|
||||||
template <typename T>
|
|
||||||
void ForAll( std::function<void (T*)> aFunction ) const
|
|
||||||
{
|
{
|
||||||
for( unsigned int i = 0; i < items.GetCount(); ++i )
|
if ( index < 0 || (unsigned int) index >= m_items.size() )
|
||||||
aFunction( Item<T>( i ) );
|
return nullptr;
|
||||||
|
|
||||||
|
return (* m_items.begin() + index );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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:
|
private:
|
||||||
|
|
||||||
|
|
||||||
/// Clears both the VIEW_GROUP and set of selected items. Please note that it does not
|
/// Clears both the VIEW_GROUP and set of selected items. Please note that it does not
|
||||||
/// change properties of selected items (e.g. selection flag).
|
/// change properties of selected items (e.g. selection flag).
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
friend class SELECTION_TOOL;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SELECTION_LOCK_FLAGS
|
enum SELECTION_LOCK_FLAGS
|
||||||
|
@ -135,7 +192,7 @@ public:
|
||||||
*
|
*
|
||||||
* Returns the set of currently selected items.
|
* Returns the set of currently selected items.
|
||||||
*/
|
*/
|
||||||
const SELECTION& GetSelection();
|
SELECTION& GetSelection();
|
||||||
|
|
||||||
inline CONDITIONAL_MENU& GetMenu()
|
inline CONDITIONAL_MENU& GetMenu()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue