GerbView GAL support part 1: changes to existing files

- New GAL draw layers for GerbView
- Improved bounding boxes for Gerber shapes
- Switched to use of SHAPE_POLY_SET for polygons
- Add GAL methods to support selection and rendering
- Add GUI support of editing GAL options
- Rename get/setActiveLayer to Get/SetActiveLayer to match convention
This commit is contained in:
Jon Evans 2017-09-17 18:43:20 -04:00 committed by Maciej Suminski
parent 460b1e8540
commit 915e51e1f0
42 changed files with 1483 additions and 535 deletions

View File

@ -100,7 +100,8 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
{
#define TO_POLY_SHAPE { aShapeBuffer.NewOutline(); \
for( unsigned jj = 0; jj < polybuffer.size(); jj++ )\
aShapeBuffer.Append( polybuffer[jj].x, polybuffer[jj].y );}
aShapeBuffer.Append( polybuffer[jj].x, polybuffer[jj].y );\
aShapeBuffer.Append( polybuffer[0].x, polybuffer[0].y );}
// Draw the primitive shape for flashed items.
static std::vector<wxPoint> polybuffer; // create a static buffer to avoid a lot of memory reallocation
@ -746,6 +747,50 @@ int AM_PRIMITIVE::GetShapeDim( GERBER_DRAW_ITEM* aParent )
}
SHAPE_POLY_SET* APERTURE_MACRO::GetApertureMacroShape( GERBER_DRAW_ITEM* aParent,
wxPoint aShapePos )
{
SHAPE_POLY_SET holeBuffer;
bool hasHole = false;
m_shape.RemoveAllContours();
for( AM_PRIMITIVES::iterator prim_macro = primitives.begin();
prim_macro != primitives.end(); ++prim_macro )
{
if( prim_macro->primitive_id == AMP_COMMENT )
continue;
if( prim_macro->IsAMPrimitiveExposureOn( aParent ) )
prim_macro->DrawBasicShape( aParent, m_shape, aShapePos );
else
{
prim_macro->DrawBasicShape( aParent, holeBuffer, aShapePos );
if( holeBuffer.OutlineCount() ) // we have a new hole in shape: remove the hole
{
m_shape.BooleanSubtract( holeBuffer, SHAPE_POLY_SET::PM_FAST );
holeBuffer.RemoveAllContours();
hasHole = true;
}
}
}
// If a hole is defined inside a polygon, we must fracture the polygon
// to be able to drawn it (i.e link holes by overlapping edges)
if( hasHole )
m_shape.Fracture( SHAPE_POLY_SET::PM_FAST );
m_boundingBox = EDA_RECT( wxPoint( 0, 0 ), wxSize( 1, 1 ) );
auto bb = m_shape.BBox();
wxPoint center( bb.Centre().x, bb.Centre().y );
m_boundingBox.Move( aParent->GetABPosition( center ) );
m_boundingBox.Inflate( bb.GetWidth() / 2, bb.GetHeight() / 2 );
return &m_shape;
}
/*
* Function DrawApertureMacroShape
* Draw the primitive shape for flashed items.
@ -756,39 +801,14 @@ void APERTURE_MACRO::DrawApertureMacroShape( GERBER_DRAW_ITEM* aParent,
COLOR4D aColor,
wxPoint aShapePos, bool aFilledShape )
{
SHAPE_POLY_SET shapeBuffer;
SHAPE_POLY_SET holeBuffer;
bool hasHole = false;
SHAPE_POLY_SET* shapeBuffer = GetApertureMacroShape( aParent, aShapePos );
for( AM_PRIMITIVES::iterator prim_macro = primitives.begin();
prim_macro != primitives.end(); ++prim_macro )
{
if( prim_macro->IsAMPrimitiveExposureOn( aParent ) )
prim_macro->DrawBasicShape( aParent, shapeBuffer, aShapePos );
else
{
prim_macro->DrawBasicShape( aParent, holeBuffer, aShapePos );
if( holeBuffer.OutlineCount() ) // we have a new hole in shape: remove the hole
{
shapeBuffer.BooleanSubtract( holeBuffer, SHAPE_POLY_SET::PM_FAST );
holeBuffer.RemoveAllContours();
hasHole = true;
}
}
}
if( shapeBuffer.OutlineCount() == 0 )
if( shapeBuffer->OutlineCount() == 0 )
return;
// If a hole is defined inside a polygon, we must fracture the polygon
// to be able to drawn it (i.e link holes by overlapping edges)
if( hasHole )
shapeBuffer.Fracture( SHAPE_POLY_SET::PM_FAST );
for( int ii = 0; ii < shapeBuffer.OutlineCount(); ii++ )
for( int ii = 0; ii < shapeBuffer->OutlineCount(); ii++ )
{
SHAPE_LINE_CHAIN& poly = shapeBuffer.Outline( ii );
SHAPE_LINE_CHAIN& poly = shapeBuffer->Outline( ii );
GRClosedPoly( aClipBox, aDC,
poly.PointCount(), (wxPoint*)&poly.Point( 0 ), aFilledShape, aColor, aColor );

View File

@ -35,6 +35,7 @@
#include <base_struct.h>
#include <class_am_param.h>
#include <class_eda_rect.h>
class SHAPE_POLY_SET;
@ -170,6 +171,9 @@ struct APERTURE_MACRO
*/
AM_PARAMS m_localparamStack;
SHAPE_POLY_SET m_shape; ///< The shape of the item, calculated by GetApertureMacroShape
EDA_RECT m_boundingBox; ///< The bounding box of the item, calculated by GetApertureMacroShape
/**
* function GetLocalParam
* Usually, parameters are defined inside the aperture primitive
@ -183,6 +187,16 @@ struct APERTURE_MACRO
*/
double GetLocalParam( const D_CODE* aDcode, unsigned aParamId ) const;
/**
* Function GetApertureMacroShape
* Calculate the primitive shape for flashed items.
* When an item is flashed, this is the shape of the item
* @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn
* @return The shape of the item
*/
SHAPE_POLY_SET* GetApertureMacroShape( GERBER_DRAW_ITEM* aParent, wxPoint aShapePos );
/**
* Function DrawApertureMacroShape
* Draw the primitive shape for flashed items.
@ -210,6 +224,12 @@ struct APERTURE_MACRO
* @return a dimension, or -1 if no dim to calculate
*/
int GetShapeDim( GERBER_DRAW_ITEM* aParent );
/// Returns the bounding box of the shape
EDA_RECT GetBoundingBox() const
{
return m_boundingBox;
}
};

View File

@ -47,6 +47,8 @@ public:
bool m_DisplayNegativeObjects; ///< Option to draw negative objects in a specific color
bool m_IsPrinting; ///< true when printing a page, false when drawing on screen
bool m_ForceBlackAndWhite; ///< Option print in blackand white (ont used id draw mode
bool m_DiffMode; ///< Display layers in diff mode
bool m_HighContrastMode; ///< High contrast mode (dim un-highlighted objects)
COLOR4D m_NegativeDrawColor; ///< The color used to draw negative objects, usually the
///< background color, but not always, when negative objects
///< must be visible
@ -65,6 +67,8 @@ public:
m_ForceBlackAndWhite = false;
m_NegativeDrawColor = COLOR4D( DARKGRAY );
m_BgDrawColor = COLOR4D::BLACK;
m_DiffMode = true;
m_HighContrastMode = false;
}
};

View File

@ -73,7 +73,7 @@ COLOR4D GBR_LAYER_BOX_SELECTOR::GetLayerColor( int aLayer ) const
{
GERBVIEW_FRAME* frame = (GERBVIEW_FRAME*) GetParent()->GetParent();
return frame->GetLayerColor( aLayer );
return frame->GetLayerColor( GERBER_DRAW_LAYER( aLayer ) );
}

View File

@ -36,7 +36,8 @@
#include <class_gerber_file_image.h>
#include <class_gerber_file_image_list.h>
GBR_LAYOUT::GBR_LAYOUT()
GBR_LAYOUT::GBR_LAYOUT() :
EDA_ITEM( (EDA_ITEM*)NULL, GERBER_LAYOUT_T )
{
}
@ -46,7 +47,7 @@ GBR_LAYOUT::~GBR_LAYOUT()
}
// Accessor to the list of gerber files (and drill files) images
GERBER_FILE_IMAGE_LIST* GBR_LAYOUT::GetImagesList()
GERBER_FILE_IMAGE_LIST* GBR_LAYOUT::GetImagesList() const
{
return &GERBER_FILE_IMAGE_LIST::GetImagesList();
}
@ -64,7 +65,7 @@ bool GBR_LAYOUT::IsLayerPrintable( int aLayer ) const
}
EDA_RECT GBR_LAYOUT::ComputeBoundingBox()
EDA_RECT GBR_LAYOUT::ComputeBoundingBox() const
{
EDA_RECT bbox;
bool first_item = true;
@ -88,7 +89,10 @@ EDA_RECT GBR_LAYOUT::ComputeBoundingBox()
}
}
SetBoundingBox( bbox );
bbox.Inflate( ( bbox.GetWidth() / 10 ) + 100 );
bbox.Normalize();
m_BoundingBox = bbox;
return bbox;
}
@ -185,7 +189,7 @@ void GBR_LAYOUT::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDrawMode,
// In non transparent modes, the last layer drawn masks others layers
for( int layer = GERBER_DRAWLAYERS_COUNT-1; !end; --layer )
{
int active_layer = gerbFrame->getActiveLayer();
int active_layer = gerbFrame->GetActiveLayer();
if( layer == active_layer ) // active layer will be drawn after other layers
continue;
@ -204,12 +208,12 @@ void GBR_LAYOUT::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDrawMode,
if( aDisplayOptions->m_IsPrinting )
gerber->m_IsVisible = IsLayerPrintable( layer );
else
gerber->m_IsVisible = gerbFrame->IsLayerVisible( layer );
gerber->m_IsVisible = gerbFrame->IsLayerVisible( GERBER_DRAW_LAYER( layer ) );
if( !gerber->m_IsVisible )
continue;
gerber->m_PositiveDrawColor = gerbFrame->GetLayerColor( layer );
gerber->m_PositiveDrawColor = gerbFrame->GetLayerColor( GERBER_DRAW_LAYER( layer ) );
// Force black and white draw mode on request:
if( aDisplayOptions->m_ForceBlackAndWhite )
@ -277,7 +281,7 @@ void GBR_LAYOUT::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDrawMode,
int dcode_highlight = 0;
if( layer == gerbFrame->getActiveLayer() )
if( layer == gerbFrame->GetActiveLayer() )
dcode_highlight = gerber->m_Selected_Tool;
GR_DRAWMODE layerdrawMode = GR_COPY;
@ -433,3 +437,50 @@ void GBR_LAYOUT::DrawItemsDCodeID( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
}
}
}
SEARCH_RESULT GBR_LAYOUT::Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] )
{
KICAD_T stype;
SEARCH_RESULT result = SEARCH_CONTINUE;
const KICAD_T* p = scanTypes;
bool done = false;
#if 0 && defined(DEBUG)
std::cout << GetClass().mb_str() << ' ';
#endif
while( !done )
{
stype = *p;
switch( stype )
{
case GERBER_IMAGE_LIST_T:
for( unsigned layer = 0; layer < GetImagesList()->ImagesMaxCount(); ++layer )
{
GERBER_FILE_IMAGE* gerber = GetImagesList()->GetGbrImage( layer );
if( gerber == NULL ) // Graphic layer not yet used
continue;
result = gerber->Visit( inspector, testData, p );
if( result == SEARCH_QUIT )
break;
}
++p;
break;
default: // catch EOT or ANY OTHER type here and return.
done = true;
break;
}
if( result == SEARCH_QUIT )
break;
}
return result;
}

View File

@ -50,10 +50,10 @@ class GERBER_FILE_IMAGE_LIST;
* Class GBR_LAYOUT
* holds list of GERBER_DRAW_ITEM currently loaded.
*/
class GBR_LAYOUT
class GBR_LAYOUT : public EDA_ITEM
{
private:
EDA_RECT m_BoundingBox;
mutable EDA_RECT m_BoundingBox;
TITLE_BLOCK m_titles;
wxPoint m_originAxisPosition;
std::vector<int> m_printLayersList; // When printing: the list of graphic layers Id to print
@ -63,9 +63,14 @@ public:
GBR_LAYOUT();
~GBR_LAYOUT();
wxString GetClass() const override
{
return wxT( "GBR_LAYOUT" );
}
// Accessor to the GERBER_FILE_IMAGE_LIST,
// which handles the list of gerber files (and drill files) images loaded
GERBER_FILE_IMAGE_LIST* GetImagesList();
GERBER_FILE_IMAGE_LIST* GetImagesList() const;
const wxPoint& GetAuxOrigin() const
{
@ -92,14 +97,15 @@ public:
* calculates the bounding box containing all Gerber items.
* @return EDA_RECT - the full item list bounding box
*/
EDA_RECT ComputeBoundingBox();
EDA_RECT ComputeBoundingBox() const;
/**
* Function GetBoundingBox
* may be called soon after ComputeBoundingBox() to return the same EDA_RECT,
* as long as the CLASS_GBR_LAYOUT has not changed.
*/
EDA_RECT GetBoundingBox() const { return m_BoundingBox; }
const EDA_RECT GetBoundingBox() const override
{
return ComputeBoundingBox();
}
void SetBoundingBox( const EDA_RECT& aBox ) { m_BoundingBox = aBox; }
@ -176,8 +182,13 @@ public:
*/
bool IsLayerPrintable( int aLayer ) const;
///> @copydoc EDA_ITEM::Visit()
SEARCH_RESULT Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] ) override;
#if defined(DEBUG)
void Show( int nestLevel, std::ostream& os ) const;
void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
#endif
};

View File

