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(); \ #define TO_POLY_SHAPE { aShapeBuffer.NewOutline(); \
for( unsigned jj = 0; jj < polybuffer.size(); jj++ )\ 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. // Draw the primitive shape for flashed items.
static std::vector<wxPoint> polybuffer; // create a static buffer to avoid a lot of memory reallocation 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 * Function DrawApertureMacroShape
* Draw the primitive shape for flashed items. * Draw the primitive shape for flashed items.
@ -756,39 +801,14 @@ void APERTURE_MACRO::DrawApertureMacroShape( GERBER_DRAW_ITEM* aParent,
COLOR4D aColor, COLOR4D aColor,
wxPoint aShapePos, bool aFilledShape ) wxPoint aShapePos, bool aFilledShape )
{ {
SHAPE_POLY_SET shapeBuffer; SHAPE_POLY_SET* shapeBuffer = GetApertureMacroShape( aParent, aShapePos );
SHAPE_POLY_SET holeBuffer;
bool hasHole = false;
for( AM_PRIMITIVES::iterator prim_macro = primitives.begin(); if( shapeBuffer->OutlineCount() == 0 )
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 )
return; return;
// If a hole is defined inside a polygon, we must fracture the polygon for( int ii = 0; ii < shapeBuffer->OutlineCount(); ii++ )
// 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++ )
{ {
SHAPE_LINE_CHAIN& poly = shapeBuffer.Outline( ii ); SHAPE_LINE_CHAIN& poly = shapeBuffer->Outline( ii );
GRClosedPoly( aClipBox, aDC, GRClosedPoly( aClipBox, aDC,
poly.PointCount(), (wxPoint*)&poly.Point( 0 ), aFilledShape, aColor, aColor ); poly.PointCount(), (wxPoint*)&poly.Point( 0 ), aFilledShape, aColor, aColor );

View File

@ -35,6 +35,7 @@
#include <base_struct.h> #include <base_struct.h>
#include <class_am_param.h> #include <class_am_param.h>
#include <class_eda_rect.h>
class SHAPE_POLY_SET; class SHAPE_POLY_SET;
@ -170,6 +171,9 @@ struct APERTURE_MACRO
*/ */
AM_PARAMS m_localparamStack; 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 * function GetLocalParam
* Usually, parameters are defined inside the aperture primitive * Usually, parameters are defined inside the aperture primitive
@ -183,6 +187,16 @@ struct APERTURE_MACRO
*/ */
double GetLocalParam( const D_CODE* aDcode, unsigned aParamId ) const; 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 * Function DrawApertureMacroShape
* Draw the primitive shape for flashed items. * Draw the primitive shape for flashed items.
@ -210,6 +224,12 @@ struct APERTURE_MACRO
* @return a dimension, or -1 if no dim to calculate * @return a dimension, or -1 if no dim to calculate
*/ */
int GetShapeDim( GERBER_DRAW_ITEM* aParent ); 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_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_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_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 COLOR4D m_NegativeDrawColor; ///< The color used to draw negative objects, usually the
///< background color, but not always, when negative objects ///< background color, but not always, when negative objects
///< must be visible ///< must be visible
@ -65,6 +67,8 @@ public:
m_ForceBlackAndWhite = false; m_ForceBlackAndWhite = false;
m_NegativeDrawColor = COLOR4D( DARKGRAY ); m_NegativeDrawColor = COLOR4D( DARKGRAY );
m_BgDrawColor = COLOR4D::BLACK; 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(); 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.h>
#include <class_gerber_file_image_list.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 // 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(); 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; EDA_RECT bbox;
bool first_item = true; 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; 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 // In non transparent modes, the last layer drawn masks others layers
for( int layer = GERBER_DRAWLAYERS_COUNT-1; !end; --layer ) 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 if( layer == active_layer ) // active layer will be drawn after other layers
continue; continue;
@ -204,12 +208,12 @@ void GBR_LAYOUT::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDrawMode,
if( aDisplayOptions->m_IsPrinting ) if( aDisplayOptions->m_IsPrinting )
gerber->m_IsVisible = IsLayerPrintable( layer ); gerber->m_IsVisible = IsLayerPrintable( layer );
else else
gerber->m_IsVisible = gerbFrame->IsLayerVisible( layer ); gerber->m_IsVisible = gerbFrame->IsLayerVisible( GERBER_DRAW_LAYER( layer ) );
if( !gerber->m_IsVisible ) if( !gerber->m_IsVisible )
continue; continue;
gerber->m_PositiveDrawColor = gerbFrame->GetLayerColor( layer ); gerber->m_PositiveDrawColor = gerbFrame->GetLayerColor( GERBER_DRAW_LAYER( layer ) );
// Force black and white draw mode on request: // Force black and white draw mode on request:
if( aDisplayOptions->m_ForceBlackAndWhite ) 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; int dcode_highlight = 0;
if( layer == gerbFrame->getActiveLayer() ) if( layer == gerbFrame->GetActiveLayer() )
dcode_highlight = gerber->m_Selected_Tool; dcode_highlight = gerber->m_Selected_Tool;
GR_DRAWMODE layerdrawMode = GR_COPY; 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 * Class GBR_LAYOUT
* holds list of GERBER_DRAW_ITEM currently loaded. * holds list of GERBER_DRAW_ITEM currently loaded.
*/ */
class GBR_LAYOUT class GBR_LAYOUT : public EDA_ITEM
{ {
private: private:
EDA_RECT m_BoundingBox; mutable EDA_RECT m_BoundingBox;
TITLE_BLOCK m_titles; TITLE_BLOCK m_titles;
wxPoint m_originAxisPosition; wxPoint m_originAxisPosition;
std::vector<int> m_printLayersList; // When printing: the list of graphic layers Id to print std::vector<int> m_printLayersList; // When printing: the list of graphic layers Id to print
@ -63,9 +63,14 @@ public:
GBR_LAYOUT(); GBR_LAYOUT();
~GBR_LAYOUT(); ~GBR_LAYOUT();
wxString GetClass() const override
{
return wxT( "GBR_LAYOUT" );
}
// Accessor to the GERBER_FILE_IMAGE_LIST, // Accessor to the GERBER_FILE_IMAGE_LIST,
// which handles the list of gerber files (and drill files) images loaded // 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 const wxPoint& GetAuxOrigin() const
{ {
@ -92,14 +97,15 @@ public:
* calculates the bounding box containing all Gerber items. * calculates the bounding box containing all Gerber items.
* @return EDA_RECT - the full item list bounding box * @return EDA_RECT - the full item list bounding box
*/ */
EDA_RECT ComputeBoundingBox(); EDA_RECT ComputeBoundingBox() const;
/** /**
* Function GetBoundingBox * 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; } void SetBoundingBox( const EDA_RECT& aBox ) { m_BoundingBox = aBox; }
@ -176,8 +182,13 @@ public:
*/ */
bool IsLayerPrintable( int aLayer ) const; bool IsLayerPrintable( int aLayer ) const;
///> @copydoc EDA_ITEM::Visit()
SEARCH_RESULT Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] ) override;
#if defined(DEBUG) #if defined(DEBUG)
void Show( int nestLevel, std::ostream& os ) const;
void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
#endif #endif
}; };

View File

@ -33,6 +33,7 @@
#include <class_drawpanel.h> #include <class_drawpanel.h>
#include <msgpanel.h> #include <msgpanel.h>
#include <gerbview_frame.h> #include <gerbview_frame.h>
#include <convert_basic_shapes_to_polygon.h>
#include <class_gerber_draw_item.h> #include <class_gerber_draw_item.h>
#include <class_gerber_file_image.h> #include <class_gerber_file_image.h>
@ -40,7 +41,7 @@
GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( GERBER_FILE_IMAGE* aGerberImageFile ) : 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_GerberImageFile = aGerberImageFile;
m_Shape = GBR_SEGMENT; 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 ) 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) ) if( (m_DCode < FIRST_DCODE) || (m_DCode > LAST_DCODE) )
return NULL; return NULL;
@ -211,7 +212,7 @@ D_CODE* GERBER_DRAW_ITEM::GetDcodeDescr()
if( m_GerberImageFile == NULL ) if( m_GerberImageFile == NULL )
return 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 // return a rectangle which is (pos,dim) in nature. therefore the +1
EDA_RECT bbox( m_Start, wxSize( 1, 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 // calculate the corners coordinates in current gerber axis orientations
wxPoint org = GetABPosition( bbox.GetOrigin() ); wxPoint org = GetABPosition( bbox.GetOrigin() );
@ -243,8 +336,11 @@ void GERBER_DRAW_ITEM::MoveAB( const wxPoint& aMoveVector )
m_End += xymove; m_End += xymove;
m_ArcCentre += xymove; m_ArcCentre += xymove;
for( unsigned ii = 0; ii < m_PolyCorners.size(); ii++ ) if( m_Polygon.OutlineCount() > 0 )
m_PolyCorners[ii] += xymove; {
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_End += aMoveVector;
m_ArcCentre += aMoveVector; m_ArcCentre += aMoveVector;
for( unsigned ii = 0; ii < m_PolyCorners.size(); ii++ ) if( m_Polygon.OutlineCount() > 0 )
m_PolyCorners[ii] += aMoveVector; {
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( d_codeDescr->m_Shape == APT_RECT )
{ {
if( m_PolyCorners.size() == 0 ) if( m_Polygon.OutlineCount() == 0 )
ConvertSegmentToPolygon( ); ConvertSegmentToPolygon();
DrawGbrPoly( aPanel->GetClipBox(), aDC, color, aOffset, isFilled ); 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_Polygon.RemoveAllContours();
m_PolyCorners.reserve(6); m_Polygon.NewOutline();
wxPoint start = m_Start; wxPoint start = m_Start;
wxPoint end = m_End; wxPoint end = m_End;
@ -443,34 +542,37 @@ void GERBER_DRAW_ITEM::ConvertSegmentToPolygon( )
wxPoint corner; wxPoint corner;
corner.x -= m_Size.x/2; corner.x -= m_Size.x/2;
corner.y -= m_Size.y/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; 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) if( delta.x || delta.y)
{ {
corner += delta; 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; 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; 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 ) if( delta.x || delta.y )
{ {
corner -= delta; 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: // Create final polygon:
for( unsigned ii = 0; ii < m_PolyCorners.size(); ii++ ) for( auto it = m_Polygon.Iterate( 0 ); it; ++it )
{ {
if( change ) 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 ) bool aFilledShape )
{ {
std::vector<wxPoint> points; std::vector<wxPoint> points;
SHAPE_LINE_CHAIN& poly = m_Polygon.Outline( 0 );
int pointCount = poly.PointCount() - 1;
points = m_PolyCorners; points.reserve( pointCount );
for( unsigned ii = 0; ii < points.size(); ii++ )
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] ); 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 ); msg.Printf( _( "D Code %d" ), m_DCode );
D_CODE* apertDescr = GetDcodeDescr(); D_CODE* apertDescr = GetDcodeDescr();
if( apertDescr->m_AperFunction.IsEmpty() ) if( !apertDescr || apertDescr->m_AperFunction.IsEmpty() )
text = _( "No attribute" ); text = _( "No attribute" );
else else
text = apertDescr->m_AperFunction; 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) // 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; 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 ) if( m_Flashed )
return HitTestPoints( m_Start, ref_pos, radius ); return HitTestPoints( m_Start, ref_pos, radius );
else else
@ -624,3 +761,60 @@ void GERBER_DRAW_ITEM::Show( int nestLevel, std::ostream& os ) const
} }
#endif #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 <gr_basic.h>
#include <gbr_netlist_metadata.h> #include <gbr_netlist_metadata.h>
#include <dcode.h> #include <dcode.h>
#include <geometry/shape_poly_set.h>
class GERBER_FILE_IMAGE; class GERBER_FILE_IMAGE;
class GBR_LAYOUT; class GBR_LAYOUT;
@ -42,6 +43,11 @@ class D_CODE;
class MSG_PANEL_ITEM; class MSG_PANEL_ITEM;
class GBR_DISPLAY_OPTIONS; class GBR_DISPLAY_OPTIONS;
namespace KIGFX
{
class VIEW;
};
/* Shapes id for basic shapes ( .m_Shape member ) */ /* Shapes id for basic shapes ( .m_Shape member ) */
enum Gbr_Basic_Shapes { enum Gbr_Basic_Shapes {
@ -76,7 +82,7 @@ public:
// for flashed items // for flashed items
wxPoint m_End; // Line or arc end point wxPoint m_End; // Line or arc end point
wxPoint m_ArcCentre; // for arcs only: Centre of arc 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 // or for complex shapes which are converted to polygon
wxSize m_Size; // Flashed shapes: size of the shape wxSize m_Size; // Flashed shapes: size of the shape
// Lines : m_Size.x = m_Size.y = line width // 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 ); } GERBER_DRAW_ITEM* Back() const { return static_cast<GERBER_DRAW_ITEM*>( Pback ); }
void SetNetAttributes( const GBR_NETLIST_METADATA& aNetAttributes ); 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 * Function GetLayer
@ -124,7 +130,7 @@ public:
*/ */
int GetLayer() const; int GetLayer() const;
bool GetLayerPolarity() bool GetLayerPolarity() const
{ {
return m_LayerNegative; return m_LayerNegative;
} }
@ -186,6 +192,11 @@ public:
*/ */
wxPoint GetABPosition( const wxPoint& aXYPosition ) const; wxPoint GetABPosition( const wxPoint& aXYPosition ) const;
VECTOR2I GetABPosition( const VECTOR2I& aXYPosition ) const
{
return VECTOR2I( GetABPosition( wxPoint( aXYPosition.x, aXYPosition.y ) ) );
}
/** /**
* Function GetXYPosition * Function GetXYPosition
* returns the image position of aPosition for this object. * returns the image position of aPosition for this object.
@ -201,7 +212,7 @@ public:
* returns the GetDcodeDescr of this object, or NULL. * returns the GetDcodeDescr of this object, or NULL.
* @return D_CODE* - a pointer to the DCode description (for flashed items). * @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; const EDA_RECT GetBoundingBox() const override;
@ -229,7 +240,7 @@ public:
void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) override; void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) override;
wxString ShowGBRShape(); wxString ShowGBRShape() const;
/** /**
* Function HitTest * Function HitTest
@ -284,6 +295,26 @@ public:
void Show( int nestLevel, std::ostream& os ) const override; void Show( int nestLevel, std::ostream& os ) const override;
#endif #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 */ #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_GraphicLayer = aLayer; // Graphic layer Number
m_IsVisible = true; // must be drawn m_IsVisible = true; // must be drawn
@ -126,7 +127,8 @@ GERBER_DRAW_ITEM * GERBER_FILE_IMAGE::GetItemsList()
return m_Drawings; 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; 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* GERBER_FILE_IMAGE::FindApertureMacro( const APERTURE_MACRO& aLookup )
{ {
APERTURE_MACRO_SET::iterator iter = m_aperture_macros.find( 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" ) if( aAttribute.GetPrm( 1 ).IsEmpty() || aAttribute.GetPrm( 1 ) == ".AperFunction" )
m_AperFunction.Clear(); 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 * holds the Image data and parameters for one gerber file
* and layer parameters (TODO: move them in GERBER_LAYER class * 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) 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 bool m_Exposure; ///< whether an aperture macro tool is flashed on or off
@ -180,6 +180,11 @@ public:
GERBER_FILE_IMAGE( int layer ); GERBER_FILE_IMAGE( int layer );
virtual ~GERBER_FILE_IMAGE(); virtual ~GERBER_FILE_IMAGE();
wxString GetClass() const override
{
return wxT( "GERBER_FILE_IMAGE" );
}
void Clear_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 * returns a pointer to the D_CODE within this GERBER for the given
* \a aDCODE. * \a aDCODE.
* @param aDCODE The numeric value of the D_CODE to look up. * @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 * @return D_CODE* - the one implied by the given \a aDCODE, or NULL
* if the requested \a aDCODE is out of range. * 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 * Function FindApertureMacro
@ -350,6 +365,15 @@ public:
* only this attribute is cleared * only this attribute is cleared
*/ */
void RemoveAttribute( X2_ATTRIBUTE& aAttribute ); 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 #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 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 ); m_GERBER_List.reserve( GERBER_DRAWLAYERS_COUNT );
@ -244,4 +245,3 @@ void GERBER_FILE_IMAGE_LIST::SortImagesByZOrder()
gerber->m_GraphicLayer = layer ; gerber->m_GraphicLayer = layer ;
} }
} }

View File

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

View File

@ -41,6 +41,10 @@
#include <layer_widget.h> #include <layer_widget.h>
#include <class_gerbview_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 * 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( ) void GERBER_LAYER_WIDGET::SetLayersManagerTabsText( )
{ {
m_notebook->SetPageText(0, _("Layer") ); m_notebook->SetPageText(0, _("Layer") );
@ -180,8 +190,11 @@ void GERBER_LAYER_WIDGET::onPopupSelection( wxCommandEvent& event )
int layer = getDecodedId( cb->GetId() ); int layer = getDecodedId( cb->GetId() );
bool loc_visible = visible; 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; loc_visible = true;
}
cb->SetValue( loc_visible ); cb->SetValue( loc_visible );
@ -228,8 +241,19 @@ void GERBER_LAYER_WIDGET::ReFill()
{ {
wxString msg = GetImagesList()->GetDisplayName( layer ); wxString msg = GetImagesList()->GetDisplayName( layer );
AppendLayerRow( LAYER_WIDGET::ROW( msg, layer, bool visible = true;
myframe->GetLayerColor( layer ), wxEmptyString, 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(); Thaw();
@ -246,6 +270,14 @@ void GERBER_LAYER_WIDGET::OnLayerColorChange( int aLayer, COLOR4D aColor )
{ {
myframe->SetLayerColor( aLayer, aColor ); myframe->SetLayerColor( aLayer, aColor );
myframe->m_SelLayerBox->ResyncBitmapOnly(); 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(); 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 // the layer change from the GERBER_LAYER_WIDGET can be denied by returning
// false from this function. // false from this function.
int layer = myframe->getActiveLayer( ); int layer = myframe->GetActiveLayer( );
myframe->setActiveLayer( aLayer, false ); // 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(); myframe->syncLayerBox();
if( layer != myframe->getActiveLayer( ) ) if( layer != myframe->GetActiveLayer( ) )
{ {
if( ! OnLayerSelected() ) if( ! OnLayerSelected() )
myframe->GetCanvas()->Refresh(); 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 ) void GERBER_LAYER_WIDGET::OnRenderColorChange( int aId, COLOR4D aColor )
{ {
myframe->SetVisibleElementColor( (GERBVIEW_LAYER_ID) aId, 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(); myframe->GetCanvas()->Refresh();
} }
void GERBER_LAYER_WIDGET::OnRenderEnable( int aId, bool isEnabled ) void GERBER_LAYER_WIDGET::OnRenderEnable( int aId, bool isEnabled )
{ {
myframe->SetElementVisibility( (GERBVIEW_LAYER_ID) aId, 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(); myframe->GetCanvas()->Refresh();
} }

View File

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

View File

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

View File

@ -36,6 +36,7 @@
#include <gerbview_frame.h> #include <gerbview_frame.h>
#include <class_gerber_file_image.h> #include <class_gerber_file_image.h>
#include <convert_to_biu.h> #include <convert_to_biu.h>
#include <convert_basic_shapes_to_polygon.h>
#define DCODE_DEFAULT_SIZE Millimeter2iu( 0.1 ) #define DCODE_DEFAULT_SIZE Millimeter2iu( 0.1 )
@ -87,7 +88,7 @@ void D_CODE::Clear_D_CODE_Data()
m_Macro = NULL; m_Macro = NULL;
m_Rotation = 0.0; m_Rotation = 0.0;
m_EdgesCount = 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), GRFilledCircle( aClipBox, aDC, aParent->GetABPosition(aShapePos),
radius, aColor ); 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; int width = (m_Size.x - m_Drill.x ) / 2;
GRCircle( aClipBox, aDC, aParent->GetABPosition(aShapePos), GRCircle( aClipBox, aDC, aParent->GetABPosition(aShapePos),
@ -181,7 +182,7 @@ void D_CODE::DrawFlashedShape( GERBER_DRAW_ITEM* aParent,
} }
else // rectangular hole else // rectangular hole
{ {
if( m_PolyCorners.size() == 0 ) if( m_Polygon.OutlineCount() == 0 )
ConvertShapeToPolygon(); ConvertShapeToPolygon();
DrawFlashedPolygon( aParent, aClipBox, aDC, aColor, aFilledShape, aShapePos ); DrawFlashedPolygon( aParent, aClipBox, aDC, aColor, aFilledShape, aShapePos );
@ -207,7 +208,7 @@ void D_CODE::DrawFlashedShape( GERBER_DRAW_ITEM* aParent,
} }
else else
{ {
if( m_PolyCorners.size() == 0 ) if( m_Polygon.OutlineCount() == 0 )
ConvertShapeToPolygon(); ConvertShapeToPolygon();
DrawFlashedPolygon( aParent, aClipBox, aDC, aColor, aFilledShape, aShapePos ); DrawFlashedPolygon( aParent, aClipBox, aDC, aColor, aFilledShape, aShapePos );
@ -248,7 +249,7 @@ void D_CODE::DrawFlashedShape( GERBER_DRAW_ITEM* aParent,
} }
else else
{ {
if( m_PolyCorners.size() == 0 ) if( m_Polygon.OutlineCount() == 0 )
ConvertShapeToPolygon(); ConvertShapeToPolygon();
DrawFlashedPolygon( aParent, aClipBox, aDC, aColor, aFilledShape, aShapePos ); DrawFlashedPolygon( aParent, aClipBox, aDC, aColor, aFilledShape, aShapePos );
@ -257,7 +258,7 @@ void D_CODE::DrawFlashedShape( GERBER_DRAW_ITEM* aParent,
break; break;
case APT_POLYGON: case APT_POLYGON:
if( m_PolyCorners.size() == 0 ) if( m_Polygon.OutlineCount() == 0 )
ConvertShapeToPolygon(); ConvertShapeToPolygon();
DrawFlashedPolygon( aParent, aClipBox, aDC, aColor, aFilledShape, aShapePos ); DrawFlashedPolygon( aParent, aClipBox, aDC, aColor, aFilledShape, aShapePos );
@ -271,27 +272,29 @@ void D_CODE::DrawFlashedPolygon( GERBER_DRAW_ITEM* aParent,
COLOR4D aColor, bool aFilled, COLOR4D aColor, bool aFilled,
const wxPoint& aPosition ) const wxPoint& aPosition )
{ {
if( m_PolyCorners.size() == 0 ) if( m_Polygon.OutlineCount() == 0 )
return; return;
int pointCount = m_Polygon.VertexCount();
std::vector<wxPoint> points; 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] ); 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 // 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, APERTURE_DEF_HOLETYPE aHoleShape,
wxSize aSize, wxSize aSize,
wxPoint aAnchorPos ); wxPoint aAnchorPos );
@ -302,43 +305,37 @@ void D_CODE::ConvertShapeToPolygon()
wxPoint initialpos; wxPoint initialpos;
wxPoint currpos; wxPoint currpos;
m_PolyCorners.clear(); m_Polygon.RemoveAllContours();
switch( m_Shape ) switch( m_Shape )
{ {
case APT_CIRCLE: // creates only a circle with rectangular hole case APT_CIRCLE: // creates only a circle with rectangular hole
currpos.x = m_Size.x >> 1; TransformCircleToPolygon( m_Polygon, initialpos, m_Size.x >> 1, SEGS_CNT );
initialpos = currpos; addHoleToPolygon( &m_Polygon, m_DrillShape, m_Drill, initialpos );
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 );
break; break;
case APT_RECT: case APT_RECT:
m_Polygon.NewOutline();
currpos.x = m_Size.x / 2; currpos.x = m_Size.x / 2;
currpos.y = m_Size.y / 2; currpos.y = m_Size.y / 2;
initialpos = currpos; initialpos = currpos;
m_PolyCorners.push_back( currpos ); m_Polygon.Append( VECTOR2I( currpos ) );
currpos.x -= m_Size.x; currpos.x -= m_Size.x;
m_PolyCorners.push_back( currpos ); m_Polygon.Append( VECTOR2I( currpos ) );
currpos.y -= m_Size.y; currpos.y -= m_Size.y;
m_PolyCorners.push_back( currpos ); m_Polygon.Append( VECTOR2I( currpos ) );
currpos.x += m_Size.x; currpos.x += m_Size.x;
m_PolyCorners.push_back( currpos ); m_Polygon.Append( VECTOR2I( currpos ) );
currpos.y += m_Size.y; 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; break;
case APT_OVAL: case APT_OVAL:
{ {
m_Polygon.NewOutline();
int delta, radius; int delta, radius;
// we create an horizontal oval shape. then rotate if needed // we create an horizontal oval shape. then rotate if needed
@ -355,7 +352,7 @@ void D_CODE::ConvertShapeToPolygon()
currpos.y = radius; currpos.y = radius;
initialpos = currpos; initialpos = currpos;
m_PolyCorners.push_back( currpos ); m_Polygon.Append( VECTOR2I( currpos ) );
// build the right arc of the shape // build the right arc of the shape
unsigned ii = 0; unsigned ii = 0;
@ -365,7 +362,7 @@ void D_CODE::ConvertShapeToPolygon()
currpos = initialpos; currpos = initialpos;
RotatePoint( &currpos, ii * 3600.0 / SEGS_CNT ); RotatePoint( &currpos, ii * 3600.0 / SEGS_CNT );
currpos.x += delta; currpos.x += delta;
m_PolyCorners.push_back( currpos ); m_Polygon.Append( VECTOR2I( currpos ) );
} }
// build the left arc of the shape // build the left arc of the shape
@ -374,22 +371,23 @@ void D_CODE::ConvertShapeToPolygon()
currpos = initialpos; currpos = initialpos;
RotatePoint( &currpos, ii * 3600.0 / SEGS_CNT ); RotatePoint( &currpos, ii * 3600.0 / SEGS_CNT );
currpos.x -= delta; 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. if( m_Size.y > m_Size.x ) // vertical oval, rotate polygon.
{ {
for( unsigned jj = 0; jj < m_PolyCorners.size(); jj++ ) for( auto it = m_Polygon.Iterate( 0 ); it; ++it )
RotatePoint( &m_PolyCorners[jj], 900 ); it->Rotate( -M_PI / 2 );
} }
addHoleToPolygon( m_PolyCorners, m_DrillShape, m_Drill, initialpos ); addHoleToPolygon( &m_Polygon, m_DrillShape, m_Drill, initialpos );
} }
break; break;
case APT_POLYGON: case APT_POLYGON:
m_Polygon.NewOutline();
currpos.x = m_Size.x >> 1; // first point is on X axis currpos.x = m_Size.x >> 1; // first point is on X axis
initialpos = currpos; initialpos = currpos;
@ -400,23 +398,21 @@ void D_CODE::ConvertShapeToPolygon()
if( m_EdgesCount > 12 ) if( m_EdgesCount > 12 )
m_EdgesCount = 12; m_EdgesCount = 12;
for( int ii = 0; ii <= m_EdgesCount; ii++ ) for( int ii = 0; ii < m_EdgesCount; ii++ )
{ {
currpos = initialpos; currpos = initialpos;
RotatePoint( &currpos, ii * 3600.0 / m_EdgesCount ); 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. if( m_Rotation ) // vertical oval, rotate polygon.
{ {
int angle = KiROUND( m_Rotation * 10 ); int angle = KiROUND( m_Rotation * 10 );
for( unsigned jj = 0; jj < m_PolyCorners.size(); jj++ ) for( auto it = m_Polygon.Iterate( 0 ); it; ++it )
{ it->Rotate( -angle );
RotatePoint( &m_PolyCorners[jj], -angle );
}
} }
break; break;
@ -431,39 +427,36 @@ void D_CODE::ConvertShapeToPolygon()
// The helper function for D_CODE::ConvertShapeToPolygon(). // The helper function for D_CODE::ConvertShapeToPolygon().
// Add a hole to a polygon // Add a hole to a polygon
static void addHoleToPolygon( std::vector<wxPoint>& aBuffer, static void addHoleToPolygon( SHAPE_POLY_SET* aPolygon,
APERTURE_DEF_HOLETYPE aHoleShape, APERTURE_DEF_HOLETYPE aHoleShape,
wxSize aSize, wxSize aSize,
wxPoint aAnchorPos ) wxPoint aAnchorPos )
{ {
wxPoint currpos; 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++ ) TransformCircleToPolygon( holeBuffer, wxPoint( 0, 0 ), aSize.x / 2, SEGS_CNT );
{
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 );
} }
else if( aHoleShape == APT_DEF_RECT_HOLE )
aBuffer.push_back( aAnchorPos ); // link to outline
}
if( aHoleShape == APT_DEF_RECT_HOLE ) // Create rectangular hole
{ {
holeBuffer.NewOutline();
currpos.x = aSize.x / 2; currpos.x = aSize.x / 2;
currpos.y = aSize.y / 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; currpos.x -= aSize.x;
aBuffer.push_back( currpos ); holeBuffer.Append( VECTOR2I( currpos ) );
currpos.y -= aSize.y; currpos.y -= aSize.y;
aBuffer.push_back( currpos ); holeBuffer.Append( VECTOR2I( currpos ) );
currpos.x += aSize.x; currpos.x += aSize.x;
aBuffer.push_back( currpos ); holeBuffer.Append( VECTOR2I( currpos ) );
currpos.y += aSize.y; currpos.y += aSize.y;
aBuffer.push_back( currpos ); // close hole holeBuffer.Append( VECTOR2I( currpos ) ); // close hole
aBuffer.push_back( aAnchorPos ); // link to outline
} }
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 <base_struct.h>
#include <gal/color4d.h> #include <gal/color4d.h>
#include <geometry/shape_poly_set.h>
using KIGFX::COLOR4D; using KIGFX::COLOR4D;
@ -89,11 +90,6 @@ private:
*/ */
std::vector<double> m_am_params; 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: public:
wxSize m_Size; ///< Horizontal and vertical dimensions. wxSize m_Size; ///< Horizontal and vertical dimensions.
APERTURE_T m_Shape; ///< shape ( Line, rectangle, circle , oval .. ) 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 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) wxString m_AperFunction; ///< the aperture attribute (created by a %TA.AperFunction command)
///< attached to the D_CODE ///< 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: public:
D_CODE( int num_dcode ); D_CODE( int num_dcode );

View File

@ -32,11 +32,18 @@
#include <common.h> #include <common.h>
#include <macros.h> #include <macros.h>
#include <class_drawpanel.h> #include <class_drawpanel.h>
#include <config_map.h>
#include <gerbview.h> #include <gerbview.h>
#include <gerbview_frame.h> #include <gerbview_frame.h>
#include <gerbview_dialog_display_options_frame_base.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 */ /* Dialog frame to select display options */
@ -45,6 +52,7 @@ class DIALOG_DISPLAY_OPTIONS : public DIALOG_DISPLAY_OPTIONS_BASE
{ {
private: private:
GERBVIEW_FRAME* m_Parent; GERBVIEW_FRAME* m_Parent;
GAL_OPTIONS_PANEL* m_galOptsPanel;
public: public:
@ -79,6 +87,8 @@ DIALOG_DISPLAY_OPTIONS::DIALOG_DISPLAY_OPTIONS( GERBVIEW_FRAME *parent) :
GetSizer()->SetSizeHints( this ); GetSizer()->SetSizeHints( this );
Center(); Center();
m_sdbSizer1OK->SetDefault(); m_sdbSizer1OK->SetDefault();
FinishDialogSettings();
} }
@ -90,23 +100,14 @@ void DIALOG_DISPLAY_OPTIONS::OnCancelButtonClick( wxCommandEvent& event )
void DIALOG_DISPLAY_OPTIONS::initOptDialog( ) 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_PolarDisplay->SetSelection( m_Parent->m_DisplayOptions.m_DisplayPolarCood ? 1 : 0 );
m_BoxUnits->SetSelection( g_UserUnit ? 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 // Show Option Draw Lines. We use DisplayPcbTrackFill as Lines draw option
m_OptDisplayLines->SetSelection( m_Parent->m_DisplayOptions.m_DisplayLinesFill ? 1 : 0 ); m_OptDisplayLines->SetSelection( m_Parent->m_DisplayOptions.m_DisplayLinesFill ? 1 : 0 );
m_OptDisplayFlashedItems->SetSelection( m_Parent->m_DisplayOptions.m_DisplayFlashedItemsFill ? 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_OptDisplayDCodes->SetValue( m_Parent->IsElementVisible( LAYER_DCODES ) );
m_OptZoomNoCenter->SetValue( m_Parent->GetCanvas()->GetEnableZoomNoCenter() ); m_OptZoomNoCenter->SetValue( m_Parent->GetCanvas()->GetEnableZoomNoCenter() );
m_OptMousewheelPan->SetValue( m_Parent->GetCanvas()->GetEnableMousewheelPan() ); m_OptMousewheelPan->SetValue( m_Parent->GetCanvas()->GetEnableMousewheelPan() );
} }
@ -140,18 +139,12 @@ void DIALOG_DISPLAY_OPTIONS::initOptDialog( )
void DIALOG_DISPLAY_OPTIONS::OnOKBUttonClick( wxCommandEvent& event ) void DIALOG_DISPLAY_OPTIONS::OnOKBUttonClick( wxCommandEvent& event )
{ {
auto displayOptions = (GBR_DISPLAY_OPTIONS*) m_Parent->GetDisplayOptions();
m_Parent->m_DisplayOptions.m_DisplayPolarCood = m_Parent->m_DisplayOptions.m_DisplayPolarCood =
(m_PolarDisplay->GetSelection() == 0) ? false : true; (m_PolarDisplay->GetSelection() == 0) ? false : true;
g_UserUnit = (m_BoxUnits->GetSelection() == 0) ? INCHES : MILLIMETRES; 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 ) if( m_OptDisplayLines->GetSelection() == 1 )
m_Parent->m_DisplayOptions.m_DisplayLinesFill = true; m_Parent->m_DisplayOptions.m_DisplayLinesFill = true;
else else
@ -166,7 +159,6 @@ void DIALOG_DISPLAY_OPTIONS::OnOKBUttonClick( wxCommandEvent& event )
m_Parent->m_DisplayOptions.m_DisplayFlashedItemsFill = false; m_Parent->m_DisplayOptions.m_DisplayFlashedItemsFill = false;
} }
if( m_OptDisplayPolygons->GetSelection() == 0 ) if( m_OptDisplayPolygons->GetSelection() == 0 )
m_Parent->m_DisplayOptions.m_DisplayPolygonsFill = false; m_Parent->m_DisplayOptions.m_DisplayPolygonsFill = false;
else else
@ -185,6 +177,16 @@ void DIALOG_DISPLAY_OPTIONS::OnOKBUttonClick( wxCommandEvent& event )
m_Parent->GetCanvas()->SetEnableZoomNoCenter( m_OptZoomNoCenter->GetValue() ); m_Parent->GetCanvas()->SetEnableZoomNoCenter( m_OptZoomNoCenter->GetValue() );
m_Parent->GetCanvas()->SetEnableMousewheelPan( m_OptMousewheelPan->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(); m_Parent->GetCanvas()->Refresh();
EndModal( 1 ); 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/ // http://www.wxformbuilder.org/
// //
// PLEASE DO "NOT" EDIT THIS FILE! // PLEASE DO "NOT" EDIT THIS FILE!
@ -16,8 +16,7 @@ DIALOG_DISPLAY_OPTIONS_BASE::DIALOG_DISPLAY_OPTIONS_BASE( wxWindow* parent, wxWi
wxBoxSizer* bDialogSizer; wxBoxSizer* bDialogSizer;
bDialogSizer = new wxBoxSizer( wxVERTICAL ); bDialogSizer = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bUpperSizer; m_UpperSizer = new wxBoxSizer( wxHORIZONTAL );
bUpperSizer = new wxBoxSizer( wxHORIZONTAL );
wxBoxSizer* bLeftSizer; wxBoxSizer* bLeftSizer;
bLeftSizer = new wxBoxSizer( wxVERTICAL ); bLeftSizer = new wxBoxSizer( wxVERTICAL );
@ -34,42 +33,30 @@ DIALOG_DISPLAY_OPTIONS_BASE::DIALOG_DISPLAY_OPTIONS_BASE( wxWindow* parent, wxWi
m_BoxUnits->SetSelection( 0 ); m_BoxUnits->SetSelection( 0 );
bLeftSizer->Add( m_BoxUnits, 0, wxALL|wxEXPAND, 5 ); bLeftSizer->Add( m_BoxUnits, 0, wxALL|wxEXPAND, 5 );
wxString m_CursorShapeChoices[] = { _("Small cross"), _("Full screen cursor") }; wxString m_OptDisplayFlashedItemsChoices[] = { _("Sketch"), _("Filled") };
int m_CursorShapeNChoices = sizeof( m_CursorShapeChoices ) / sizeof( wxString ); int m_OptDisplayFlashedItemsNChoices = sizeof( m_OptDisplayFlashedItemsChoices ) / sizeof( wxString );
m_CursorShape = new wxRadioBox( this, wxID_ANY, _("Cursor"), wxDefaultPosition, wxDefaultSize, m_CursorShapeNChoices, m_CursorShapeChoices, 1, wxRA_SPECIFY_COLS ); m_OptDisplayFlashedItems = new wxRadioBox( this, wxID_ANY, _("Flashed items"), wxDefaultPosition, wxDefaultSize, m_OptDisplayFlashedItemsNChoices, m_OptDisplayFlashedItemsChoices, 1, wxRA_SPECIFY_COLS );
m_CursorShape->SetSelection( 1 ); m_OptDisplayFlashedItems->SetSelection( 1 );
bLeftSizer->Add( m_CursorShape, 0, wxALL|wxEXPAND, 5 ); 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 = new wxCheckBox( this, wxID_ANY, _("Show D codes"), wxDefaultPosition, wxDefaultSize, 0 );
m_OptDisplayDCodes->SetValue(true); m_OptDisplayDCodes->SetValue(true);
bLeftSizer->Add( m_OptDisplayDCodes, 0, wxALL, 5 ); bLeftSizer->Add( m_OptDisplayDCodes, 0, wxALL, 5 );
bUpperSizer->Add( bLeftSizer, 1, wxALL|wxEXPAND, 5 ); m_UpperSizer->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 );
wxBoxSizer* bRightSizer; wxBoxSizer* bRightSizer;
bRightSizer = new wxBoxSizer( wxVERTICAL ); 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 ); 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 ); m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bDialogSizer->Add( m_staticline1, 0, wxEXPAND|wxLEFT|wxRIGHT, 5 ); bDialogSizer->Add( m_staticline1, 0, wxEXPAND|wxLEFT|wxRIGHT, 5 );

View File

@ -99,9 +99,9 @@
<property name="proportion">1</property> <property name="proportion">1</property>
<object class="wxBoxSizer" expanded="1"> <object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property> <property name="minimum_size"></property>
<property name="name">bUpperSizer</property> <property name="name">m_UpperSizer</property>
<property name="orient">wxHORIZONTAL</property> <property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property> <property name="permission">protected</property>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="1">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property> <property name="flag">wxALL|wxEXPAND</property>
@ -309,7 +309,7 @@
<property name="caption"></property> <property name="caption"></property>
<property name="caption_visible">1</property> <property name="caption_visible">1</property>
<property name="center_pane">0</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="close_button">1</property>
<property name="context_help"></property> <property name="context_help"></property>
<property name="context_menu">1</property> <property name="context_menu">1</property>
@ -324,7 +324,7 @@
<property name="gripper">0</property> <property name="gripper">0</property>
<property name="hidden">0</property> <property name="hidden">0</property>
<property name="id">wxID_ANY</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="majorDimension">1</property>
<property name="max_size"></property> <property name="max_size"></property>
<property name="maximize_button">0</property> <property name="maximize_button">0</property>
@ -333,7 +333,7 @@
<property name="minimize_button">0</property> <property name="minimize_button">0</property>
<property name="minimum_size"></property> <property name="minimum_size"></property>
<property name="moveable">1</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_border">1</property>
<property name="pane_position"></property> <property name="pane_position"></property>
<property name="pane_size"></property> <property name="pane_size"></property>
@ -381,105 +381,6 @@
<event name="OnUpdateUI"></event> <event name="OnUpdateUI"></event>
</object> </object>
</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"> <object class="sizeritem" expanded="1">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property> <property name="flag">wxALL|wxEXPAND</property>
@ -570,96 +471,6 @@
<event name="OnUpdateUI"></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">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"> <object class="sizeritem" expanded="1">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property> <property name="flag">wxALL|wxEXPAND</property>
@ -750,6 +561,94 @@
<event name="OnUpdateUI"></event> <event name="OnUpdateUI"></event>
</object> </object>
</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> </object>
<object class="sizeritem" expanded="1"> <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/ // http://www.wxformbuilder.org/
// //
// PLEASE DO "NOT" EDIT THIS FILE! // PLEASE DO "NOT" EDIT THIS FILE!
@ -38,13 +38,13 @@ class DIALOG_DISPLAY_OPTIONS_BASE : public DIALOG_SHIM
private: private:
protected: protected:
wxBoxSizer* m_UpperSizer;
wxRadioBox* m_PolarDisplay; wxRadioBox* m_PolarDisplay;
wxRadioBox* m_BoxUnits; wxRadioBox* m_BoxUnits;
wxRadioBox* m_CursorShape;
wxCheckBox* m_OptDisplayDCodes;
wxRadioBox* m_OptDisplayLines;
wxRadioBox* m_OptDisplayFlashedItems; wxRadioBox* m_OptDisplayFlashedItems;
wxRadioBox* m_OptDisplayLines;
wxRadioBox* m_OptDisplayPolygons; wxRadioBox* m_OptDisplayPolygons;
wxCheckBox* m_OptDisplayDCodes;
wxRadioBox* m_ShowPageLimits; wxRadioBox* m_ShowPageLimits;
wxCheckBox* m_OptZoomNoCenter; wxCheckBox* m_OptZoomNoCenter;
wxCheckBox* m_OptMousewheelPan; wxCheckBox* m_OptMousewheelPan;

View File

@ -135,7 +135,16 @@ void GERBVIEW_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg )
if( IsShown() ) if( IsShown() )
{ {
m_overlay.Reset(); 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(); overlaydc.Clear();
} }
#endif #endif

View File

@ -43,6 +43,10 @@
#include <class_gerbview_layer_widget.h> #include <class_gerbview_layer_widget.h>
#include <dialog_show_page_borders.h> #include <dialog_show_page_borders.h>
#include <tool/tool_manager.h>
#include <gerbview_painter.h>
#include <view/view.h>
// Event table: // Event table:
@ -83,6 +87,12 @@ BEGIN_EVENT_TABLE( GERBVIEW_FRAME, EDA_DRAW_FRAME )
EVT_MENU( ID_MENU_GERBVIEW_SHOW_HIDE_LAYERS_MANAGER_DIALOG, EVT_MENU( ID_MENU_GERBVIEW_SHOW_HIDE_LAYERS_MANAGER_DIALOG,
GERBVIEW_FRAME::OnSelectOptionToolbar ) GERBVIEW_FRAME::OnSelectOptionToolbar )
EVT_MENU( wxID_PREFERENCES, GERBVIEW_FRAME::InstallGerberOptionsDialog ) 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 // menu Postprocess
EVT_MENU( ID_GERBVIEW_SHOW_LIST_DCODES, GERBVIEW_FRAME::Process_Special_Functions ) 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 // Option toolbar
//EVT_TOOL( ID_NO_TOOL_SELECTED, GERBVIEW_FRAME::Process_Special_Functions ) // mentioned below //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_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_POLAR_COORD, GERBVIEW_FRAME::OnSelectOptionToolbar )
EVT_TOOL( ID_TB_OPTIONS_SHOW_POLYGONS_SKETCH, 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 ) 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( 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, EVT_TOOL_RANGE( ID_TB_OPTIONS_SHOW_GBR_MODE_0, ID_TB_OPTIONS_SHOW_GBR_MODE_2,
GERBVIEW_FRAME::OnSelectDisplayMode ) 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 // Auxiliary horizontal toolbar
EVT_CHOICE( ID_GBR_AUX_TOOLBAR_PCB_CMP_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::Process_Special_Functions ) EVT_CHOICE( ID_GBR_AUX_TOOLBAR_PCB_NET_CHOICE, GERBVIEW_FRAME::OnSelectHighlightChoice )
EVT_CHOICE( ID_GBR_AUX_TOOLBAR_PCB_APERATTRIBUTES_CHOICE, GERBVIEW_FRAME::Process_Special_Functions ) EVT_CHOICE( ID_GBR_AUX_TOOLBAR_PCB_APERATTRIBUTES_CHOICE, GERBVIEW_FRAME::OnSelectHighlightChoice )
// Right click context menu // Right click context menu
EVT_MENU( ID_HIGHLIGHT_CMP_ITEMS, GERBVIEW_FRAME::Process_Special_Functions ) 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_NO_TOOL_SELECTED, GERBVIEW_FRAME::OnUpdateSelectTool )
EVT_UPDATE_UI( ID_ZOOM_SELECTION, 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_POLAR_COORD, GERBVIEW_FRAME::OnUpdateCoordType )
EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH, EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH,
GERBVIEW_FRAME::OnUpdateFlashedItemsDrawMode ) GERBVIEW_FRAME::OnUpdateFlashedItemsDrawMode )
@ -223,6 +237,10 @@ void GERBVIEW_FRAME::Process_Special_Functions( wxCommandEvent& event )
SetNoToolSelected(); SetNoToolSelected();
break; break;
case ID_TB_MEASUREMENT_TOOL:
SetToolID( id, wxCURSOR_DEFAULT, _( "Unsupported tool in this canvas" ) );
break;
case ID_POPUP_CLOSE_CURRENT_TOOL: case ID_POPUP_CLOSE_CURRENT_TOOL:
SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString ); SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
break; break;
@ -246,12 +264,6 @@ void GERBVIEW_FRAME::Process_Special_Functions( wxCommandEvent& event )
HandleBlockEnd( &dc ); HandleBlockEnd( &dc );
break; 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: case ID_HIGHLIGHT_CMP_ITEMS:
if( m_SelComponentBox->SetStringSelection( currItem->GetNetAttributes().m_Cmpref ) ) if( m_SelComponentBox->SetStringSelection( currItem->GetNetAttributes().m_Cmpref ) )
m_canvas->Refresh(); m_canvas->Refresh();
@ -275,8 +287,8 @@ void GERBVIEW_FRAME::Process_Special_Functions( wxCommandEvent& event )
m_SelNetnameBox->SetSelection( 0 ); m_SelNetnameBox->SetSelection( 0 );
m_SelAperAttributesBox->SetSelection( 0 ); m_SelAperAttributesBox->SetSelection( 0 );
if( GetGbrImage( getActiveLayer() ) ) if( GetGbrImage( GetActiveLayer() ) )
GetGbrImage( getActiveLayer() )->m_Selected_Tool = 0; GetGbrImage( GetActiveLayer() )->m_Selected_Tool = 0;
m_canvas->Refresh(); m_canvas->Refresh();
break; 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 ) void GERBVIEW_FRAME::OnSelectActiveDCode( wxCommandEvent& event )
{ {
GERBER_FILE_IMAGE* gerber_image = GetGbrImage( getActiveLayer() ); GERBER_FILE_IMAGE* gerber_image = GetGbrImage( GetActiveLayer() );
if( gerber_image ) if( gerber_image )
{ {
@ -307,11 +350,11 @@ void GERBVIEW_FRAME::OnSelectActiveDCode( wxCommandEvent& event )
void GERBVIEW_FRAME::OnSelectActiveLayer( 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() ) if( m_LayersManager->OnLayerSelected() )
m_canvas->Refresh(); m_canvas->Refresh();
@ -321,7 +364,7 @@ void GERBVIEW_FRAME::OnSelectActiveLayer( wxCommandEvent& event )
void GERBVIEW_FRAME::OnShowGerberSourceFile( wxCommandEvent& event ) void GERBVIEW_FRAME::OnShowGerberSourceFile( wxCommandEvent& event )
{ {
int layer = getActiveLayer(); int layer = GetActiveLayer();
GERBER_FILE_IMAGE* gerber_layer = GetGbrImage( layer ); GERBER_FILE_IMAGE* gerber_layer = GetGbrImage( layer );
if( gerber_layer ) if( gerber_layer )
@ -427,16 +470,19 @@ void GERBVIEW_FRAME::OnSelectOptionToolbar( wxCommandEvent& event )
case ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH: case ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH:
m_DisplayOptions.m_DisplayFlashedItemsFill = not state; m_DisplayOptions.m_DisplayFlashedItemsFill = not state;
applyDisplaySettingsToGAL();
m_canvas->Refresh( true ); m_canvas->Refresh( true );
break; break;
case ID_TB_OPTIONS_SHOW_LINES_SKETCH: case ID_TB_OPTIONS_SHOW_LINES_SKETCH:
m_DisplayOptions.m_DisplayLinesFill = not state; m_DisplayOptions.m_DisplayLinesFill = not state;
applyDisplaySettingsToGAL();
m_canvas->Refresh( true ); m_canvas->Refresh( true );
break; break;
case ID_TB_OPTIONS_SHOW_POLYGONS_SKETCH: case ID_TB_OPTIONS_SHOW_POLYGONS_SKETCH:
m_DisplayOptions.m_DisplayPolygonsFill = not state; m_DisplayOptions.m_DisplayPolygonsFill = not state;
applyDisplaySettingsToGAL();
m_canvas->Refresh( true ); m_canvas->Refresh( true );
break; break;
@ -450,6 +496,18 @@ void GERBVIEW_FRAME::OnSelectOptionToolbar( wxCommandEvent& event )
m_canvas->Refresh( true ); m_canvas->Refresh( true );
break; 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: case ID_TB_OPTIONS_SHOW_LAYERS_MANAGER_VERTICAL_TOOLBAR:
// show/hide auxiliary Vertical layers and visibility manager 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" )); _("Hide &Layers Manager" ) : _("Show &Layers Manager" ));
break; break;
// collect GAL-only tools here:
case ID_TB_MEASUREMENT_TOOL:
SetToolID( id, wxCURSOR_DEFAULT, _( "Unsupported tool in this canvas" ) );
break;
default: default:
wxMessageBox( wxT( "GERBVIEW_FRAME::OnSelectOptionToolbar error" ) ); wxMessageBox( wxT( "GERBVIEW_FRAME::OnSelectOptionToolbar error" ) );
break; break;
@ -472,3 +535,62 @@ void GERBVIEW_FRAME::OnUpdateSelectTool( wxUpdateUIEvent& aEvent )
{ {
aEvent.Check( GetToolId() == aEvent.GetId() ); 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 <class_excellon.h>
#include <kicad_string.h> #include <kicad_string.h>
#include <class_X2_gerber_attributes.h> #include <class_X2_gerber_attributes.h>
#include <view/view.h>
#include <cmath> #include <cmath>
@ -160,7 +161,7 @@ static EXCELLON_CMD excellon_G_CmdList[] =
bool GERBVIEW_FRAME::Read_EXCELLON_File( const wxString& aFullFileName ) bool GERBVIEW_FRAME::Read_EXCELLON_File( const wxString& aFullFileName )
{ {
wxString msg; 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(); GERBER_FILE_IMAGE_LIST* images = GetGerberLayout()->GetImagesList();
EXCELLON_IMAGE* drill_Layer = (EXCELLON_IMAGE*) images->GetGbrImage( layerId ); 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.ListSet( drill_Layer->GetMessages() );
dlg.ShowModal(); 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; return success;
} }
@ -494,7 +510,7 @@ bool EXCELLON_IMAGE::readToolInformation( char*& aText )
// Initialize Dcode to handle this Tool // Initialize Dcode to handle this Tool
// Remember: dcodes are >= FIRST_DCODE // Remember: dcodes are >= FIRST_DCODE
D_CODE* dcode = GetDCODE( iprm + FIRST_DCODE ); D_CODE* dcode = GetDCODEOrCreate( iprm + FIRST_DCODE );
if( dcode == NULL ) if( dcode == NULL )
return false; return false;
@ -532,7 +548,7 @@ bool EXCELLON_IMAGE::Execute_Drill_Command( char*& text )
Execute_EXCELLON_G_Command( text ); Execute_EXCELLON_G_Command( text );
break; break;
case 0: // E.O.L: execute command case 0: // E.O.L: execute command
tool = GetDCODE( m_Current_Tool, false ); tool = GetDCODE( m_Current_Tool );
if( !tool ) if( !tool )
{ {
@ -593,13 +609,13 @@ bool EXCELLON_IMAGE::Select_Tool( char*& text )
dcode_id = TOOLS_MAX_COUNT - 1; dcode_id = TOOLS_MAX_COUNT - 1;
m_Current_Tool = dcode_id; 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 if( currDcode == NULL && tool_id > 0 ) // if the definition is embedded, enter it
{ {
text = startline; // text starts at the beginning of the command text = startline; // text starts at the beginning of the command
readToolInformation( text ); readToolInformation( text );
currDcode = GetDCODE( dcode_id , false ); currDcode = GetDCODE( dcode_id );
} }
if( currDcode ) 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 // Read gerber files: each file is loaded on a new GerbView layer
bool success = true; bool success = true;
int layer = getActiveLayer(); int layer = GetActiveLayer();
// Manage errors when loading files // Manage errors when loading files
wxString msg; wxString msg;
@ -237,7 +237,7 @@ bool GERBVIEW_FRAME::LoadGerberFiles( const wxString& aFullFileName )
m_lastFileName = filename.GetFullPath(); m_lastFileName = filename.GetFullPath();
setActiveLayer( layer, false ); SetActiveLayer( layer, false );
if( Read_GERBER_File( filename.GetFullPath() ) ) if( Read_GERBER_File( filename.GetFullPath() ) )
{ {
@ -263,7 +263,7 @@ bool GERBVIEW_FRAME::LoadGerberFiles( const wxString& aFullFileName )
break; 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: // Synchronize layers tools with actual active layer:
ReFillLayerWidget(); ReFillLayerWidget();
setActiveLayer( getActiveLayer() ); SetActiveLayer( GetActiveLayer() );
m_LayersManager->UpdateLayerIcons(); m_LayersManager->UpdateLayerIcons();
syncLayerBox(); syncLayerBox();
return success; 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 // Read Excellon drill files: each file is loaded on a new GerbView layer
bool success = true; bool success = true;
int layer = getActiveLayer(); int layer = GetActiveLayer();
// Manage errors when loading files // Manage errors when loading files
wxString msg; wxString msg;
@ -340,7 +340,7 @@ bool GERBVIEW_FRAME::LoadExcellonFiles( const wxString& aFullFileName )
m_lastFileName = filename.GetFullPath(); m_lastFileName = filename.GetFullPath();
setActiveLayer( layer, false ); SetActiveLayer( layer, false );
if( Read_EXCELLON_File( filename.GetFullPath() ) ) if( Read_EXCELLON_File( filename.GetFullPath() ) )
{ {
@ -367,7 +367,7 @@ bool GERBVIEW_FRAME::LoadExcellonFiles( const wxString& aFullFileName )
break; 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: // Synchronize layers tools with actual active layer:
ReFillLayerWidget(); ReFillLayerWidget();
setActiveLayer( getActiveLayer() ); SetActiveLayer( GetActiveLayer() );
m_LayersManager->UpdateLayerIcons(); m_LayersManager->UpdateLayerIcons();
syncLayerBox(); syncLayerBox();
@ -454,7 +454,7 @@ bool GERBVIEW_FRAME::unarchiveFiles( const wxString& aFullFileName, REPORTER* aR
continue; continue;
} }
int layer = getActiveLayer(); int layer = GetActiveLayer();
if( layer == NO_AVAILABLE_LAYERS ) if( layer == NO_AVAILABLE_LAYERS )
{ {
@ -531,7 +531,7 @@ bool GERBVIEW_FRAME::unarchiveFiles( const wxString& aFullFileName, REPORTER* aR
gerber_image->m_FileName = fname; gerber_image->m_FileName = fname;
layer = getNextAvailableLayer( layer ); 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: // Synchronize layers tools with actual active layer:
ReFillLayerWidget(); ReFillLayerWidget();
setActiveLayer( getActiveLayer() ); SetActiveLayer( GetActiveLayer() );
m_LayersManager->UpdateLayerIcons(); m_LayersManager->UpdateLayerIcons();
syncLayerBox(); syncLayerBox();

View File

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

View File

@ -49,6 +49,14 @@
#include <class_DCodeSelectionbox.h> #include <class_DCodeSelectionbox.h>
#include <class_gerbview_layer_widget.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 // Config keywords
static const wxString cfgShowPageSizeOption( wxT( "PageSizeOpt" ) ); 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 cfgShowNegativeObjects( wxT( "ShowNegativeObjectsOpt" ) );
static const wxString cfgShowBorderAndTitleBlock( wxT( "ShowBorderAndTitleBlock" ) ); static const wxString cfgShowBorderAndTitleBlock( wxT( "ShowBorderAndTitleBlock" ) );
const wxChar GERBVIEW_FRAME::CANVAS_TYPE_KEY[] = wxT( "canvas_type" );
// Colors for layers and items // Colors for layers and items
COLORS_DESIGN_SETTINGS g_ColorsSettings( FRAME_GERBER ); 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_zipFileHistory.SetBaseId( ID_GERBVIEW_ZIP_FILE1 );
m_jobFileHistory.SetBaseId( ID_GERBVIEW_JOB_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 ) if( m_canvas )
m_canvas->SetEnableBlockCommands( true ); m_canvas->SetEnableBlockCommands( true );
@ -174,22 +194,59 @@ GERBVIEW_FRAME::GERBVIEW_FRAME( KIWAY* aKiway, wxWindow* aParent ):
m_auimgr.AddPane( m_canvas, m_auimgr.AddPane( m_canvas,
wxAuiPaneInfo().Name( wxT( "DrawFrame" ) ).CentrePane() ); wxAuiPaneInfo().Name( wxT( "DrawFrame" ) ).CentrePane() );
if( GetGalCanvas() )
m_auimgr.AddPane( (wxWindow*) GetGalCanvas(),
wxAuiPaneInfo().Name( wxT( "DrawFrameGal" ) ).CentrePane().Hide() );
if( m_messagePanel ) if( m_messagePanel )
m_auimgr.AddPane( m_messagePanel, m_auimgr.AddPane( m_messagePanel,
wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom().Layer( 10 ) ); wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom().Layer( 10 ) );
ReFillLayerWidget(); // this is near end because contents establish size ReFillLayerWidget(); // this is near end because contents establish size
m_LayersManager->ReFillRender(); // Update colors in Render after the config is read
m_auimgr.Update(); m_auimgr.Update();
setActiveLayer( 0, true ); setupTools();
SetActiveLayer( 0, true );
Zoom_Automatique( false ); // Gives a default zoom value Zoom_Automatique( false ); // Gives a default zoom value
UpdateTitleAndInfo(); 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() 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 ) for( unsigned i=0; i<limit; ++i, ++layer )
{ {
setActiveLayer( layer ); SetActiveLayer( layer );
// Try to guess the type of file by its ext // Try to guess the type of file by its ext
// if it is .drl (Kicad files), it is a drill file // 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 ); wxLogDebug( wxT( "GERBVIEW_FRAME::SetElementVisibility(): bad arg %d" ), aItemIdVisible );
} }
applyDisplaySettingsToGAL();
m_LayersManager->SetRenderState( aItemIdVisible, aNewState ); 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 GERBVIEW_FRAME::getNextAvailableLayer( int aLayer ) const
{ {
int layer = aLayer; int layer = aLayer;
@ -427,7 +499,7 @@ int GERBVIEW_FRAME::getNextAvailableLayer( int aLayer ) const
void GERBVIEW_FRAME::syncLayerWidget() void GERBVIEW_FRAME::syncLayerWidget()
{ {
m_LayersManager->SelectLayer( getActiveLayer() ); m_LayersManager->SelectLayer( GetActiveLayer() );
UpdateTitleAndInfo(); UpdateTitleAndInfo();
} }
@ -437,10 +509,10 @@ void GERBVIEW_FRAME::syncLayerBox( bool aRebuildLayerBox )
if( aRebuildLayerBox ) if( aRebuildLayerBox )
m_SelLayerBox->Resync(); m_SelLayerBox->Resync();
m_SelLayerBox->SetSelection( getActiveLayer() ); m_SelLayerBox->SetSelection( GetActiveLayer() );
int dcodeSelected = -1; int dcodeSelected = -1;
GERBER_FILE_IMAGE* gerber = GetGbrImage( getActiveLayer() ); GERBER_FILE_IMAGE* gerber = GetGbrImage( GetActiveLayer() );
if( gerber ) if( gerber )
dcodeSelected = gerber->m_Selected_Tool; dcodeSelected = gerber->m_Selected_Tool;
@ -462,7 +534,7 @@ void GERBVIEW_FRAME::Liste_D_Codes()
wxString Line; wxString Line;
wxArrayString list; wxArrayString list;
double scale = g_UserUnit == INCHES ? IU_PER_MILS * 1000 : IU_PER_MM; 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 ) 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++ ) 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 ) if( pt_D_code == NULL )
continue; continue;
@ -522,7 +594,7 @@ void GERBVIEW_FRAME::Liste_D_Codes()
void GERBVIEW_FRAME::UpdateTitleAndInfo() void GERBVIEW_FRAME::UpdateTitleAndInfo()
{ {
GERBER_FILE_IMAGE* gerber = GetGbrImage( getActiveLayer() ); GERBER_FILE_IMAGE* gerber = GetGbrImage( GetActiveLayer() );
// Display the gerber filename // Display the gerber filename
if( gerber == NULL ) if( gerber == NULL )
@ -532,7 +604,7 @@ void GERBVIEW_FRAME::UpdateTitleAndInfo()
SetStatusText( wxEmptyString, 0 ); SetStatusText( wxEmptyString, 0 );
wxString info; 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 ); m_TextInfo->SetValue( info );
if( EnsureTextCtrlWidth( m_TextInfo, &info ) ) // Resized if( EnsureTextCtrlWidth( m_TextInfo, &info ) ) // Resized
@ -611,14 +683,29 @@ long GERBVIEW_FRAME::GetVisibleLayers() const
void GERBVIEW_FRAME::SetVisibleLayers( long aLayerMask ) 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 bool GERBVIEW_FRAME::IsLayerVisible( int aLayer ) const
{ {
if( ! m_DisplayOptions.m_IsPrinting ) if( ! m_DisplayOptions.m_IsPrinting )
{
if( IsGalCanvasActive() )
aLayer = GERBER_DRAW_LAYER( aLayer );
return m_LayersManager->IsLayerVisible( aLayer ); return m_LayersManager->IsLayerVisible( aLayer );
}
else else
return GetGerberLayout()->IsLayerPrintable( aLayer ); return GetGerberLayout()->IsLayerPrintable( aLayer );
} }
@ -666,6 +753,8 @@ void GERBVIEW_FRAME::SetVisibleElementColor( GERBVIEW_LAYER_ID aItemIdVisible,
break; break;
case LAYER_GERBVIEW_GRID: case LAYER_GERBVIEW_GRID:
// Ensure grid always has low alpha
aColor.a = 0.8;
SetGridColor( aColor ); SetGridColor( aColor );
m_colorsSettings->SetItemColor( aItemIdVisible, aColor ); m_colorsSettings->SetItemColor( aItemIdVisible, aColor );
break; break;
@ -694,21 +783,35 @@ COLOR4D GERBVIEW_FRAME::GetLayerColor( int aLayer ) const
void GERBVIEW_FRAME::SetLayerColor( int aLayer, COLOR4D aColor ) void GERBVIEW_FRAME::SetLayerColor( int aLayer, COLOR4D aColor )
{ {
m_colorsSettings->SetLayerColor( aLayer, aColor ); m_colorsSettings->SetLayerColor( aLayer, aColor );
applyDisplaySettingsToGAL();
} }
int GERBVIEW_FRAME::getActiveLayer() int GERBVIEW_FRAME::GetActiveLayer()
{ {
return ( (GBR_SCREEN*) GetScreen() )->m_Active_Layer; 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; ( (GBR_SCREEN*) GetScreen() )->m_Active_Layer = aLayer;
if( doLayerWidgetUpdate ) 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() EDA_RECT GERBVIEW_FRAME::GetGerberLayoutBoundingBox()
{ {
GetGerberLayout()->ComputeBoundingBox(); GetGerberLayout()->ComputeBoundingBox();
@ -909,3 +1023,113 @@ void GERBVIEW_FRAME::unitsChangeRefresh()
EDA_DRAW_FRAME::unitsChangeRefresh(); EDA_DRAW_FRAME::unitsChangeRefresh();
updateDCodeSelectBox(); 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 <layers_id_colors_and_visibility.h>
#include <gerbview.h> #include <gerbview.h>
#include <convert_to_biu.h>
#include <class_gbr_layout.h> #include <class_gbr_layout.h>
#include <class_gbr_screen.h> #include <class_gbr_screen.h>
#include <class_page_info.h> #include <class_page_info.h>
#include <class_gbr_display_options.h> #include <class_gbr_display_options.h>
#include <class_draw_panel_gal.h>
#include <class_colors_design_settings.h> #include <class_colors_design_settings.h>
extern COLORS_DESIGN_SETTINGS g_ColorsSettings; extern COLORS_DESIGN_SETTINGS g_ColorsSettings;
@ -154,6 +156,9 @@ public:
*/ */
int SelectPCBLayer( int aDefaultLayer, int aOpperLayerCount, bool aNullLayer = false ); int SelectPCBLayer( int aDefaultLayer, int aOpperLayerCount, bool aNullLayer = false );
///> @copydoc EDA_DRAW_FRAME::SetGridColor()
virtual void SetGridColor( COLOR4D aColor ) override;
protected: protected:
GERBER_LAYER_WIDGET* m_LayersManager; GERBER_LAYER_WIDGET* m_LayersManager;
@ -169,6 +174,9 @@ protected:
/// The last filename chosen to be proposed to the user /// The last filename chosen to be proposed to the user
wxString m_lastFileName; wxString m_lastFileName;
///> @copydoc EDA_DRAW_FRAME::forceColorsToLegacy()
virtual void forceColorsToLegacy() override;
public: public:
wxChoice* m_SelComponentBox; // a choice box to display and highlight component graphic items 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 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 wxTextCtrl* m_TextInfo; // a wxTextCtrl used to display some info about
// gerber data (format..) // gerber data (format..)
COLORS_DESIGN_SETTINGS* m_colorsSettings;
private: private:
/// Auxiliary tool bar typically shown below the main tool bar at the top of the /// Auxiliary tool bar typically shown below the main tool bar at the top of the
/// main window. /// main window.
@ -186,7 +196,6 @@ private:
// list of PARAM_CFG_xxx to read/write parameters saved in config // list of PARAM_CFG_xxx to read/write parameters saved in config
PARAM_CFG_ARRAY m_configSettings; PARAM_CFG_ARRAY m_configSettings;
COLORS_DESIGN_SETTINGS* m_colorsSettings;
int m_displayMode; // Gerber images ("layers" in Gerbview) can be drawn: int m_displayMode; // Gerber images ("layers" in Gerbview) can be drawn:
// - in fast mode (write mode) but if there are negative // - in fast mode (write mode) but if there are negative
@ -206,9 +215,15 @@ private:
void updateDCodeSelectBox(); void updateDCodeSelectBox();
virtual void unitsChangeRefresh() override; // See class EDA_DRAW_FRAME 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. // An array string to store warning messages when reading a gerber file.
wxArrayString m_Messages; wxArrayString m_Messages;
/// Updates the GAL with display settings changes
void applyDisplaySettingsToGAL();
public: public:
GERBVIEW_FRAME( KIWAY* aKiway, wxWindow* aParent ); GERBVIEW_FRAME( KIWAY* aKiway, wxWindow* aParent );
~GERBVIEW_FRAME(); ~GERBVIEW_FRAME();
@ -243,6 +258,8 @@ public:
double BestZoom() override; double BestZoom() override;
void UpdateStatusBar() override; void UpdateStatusBar() override;
wxAuiToolBar* GetMainToolBar() { return m_optionsToolBar; }
/** /**
* Function GetZoomLevelIndicator * Function GetZoomLevelIndicator
* returns a human readable value which can be displayed as zoom * returns a human readable value which can be displayed as zoom
@ -332,7 +349,7 @@ public:
/** /**
* Function IsLayerVisible * Function IsLayerVisible
* tests whether a given layer is visible * 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. * @return bool - true if the layer is visible.
*/ */
bool IsLayerVisible( int aLayer ) const; bool IsLayerVisible( int aLayer ) const;
@ -403,17 +420,17 @@ public:
void ReFillLayerWidget(); void ReFillLayerWidget();
/** /**
* Function setActiveLayer * Function SetActiveLayer
* will change the currently active layer to \a aLayer and also * will change the currently active layer to \a aLayer and also
* update the GERBER_LAYER_WIDGET. * 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 * returns the active layer
*/ */
int getActiveLayer(); int GetActiveLayer();
/** /**
* Function getNextAvailableLayer * Function getNextAvailableLayer
@ -432,7 +449,7 @@ public:
/** /**
* Function syncLayerWidget * Function syncLayerWidget
* updates the currently "selected" layer within the GERBER_LAYER_WIDGET. * 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> * <p>
* This function cannot be inline without including layer_widget.h in * This function cannot be inline without including layer_widget.h in
* here and we do not want to do that. * here and we do not want to do that.
@ -443,7 +460,7 @@ public:
* Function syncLayerBox * Function syncLayerBox
* updates the currently "selected" layer within m_SelLayerBox * updates the currently "selected" layer within m_SelLayerBox
* The currently active layer, as defined by the return value of * The currently active layer, as defined by the return value of
* getActiveLayer(). * GetActiveLayer().
* @param aRebuildLayerBox = true to rebuild the layer box * @param aRebuildLayerBox = true to rebuild the layer box
* false to just updates the selection. * false to just updates the selection.
*/ */
@ -479,6 +496,7 @@ public:
void Process_Special_Functions( wxCommandEvent& event ); void Process_Special_Functions( wxCommandEvent& event );
void OnSelectOptionToolbar( wxCommandEvent& event ); void OnSelectOptionToolbar( wxCommandEvent& event );
void OnSelectHighlightChoice( wxCommandEvent& event );
/** /**
* Function OnSelectActiveDCode * Function OnSelectActiveDCode
@ -714,6 +732,34 @@ public:
virtual void PrintPage( wxDC* aDC, LSET aPrintMasklayer, bool aPrintMirrorMode, virtual void PrintPage( wxDC* aDC, LSET aPrintMasklayer, bool aPrintMirrorMode,
void* aData = NULL ) override; 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() DECLARE_EVENT_TABLE()
}; };

View File

@ -50,6 +50,9 @@ enum gerbview_ids
ID_MENU_GERBVIEW_SHOW_HIDE_LAYERS_MANAGER_DIALOG, ID_MENU_GERBVIEW_SHOW_HIDE_LAYERS_MANAGER_DIALOG,
ID_MENU_GERBVIEW_SELECT_PREFERED_EDITOR, 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_CMP_CHOICE,
ID_GBR_AUX_TOOLBAR_PCB_NET_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_0,
ID_TB_OPTIONS_SHOW_GBR_MODE_1, ID_TB_OPTIONS_SHOW_GBR_MODE_1,
ID_TB_OPTIONS_SHOW_GBR_MODE_2, 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 // Right click context menu
ID_HIGHLIGHT_REMOVE_ALL, ID_HIGHLIGHT_REMOVE_ALL,

View File

@ -28,7 +28,7 @@
#include <fctsys.h> #include <fctsys.h>
#include <common.h> #include <common.h>
#include <id.h> #include <gerbview_id.h>
#include <gerbview.h> #include <gerbview.h>
#include <gerbview_frame.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" ), static EDA_HOTKEY HkSwitch2PreviousCopperLayer( _HKI( "Switch to Previous Layer" ),
HK_SWITCH_LAYER_TO_PREVIOUS, '-' ); 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 // List of common hotkey descriptors
EDA_HOTKEY* gerbviewHotkeyList[] = { EDA_HOTKEY* gerbviewHotkeyList[] = {
&HkHelp, &HkHelp,
@ -95,6 +114,9 @@ EDA_HOTKEY* gerbviewHotkeyList[] = {
&HkDCodesDisplayMode, &HkNegativeObjDisplayMode, &HkDCodesDisplayMode, &HkNegativeObjDisplayMode,
&HkSwitch2NextCopperLayer, &HkSwitch2NextCopperLayer,
&HkSwitch2PreviousCopperLayer, &HkSwitch2PreviousCopperLayer,
&HkCanvasDefault,
&HkCanvasOpenGL,
&HkCanvasCairo,
NULL NULL
}; };
@ -205,22 +227,37 @@ bool GERBVIEW_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit
break; break;
case HK_SWITCH_LAYER_TO_PREVIOUS: case HK_SWITCH_LAYER_TO_PREVIOUS:
if( getActiveLayer() > 0 ) if( GetActiveLayer() > 0 )
{ {
setActiveLayer( getActiveLayer() - 1 ); SetActiveLayer( GetActiveLayer() - 1 );
m_LayersManager->OnLayerSelected(); m_LayersManager->OnLayerSelected();
m_canvas->Refresh(); m_canvas->Refresh();
} }
break; break;
case HK_SWITCH_LAYER_TO_NEXT: 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_LayersManager->OnLayerSelected();
m_canvas->Refresh(); m_canvas->Refresh();
} }
break; 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; return true;

View File

@ -42,7 +42,10 @@ enum hotkey_id_commnand {
HK_GBR_NEGATIVE_DISPLAY_ONOFF, HK_GBR_NEGATIVE_DISPLAY_ONOFF,
HK_GBR_DCODE_DISPLAY_ONOFF, HK_GBR_DCODE_DISPLAY_ONOFF,
HK_SWITCH_LAYER_TO_NEXT, 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. // List of hotkey descriptors for GerbView.

View File

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

View File

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

View File

@ -42,6 +42,7 @@ void GERBVIEW_FRAME::ReCreateMenuBar()
{ {
// Create and try to get the current menubar // Create and try to get the current menubar
wxMenuBar* menuBar = GetMenuBar(); wxMenuBar* menuBar = GetMenuBar();
wxString text;
if( !menuBar ) if( !menuBar )
menuBar = new wxMenuBar(); menuBar = new wxMenuBar();
@ -207,6 +208,33 @@ void GERBVIEW_FRAME::ReCreateMenuBar()
// Hotkey submenu // Hotkey submenu
AddHotkeyConfigMenu( configMenu ); 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 // Menu miscellaneous
wxMenu* miscellaneousMenu = new wxMenu; wxMenu* miscellaneousMenu = new wxMenu;

View File

@ -36,13 +36,15 @@
*/ */
void GERBVIEW_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) 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 ); GERBER_DRAW_ITEM* DrawStruct = Locate( aPosition, CURSEUR_OFF_GRILLE );
GetScreen()->SetCurItem( DrawStruct ); GetScreen()->SetCurItem( DrawStruct );
if( DrawStruct == NULL ) if( DrawStruct == NULL )
{ {
GERBER_FILE_IMAGE* gerber = GetGbrImage( getActiveLayer() ); GERBER_FILE_IMAGE* gerber = GetGbrImage( GetActiveLayer() );
if( gerber ) if( gerber )
gerber->DisplayImageInfo( this ); gerber->DisplayImageInfo( this );

View File

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

View File

@ -30,6 +30,7 @@
#include <gerbview_frame.h> #include <gerbview_frame.h>
#include <class_gerber_file_image.h> #include <class_gerber_file_image.h>
#include <class_gerber_file_image_list.h> #include <class_gerber_file_image_list.h>
#include <view/view.h>
#include <html_messagebox.h> #include <html_messagebox.h>
#include <macros.h> #include <macros.h>
@ -40,7 +41,7 @@ bool GERBVIEW_FRAME::Read_GERBER_File( const wxString& GERBER_FullFileName )
{ {
wxString msg; wxString msg;
int layer = getActiveLayer(); int layer = GetActiveLayer();
GERBER_FILE_IMAGE_LIST* images = GetImagesList(); GERBER_FILE_IMAGE_LIST* images = GetImagesList();
GERBER_FILE_IMAGE* gerber = GetGbrImage( layer ); GERBER_FILE_IMAGE* gerber = GetGbrImage( layer );
@ -79,6 +80,23 @@ bool GERBVIEW_FRAME::Read_GERBER_File( const wxString& GERBER_FullFileName )
wxMessageBox( msg ); 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; return true;
} }

View File

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

View File

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

View File

@ -206,9 +206,8 @@ void GERBVIEW_FRAME::ReCreateVToolbar( void )
void GERBVIEW_FRAME::ReCreateOptToolbar( void ) void GERBVIEW_FRAME::ReCreateOptToolbar( void )
{ {
if( m_optionsToolBar ) if( m_optionsToolBar )
return; m_optionsToolBar->Clear();
else
// creation of tool bar options
m_optionsToolBar = new wxAuiToolBar( this, ID_OPT_TOOLBAR, wxDefaultPosition, wxDefaultSize, m_optionsToolBar = new wxAuiToolBar( this, ID_OPT_TOOLBAR, wxDefaultPosition, wxDefaultSize,
wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_VERTICAL ); 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 ), m_optionsToolBar->AddTool( ID_NO_TOOL_SELECTED, wxEmptyString, KiBitmap( cursor_xpm ),
wxEmptyString, wxITEM_CHECK ); 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->AddSeparator();
m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GRID, wxEmptyString, KiBitmap( grid_xpm ), 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 ), KiBitmap( show_dcodenumber_xpm ),
_( "Show dcode number" ), wxITEM_CHECK ); _( "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->AddSeparator();
m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GBR_MODE_0, wxEmptyString, m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GBR_MODE_0, wxEmptyString,
KiBitmap( gbr_select_mode0_xpm ), KiBitmap( gbr_select_mode0_xpm ),
_( "Show layers in raw mode \ _( "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 ); wxITEM_CHECK );
m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GBR_MODE_1, wxEmptyString, m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GBR_MODE_1, wxEmptyString,
KiBitmap( gbr_select_mode1_xpm ), KiBitmap( gbr_select_mode1_xpm ),
_( "Show layers in stacked mode \ _( "Show layers in stacked mode \
(show negative items without artifacts, sometimes slow)" ), (show negative items without artifacts, sometimes slow)" ),
wxITEM_CHECK ); wxITEM_CHECK );
m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GBR_MODE_2, wxEmptyString, m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GBR_MODE_2, wxEmptyString,
KiBitmap( gbr_select_mode2_xpm ), KiBitmap( gbr_select_mode2_xpm ),
_( "Show layers in transparency mode \ _( "Show layers in transparency mode \
(show negative items without artifacts, sometimes slow)" ), (show negative items without artifacts, sometimes slow)" ),
wxITEM_CHECK ); 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: // Tools to show/hide toolbars:
m_optionsToolBar->AddSeparator(); m_optionsToolBar->AddSeparator();
@ -304,7 +330,7 @@ void GERBVIEW_FRAME::updateDCodeSelectBox()
// Add an empty string to deselect net highlight // Add an empty string to deselect net highlight
m_DCodeSelector->Append( NO_SELECTION_STRING ); m_DCodeSelector->Append( NO_SELECTION_STRING );
int layer = getActiveLayer(); int layer = GetActiveLayer();
GERBER_FILE_IMAGE* gerber = GetGbrImage( layer ); GERBER_FILE_IMAGE* gerber = GetGbrImage( layer );
if( !gerber || gerber->GetDcodesCount() == 0 ) if( !gerber || gerber->GetDcodesCount() == 0 )
@ -323,7 +349,7 @@ void GERBVIEW_FRAME::updateDCodeSelectBox()
for( int ii = 0; ii < TOOLS_MAX_COUNT; ii++ ) 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 ) if( dcode == NULL )
continue; continue;
@ -433,7 +459,7 @@ void GERBVIEW_FRAME::updateAperAttributesSelectBox()
for( int ii = 0; ii < TOOLS_MAX_COUNT; ii++ ) 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 ) if( aperture == NULL )
continue; continue;
@ -534,7 +560,7 @@ void GERBVIEW_FRAME::OnUpdateSelectDCode( wxUpdateUIEvent& aEvent )
if( !m_DCodeSelector ) if( !m_DCodeSelector )
return; return;
int layer = getActiveLayer(); int layer = GetActiveLayer();
GERBER_FILE_IMAGE* gerber = GetGbrImage( layer ); GERBER_FILE_IMAGE* gerber = GetGbrImage( layer );
int selected = ( gerber ) ? gerber->m_Selected_Tool : 0; int selected = ( gerber ) ? gerber->m_Selected_Tool : 0;
@ -553,8 +579,8 @@ void GERBVIEW_FRAME::OnUpdateSelectDCode( wxUpdateUIEvent& aEvent )
void GERBVIEW_FRAME::OnUpdateLayerSelectBox( 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: * 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 * 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_LAYER_ID_START = SCH_LAYER_ID_END,
/// GerbView draw layers /// GerbView draw layers and d-code layers
GERBVIEW_LAYER_ID_RESERVED = GERBVIEW_LAYER_ID_START + GERBER_DRAWLAYERS_COUNT, GERBVIEW_LAYER_ID_RESERVED = GERBVIEW_LAYER_ID_START + ( 2 * GERBER_DRAWLAYERS_COUNT ),
LAYER_DCODES, LAYER_DCODES,
LAYER_NEGATIVE_OBJECTS, LAYER_NEGATIVE_OBJECTS,
@ -288,6 +288,12 @@ enum GERBVIEW_LAYER_ID: int
GERBVIEW_LAYER_ID_END 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! /// Must update this if you add any enums after GerbView!
#define LAYER_ID_COUNT GERBVIEW_LAYER_ID_END #define LAYER_ID_COUNT GERBVIEW_LAYER_ID_END
@ -605,6 +611,7 @@ private:
} }
}; };
/** /**
* Function IsValidLayer * Function IsValidLayer
* tests whether a given integer is a valid layer index, i.e. can * 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 ); PCB_LAYER_ID ToLAYER_ID( int aLayer );
#endif // LAYERS_ID_AND_VISIBILITY_H_ #endif // LAYERS_ID_AND_VISIBILITY_H_