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<MODULE> Modules() { return DLIST_ITERATOR_WRAPPER<MODULE>(m_Modules); }
|
||||
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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
aLayers[0] = LAYER_VIAS_HOLES;
|
||||
aCount = 2;
|
||||
aLayers[1] = GetNetnameLayer( m_Layer );
|
||||
aCount = 3;
|
||||
|
||||
// Just show it on common via & via holes layers
|
||||
switch( GetViaType() )
|
||||
{
|
||||
case VIA_THROUGH:
|
||||
aLayers[1] = LAYER_VIA_THROUGH;
|
||||
aLayers[2] = LAYER_VIA_THROUGH;
|
||||
break;
|
||||
|
||||
case VIA_BLIND_BURIED:
|
||||
aLayers[1] = LAYER_VIA_BBLIND;
|
||||
aLayers[2] = m_Layer;
|
||||
aLayers[3] = m_BottomLayer;
|
||||
aLayers[2] = LAYER_VIA_BBLIND;
|
||||
aLayers[3] = m_Layer;
|
||||
aLayers[4] = m_BottomLayer;
|
||||
aCount += 2;
|
||||
break;
|
||||
|
||||
case VIA_MICROVIA:
|
||||
aLayers[1] = LAYER_VIA_MICROVIA;
|
||||
aLayers[2] = LAYER_VIA_MICROVIA;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -30,6 +30,7 @@ enum pcbnew_ids
|
|||
ID_PCB_MODULE_BUTT,
|
||||
ID_TRACK_BUTT,
|
||||
ID_PCB_ZONES_BUTT,
|
||||
ID_PCB_DRAW_VIA_BUTT,
|
||||
ID_PCB_KEEPOUT_AREA_BUTT,
|
||||
ID_PCB_ADD_LINE_BUTT,
|
||||
ID_PCB_CIRCLE_BUTT,
|
||||
|
|
|
@ -440,7 +440,10 @@ void PCB_EDIT_FRAME::ReCreateVToolbar()
|
|||
_( "Add footprints" ), wxITEM_CHECK );
|
||||
|
||||
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 ),
|
||||
_( "Add filled zones" ), wxITEM_CHECK );
|
||||
|
|
|
@ -88,7 +88,11 @@ TOOL_ACTION PCB_ACTIONS::drawZone( "pcbnew.InteractiveDrawing.zone",
|
|||
AS_GLOBAL, 0,
|
||||
_( "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,
|
||||
_( "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()
|
||||
{
|
||||
|
@ -1403,6 +1537,7 @@ void DRAWING_TOOL::SetTransitions()
|
|||
Go( &DRAWING_TOOL::DrawZoneKeepout, PCB_ACTIONS::drawZoneKeepout.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawZoneCutout, PCB_ACTIONS::drawZoneCutout.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::PlaceDXF, PCB_ACTIONS::placeDXF.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::SetAnchor, PCB_ACTIONS::setAnchor.MakeEvent() );
|
||||
|
|
|
@ -135,6 +135,8 @@ public:
|
|||
*/
|
||||
int DrawZone( const TOOL_EVENT& aEvent );
|
||||
|
||||
int DrawVia( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Function DrawZoneKeepout()
|
||||
* 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 );
|
||||
|
||||
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,
|
||||
// so we have to remove it before committing the change
|
||||
// @todo LEGACY
|
||||
if( module )
|
||||
MICROWAVE_PLACER( MICROWAVE_TOOL_INFO& aInfo ) :
|
||||
m_info( aInfo ) {};
|
||||
|
||||
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();
|
||||
|
||||
|
|
|
@ -95,85 +95,28 @@ void MODULE_EDITOR_TOOLS::Reset( RESET_REASON aReason )
|
|||
}
|
||||
|
||||
|
||||
|
||||
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" ) );
|
||||
|
||||
assert( board()->m_Modules );
|
||||
|
||||
D_PAD* pad = new D_PAD( board()->m_Modules );
|
||||
frame()->Import_Pad_Settings( pad, false ); // use the global settings for pad
|
||||
doInteractiveItemPlacement( &placer, _( "Place pad" ), IPO_REPEAT | IPO_SINGLE_CLICK | IPO_ROTATE | IPO_FLIP | IPO_PROPERTIES );
|
||||
|
||||
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();
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -58,6 +58,9 @@ boost::optional<TOOL_EVENT> PCB_ACTIONS::TranslateLegacyId( int aId )
|
|||
case ID_PCB_ZONES_BUTT:
|
||||
return PCB_ACTIONS::drawZone.MakeEvent();
|
||||
|
||||
case ID_PCB_DRAW_VIA_BUTT:
|
||||
return PCB_ACTIONS::drawVia.MakeEvent();
|
||||
|
||||
case ID_PCB_KEEPOUT_AREA_BUTT:
|
||||
return PCB_ACTIONS::drawZoneKeepout.MakeEvent();
|
||||
|
||||
|
|
|
@ -139,6 +139,9 @@ public:
|
|||
/// Activation of the drawing tool (drawing a ZONE)
|
||||
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)
|
||||
static TOOL_ACTION drawZoneKeepout;
|
||||
|
||||
|
|
|
@ -35,36 +35,44 @@
|
|||
#include "pcb_actions.h"
|
||||
#include "tool_event_utils.h"
|
||||
|
||||
|
||||
void PCB_TOOL::doInteractiveItemPlacement( ITEM_CREATOR aItemCreator,
|
||||
const wxString& aCommitMessage )
|
||||
void PCB_TOOL::doInteractiveItemPlacement( INTERACTIVE_PLACER_BASE *aPlacer,
|
||||
const wxString& aCommitMessage,
|
||||
int aOptions )
|
||||
{
|
||||
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;
|
||||
|
||||
Activate();
|
||||
|
||||
BOARD_COMMIT commit( &frame );
|
||||
BOARD_COMMIT commit( frame() );
|
||||
|
||||
GetManager()->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||
|
||||
// do not capture or auto-pan until we start placing an item
|
||||
controls.ShowCursor( true );
|
||||
controls.SetSnapping( true );
|
||||
controls()->ShowCursor( true );
|
||||
controls()->SetSnapping( true );
|
||||
|
||||
// Add a VIEW_GROUP that serves as a preview for the new item
|
||||
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
|
||||
while( OPT_TOOL_EVENT evt = Wait() )
|
||||
{
|
||||
VECTOR2I cursorPos = controls.GetCursorPosition();
|
||||
VECTOR2I cursorPos = controls()->GetCursorPosition();
|
||||
|
||||
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
|
||||
{
|
||||
|
@ -75,9 +83,12 @@ void PCB_TOOL::doInteractiveItemPlacement( ITEM_CREATOR aItemCreator,
|
|||
|
||||
preview.Clear();
|
||||
|
||||
controls.SetAutoPan( false );
|
||||
controls.CaptureCursor( false );
|
||||
controls.ShowCursor( true );
|
||||
if ( aOptions & IPO_SINGLE_CLICK )
|
||||
break;
|
||||
|
||||
controls()->SetAutoPan( false );
|
||||
controls()->CaptureCursor( false );
|
||||
controls()->ShowCursor( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -93,14 +104,14 @@ void PCB_TOOL::doInteractiveItemPlacement( ITEM_CREATOR aItemCreator,
|
|||
if( !newItem )
|
||||
{
|
||||
// create the item if possible
|
||||
newItem = aItemCreator( *evt );
|
||||
newItem = aPlacer->CreateItem();
|
||||
|
||||
// no item created, so wait for another click
|
||||
if( !newItem )
|
||||
continue;
|
||||
|
||||
controls.CaptureCursor( true );
|
||||
controls.SetAutoPan( true );
|
||||
controls()->CaptureCursor( true );
|
||||
controls()->SetAutoPan( true );
|
||||
|
||||
newItem->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
|
||||
|
||||
|
@ -119,6 +130,8 @@ void PCB_TOOL::doInteractiveItemPlacement( ITEM_CREATOR aItemCreator,
|
|||
newItem->ClearFlags();
|
||||
preview.Remove( newItem.get() );
|
||||
|
||||
aPlacer->PlaceItem( newItem.get() );
|
||||
|
||||
if( newItem->Type() == PCB_MODULE_T )
|
||||
{
|
||||
auto module = dyn_cast<MODULE*>( newItem.get() );
|
||||
|
@ -128,9 +141,22 @@ void PCB_TOOL::doInteractiveItemPlacement( ITEM_CREATOR aItemCreator,
|
|||
commit.Add( newItem.release() );
|
||||
commit.Push( aCommitMessage );
|
||||
|
||||
controls.CaptureCursor( false );
|
||||
controls.SetAutoPan( false );
|
||||
controls.ShowCursor( true );
|
||||
controls()->CaptureCursor( false );
|
||||
controls()->SetAutoPan( false );
|
||||
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
|
||||
*/
|
||||
|
||||
if( TOOL_EVT_UTILS::IsRotateToolEvt( *evt ) )
|
||||
if( TOOL_EVT_UTILS::IsRotateToolEvt( *evt ) && ( aOptions & IPO_ROTATE ) )
|
||||
{
|
||||
const auto rotationAngle = TOOL_EVT_UTILS::GetEventRotationAngle(
|
||||
frame, *evt );
|
||||
*frame(), *evt );
|
||||
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() );
|
||||
view.Update( &preview );
|
||||
view()->Update( &preview );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,9 +187,9 @@ void PCB_TOOL::doInteractiveItemPlacement( ITEM_CREATOR aItemCreator,
|
|||
newItem->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
|
||||
|
||||
// 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
|
||||
**/
|
||||
|
||||
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
|
||||
{
|
||||
public:
|
||||
|
@ -82,13 +95,14 @@ public:
|
|||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Callable that returns a new board item.
|
||||
*
|
||||
* The event that triggered it is provided, so you can check modifier
|
||||
* keys, position, etc, if required
|
||||
*/
|
||||
using ITEM_CREATOR = std::function< std::unique_ptr< BOARD_ITEM >( const TOOL_EVENT& aEvt ) >;
|
||||
enum INTERACTIVE_PLACEMENT_OPTIONS {
|
||||
IPO_ROTATE = 1,
|
||||
IPO_FLIP = 2,
|
||||
IPO_PROPERTIES = 4,
|
||||
IPO_SINGLE_CLICK = 8,
|
||||
IPO_REPEAT = 16
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 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 aCommitMessage the message used on a successful commit
|
||||
*/
|
||||
void doInteractiveItemPlacement( ITEM_CREATOR aItemCreator,
|
||||
const wxString& aCommitMessage );
|
||||
void doInteractiveItemPlacement( INTERACTIVE_PLACER_BASE *aPlacer,
|
||||
const wxString& aCommitMessage,
|
||||
int aOptions = IPO_ROTATE | IPO_FLIP | IPO_REPEAT );
|
||||
|
||||
KIGFX::VIEW* view() const { return getView(); }
|
||||
KIGFX::VIEW_CONTROLS* controls() const { return getViewControls(); }
|
||||
PCB_EDIT_FRAME* frame() const { return getEditFrame<PCB_EDIT_FRAME>(); }
|
||||
BOARD* board() const { return getModel<BOARD>(); }
|
||||
|
||||
|
|
Loading…
Reference in New Issue