@ -33,6 +33,7 @@
#include <class_drawpanel.h>
#include <msgpanel.h>
#include <gerbview_frame.h>
#include <convert_basic_shapes_to_polygon.h>
#include <class_gerber_draw_item.h>
#include <class_gerber_file_image.h>
@ -40,7 +41,7 @@
GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( GERBER_FILE_IMAGE* aGerberImageFile ) :
EDA_ITEM( (EDA_ITEM*)NULL, TYPE_GERBER_DRAW_ITEM )
EDA_ITEM( (EDA_ITEM*)NULL, GERBER_DRAW_ITEM_T )
{
m_GerberImageFile = aGerberImageFile;
m_Shape = GBR_SEGMENT;
@ -158,7 +159,7 @@ void GERBER_DRAW_ITEM::SetLayerParameters()
}
wxString GERBER_DRAW_ITEM::ShowGBRShape()
wxString GERBER_DRAW_ITEM::ShowGBRShape() const
{
switch( m_Shape )
{
@ -203,7 +204,7 @@ wxString GERBER_DRAW_ITEM::ShowGBRShape()
}
D_CODE* GERBER_DRAW_ITEM::GetDcodeDescr()
D_CODE* GERBER_DRAW_ITEM::GetDcodeDescr() const
{
if( (m_DCode < FIRST_DCODE) || (m_DCode > LAST_DCODE) )
return NULL;
@ -211,7 +212,7 @@ D_CODE* GERBER_DRAW_ITEM::GetDcodeDescr()
if( m_GerberImageFile == NULL )
return NULL;
return m_GerberImageFile->GetDCODE( m_DCode, false );
return m_GerberImageFile->GetDCODE( m_DCode );
}
@ -219,8 +220,100 @@ const EDA_RECT GERBER_DRAW_ITEM::GetBoundingBox() const
{
// return a rectangle which is (pos,dim) in nature. therefore the +1
EDA_RECT bbox( m_Start, wxSize( 1, 1 ) );
D_CODE* code = GetDcodeDescr();
bbox.Inflate( m_Size.x / 2, m_Size.y / 2 );
// TODO(JE) GERBER_DRAW_ITEM maybe should actually be a number of subclasses.
// Until/unless that is changed, we need to do different things depending on
// what is actually being represented by this GERBER_DRAW_ITEM.
switch( m_Shape )
{
case GBR_POLYGON:
{
auto bb = m_Polygon.BBox();
bbox.Inflate( bb.GetWidth() / 2, bb.GetHeight() / 2 );
bbox.SetOrigin( bb.GetOrigin().x, bb.GetOrigin().y );
break;
}
case GBR_CIRCLE:
{
double radius = GetLineLength( m_Start, m_End );
bbox.Inflate( radius, radius );
break;
}
case GBR_ARC:
{
// Note: using a larger-than-necessary BB to simplify computation
double radius = GetLineLength( m_Start, m_ArcCentre );
bbox.Inflate( radius, radius );
break;
}
case GBR_SPOT_CIRCLE:
{
int radius = code->m_Size.x >> 1;
bbox.Inflate( radius, radius );
break;
}
case GBR_SPOT_RECT:
{
bbox.Inflate( code->m_Size.x / 2, code->m_Size.y / 2 );
break;
}
case GBR_SPOT_OVAL:
{
bbox.Inflate( code->m_Size.x, code->m_Size.y );
break;
}
case GBR_SPOT_POLY:
{
if( code->m_Polygon.OutlineCount() == 0 )
code->ConvertShapeToPolygon();
bbox.Inflate( code->m_Polygon.BBox().GetWidth() / 2, code->m_Polygon.BBox().GetHeight() / 2 );
break;
}
case GBR_SPOT_MACRO:
{
bbox = code->GetMacro()->GetBoundingBox();
break;
}
case GBR_SEGMENT:
{
if( code && code->m_Shape == APT_RECT )
{
if( m_Polygon.OutlineCount() > 0 )
{
auto bb = m_Polygon.BBox();
bbox.Inflate( bb.GetWidth() / 2, bb.GetHeight() / 2 );
bbox.SetOrigin( bb.GetOrigin().x, bb.GetOrigin().y );
}
}
else
{
int radius = ( m_Size.x + 1 ) / 2;
int ymax = std::max( m_Start.y, m_End.y ) + radius;
int xmax = std::max( m_Start.x, m_End.x ) + radius;
int ymin = std::min( m_Start.y, m_End.y ) - radius;
int xmin = std::min( m_Start.x, m_End.x ) - radius;
bbox = EDA_RECT( wxPoint( xmin, ymin ), wxSize( xmax - xmin + 1, ymax - ymin + 1 ) );
}
break;
}
default:
wxASSERT_MSG( false, wxT( "GERBER_DRAW_ITEM shape is unknown!" ) );
break;
}
// calculate the corners coordinates in current gerber axis orientations
wxPoint org = GetABPosition( bbox.GetOrigin() );
@ -243,8 +336,11 @@ void GERBER_DRAW_ITEM::MoveAB( const wxPoint& aMoveVector )
m_End += xymove;
m_ArcCentre += xymove;
for( unsigned ii = 0; ii < m_PolyCorners.size(); ii++ )
m_PolyCorners[ii] += xymove;
if( m_Polygon.OutlineCount() > 0 )
{
for( auto it = m_Polygon.Iterate( 0 ); it; ++it )
*it += xymove;
}
}
@ -254,8 +350,11 @@ void GERBER_DRAW_ITEM::MoveXY( const wxPoint& aMoveVector )
m_End += aMoveVector;
m_ArcCentre += aMoveVector;
for( unsigned ii = 0; ii < m_PolyCorners.size(); ii++ )
m_PolyCorners[ii] += aMoveVector;
if( m_Polygon.OutlineCount() > 0 )
{
for( auto it = m_Polygon.Iterate( 0 ); it; ++it )
*it += aMoveVector;
}
}
@ -378,8 +477,8 @@ void GERBER_DRAW_ITEM::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDra
*/
if( d_codeDescr->m_Shape == APT_RECT )
{
if( m_PolyCorners.size() == 0 )
ConvertSegmentToPolygon( );
if( m_Polygon.OutlineCount() == 0 )
ConvertSegmentToPolygon();
DrawGbrPoly( aPanel->GetClipBox(), aDC, color, aOffset, isFilled );
}
@ -411,10 +510,10 @@ void GERBER_DRAW_ITEM::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDra
}
void GERBER_DRAW_ITEM::ConvertSegmentToPolygon( )
void GERBER_DRAW_ITEM::ConvertSegmentToPolygon()
{
m_PolyCorners.clear();
m_PolyCorners.reserve(6);
m_Polygon.RemoveAllContours();
m_Polygon.NewOutline();
wxPoint start = m_Start;
wxPoint end = m_End;
@ -443,34 +542,37 @@ void GERBER_DRAW_ITEM::ConvertSegmentToPolygon( )
wxPoint corner;
corner.x -= m_Size.x/2;
corner.y -= m_Size.y/2;
m_PolyCorners.push_back( corner ); // Lower left corner, start point (1)
wxPoint close = corner;
m_Polygon.Append( VECTOR2I( corner ) ); // Lower left corner, start point (1)
corner.y += m_Size.y;
m_PolyCorners.push_back( corner ); // upper left corner, start point (2)
m_Polygon.Append( VECTOR2I( corner ) ); // upper left corner, start point (2)
if( delta.x || delta.y)
{
corner += delta;
m_PolyCorners.push_back( corner ); // upper left corner, end point (3)
m_Polygon.Append( VECTOR2I( corner ) ); // upper left corner, end point (3)
}
corner.x += m_Size.x;
m_PolyCorners.push_back( corner ); // upper right corner, end point (4)
m_Polygon.Append( VECTOR2I( corner ) ); // upper right corner, end point (4)
corner.y -= m_Size.y;
m_PolyCorners.push_back( corner ); // lower right corner, end point (5)
m_Polygon.Append( VECTOR2I( corner ) ); // lower right corner, end point (5)
if( delta.x || delta.y )
{
corner -= delta;
m_PolyCorners.push_back( corner ); // lower left corner, start point (6)
m_Polygon.Append( VECTOR2I( corner ) ); // lower left corner, start point (6)
}
m_Polygon.Append( VECTOR2I( close ) ); // close the shape
// Create final polygon:
for( unsigned ii = 0; ii < m_PolyCorners.size(); ii++ )
for( auto it = m_Polygon.Iterate( 0 ); it; ++it )
{
if( change )
m_PolyCorners[ii].y = -m_PolyCorners[ii].y;
( *it ).y = -( *it ).y;
m_PolyCorners[ii] += start;
*it += start;
}
}
@ -482,15 +584,19 @@ void GERBER_DRAW_ITEM::DrawGbrPoly( EDA_RECT* aClipBox,
bool aFilledShape )
{
std::vector<wxPoint> points;
SHAPE_LINE_CHAIN& poly = m_Polygon.Outline( 0 );
int pointCount = poly.PointCount() - 1;
points = m_PolyCorners;
for( unsigned ii = 0; ii < points.size(); ii++ )
points.reserve( pointCount );
for( int ii = 0; ii < pointCount; ii++ )
{
points[ii] += aOffset;
wxPoint p( poly.Point( ii ).x, poly.Point( ii ).y );
points[ii] = p + aOffset;
points[ii] = GetABPosition( points[ii] );
}
GRClosedPoly( aClipBox, aDC, points.size(), &points[0], aFilledShape, aColor, aColor );
GRClosedPoly( aClipBox, aDC, pointCount, &points[0], aFilledShape, aColor, aColor );
}
@ -506,7 +612,7 @@ void GERBER_DRAW_ITEM::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
msg.Printf( _( "D Code %d" ), m_DCode );
D_CODE* apertDescr = GetDcodeDescr();
if( apertDescr->m_AperFunction.IsEmpty() )
if( !apertDescr || apertDescr->m_AperFunction.IsEmpty() )
text = _( "No attribute" );
else
text = apertDescr->m_AperFunction;
@ -582,6 +688,37 @@ bool GERBER_DRAW_ITEM::HitTest( const wxPoint& aRefPos ) const
// TODO: a better analyze of the shape (perhaps create a D_CODE::HitTest for flashed items)
int radius = std::min( m_Size.x, m_Size.y ) >> 1;
SHAPE_POLY_SET poly;
switch( m_Shape )
{
case GBR_POLYGON:
poly = m_Polygon;
return poly.Contains( VECTOR2I( ref_pos ), 0 );
break;
case GBR_SPOT_POLY:
poly = GetDcodeDescr()->m_Polygon;
poly.Move( m_Start );
return poly.Contains( VECTOR2I( ref_pos ), 0 );
break;
case GBR_SPOT_RECT:
return GetBoundingBox().Contains( aRefPos );
break;
case GBR_SPOT_MACRO:
// Aperture macro polygons are already in absolute coordinates
poly = GetDcodeDescr()->GetMacro()->m_shape;
for( int i = 0; i < poly.OutlineCount(); ++i )
{
if( poly.Contains( VECTOR2I( aRefPos ), i ) )
return true;
}
return false;
break;
}
if( m_Flashed )
return HitTestPoints( m_Start, ref_pos, radius );
else
@ -624,3 +761,60 @@ void GERBER_DRAW_ITEM::Show( int nestLevel, std::ostream& os ) const
}
#endif
void GERBER_DRAW_ITEM::ViewGetLayers( int aLayers[], int& aCount ) const
{
aCount = 2;
aLayers[0] = GERBER_DRAW_LAYER( GetLayer() );
aLayers[1] = GERBER_DCODE_LAYER( aLayers[0] );
}
const BOX2I GERBER_DRAW_ITEM::ViewBBox() const
{
EDA_RECT bbox = GetBoundingBox();
return BOX2I( VECTOR2I( bbox.GetOrigin() ),
VECTOR2I( bbox.GetSize() ) );
}
unsigned int GERBER_DRAW_ITEM::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
{
// DCodes will be shown only if zoom is appropriate
if( IsDCodeLayer( aLayer ) )
{
return ( 400000 / ( m_Size.x + 1 ) );
}
// Other layers are shown without any conditions
return 0;
}
SEARCH_RESULT GERBER_DRAW_ITEM::Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] )
{
KICAD_T stype = *scanTypes;
// If caller wants to inspect my type
if( stype == Type() )
{
if( SEARCH_QUIT == inspector( this, testData ) )
return SEARCH_QUIT;
}
return SEARCH_CONTINUE;
}
wxString GERBER_DRAW_ITEM::GetSelectMenuText() const
{
wxString text, layerName;
layerName = GERBER_FILE_IMAGE_LIST::GetImagesList().GetDisplayName( GetLayer(), true );
text.Printf( _( "%s (D%d) on layer %d: %s" ), ShowGBRShape(), m_DCode,
GetLayer() + 1, layerName );
return text;
}

View File

@ -35,6 +35,7 @@
#include <gr_basic.h>
#include <gbr_netlist_metadata.h>
#include <dcode.h>
#include <geometry/shape_poly_set.h>
class GERBER_FILE_IMAGE;
class GBR_LAYOUT;
@ -42,6 +43,11 @@ class D_CODE;
class MSG_PANEL_ITEM;
class GBR_DISPLAY_OPTIONS;
namespace KIGFX
{
class VIEW;
};
/* Shapes id for basic shapes ( .m_Shape member ) */
enum Gbr_Basic_Shapes {
@ -76,7 +82,7 @@ public:
// for flashed items
wxPoint m_End; // Line or arc end point
wxPoint m_ArcCentre; // for arcs only: Centre of arc
std::vector <wxPoint> m_PolyCorners; // list of corners for polygons (G36 to G37 coordinates)
SHAPE_POLY_SET m_Polygon; // Polygon shape data (G36 to G37 coordinates)
// or for complex shapes which are converted to polygon
wxSize m_Size; // Flashed shapes: size of the shape
// Lines : m_Size.x = m_Size.y = line width
@ -116,7 +122,7 @@ public:
GERBER_DRAW_ITEM* Back() const { return static_cast<GERBER_DRAW_ITEM*>( Pback ); }
void SetNetAttributes( const GBR_NETLIST_METADATA& aNetAttributes );
const GBR_NETLIST_METADATA& GetNetAttributes() { return m_netAttributes; }
const GBR_NETLIST_METADATA& GetNetAttributes() const { return m_netAttributes; }
/**
* Function GetLayer
@ -124,7 +130,7 @@ public:
*/
int GetLayer() const;
bool GetLayerPolarity()
bool GetLayerPolarity() const
{
return m_LayerNegative;
}
@ -186,6 +192,11 @@ public:
*/
wxPoint GetABPosition( const wxPoint& aXYPosition ) const;
VECTOR2I GetABPosition( const VECTOR2I& aXYPosition ) const
{
return VECTOR2I( GetABPosition( wxPoint( aXYPosition.x, aXYPosition.y ) ) );
}
/**
* Function GetXYPosition
* returns the image position of aPosition for this object.
@ -201,7 +212,7 @@ public:
* returns the GetDcodeDescr of this object, or NULL.
* @return D_CODE* - a pointer to the DCode description (for flashed items).
*/
D_CODE* GetDcodeDescr();
D_CODE* GetDcodeDescr() const;
const EDA_RECT GetBoundingBox() const override;
@ -229,7 +240,7 @@ public:
void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) override;
wxString ShowGBRShape();
wxString ShowGBRShape() const;
/**
* Function HitTest
@ -284,6 +295,26 @@ public:
void Show( int nestLevel, std::ostream& os ) const override;
#endif
/// @copydoc VIEW_ITEM::ViewGetLayers()
virtual void ViewGetLayers( int aLayers[], int& aCount ) const override;
/// @copydoc VIEW_ITEM::ViewBBox()
virtual const BOX2I ViewBBox() const override;
/// @copydoc VIEW_ITEM::ViewGetLOD()
virtual unsigned int ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const override;
///> @copydoc EDA_ITEM::Visit()
SEARCH_RESULT Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] ) override;
virtual wxString GetSelectMenuText() const override;
};
class GERBER_NEGATIVE_IMAGE_BACKDROP : public EDA_ITEM
{
};
#endif /* CLASS_GERBER_DRAW_ITEM_H */

View File

@ -89,7 +89,8 @@ void GERBER_LAYER::ResetDefaultValues()
}
GERBER_FILE_IMAGE::GERBER_FILE_IMAGE( int aLayer )
GERBER_FILE_IMAGE::GERBER_FILE_IMAGE( int aLayer ) :
EDA_ITEM( (EDA_ITEM*)NULL, GERBER_IMAGE_T )
{
m_GraphicLayer = aLayer; // Graphic layer Number
m_IsVisible = true; // must be drawn
@ -126,7 +127,8 @@ GERBER_DRAW_ITEM * GERBER_FILE_IMAGE::GetItemsList()
return m_Drawings;
}
D_CODE* GERBER_FILE_IMAGE::GetDCODE( int aDCODE, bool aCreateIfNoExist )
D_CODE* GERBER_FILE_IMAGE::GetDCODEOrCreate( int aDCODE, bool aCreateIfNoExist )
{
unsigned ndx = aDCODE - FIRST_DCODE;
@ -146,6 +148,19 @@ D_CODE* GERBER_FILE_IMAGE::GetDCODE( int aDCODE, bool aCreateIfNoExist )
}
D_CODE* GERBER_FILE_IMAGE::GetDCODE( int aDCODE ) const
{
unsigned ndx = aDCODE - FIRST_DCODE;
if( ndx < (unsigned) DIM( m_Aperture_List ) )
{
return m_Aperture_List[ndx];
}
return NULL;
}
APERTURE_MACRO* GERBER_FILE_IMAGE::FindApertureMacro( const APERTURE_MACRO& aLookup )
{
APERTURE_MACRO_SET::iterator iter = m_aperture_macros.find( aLookup );
@ -370,3 +385,43 @@ void GERBER_FILE_IMAGE::RemoveAttribute( X2_ATTRIBUTE& aAttribute )
if( aAttribute.GetPrm( 1 ).IsEmpty() || aAttribute.GetPrm( 1 ) == ".AperFunction" )
m_AperFunction.Clear();
}
SEARCH_RESULT GERBER_FILE_IMAGE::Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] )
{
KICAD_T stype;
SEARCH_RESULT result = SEARCH_CONTINUE;
const KICAD_T* p = scanTypes;
bool done = false;
#if 0 && defined(DEBUG)
std::cout << GetClass().mb_str() << ' ';
#endif
while( !done )
{
stype = *p;
switch( stype )
{
case GERBER_IMAGE_T:
case GERBER_IMAGE_LIST_T:
++p;
break;
case GERBER_DRAW_ITEM_T:
result = IterateForward( &m_Drawings[0], inspector, testData, p );
++p;
break;
default: // catch EOT or ANY OTHER type here and return.
done = true;
break;
}
if( result == SEARCH_QUIT )
break;
}
return result;
}

View File

@ -95,7 +95,7 @@ private:
* holds the Image data and parameters for one gerber file
* and layer parameters (TODO: move them in GERBER_LAYER class
*/
class GERBER_FILE_IMAGE
class GERBER_FILE_IMAGE : public EDA_ITEM
{
D_CODE* m_Aperture_List[TOOLS_MAX_COUNT]; ///< Dcode (Aperture) List for this layer (max 999)
bool m_Exposure; ///< whether an aperture macro tool is flashed on or off
@ -180,6 +180,11 @@ public:
GERBER_FILE_IMAGE( int layer );
virtual ~GERBER_FILE_IMAGE();
wxString GetClass() const override
{
return wxT( "GERBER_FILE_IMAGE" );
}
void Clear_GERBER_FILE_IMAGE();
/**
@ -300,7 +305,7 @@ public:
/**
* Function GetDCODE
* Function GetDCODEOrCreate
* returns a pointer to the D_CODE within this GERBER for the given
* \a aDCODE.
* @param aDCODE The numeric value of the D_CODE to look up.
@ -309,7 +314,17 @@ public:
* @return D_CODE* - the one implied by the given \a aDCODE, or NULL
* if the requested \a aDCODE is out of range.
*/
D_CODE* GetDCODE( int aDCODE, bool aCreateIfNoExist = true );
D_CODE* GetDCODEOrCreate( int aDCODE, bool aCreateIfNoExist = true );
/**
* Function GetDCODE
* returns a pointer to the D_CODE within this GERBER for the given
* \a aDCODE.
* @param aDCODE The numeric value of the D_CODE to look up.
* @return D_CODE* - the one implied by the given \a aDCODE, or NULL
* if the requested \a aDCODE is out of range.
*/
D_CODE* GetDCODE( int aDCODE ) const;
/**
* Function FindApertureMacro
@ -350,6 +365,15 @@ public:
* only this attribute is cleared
*/
void RemoveAttribute( X2_ATTRIBUTE& aAttribute );
///> @copydoc EDA_ITEM::Visit()
SEARCH_RESULT Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] ) override;
#if defined(DEBUG)
void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
#endif
};
#endif // ifndef CLASS_GERBER_FILE_IMAGE_H

