Zone merging (GAL).

This commit is contained in:
Maciej Suminski 2015-06-19 17:32:33 +02:00
parent 39ddb3e9ae
commit a988ebaabd
6 changed files with 140 additions and 6 deletions

View File

@ -186,6 +186,13 @@ void CONTEXT_MENU::UpdateAll()
}
TOOL_MANAGER* CONTEXT_MENU::getToolManager()
{
assert( m_tool );
return m_tool->GetManager();
}
void CONTEXT_MENU::updateHotKeys()
{
for( std::map<int, const TOOL_ACTION*>::const_iterator it = m_toolActions.begin();

View File

@ -125,6 +125,7 @@ public:
*/
void UpdateAll();
// Helper typedefs
typedef boost::function<OPT_TOOL_EVENT(const wxMenuEvent&)> MENU_HANDLER;
typedef boost::function<void()> UPDATE_HANDLER;
@ -146,6 +147,16 @@ public:
m_update_handler = aUpdateHandler;
}
protected:
///> Returns an instance of TOOL_MANAGER class.
TOOL_MANAGER* getToolManager();
///> Returns the corresponding wxMenuItem identifier for a TOOL_ACTION object.
static inline int getMenuId( const TOOL_ACTION& aAction )
{
return aAction.GetId() + ACTION_ID;
}
private:
// Empty stubs used by the default constructor
static OPT_TOOL_EVENT menuHandlerStub(const wxMenuEvent& );
@ -183,12 +194,6 @@ private:
///> Runs a function on the menu and all its submenus.
void runOnSubmenus( boost::function<void(CONTEXT_MENU*)> aFunction );
///> Returns the corresponding wxMenuItem identifier for a TOOL_ACTION object.
static inline int getMenuId( const TOOL_ACTION& aAction )
{
return aAction.GetId() + ACTION_ID;
}
///> Flag indicating that the menu title was set up.
bool m_titleSet;

View File

@ -374,6 +374,10 @@ TOOL_ACTION COMMON_ACTIONS::zoneUnfillAll( "pcbnew.EditorControl.zoneUnfillAll",
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_ZONE_REMOVE_FILLED ),
_( "Unfill all" ), _( "Unfill all zones" ) );
TOOL_ACTION COMMON_ACTIONS::zoneMerge( "pcbnew.EditorControl.zoneMerge",
AS_GLOBAL, 0,
_( "Merge zones" ), _( "Merge zones" ) );
TOOL_ACTION COMMON_ACTIONS::placeTarget( "pcbnew.EditorControl.placeTarget",
AS_GLOBAL, 0,

View File

@ -242,6 +242,7 @@ public:
static TOOL_ACTION zoneFillAll;
static TOOL_ACTION zoneUnfill;
static TOOL_ACTION zoneUnfillAll;
static TOOL_ACTION zoneMerge;
// Module editor tools
/// Activation of the drawing tool (placing a PAD)

View File

@ -42,11 +42,14 @@
#include <class_mire.h>
#include <ratsnest_data.h>
#include <collectors.h>
#include <zones_functions_for_undo_redo.h>
#include <view/view_group.h>
#include <view/view_controls.h>
#include <origin_viewitem.h>
#include <boost/bind.hpp>
class ZONE_CONTEXT_MENU : public CONTEXT_MENU
{
@ -54,10 +57,26 @@ public:
ZONE_CONTEXT_MENU()
{
SetIcon( add_zone_xpm );
SetUpdateHandler( boost::bind( &ZONE_CONTEXT_MENU::update, this ) );
Add( COMMON_ACTIONS::zoneFill );
Add( COMMON_ACTIONS::zoneFillAll );
Add( COMMON_ACTIONS::zoneUnfill );
Add( COMMON_ACTIONS::zoneUnfillAll );
Add( COMMON_ACTIONS::zoneMerge );
}
private:
void update()
{
SELECTION_TOOL* selTool = getToolManager()->GetTool<SELECTION_TOOL>();
// lines like this make me really think about a better name for SELECTION_CONDITIONS class
bool mergeEnabled = ( SELECTION_CONDITIONS::MoreThan( 1 ) &&
/*SELECTION_CONDITIONS::OnlyType( PCB_ZONE_AREA_T ) &&*/
SELECTION_CONDITIONS::SameNet() &&
SELECTION_CONDITIONS::SameLayer() )( selTool->GetSelection() );
Enable( getMenuId( COMMON_ACTIONS::zoneMerge ), mergeEnabled );
}
};
@ -473,6 +492,102 @@ int PCB_EDITOR_CONTROL::ZoneUnfillAll( const TOOL_EVENT& aEvent )
}
int PCB_EDITOR_CONTROL::ZoneMerge( const TOOL_EVENT& aEvent )
{
SELECTION selection = m_toolMgr->GetTool<SELECTION_TOOL>()->GetSelection();
BOARD* board = getModel<BOARD>();
RN_DATA* ratsnest = board->GetRatsnest();
KIGFX::VIEW* view = getView();
if( selection.Size() < 2 )
return 0;
PICKED_ITEMS_LIST changes;
int netcode = -1;
// Loop through all combinations
for( int ia1 = 0; ia1 < selection.Size() - 1; ++ia1 )
{
ZONE_CONTAINER* curr_area = dynamic_cast<ZONE_CONTAINER*>( selection.Item<EDA_ITEM>( ia1 ) );
if( !curr_area )
continue;
netcode = curr_area->GetNetCode();
EDA_RECT b1 = curr_area->Outline()->GetBoundingBox();
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( !area2 )
continue;
if( area2->GetNetCode() != netcode )
continue;
if( curr_area->GetPriority() != area2->GetPriority() )
continue;
if( curr_area->GetIsKeepout() != area2->GetIsKeepout() )
continue;
if( curr_area->GetLayer() != area2->GetLayer() )
continue;
EDA_RECT b2 = area2->Outline()->GetBoundingBox();
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
{
delete backup;
}
}
}
if( mod_ia1 )
--ia1; // if modified, we need to check it again
}
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
m_frame->SaveCopyInUndoList( changes, UR_UNSPECIFIED );
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 )
{
item->ViewUpdate( KIGFX::VIEW_ITEM::ALL );
m_toolMgr->RunAction( COMMON_ACTIONS::selectItem, true, item );
}
}
return 0;
}
int PCB_EDITOR_CONTROL::SelectionCrossProbe( const TOOL_EVENT& aEvent )
{
SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
@ -575,6 +690,7 @@ void PCB_EDITOR_CONTROL::SetTransitions()
Go( &PCB_EDITOR_CONTROL::ZoneFillAll, COMMON_ACTIONS::zoneFillAll.MakeEvent() );
Go( &PCB_EDITOR_CONTROL::ZoneUnfill, COMMON_ACTIONS::zoneUnfill.MakeEvent() );
Go( &PCB_EDITOR_CONTROL::ZoneUnfillAll, COMMON_ACTIONS::zoneUnfillAll.MakeEvent() );
Go( &PCB_EDITOR_CONTROL::ZoneMerge, COMMON_ACTIONS::zoneMerge.MakeEvent() );
// Placing tools
Go( &PCB_EDITOR_CONTROL::PlaceTarget, COMMON_ACTIONS::placeTarget.MakeEvent() );

View File

@ -60,6 +60,7 @@ public:
int ZoneFillAll( const TOOL_EVENT& aEvent );
int ZoneUnfill( const TOOL_EVENT& aEvent );
int ZoneUnfillAll( const TOOL_EVENT& aEvent );
int ZoneMerge( const TOOL_EVENT& aEvent );
/**
* Function PlaceTarget()