pcbnew: via placement tool, initial version
This commit is contained in:
parent
bd960f0e5c
commit
3b7b0603b6
|
@ -256,7 +256,7 @@ public:
|
||||||
DLIST_ITERATOR_WRAPPER<TRACK> Tracks() { return DLIST_ITERATOR_WRAPPER<TRACK>(m_Track); }
|
DLIST_ITERATOR_WRAPPER<TRACK> Tracks() { return DLIST_ITERATOR_WRAPPER<TRACK>(m_Track); }
|
||||||
DLIST_ITERATOR_WRAPPER<MODULE> Modules() { return DLIST_ITERATOR_WRAPPER<MODULE>(m_Modules); }
|
DLIST_ITERATOR_WRAPPER<MODULE> Modules() { return DLIST_ITERATOR_WRAPPER<MODULE>(m_Modules); }
|
||||||
DLIST_ITERATOR_WRAPPER<BOARD_ITEM> Drawings() { return DLIST_ITERATOR_WRAPPER<BOARD_ITEM>(m_Drawings); }
|
DLIST_ITERATOR_WRAPPER<BOARD_ITEM> Drawings() { return DLIST_ITERATOR_WRAPPER<BOARD_ITEM>(m_Drawings); }
|
||||||
|
ZONE_CONTAINERS& Zones() { return m_ZoneDescriptorList; }
|
||||||
|
|
||||||
|
|
||||||
// will be deprecated as soon as append board functionality is fixed
|
// will be deprecated as soon as append board functionality is fixed
|
||||||
|
|
|
@ -990,24 +990,25 @@ void VIA::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, const w
|
||||||
void VIA::ViewGetLayers( int aLayers[], int& aCount ) const
|
void VIA::ViewGetLayers( int aLayers[], int& aCount ) const
|
||||||
{
|
{
|
||||||
aLayers[0] = LAYER_VIAS_HOLES;
|
aLayers[0] = LAYER_VIAS_HOLES;
|
||||||
aCount = 2;
|
aLayers[1] = GetNetnameLayer( m_Layer );
|
||||||
|
aCount = 3;
|
||||||
|
|
||||||
// Just show it on common via & via holes layers
|
// Just show it on common via & via holes layers
|
||||||
switch( GetViaType() )
|
switch( GetViaType() )
|
||||||
{
|
{
|
||||||
case VIA_THROUGH:
|
case VIA_THROUGH:
|
||||||
aLayers[1] = LAYER_VIA_THROUGH;
|
aLayers[2] = LAYER_VIA_THROUGH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIA_BLIND_BURIED:
|
case VIA_BLIND_BURIED:
|
||||||
aLayers[1] = LAYER_VIA_BBLIND;
|
aLayers[2] = LAYER_VIA_BBLIND;
|
||||||
aLayers[2] = m_Layer;
|
aLayers[3] = m_Layer;
|
||||||
aLayers[3] = m_BottomLayer;
|
aLayers[4] = m_BottomLayer;
|
||||||
aCount += 2;
|
aCount += 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIA_MICROVIA:
|
case VIA_MICROVIA:
|
||||||
aLayers[1] = LAYER_VIA_MICROVIA;
|
aLayers[2] = LAYER_VIA_MICROVIA;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -30,6 +30,7 @@ enum pcbnew_ids
|
||||||
ID_PCB_MODULE_BUTT,
|
ID_PCB_MODULE_BUTT,
|
||||||
ID_TRACK_BUTT,
|
ID_TRACK_BUTT,
|
||||||
ID_PCB_ZONES_BUTT,
|
ID_PCB_ZONES_BUTT,
|
||||||
|
ID_PCB_DRAW_VIA_BUTT,
|
||||||
ID_PCB_KEEPOUT_AREA_BUTT,
|
ID_PCB_KEEPOUT_AREA_BUTT,
|
||||||
ID_PCB_ADD_LINE_BUTT,
|
ID_PCB_ADD_LINE_BUTT,
|
||||||
ID_PCB_CIRCLE_BUTT,
|
ID_PCB_CIRCLE_BUTT,
|
||||||
|
|
|
@ -440,7 +440,10 @@ void PCB_EDIT_FRAME::ReCreateVToolbar()
|
||||||
_( "Add footprints" ), wxITEM_CHECK );
|
_( "Add footprints" ), wxITEM_CHECK );
|
||||||
|
|
||||||
m_drawToolBar->AddTool( ID_TRACK_BUTT, wxEmptyString, KiBitmap( add_tracks_xpm ),
|
m_drawToolBar->AddTool( ID_TRACK_BUTT, wxEmptyString, KiBitmap( add_tracks_xpm ),
|
||||||
_( "Add tracks and vias" ), wxITEM_CHECK );
|
_( "Route tracks" ), wxITEM_CHECK );
|
||||||
|
|
||||||
|
m_drawToolBar->AddTool( ID_PCB_DRAW_VIA_BUTT, wxEmptyString, KiBitmap( add_via_xpm ),
|
||||||
|
_( "Add vias" ), wxITEM_CHECK );
|
||||||
|
|
||||||
m_drawToolBar->AddTool( ID_PCB_ZONES_BUTT, wxEmptyString, KiBitmap( add_zone_xpm ),
|
m_drawToolBar->AddTool( ID_PCB_ZONES_BUTT, wxEmptyString, KiBitmap( add_zone_xpm ),
|
||||||
_( "Add filled zones" ), wxITEM_CHECK );
|
_( "Add filled zones" ), wxITEM_CHECK );
|
||||||
|
|
|
@ -88,7 +88,11 @@ TOOL_ACTION PCB_ACTIONS::drawZone( "pcbnew.InteractiveDrawing.zone",
|
||||||
AS_GLOBAL, 0,
|
AS_GLOBAL, 0,
|
||||||
_( "Add Filled Zone" ), _( "Add a filled zone" ), NULL, AF_ACTIVATE );
|
_( "Add Filled Zone" ), _( "Add a filled zone" ), NULL, AF_ACTIVATE );
|
||||||
|
|
||||||
TOOL_ACTION PCB_ACTIONS::drawZoneKeepout( "pcbnew.InteractiveDrawing.keepout",
|
TOOL_ACTION PCB_ACTIONS::drawVia( "pcbnew.InteractiveDrawing.via",
|
||||||
|
AS_GLOBAL, 0,
|
||||||
|
_( "Add Vias" ), _( "Add free-stanging vias" ), NULL, AF_ACTIVATE );
|
||||||
|
|
||||||
|
TOOL_ACTION PCB_ACTIONS::drawKeepout( "pcbnew.InteractiveDrawing.keepout",
|
||||||
AS_GLOBAL, 0,
|
AS_GLOBAL, 0,
|
||||||
_( "Add Keepout Area" ), _( "Add a keepout area" ), NULL, AF_ACTIVATE );
|
_( "Add Keepout Area" ), _( "Add a keepout area" ), NULL, AF_ACTIVATE );
|
||||||
|
|
||||||
|
@ -1392,6 +1396,136 @@ void DRAWING_TOOL::make45DegLine( DRAWSEGMENT* aSegment, DRAWSEGMENT* aHelper )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
struct VIA_PLACER : public INTERACTIVE_PLACER_BASE
|
||||||
|
{
|
||||||
|
int findStitchedZoneNet( VIA *aVia )
|
||||||
|
{
|
||||||
|
const auto pos = aVia->GetPosition();
|
||||||
|
const auto lset = aVia->GetLayerSet();
|
||||||
|
|
||||||
|
for ( auto tv : m_board->Tracks() ) // fixme: move to BOARD class?
|
||||||
|
if( tv->HitTest(pos) && (tv->GetLayerSet() &
|
||||||
|
lset ).any() )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for ( auto mod : m_board->Modules() )
|
||||||
|
for ( auto pad : mod->PadsIter() )
|
||||||
|
if( pad->HitTest(pos) && (pad->GetLayerSet() &
|
||||||
|
lset ).any() )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
std::set<ZONE_CONTAINER* > foundZones;
|
||||||
|
|
||||||
|
for( auto zone : m_board->Zones() )
|
||||||
|
{
|
||||||
|
if ( zone->HitTestFilledArea ( pos ) )
|
||||||
|
{
|
||||||
|
foundZones.insert ( zone );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for( auto z : foundZones )
|
||||||
|
{
|
||||||
|
if ( m_frame->GetActiveLayer() == z->GetLayer() )
|
||||||
|
return z->GetNetCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlaceItem( BOARD_ITEM *aItem ) override
|
||||||
|
{
|
||||||
|
auto via = static_cast<VIA*>(aItem);
|
||||||
|
int newNet = findStitchedZoneNet(via);
|
||||||
|
|
||||||
|
if(newNet > 0 )
|
||||||
|
via->SetNetCode( newNet );
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::unique_ptr<BOARD_ITEM> CreateItem() override
|
||||||
|
{
|
||||||
|
auto& ds = m_board->GetDesignSettings();
|
||||||
|
VIA* via = new VIA ( m_board );
|
||||||
|
|
||||||
|
via->SetNetCode( 0 );
|
||||||
|
via->SetViaType( ds.m_CurrentViaType );
|
||||||
|
|
||||||
|
// for microvias, the size and hole will be changed later.
|
||||||
|
via->SetWidth( ds.GetCurrentViaSize());
|
||||||
|
via->SetDrill( ds.GetCurrentViaDrill() );
|
||||||
|
|
||||||
|
// Usual via is from copper to component.
|
||||||
|
// layer pair is B_Cu and F_Cu.
|
||||||
|
via->SetLayerPair( B_Cu, F_Cu );
|
||||||
|
|
||||||
|
LAYER_ID first_layer = m_frame->GetActiveLayer();
|
||||||
|
LAYER_ID last_layer;
|
||||||
|
|
||||||
|
// prepare switch to new active layer:
|
||||||
|
if( first_layer != m_frame->GetScreen()->m_Route_Layer_TOP )
|
||||||
|
last_layer = m_frame->GetScreen()->m_Route_Layer_TOP;
|
||||||
|
else
|
||||||
|
last_layer = m_frame->GetScreen()->m_Route_Layer_BOTTOM;
|
||||||
|
|
||||||
|
// Adjust the actual via layer pair
|
||||||
|
switch( via->GetViaType() )
|
||||||
|
{
|
||||||
|
case VIA_BLIND_BURIED:
|
||||||
|
via->SetLayerPair( first_layer, last_layer );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VIA_MICROVIA: // from external to the near neighbor inner layer
|
||||||
|
{
|
||||||
|
LAYER_ID last_inner_layer = ToLAYER_ID( ( m_board->GetCopperLayerCount() - 2 ) );
|
||||||
|
|
||||||
|
if( first_layer == B_Cu )
|
||||||
|
last_layer = last_inner_layer;
|
||||||
|
else if( first_layer == F_Cu )
|
||||||
|
last_layer = In1_Cu;
|
||||||
|
else if( first_layer == last_inner_layer )
|
||||||
|
last_layer = B_Cu;
|
||||||
|
else if( first_layer == In1_Cu )
|
||||||
|
last_layer = F_Cu;
|
||||||
|
// else error: will be removed later
|
||||||
|
via->SetLayerPair( first_layer, last_layer );
|
||||||
|
|
||||||
|
// Update diameter and hole size, which where set previously
|
||||||
|
// for normal vias
|
||||||
|
NETINFO_ITEM* net = via->GetNet();
|
||||||
|
if( net )
|
||||||
|
{
|
||||||
|
via->SetWidth( net->GetMicroViaSize() );
|
||||||
|
via->SetDrill( net->GetMicroViaDrillSize() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return std::unique_ptr<BOARD_ITEM>(via);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
VIA_PLACER placer;
|
||||||
|
|
||||||
|
frame()->SetToolID( ID_PCB_DRAW_VIA_BUTT, wxCURSOR_PENCIL, _( "Add vias" ) );
|
||||||
|
|
||||||
|
doInteractiveItemPlacement( &placer, _( "Place via" ), IPO_REPEAT | IPO_SINGLE_CLICK | IPO_ROTATE | IPO_FLIP | IPO_PROPERTIES );
|
||||||
|
|
||||||
|
frame()->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void DRAWING_TOOL::SetTransitions()
|
void DRAWING_TOOL::SetTransitions()
|
||||||
{
|
{
|
||||||
|
@ -1403,6 +1537,7 @@ void DRAWING_TOOL::SetTransitions()
|
||||||
Go( &DRAWING_TOOL::DrawZoneKeepout, PCB_ACTIONS::drawZoneKeepout.MakeEvent() );
|
Go( &DRAWING_TOOL::DrawZoneKeepout, PCB_ACTIONS::drawZoneKeepout.MakeEvent() );
|
||||||
Go( &DRAWING_TOOL::DrawZoneCutout, PCB_ACTIONS::drawZoneCutout.MakeEvent() );
|
Go( &DRAWING_TOOL::DrawZoneCutout, PCB_ACTIONS::drawZoneCutout.MakeEvent() );
|
||||||
Go( &DRAWING_TOOL::DrawSimilarZone, PCB_ACTIONS::drawSimilarZone.MakeEvent() );
|
Go( &DRAWING_TOOL::DrawSimilarZone, PCB_ACTIONS::drawSimilarZone.MakeEvent() );
|
||||||
|
Go( &DRAWING_TOOL::DrawVia, PCB_ACTIONS::drawVia.MakeEvent() );
|
||||||
Go( &DRAWING_TOOL::PlaceText, PCB_ACTIONS::placeText.MakeEvent() );
|
Go( &DRAWING_TOOL::PlaceText, PCB_ACTIONS::placeText.MakeEvent() );
|
||||||
Go( &DRAWING_TOOL::PlaceDXF, PCB_ACTIONS::placeDXF.MakeEvent() );
|
Go( &DRAWING_TOOL::PlaceDXF, PCB_ACTIONS::placeDXF.MakeEvent() );
|
||||||
Go( &DRAWING_TOOL::SetAnchor, PCB_ACTIONS::setAnchor.MakeEvent() );
|
Go( &DRAWING_TOOL::SetAnchor, PCB_ACTIONS::setAnchor.MakeEvent() );
|
||||||
|
|
|
@ -135,6 +135,8 @@ public:
|
||||||
*/
|
*/
|
||||||
int DrawZone( const TOOL_EVENT& aEvent );
|
int DrawZone( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
int DrawVia( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function DrawZoneKeepout()
|
* Function DrawZoneKeepout()
|
||||||
* Starts interactively drawing a keepout area. After invoking the function an area settings
|
* Starts interactively drawing a keepout area. After invoking the function an area settings
|
||||||
|
|
|
@ -201,22 +201,32 @@ int MICROWAVE_TOOL::addMicrowaveFootprint( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
frame.SetToolID( info.toolId, wxCURSOR_PENCIL, info.name );
|
frame.SetToolID( info.toolId, wxCURSOR_PENCIL, info.name );
|
||||||
|
|
||||||
ITEM_CREATOR moduleCreator = [this, &info] ( const TOOL_EVENT& aAddingEvent )
|
struct MICROWAVE_PLACER : public INTERACTIVE_PLACER_BASE
|
||||||
{
|
{
|
||||||
auto module = info.creatorFunc();
|
MICROWAVE_TOOL_INFO& m_info;
|
||||||
|
|
||||||
// Module has been added in the legacy backend,
|
MICROWAVE_PLACER( MICROWAVE_TOOL_INFO& aInfo ) :
|
||||||
// so we have to remove it before committing the change
|
m_info( aInfo ) {};
|
||||||
// @todo LEGACY
|
|
||||||
if( module )
|
std::unique_ptr<BOARD_ITEM> CreateItem() override
|
||||||
{
|
{
|
||||||
board()->Remove( module.get() );
|
auto module = m_info.creatorFunc();
|
||||||
}
|
|
||||||
|
|
||||||
return module;
|
// Module has been added in the legacy backend,
|
||||||
|
// so we have to remove it before committing the change
|
||||||
|
// @todo LEGACY
|
||||||
|
if( module )
|
||||||
|
{
|
||||||
|
m_board->Remove( module.get() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::unique_ptr<BOARD_ITEM>( module.release() );
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
doInteractiveItemPlacement( moduleCreator, _( "Place microwave feature" ) );
|
MICROWAVE_PLACER placer ( info );
|
||||||
|
|
||||||
|
doInteractiveItemPlacement( &placer, _( "Place microwave feature" ) );
|
||||||
|
|
||||||
frame.SetNoToolSelected();
|
frame.SetNoToolSelected();
|
||||||
|
|
||||||
|
|
|
@ -95,85 +95,28 @@ void MODULE_EDITOR_TOOLS::Reset( RESET_REASON aReason )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int MODULE_EDITOR_TOOLS::PlacePad( const TOOL_EVENT& aEvent )
|
int MODULE_EDITOR_TOOLS::PlacePad( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
|
struct PAD_PLACER : public INTERACTIVE_PLACER_BASE
|
||||||
|
{
|
||||||
|
std::unique_ptr<BOARD_ITEM> CreateItem() override
|
||||||
|
{
|
||||||
|
D_PAD* pad = new D_PAD ( m_board->m_Modules );
|
||||||
|
m_frame->Import_Pad_Settings( pad, false ); // use the global settings for pad
|
||||||
|
// pad->IncrementPadName( true, true );
|
||||||
|
return std::unique_ptr<BOARD_ITEM>( pad );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
PAD_PLACER placer;
|
||||||
|
|
||||||
frame()->SetToolID( ID_MODEDIT_PAD_TOOL, wxCURSOR_PENCIL, _( "Add pads" ) );
|
frame()->SetToolID( ID_MODEDIT_PAD_TOOL, wxCURSOR_PENCIL, _( "Add pads" ) );
|
||||||
|
|
||||||
assert( board()->m_Modules );
|
assert( board()->m_Modules );
|
||||||
|
|
||||||
D_PAD* pad = new D_PAD( board()->m_Modules );
|
doInteractiveItemPlacement( &placer, _( "Place pad" ), IPO_REPEAT | IPO_SINGLE_CLICK | IPO_ROTATE | IPO_FLIP | IPO_PROPERTIES );
|
||||||
frame()->Import_Pad_Settings( pad, false ); // use the global settings for pad
|
|
||||||
|
|
||||||
VECTOR2I cursorPos = getViewControls()->GetCursorPosition();
|
|
||||||
pad->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
|
|
||||||
|
|
||||||
// Add a VIEW_GROUP that serves as a preview for the new item
|
|
||||||
KIGFX::VIEW_GROUP preview( view() );
|
|
||||||
preview.Add( pad );
|
|
||||||
view()->Add( &preview );
|
|
||||||
|
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
|
||||||
getViewControls()->ShowCursor( true );
|
|
||||||
getViewControls()->SetSnapping( true );
|
|
||||||
|
|
||||||
Activate();
|
|
||||||
|
|
||||||
// Main loop: keep receiving events
|
|
||||||
while( OPT_TOOL_EVENT evt = Wait() )
|
|
||||||
{
|
|
||||||
cursorPos = getViewControls()->GetCursorPosition();
|
|
||||||
|
|
||||||
if( evt->IsMotion() )
|
|
||||||
{
|
|
||||||
pad->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
|
|
||||||
view()->Update( &preview );
|
|
||||||
}
|
|
||||||
|
|
||||||
else if( evt->Category() == TC_COMMAND )
|
|
||||||
{
|
|
||||||
if( TOOL_EVT_UTILS::IsRotateToolEvt( *evt ) )
|
|
||||||
{
|
|
||||||
const auto rotationAngle = TOOL_EVT_UTILS::GetEventRotationAngle(
|
|
||||||
*frame(), *evt );
|
|
||||||
pad->Rotate( pad->GetPosition(), rotationAngle );
|
|
||||||
view()->Update( &preview );
|
|
||||||
}
|
|
||||||
else if( evt->IsAction( &PCB_ACTIONS::flip ) )
|
|
||||||
{
|
|
||||||
pad->Flip( pad->GetPosition() );
|
|
||||||
view()->Update( &preview );
|
|
||||||
}
|
|
||||||
else if( evt->IsCancel() || evt->IsActivate() )
|
|
||||||
{
|
|
||||||
preview.Clear();
|
|
||||||
delete pad;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if( evt->IsClick( BUT_LEFT ) )
|
|
||||||
{
|
|
||||||
BOARD_COMMIT commit( frame() );
|
|
||||||
commit.Add( pad );
|
|
||||||
|
|
||||||
board()->m_Status_Pcb = 0; // I have no clue why, but it is done in the legacy view
|
|
||||||
|
|
||||||
// Take the next available pad number
|
|
||||||
pad->IncrementPadName( true, true );
|
|
||||||
|
|
||||||
// Handle the view aspect
|
|
||||||
preview.Remove( pad );
|
|
||||||
commit.Push( _( "Add a pad" ) );
|
|
||||||
|
|
||||||
// Start placing next pad
|
|
||||||
pad = new D_PAD( board()->m_Modules );
|
|
||||||
frame()->Import_Pad_Settings( pad, false );
|
|
||||||
pad->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
|
|
||||||
preview.Add( pad );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
view()->Remove( &preview );
|
|
||||||
frame()->SetNoToolSelected();
|
frame()->SetNoToolSelected();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -58,6 +58,9 @@ boost::optional<TOOL_EVENT> PCB_ACTIONS::TranslateLegacyId( int aId )
|
||||||
case ID_PCB_ZONES_BUTT:
|
case ID_PCB_ZONES_BUTT:
|
||||||
return PCB_ACTIONS::drawZone.MakeEvent();
|
return PCB_ACTIONS::drawZone.MakeEvent();
|
||||||
|
|
||||||
|
case ID_PCB_DRAW_VIA_BUTT:
|
||||||
|
return PCB_ACTIONS::drawVia.MakeEvent();
|
||||||
|
|
||||||
case ID_PCB_KEEPOUT_AREA_BUTT:
|
case ID_PCB_KEEPOUT_AREA_BUTT:
|
||||||
return PCB_ACTIONS::drawZoneKeepout.MakeEvent();
|
return PCB_ACTIONS::drawZoneKeepout.MakeEvent();
|
||||||
|
|
||||||
|
|
|
@ -139,6 +139,9 @@ public:
|
||||||
/// Activation of the drawing tool (drawing a ZONE)
|
/// Activation of the drawing tool (drawing a ZONE)
|
||||||
static TOOL_ACTION drawZone;
|
static TOOL_ACTION drawZone;
|
||||||
|
|
||||||
|
/// Activation of the drawing tool (drawing a VIA)
|
||||||
|
static TOOL_ACTION drawVia;
|
||||||
|
|
||||||
/// Activation of the drawing tool (drawing a keepout area)
|
/// Activation of the drawing tool (drawing a keepout area)
|
||||||
static TOOL_ACTION drawZoneKeepout;
|
static TOOL_ACTION drawZoneKeepout;
|
||||||
|
|
||||||
|
|
|
@ -35,36 +35,44 @@
|
||||||
#include "pcb_actions.h"
|
#include "pcb_actions.h"
|
||||||
#include "tool_event_utils.h"
|
#include "tool_event_utils.h"
|
||||||
|
|
||||||
|
void PCB_TOOL::doInteractiveItemPlacement( INTERACTIVE_PLACER_BASE *aPlacer,
|
||||||
void PCB_TOOL::doInteractiveItemPlacement( ITEM_CREATOR aItemCreator,
|
const wxString& aCommitMessage,
|
||||||
const wxString& aCommitMessage )
|
int aOptions )
|
||||||
{
|
{
|
||||||
using namespace std::placeholders;
|
using namespace std::placeholders;
|
||||||
|
|
||||||
KIGFX::VIEW& view = *getView();
|
|
||||||
KIGFX::VIEW_CONTROLS& controls = *getViewControls();
|
|
||||||
auto& frame = *getEditFrame<PCB_EDIT_FRAME>();
|
|
||||||
|
|
||||||
std::unique_ptr<BOARD_ITEM> newItem;
|
std::unique_ptr<BOARD_ITEM> newItem;
|
||||||
|
|
||||||
Activate();
|
Activate();
|
||||||
|
|
||||||
BOARD_COMMIT commit( &frame );
|
BOARD_COMMIT commit( frame() );
|
||||||
|
|
||||||
GetManager()->RunAction( PCB_ACTIONS::selectionClear, true );
|
GetManager()->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||||
|
|
||||||
// do not capture or auto-pan until we start placing an item
|
// do not capture or auto-pan until we start placing an item
|
||||||
controls.ShowCursor( true );
|
controls()->ShowCursor( true );
|
||||||
controls.SetSnapping( true );
|
controls()->SetSnapping( true );
|
||||||
|
|
||||||
// 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
|
||||||
SELECTION preview;
|
SELECTION preview;
|
||||||
view.Add( &preview );
|
view()->Add( &preview );
|
||||||
|
|
||||||
|
aPlacer->m_board = board();
|
||||||
|
aPlacer->m_frame = frame();
|
||||||
|
|
||||||
|
if ( aOptions & IPO_SINGLE_CLICK )
|
||||||
|
{
|
||||||
|
VECTOR2I cursorPos = controls()->GetCursorPosition();
|
||||||
|
|
||||||
|
newItem = aPlacer->CreateItem();
|
||||||
|
newItem->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
|
||||||
|
|
||||||
|
preview.Add( newItem.get() );
|
||||||
|
}
|
||||||
|
|
||||||
// Main loop: keep receiving events
|
// Main loop: keep receiving events
|
||||||
while( OPT_TOOL_EVENT evt = Wait() )
|
while( OPT_TOOL_EVENT evt = Wait() )
|
||||||
{
|
{
|
||||||
VECTOR2I cursorPos = controls.GetCursorPosition();
|
VECTOR2I cursorPos = controls()->GetCursorPosition();
|
||||||
|
|
||||||
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
|
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
|
||||||
{
|
{
|
||||||
|
@ -75,9 +83,12 @@ void PCB_TOOL::doInteractiveItemPlacement( ITEM_CREATOR aItemCreator,
|
||||||
|
|
||||||
preview.Clear();
|
preview.Clear();
|
||||||
|
|
||||||
controls.SetAutoPan( false );
|
if ( aOptions & IPO_SINGLE_CLICK )
|
||||||
controls.CaptureCursor( false );
|
break;
|
||||||
controls.ShowCursor( true );
|
|
||||||
|
controls()->SetAutoPan( false );
|
||||||
|
controls()->CaptureCursor( false );
|
||||||
|
controls()->ShowCursor( true );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -93,14 +104,14 @@ void PCB_TOOL::doInteractiveItemPlacement( ITEM_CREATOR aItemCreator,
|
||||||
if( !newItem )
|
if( !newItem )
|
||||||
{
|
{
|
||||||
// create the item if possible
|
// create the item if possible
|
||||||
newItem = aItemCreator( *evt );
|
newItem = aPlacer->CreateItem();
|
||||||
|
|
||||||
// no item created, so wait for another click
|
// no item created, so wait for another click
|
||||||
if( !newItem )
|
if( !newItem )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
controls.CaptureCursor( true );
|
controls()->CaptureCursor( true );
|
||||||
controls.SetAutoPan( true );
|
controls()->SetAutoPan( true );
|
||||||
|
|
||||||
newItem->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
|
newItem->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
|
||||||
|
|
||||||
|
@ -119,6 +130,8 @@ void PCB_TOOL::doInteractiveItemPlacement( ITEM_CREATOR aItemCreator,
|
||||||
newItem->ClearFlags();
|
newItem->ClearFlags();
|
||||||
preview.Remove( newItem.get() );
|
preview.Remove( newItem.get() );
|
||||||
|
|
||||||
|
aPlacer->PlaceItem( newItem.get() );
|
||||||
|
|
||||||
if( newItem->Type() == PCB_MODULE_T )
|
if( newItem->Type() == PCB_MODULE_T )
|
||||||
{
|
{
|
||||||
auto module = dyn_cast<MODULE*>( newItem.get() );
|
auto module = dyn_cast<MODULE*>( newItem.get() );
|
||||||
|
@ -128,9 +141,22 @@ void PCB_TOOL::doInteractiveItemPlacement( ITEM_CREATOR aItemCreator,
|
||||||
commit.Add( newItem.release() );
|
commit.Add( newItem.release() );
|
||||||
commit.Push( aCommitMessage );
|
commit.Push( aCommitMessage );
|
||||||
|
|
||||||
controls.CaptureCursor( false );
|
controls()->CaptureCursor( false );
|
||||||
controls.SetAutoPan( false );
|
controls()->SetAutoPan( false );
|
||||||
controls.ShowCursor( true );
|
controls()->ShowCursor( true );
|
||||||
|
if (! ( aOptions & IPO_REPEAT ) )
|
||||||
|
break;
|
||||||
|
|
||||||
|
if ( aOptions & IPO_SINGLE_CLICK )
|
||||||
|
{
|
||||||
|
VECTOR2I cursorPos = controls()->GetCursorPosition();
|
||||||
|
|
||||||
|
newItem = aPlacer->CreateItem();
|
||||||
|
newItem->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
|
||||||
|
|
||||||
|
preview.Add( newItem.get() );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,17 +167,17 @@ void PCB_TOOL::doInteractiveItemPlacement( ITEM_CREATOR aItemCreator,
|
||||||
* it around, eg rotate and flip
|
* it around, eg rotate and flip
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if( TOOL_EVT_UTILS::IsRotateToolEvt( *evt ) )
|
if( TOOL_EVT_UTILS::IsRotateToolEvt( *evt ) && ( aOptions & IPO_ROTATE ) )
|
||||||
{
|
{
|
||||||
const auto rotationAngle = TOOL_EVT_UTILS::GetEventRotationAngle(
|
const auto rotationAngle = TOOL_EVT_UTILS::GetEventRotationAngle(
|
||||||
frame, *evt );
|
*frame(), *evt );
|
||||||
newItem->Rotate( newItem->GetPosition(), rotationAngle );
|
newItem->Rotate( newItem->GetPosition(), rotationAngle );
|
||||||
view.Update( &preview );
|
view()->Update( &preview );
|
||||||
}
|
}
|
||||||
else if( evt->IsAction( &PCB_ACTIONS::flip ) )
|
else if( evt->IsAction( &PCB_ACTIONS::flip ) && ( aOptions & IPO_FLIP ) )
|
||||||
{
|
{
|
||||||
newItem->Flip( newItem->GetPosition() );
|
newItem->Flip( newItem->GetPosition() );
|
||||||
view.Update( &preview );
|
view()->Update( &preview );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,9 +187,9 @@ void PCB_TOOL::doInteractiveItemPlacement( ITEM_CREATOR aItemCreator,
|
||||||
newItem->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
|
newItem->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
|
||||||
|
|
||||||
// Show a preview of the item
|
// Show a preview of the item
|
||||||
view.Update( &preview );
|
view()->Update( &preview );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
view.Remove( &preview );
|
view()->Remove( &preview );
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,19 @@
|
||||||
* A tool operating on a BOARD object
|
* A tool operating on a BOARD object
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
class PCB_TOOL;
|
||||||
|
class PCB_EDIT_FRAME;
|
||||||
|
|
||||||
|
struct INTERACTIVE_PLACER_BASE
|
||||||
|
{
|
||||||
|
virtual std::unique_ptr<BOARD_ITEM> CreateItem() = 0;
|
||||||
|
virtual bool PlaceItem( BOARD_ITEM *aItem ) { return false; }
|
||||||
|
|
||||||
|
PCB_EDIT_FRAME *m_frame;
|
||||||
|
BOARD *m_board;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class PCB_TOOL : public TOOL_INTERACTIVE
|
class PCB_TOOL : public TOOL_INTERACTIVE
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -82,13 +95,14 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/**
|
enum INTERACTIVE_PLACEMENT_OPTIONS {
|
||||||
* Callable that returns a new board item.
|
IPO_ROTATE = 1,
|
||||||
*
|
IPO_FLIP = 2,
|
||||||
* The event that triggered it is provided, so you can check modifier
|
IPO_PROPERTIES = 4,
|
||||||
* keys, position, etc, if required
|
IPO_SINGLE_CLICK = 8,
|
||||||
*/
|
IPO_REPEAT = 16
|
||||||
using ITEM_CREATOR = std::function< std::unique_ptr< BOARD_ITEM >( const TOOL_EVENT& aEvt ) >;
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function for performing a common interactive idiom:
|
* Helper function for performing a common interactive idiom:
|
||||||
|
@ -102,10 +116,12 @@ protected:
|
||||||
* @param aItemCreator the callable that will attempt to create the item
|
* @param aItemCreator the callable that will attempt to create the item
|
||||||
* @param aCommitMessage the message used on a successful commit
|
* @param aCommitMessage the message used on a successful commit
|
||||||
*/
|
*/
|
||||||
void doInteractiveItemPlacement( ITEM_CREATOR aItemCreator,
|
void doInteractiveItemPlacement( INTERACTIVE_PLACER_BASE *aPlacer,
|
||||||
const wxString& aCommitMessage );
|
const wxString& aCommitMessage,
|
||||||
|
int aOptions = IPO_ROTATE | IPO_FLIP | IPO_REPEAT );
|
||||||
|
|
||||||
KIGFX::VIEW* view() const { return getView(); }
|
KIGFX::VIEW* view() const { return getView(); }
|
||||||
|
KIGFX::VIEW_CONTROLS* controls() const { return getViewControls(); }
|
||||||
PCB_EDIT_FRAME* frame() const { return getEditFrame<PCB_EDIT_FRAME>(); }
|
PCB_EDIT_FRAME* frame() const { return getEditFrame<PCB_EDIT_FRAME>(); }
|
||||||
BOARD* board() const { return getModel<BOARD>(); }
|
BOARD* board() const { return getModel<BOARD>(); }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue