Add zone cutout tool to GAL
When activated, the zone interactive editor is launched with a flag. The drawn zone is then used to modify the existing zone at the end of the action.
This commit is contained in:
parent
d37586aeaf
commit
abe83b54ae
|
@ -189,6 +189,11 @@ TOOL_ACTION COMMON_ACTIONS::drawKeepout( "pcbnew.InteractiveDrawing.keepout",
|
|||
AS_GLOBAL, 0,
|
||||
_( "Add Keepout Area" ), _( "Add a keepout area" ), NULL, AF_ACTIVATE );
|
||||
|
||||
TOOL_ACTION COMMON_ACTIONS::drawZoneCutout( "pcbnew.InteractiveDrawing.zoneCutout",
|
||||
AS_GLOBAL, 0,
|
||||
_( "Add a Zone Cutout" ), _( "Add a cutout area of an existing zone" ),
|
||||
add_zone_cutout_xpm, AF_ACTIVATE );
|
||||
|
||||
TOOL_ACTION COMMON_ACTIONS::placeDXF( "pcbnew.InteractiveDrawing.placeDXF",
|
||||
AS_GLOBAL, 0,
|
||||
"Place DXF", "", NULL, AF_ACTIVATE );
|
||||
|
|
|
@ -126,6 +126,9 @@ public:
|
|||
/// Activation of the drawing tool (drawing a keepout area)
|
||||
static TOOL_ACTION drawKeepout;
|
||||
|
||||
/// Activation of the drawing tool (drawing a ZONE cutout)
|
||||
static TOOL_ACTION drawZoneCutout;
|
||||
|
||||
/// Activation of the drawing tool (placing a TARGET)
|
||||
static TOOL_ACTION placeTarget;
|
||||
|
||||
|
|
|
@ -545,7 +545,7 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
|
|||
SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ZONE );
|
||||
m_frame->SetToolID( ID_PCB_ZONES_BUTT, wxCURSOR_PENCIL, _( "Add zones" ) );
|
||||
|
||||
return drawZone( false );
|
||||
return drawZone( false, ZONE_MODE::ADD );
|
||||
}
|
||||
|
||||
|
||||
|
@ -554,7 +554,16 @@ int DRAWING_TOOL::DrawKeepout( const TOOL_EVENT& aEvent )
|
|||
SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::KEEPOUT );
|
||||
m_frame->SetToolID( ID_PCB_KEEPOUT_AREA_BUTT, wxCURSOR_PENCIL, _( "Add keepout" ) );
|
||||
|
||||
return drawZone( true );
|
||||
return drawZone( true, ZONE_MODE::ADD );
|
||||
}
|
||||
|
||||
|
||||
int DRAWING_TOOL::DrawZoneCutout( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ZONE );
|
||||
m_frame->SetToolID( ID_PCB_KEEPOUT_AREA_BUTT, wxCURSOR_PENCIL, _( "Add zone cutout" ) );
|
||||
|
||||
return drawZone( false, ZONE_MODE::CUTOUT );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1186,12 +1195,89 @@ std::unique_ptr<ZONE_CONTAINER> DRAWING_TOOL::createNewZone(
|
|||
}
|
||||
|
||||
|
||||
int DRAWING_TOOL::drawZone( bool aKeepout )
|
||||
std::unique_ptr<ZONE_CONTAINER> DRAWING_TOOL::createZoneFromExisting(
|
||||
const ZONE_CONTAINER& aSrcZone )
|
||||
{
|
||||
auto newZone = std::make_unique<ZONE_CONTAINER>( m_board );
|
||||
|
||||
ZONE_SETTINGS zoneSettings;
|
||||
zoneSettings << aSrcZone;
|
||||
|
||||
zoneSettings.ExportSetting( *newZone );
|
||||
|
||||
return newZone;
|
||||
}
|
||||
|
||||
|
||||
bool DRAWING_TOOL::getSourceZoneForAction( ZONE_MODE aMode,
|
||||
ZONE_CONTAINER*& aZone )
|
||||
{
|
||||
aZone = nullptr;
|
||||
|
||||
// not an action that needs a source zone
|
||||
if( aMode == ZONE_MODE::ADD )
|
||||
return true;
|
||||
|
||||
SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
||||
const SELECTION& selection = selTool->GetSelection();
|
||||
|
||||
if( selection.Empty() )
|
||||
m_toolMgr->RunAction( COMMON_ACTIONS::selectionCursor, true );
|
||||
|
||||
// we want a single zone
|
||||
if( selection.Size() != 1 )
|
||||
return false;
|
||||
|
||||
aZone = dyn_cast<ZONE_CONTAINER*>( selection[0] );
|
||||
|
||||
// expected a zone, but didn't get one
|
||||
if( !aZone )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void DRAWING_TOOL::performZoneCutout( ZONE_CONTAINER& aExistingZone,
|
||||
ZONE_CONTAINER& cutout )
|
||||
{
|
||||
// Copy cutout corners into existing zone
|
||||
for( int ii = 0; ii < cutout.GetNumCorners(); ii++ )
|
||||
{
|
||||
aExistingZone.AppendCorner( cutout.GetCornerPosition( ii ) );
|
||||
}
|
||||
|
||||
// Close the current corner list
|
||||
aExistingZone.Outline()->CloseLastContour();
|
||||
|
||||
m_board->OnAreaPolygonModified( nullptr, &aExistingZone );
|
||||
|
||||
// Re-fill if needed
|
||||
if( aExistingZone.IsFilled() )
|
||||
{
|
||||
SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
||||
|
||||
auto& selection = selTool->GetSelection();
|
||||
|
||||
selection.Clear();
|
||||
selection.Add( &aExistingZone );
|
||||
|
||||
m_toolMgr->RunAction( COMMON_ACTIONS::zoneFill, true );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int DRAWING_TOOL::drawZone( bool aKeepout, ZONE_MODE aMode )
|
||||
{
|
||||
std::unique_ptr<ZONE_CONTAINER> zone;
|
||||
DRAWSEGMENT line45;
|
||||
DRAWSEGMENT* helperLine = NULL; // we will need more than one helper line
|
||||
BOARD_COMMIT commit( m_frame );
|
||||
ZONE_CONTAINER* sourceZone = nullptr;
|
||||
|
||||
// get a source zone, if we need one
|
||||
if( !getSourceZoneForAction( aMode, sourceZone ) )
|
||||
return 0;
|
||||
|
||||
// Add a VIEW_GROUP that serves as a preview for the new item
|
||||
SELECTION preview;
|
||||
|
@ -1279,9 +1365,22 @@ int DRAWING_TOOL::drawZone( bool aKeepout )
|
|||
if( !aKeepout )
|
||||
static_cast<PCB_EDIT_FRAME*>( m_frame )->Fill_Zone( zone.get() );
|
||||
|
||||
if ( aMode == ZONE_MODE::CUTOUT )
|
||||
{
|
||||
// For cutouts, subtract from the source
|
||||
commit.Modify( sourceZone );
|
||||
|
||||
performZoneCutout( *sourceZone, *zone );
|
||||
|
||||
commit.Push( _( "Add a zone cutout" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add the zone as a new board item
|
||||
commit.Add( zone.release() );
|
||||
commit.Push( _( "Draw a zone" ) );
|
||||
}
|
||||
}
|
||||
|
||||
// if kept, this was released. if still not null,
|
||||
// this zone is now unwanted and can be removed
|
||||
|
@ -1303,8 +1402,15 @@ int DRAWING_TOOL::drawZone( bool aKeepout )
|
|||
else
|
||||
{
|
||||
if( numPoints == 0 ) // it's the first click
|
||||
{
|
||||
if( sourceZone )
|
||||
{
|
||||
zone = createZoneFromExisting( *sourceZone );
|
||||
}
|
||||
else
|
||||
{
|
||||
zone = createNewZone( aKeepout );
|
||||
}
|
||||
|
||||
if( !zone )
|
||||
{
|
||||
|
@ -1397,6 +1503,7 @@ void DRAWING_TOOL::SetTransitions()
|
|||
Go( &DRAWING_TOOL::DrawDimension, COMMON_ACTIONS::drawDimension.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawZone, COMMON_ACTIONS::drawZone.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawKeepout, COMMON_ACTIONS::drawKeepout.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawZoneCutout, COMMON_ACTIONS::drawZoneCutout.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::PlaceText, COMMON_ACTIONS::placeText.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::PlaceDXF, COMMON_ACTIONS::placeDXF.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::SetAnchor, COMMON_ACTIONS::setAnchor.MakeEvent() );
|
||||
|
|
|
@ -143,6 +143,15 @@ public:
|
|||
*/
|
||||
int DrawKeepout( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Function DrawZoneCutout()
|
||||
* Starts interactively drawing a zone cutout area of an existing zone.
|
||||
* The normal zone interactive tool is used, but the zone settings
|
||||
* dialog is not shown (since the cutout affects only shape of an
|
||||
* existing zone).
|
||||
*/
|
||||
int DrawZoneCutout( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Function PlaceDXF()
|
||||
* Places a drawing imported from a DXF file in module editor.
|
||||
|
@ -159,6 +168,13 @@ public:
|
|||
void SetTransitions() override;
|
||||
|
||||
private:
|
||||
|
||||
enum class ZONE_MODE
|
||||
{
|
||||
ADD, ///< Add a new zone/keepout with fresh settings
|
||||
CUTOUT, ///< Make a cutout to an existing zone
|
||||
};
|
||||
|
||||
///> Shows the context menu for the drawing tool
|
||||
///> This menu consists of normal UI functions (zoom, grid, etc)
|
||||
///> And any suitable global functions for the active drawing type.
|
||||
|
@ -180,9 +196,14 @@ private:
|
|||
///> the same point.
|
||||
bool drawArc( DRAWSEGMENT*& aGraphic );
|
||||
|
||||
///> Draws a polygon, that is added as a zone or a keepout area.
|
||||
///> @param aKeepout decides if the drawn polygon is a zone or a keepout area.
|
||||
int drawZone( bool aKeepout );
|
||||
/**
|
||||
* Draws a polygon, that is added as a zone or a keepout area.
|
||||
*
|
||||
* @param aKeepout dictates if the drawn polygon is a zone or a
|
||||
* keepout area.
|
||||
* @param aMode dictates the mode of the zone tool
|
||||
*/
|
||||
int drawZone( bool aKeepout, ZONE_MODE aMode );
|
||||
|
||||
/**
|
||||
* Function createNewZone()
|
||||
|
@ -195,6 +216,44 @@ private:
|
|||
*/
|
||||
std::unique_ptr<ZONE_CONTAINER> createNewZone( bool aKeepout );
|
||||
|
||||
/**
|
||||
* Function createZoneFromExisting
|
||||
*
|
||||
* Create a new zone with the settings from an existing zone
|
||||
*
|
||||
* @param aSrcZone the zone to copy settings from
|
||||
* @return the new zone
|
||||
*/
|
||||
std::unique_ptr<ZONE_CONTAINER> createZoneFromExisting(
|
||||
const ZONE_CONTAINER& aSrcZone );
|
||||
|
||||
/**
|
||||
* Function getSourceZoneForAction()
|
||||
*
|
||||
* Gets a source zone item for an action that takes an existing zone
|
||||
* into account (for example a cutout of an existing zone). The source
|
||||
* zone is taken from the current selection
|
||||
*
|
||||
* @param aMode mode of the zone tool
|
||||
* @param aZone updated pointer to a suitable source zone,
|
||||
* or nullptr if none found, or the action doesn't need a source
|
||||
* @return true if a suitable zone was found, or the action doesn't
|
||||
* need a zone. False if the action needs a zone but none was found.
|
||||
*/
|
||||
bool getSourceZoneForAction( ZONE_MODE aMode, ZONE_CONTAINER*& aZone );
|
||||
|
||||
/**
|
||||
* Function performZoneCutout()
|
||||
*
|
||||
* Cut one zone out of another one (i.e. subtraction) and
|
||||
* update the zone.
|
||||
*
|
||||
* @param aExistingZone the zone to removed area from
|
||||
* @param aCutout the area to remove
|
||||
*/
|
||||
void performZoneCutout( ZONE_CONTAINER& aExistingZone,
|
||||
ZONE_CONTAINER& cutout );
|
||||
|
||||
/**
|
||||
* Function make45DegLine()
|
||||
* Forces a DRAWSEGMENT to be drawn at multiple of 45 degrees. The origin stays the same,
|
||||
|
|
|
@ -74,6 +74,7 @@ public:
|
|||
|
||||
Add( COMMON_ACTIONS::zoneMerge );
|
||||
Add( COMMON_ACTIONS::zoneDuplicate );
|
||||
Add( COMMON_ACTIONS::drawZoneCutout );
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -93,6 +94,7 @@ private:
|
|||
)( selTool->GetSelection() );
|
||||
|
||||
Enable( getMenuId( COMMON_ACTIONS::zoneDuplicate), singleZoneActionsEnabled );
|
||||
Enable( getMenuId( COMMON_ACTIONS::drawZoneCutout), singleZoneActionsEnabled );
|
||||
|
||||
// enable zone actions that ably to a specific set of zones (as opposed to all of them)
|
||||
bool nonGlobalActionsEnabled = ( SELECTION_CONDITIONS::MoreThan( 0 ) )( selTool->GetSelection() );
|
||||
|
|
Loading…
Reference in New Issue