View File

@ -43,7 +43,8 @@ GERBER_FILE_IMAGE_LIST s_GERBER_List;
// GERBER_FILE_IMAGE_LIST is a helper class to handle a list of GERBER_FILE_IMAGE files
GERBER_FILE_IMAGE_LIST::GERBER_FILE_IMAGE_LIST()
GERBER_FILE_IMAGE_LIST::GERBER_FILE_IMAGE_LIST() :
EDA_ITEM( (EDA_ITEM*)NULL, GERBER_IMAGE_LIST_T )
{
m_GERBER_List.reserve( GERBER_DRAWLAYERS_COUNT );
@ -244,4 +245,3 @@ void GERBER_FILE_IMAGE_LIST::SortImagesByZOrder()
gerber->m_GraphicLayer = layer ;
}
}

View File

@ -59,7 +59,7 @@ class GERBER_FILE_IMAGE;
* which are loaded and can be displayed
* there are 32 images max which can be loaded
*/
class GERBER_FILE_IMAGE_LIST
class GERBER_FILE_IMAGE_LIST : public EDA_ITEM
{
// the list of loaded images (1 image = 1 gerber file)
std::vector<GERBER_FILE_IMAGE*> m_GERBER_List;
@ -68,6 +68,11 @@ public:
GERBER_FILE_IMAGE_LIST();
~GERBER_FILE_IMAGE_LIST();
wxString GetClass() const override
{
return wxT( "GERBER_FILE_IMAGE_LIST" );
}
//Accessor
static GERBER_FILE_IMAGE_LIST& GetImagesList();
GERBER_FILE_IMAGE* GetGbrImage( int aIdx );
@ -115,6 +120,12 @@ public:
* (SortImagesByZOrder updates the graphic layer of these items)
*/
void SortImagesByZOrder();
#if defined(DEBUG)
void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
#endif
};
#endif // ifndef CLASS_GERBER_FILE_IMAGE_LIST_H

View File

@ -41,6 +41,10 @@
#include <layer_widget.h>
#include <class_gerbview_layer_widget.h>
#include <view/view.h>
#include <gerbview_painter.h>
#include <gal/graphics_abstraction_layer.h>
/*
* Class GERBER_LAYER_WIDGET
@ -80,6 +84,12 @@ GERBER_FILE_IMAGE_LIST* GERBER_LAYER_WIDGET::GetImagesList()
}
bool GERBER_LAYER_WIDGET::AreArbitraryColorsAllowed()
{
return myframe->IsGalCanvasActive();
}
void GERBER_LAYER_WIDGET::SetLayersManagerTabsText( )
{
m_notebook->SetPageText(0, _("Layer") );
@ -180,8 +190,11 @@ void GERBER_LAYER_WIDGET::onPopupSelection( wxCommandEvent& event )
int layer = getDecodedId( cb->GetId() );
bool loc_visible = visible;
if( force_active_layer_visible && (layer == myframe->getActiveLayer() ) )
if( force_active_layer_visible &&
(layer == GERBER_DRAW_LAYER( myframe->GetActiveLayer() ) ) )
{
loc_visible = true;
}
cb->SetValue( loc_visible );
@ -228,8 +241,19 @@ void GERBER_LAYER_WIDGET::ReFill()
{
wxString msg = GetImagesList()->GetDisplayName( layer );
AppendLayerRow( LAYER_WIDGET::ROW( msg, layer,
myframe->GetLayerColor( layer ), wxEmptyString, true ) );
bool visible = true;
if( auto canvas = myframe->GetGalCanvas() )
{
visible = canvas->GetView()->IsLayerVisible( GERBER_DRAW_LAYER( layer ) );
}
else
{
visible = myframe->IsLayerVisible( layer );
}
AppendLayerRow( LAYER_WIDGET::ROW( msg, GERBER_DRAW_LAYER( layer ),
myframe->GetLayerColor( GERBER_DRAW_LAYER( layer ) ),
wxEmptyString, visible, true ) );
}
Thaw();
@ -246,6 +270,14 @@ void GERBER_LAYER_WIDGET::OnLayerColorChange( int aLayer, COLOR4D aColor )
{
myframe->SetLayerColor( aLayer, aColor );
myframe->m_SelLayerBox->ResyncBitmapOnly();
if( myframe->IsGalCanvasActive() )
{
KIGFX::VIEW* view = myframe->GetGalCanvas()->GetView();
view->GetPainter()->GetSettings()->ImportLegacyColors( myframe->m_colorsSettings );
view->UpdateLayerColor( aLayer );
}
myframe->GetCanvas()->Refresh();
}
@ -253,11 +285,13 @@ bool GERBER_LAYER_WIDGET::OnLayerSelect( int aLayer )
{
// the layer change from the GERBER_LAYER_WIDGET can be denied by returning
// false from this function.
int layer = myframe->getActiveLayer( );
myframe->setActiveLayer( aLayer, false );
int layer = myframe->GetActiveLayer( );
// TODO(JE) ActiveLayer is stored as an index from 0 rather than as a layer
// id matching GERBER_DRAW_LAYER( idx ), is this what we want long-term?
myframe->SetActiveLayer( GERBER_DRAW_LAYER_INDEX( aLayer ), false );
myframe->syncLayerBox();
if( layer != myframe->getActiveLayer( ) )
if( layer != myframe->GetActiveLayer( ) )
{
if( ! OnLayerSelected() )
myframe->GetCanvas()->Refresh();
@ -284,12 +318,47 @@ void GERBER_LAYER_WIDGET::OnLayerVisible( int aLayer, bool isVisible, bool isFin
void GERBER_LAYER_WIDGET::OnRenderColorChange( int aId, COLOR4D aColor )
{
myframe->SetVisibleElementColor( (GERBVIEW_LAYER_ID) aId, aColor );
auto galCanvas = myframe->GetGalCanvas();
if( galCanvas && myframe->IsGalCanvasActive() )
{
auto view = galCanvas->GetView();
view->GetPainter()->GetSettings()->ImportLegacyColors( myframe->m_colorsSettings );
view->UpdateLayerColor( aId );
// TODO(JE) Why are the below two lines needed? Not needed in pcbnew
view->MarkTargetDirty( KIGFX::TARGET_NONCACHED );
view->RecacheAllItems();
}
if( galCanvas && myframe->IsGalCanvasActive() )
galCanvas->Refresh();
else
myframe->GetCanvas()->Refresh();
}
void GERBER_LAYER_WIDGET::OnRenderEnable( int aId, bool isEnabled )
{
myframe->SetElementVisibility( (GERBVIEW_LAYER_ID) aId, isEnabled );
auto galCanvas = myframe->GetGalCanvas();
if( galCanvas )
{
if( aId == LAYER_GERBVIEW_GRID )
{
galCanvas->GetGAL()->SetGridVisibility( myframe->IsGridVisible() );
galCanvas->GetView()->MarkTargetDirty( KIGFX::TARGET_NONCACHED );
// TODO(JE) Why is the below line needed? Not needed in pcbnew
galCanvas->GetView()->RecacheAllItems();
}
else
galCanvas->GetView()->SetLayerVisible( aId, isEnabled );
}
if( galCanvas && myframe->IsGalCanvasActive() )
galCanvas->Refresh();
else
myframe->GetCanvas()->Refresh();
}

View File

@ -65,6 +65,8 @@ class GERBER_LAYER_WIDGET : public LAYER_WIDGET
*/
virtual bool useAlternateBitmap(int aRow) override;
virtual bool AreArbitraryColorsAllowed() override;
GERBER_FILE_IMAGE_LIST* GetImagesList();
public:

View File

@ -35,6 +35,7 @@
#include <class_gerber_file_image.h>
#include <class_gerber_file_image_list.h>
#include <class_gerbview_layer_widget.h>
#include <view/view.h>
bool GERBVIEW_FRAME::Clear_DrawLayers( bool query )
{
@ -47,11 +48,16 @@ bool GERBVIEW_FRAME::Clear_DrawLayers( bool query )
return false;
}
if( auto canvas = GetGalCanvas() )
{
canvas->GetView()->Clear();
}
GetImagesList()->DeleteAllImages();
GetGerberLayout()->SetBoundingBox( EDA_RECT() );
setActiveLayer( 0 );
SetActiveLayer( 0 );
ReFillLayerWidget();
syncLayerBox();
return true;
@ -60,7 +66,7 @@ bool GERBVIEW_FRAME::Clear_DrawLayers( bool query )
void GERBVIEW_FRAME::Erase_Current_DrawLayer( bool query )
{
int layer = getActiveLayer();
int layer = GetActiveLayer();
wxString msg;
msg.Printf( _( "Clear layer %d?" ), layer + 1 );

View File

@ -36,6 +36,7 @@
#include <gerbview_frame.h>
#include <class_gerber_file_image.h>
#include <convert_to_biu.h>
#include <convert_basic_shapes_to_polygon.h>
#define DCODE_DEFAULT_SIZE Millimeter2iu( 0.1 )
@ -87,7 +88,7 @@ void D_CODE::Clear_D_CODE_Data()
m_Macro = NULL;
m_Rotation = 0.0;
m_EdgesCount = 0;
m_PolyCorners.clear();
m_Polygon.RemoveAllContours();
}
@ -173,7 +174,7 @@ void D_CODE::DrawFlashedShape( GERBER_DRAW_ITEM* aParent,
GRFilledCircle( aClipBox, aDC, aParent->GetABPosition(aShapePos),
radius, aColor );
}
else if( APT_DEF_ROUND_HOLE == 1 ) // round hole in shape
else if( m_DrillShape == APT_DEF_ROUND_HOLE ) // round hole in shape
{
int width = (m_Size.x - m_Drill.x ) / 2;
GRCircle( aClipBox, aDC, aParent->GetABPosition(aShapePos),
@ -181,7 +182,7 @@ void D_CODE::DrawFlashedShape( GERBER_DRAW_ITEM* aParent,
}
else // rectangular hole
{
if( m_PolyCorners.size() == 0 )
if( m_Polygon.OutlineCount() == 0 )
ConvertShapeToPolygon();
DrawFlashedPolygon( aParent, aClipBox, aDC, aColor, aFilledShape, aShapePos );
@ -207,7 +208,7 @@ void D_CODE::DrawFlashedShape( GERBER_DRAW_ITEM* aParent,
}
else
{
if( m_PolyCorners.size() == 0 )
if( m_Polygon.OutlineCount() == 0 )
ConvertShapeToPolygon();
DrawFlashedPolygon( aParent, aClipBox, aDC, aColor, aFilledShape, aShapePos );
@ -248,7 +249,7 @@ void D_CODE::DrawFlashedShape( GERBER_DRAW_ITEM* aParent,
}
else
{
if( m_PolyCorners.size() == 0 )
if( m_Polygon.OutlineCount() == 0 )
ConvertShapeToPolygon();
DrawFlashedPolygon( aParent, aClipBox, aDC, aColor, aFilledShape, aShapePos );
@ -257,7 +258,7 @@ void D_CODE::DrawFlashedShape( GERBER_DRAW_ITEM* aParent,
break;
case APT_POLYGON:
if( m_PolyCorners.size() == 0 )
if( m_Polygon.OutlineCount() == 0 )
ConvertShapeToPolygon();
DrawFlashedPolygon( aParent, aClipBox, aDC, aColor, aFilledShape, aShapePos );
@ -271,27 +272,29 @@ void D_CODE::DrawFlashedPolygon( GERBER_DRAW_ITEM* aParent,
COLOR4D aColor, bool aFilled,
const wxPoint& aPosition )
{
if( m_PolyCorners.size() == 0 )
if( m_Polygon.OutlineCount() == 0 )
return;
int pointCount = m_Polygon.VertexCount();
std::vector<wxPoint> points;
points = m_PolyCorners;
points.reserve( pointCount );
for( unsigned ii = 0; ii < points.size(); ii++ )
for( int ii = 0; ii < pointCount; ii++ )
{
points[ii] += aPosition;
wxPoint p( m_Polygon.Vertex( ii ).x, m_Polygon.Vertex( ii ).y );
points[ii] = p + aPosition;
points[ii] = aParent->GetABPosition( points[ii] );
}
GRClosedPoly( aClipBox, aDC, points.size(), &points[0], aFilled, aColor, aColor );
GRClosedPoly( aClipBox, aDC, pointCount, &points[0], aFilled, aColor, aColor );
}
#define SEGS_CNT 32 // number of segments to approximate a circle
#define SEGS_CNT 64 // number of segments to approximate a circle
// A helper function for D_CODE::ConvertShapeToPolygon(). Add a hole to a polygon
static void addHoleToPolygon( std::vector<wxPoint>& aBuffer,
static void addHoleToPolygon( SHAPE_POLY_SET* aPolygon,
APERTURE_DEF_HOLETYPE aHoleShape,
wxSize aSize,
wxPoint aAnchorPos );
@ -302,43 +305,37 @@ void D_CODE::ConvertShapeToPolygon()
wxPoint initialpos;
wxPoint currpos;
m_PolyCorners.clear();
m_Polygon.RemoveAllContours();
switch( m_Shape )
{
case APT_CIRCLE: // creates only a circle with rectangular hole
currpos.x = m_Size.x >> 1;
initialpos = currpos;
for( unsigned ii = 0; ii <= SEGS_CNT; ii++ )
{
currpos = initialpos;
RotatePoint( &currpos, ii * 3600.0 / SEGS_CNT );
m_PolyCorners.push_back( currpos );
}
addHoleToPolygon( m_PolyCorners, m_DrillShape, m_Drill, initialpos );
TransformCircleToPolygon( m_Polygon, initialpos, m_Size.x >> 1, SEGS_CNT );
addHoleToPolygon( &m_Polygon, m_DrillShape, m_Drill, initialpos );
break;
case APT_RECT:
m_Polygon.NewOutline();
currpos.x = m_Size.x / 2;
currpos.y = m_Size.y / 2;
initialpos = currpos;
m_PolyCorners.push_back( currpos );
m_Polygon.Append( VECTOR2I( currpos ) );
currpos.x -= m_Size.x;
m_PolyCorners.push_back( currpos );
m_Polygon.Append( VECTOR2I( currpos ) );
currpos.y -= m_Size.y;
m_PolyCorners.push_back( currpos );
m_Polygon.Append( VECTOR2I( currpos ) );
currpos.x += m_Size.x;
m_PolyCorners.push_back( currpos );
m_Polygon.Append( VECTOR2I( currpos ) );
currpos.y += m_Size.y;
m_PolyCorners.push_back( currpos ); // close polygon
m_Polygon.Append( VECTOR2I( currpos ) ); // close polygon
m_Polygon.Append( VECTOR2I( initialpos ) );
addHoleToPolygon( m_PolyCorners, m_DrillShape, m_Drill, initialpos );
addHoleToPolygon( &m_Polygon, m_DrillShape, m_Drill, initialpos );
break;
case APT_OVAL:
{
m_Polygon.NewOutline();
int delta, radius;
// we create an horizontal oval shape. then rotate if needed
@ -355,7 +352,7 @@ void D_CODE::ConvertShapeToPolygon()
currpos.y = radius;
initialpos = currpos;
m_PolyCorners.push_back( currpos );
m_Polygon.Append( VECTOR2I( currpos ) );
// build the right arc of the shape
unsigned ii = 0;
@ -365,7 +362,7 @@ void D_CODE::ConvertShapeToPolygon()
currpos = initialpos;
RotatePoint( &currpos, ii * 3600.0 / SEGS_CNT );
currpos.x += delta;
m_PolyCorners.push_back( currpos );
m_Polygon.Append( VECTOR2I( currpos ) );
}
// build the left arc of the shape
@ -374,22 +371,23 @@ void D_CODE::ConvertShapeToPolygon()
currpos = initialpos;
RotatePoint( &currpos, ii * 3600.0 / SEGS_CNT );
currpos.x -= delta;
m_PolyCorners.push_back( currpos );
m_Polygon.Append( VECTOR2I( currpos ) );
}
m_PolyCorners.push_back( initialpos ); // close outline
m_Polygon.Append( VECTOR2I( initialpos ) ); // close outline
if( m_Size.y > m_Size.x ) // vertical oval, rotate polygon.
{
for( unsigned jj = 0; jj < m_PolyCorners.size(); jj++ )
RotatePoint( &m_PolyCorners[jj], 900 );
for( auto it = m_Polygon.Iterate( 0 ); it; ++it )
it->Rotate( -M_PI / 2 );
}
addHoleToPolygon( m_PolyCorners, m_DrillShape, m_Drill, initialpos );
addHoleToPolygon( &m_Polygon, m_DrillShape, m_Drill, initialpos );
}
break;
case APT_POLYGON:
m_Polygon.NewOutline();
currpos.x = m_Size.x >> 1; // first point is on X axis
initialpos = currpos;
@ -400,23 +398,21 @@ void D_CODE::ConvertShapeToPolygon()
if( m_EdgesCount > 12 )
m_EdgesCount = 12;
for( int ii = 0; ii <= m_EdgesCount; ii++ )
for( int ii = 0; ii < m_EdgesCount; ii++ )
{
currpos = initialpos;
RotatePoint( &currpos, ii * 3600.0 / m_EdgesCount );
m_PolyCorners.push_back( currpos );
m_Polygon.Append( VECTOR2I( currpos ) );
}
addHoleToPolygon( m_PolyCorners, m_DrillShape, m_Drill, initialpos );
addHoleToPolygon( &m_Polygon, m_DrillShape, m_Drill, initialpos );
if( m_Rotation ) // vertical oval, rotate polygon.
{
int angle = KiROUND( m_Rotation * 10 );
for( unsigned jj = 0; jj < m_PolyCorners.size(); jj++ )
{
RotatePoint( &m_PolyCorners[jj], -angle );
}
for( auto it = m_Polygon.Iterate( 0 ); it; ++it )
it->Rotate( -angle );
}
break;
@ -431,39 +427,36 @@ void D_CODE::ConvertShapeToPolygon()
// The helper function for D_CODE::ConvertShapeToPolygon().
// Add a hole to a polygon
static void addHoleToPolygon( std::vector<wxPoint>& aBuffer,
static void addHoleToPolygon( SHAPE_POLY_SET* aPolygon,
APERTURE_DEF_HOLETYPE aHoleShape,
wxSize aSize,
wxPoint aAnchorPos )
{
wxPoint currpos;
SHAPE_POLY_SET holeBuffer;
if( aHoleShape == APT_DEF_ROUND_HOLE ) // build a round hole
if( aHoleShape == APT_DEF_ROUND_HOLE )
{
for( int ii = 0; ii <= SEGS_CNT; ii++ )
{
currpos.x = 0;
currpos.y = aSize.x / 2; // aSize.x / 2 is the radius of the hole
RotatePoint( &currpos, ii * 3600.0 / SEGS_CNT );
aBuffer.push_back( currpos );
TransformCircleToPolygon( holeBuffer, wxPoint( 0, 0 ), aSize.x / 2, SEGS_CNT );
}
aBuffer.push_back( aAnchorPos ); // link to outline
}
if( aHoleShape == APT_DEF_RECT_HOLE ) // Create rectangular hole
else if( aHoleShape == APT_DEF_RECT_HOLE )
{
holeBuffer.NewOutline();
currpos.x = aSize.x / 2;
currpos.y = aSize.y / 2;
aBuffer.push_back( currpos ); // link to hole and begin hole
holeBuffer.Append( VECTOR2I( currpos ) ); // link to hole and begin hole
currpos.x -= aSize.x;
aBuffer.push_back( currpos );
holeBuffer.Append( VECTOR2I( currpos ) );
currpos.y -= aSize.y;
aBuffer.push_back( currpos );
holeBuffer.Append( VECTOR2I( currpos ) );
currpos.x += aSize.x;
aBuffer.push_back( currpos );
holeBuffer.Append( VECTOR2I( currpos ) );
currpos.y += aSize.y;
aBuffer.push_back( currpos ); // close hole
aBuffer.push_back( aAnchorPos ); // link to outline
holeBuffer.Append( VECTOR2I( currpos ) ); // close hole
}
aPolygon->BooleanSubtract( holeBuffer, SHAPE_POLY_SET::PM_FAST );
// Needed for legacy canvas only
aPolygon->Fracture( SHAPE_POLY_SET::PM_FAST );
}

View File

@ -34,6 +34,7 @@
#include <base_struct.h>
#include <gal/color4d.h>
#include <geometry/shape_poly_set.h>
using KIGFX::COLOR4D;
@ -89,11 +90,6 @@ private:
*/
std::vector<double> m_am_params;
std::vector <wxPoint> m_PolyCorners; /* Polygon used to draw APT_POLYGON shape and some other
* complex shapes which are converted to polygon
* (shapes with hole )
*/
public:
wxSize m_Size; ///< Horizontal and vertical dimensions.
APERTURE_T m_Shape; ///< shape ( Line, rectangle, circle , oval .. )
@ -108,7 +104,10 @@ public:
bool m_Defined; ///< false if the aperture is not defined in the header
wxString m_AperFunction; ///< the aperture attribute (created by a %TA.AperFunction command)
///< attached to the D_CODE
SHAPE_POLY_SET m_Polygon; /* Polygon used to draw APT_POLYGON shape and some other
* complex shapes which are converted to polygon
* (shapes with hole )
*/
public:
D_CODE( int num_dcode );

View File

@ -32,11 +32,18 @@
#include <common.h>
#include <macros.h>
#include <class_drawpanel.h>
#include <config_map.h>
#include <gerbview.h>
#include <gerbview_frame.h>
#include <gerbview_dialog_display_options_frame_base.h>
#include <class_draw_panel_gal.h>
#include <view/view.h>
#include <gerbview_painter.h>
#include <gal/gal_display_options.h>
#include <widgets/gal_options_panel.h>
/*******************************************/
/* Dialog frame to select display options */
@ -45,6 +52,7 @@ class DIALOG_DISPLAY_OPTIONS : public DIALOG_DISPLAY_OPTIONS_BASE
{
private:
GERBVIEW_FRAME* m_Parent;
GAL_OPTIONS_PANEL* m_galOptsPanel;
public:
@ -79,6 +87,8 @@ DIALOG_DISPLAY_OPTIONS::DIALOG_DISPLAY_OPTIONS( GERBVIEW_FRAME *parent) :
GetSizer()->SetSizeHints( this );
Center();
m_sdbSizer1OK->SetDefault();
FinishDialogSettings();
}
@ -90,23 +100,14 @@ void DIALOG_DISPLAY_OPTIONS::OnCancelButtonClick( wxCommandEvent& event )
void DIALOG_DISPLAY_OPTIONS::initOptDialog( )
{
KIGFX::GAL_DISPLAY_OPTIONS& galOptions = m_Parent->GetGalDisplayOptions();
m_galOptsPanel = new GAL_OPTIONS_PANEL( this, galOptions );
m_UpperSizer->Add( m_galOptsPanel, 0, wxEXPAND, 0 );
m_galOptsPanel->TransferDataToWindow();
m_PolarDisplay->SetSelection( m_Parent->m_DisplayOptions.m_DisplayPolarCood ? 1 : 0 );
m_BoxUnits->SetSelection( g_UserUnit ? 1 : 0 );
// @todo: LEGACY: Cursor shape can be set using the GAL options
// widget, when that is added to gerbview. For now, access the
// setting via the frame's GAL options object directly
// Cursor shape cannot be implemented on OS X
#ifdef __APPLE__
m_CursorShape->Hide();
#else
{
auto& galOpts = m_Parent->GetGalDisplayOptions();
m_CursorShape->SetSelection( galOpts.m_fullscreenCursor ? 1 : 0 );
}
#endif // __APPLE__
// Show Option Draw Lines. We use DisplayPcbTrackFill as Lines draw option
m_OptDisplayLines->SetSelection( m_Parent->m_DisplayOptions.m_DisplayLinesFill ? 1 : 0 );
m_OptDisplayFlashedItems->SetSelection( m_Parent->m_DisplayOptions.m_DisplayFlashedItemsFill ? 1 : 0);
@ -131,8 +132,6 @@ void DIALOG_DISPLAY_OPTIONS::initOptDialog( )
}
m_OptDisplayDCodes->SetValue( m_Parent->IsElementVisible( LAYER_DCODES ) );
m_OptZoomNoCenter->SetValue( m_Parent->GetCanvas()->GetEnableZoomNoCenter() );
m_OptMousewheelPan->SetValue( m_Parent->GetCanvas()->GetEnableMousewheelPan() );
}
@ -140,18 +139,12 @@ void DIALOG_DISPLAY_OPTIONS::initOptDialog( )
void DIALOG_DISPLAY_OPTIONS::OnOKBUttonClick( wxCommandEvent& event )
{
auto displayOptions = (GBR_DISPLAY_OPTIONS*) m_Parent->GetDisplayOptions();
m_Parent->m_DisplayOptions.m_DisplayPolarCood =
(m_PolarDisplay->GetSelection() == 0) ? false : true;
g_UserUnit = (m_BoxUnits->GetSelection() == 0) ? INCHES : MILLIMETRES;
// @todo LEGACY: as above, this should be via the GAL display widget
#ifndef __APPLE__
{
auto& galOpts = m_Parent->GetGalDisplayOptions();
galOpts.m_fullscreenCursor = m_CursorShape->GetSelection();
}
#endif // !__APPLE__
if( m_OptDisplayLines->GetSelection() == 1 )
m_Parent->m_DisplayOptions.m_DisplayLinesFill = true;
else
@ -166,7 +159,6 @@ void DIALOG_DISPLAY_OPTIONS::OnOKBUttonClick( wxCommandEvent& event )
m_Parent->m_DisplayOptions.m_DisplayFlashedItemsFill = false;
}
if( m_OptDisplayPolygons->GetSelection() == 0 )
m_Parent->m_DisplayOptions.m_DisplayPolygonsFill = false;
else
@ -185,6 +177,16 @@ void DIALOG_DISPLAY_OPTIONS::OnOKBUttonClick( wxCommandEvent& event )
m_Parent->GetCanvas()->SetEnableZoomNoCenter( m_OptZoomNoCenter->GetValue() );
m_Parent->GetCanvas()->SetEnableMousewheelPan( m_OptMousewheelPan->GetValue() );
m_galOptsPanel->TransferDataFromWindow();
// Apply changes to the GAL
auto view = m_Parent->GetGalCanvas()->GetView();
auto painter = static_cast<KIGFX::GERBVIEW_PAINTER*>( view->GetPainter() );
auto settings = static_cast<KIGFX::GERBVIEW_RENDER_SETTINGS*>( painter->GetSettings() );
settings->LoadDisplayOptions( displayOptions );
view->RecacheAllItems();
view->MarkTargetDirty( KIGFX::TARGET_NONCACHED );
m_Parent->GetCanvas()->Refresh();
EndModal( 1 );

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version May 6 2016)
// C++ code generated with wxFormBuilder (version Nov 30 2016)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
@ -16,8 +16,7 @@ DIALOG_DISPLAY_OPTIONS_BASE::DIALOG_DISPLAY_OPTIONS_BASE( wxWindow* parent, wxWi
wxBoxSizer* bDialogSizer;
bDialogSizer = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bUpperSizer;
bUpperSizer = new wxBoxSizer( wxHORIZONTAL );
m_UpperSizer = new wxBoxSizer( wxHORIZONTAL );
wxBoxSizer* bLeftSizer;
bLeftSizer = new wxBoxSizer( wxVERTICAL );
@ -34,42 +33,30 @@ DIALOG_DISPLAY_OPTIONS_BASE::DIALOG_DISPLAY_OPTIONS_BASE( wxWindow* parent, wxWi
m_BoxUnits->SetSelection( 0 );
bLeftSizer->Add( m_BoxUnits, 0, wxALL|wxEXPAND, 5 );
wxString m_CursorShapeChoices[] = { _("Small cross"), _("Full screen cursor") };
int m_CursorShapeNChoices = sizeof( m_CursorShapeChoices ) / sizeof( wxString );
m_CursorShape = new wxRadioBox( this, wxID_ANY, _("Cursor"), wxDefaultPosition, wxDefaultSize, m_CursorShapeNChoices, m_CursorShapeChoices, 1, wxRA_SPECIFY_COLS );
m_CursorShape->SetSelection( 1 );
bLeftSizer->Add( m_CursorShape, 0, wxALL|wxEXPAND, 5 );
wxString m_OptDisplayFlashedItemsChoices[] = { _("Sketch"), _("Filled") };
int m_OptDisplayFlashedItemsNChoices = sizeof( m_OptDisplayFlashedItemsChoices ) / sizeof( wxString );
m_OptDisplayFlashedItems = new wxRadioBox( this, wxID_ANY, _("Flashed items"), wxDefaultPosition, wxDefaultSize, m_OptDisplayFlashedItemsNChoices, m_OptDisplayFlashedItemsChoices, 1, wxRA_SPECIFY_COLS );
m_OptDisplayFlashedItems->SetSelection( 1 );
bLeftSizer->Add( m_OptDisplayFlashedItems, 0, wxALL|wxEXPAND, 5 );
wxString m_OptDisplayLinesChoices[] = { _("Sketch"), _("Filled") };
int m_OptDisplayLinesNChoices = sizeof( m_OptDisplayLinesChoices ) / sizeof( wxString );
m_OptDisplayLines = new wxRadioBox( this, wxID_ANY, _("Lines"), wxDefaultPosition, wxDefaultSize, m_OptDisplayLinesNChoices, m_OptDisplayLinesChoices, 1, wxRA_SPECIFY_COLS );
m_OptDisplayLines->SetSelection( 1 );
bLeftSizer->Add( m_OptDisplayLines, 0, wxALL|wxEXPAND, 5 );
wxString m_OptDisplayPolygonsChoices[] = { _("Sketch"), _("Filled") };
int m_OptDisplayPolygonsNChoices = sizeof( m_OptDisplayPolygonsChoices ) / sizeof( wxString );
m_OptDisplayPolygons = new wxRadioBox( this, wxID_ANY, _("Polygons"), wxDefaultPosition, wxDefaultSize, m_OptDisplayPolygonsNChoices, m_OptDisplayPolygonsChoices, 1, wxRA_SPECIFY_COLS );
m_OptDisplayPolygons->SetSelection( 1 );
bLeftSizer->Add( m_OptDisplayPolygons, 0, wxALL|wxEXPAND, 5 );
m_OptDisplayDCodes = new wxCheckBox( this, wxID_ANY, _("Show D codes"), wxDefaultPosition, wxDefaultSize, 0 );
m_OptDisplayDCodes->SetValue(true);
bLeftSizer->Add( m_OptDisplayDCodes, 0, wxALL, 5 );
bUpperSizer->Add( bLeftSizer, 1, wxALL|wxEXPAND, 5 );
wxBoxSizer* bMiddleSizer;
bMiddleSizer = new wxBoxSizer( wxVERTICAL );
wxString m_OptDisplayLinesChoices[] = { _("Sketch"), _("Filled") };
int m_OptDisplayLinesNChoices = sizeof( m_OptDisplayLinesChoices ) / sizeof( wxString );
m_OptDisplayLines = new wxRadioBox( this, wxID_ANY, _("Lines"), wxDefaultPosition, wxDefaultSize, m_OptDisplayLinesNChoices, m_OptDisplayLinesChoices, 1, wxRA_SPECIFY_COLS );
m_OptDisplayLines->SetSelection( 1 );
bMiddleSizer->Add( m_OptDisplayLines, 0, wxALL|wxEXPAND, 5 );
wxString m_OptDisplayFlashedItemsChoices[] = { _("Sketch"), _("Filled") };
int m_OptDisplayFlashedItemsNChoices = sizeof( m_OptDisplayFlashedItemsChoices ) / sizeof( wxString );
m_OptDisplayFlashedItems = new wxRadioBox( this, wxID_ANY, _("Flashed items"), wxDefaultPosition, wxDefaultSize, m_OptDisplayFlashedItemsNChoices, m_OptDisplayFlashedItemsChoices, 1, wxRA_SPECIFY_COLS );
m_OptDisplayFlashedItems->SetSelection( 1 );
bMiddleSizer->Add( m_OptDisplayFlashedItems, 0, wxALL|wxEXPAND, 5 );
wxString m_OptDisplayPolygonsChoices[] = { _("Sketch"), _("Filled") };
int m_OptDisplayPolygonsNChoices = sizeof( m_OptDisplayPolygonsChoices ) / sizeof( wxString );
m_OptDisplayPolygons = new wxRadioBox( this, wxID_ANY, _("Polygons"), wxDefaultPosition, wxDefaultSize, m_OptDisplayPolygonsNChoices, m_OptDisplayPolygonsChoices, 1, wxRA_SPECIFY_COLS );
m_OptDisplayPolygons->SetSelection( 1 );
bMiddleSizer->Add( m_OptDisplayPolygons, 0, wxALL|wxEXPAND, 5 );
bUpperSizer->Add( bMiddleSizer, 1, wxALL|wxEXPAND, 5 );
m_UpperSizer->Add( bLeftSizer, 1, wxALL|wxEXPAND, 5 );
wxBoxSizer* bRightSizer;
bRightSizer = new wxBoxSizer( wxVERTICAL );
@ -97,10 +84,10 @@ DIALOG_DISPLAY_OPTIONS_BASE::DIALOG_DISPLAY_OPTIONS_BASE( wxWindow* parent, wxWi
bRightSizer->Add( bLeftBottomSizer, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
bUpperSizer->Add( bRightSizer, 2, wxALL|wxEXPAND, 5 );
m_UpperSizer->Add( bRightSizer, 2, wxALL|wxEXPAND, 5 );
bDialogSizer->Add( bUpperSizer, 1, wxEXPAND, 5 );
bDialogSizer->Add( m_UpperSizer, 1, wxEXPAND, 5 );
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bDialogSizer->Add( m_staticline1, 0, wxEXPAND|wxLEFT|wxRIGHT, 5 );

View File

@ -99,9 +99,9 @@
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bUpperSizer</property>
<property name="name">m_UpperSizer</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<property name="permission">protected</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
@ -309,7 +309,7 @@
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="choices">&quot;Small cross&quot; &quot;Full screen cursor&quot;</property>
<property name="choices">&quot;Sketch&quot; &quot;Filled&quot;</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
@ -324,7 +324,7 @@
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Cursor</property>
<property name="label">Flashed items</property>
<property name="majorDimension">1</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
@ -333,7 +333,7 @@
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_CursorShape</property>
<property name="name">m_OptDisplayFlashedItems</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
@ -381,105 +381,6 @@
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">1</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Show D codes</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_OptDisplayDCodes</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnCheckBox"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bMiddleSizer</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
@ -570,96 +471,6 @@
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxRadioBox" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="choices">&quot;Sketch&quot; &quot;Filled&quot;</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Flashed items</property>
<property name="majorDimension">1</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_OptDisplayFlashedItems</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="selection">1</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxRA_SPECIFY_COLS</property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRadioBox"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
@ -750,6 +561,94 @@
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">1</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Show D codes</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_OptDisplayDCodes</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnCheckBox"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="1">

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version May 6 2016)
// C++ code generated with wxFormBuilder (version Nov 30 2016)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
@ -38,13 +38,13 @@ class DIALOG_DISPLAY_OPTIONS_BASE : public DIALOG_SHIM
private:
protected:
wxBoxSizer* m_UpperSizer;
wxRadioBox* m_PolarDisplay;
wxRadioBox* m_BoxUnits;
wxRadioBox* m_CursorShape;
wxCheckBox* m_OptDisplayDCodes;
wxRadioBox* m_OptDisplayLines;
wxRadioBox* m_OptDisplayFlashedItems;
wxRadioBox* m_OptDisplayLines;
wxRadioBox* m_OptDisplayPolygons;
wxCheckBox* m_OptDisplayDCodes;
wxRadioBox* m_ShowPageLimits;
wxCheckBox* m_OptZoomNoCenter;
wxCheckBox* m_OptMousewheelPan;

View File

@ -135,7 +135,16 @@ void GERBVIEW_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg )
if( IsShown() )
{
m_overlay.Reset();
wxDCOverlay overlaydc( m_overlay, (wxWindowDC*)DC );
// On macOS, the call to create overlaydc fails for some reason due to
// the DC having zero size initially.
wxCoord w = 0, h = 0;
( (wxWindowDC*)DC )->GetSize( &w, &h );
if( w == 0 || h == 0)
{
w = h = 1;
}
wxDCOverlay overlaydc( m_overlay, (wxWindowDC*)DC, 0, 0, 1, 1 );
overlaydc.Clear();
}
#endif

View File

@ -43,6 +43,10 @@
#include <class_gerbview_layer_widget.h>
#include <dialog_show_page_borders.h>
#include <tool/tool_manager.h>
#include <gerbview_painter.h>
#include <view/view.h>
// Event table:
@ -83,6 +87,12 @@ BEGIN_EVENT_TABLE( GERBVIEW_FRAME, EDA_DRAW_FRAME )
EVT_MENU( ID_MENU_GERBVIEW_SHOW_HIDE_LAYERS_MANAGER_DIALOG,
GERBVIEW_FRAME::OnSelectOptionToolbar )
EVT_MENU( wxID_PREFERENCES, GERBVIEW_FRAME::InstallGerberOptionsDialog )
EVT_UPDATE_UI( ID_MENU_CANVAS_LEGACY, GERBVIEW_FRAME::OnUpdateSwitchCanvas )
EVT_UPDATE_UI( ID_MENU_CANVAS_CAIRO, GERBVIEW_FRAME::OnUpdateSwitchCanvas )
EVT_UPDATE_UI( ID_MENU_CANVAS_OPENGL, GERBVIEW_FRAME::OnUpdateSwitchCanvas )
EVT_MENU( ID_MENU_CANVAS_LEGACY, GERBVIEW_FRAME::SwitchCanvas )
EVT_MENU( ID_MENU_CANVAS_CAIRO, GERBVIEW_FRAME::SwitchCanvas )
EVT_MENU( ID_MENU_CANVAS_OPENGL, GERBVIEW_FRAME::SwitchCanvas )
// menu Postprocess
EVT_MENU( ID_GERBVIEW_SHOW_LIST_DCODES, GERBVIEW_FRAME::Process_Special_Functions )
@ -115,6 +125,7 @@ BEGIN_EVENT_TABLE( GERBVIEW_FRAME, EDA_DRAW_FRAME )
// Option toolbar
//EVT_TOOL( ID_NO_TOOL_SELECTED, GERBVIEW_FRAME::Process_Special_Functions ) // mentioned below
EVT_TOOL( ID_ZOOM_SELECTION, GERBVIEW_FRAME::Process_Special_Functions )
EVT_TOOL( ID_TB_MEASUREMENT_TOOL, GERBVIEW_FRAME::Process_Special_Functions )
EVT_TOOL( ID_TB_OPTIONS_SHOW_POLAR_COORD, GERBVIEW_FRAME::OnSelectOptionToolbar )
EVT_TOOL( ID_TB_OPTIONS_SHOW_POLYGONS_SKETCH, GERBVIEW_FRAME::OnSelectOptionToolbar )
EVT_TOOL( ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH, GERBVIEW_FRAME::OnSelectOptionToolbar )
@ -125,11 +136,13 @@ BEGIN_EVENT_TABLE( GERBVIEW_FRAME, EDA_DRAW_FRAME )
EVT_TOOL( ID_TB_OPTIONS_SHOW_NEGATIVE_ITEMS, GERBVIEW_FRAME::OnSelectOptionToolbar )
EVT_TOOL_RANGE( ID_TB_OPTIONS_SHOW_GBR_MODE_0, ID_TB_OPTIONS_SHOW_GBR_MODE_2,
GERBVIEW_FRAME::OnSelectDisplayMode )
EVT_TOOL( ID_TB_OPTIONS_DIFF_MODE, GERBVIEW_FRAME::OnSelectOptionToolbar )
EVT_TOOL( ID_TB_OPTIONS_HIGH_CONTRAST_MODE, GERBVIEW_FRAME::OnSelectOptionToolbar )
// Auxiliary horizontal toolbar
EVT_CHOICE( ID_GBR_AUX_TOOLBAR_PCB_CMP_CHOICE, GERBVIEW_FRAME::Process_Special_Functions )
EVT_CHOICE( ID_GBR_AUX_TOOLBAR_PCB_NET_CHOICE, GERBVIEW_FRAME::Process_Special_Functions )
EVT_CHOICE( ID_GBR_AUX_TOOLBAR_PCB_APERATTRIBUTES_CHOICE, GERBVIEW_FRAME::Process_Special_Functions )
EVT_CHOICE( ID_GBR_AUX_TOOLBAR_PCB_CMP_CHOICE, GERBVIEW_FRAME::OnSelectHighlightChoice )
EVT_CHOICE( ID_GBR_AUX_TOOLBAR_PCB_NET_CHOICE, GERBVIEW_FRAME::OnSelectHighlightChoice )
EVT_CHOICE( ID_GBR_AUX_TOOLBAR_PCB_APERATTRIBUTES_CHOICE, GERBVIEW_FRAME::OnSelectHighlightChoice )
// Right click context menu
EVT_MENU( ID_HIGHLIGHT_CMP_ITEMS, GERBVIEW_FRAME::Process_Special_Functions )
@ -139,6 +152,7 @@ BEGIN_EVENT_TABLE( GERBVIEW_FRAME, EDA_DRAW_FRAME )
EVT_UPDATE_UI( ID_NO_TOOL_SELECTED, GERBVIEW_FRAME::OnUpdateSelectTool )
EVT_UPDATE_UI( ID_ZOOM_SELECTION, GERBVIEW_FRAME::OnUpdateSelectTool )
EVT_UPDATE_UI( ID_TB_MEASUREMENT_TOOL, GERBVIEW_FRAME::OnUpdateSelectTool )
EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_POLAR_COORD, GERBVIEW_FRAME::OnUpdateCoordType )
EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH,
GERBVIEW_FRAME::OnUpdateFlashedItemsDrawMode )
@ -223,6 +237,10 @@ void GERBVIEW_FRAME::Process_Special_Functions( wxCommandEvent& event )
SetNoToolSelected();
break;
case ID_TB_MEASUREMENT_TOOL:
SetToolID( id, wxCURSOR_DEFAULT, _( "Unsupported tool in this canvas" ) );
break;
case ID_POPUP_CLOSE_CURRENT_TOOL:
SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
break;
@ -246,12 +264,6 @@ void GERBVIEW_FRAME::Process_Special_Functions( wxCommandEvent& event )
HandleBlockEnd( &dc );
break;
case ID_GBR_AUX_TOOLBAR_PCB_CMP_CHOICE:
case ID_GBR_AUX_TOOLBAR_PCB_NET_CHOICE:
case ID_GBR_AUX_TOOLBAR_PCB_APERATTRIBUTES_CHOICE:
m_canvas->Refresh();
break;
case ID_HIGHLIGHT_CMP_ITEMS:
if( m_SelComponentBox->SetStringSelection( currItem->GetNetAttributes().m_Cmpref ) )
m_canvas->Refresh();
@ -275,8 +287,8 @@ void GERBVIEW_FRAME::Process_Special_Functions( wxCommandEvent& event )
m_SelNetnameBox->SetSelection( 0 );
m_SelAperAttributesBox->SetSelection( 0 );
if( GetGbrImage( getActiveLayer() ) )
GetGbrImage( getActiveLayer() )->m_Selected_Tool = 0;
if( GetGbrImage( GetActiveLayer() ) )
GetGbrImage( GetActiveLayer() )->m_Selected_Tool = 0;
m_canvas->Refresh();
break;
@ -288,9 +300,40 @@ void GERBVIEW_FRAME::Process_Special_Functions( wxCommandEvent& event )
}
// Handles the changing of the highlighted component/net/attribute
void GERBVIEW_FRAME::OnSelectHighlightChoice( wxCommandEvent& event )
{
if( IsGalCanvasActive() )
{
auto settings = static_cast<KIGFX::GERBVIEW_PAINTER*>( GetGalCanvas()->GetView()->GetPainter() )->GetSettings();
switch( event.GetId() )
{
case ID_GBR_AUX_TOOLBAR_PCB_CMP_CHOICE:
settings->m_componentHighlightString = m_SelComponentBox->GetStringSelection();
break;
case ID_GBR_AUX_TOOLBAR_PCB_NET_CHOICE:
settings->m_netHighlightString = m_SelNetnameBox->GetStringSelection();
break;
case ID_GBR_AUX_TOOLBAR_PCB_APERATTRIBUTES_CHOICE:
settings->m_attributeHighlightString = m_SelAperAttributesBox->GetStringSelection();
break;
}
GetGalCanvas()->GetView()->RecacheAllItems();
GetGalCanvas()->Refresh();
}
else
m_canvas->Refresh();
}
void GERBVIEW_FRAME::OnSelectActiveDCode( wxCommandEvent& event )
{
GERBER_FILE_IMAGE* gerber_image = GetGbrImage( getActiveLayer() );
GERBER_FILE_IMAGE* gerber_image = GetGbrImage( GetActiveLayer() );
if( gerber_image )
{
@ -307,11 +350,11 @@ void GERBVIEW_FRAME::OnSelectActiveDCode( wxCommandEvent& event )
void GERBVIEW_FRAME::OnSelectActiveLayer( wxCommandEvent& event )
{
int layer = getActiveLayer();
int layer = GetActiveLayer();
setActiveLayer( event.GetSelection() );
SetActiveLayer( event.GetSelection() );
if( layer != getActiveLayer() )
if( layer != GetActiveLayer() )
{
if( m_LayersManager->OnLayerSelected() )
m_canvas->Refresh();
@ -321,7 +364,7 @@ void GERBVIEW_FRAME::OnSelectActiveLayer( wxCommandEvent& event )
void GERBVIEW_FRAME::OnShowGerberSourceFile( wxCommandEvent& event )
{
int layer = getActiveLayer();
int layer = GetActiveLayer();
GERBER_FILE_IMAGE* gerber_layer = GetGbrImage( layer );
if( gerber_layer )
@ -427,16 +470,19 @@ void GERBVIEW_FRAME::OnSelectOptionToolbar( wxCommandEvent& event )
case ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH:
m_DisplayOptions.m_DisplayFlashedItemsFill = not state;
applyDisplaySettingsToGAL();
m_canvas->Refresh( true );
break;
case ID_TB_OPTIONS_SHOW_LINES_SKETCH:
m_DisplayOptions.m_DisplayLinesFill = not state;
applyDisplaySettingsToGAL();
m_canvas->Refresh( true );
break;
case ID_TB_OPTIONS_SHOW_POLYGONS_SKETCH:
m_DisplayOptions.m_DisplayPolygonsFill = not state;
applyDisplaySettingsToGAL();
m_canvas->Refresh( true );
break;
@ -450,6 +496,18 @@ void GERBVIEW_FRAME::OnSelectOptionToolbar( wxCommandEvent& event )
m_canvas->Refresh( true );
break;
case ID_TB_OPTIONS_DIFF_MODE:
m_DisplayOptions.m_DiffMode = state;
applyDisplaySettingsToGAL();
m_canvas->Refresh( true );
break;
case ID_TB_OPTIONS_HIGH_CONTRAST_MODE:
m_DisplayOptions.m_HighContrastMode = state;
applyDisplaySettingsToGAL();
m_canvas->Refresh( true );
break;
case ID_TB_OPTIONS_SHOW_LAYERS_MANAGER_VERTICAL_TOOLBAR:
// show/hide auxiliary Vertical layers and visibility manager toolbar
@ -461,6 +519,11 @@ void GERBVIEW_FRAME::OnSelectOptionToolbar( wxCommandEvent& event )
_("Hide &Layers Manager" ) : _("Show &Layers Manager" ));
break;
// collect GAL-only tools here:
case ID_TB_MEASUREMENT_TOOL:
SetToolID( id, wxCURSOR_DEFAULT, _( "Unsupported tool in this canvas" ) );
break;
default:
wxMessageBox( wxT( "GERBVIEW_FRAME::OnSelectOptionToolbar error" ) );
break;
@ -472,3 +535,62 @@ void GERBVIEW_FRAME::OnUpdateSelectTool( wxUpdateUIEvent& aEvent )
{
aEvent.Check( GetToolId() == aEvent.GetId() );
}
void GERBVIEW_FRAME::SwitchCanvas( wxCommandEvent& aEvent )
{
bool use_gal = false;
EDA_DRAW_PANEL_GAL::GAL_TYPE canvasType = EDA_DRAW_PANEL_GAL::GAL_TYPE_NONE;
switch( aEvent.GetId() )
{
case ID_MENU_CANVAS_LEGACY:
break;
case ID_MENU_CANVAS_CAIRO:
use_gal = GetGalCanvas()->SwitchBackend( EDA_DRAW_PANEL_GAL::GAL_TYPE_CAIRO );
if( use_gal )
canvasType = EDA_DRAW_PANEL_GAL::GAL_TYPE_CAIRO;
break;
case ID_MENU_CANVAS_OPENGL:
use_gal = GetGalCanvas()->SwitchBackend( EDA_DRAW_PANEL_GAL::GAL_TYPE_OPENGL );
if( use_gal )
canvasType = EDA_DRAW_PANEL_GAL::GAL_TYPE_OPENGL;
break;
}
SaveCanvasTypeSetting( canvasType );
UseGalCanvas( use_gal );
wxUpdateUIEvent e;
OnUpdateSwitchCanvas( e );
}
void GERBVIEW_FRAME::OnUpdateSwitchCanvas( wxUpdateUIEvent& aEvent )
{
wxMenuBar* menuBar = GetMenuBar();
EDA_DRAW_PANEL_GAL* gal_canvas = GetGalCanvas();
EDA_DRAW_PANEL_GAL::GAL_TYPE canvasType = EDA_DRAW_PANEL_GAL::GAL_TYPE_NONE;
if( IsGalCanvasActive() && gal_canvas )
canvasType = gal_canvas->GetBackend();
struct { int menuId; int galType; } menuList[] =
{
{ ID_MENU_CANVAS_LEGACY, EDA_DRAW_PANEL_GAL::GAL_TYPE_NONE },
{ ID_MENU_CANVAS_OPENGL, EDA_DRAW_PANEL_GAL::GAL_TYPE_OPENGL },
{ ID_MENU_CANVAS_CAIRO, EDA_DRAW_PANEL_GAL::GAL_TYPE_CAIRO },
};
for( auto ii: menuList )
{
wxMenuItem* item = menuBar->FindItem( ii.menuId );
if( ii.galType == canvasType )
{
item->Check( true );
}
}
}

View File

@ -73,6 +73,7 @@
#include <class_excellon.h>
#include <kicad_string.h>
#include <class_X2_gerber_attributes.h>
#include <view/view.h>
#include <cmath>
@ -160,7 +161,7 @@ static EXCELLON_CMD excellon_G_CmdList[] =
bool GERBVIEW_FRAME::Read_EXCELLON_File( const wxString& aFullFileName )
{
wxString msg;
int layerId = getActiveLayer(); // current layer used in GerbView
int layerId = GetActiveLayer(); // current layer used in GerbView
GERBER_FILE_IMAGE_LIST* images = GetGerberLayout()->GetImagesList();
EXCELLON_IMAGE* drill_Layer = (EXCELLON_IMAGE*) images->GetGbrImage( layerId );
@ -193,6 +194,21 @@ bool GERBVIEW_FRAME::Read_EXCELLON_File( const wxString& aFullFileName )
dlg.ListSet( drill_Layer->GetMessages() );
dlg.ShowModal();
}
// TODO(JE) Is this the best place to add items to the view?
if( success )
{
EDA_DRAW_PANEL_GAL* canvas = GetGalCanvas();
if( canvas )
{
KIGFX::VIEW* view = canvas->GetView();
for( GERBER_DRAW_ITEM* item = drill_Layer->GetItemsList(); item; item = item->Next() )
{
view->Add( (KIGFX::VIEW_ITEM*) item );
}
}
}
return success;
}
@ -494,7 +510,7 @@ bool EXCELLON_IMAGE::readToolInformation( char*& aText )
// Initialize Dcode to handle this Tool
// Remember: dcodes are >= FIRST_DCODE
D_CODE* dcode = GetDCODE( iprm + FIRST_DCODE );
D_CODE* dcode = GetDCODEOrCreate( iprm + FIRST_DCODE );
if( dcode == NULL )
return false;
@ -532,7 +548,7 @@ bool EXCELLON_IMAGE::Execute_Drill_Command( char*& text )
Execute_EXCELLON_G_Command( text );
break;
case 0: // E.O.L: execute command
tool = GetDCODE( m_Current_Tool, false );
tool = GetDCODE( m_Current_Tool );
if( !tool )
{
@ -593,13 +609,13 @@ bool EXCELLON_IMAGE::Select_Tool( char*& text )
dcode_id = TOOLS_MAX_COUNT - 1;
m_Current_Tool = dcode_id;
D_CODE* currDcode = GetDCODE( dcode_id , false );
D_CODE* currDcode = GetDCODEOrCreate( dcode_id, true );
if( currDcode == NULL && tool_id > 0 ) // if the definition is embedded, enter it
{
text = startline; // text starts at the beginning of the command
readToolInformation( text );
currDcode = GetDCODE( dcode_id , false );
currDcode = GetDCODE( dcode_id );
}
if( currDcode )

View File

@ -222,7 +222,7 @@ bool GERBVIEW_FRAME::LoadGerberFiles( const wxString& aFullFileName )
// Read gerber files: each file is loaded on a new GerbView layer
bool success = true;
int layer = getActiveLayer();
int layer = GetActiveLayer();
// Manage errors when loading files
wxString msg;
@ -237,7 +237,7 @@ bool GERBVIEW_FRAME::LoadGerberFiles( const wxString& aFullFileName )
m_lastFileName = filename.GetFullPath();
setActiveLayer( layer, false );
SetActiveLayer( layer, false );
if( Read_GERBER_File( filename.GetFullPath() ) )
{
@ -263,7 +263,7 @@ bool GERBVIEW_FRAME::LoadGerberFiles( const wxString& aFullFileName )
break;
}
setActiveLayer( layer, false );
SetActiveLayer( layer, false );
}
}
@ -278,7 +278,7 @@ bool GERBVIEW_FRAME::LoadGerberFiles( const wxString& aFullFileName )
// Synchronize layers tools with actual active layer:
ReFillLayerWidget();
setActiveLayer( getActiveLayer() );
SetActiveLayer( GetActiveLayer() );
m_LayersManager->UpdateLayerIcons();
syncLayerBox();
return success;
@ -325,7 +325,7 @@ bool GERBVIEW_FRAME::LoadExcellonFiles( const wxString& aFullFileName )
// Read Excellon drill files: each file is loaded on a new GerbView layer
bool success = true;
int layer = getActiveLayer();
int layer = GetActiveLayer();
// Manage errors when loading files
wxString msg;
@ -340,7 +340,7 @@ bool GERBVIEW_FRAME::LoadExcellonFiles( const wxString& aFullFileName )
m_lastFileName = filename.GetFullPath();
setActiveLayer( layer, false );
SetActiveLayer( layer, false );
if( Read_EXCELLON_File( filename.GetFullPath() ) )
{
@ -367,7 +367,7 @@ bool GERBVIEW_FRAME::LoadExcellonFiles( const wxString& aFullFileName )
break;
}
setActiveLayer( layer, false );
SetActiveLayer( layer, false );
}
}
@ -382,7 +382,7 @@ bool GERBVIEW_FRAME::LoadExcellonFiles( const wxString& aFullFileName )
// Synchronize layers tools with actual active layer:
ReFillLayerWidget();
setActiveLayer( getActiveLayer() );
SetActiveLayer( GetActiveLayer() );
m_LayersManager->UpdateLayerIcons();
syncLayerBox();
@ -454,7 +454,7 @@ bool GERBVIEW_FRAME::unarchiveFiles( const wxString& aFullFileName, REPORTER* aR
continue;
}
int layer = getActiveLayer();
int layer = GetActiveLayer();
if( layer == NO_AVAILABLE_LAYERS )
{
@ -531,7 +531,7 @@ bool GERBVIEW_FRAME::unarchiveFiles( const wxString& aFullFileName, REPORTER* aR
gerber_image->m_FileName = fname;
layer = getNextAvailableLayer( layer );
setActiveLayer( layer, false );
SetActiveLayer( layer, false );
}
}
@ -584,7 +584,7 @@ bool GERBVIEW_FRAME::LoadZipArchiveFile( const wxString& aFullFileName )
// Synchronize layers tools with actual active layer:
ReFillLayerWidget();
setActiveLayer( getActiveLayer() );
SetActiveLayer( GetActiveLayer() );
m_LayersManager->UpdateLayerIcons();
syncLayerBox();

View File

@ -92,6 +92,11 @@ PARAM_CFG_ARRAY& GERBVIEW_FRAME::GetConfigurationSettings()
&g_ColorsSettings.m_LayersColors[
LAYER_NEGATIVE_OBJECTS],
DARKGRAY ) );
m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true,
wxT( "GridColorEx" ),
&g_ColorsSettings.m_LayersColors[
LAYER_GERBVIEW_GRID],
DARKGRAY ) );
m_configSettings.push_back( new PARAM_CFG_BOOL( true,
wxT( "DisplayPolarCoordinates" ),
&m_DisplayOptions.m_DisplayPolarCood,
@ -129,7 +134,7 @@ PARAM_CFG_ARRAY& GERBVIEW_FRAME::GetConfigurationSettings()
for( unsigned i = 0; i < DIM(keys); ++i )
{
COLOR4D* prm = &g_ColorsSettings.m_LayersColors[i];
COLOR4D* prm = &g_ColorsSettings.m_LayersColors[ GERBER_DRAW_LAYER( i ) ];
PARAM_CFG_SETCOLOR* prm_entry =
new PARAM_CFG_SETCOLOR( true, keys[i], prm, color_default[i] );

View File

@ -49,6 +49,14 @@
#include <class_DCodeSelectionbox.h>
#include <class_gerbview_layer_widget.h>
#include <gerbview_draw_panel_gal.h>
#include <gal/graphics_abstraction_layer.h>
#include <tool/tool_manager.h>
#include <tool/tool_dispatcher.h>
#include <tools/gerbview_actions.h>
#include <view/view.h>
#include <gerbview_painter.h>
// Config keywords
static const wxString cfgShowPageSizeOption( wxT( "PageSizeOpt" ) );
@ -56,6 +64,8 @@ static const wxString cfgShowDCodes( wxT( "ShowDCodesOpt" ) );
static const wxString cfgShowNegativeObjects( wxT( "ShowNegativeObjectsOpt" ) );
static const wxString cfgShowBorderAndTitleBlock( wxT( "ShowBorderAndTitleBlock" ) );
const wxChar GERBVIEW_FRAME::CANVAS_TYPE_KEY[] = wxT( "canvas_type" );
// Colors for layers and items
COLORS_DESIGN_SETTINGS g_ColorsSettings( FRAME_GERBER );
@ -87,6 +97,16 @@ GERBVIEW_FRAME::GERBVIEW_FRAME( KIWAY* aKiway, wxWindow* aParent ):
m_zipFileHistory.SetBaseId( ID_GERBVIEW_ZIP_FILE1 );
m_jobFileHistory.SetBaseId( ID_GERBVIEW_JOB_FILE1 );
EDA_DRAW_PANEL_GAL* galCanvas = new GERBVIEW_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ),
m_FrameSize,
GetGalDisplayOptions(),
EDA_DRAW_PANEL_GAL::GAL_TYPE_NONE );
SetGalCanvas( galCanvas );
// GerbView requires draw priority for rendering negative objects
galCanvas->GetView()->UseDrawPriority( true );
if( m_canvas )
m_canvas->SetEnableBlockCommands( true );
@ -174,22 +194,59 @@ GERBVIEW_FRAME::GERBVIEW_FRAME( KIWAY* aKiway, wxWindow* aParent ):
m_auimgr.AddPane( m_canvas,
wxAuiPaneInfo().Name( wxT( "DrawFrame" ) ).CentrePane() );
if( GetGalCanvas() )
m_auimgr.AddPane( (wxWindow*) GetGalCanvas(),
wxAuiPaneInfo().Name( wxT( "DrawFrameGal" ) ).CentrePane().Hide() );
if( m_messagePanel )
m_auimgr.AddPane( m_messagePanel,
wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom().Layer( 10 ) );
ReFillLayerWidget(); // this is near end because contents establish size
m_LayersManager->ReFillRender(); // Update colors in Render after the config is read
m_auimgr.Update();
setActiveLayer( 0, true );
setupTools();
SetActiveLayer( 0, true );
Zoom_Automatique( false ); // Gives a default zoom value
UpdateTitleAndInfo();
EDA_DRAW_PANEL_GAL::GAL_TYPE canvasType = LoadCanvasTypeSetting();
if( canvasType != EDA_DRAW_PANEL_GAL::GAL_TYPE_NONE )
{
if( GetGalCanvas()->SwitchBackend( canvasType ) )
UseGalCanvas( true );
wxUpdateUIEvent e;
OnUpdateSwitchCanvas( e );
}
else
{
forceColorsToLegacy();
m_canvas->Refresh();
}
// Enable the axes to match legacy draw style
auto& galOptions = GetGalDisplayOptions();
galOptions.m_axesEnabled = true;
galOptions.NotifyChanged();
m_LayersManager->ReFill();
m_LayersManager->ReFillRender(); // Update colors in Render after the config is read
}
GERBVIEW_FRAME::~GERBVIEW_FRAME()
{
if( m_toolManager )
m_toolManager->DeactivateTool();
if( auto canvas = GetGalCanvas() )
{
canvas->GetView()->Clear();
}
GetGerberLayout()->GetImagesList()->DeleteAllImages();
}
@ -228,7 +285,7 @@ bool GERBVIEW_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
for( unsigned i=0; i<limit; ++i, ++layer )
{
setActiveLayer( layer );
SetActiveLayer( layer );
// Try to guess the type of file by its ext
// if it is .drl (Kicad files), it is a drill file
@ -400,10 +457,25 @@ void GERBVIEW_FRAME::SetElementVisibility( GERBVIEW_LAYER_ID aItemIdVisible,
wxLogDebug( wxT( "GERBVIEW_FRAME::SetElementVisibility(): bad arg %d" ), aItemIdVisible );
}
applyDisplaySettingsToGAL();
m_LayersManager->SetRenderState( aItemIdVisible, aNewState );
}
void GERBVIEW_FRAME::applyDisplaySettingsToGAL()
{
auto view = GetGalCanvas()->GetView();
auto painter = static_cast<KIGFX::GERBVIEW_PAINTER*>( view->GetPainter() );
auto settings = static_cast<KIGFX::GERBVIEW_RENDER_SETTINGS*>( painter->GetSettings() );
settings->LoadDisplayOptions( &m_DisplayOptions );
settings->ImportLegacyColors( m_colorsSettings );
view->RecacheAllItems();
view->MarkTargetDirty( KIGFX::TARGET_NONCACHED );
}
int GERBVIEW_FRAME::getNextAvailableLayer( int aLayer ) const
{
int layer = aLayer;
@ -427,7 +499,7 @@ int GERBVIEW_FRAME::getNextAvailableLayer( int aLayer ) const
void GERBVIEW_FRAME::syncLayerWidget()
{
m_LayersManager->SelectLayer( getActiveLayer() );
m_LayersManager->SelectLayer( GetActiveLayer() );
UpdateTitleAndInfo();
}
@ -437,10 +509,10 @@ void GERBVIEW_FRAME::syncLayerBox( bool aRebuildLayerBox )
if( aRebuildLayerBox )
m_SelLayerBox->Resync();
m_SelLayerBox->SetSelection( getActiveLayer() );
m_SelLayerBox->SetSelection( GetActiveLayer() );
int dcodeSelected = -1;
GERBER_FILE_IMAGE* gerber = GetGbrImage( getActiveLayer() );
GERBER_FILE_IMAGE* gerber = GetGbrImage( GetActiveLayer() );
if( gerber )
dcodeSelected = gerber->m_Selected_Tool;
@ -462,7 +534,7 @@ void GERBVIEW_FRAME::Liste_D_Codes()
wxString Line;
wxArrayString list;
double scale = g_UserUnit == INCHES ? IU_PER_MILS * 1000 : IU_PER_MM;
int curr_layer = getActiveLayer();
int curr_layer = GetActiveLayer();
for( int layer = 0; layer < (int)ImagesMaxCount(); ++layer )
{
@ -485,7 +557,7 @@ void GERBVIEW_FRAME::Liste_D_Codes()
for( ii = 0, jj = 1; ii < TOOLS_MAX_COUNT; ii++ )
{
D_CODE* pt_D_code = gerber->GetDCODE( ii + FIRST_DCODE, false );
D_CODE* pt_D_code = gerber->GetDCODE( ii + FIRST_DCODE );
if( pt_D_code == NULL )
continue;
@ -522,7 +594,7 @@ void GERBVIEW_FRAME::Liste_D_Codes()
void GERBVIEW_FRAME::UpdateTitleAndInfo()
{
GERBER_FILE_IMAGE* gerber = GetGbrImage( getActiveLayer() );
GERBER_FILE_IMAGE* gerber = GetGbrImage( GetActiveLayer() );
// Display the gerber filename
if( gerber == NULL )
@ -532,7 +604,7 @@ void GERBVIEW_FRAME::UpdateTitleAndInfo()
SetStatusText( wxEmptyString, 0 );
wxString info;
info.Printf( _( "Drawing layer %d not in use" ), getActiveLayer() + 1 );
info.Printf( _( "Drawing layer %d not in use" ), GetActiveLayer() + 1 );
m_TextInfo->SetValue( info );
if( EnsureTextCtrlWidth( m_TextInfo, &info ) ) // Resized
@ -611,14 +683,29 @@ long GERBVIEW_FRAME::GetVisibleLayers() const
void GERBVIEW_FRAME::SetVisibleLayers( long aLayerMask )
{
// GetGerberLayout()->SetVisibleLayers( aLayerMask );
if( auto canvas = GetGalCanvas() )
{
// NOTE: This assumes max 32 drawlayers!
for( int i = 0; i < GERBER_DRAWLAYERS_COUNT; i++ )
{
bool v = ( aLayerMask & ( 1 << i ) );
int layer = GERBER_DRAW_LAYER( i );
canvas->GetView()->SetLayerVisible( layer, v );
canvas->GetView()->SetLayerVisible( GERBER_DCODE_LAYER( layer ), v );
}
}
}
bool GERBVIEW_FRAME::IsLayerVisible( int aLayer ) const
{
if( ! m_DisplayOptions.m_IsPrinting )
{
if( IsGalCanvasActive() )
aLayer = GERBER_DRAW_LAYER( aLayer );
return m_LayersManager->IsLayerVisible( aLayer );
}
else
return GetGerberLayout()->IsLayerPrintable( aLayer );
}
@ -666,6 +753,8 @@ void GERBVIEW_FRAME::SetVisibleElementColor( GERBVIEW_LAYER_ID aItemIdVisible,
break;
case LAYER_GERBVIEW_GRID:
// Ensure grid always has low alpha
aColor.a = 0.8;
SetGridColor( aColor );
m_colorsSettings->SetItemColor( aItemIdVisible, aColor );
break;
@ -694,21 +783,35 @@ COLOR4D GERBVIEW_FRAME::GetLayerColor( int aLayer ) const
void GERBVIEW_FRAME::SetLayerColor( int aLayer, COLOR4D aColor )
{
m_colorsSettings->SetLayerColor( aLayer, aColor );
applyDisplaySettingsToGAL();
}
int GERBVIEW_FRAME::getActiveLayer()
int GERBVIEW_FRAME::GetActiveLayer()
{
return ( (GBR_SCREEN*) GetScreen() )->m_Active_Layer;
}
void GERBVIEW_FRAME::setActiveLayer( int aLayer, bool doLayerWidgetUpdate )
void GERBVIEW_FRAME::SetActiveLayer( int aLayer, bool doLayerWidgetUpdate )
{
( (GBR_SCREEN*) GetScreen() )->m_Active_Layer = aLayer;
if( doLayerWidgetUpdate )
m_LayersManager->SelectLayer( getActiveLayer() );
m_LayersManager->SelectLayer( GetActiveLayer() );
if( IsGalCanvasActive() )
{
m_toolManager->RunAction( GERBVIEW_ACTIONS::layerChanged ); // notify other tools
GetGalCanvas()->SetFocus(); // otherwise hotkeys are stuck somewhere
GetGalCanvas()->SetTopLayer( GERBER_DRAW_LAYER( aLayer ) );
GetGalCanvas()->SetHighContrastLayer( GERBER_DRAW_LAYER( aLayer ) );
GetGalCanvas()->Refresh();
GetGalCanvas()->GetView()->RecacheAllItems();
}
}
@ -784,6 +887,17 @@ void GERBVIEW_FRAME::SetCurItem( GERBER_DRAW_ITEM* aItem, bool aDisplayInfo )
}
void GERBVIEW_FRAME::SetGridColor( COLOR4D aColor )
{
if( IsGalCanvasActive() )
{
GetGalCanvas()->GetGAL()->SetGridColor( aColor );
}
m_gridColor = aColor;
}
EDA_RECT GERBVIEW_FRAME::GetGerberLayoutBoundingBox()
{
GetGerberLayout()->ComputeBoundingBox();
@ -909,3 +1023,113 @@ void GERBVIEW_FRAME::unitsChangeRefresh()
EDA_DRAW_FRAME::unitsChangeRefresh();
updateDCodeSelectBox();
}
void GERBVIEW_FRAME::forceColorsToLegacy()
{
for( int i = 0; i < LAYER_ID_COUNT; i++ )
{
COLOR4D c = m_colorsSettings->GetLayerColor( i );
c.SetToNearestLegacyColor();
m_colorsSettings->SetLayerColor( i, c );
}
}
void GERBVIEW_FRAME::UseGalCanvas( bool aEnable )
{
EDA_DRAW_FRAME::UseGalCanvas( aEnable );
EDA_DRAW_PANEL_GAL* galCanvas = GetGalCanvas();
if( m_toolManager )
m_toolManager->SetEnvironment( m_gerberLayout, GetGalCanvas()->GetView(),
GetGalCanvas()->GetViewControls(), this );
if( aEnable )
{
if( m_toolManager )
m_toolManager->ResetTools( TOOL_BASE::GAL_SWITCH );
galCanvas->GetGAL()->SetGridColor( GetLayerColor( LAYER_GERBVIEW_GRID ) );
galCanvas->GetView()->RecacheAllItems();
galCanvas->SetEventDispatcher( m_toolDispatcher );
galCanvas->StartDrawing();
}
else
{
if( m_toolManager )
m_toolManager->ResetTools( TOOL_BASE::GAL_SWITCH );
galCanvas->StopDrawing();
// Redirect all events to the legacy canvas
galCanvas->SetEventDispatcher( NULL );
forceColorsToLegacy();
m_canvas->Refresh();
}
m_LayersManager->ReFill();
m_LayersManager->ReFillRender();
ReCreateOptToolbar();
}
EDA_DRAW_PANEL_GAL::GAL_TYPE GERBVIEW_FRAME::LoadCanvasTypeSetting() const
{
EDA_DRAW_PANEL_GAL::GAL_TYPE canvasType = EDA_DRAW_PANEL_GAL::GAL_TYPE_NONE;
wxConfigBase* cfg = Kiface().KifaceSettings();
if( cfg )
canvasType = (EDA_DRAW_PANEL_GAL::GAL_TYPE) cfg->ReadLong( CANVAS_TYPE_KEY,
EDA_DRAW_PANEL_GAL::GAL_TYPE_NONE );
if( canvasType < EDA_DRAW_PANEL_GAL::GAL_TYPE_NONE
|| canvasType >= EDA_DRAW_PANEL_GAL::GAL_TYPE_LAST )
{
assert( false );
canvasType = EDA_DRAW_PANEL_GAL::GAL_TYPE_NONE;
}
return canvasType;
}
bool GERBVIEW_FRAME::SaveCanvasTypeSetting( EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType )
{
if( aCanvasType < EDA_DRAW_PANEL_GAL::GAL_TYPE_NONE
|| aCanvasType >= EDA_DRAW_PANEL_GAL::GAL_TYPE_LAST )
{
assert( false );
return false;
}
wxConfigBase* cfg = Kiface().KifaceSettings();
if( cfg )
return cfg->Write( CANVAS_TYPE_KEY, (long) aCanvasType );
return false;
}
void GERBVIEW_FRAME::setupTools()
{
// Create the manager and dispatcher & route draw panel events to the dispatcher
m_toolManager = new TOOL_MANAGER;
m_toolManager->SetEnvironment( m_gerberLayout, GetGalCanvas()->GetView(),
GetGalCanvas()->GetViewControls(), this );
m_actions = new GERBVIEW_ACTIONS();
m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager, m_actions );
// Register tools
m_actions->RegisterAllTools( m_toolManager );
m_toolManager->InitTools();
// Run the selection tool, it is supposed to be always active
m_toolManager->InvokeTool( "gerbview.InteractiveSelection" );
}

View File

@ -36,10 +36,12 @@
#include <layers_id_colors_and_visibility.h>
#include <gerbview.h>
#include <convert_to_biu.h>
#include <class_gbr_layout.h>
#include <class_gbr_screen.h>
#include <class_page_info.h>
#include <class_gbr_display_options.h>
#include <class_draw_panel_gal.h>
#include <class_colors_design_settings.h>
extern COLORS_DESIGN_SETTINGS g_ColorsSettings;
@ -154,6 +156,9 @@ public:
*/
int SelectPCBLayer( int aDefaultLayer, int aOpperLayerCount, bool aNullLayer = false );
///> @copydoc EDA_DRAW_FRAME::SetGridColor()
virtual void SetGridColor( COLOR4D aColor ) override;
protected:
GERBER_LAYER_WIDGET* m_LayersManager;
@ -169,6 +174,9 @@ protected:
/// The last filename chosen to be proposed to the user
wxString m_lastFileName;
///> @copydoc EDA_DRAW_FRAME::forceColorsToLegacy()
virtual void forceColorsToLegacy() override;
public:
wxChoice* m_SelComponentBox; // a choice box to display and highlight component graphic items
wxChoice* m_SelNetnameBox; // a choice box to display and highlight netlist graphic items
@ -179,6 +187,8 @@ public:
wxTextCtrl* m_TextInfo; // a wxTextCtrl used to display some info about
// gerber data (format..)
COLORS_DESIGN_SETTINGS* m_colorsSettings;
private:
/// Auxiliary tool bar typically shown below the main tool bar at the top of the
/// main window.
@ -186,7 +196,6 @@ private:
// list of PARAM_CFG_xxx to read/write parameters saved in config
PARAM_CFG_ARRAY m_configSettings;
COLORS_DESIGN_SETTINGS* m_colorsSettings;
int m_displayMode; // Gerber images ("layers" in Gerbview) can be drawn:
// - in fast mode (write mode) but if there are negative
@ -206,9 +215,15 @@ private:
void updateDCodeSelectBox();
virtual void unitsChangeRefresh() override; // See class EDA_DRAW_FRAME
// The Tool Framework initalization
void setupTools();
// An array string to store warning messages when reading a gerber file.
wxArrayString m_Messages;
/// Updates the GAL with display settings changes
void applyDisplaySettingsToGAL();
public:
GERBVIEW_FRAME( KIWAY* aKiway, wxWindow* aParent );
~GERBVIEW_FRAME();
@ -243,6 +258,8 @@ public:
double BestZoom() override;
void UpdateStatusBar() override;
wxAuiToolBar* GetMainToolBar() { return m_optionsToolBar; }
/**
* Function GetZoomLevelIndicator
* returns a human readable value which can be displayed as zoom
@ -332,7 +349,7 @@ public:
/**
* Function IsLayerVisible
* tests whether a given layer is visible
* @param aLayer = The layer to be tested
* @param aLayer = The layer to be tested (still 0-31!)
* @return bool - true if the layer is visible.
*/
bool IsLayerVisible( int aLayer ) const;
@ -403,17 +420,17 @@ public:
void ReFillLayerWidget();
/**
* Function setActiveLayer
* Function SetActiveLayer
* will change the currently active layer to \a aLayer and also
* update the GERBER_LAYER_WIDGET.
*/
void setActiveLayer( int aLayer, bool doLayerWidgetUpdate = true );
void SetActiveLayer( int aLayer, bool doLayerWidgetUpdate = true );
/**
* Function getActiveLayer
* Function SetActiveLayer
* returns the active layer
*/
int getActiveLayer();
int GetActiveLayer();
/**
* Function getNextAvailableLayer
@ -432,7 +449,7 @@ public:
/**
* Function syncLayerWidget
* updates the currently "selected" layer within the GERBER_LAYER_WIDGET.
* The currently active layer is defined by the return value of getActiveLayer().
* The currently active layer is defined by the return value of GetActiveLayer().
* <p>
* This function cannot be inline without including layer_widget.h in
* here and we do not want to do that.
@ -443,7 +460,7 @@ public:
* Function syncLayerBox
* updates the currently "selected" layer within m_SelLayerBox
* The currently active layer, as defined by the return value of
* getActiveLayer().
* GetActiveLayer().
* @param aRebuildLayerBox = true to rebuild the layer box
* false to just updates the selection.
*/
@ -479,6 +496,7 @@ public:
void Process_Special_Functions( wxCommandEvent& event );
void OnSelectOptionToolbar( wxCommandEvent& event );
void OnSelectHighlightChoice( wxCommandEvent& event );
/**
* Function OnSelectActiveDCode
@ -714,6 +732,34 @@ public:
virtual void PrintPage( wxDC* aDC, LSET aPrintMasklayer, bool aPrintMirrorMode,
void* aData = NULL ) override;
///> @copydoc EDA_DRAW_FRAME::UseGalCanvas
virtual void UseGalCanvas( bool aEnable ) override;
/**
* switches currently used canvas (default / Cairo / OpenGL).
*/
void SwitchCanvas( wxCommandEvent& aEvent );
/**
* Update UI called when switches currently used canvas (default / Cairo / OpenGL).
*/
void OnUpdateSwitchCanvas( wxUpdateUIEvent& aEvent );
/**
* Function LoadCanvasTypeSetting()
* Returns the canvas type stored in the application settings.
*/
EDA_DRAW_PANEL_GAL::GAL_TYPE LoadCanvasTypeSetting() const;
/**
* Function SaveCanvasTypeSetting()
* Stores the canvas type in the application settings.
*/
bool SaveCanvasTypeSetting( EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType );
///> Key in KifaceSettings to store the canvas type.
static const wxChar CANVAS_TYPE_KEY[];
DECLARE_EVENT_TABLE()
};

View File

@ -50,6 +50,9 @@ enum gerbview_ids
ID_MENU_GERBVIEW_SHOW_HIDE_LAYERS_MANAGER_DIALOG,
ID_MENU_GERBVIEW_SELECT_PREFERED_EDITOR,
ID_MENU_CANVAS_LEGACY,
ID_MENU_CANVAS_OPENGL,
ID_MENU_CANVAS_CAIRO,
ID_GBR_AUX_TOOLBAR_PCB_CMP_CHOICE,
ID_GBR_AUX_TOOLBAR_PCB_NET_CHOICE,
@ -104,6 +107,9 @@ enum gerbview_ids
ID_TB_OPTIONS_SHOW_GBR_MODE_0,
ID_TB_OPTIONS_SHOW_GBR_MODE_1,
ID_TB_OPTIONS_SHOW_GBR_MODE_2,
ID_TB_OPTIONS_DIFF_MODE,
ID_TB_OPTIONS_HIGH_CONTRAST_MODE,
ID_TB_MEASUREMENT_TOOL,
// Right click context menu
ID_HIGHLIGHT_REMOVE_ALL,

View File

@ -28,7 +28,7 @@
#include <fctsys.h>
#include <common.h>
#include <id.h>
#include <gerbview_id.h>
#include <gerbview.h>
#include <gerbview_frame.h>
@ -86,6 +86,25 @@ static EDA_HOTKEY HkSwitch2NextCopperLayer( _HKI( "Switch to Next Layer" ),
static EDA_HOTKEY HkSwitch2PreviousCopperLayer( _HKI( "Switch to Previous Layer" ),
HK_SWITCH_LAYER_TO_PREVIOUS, '-' );
static EDA_HOTKEY HkCanvasDefault( _HKI( "Switch to Legacy Canvas" ),
HK_CANVAS_LEGACY,
#ifdef __WXMAC__
GR_KB_ALT +
#endif
WXK_F9 );
static EDA_HOTKEY HkCanvasOpenGL( _HKI( "Switch to OpenGL Canvas" ),
HK_CANVAS_OPENGL,
#ifdef __WXMAC__
GR_KB_ALT +
#endif
WXK_F11 );
static EDA_HOTKEY HkCanvasCairo( _HKI( "Switch to Cairo Canvas" ),
HK_CANVAS_CAIRO,
#ifdef __WXMAC__
GR_KB_ALT +
#endif
WXK_F12 );
// List of common hotkey descriptors
EDA_HOTKEY* gerbviewHotkeyList[] = {
&HkHelp,
@ -95,6 +114,9 @@ EDA_HOTKEY* gerbviewHotkeyList[] = {
&HkDCodesDisplayMode, &HkNegativeObjDisplayMode,
&HkSwitch2NextCopperLayer,
&HkSwitch2PreviousCopperLayer,
&HkCanvasDefault,
&HkCanvasOpenGL,
&HkCanvasCairo,
NULL
};
@ -205,22 +227,37 @@ bool GERBVIEW_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit
break;
case HK_SWITCH_LAYER_TO_PREVIOUS:
if( getActiveLayer() > 0 )
if( GetActiveLayer() > 0 )
{
setActiveLayer( getActiveLayer() - 1 );
SetActiveLayer( GetActiveLayer() - 1 );
m_LayersManager->OnLayerSelected();
m_canvas->Refresh();
}
break;
case HK_SWITCH_LAYER_TO_NEXT:
if( getActiveLayer() < 31 )
if( GetActiveLayer() < GERBER_DRAWLAYERS_COUNT - 1 )
{
setActiveLayer( getActiveLayer() + 1 );
SetActiveLayer( GetActiveLayer() + 1 );
m_LayersManager->OnLayerSelected();
m_canvas->Refresh();
}
break;
case HK_CANVAS_CAIRO:
cmd.SetId( ID_MENU_CANVAS_CAIRO );
GetEventHandler()->ProcessEvent( cmd );
break;
case HK_CANVAS_OPENGL:
cmd.SetId( ID_MENU_CANVAS_OPENGL );
GetEventHandler()->ProcessEvent( cmd );
break;
case HK_CANVAS_LEGACY:
cmd.SetId( ID_MENU_CANVAS_LEGACY );
GetEventHandler()->ProcessEvent( cmd );
break;
}
return true;

View File

@ -42,7 +42,10 @@ enum hotkey_id_commnand {
HK_GBR_NEGATIVE_DISPLAY_ONOFF,
HK_GBR_DCODE_DISPLAY_ONOFF,
HK_SWITCH_LAYER_TO_NEXT,
HK_SWITCH_LAYER_TO_PREVIOUS
HK_SWITCH_LAYER_TO_PREVIOUS,
HK_CANVAS_LEGACY,
HK_CANVAS_OPENGL,
HK_CANVAS_CAIRO
};
// List of hotkey descriptors for GerbView.

View File

@ -193,7 +193,7 @@ bool GERBVIEW_FRAME::LoadGerberJobFile( const wxString& aFullFileName )
wxFileName gbr_fn = filename;
bool read_ok;
int layer = 0;
setActiveLayer( layer, false );
SetActiveLayer( layer, false );
for( unsigned ii = 0; ii < gbrfiles.GetCount(); ii++ )
{
@ -207,7 +207,7 @@ bool GERBVIEW_FRAME::LoadGerberJobFile( const wxString& aFullFileName )
if( read_ok )
{
layer = getNextAvailableLayer( layer );
setActiveLayer( layer, false );
SetActiveLayer( layer, false );
}
}
else

View File

@ -49,7 +49,7 @@ GERBER_DRAW_ITEM* GERBVIEW_FRAME::Locate( const wxPoint& aPosition, int aTypeloc
if( aTypeloc == CURSEUR_ON_GRILLE )
ref = GetNearestGridPosition( ref );
int layer = getActiveLayer();
int layer = GetActiveLayer();
GERBER_FILE_IMAGE* gerber = GetGbrImage( layer );
GERBER_DRAW_ITEM* gerb_item = NULL;

View File

@ -42,6 +42,7 @@ void GERBVIEW_FRAME::ReCreateMenuBar()
{
// Create and try to get the current menubar
wxMenuBar* menuBar = GetMenuBar();
wxString text;
if( !menuBar )
menuBar = new wxMenuBar();
@ -207,6 +208,33 @@ void GERBVIEW_FRAME::ReCreateMenuBar()
// Hotkey submenu
AddHotkeyConfigMenu( configMenu );
// Canvas selection
configMenu->AppendSeparator();
text = AddHotkeyName( _( "Legacy Canva&s" ), GerbviewHokeysDescr,
HK_CANVAS_LEGACY );
configMenu->Append(
new wxMenuItem( configMenu, ID_MENU_CANVAS_LEGACY,
text, _( "Switch the canvas implementation to Legacy" ),
wxITEM_RADIO ) );
text = AddHotkeyName( _( "Open&GL Canvas" ), GerbviewHokeysDescr,
HK_CANVAS_OPENGL );
configMenu->Append(
new wxMenuItem( configMenu, ID_MENU_CANVAS_OPENGL,
text, _( "Switch the canvas implementation to OpenGL" ),
wxITEM_RADIO ) );
text = AddHotkeyName( _( "&Cairo Canvas" ), GerbviewHokeysDescr,
HK_CANVAS_CAIRO );
configMenu->Append(
new wxMenuItem( configMenu, ID_MENU_CANVAS_CAIRO,
text, _( "Switch the canvas implementation to Cairo" ),
wxITEM_RADIO ) );
// Menu miscellaneous
wxMenu* miscellaneousMenu = new wxMenu;

View File

@ -36,13 +36,15 @@
*/
void GERBVIEW_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
{
SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
GERBER_DRAW_ITEM* DrawStruct = Locate( aPosition, CURSEUR_OFF_GRILLE );
GetScreen()->SetCurItem( DrawStruct );
if( DrawStruct == NULL )
{
GERBER_FILE_IMAGE* gerber = GetGbrImage( getActiveLayer() );
GERBER_FILE_IMAGE* gerber = GetGbrImage( GetActiveLayer() );
if( gerber )
gerber->DisplayImageInfo( this );

View File

@ -120,7 +120,7 @@ bool GERBVIEW_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* aPopMenu )
D_CODE* apertDescr = currItem->GetDcodeDescr();
if( !apertDescr->m_AperFunction.IsEmpty() )
if( apertDescr && !apertDescr->m_AperFunction.IsEmpty() )
{
AddMenuItem( aPopMenu, ID_HIGHLIGHT_APER_ATTRIBUTE_ITEMS,
wxString::Format( _( "Highlight aperture type '%s'" ),

View File

@ -30,6 +30,7 @@
#include <gerbview_frame.h>
#include <class_gerber_file_image.h>
#include <class_gerber_file_image_list.h>
#include <view/view.h>
#include <html_messagebox.h>
#include <macros.h>
@ -40,7 +41,7 @@ bool GERBVIEW_FRAME::Read_GERBER_File( const wxString& GERBER_FullFileName )
{
wxString msg;
int layer = getActiveLayer();
int layer = GetActiveLayer();
GERBER_FILE_IMAGE_LIST* images = GetImagesList();
GERBER_FILE_IMAGE* gerber = GetGbrImage( layer );
@ -79,6 +80,23 @@ bool GERBVIEW_FRAME::Read_GERBER_File( const wxString& GERBER_FullFileName )
wxMessageBox( msg );
}
auto canvas = GetGalCanvas();
if( canvas )
{
auto view = canvas->GetView();
if( gerber->m_ImageNegative )
{
// TODO: find a way to handle negative images
// (maybe convert geometry into positives?)
}
for( auto item = gerber->GetItemsList(); item; item = item->Next() )
{
view->Add( (KIGFX::VIEW_ITEM*) item );
}
}
return true;
}

View File

@ -140,6 +140,9 @@ void fillFlashedGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
case APT_MACRO:
aGbrItem->m_Shape = GBR_SPOT_MACRO;
// Cache the bounding box for aperture macros
aGbrItem->GetDcodeDescr()->GetMacro()->GetApertureMacroShape( aGbrItem, aPos );
break;
}
}
@ -379,6 +382,9 @@ static void fillArcPOLY( GERBER_DRAW_ITEM* aGbrItem,
const int increment_angle = 3600 / 36;
int count = std::abs( arc_angle / increment_angle );
if( aGbrItem->m_Polygon.OutlineCount() == 0 )
aGbrItem->m_Polygon.NewOutline();
// calculate polygon corners
// when arc is counter-clockwise, dummyGbrItem arc goes from end to start
// and we must always create a polygon from start to end.
@ -397,7 +403,7 @@ static void fillArcPOLY( GERBER_DRAW_ITEM* aGbrItem,
else // last point
end_arc = aClockwise ? end : start;
aGbrItem->m_PolyCorners.push_back( end_arc + center );
aGbrItem->m_Polygon.Append( VECTOR2I( end_arc + center ) );
start_arc = end_arc;
}
@ -510,7 +516,7 @@ bool GERBER_FILE_IMAGE::Execute_G_Command( char*& text, int G_command )
if( D_commande > (TOOLS_MAX_COUNT - 1) )
D_commande = TOOLS_MAX_COUNT - 1;
m_Current_Tool = D_commande;
D_CODE* pt_Dcode = GetDCODE( D_commande, false );
D_CODE* pt_Dcode = GetDCODE( D_commande );
if( pt_Dcode )
pt_Dcode->m_InUse = true;
break;
@ -552,6 +558,7 @@ bool GERBER_FILE_IMAGE::Execute_G_Command( char*& text, int G_command )
if( m_Exposure && GetItemsList() ) // End of polygon
{
GERBER_DRAW_ITEM * gbritem = m_Drawings.GetLast();
gbritem->m_Polygon.Append( gbritem->m_Polygon.Vertex( 0 ) );
StepAndRepeatItem( *gbritem );
}
m_Exposure = false;
@ -594,7 +601,7 @@ bool GERBER_FILE_IMAGE::Execute_DCODE_Command( char*& text, int D_commande )
// call
m_Current_Tool = D_commande;
D_CODE* pt_Dcode = GetDCODE( D_commande, false );
D_CODE* pt_Dcode = GetDCODE( D_commande );
if( pt_Dcode )
pt_Dcode->m_InUse = true;
@ -635,11 +642,14 @@ bool GERBER_FILE_IMAGE::Execute_DCODE_Command( char*& text, int D_commande )
gbritem = m_Drawings.GetLast();
gbritem->m_Start = m_PreviousPos; // m_Start is used as temporary storage
if( gbritem->m_PolyCorners.size() == 0 )
gbritem->m_PolyCorners.push_back( gbritem->m_Start );
if( gbritem->m_Polygon.OutlineCount() == 0 )
{
gbritem->m_Polygon.NewOutline();
gbritem->m_Polygon.Append( VECTOR2I( gbritem->m_Start ) );
}
gbritem->m_End = m_CurrentPos; // m_End is used as temporary storage
gbritem->m_PolyCorners.push_back( gbritem->m_End );
gbritem->m_Polygon.Append( VECTOR2I( gbritem->m_End ) );
break;
}
@ -651,6 +661,7 @@ bool GERBER_FILE_IMAGE::Execute_DCODE_Command( char*& text, int D_commande )
if( m_Exposure && GetItemsList() ) // End of polygon
{
gbritem = m_Drawings.GetLast();
gbritem->m_Polygon.Append( gbritem->m_Polygon.Vertex( 0 ) );
StepAndRepeatItem( *gbritem );
}
m_Exposure = false;
@ -669,7 +680,7 @@ bool GERBER_FILE_IMAGE::Execute_DCODE_Command( char*& text, int D_commande )
case 1: // code D01 Draw line, exposure ON
m_Exposure = true;
tool = GetDCODE( m_Current_Tool, false );
tool = GetDCODE( m_Current_Tool );
if( tool )
{
size = tool->m_Size;
@ -722,7 +733,7 @@ bool GERBER_FILE_IMAGE::Execute_DCODE_Command( char*& text, int D_commande )
break;
case 3: // code D3: flash aperture
tool = GetDCODE( m_Current_Tool, false );
tool = GetDCODE( m_Current_Tool );
if( tool )
{
size = tool->m_Size;

View File

@ -710,7 +710,7 @@ bool GERBER_FILE_IMAGE::ExecuteRS274XCommand( int command, char* buff, char*& te
code = ReadInt( text );
D_CODE* dcode;
dcode = GetDCODE( code );
dcode = GetDCODEOrCreate( code );
if( dcode == NULL )
break;

View File

@ -206,9 +206,8 @@ void GERBVIEW_FRAME::ReCreateVToolbar( void )
void GERBVIEW_FRAME::ReCreateOptToolbar( void )
{
if( m_optionsToolBar )
return;
// creation of tool bar options
m_optionsToolBar->Clear();
else
m_optionsToolBar = new wxAuiToolBar( this, ID_OPT_TOOLBAR, wxDefaultPosition, wxDefaultSize,
wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_VERTICAL );
@ -218,6 +217,17 @@ void GERBVIEW_FRAME::ReCreateOptToolbar( void )
m_optionsToolBar->AddTool( ID_NO_TOOL_SELECTED, wxEmptyString, KiBitmap( cursor_xpm ),
wxEmptyString, wxITEM_CHECK );
m_optionsToolBar->AddTool( ID_ZOOM_SELECTION, wxEmptyString, KiBitmap( zoom_area_xpm ),
_( "Zoom to selection" ), wxITEM_CHECK );
if( IsGalCanvasActive() )
{
m_optionsToolBar->AddTool( ID_TB_MEASUREMENT_TOOL, wxEmptyString,
KiBitmap( measurement_xpm ),
_( "Measure distance between two points" ),
wxITEM_CHECK );
}
m_optionsToolBar->AddSeparator();
m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GRID, wxEmptyString, KiBitmap( grid_xpm ),
@ -264,23 +274,39 @@ void GERBVIEW_FRAME::ReCreateOptToolbar( void )
KiBitmap( show_dcodenumber_xpm ),
_( "Show dcode number" ), wxITEM_CHECK );
// tools to select draw mode in GerbView
// tools to select draw mode in GerbView, unused in GAL
if( !IsGalCanvasActive() )
{
m_optionsToolBar->AddSeparator();
m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GBR_MODE_0, wxEmptyString,
KiBitmap( gbr_select_mode0_xpm ),
_( "Show layers in raw mode \
(could have problems with negative items when more than one gerber file is shown)" ),
(could have problems with negative items when more than one gerber file is shown)" ),
wxITEM_CHECK );
m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GBR_MODE_1, wxEmptyString,
KiBitmap( gbr_select_mode1_xpm ),
_( "Show layers in stacked mode \
(show negative items without artifacts, sometimes slow)" ),
(show negative items without artifacts, sometimes slow)" ),
wxITEM_CHECK );
m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GBR_MODE_2, wxEmptyString,
KiBitmap( gbr_select_mode2_xpm ),
_( "Show layers in transparency mode \
(show negative items without artifacts, sometimes slow)" ),
(show negative items without artifacts, sometimes slow)" ),
wxITEM_CHECK );
}
else
{
m_optionsToolBar->AddTool( ID_TB_OPTIONS_DIFF_MODE, wxEmptyString,
KiBitmap( gbr_select_mode2_xpm ),
_( "Show layers in diff (compare) mode" ),
wxITEM_CHECK );
m_optionsToolBar->AddTool( ID_TB_OPTIONS_HIGH_CONTRAST_MODE, wxEmptyString,
KiBitmap( contrast_mode_xpm ),
_( "Enable high contrast display mode" ),
wxITEM_CHECK );
}
// Tools to show/hide toolbars:
m_optionsToolBar->AddSeparator();
@ -304,7 +330,7 @@ void GERBVIEW_FRAME::updateDCodeSelectBox()
// Add an empty string to deselect net highlight
m_DCodeSelector->Append( NO_SELECTION_STRING );
int layer = getActiveLayer();
int layer = GetActiveLayer();
GERBER_FILE_IMAGE* gerber = GetGbrImage( layer );
if( !gerber || gerber->GetDcodesCount() == 0 )
@ -323,7 +349,7 @@ void GERBVIEW_FRAME::updateDCodeSelectBox()
for( int ii = 0; ii < TOOLS_MAX_COUNT; ii++ )
{
D_CODE* dcode = gerber->GetDCODE( ii + FIRST_DCODE, false );
D_CODE* dcode = gerber->GetDCODE( ii + FIRST_DCODE );
if( dcode == NULL )
continue;
@ -433,7 +459,7 @@ void GERBVIEW_FRAME::updateAperAttributesSelectBox()
for( int ii = 0; ii < TOOLS_MAX_COUNT; ii++ )
{
D_CODE* aperture = gerber->GetDCODE( ii + FIRST_DCODE, false );
D_CODE* aperture = gerber->GetDCODE( ii + FIRST_DCODE );
if( aperture == NULL )
continue;
@ -534,7 +560,7 @@ void GERBVIEW_FRAME::OnUpdateSelectDCode( wxUpdateUIEvent& aEvent )
if( !m_DCodeSelector )
return;
int layer = getActiveLayer();
int layer = GetActiveLayer();
GERBER_FILE_IMAGE* gerber = GetGbrImage( layer );
int selected = ( gerber ) ? gerber->m_Selected_Tool : 0;
@ -553,8 +579,8 @@ void GERBVIEW_FRAME::OnUpdateSelectDCode( wxUpdateUIEvent& aEvent )
void GERBVIEW_FRAME::OnUpdateLayerSelectBox( wxUpdateUIEvent& aEvent )
{
if( m_SelLayerBox->GetSelection() != getActiveLayer() )
if( m_SelLayerBox->GetSelection() != GetActiveLayer() )
{
m_SelLayerBox->SetSelection( getActiveLayer() );
m_SelLayerBox->SetSelection( GetActiveLayer() );
}
}

View File

@ -171,7 +171,10 @@ enum KICAD_T
/*
* For GerbView: items type:
*/
TYPE_GERBER_DRAW_ITEM,
GERBER_LAYOUT_T,
GERBER_DRAW_ITEM_T,
GERBER_IMAGE_LIST_T,
GERBER_IMAGE_T,
/*
* for Pl_Editor, in undo/redo commands

View File

@ -276,8 +276,8 @@ enum GERBVIEW_LAYER_ID: int
{
GERBVIEW_LAYER_ID_START = SCH_LAYER_ID_END,
/// GerbView draw layers
GERBVIEW_LAYER_ID_RESERVED = GERBVIEW_LAYER_ID_START + GERBER_DRAWLAYERS_COUNT,
/// GerbView draw layers and d-code layers
GERBVIEW_LAYER_ID_RESERVED = GERBVIEW_LAYER_ID_START + ( 2 * GERBER_DRAWLAYERS_COUNT ),
LAYER_DCODES,
LAYER_NEGATIVE_OBJECTS,
@ -288,6 +288,12 @@ enum GERBVIEW_LAYER_ID: int
GERBVIEW_LAYER_ID_END
};
#define GERBER_DRAW_LAYER( x ) ( GERBVIEW_LAYER_ID_START + x )
#define GERBER_DCODE_LAYER( x ) ( GERBER_DRAWLAYERS_COUNT + x )
#define GERBER_DRAW_LAYER_INDEX( x ) ( x - GERBVIEW_LAYER_ID_START )
/// Must update this if you add any enums after GerbView!
#define LAYER_ID_COUNT GERBVIEW_LAYER_ID_END
@ -605,6 +611,7 @@ private:
}
};
/**
* Function IsValidLayer
* tests whether a given integer is a valid layer index, i.e. can
@ -774,6 +781,13 @@ inline bool IsNetnameLayer( LAYER_NUM aLayer )
}
inline bool IsDCodeLayer( int aLayer )
{
return aLayer >= (GERBVIEW_LAYER_ID_START + GERBER_DRAWLAYERS_COUNT) &&
aLayer < (GERBVIEW_LAYER_ID_START + (2 * GERBER_DRAWLAYERS_COUNT));
}
PCB_LAYER_ID ToLAYER_ID( int aLayer );
#endif // LAYERS_ID_AND_VISIBILITY_H_