GerbView GALification
This commit is contained in:
commit
6e440ffc2d
|
@ -41,6 +41,7 @@ Mateusz Skowroński <skowri[at]gmail-dot-com>
|
||||||
Cheng Sheng <chengsheng[at]google-dot-com> Google Inc.
|
Cheng Sheng <chengsheng[at]google-dot-com> Google Inc.
|
||||||
Kristoffer Ödmark <kristoffer.odmark90[at]gmail-dot-com>
|
Kristoffer Ödmark <kristoffer.odmark90[at]gmail-dot-com>
|
||||||
Oliver Walters <oliver.henry.walters[at]gmail-dot-com>
|
Oliver Walters <oliver.henry.walters[at]gmail-dot-com>
|
||||||
|
Jon Evans <jon[at]craftyjon-dot-com>
|
||||||
|
|
||||||
See also CHANGELOG.txt for contributors.
|
See also CHANGELOG.txt for contributors.
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@
|
||||||
#include <macros.h>
|
#include <macros.h>
|
||||||
#include <id.h>
|
#include <id.h>
|
||||||
#include <class_drawpanel.h>
|
#include <class_drawpanel.h>
|
||||||
#include <class_draw_panel_gal.h>
|
|
||||||
#include <class_base_screen.h>
|
#include <class_base_screen.h>
|
||||||
#include <msgpanel.h>
|
#include <msgpanel.h>
|
||||||
#include <draw_frame.h>
|
#include <draw_frame.h>
|
||||||
|
@ -52,7 +51,6 @@
|
||||||
#include <view/view.h>
|
#include <view/view.h>
|
||||||
#include <view/view_controls.h>
|
#include <view/view_controls.h>
|
||||||
#include <gal/graphics_abstraction_layer.h>
|
#include <gal/graphics_abstraction_layer.h>
|
||||||
#include <gal/gal_display_options.h>
|
|
||||||
#include <tool/tool_manager.h>
|
#include <tool/tool_manager.h>
|
||||||
#include <tool/tool_dispatcher.h>
|
#include <tool/tool_dispatcher.h>
|
||||||
#include <tool/actions.h>
|
#include <tool/actions.h>
|
||||||
|
@ -76,6 +74,9 @@ static const wxString LastGridSizeIdKeyword( wxT( "_LastGridSize" ) );
|
||||||
/// GAL Display Options
|
/// GAL Display Options
|
||||||
static const wxString GalDisplayOptionsKeyword( wxT( "GalDisplayOptions" ) );
|
static const wxString GalDisplayOptionsKeyword( wxT( "GalDisplayOptions" ) );
|
||||||
|
|
||||||
|
const wxChar EDA_DRAW_FRAME::CANVAS_TYPE_KEY[] = wxT( "canvas_type" );
|
||||||
|
|
||||||
|
|
||||||
///@}
|
///@}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1169,6 +1170,44 @@ void EDA_DRAW_FRAME::UseGalCanvas( bool aEnable )
|
||||||
m_galCanvasActive = aEnable;
|
m_galCanvasActive = aEnable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EDA_DRAW_PANEL_GAL::GAL_TYPE EDA_DRAW_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 EDA_DRAW_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;
|
||||||
|
}
|
||||||
|
|
||||||
//-----< BASE_SCREEN API moved here >--------------------------------------------
|
//-----< BASE_SCREEN API moved here >--------------------------------------------
|
||||||
|
|
||||||
wxPoint EDA_DRAW_FRAME::GetCrossHairPosition( bool aInvertY ) const
|
wxPoint EDA_DRAW_FRAME::GetCrossHairPosition( bool aInvertY ) const
|
||||||
|
|
|
@ -391,7 +391,11 @@ bool EDA_DRAW_PANEL_GAL::SwitchBackend( GAL_TYPE aGalType )
|
||||||
m_painter->SetGAL( m_gal );
|
m_painter->SetGAL( m_gal );
|
||||||
|
|
||||||
if( m_view )
|
if( m_view )
|
||||||
|
{
|
||||||
m_view->SetGAL( m_gal );
|
m_view->SetGAL( m_gal );
|
||||||
|
// Note: OpenGL requires reverse draw order when draw priority is enabled
|
||||||
|
m_view->ReverseDrawOrder( aGalType == GAL_TYPE_OPENGL );
|
||||||
|
}
|
||||||
|
|
||||||
m_backend = aGalType;
|
m_backend = aGalType;
|
||||||
|
|
||||||
|
|
|
@ -857,6 +857,12 @@ void CAIRO_GAL::ClearTarget( RENDER_TARGET aTarget )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CAIRO_GAL::SetNegativeDrawMode( bool aSetting )
|
||||||
|
{
|
||||||
|
cairo_set_operator( currentContext, aSetting ? CAIRO_OPERATOR_CLEAR : CAIRO_OPERATOR_OVER );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void CAIRO_GAL::DrawCursor( const VECTOR2D& aCursorPosition )
|
void CAIRO_GAL::DrawCursor( const VECTOR2D& aCursorPosition )
|
||||||
{
|
{
|
||||||
cursorPosition = aCursorPosition;
|
cursorPosition = aCursorPosition;
|
||||||
|
|
|
@ -267,7 +267,8 @@ VIEW::VIEW( bool aIsDynamic ) :
|
||||||
m_gal( NULL ),
|
m_gal( NULL ),
|
||||||
m_dynamic( aIsDynamic ),
|
m_dynamic( aIsDynamic ),
|
||||||
m_useDrawPriority( false ),
|
m_useDrawPriority( false ),
|
||||||
m_nextDrawPriority( 0 )
|
m_nextDrawPriority( 0 ),
|
||||||
|
m_reverseDrawOrder( false )
|
||||||
{
|
{
|
||||||
m_boundary.SetMaximum();
|
m_boundary.SetMaximum();
|
||||||
m_allItems.reserve( 32768 );
|
m_allItems.reserve( 32768 );
|
||||||
|
@ -334,7 +335,7 @@ void VIEW::Add( VIEW_ITEM* aItem, int aDrawPriority )
|
||||||
}
|
}
|
||||||
|
|
||||||
SetVisible( aItem, true );
|
SetVisible( aItem, true );
|
||||||
Update( aItem, KIGFX::ALL );
|
Update( aItem, KIGFX::INITIAL_ADD );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -815,8 +816,10 @@ void VIEW::UpdateAllLayersOrder()
|
||||||
|
|
||||||
struct VIEW::drawItem
|
struct VIEW::drawItem
|
||||||
{
|
{
|
||||||
drawItem( VIEW* aView, int aLayer, bool aUseDrawPriority ) :
|
drawItem( VIEW* aView, int aLayer, bool aUseDrawPriority, bool aReverseDrawOrder ) :
|
||||||
view( aView ), layer( aLayer ), useDrawPriority( aUseDrawPriority )
|
view( aView ), layer( aLayer ),
|
||||||
|
useDrawPriority( aUseDrawPriority ),
|
||||||
|
reverseDrawOrder( aReverseDrawOrder )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -824,7 +827,7 @@ struct VIEW::drawItem
|
||||||
{
|
{
|
||||||
wxASSERT( aItem->viewPrivData() );
|
wxASSERT( aItem->viewPrivData() );
|
||||||
|
|
||||||
// Conditions that have te be fulfilled for an item to be drawn
|
// Conditions that have to be fulfilled for an item to be drawn
|
||||||
bool drawCondition = aItem->viewPrivData()->isRenderable() &&
|
bool drawCondition = aItem->viewPrivData()->isRenderable() &&
|
||||||
aItem->ViewGetLOD( layer, view ) < view->m_scale;
|
aItem->ViewGetLOD( layer, view ) < view->m_scale;
|
||||||
if( !drawCondition )
|
if( !drawCondition )
|
||||||
|
@ -840,10 +843,16 @@ struct VIEW::drawItem
|
||||||
|
|
||||||
void deferredDraw()
|
void deferredDraw()
|
||||||
{
|
{
|
||||||
std::sort( drawItems.begin(), drawItems.end(),
|
if( reverseDrawOrder )
|
||||||
[]( VIEW_ITEM* a, VIEW_ITEM* b ) -> bool {
|
std::sort( drawItems.begin(), drawItems.end(),
|
||||||
return b->viewPrivData()->m_drawPriority < a->viewPrivData()->m_drawPriority;
|
[]( VIEW_ITEM* a, VIEW_ITEM* b ) -> bool {
|
||||||
});
|
return b->viewPrivData()->m_drawPriority < a->viewPrivData()->m_drawPriority;
|
||||||
|
});
|
||||||
|
else
|
||||||
|
std::sort( drawItems.begin(), drawItems.end(),
|
||||||
|
[]( VIEW_ITEM* a, VIEW_ITEM* b ) -> bool {
|
||||||
|
return a->viewPrivData()->m_drawPriority < b->viewPrivData()->m_drawPriority;
|
||||||
|
});
|
||||||
|
|
||||||
for( auto item : drawItems )
|
for( auto item : drawItems )
|
||||||
view->draw( item, layer );
|
view->draw( item, layer );
|
||||||
|
@ -851,7 +860,7 @@ struct VIEW::drawItem
|
||||||
|
|
||||||
VIEW* view;
|
VIEW* view;
|
||||||
int layer, layers[VIEW_MAX_LAYERS];
|
int layer, layers[VIEW_MAX_LAYERS];
|
||||||
bool useDrawPriority;
|
bool useDrawPriority, reverseDrawOrder;
|
||||||
std::vector<VIEW_ITEM*> drawItems;
|
std::vector<VIEW_ITEM*> drawItems;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -862,7 +871,7 @@ void VIEW::redrawRect( const BOX2I& aRect )
|
||||||
{
|
{
|
||||||
if( l->visible && IsTargetDirty( l->target ) && areRequiredLayersEnabled( l->id ) )
|
if( l->visible && IsTargetDirty( l->target ) && areRequiredLayersEnabled( l->id ) )
|
||||||
{
|
{
|
||||||
drawItem drawFunc( this, l->id, m_useDrawPriority );
|
drawItem drawFunc( this, l->id, m_useDrawPriority, m_reverseDrawOrder );
|
||||||
|
|
||||||
m_gal->SetTarget( l->target );
|
m_gal->SetTarget( l->target );
|
||||||
m_gal->SetLayerDepth( l->renderingOrder );
|
m_gal->SetLayerDepth( l->renderingOrder );
|
||||||
|
@ -1067,14 +1076,23 @@ void VIEW::clearGroupCache()
|
||||||
|
|
||||||
void VIEW::invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags )
|
void VIEW::invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags )
|
||||||
{
|
{
|
||||||
// updateLayers updates geometry too, so we do not have to update both of them at the same time
|
if( aUpdateFlags & INITIAL_ADD )
|
||||||
if( aUpdateFlags & LAYERS )
|
|
||||||
{
|
{
|
||||||
updateLayers( aItem );
|
// Don't update layers or bbox, since it was done in VIEW::Add()
|
||||||
|
// Now that we have initialized, set flags to ALL for the code below
|
||||||
|
aUpdateFlags = ALL;
|
||||||
}
|
}
|
||||||
else if( aUpdateFlags & GEOMETRY )
|
else
|
||||||
{
|
{
|
||||||
updateBbox( aItem );
|
// updateLayers updates geometry too, so we do not have to update both of them at the same time
|
||||||
|
if( aUpdateFlags & LAYERS )
|
||||||
|
{
|
||||||
|
updateLayers( aItem );
|
||||||
|
}
|
||||||
|
else if( aUpdateFlags & GEOMETRY )
|
||||||
|
{
|
||||||
|
updateBbox( aItem );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int layers[VIEW_MAX_LAYERS], layers_count;
|
int layers[VIEW_MAX_LAYERS], layers_count;
|
||||||
|
|
|
@ -63,6 +63,14 @@ set( GERBVIEW_SRCS
|
||||||
rs274x.cpp
|
rs274x.cpp
|
||||||
select_layers_to_pcb.cpp
|
select_layers_to_pcb.cpp
|
||||||
toolbars_gerber.cpp
|
toolbars_gerber.cpp
|
||||||
|
|
||||||
|
gerbview_draw_panel_gal.cpp
|
||||||
|
gerbview_painter.cpp
|
||||||
|
|
||||||
|
tools/gerbview_actions.cpp
|
||||||
|
tools/selection_tool.cpp
|
||||||
|
tools/gerbview_control.cpp
|
||||||
|
gerber_collectors.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set( GERBVIEW_EXTRA_SRCS
|
set( GERBVIEW_EXTRA_SRCS
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
|
@ -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] = GetABPosition( points[ii] );
|
points[ii] = p + aOffset;
|
||||||
|
points[ii] = GetABPosition( points[ii] );
|
||||||
}
|
}
|
||||||
|
|
||||||
GRClosedPoly( aClipBox, aDC, points.size(), &points[0], aFilledShape, aColor, aColor );
|
GRClosedPoly( aClipBox, aDC, pointCount, &points[0], aFilledShape, aColor, aColor );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -506,7 +612,7 @@ void GERBER_DRAW_ITEM::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
|
||||||
msg.Printf( _( "D Code %d" ), m_DCode );
|
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,61 @@ 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;
|
||||||
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
@ -271,9 +305,9 @@ void GERBER_LAYER_WIDGET::OnLayerVisible( int aLayer, bool isVisible, bool isFin
|
||||||
long visibleLayers = myframe->GetVisibleLayers();
|
long visibleLayers = myframe->GetVisibleLayers();
|
||||||
|
|
||||||
if( isVisible )
|
if( isVisible )
|
||||||
visibleLayers |= 1 << aLayer;
|
visibleLayers |= 1 << ( aLayer - GERBVIEW_LAYER_ID_START );
|
||||||
else
|
else
|
||||||
visibleLayers &= ~( 1 << aLayer );
|
visibleLayers &= ~( 1 << ( aLayer - GERBVIEW_LAYER_ID_START ) );
|
||||||
|
|
||||||
myframe->SetVisibleLayers( visibleLayers );
|
myframe->SetVisibleLayers( visibleLayers );
|
||||||
|
|
||||||
|
@ -284,13 +318,48 @@ 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 );
|
||||||
myframe->GetCanvas()->Refresh();
|
|
||||||
|
auto galCanvas = myframe->GetGalCanvas();
|
||||||
|
|
||||||
|
if( galCanvas && myframe->IsGalCanvasActive() )
|
||||||
|
{
|
||||||
|
auto view = galCanvas->GetView();
|
||||||
|
view->GetPainter()->GetSettings()->ImportLegacyColors( myframe->m_colorsSettings );
|
||||||
|
view->UpdateLayerColor( aId );
|
||||||
|
// TODO(JE) Why are the below two lines needed? Not needed in pcbnew
|
||||||
|
view->MarkTargetDirty( KIGFX::TARGET_NONCACHED );
|
||||||
|
view->RecacheAllItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( galCanvas && myframe->IsGalCanvasActive() )
|
||||||
|
galCanvas->Refresh();
|
||||||
|
else
|
||||||
|
myframe->GetCanvas()->Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GERBER_LAYER_WIDGET::OnRenderEnable( int aId, bool isEnabled )
|
void GERBER_LAYER_WIDGET::OnRenderEnable( int aId, bool isEnabled )
|
||||||
{
|
{
|
||||||
myframe->SetElementVisibility( (GERBVIEW_LAYER_ID) aId, isEnabled );
|
myframe->SetElementVisibility( (GERBVIEW_LAYER_ID) aId, isEnabled );
|
||||||
myframe->GetCanvas()->Refresh();
|
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----</LAYER_WIDGET callbacks>------------------------------------------
|
//-----</LAYER_WIDGET callbacks>------------------------------------------
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
aBuffer.push_back( aAnchorPos ); // link to outline
|
|
||||||
}
|
}
|
||||||
|
else if( aHoleShape == APT_DEF_RECT_HOLE )
|
||||||
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 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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">"Small cross" "Full screen cursor"</property>
|
<property name="choices">"Sketch" "Filled"</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">"Sketch" "Filled"</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">
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -135,7 +135,18 @@ 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;
|
||||||
|
static_cast<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
|
||||||
|
|
|
@ -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 )
|
||||||
|
@ -148,6 +162,8 @@ BEGIN_EVENT_TABLE( GERBVIEW_FRAME, EDA_DRAW_FRAME )
|
||||||
EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_NEGATIVE_ITEMS, GERBVIEW_FRAME::OnUpdateShowNegativeItems )
|
EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_NEGATIVE_ITEMS, GERBVIEW_FRAME::OnUpdateShowNegativeItems )
|
||||||
EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_LAYERS_MANAGER_VERTICAL_TOOLBAR,
|
EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_LAYERS_MANAGER_VERTICAL_TOOLBAR,
|
||||||
GERBVIEW_FRAME::OnUpdateShowLayerManager )
|
GERBVIEW_FRAME::OnUpdateShowLayerManager )
|
||||||
|
EVT_UPDATE_UI( ID_TB_OPTIONS_DIFF_MODE, GERBVIEW_FRAME::OnUpdateDiffMode )
|
||||||
|
EVT_UPDATE_UI( ID_TB_OPTIONS_HIGH_CONTRAST_MODE, GERBVIEW_FRAME::OnUpdateHighContrastMode )
|
||||||
|
|
||||||
EVT_UPDATE_UI( ID_TOOLBARH_GERBER_SELECT_ACTIVE_DCODE, GERBVIEW_FRAME::OnUpdateSelectDCode )
|
EVT_UPDATE_UI( ID_TOOLBARH_GERBER_SELECT_ACTIVE_DCODE, GERBVIEW_FRAME::OnUpdateSelectDCode )
|
||||||
EVT_UPDATE_UI( ID_TOOLBARH_GERBVIEW_SELECT_ACTIVE_LAYER,
|
EVT_UPDATE_UI( ID_TOOLBARH_GERBVIEW_SELECT_ACTIVE_LAYER,
|
||||||
|
@ -223,6 +239,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 +266,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 +289,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 +302,39 @@ void GERBVIEW_FRAME::Process_Special_Functions( wxCommandEvent& event )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 +351,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 +365,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 +471,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 +497,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 +520,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 +536,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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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,23 @@ 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 +512,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 +550,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 +611,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 )
|
||||||
|
|
|
@ -220,9 +220,12 @@ bool GERBVIEW_FRAME::LoadGerberFiles( const wxString& aFullFileName )
|
||||||
m_mruPath = currentPath;
|
m_mruPath = currentPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the busy cursor
|
||||||
|
wxBusyCursor wait;
|
||||||
|
|
||||||
// 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 +240,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 +266,7 @@ bool GERBVIEW_FRAME::LoadGerberFiles( const wxString& aFullFileName )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
setActiveLayer( layer, false );
|
SetActiveLayer( layer, false );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,7 +281,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 +328,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 +343,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 +370,7 @@ bool GERBVIEW_FRAME::LoadExcellonFiles( const wxString& aFullFileName )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
setActiveLayer( layer, false );
|
SetActiveLayer( layer, false );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,7 +385,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 +457,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 +534,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 +587,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();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gerber_collectors.h"
|
||||||
|
|
||||||
|
const KICAD_T GERBER_COLLECTOR::AllItems[] = {
|
||||||
|
GERBER_IMAGE_LIST_T,
|
||||||
|
GERBER_IMAGE_T,
|
||||||
|
GERBER_DRAW_ITEM_T,
|
||||||
|
EOT
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Inspect
|
||||||
|
* is the examining function within the INSPECTOR which is passed to the
|
||||||
|
* Iterate function. Searches and collects all the objects that the old
|
||||||
|
* function PcbGeneralLocateAndDisplay() would find, except that it keeps all
|
||||||
|
* that it finds and does not do any displaying.
|
||||||
|
*
|
||||||
|
* @param testItem An EDA_ITEM to examine.
|
||||||
|
* @param testData not used here.
|
||||||
|
* @return SEARCH_RESULT - SEARCH_QUIT if the Iterator is to stop the scan,
|
||||||
|
* else SCAN_CONTINUE;
|
||||||
|
*/
|
||||||
|
SEARCH_RESULT GERBER_COLLECTOR::Inspect( EDA_ITEM* testItem, void* testData )
|
||||||
|
{
|
||||||
|
if( testItem->HitTest( m_RefPos ) )
|
||||||
|
Append( testItem );
|
||||||
|
|
||||||
|
return SEARCH_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GERBER_COLLECTOR::Collect( EDA_ITEM* aItem, const KICAD_T aScanList[],
|
||||||
|
const wxPoint& aRefPos/*, const COLLECTORS_GUIDE& aGuide*/ )
|
||||||
|
{
|
||||||
|
Empty(); // empty the collection, primary criteria list
|
||||||
|
|
||||||
|
// remember guide, pass it to Inspect()
|
||||||
|
//SetGuide( &aGuide );
|
||||||
|
|
||||||
|
SetScanTypes( aScanList );
|
||||||
|
|
||||||
|
// remember where the snapshot was taken from and pass refPos to
|
||||||
|
// the Inspect() function.
|
||||||
|
SetRefPos( aRefPos );
|
||||||
|
|
||||||
|
aItem->Visit( m_inspector, NULL, m_ScanTypes );
|
||||||
|
|
||||||
|
SetTimeNow(); // when snapshot was taken
|
||||||
|
|
||||||
|
// record the length of the primary list before concatenating on to it.
|
||||||
|
m_PrimaryLength = m_List.size();
|
||||||
|
}
|
|
@ -0,0 +1,134 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GERBER_COLLECTORS_H
|
||||||
|
#define GERBER_COLLECTORS_H
|
||||||
|
|
||||||
|
#include <class_collector.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class GERBER_COLLECTOR
|
||||||
|
* is intended for use when the right click button is pressed, or when the
|
||||||
|
* plain "arrow" tool is in effect.
|
||||||
|
*/
|
||||||
|
class GERBER_COLLECTOR : public COLLECTOR
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* A place to hold collected objects which don't match precisely the search
|
||||||
|
* criteria, but would be acceptable if nothing else is found.
|
||||||
|
* "2nd" choice, which will be appended to the end of COLLECTOR's prime
|
||||||
|
* "list" at the end of the search.
|
||||||
|
*/
|
||||||
|
std::vector<EDA_ITEM*> m_List2nd;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines which items are to be collected by Inspect()
|
||||||
|
*/
|
||||||
|
//const COLLECTORS_GUIDE* m_Guide;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of items that were originally in the primary list before the
|
||||||
|
* m_List2nd was concatenated onto the end of it.
|
||||||
|
*/
|
||||||
|
int m_PrimaryLength;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A scan list for all selectable gerber items
|
||||||
|
*/
|
||||||
|
static const KICAD_T AllItems[];
|
||||||
|
|
||||||
|
GERBER_COLLECTOR()
|
||||||
|
{
|
||||||
|
//m_Guide = NULL;
|
||||||
|
m_PrimaryLength = 0;
|
||||||
|
SetScanTypes( AllItems );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Empty2nd()
|
||||||
|
{
|
||||||
|
m_List2nd.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*void Append2nd( BOARD_ITEM* item )
|
||||||
|
{
|
||||||
|
m_List2nd.push_back( item );
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function SetGuide
|
||||||
|
* records which COLLECTORS_GUIDE to use.
|
||||||
|
* @param aGuide Which guide to use in the collection.
|
||||||
|
*/
|
||||||
|
//void SetGuide( const COLLECTORS_GUIDE* aGuide ) { m_Guide = aGuide; }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function operator[int]
|
||||||
|
* overloads COLLECTOR::operator[](int) to return a EDA_ITEM* instead of
|
||||||
|
* an EDA_ITEM* type.
|
||||||
|
* @param ndx The index into the list.
|
||||||
|
* @return EDA_ITEM* - or something derived from it, or NULL.
|
||||||
|
*/
|
||||||
|
EDA_ITEM* operator[]( int ndx ) const
|
||||||
|
{
|
||||||
|
if( (unsigned)ndx < (unsigned)GetCount() )
|
||||||
|
return (EDA_ITEM*) m_List[ ndx ];
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function GetPrimaryCount
|
||||||
|
* @return int - The number if items which met the primary search criteria
|
||||||
|
*/
|
||||||
|
int GetPrimaryCount() { return m_PrimaryLength; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Inspect
|
||||||
|
* is the examining function within the INSPECTOR which is passed to the
|
||||||
|
* Iterate function.
|
||||||
|
*
|
||||||
|
* @param testItem An EDA_ITEM to examine.
|
||||||
|
* @param testData is not used in this class.
|
||||||
|
* @return SEARCH_RESULT - SEARCH_QUIT if the Iterator is to stop the scan,
|
||||||
|
* else SCAN_CONTINUE;
|
||||||
|
*/
|
||||||
|
SEARCH_RESULT Inspect( EDA_ITEM* testItem, void* testData ) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Collect
|
||||||
|
* scans an EDA_ITEM using this class's Inspector method, which does the collection.
|
||||||
|
* @param aItem An EDA_ITEM to scan
|
||||||
|
* @param aScanList A list of KICAD_Ts with a terminating EOT, that specs
|
||||||
|
* what is to be collected and the priority order of the resultant
|
||||||
|
* collection in "m_List".
|
||||||
|
* @param aRefPos A wxPoint to use in hit-testing.
|
||||||
|
* @param aGuide The COLLECTORS_GUIDE to use in collecting items.
|
||||||
|
*/
|
||||||
|
void Collect( EDA_ITEM* aItem, const KICAD_T aScanList[],
|
||||||
|
const wxPoint& aRefPos/*, const COLLECTORS_GUIDE& aGuide */);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -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] );
|
||||||
|
|
|
@ -0,0 +1,154 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gerbview_draw_panel_gal.h"
|
||||||
|
#include <view/view.h>
|
||||||
|
#include <view/wx_view_controls.h>
|
||||||
|
#include <gerbview_painter.h>
|
||||||
|
|
||||||
|
#include <class_colors_design_settings.h>
|
||||||
|
#include <gerbview_frame.h>
|
||||||
|
#include <class_gbr_display_options.h>
|
||||||
|
#include <gal/graphics_abstraction_layer.h>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
using namespace std::placeholders;
|
||||||
|
|
||||||
|
|
||||||
|
GERBVIEW_DRAW_PANEL_GAL::GERBVIEW_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWindowId,
|
||||||
|
const wxPoint& aPosition, const wxSize& aSize,
|
||||||
|
KIGFX::GAL_DISPLAY_OPTIONS& aOptions, GAL_TYPE aGalType ) :
|
||||||
|
EDA_DRAW_PANEL_GAL( aParentWindow, aWindowId, aPosition, aSize, aOptions, aGalType )
|
||||||
|
{
|
||||||
|
setDefaultLayerDeps();
|
||||||
|
|
||||||
|
m_painter = new KIGFX::GERBVIEW_PAINTER( m_gal );
|
||||||
|
m_view->SetPainter( m_painter );
|
||||||
|
|
||||||
|
// Load display options (such as filled/outline display of items).
|
||||||
|
auto frame = static_cast< GERBVIEW_FRAME* >( GetParentEDAFrame() );
|
||||||
|
|
||||||
|
if( frame )
|
||||||
|
{
|
||||||
|
auto displ_opts = (GBR_DISPLAY_OPTIONS*) frame->GetDisplayOptions();
|
||||||
|
static_cast<KIGFX::GERBVIEW_RENDER_SETTINGS*>( m_view->GetPainter()->GetSettings() )->LoadDisplayOptions( displ_opts );
|
||||||
|
UseColorScheme( frame->m_colorsSettings );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GERBVIEW_DRAW_PANEL_GAL::~GERBVIEW_DRAW_PANEL_GAL()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GERBVIEW_DRAW_PANEL_GAL::UseColorScheme( const COLORS_DESIGN_SETTINGS* aSettings )
|
||||||
|
{
|
||||||
|
KIGFX::GERBVIEW_RENDER_SETTINGS* rs;
|
||||||
|
rs = static_cast<KIGFX::GERBVIEW_RENDER_SETTINGS*>( m_view->GetPainter()->GetSettings() );
|
||||||
|
rs->ImportLegacyColors( aSettings );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GERBVIEW_DRAW_PANEL_GAL::SetHighContrastLayer( int aLayer )
|
||||||
|
{
|
||||||
|
// Set display settings for high contrast mode
|
||||||
|
KIGFX::RENDER_SETTINGS* rSettings = m_view->GetPainter()->GetSettings();
|
||||||
|
|
||||||
|
SetTopLayer( aLayer );
|
||||||
|
|
||||||
|
rSettings->ClearActiveLayers();
|
||||||
|
rSettings->SetActiveLayer( aLayer );
|
||||||
|
rSettings->SetActiveLayer( GERBER_DCODE_LAYER( aLayer ) );
|
||||||
|
|
||||||
|
m_view->UpdateAllLayersColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GERBVIEW_DRAW_PANEL_GAL::GetMsgPanelInfo( std::vector<MSG_PANEL_ITEM>& aList )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GERBVIEW_DRAW_PANEL_GAL::OnShow()
|
||||||
|
{
|
||||||
|
GERBVIEW_FRAME* frame = dynamic_cast<GERBVIEW_FRAME*>( GetParent() );
|
||||||
|
|
||||||
|
if( frame )
|
||||||
|
{
|
||||||
|
SetTopLayer( frame->GetActiveLayer() );
|
||||||
|
GBR_DISPLAY_OPTIONS* displ_opts = (GBR_DISPLAY_OPTIONS*) frame->GetDisplayOptions();
|
||||||
|
static_cast<KIGFX::GERBVIEW_RENDER_SETTINGS*>(
|
||||||
|
m_view->GetPainter()->GetSettings() )->LoadDisplayOptions( displ_opts );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_view->RecacheAllItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool GERBVIEW_DRAW_PANEL_GAL::SwitchBackend( GAL_TYPE aGalType )
|
||||||
|
{
|
||||||
|
bool rv = EDA_DRAW_PANEL_GAL::SwitchBackend( aGalType );
|
||||||
|
setDefaultLayerDeps();
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GERBVIEW_DRAW_PANEL_GAL::setDefaultLayerDeps()
|
||||||
|
{
|
||||||
|
// caching makes no sense for Cairo and other software renderers
|
||||||
|
auto target = m_backend == GAL_TYPE_OPENGL ? KIGFX::TARGET_CACHED : KIGFX::TARGET_NONCACHED;
|
||||||
|
|
||||||
|
for( int i = 0; i < KIGFX::VIEW::VIEW_MAX_LAYERS; i++ )
|
||||||
|
m_view->SetLayerTarget( i, target );
|
||||||
|
|
||||||
|
// for( int i = GERBVIEW_LAYER_ID_START; i < GERBVIEW_LAYER_ID_RESERVED; i++ )
|
||||||
|
// m_view->SetLayerDisplayOnly( i );
|
||||||
|
|
||||||
|
m_view->SetLayerDisplayOnly( LAYER_DCODES );
|
||||||
|
m_view->SetLayerDisplayOnly( LAYER_NEGATIVE_OBJECTS );
|
||||||
|
m_view->SetLayerDisplayOnly( LAYER_GERBVIEW_GRID );
|
||||||
|
m_view->SetLayerDisplayOnly( LAYER_GERBVIEW_AXES );
|
||||||
|
m_view->SetLayerDisplayOnly( LAYER_GERBVIEW_BACKGROUND );
|
||||||
|
|
||||||
|
m_view->SetLayerTarget( LAYER_GP_OVERLAY, KIGFX::TARGET_OVERLAY );
|
||||||
|
m_view->SetLayerDisplayOnly( LAYER_GP_OVERLAY );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GERBVIEW_DRAW_PANEL_GAL::SetTopLayer( int aLayer )
|
||||||
|
{
|
||||||
|
m_view->ClearTopLayers();
|
||||||
|
|
||||||
|
for( int i = 0; i < GERBER_DRAWLAYERS_COUNT; ++i )
|
||||||
|
{
|
||||||
|
m_view->SetLayerOrder( GERBER_DCODE_LAYER( GERBER_DRAW_LAYER( i ) ), 2 * i );
|
||||||
|
m_view->SetLayerOrder( i, ( 2 * i ) + 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_view->SetTopLayer( aLayer );
|
||||||
|
|
||||||
|
// Move DCODE layer to the top
|
||||||
|
m_view->SetTopLayer( GERBER_DCODE_LAYER( aLayer ) );
|
||||||
|
|
||||||
|
m_view->SetTopLayer( LAYER_GP_OVERLAY );
|
||||||
|
|
||||||
|
m_view->UpdateAllLayersOrder();
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GERBVIEW_DRAW_PANEL_GAL_H_
|
||||||
|
#define GERBVIEW_DRAW_PANEL_GAL_H_
|
||||||
|
|
||||||
|
#include <class_draw_panel_gal.h>
|
||||||
|
|
||||||
|
class COLORS_DESIGN_SETTINGS;
|
||||||
|
|
||||||
|
|
||||||
|
class GERBVIEW_DRAW_PANEL_GAL : public EDA_DRAW_PANEL_GAL
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GERBVIEW_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWindowId, const wxPoint& aPosition,
|
||||||
|
const wxSize& aSize, KIGFX::GAL_DISPLAY_OPTIONS& aOptions,
|
||||||
|
GAL_TYPE aGalType = GAL_TYPE_OPENGL );
|
||||||
|
|
||||||
|
virtual ~GERBVIEW_DRAW_PANEL_GAL();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function UseColorScheme
|
||||||
|
* Applies layer color settings.
|
||||||
|
* @param aSettings are the new settings.
|
||||||
|
*/
|
||||||
|
void UseColorScheme( const COLORS_DESIGN_SETTINGS* aSettings );
|
||||||
|
|
||||||
|
///> @copydoc EDA_DRAW_PANEL_GAL::SetHighContrastLayer()
|
||||||
|
virtual void SetHighContrastLayer( int aLayer ) override;
|
||||||
|
|
||||||
|
///> @copydoc EDA_DRAW_PANEL_GAL::GetMsgPanelInfo()
|
||||||
|
void GetMsgPanelInfo( std::vector<MSG_PANEL_ITEM>& aList ) override;
|
||||||
|
|
||||||
|
///> @copydoc EDA_DRAW_PANEL_GAL::OnShow()
|
||||||
|
void OnShow() override;
|
||||||
|
|
||||||
|
bool SwitchBackend( GAL_TYPE aGalType ) override;
|
||||||
|
|
||||||
|
///> @copydoc EDA_DRAW_PANEL_GAL::SetTopLayer
|
||||||
|
virtual void SetTopLayer( int aLayer ) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
///> Sets rendering targets & dependencies for layers.
|
||||||
|
void setDefaultLayerDeps();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* GERBVIEW_DRAW_PANEL_GAL_H_ */
|
|
@ -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" ) );
|
||||||
|
@ -87,6 +95,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 +192,60 @@ 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 +284,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 +456,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 +498,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 +508,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 +533,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 +556,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 +593,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 +603,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
|
||||||
|
@ -605,20 +676,51 @@ bool GERBVIEW_FRAME::IsElementVisible( GERBVIEW_LAYER_ID aItemIdVisible ) const
|
||||||
|
|
||||||
long GERBVIEW_FRAME::GetVisibleLayers() const
|
long GERBVIEW_FRAME::GetVisibleLayers() const
|
||||||
{
|
{
|
||||||
return -1; // TODO
|
long layerMask = 0;
|
||||||
|
|
||||||
|
if( auto canvas = GetGalCanvas() )
|
||||||
|
{
|
||||||
|
// NOTE: This assumes max 32 drawlayers!
|
||||||
|
for( int i = 0; i < GERBER_DRAWLAYERS_COUNT; i++ )
|
||||||
|
{
|
||||||
|
if( canvas->GetView()->IsLayerVisible( GERBER_DRAW_LAYER( i ) ) )
|
||||||
|
layerMask |= ( 1 << i );
|
||||||
|
}
|
||||||
|
|
||||||
|
return layerMask;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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 +768,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 +798,34 @@ 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
|
||||||
|
|
||||||
|
// NOTE(JE) The next two calls are slow (scales with number of items)
|
||||||
|
GetGalCanvas()->SetTopLayer( GERBER_DRAW_LAYER( aLayer ) );
|
||||||
|
GetGalCanvas()->SetHighContrastLayer( GERBER_DRAW_LAYER( aLayer ) );
|
||||||
|
|
||||||
|
GetGalCanvas()->Refresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -784,6 +901,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 +1037,75 @@ 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#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>
|
||||||
|
@ -154,6 +155,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 +173,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 +186,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 +195,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 +214,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 +257,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 +348,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 +419,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 +448,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 +459,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.
|
||||||
*/
|
*/
|
||||||
|
@ -480,6 +496,9 @@ public:
|
||||||
void Process_Special_Functions( wxCommandEvent& event );
|
void Process_Special_Functions( wxCommandEvent& event );
|
||||||
void OnSelectOptionToolbar( wxCommandEvent& event );
|
void OnSelectOptionToolbar( wxCommandEvent& event );
|
||||||
|
|
||||||
|
/// Handles the changing of the highlighted component/net/attribute
|
||||||
|
void OnSelectHighlightChoice( wxCommandEvent& event );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function OnSelectActiveDCode
|
* Function OnSelectActiveDCode
|
||||||
* Selects the active DCode for the current active layer.
|
* Selects the active DCode for the current active layer.
|
||||||
|
@ -545,6 +564,8 @@ public:
|
||||||
void OnUpdateShowLayerManager( wxUpdateUIEvent& aEvent );
|
void OnUpdateShowLayerManager( wxUpdateUIEvent& aEvent );
|
||||||
void OnUpdateSelectDCode( wxUpdateUIEvent& aEvent );
|
void OnUpdateSelectDCode( wxUpdateUIEvent& aEvent );
|
||||||
void OnUpdateLayerSelectBox( wxUpdateUIEvent& aEvent );
|
void OnUpdateLayerSelectBox( wxUpdateUIEvent& aEvent );
|
||||||
|
void OnUpdateDiffMode( wxUpdateUIEvent& aEvent );
|
||||||
|
void OnUpdateHighContrastMode( wxUpdateUIEvent& aEvent );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function BlockCommand
|
* Function BlockCommand
|
||||||
|
@ -714,6 +735,19 @@ 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 );
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -0,0 +1,566 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 Jon Evans <jon@craftyjon.com>
|
||||||
|
* Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <class_colors_design_settings.h>
|
||||||
|
|
||||||
|
#include <gerbview_painter.h>
|
||||||
|
#include <gal/graphics_abstraction_layer.h>
|
||||||
|
#include <convert_basic_shapes_to_polygon.h>
|
||||||
|
#include <convert_to_biu.h>
|
||||||
|
#include <gerbview.h>
|
||||||
|
|
||||||
|
#include <class_gerber_draw_item.h>
|
||||||
|
#include <class_gerber_file_image.h>
|
||||||
|
|
||||||
|
using namespace KIGFX;
|
||||||
|
|
||||||
|
GERBVIEW_RENDER_SETTINGS::GERBVIEW_RENDER_SETTINGS()
|
||||||
|
{
|
||||||
|
m_backgroundColor = COLOR4D( 0.0, 0.0, 0.0, 1.0 );
|
||||||
|
|
||||||
|
m_spotFill = true;
|
||||||
|
m_lineFill = true;
|
||||||
|
m_polygonFill = true;
|
||||||
|
m_showNegativeItems = false;
|
||||||
|
m_showCodes = false;
|
||||||
|
m_diffMode = true;
|
||||||
|
|
||||||
|
m_componentHighlightString = "";
|
||||||
|
m_netHighlightString = "";
|
||||||
|
m_attributeHighlightString = "";
|
||||||
|
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GERBVIEW_RENDER_SETTINGS::ImportLegacyColors( const COLORS_DESIGN_SETTINGS* aSettings )
|
||||||
|
{
|
||||||
|
for( int i = GERBVIEW_LAYER_ID_START;
|
||||||
|
i < GERBVIEW_LAYER_ID_START + GERBER_DRAWLAYERS_COUNT; i++ )
|
||||||
|
{
|
||||||
|
COLOR4D baseColor = aSettings->GetLayerColor( i );
|
||||||
|
m_layerColors[i] = baseColor;
|
||||||
|
m_layerColorsHi[i] = baseColor.Brightened( 0.5 );
|
||||||
|
m_layerColorsSel[i] = baseColor.Brightened( 0.8 );
|
||||||
|
m_layerColorsDark[i] = baseColor.Darkened( 0.25 );
|
||||||
|
}
|
||||||
|
|
||||||
|
for( int i = LAYER_DCODES; i < GERBVIEW_LAYER_ID_END; i++ )
|
||||||
|
m_layerColors[i] = aSettings->GetLayerColor( i );
|
||||||
|
|
||||||
|
for( int i = GAL_LAYER_ID_START; i < GAL_LAYER_ID_END; i++ )
|
||||||
|
m_layerColors[i] = aSettings->GetLayerColor( i );
|
||||||
|
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GERBVIEW_RENDER_SETTINGS::LoadDisplayOptions( const GBR_DISPLAY_OPTIONS* aOptions )
|
||||||
|
{
|
||||||
|
if( aOptions == NULL )
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_spotFill = aOptions->m_DisplayFlashedItemsFill;
|
||||||
|
m_lineFill = aOptions->m_DisplayLinesFill;
|
||||||
|
m_polygonFill = aOptions->m_DisplayPolygonsFill;
|
||||||
|
m_showNegativeItems = aOptions->m_DisplayNegativeObjects;
|
||||||
|
m_showCodes = aOptions->m_DisplayDCodes;
|
||||||
|
m_diffMode = aOptions->m_DiffMode;
|
||||||
|
m_hiContrastEnabled = aOptions->m_HighContrastMode;
|
||||||
|
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const COLOR4D& GERBVIEW_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) const
|
||||||
|
{
|
||||||
|
const GERBER_DRAW_ITEM* item = static_cast<const GERBER_DRAW_ITEM*>( aItem );
|
||||||
|
|
||||||
|
// All DCODE layers stored under a single color setting
|
||||||
|
if( IsDCodeLayer( aLayer ) )
|
||||||
|
return m_layerColors[ LAYER_DCODES ];
|
||||||
|
|
||||||
|
if( item )
|
||||||
|
{
|
||||||
|
if( item->IsSelected() )
|
||||||
|
return m_layerColorsSel[aLayer];
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !m_netHighlightString.IsEmpty() &&
|
||||||
|
m_netHighlightString == item->GetNetAttributes().m_Netname )
|
||||||
|
return m_layerColorsHi[aLayer];
|
||||||
|
|
||||||
|
if( !m_componentHighlightString.IsEmpty() &&
|
||||||
|
m_componentHighlightString == item->GetNetAttributes().m_Cmpref )
|
||||||
|
return m_layerColorsHi[aLayer];
|
||||||
|
|
||||||
|
if( !m_attributeHighlightString.IsEmpty() && item->GetDcodeDescr() &&
|
||||||
|
m_attributeHighlightString == item->GetDcodeDescr()->m_AperFunction )
|
||||||
|
return m_layerColorsHi[aLayer];
|
||||||
|
|
||||||
|
// Return grayish color for non-highlighted layers in the high contrast mode
|
||||||
|
if( m_hiContrastEnabled && m_activeLayers.count( aLayer ) == 0)
|
||||||
|
return m_hiContrastColor;
|
||||||
|
|
||||||
|
// Catch the case when highlight and high-contraste modes are enabled
|
||||||
|
// and we are drawing a not highlighted track
|
||||||
|
if( m_highlightEnabled )
|
||||||
|
return m_layerColorsDark[aLayer];
|
||||||
|
|
||||||
|
// No special modificators enabled
|
||||||
|
return m_layerColors[aLayer];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GERBVIEW_PAINTER::GERBVIEW_PAINTER( GAL* aGal ) :
|
||||||
|
PAINTER( aGal )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO(JE): Pull up to PAINTER?
|
||||||
|
int GERBVIEW_PAINTER::getLineThickness( int aActualThickness ) const
|
||||||
|
{
|
||||||
|
// if items have 0 thickness, draw them with the outline
|
||||||
|
// width, otherwise respect the set value (which, no matter
|
||||||
|
// how small will produce something)
|
||||||
|
if( aActualThickness == 0 )
|
||||||
|
return m_gerbviewSettings.m_outlineWidth;
|
||||||
|
|
||||||
|
return aActualThickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool GERBVIEW_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer )
|
||||||
|
{
|
||||||
|
const EDA_ITEM* item = static_cast<const EDA_ITEM*>( aItem );
|
||||||
|
|
||||||
|
// the "cast" applied in here clarifies which overloaded draw() is called
|
||||||
|
switch( item->Type() )
|
||||||
|
{
|
||||||
|
case GERBER_DRAW_ITEM_T:
|
||||||
|
draw( static_cast<GERBER_DRAW_ITEM*>( const_cast<EDA_ITEM*>( item ) ), aLayer );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Painter does not know how to draw the object
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO(JE) aItem can't be const because of GetDcodeDescr()
|
||||||
|
// Probably that can be refactored in GERBER_DRAW_ITEM to allow const here.
|
||||||
|
void GERBVIEW_PAINTER::draw( /*const*/ GERBER_DRAW_ITEM* aItem, int aLayer )
|
||||||
|
{
|
||||||
|
VECTOR2D start( aItem->GetABPosition( aItem->m_Start ) ); // TODO(JE) Getter
|
||||||
|
VECTOR2D end( aItem->GetABPosition( aItem->m_End ) ); // TODO(JE) Getter
|
||||||
|
int width = aItem->m_Size.x; // TODO(JE) Getter
|
||||||
|
bool isFilled = true;
|
||||||
|
COLOR4D color;
|
||||||
|
// TODO(JE) This doesn't actually work properly for ImageNegative
|
||||||
|
bool isNegative = ( aItem->GetLayerPolarity() ^ aItem->m_GerberImageFile->m_ImageNegative );
|
||||||
|
|
||||||
|
// Draw DCODEs if enabled
|
||||||
|
if( IsDCodeLayer( aLayer ) )
|
||||||
|
{
|
||||||
|
if( !m_gerbviewSettings.m_showCodes )
|
||||||
|
return;
|
||||||
|
|
||||||
|
wxString codeText;
|
||||||
|
VECTOR2D textPosition;
|
||||||
|
double textSize;
|
||||||
|
|
||||||
|
if( aItem->GetDcodeDescr() )
|
||||||
|
textSize = aItem->GetDcodeDescr()->GetShapeDim( aItem ) / 3.0;
|
||||||
|
else
|
||||||
|
textSize = std::min( aItem->m_Size.x, aItem->m_Size.y ) / 2.0;
|
||||||
|
|
||||||
|
if( aItem->m_Shape == GBR_ARC )
|
||||||
|
{
|
||||||
|
textPosition = start;
|
||||||
|
}
|
||||||
|
else if( aItem->m_Flashed )
|
||||||
|
{
|
||||||
|
BOX2I bb = aItem->ViewBBox();
|
||||||
|
textPosition = bb.Centre();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
textPosition.x = ( start.x + end.x ) / 2;
|
||||||
|
textPosition.y = ( start.y + end.y ) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
color = m_gerbviewSettings.GetColor( aItem, aLayer );
|
||||||
|
codeText.Printf( wxT( "D%d" ), aItem->m_DCode );
|
||||||
|
|
||||||
|
m_gal->SetIsStroke( true );
|
||||||
|
m_gal->SetIsFill( false );
|
||||||
|
m_gal->SetStrokeColor( color );
|
||||||
|
m_gal->SetFillColor( COLOR4D( 0, 0, 0, 0 ) );
|
||||||
|
m_gal->SetLineWidth( 2 );
|
||||||
|
m_gal->SetFontBold( false );
|
||||||
|
m_gal->SetFontItalic( false );
|
||||||
|
m_gal->SetTextMirrored( false );
|
||||||
|
m_gal->SetGlyphSize( VECTOR2D( textSize, textSize) );
|
||||||
|
m_gal->SetHorizontalJustify( GR_TEXT_HJUSTIFY_CENTER );
|
||||||
|
m_gal->SetVerticalJustify( GR_TEXT_VJUSTIFY_CENTER );
|
||||||
|
m_gal->BitmapText( codeText, textPosition, 0 );
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
color = m_gerbviewSettings.GetColor( aItem, aLayer );
|
||||||
|
|
||||||
|
// TODO: Should brightened color be a preference?
|
||||||
|
if( aItem->IsBrightened() )
|
||||||
|
color = COLOR4D( 0.0, 1.0, 0.0, 0.75 );
|
||||||
|
|
||||||
|
if( isNegative )
|
||||||
|
{
|
||||||
|
if( m_gerbviewSettings.m_showNegativeItems )
|
||||||
|
color = m_gerbviewSettings.GetLayerColor( LAYER_NEGATIVE_OBJECTS );
|
||||||
|
else
|
||||||
|
color = COLOR4D( 0, 0, 0, 0 );
|
||||||
|
}
|
||||||
|
else if( m_gerbviewSettings.m_diffMode )
|
||||||
|
{
|
||||||
|
color.a = 0.75;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_gal->SetNegativeDrawMode( isNegative );
|
||||||
|
m_gal->SetStrokeColor( color );
|
||||||
|
m_gal->SetFillColor( color );
|
||||||
|
m_gal->SetIsFill( isFilled );
|
||||||
|
m_gal->SetIsStroke( !isFilled );
|
||||||
|
|
||||||
|
switch( aItem->m_Shape )
|
||||||
|
{
|
||||||
|
case GBR_POLYGON:
|
||||||
|
{
|
||||||
|
isFilled = m_gerbviewSettings.m_polygonFill;
|
||||||
|
m_gal->SetIsFill( isFilled );
|
||||||
|
m_gal->SetIsStroke( !isFilled );
|
||||||
|
|
||||||
|
if( isNegative && !isFilled )
|
||||||
|
{
|
||||||
|
m_gal->SetNegativeDrawMode( false );
|
||||||
|
m_gal->SetStrokeColor( GetSettings()->GetColor( aItem, aLayer ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !isFilled )
|
||||||
|
m_gal->SetLineWidth( m_gerbviewSettings.m_outlineWidth );
|
||||||
|
|
||||||
|
SHAPE_POLY_SET absolutePolygon = aItem->m_Polygon;
|
||||||
|
|
||||||
|
for( auto it = absolutePolygon.Iterate( 0 ); it; ++it )
|
||||||
|
*it = aItem->GetABPosition( *it );
|
||||||
|
|
||||||
|
if( !isFilled )
|
||||||
|
m_gal->DrawPolyline( absolutePolygon.COutline( 0 ) );
|
||||||
|
else
|
||||||
|
m_gal->DrawPolygon( absolutePolygon );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case GBR_CIRCLE:
|
||||||
|
{
|
||||||
|
isFilled = m_gerbviewSettings.m_lineFill;
|
||||||
|
double radius = GetLineLength( aItem->m_Start, aItem->m_End );
|
||||||
|
m_gal->DrawCircle( start, radius );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case GBR_ARC:
|
||||||
|
{
|
||||||
|
isFilled = m_gerbviewSettings.m_lineFill;
|
||||||
|
|
||||||
|
// Gerber arcs are 3-point (start, center, end)
|
||||||
|
// GAL needs center, radius, start angle, end angle
|
||||||
|
double radius = GetLineLength( aItem->m_Start, aItem->m_ArcCentre );
|
||||||
|
VECTOR2D center = aItem->GetABPosition( aItem->m_ArcCentre );
|
||||||
|
VECTOR2D startVec = VECTOR2D( aItem->GetABPosition( aItem->m_Start ) ) - center;
|
||||||
|
VECTOR2D endVec = VECTOR2D( aItem->GetABPosition( aItem->m_End ) ) - center;
|
||||||
|
|
||||||
|
m_gal->SetIsFill( isFilled );
|
||||||
|
m_gal->SetIsStroke( !isFilled );
|
||||||
|
m_gal->SetLineWidth( isFilled ? width : m_gerbviewSettings.m_outlineWidth );
|
||||||
|
|
||||||
|
double startAngle = startVec.Angle();
|
||||||
|
double endAngle = endVec.Angle();
|
||||||
|
|
||||||
|
if( endAngle >= M_PI )
|
||||||
|
endAngle *= -1;
|
||||||
|
|
||||||
|
// 360-degree arcs are stored in the file with start equal to end
|
||||||
|
if( aItem->m_Start == aItem->m_End )
|
||||||
|
{
|
||||||
|
startAngle = 0;
|
||||||
|
endAngle = 2 * M_PI;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_gal->DrawArcSegment( center, radius, startAngle, endAngle, width );
|
||||||
|
|
||||||
|
// Arc Debugging
|
||||||
|
// m_gal->SetLineWidth( 5 );
|
||||||
|
// m_gal->SetStrokeColor( COLOR4D( 0.0, 1.0, 0.0, 1.0 ) );
|
||||||
|
// m_gal->DrawLine( center, aItem->GetABPosition( aItem->m_Start ) );
|
||||||
|
// m_gal->SetStrokeColor( COLOR4D( 1.0, 0.0, 0.0, 1.0 ) );
|
||||||
|
// m_gal->DrawLine( center, aItem->GetABPosition( aItem->m_End ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case GBR_SPOT_CIRCLE:
|
||||||
|
case GBR_SPOT_RECT:
|
||||||
|
case GBR_SPOT_OVAL:
|
||||||
|
case GBR_SPOT_POLY:
|
||||||
|
case GBR_SPOT_MACRO:
|
||||||
|
{
|
||||||
|
isFilled = m_gerbviewSettings.m_spotFill;
|
||||||
|
drawFlashedShape( aItem, isFilled );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case GBR_SEGMENT:
|
||||||
|
{
|
||||||
|
/* Plot a line from m_Start to m_End.
|
||||||
|
* Usually, a round pen is used, but some gerber files use a rectangular pen
|
||||||
|
* In fact, any aperture can be used to plot a line.
|
||||||
|
* currently: only a square pen is handled (I believe using a polygon gives a strange plot).
|
||||||
|
*/
|
||||||
|
isFilled = m_gerbviewSettings.m_lineFill;
|
||||||
|
m_gal->SetIsFill( isFilled );
|
||||||
|
m_gal->SetIsStroke( !isFilled );
|
||||||
|
|
||||||
|
if( isNegative && !isFilled )
|
||||||
|
m_gal->SetStrokeColor( GetSettings()->GetColor( aItem, aLayer ) );
|
||||||
|
|
||||||
|
// TODO(JE) Refactor this to allow const aItem
|
||||||
|
D_CODE* code = aItem->GetDcodeDescr();
|
||||||
|
if( code && code->m_Shape == APT_RECT )
|
||||||
|
{
|
||||||
|
if( aItem->m_Polygon.OutlineCount() == 0 )
|
||||||
|
aItem->ConvertSegmentToPolygon();
|
||||||
|
drawPolygon( aItem, aItem->m_Polygon, isFilled );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( !isFilled )
|
||||||
|
m_gal->SetLineWidth( m_gerbviewSettings.m_outlineWidth );
|
||||||
|
|
||||||
|
m_gal->DrawSegment( start, end, width );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
wxASSERT_MSG( false, wxT( "GERBER_DRAW_ITEM shape is unknown!" ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable for bounding box debugging
|
||||||
|
#if 0
|
||||||
|
const BOX2I& bb = aItem->ViewBBox();
|
||||||
|
m_gal->SetIsStroke( true );
|
||||||
|
m_gal->SetIsFill( true );
|
||||||
|
m_gal->SetLineWidth( 3 );
|
||||||
|
m_gal->SetStrokeColor( COLOR4D(0.9, 0.9, 0, 0.4) );
|
||||||
|
m_gal->SetFillColor( COLOR4D(0.9, 0.9, 0, 0.1) );
|
||||||
|
m_gal->DrawRectangle( bb.GetOrigin(), bb.GetEnd() );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GERBVIEW_PAINTER::drawPolygon( GERBER_DRAW_ITEM* aParent,
|
||||||
|
SHAPE_POLY_SET aPolygon,
|
||||||
|
bool aFilled )
|
||||||
|
{
|
||||||
|
for( auto it = aPolygon.Iterate( 0 ); it; ++it )
|
||||||
|
*it = aParent->GetABPosition( *it );
|
||||||
|
|
||||||
|
if( !m_gerbviewSettings.m_polygonFill )
|
||||||
|
m_gal->SetLineWidth( m_gerbviewSettings.m_outlineWidth );
|
||||||
|
|
||||||
|
if( !aFilled )
|
||||||
|
{
|
||||||
|
for( int i = 0; i < aPolygon.OutlineCount(); i++ )
|
||||||
|
m_gal->DrawPolyline( aPolygon.COutline( i ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_gal->DrawPolygon( aPolygon );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GERBVIEW_PAINTER::drawFlashedShape( GERBER_DRAW_ITEM* aItem, bool aFilled )
|
||||||
|
{
|
||||||
|
D_CODE* code = aItem->GetDcodeDescr();
|
||||||
|
|
||||||
|
wxASSERT_MSG( code, wxT( "drawFlashedShape: Item has no D_CODE!" ) );
|
||||||
|
|
||||||
|
m_gal->SetIsFill( aFilled );
|
||||||
|
m_gal->SetIsStroke( !aFilled );
|
||||||
|
m_gal->SetLineWidth( m_gerbviewSettings.m_outlineWidth );
|
||||||
|
|
||||||
|
switch( aItem->m_Shape )
|
||||||
|
{
|
||||||
|
case GBR_SPOT_CIRCLE:
|
||||||
|
{
|
||||||
|
int radius = code->m_Size.x >> 1;
|
||||||
|
VECTOR2D start( aItem->GetABPosition( aItem->m_Start ) );
|
||||||
|
|
||||||
|
if( !aFilled )
|
||||||
|
{
|
||||||
|
m_gal->DrawCircle( start, radius );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( code->m_DrillShape == APT_DEF_NO_HOLE )
|
||||||
|
{
|
||||||
|
m_gal->DrawCircle( start, radius );
|
||||||
|
}
|
||||||
|
else // rectangular hole
|
||||||
|
{
|
||||||
|
if( code->m_Polygon.OutlineCount() == 0 )
|
||||||
|
code->ConvertShapeToPolygon();
|
||||||
|
|
||||||
|
SHAPE_POLY_SET poly = code->m_Polygon;
|
||||||
|
poly.Move( aItem->m_Start );
|
||||||
|
|
||||||
|
drawPolygon( aItem, poly, aFilled );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case GBR_SPOT_RECT:
|
||||||
|
{
|
||||||
|
wxPoint codeStart;
|
||||||
|
wxPoint aShapePos = aItem->m_Start;
|
||||||
|
codeStart.x = aShapePos.x - code->m_Size.x / 2;
|
||||||
|
codeStart.y = aShapePos.y - code->m_Size.y / 2;
|
||||||
|
wxPoint codeEnd = codeStart + code->m_Size;
|
||||||
|
codeStart = aItem->GetABPosition( codeStart );
|
||||||
|
codeEnd = aItem->GetABPosition( codeEnd );
|
||||||
|
|
||||||
|
if( !aFilled || code->m_DrillShape == APT_DEF_NO_HOLE )
|
||||||
|
{
|
||||||
|
m_gal->DrawRectangle( VECTOR2D( codeStart ), VECTOR2D( codeEnd ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( code->m_Polygon.OutlineCount() == 0 )
|
||||||
|
code->ConvertShapeToPolygon();
|
||||||
|
|
||||||
|
SHAPE_POLY_SET poly = code->m_Polygon;
|
||||||
|
poly.Move( aItem->m_Start );
|
||||||
|
|
||||||
|
drawPolygon( aItem, poly, aFilled );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case GBR_SPOT_OVAL:
|
||||||
|
{
|
||||||
|
int radius = 0;
|
||||||
|
|
||||||
|
wxPoint codeStart = aItem->m_Start;
|
||||||
|
wxPoint codeEnd = aItem->m_Start;
|
||||||
|
|
||||||
|
if( code->m_Size.x > code->m_Size.y ) // horizontal oval
|
||||||
|
{
|
||||||
|
int delta = (code->m_Size.x - code->m_Size.y) / 2;
|
||||||
|
codeStart.x -= delta;
|
||||||
|
codeEnd.x += delta;
|
||||||
|
radius = code->m_Size.y;
|
||||||
|
}
|
||||||
|
else // horizontal oval
|
||||||
|
{
|
||||||
|
int delta = (code->m_Size.y - code->m_Size.x) / 2;
|
||||||
|
codeStart.y -= delta;
|
||||||
|
codeEnd.y += delta;
|
||||||
|
radius = code->m_Size.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
codeStart = aItem->GetABPosition( codeStart );
|
||||||
|
codeEnd = aItem->GetABPosition( codeEnd );
|
||||||
|
|
||||||
|
if( !aFilled || code->m_DrillShape == APT_DEF_NO_HOLE )
|
||||||
|
{
|
||||||
|
m_gal->DrawSegment( codeStart, codeEnd, radius );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( code->m_Polygon.OutlineCount() == 0 )
|
||||||
|
code->ConvertShapeToPolygon();
|
||||||
|
|
||||||
|
SHAPE_POLY_SET poly = code->m_Polygon;
|
||||||
|
poly.Move( aItem->m_Start );
|
||||||
|
|
||||||
|
drawPolygon( aItem, poly, aFilled );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case GBR_SPOT_POLY:
|
||||||
|
{
|
||||||
|
if( code->m_Polygon.OutlineCount() == 0 )
|
||||||
|
code->ConvertShapeToPolygon();
|
||||||
|
|
||||||
|
SHAPE_POLY_SET poly = code->m_Polygon;
|
||||||
|
poly.Move( aItem->m_Start );
|
||||||
|
|
||||||
|
drawPolygon( aItem, poly, aFilled );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case GBR_SPOT_MACRO:
|
||||||
|
drawApertureMacro( aItem, aFilled );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
wxASSERT_MSG( false, wxT( "Unknown Gerber flashed shape!" ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GERBVIEW_PAINTER::drawApertureMacro( GERBER_DRAW_ITEM* aParent, bool aFilled )
|
||||||
|
{
|
||||||
|
D_CODE* code = aParent->GetDcodeDescr();
|
||||||
|
APERTURE_MACRO* macro = code->GetMacro();
|
||||||
|
|
||||||
|
SHAPE_POLY_SET* macroShape = macro->GetApertureMacroShape( aParent, aParent->m_Start );
|
||||||
|
|
||||||
|
if( !m_gerbviewSettings.m_polygonFill )
|
||||||
|
m_gal->SetLineWidth( m_gerbviewSettings.m_outlineWidth );
|
||||||
|
|
||||||
|
if( !aFilled )
|
||||||
|
{
|
||||||
|
for( int i = 0; i < macroShape->OutlineCount(); i++ )
|
||||||
|
m_gal->DrawPolyline( macroShape->COutline( i ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_gal->DrawPolygon( *macroShape );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const double GERBVIEW_RENDER_SETTINGS::MAX_FONT_SIZE = Millimeter2iu( 10.0 );
|
|
@ -0,0 +1,203 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 Jon Evans <jon@craftyjon.com>
|
||||||
|
* Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GERBVIEW_PAINTER_H
|
||||||
|
#define __GERBVIEW_PAINTER_H
|
||||||
|
|
||||||
|
#include <layers_id_colors_and_visibility.h>
|
||||||
|
#include <painter.h>
|
||||||
|
#include <class_gbr_display_options.h>
|
||||||
|
#include <geometry/shape_poly_set.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
|
||||||
|
class EDA_ITEM;
|
||||||
|
class COLORS_DESIGN_SETTINGS;
|
||||||
|
|
||||||
|
class GERBER_DRAW_ITEM;
|
||||||
|
class GERBER_FILE_IMAGE;
|
||||||
|
|
||||||
|
|
||||||
|
namespace KIGFX
|
||||||
|
{
|
||||||
|
class GAL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class GERBVIEW_RENDER_SETTINGS
|
||||||
|
* Stores GerbView specific render settings.
|
||||||
|
*/
|
||||||
|
class GERBVIEW_RENDER_SETTINGS : public RENDER_SETTINGS
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
friend class GERBVIEW_PAINTER;
|
||||||
|
|
||||||
|
GERBVIEW_RENDER_SETTINGS();
|
||||||
|
|
||||||
|
/// @copydoc RENDER_SETTINGS::ImportLegacyColors()
|
||||||
|
void ImportLegacyColors( const COLORS_DESIGN_SETTINGS* aSettings ) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function LoadDisplayOptions
|
||||||
|
* Loads settings related to display options
|
||||||
|
* @param aOptions are settings that you want to use for displaying items.
|
||||||
|
*/
|
||||||
|
void LoadDisplayOptions( const GBR_DISPLAY_OPTIONS* aOptions );
|
||||||
|
|
||||||
|
/// @copydoc RENDER_SETTINGS::GetColor()
|
||||||
|
virtual const COLOR4D& GetColor( const VIEW_ITEM* aItem, int aLayer ) const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function GetLayerColor
|
||||||
|
* Returns the color used to draw a layer.
|
||||||
|
* @param aLayer is the layer number.
|
||||||
|
*/
|
||||||
|
inline const COLOR4D& GetLayerColor( int aLayer ) const
|
||||||
|
{
|
||||||
|
return m_layerColors[aLayer];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function SetLayerColor
|
||||||
|
* Changes the color used to draw a layer.
|
||||||
|
* @param aLayer is the layer number.
|
||||||
|
* @param aColor is the new color.
|
||||||
|
*/
|
||||||
|
inline void SetLayerColor( int aLayer, const COLOR4D& aColor )
|
||||||
|
{
|
||||||
|
m_layerColors[aLayer] = aColor;
|
||||||
|
|
||||||
|
update(); // recompute other shades of the color
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool IsSpotFill() const
|
||||||
|
{
|
||||||
|
return m_spotFill;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool IsLineFill() const
|
||||||
|
{
|
||||||
|
return m_lineFill;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool IsPolygonFill() const
|
||||||
|
{
|
||||||
|
return m_polygonFill;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool IsShowNegativeItems() const
|
||||||
|
{
|
||||||
|
return m_showNegativeItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool IsShowCodes() const
|
||||||
|
{
|
||||||
|
return m_showCodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool IsDiffMode() const
|
||||||
|
{
|
||||||
|
return m_diffMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If set to anything but an empty string, will highlight items with matching component
|
||||||
|
wxString m_componentHighlightString;
|
||||||
|
|
||||||
|
/// If set to anything but an empty string, will highlight items with matching net
|
||||||
|
wxString m_netHighlightString;
|
||||||
|
|
||||||
|
/// If set to anything but an empty string, will highlight items with matching attribute
|
||||||
|
wxString m_attributeHighlightString;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// Flag determining if spots should be drawn with fill
|
||||||
|
bool m_spotFill;
|
||||||
|
|
||||||
|
/// Flag determining if lines should be drawn with fill
|
||||||
|
bool m_lineFill;
|
||||||
|
|
||||||
|
/// Flag determining if polygons should be drawn with fill
|
||||||
|
bool m_polygonFill;
|
||||||
|
|
||||||
|
/// Flag determining if negative items should be drawn with a "ghost" color
|
||||||
|
bool m_showNegativeItems;
|
||||||
|
|
||||||
|
/// Flag determining if D-Codes should be drawn
|
||||||
|
bool m_showCodes;
|
||||||
|
|
||||||
|
/// Flag determining if layers should be rendered in "diff" mode
|
||||||
|
bool m_diffMode;
|
||||||
|
|
||||||
|
/// Maximum font size for D-Codes and other strings
|
||||||
|
static const double MAX_FONT_SIZE;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class GERBVIEW_PAINTER
|
||||||
|
* Contains methods for drawing GerbView-specific items.
|
||||||
|
*/
|
||||||
|
class GERBVIEW_PAINTER : public PAINTER
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GERBVIEW_PAINTER( GAL* aGal );
|
||||||
|
|
||||||
|
/// @copydoc PAINTER::ApplySettings()
|
||||||
|
virtual void ApplySettings( const RENDER_SETTINGS* aSettings ) override
|
||||||
|
{
|
||||||
|
m_gerbviewSettings = *static_cast<const GERBVIEW_RENDER_SETTINGS*>( aSettings );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @copydoc PAINTER::GetSettings()
|
||||||
|
virtual GERBVIEW_RENDER_SETTINGS* GetSettings() override
|
||||||
|
{
|
||||||
|
return &m_gerbviewSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @copydoc PAINTER::Draw()
|
||||||
|
virtual bool Draw( const VIEW_ITEM* aItem, int aLayer ) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
GERBVIEW_RENDER_SETTINGS m_gerbviewSettings;
|
||||||
|
|
||||||
|
// Drawing functions
|
||||||
|
void draw( /*const*/ GERBER_DRAW_ITEM* aVia, int aLayer );
|
||||||
|
|
||||||
|
/// Helper routine to draw a polygon
|
||||||
|
void drawPolygon( GERBER_DRAW_ITEM* aParent, SHAPE_POLY_SET aPolygon, bool aFilled );
|
||||||
|
|
||||||
|
/// Helper to draw a flashed shape (aka spot)
|
||||||
|
void drawFlashedShape( GERBER_DRAW_ITEM* aItem, bool aFilled );
|
||||||
|
|
||||||
|
/// Helper to draw an aperture macro shape
|
||||||
|
void drawApertureMacro( GERBER_DRAW_ITEM* aParent, bool aFilled );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function getLineThickness()
|
||||||
|
* Get the thickness to draw for a line (e.g. 0 thickness lines
|
||||||
|
* get a minimum value).
|
||||||
|
* @param aActualThickness line own thickness
|
||||||
|
* @return the thickness to draw
|
||||||
|
*/
|
||||||
|
int getLineThickness( int aActualThickness ) const;
|
||||||
|
};
|
||||||
|
} // namespace KIGFX
|
||||||
|
|
||||||
|
#endif /* __GERBVIEW_PAINTER_H */
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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'" ),
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -206,11 +206,10 @@ 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 );
|
|
||||||
|
|
||||||
// TODO: these can be moved to the 'proper' vertical toolbar if and when there are
|
// TODO: these can be moved to the 'proper' vertical toolbar if and when there are
|
||||||
// actual tools to put there. That, or I'll get around to implementing configurable
|
// actual tools to put there. That, or I'll get around to implementing configurable
|
||||||
|
@ -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
|
||||||
m_optionsToolBar->AddSeparator();
|
if( !IsGalCanvasActive() )
|
||||||
m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GBR_MODE_0, wxEmptyString,
|
{
|
||||||
KiBitmap( gbr_select_mode0_xpm ),
|
m_optionsToolBar->AddSeparator();
|
||||||
_( "Show layers in raw mode \
|
m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GBR_MODE_0, wxEmptyString,
|
||||||
(could have problems with negative items when more than one gerber file is shown)" ),
|
KiBitmap( gbr_select_mode0_xpm ),
|
||||||
wxITEM_CHECK );
|
_( "Show layers in raw mode \
|
||||||
m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GBR_MODE_1, wxEmptyString,
|
(could have problems with negative items when more than one gerber file is shown)" ),
|
||||||
KiBitmap( gbr_select_mode1_xpm ),
|
wxITEM_CHECK );
|
||||||
_( "Show layers in stacked mode \
|
m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GBR_MODE_1, wxEmptyString,
|
||||||
(show negative items without artifacts, sometimes slow)" ),
|
KiBitmap( gbr_select_mode1_xpm ),
|
||||||
wxITEM_CHECK );
|
_( "Show layers in stacked mode \
|
||||||
m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GBR_MODE_2, wxEmptyString,
|
(show negative items without artifacts, sometimes slow)" ),
|
||||||
KiBitmap( gbr_select_mode2_xpm ),
|
wxITEM_CHECK );
|
||||||
_( "Show layers in transparency mode \
|
m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GBR_MODE_2, wxEmptyString,
|
||||||
(show negative items without artifacts, sometimes slow)" ),
|
KiBitmap( gbr_select_mode2_xpm ),
|
||||||
wxITEM_CHECK );
|
_( "Show layers in transparency mode \
|
||||||
|
(show negative items without artifacts, sometimes slow)" ),
|
||||||
|
wxITEM_CHECK );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_optionsToolBar->AddTool( ID_TB_OPTIONS_DIFF_MODE, wxEmptyString,
|
||||||
|
KiBitmap( gbr_select_mode2_xpm ),
|
||||||
|
_( "Show layers in diff (compare) mode" ),
|
||||||
|
wxITEM_CHECK );
|
||||||
|
|
||||||
|
m_optionsToolBar->AddTool( ID_TB_OPTIONS_HIGH_CONTRAST_MODE, wxEmptyString,
|
||||||
|
KiBitmap( contrast_mode_xpm ),
|
||||||
|
_( "Enable high contrast display mode" ),
|
||||||
|
wxITEM_CHECK );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Tools to show/hide toolbars:
|
// 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;
|
||||||
|
@ -515,6 +541,18 @@ void GERBVIEW_FRAME::OnUpdateShowNegativeItems( wxUpdateUIEvent& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GERBVIEW_FRAME::OnUpdateDiffMode( wxUpdateUIEvent& aEvent )
|
||||||
|
{
|
||||||
|
aEvent.Check( m_DisplayOptions.m_DiffMode );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GERBVIEW_FRAME::OnUpdateHighContrastMode( wxUpdateUIEvent& aEvent )
|
||||||
|
{
|
||||||
|
aEvent.Check( m_DisplayOptions.m_HighContrastMode );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void GERBVIEW_FRAME::OnUpdateShowLayerManager( wxUpdateUIEvent& aEvent )
|
void GERBVIEW_FRAME::OnUpdateShowLayerManager( wxUpdateUIEvent& aEvent )
|
||||||
{
|
{
|
||||||
aEvent.Check( m_show_layer_manager_tools );
|
aEvent.Check( m_show_layer_manager_tools );
|
||||||
|
@ -534,7 +572,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 +591,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() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 Jon Evans <jon@craftyjon.com>
|
||||||
|
* Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <tool/tool_manager.h>
|
||||||
|
#include <tool/common_tools.h>
|
||||||
|
#include <tool/zoom_tool.h>
|
||||||
|
#include <gerbview_id.h>
|
||||||
|
|
||||||
|
#include "gerbview_actions.h"
|
||||||
|
#include "selection_tool.h"
|
||||||
|
#include "gerbview_control.h"
|
||||||
|
|
||||||
|
|
||||||
|
void GERBVIEW_ACTIONS::RegisterAllTools( TOOL_MANAGER* aToolManager )
|
||||||
|
{
|
||||||
|
aToolManager->RegisterTool( new COMMON_TOOLS );
|
||||||
|
aToolManager->RegisterTool( new GERBVIEW_SELECTION_TOOL );
|
||||||
|
aToolManager->RegisterTool( new GERBVIEW_CONTROL );
|
||||||
|
aToolManager->RegisterTool( new ZOOM_TOOL );
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::optional<TOOL_EVENT> GERBVIEW_ACTIONS::TranslateLegacyId( int aId )
|
||||||
|
{
|
||||||
|
switch( aId )
|
||||||
|
{
|
||||||
|
case ID_ZOOM_IN: // toolbar button "Zoom In"
|
||||||
|
return ACTIONS::zoomInCenter.MakeEvent();
|
||||||
|
|
||||||
|
case ID_ZOOM_OUT: // toolbar button "Zoom In"
|
||||||
|
return ACTIONS::zoomOutCenter.MakeEvent();
|
||||||
|
|
||||||
|
case ID_ZOOM_PAGE: // toolbar button "Fit on Screen"
|
||||||
|
return ACTIONS::zoomFitScreen.MakeEvent();
|
||||||
|
|
||||||
|
case ID_ZOOM_SELECTION:
|
||||||
|
return ACTIONS::zoomTool.MakeEvent();
|
||||||
|
|
||||||
|
case ID_TB_MEASUREMENT_TOOL:
|
||||||
|
return GERBVIEW_ACTIONS::measureTool.MakeEvent();
|
||||||
|
|
||||||
|
case ID_NO_TOOL_SELECTED:
|
||||||
|
return GERBVIEW_ACTIONS::selectionTool.MakeEvent();
|
||||||
|
|
||||||
|
case ID_HIGHLIGHT_REMOVE_ALL:
|
||||||
|
return GERBVIEW_ACTIONS::highlightClear.MakeEvent();
|
||||||
|
|
||||||
|
case ID_HIGHLIGHT_CMP_ITEMS:
|
||||||
|
return GERBVIEW_ACTIONS::highlightComponent.MakeEvent();
|
||||||
|
|
||||||
|
case ID_HIGHLIGHT_NET_ITEMS:
|
||||||
|
return GERBVIEW_ACTIONS::highlightNet.MakeEvent();
|
||||||
|
|
||||||
|
case ID_HIGHLIGHT_APER_ATTRIBUTE_ITEMS:
|
||||||
|
return GERBVIEW_ACTIONS::highlightAttribute.MakeEvent();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return boost::optional<TOOL_EVENT>();
|
||||||
|
}
|
|
@ -0,0 +1,139 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 Jon Evans <jon@craftyjon.com>
|
||||||
|
* Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GERBVIEW_ACTIONS_H
|
||||||
|
#define __GERBVIEW_ACTIONS_H
|
||||||
|
|
||||||
|
#include <tool/tool_action.h>
|
||||||
|
#include <tool/actions.h>
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
|
class TOOL_EVENT;
|
||||||
|
class TOOL_MANAGER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class GERBVIEW_ACTIONS
|
||||||
|
*
|
||||||
|
* Gathers all the actions that are shared by tools. The instance of GERBVIEW_ACTIONS is created
|
||||||
|
* inside of ACTION_MANAGER object that registers the actions.
|
||||||
|
*/
|
||||||
|
class GERBVIEW_ACTIONS : public ACTIONS
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Selection Tool
|
||||||
|
/// Activation of the selection tool
|
||||||
|
static TOOL_ACTION selectionActivate;
|
||||||
|
|
||||||
|
/// Select a single item under the cursor position
|
||||||
|
static TOOL_ACTION selectionCursor;
|
||||||
|
|
||||||
|
/// Clears the current selection
|
||||||
|
static TOOL_ACTION selectionClear;
|
||||||
|
|
||||||
|
/// Selects an item (specified as the event parameter).
|
||||||
|
static TOOL_ACTION selectItem;
|
||||||
|
|
||||||
|
/// Unselects an item (specified as the event parameter).
|
||||||
|
static TOOL_ACTION unselectItem;
|
||||||
|
|
||||||
|
/// Activation of the edit tool
|
||||||
|
static TOOL_ACTION properties;
|
||||||
|
|
||||||
|
static TOOL_ACTION measureTool;
|
||||||
|
|
||||||
|
// View controls
|
||||||
|
static TOOL_ACTION zoomIn;
|
||||||
|
static TOOL_ACTION zoomOut;
|
||||||
|
static TOOL_ACTION zoomInCenter;
|
||||||
|
static TOOL_ACTION zoomOutCenter;
|
||||||
|
static TOOL_ACTION zoomCenter;
|
||||||
|
static TOOL_ACTION zoomFitScreen;
|
||||||
|
static TOOL_ACTION zoomPreset;
|
||||||
|
|
||||||
|
// Display modes
|
||||||
|
static TOOL_ACTION zoneDisplayEnable;
|
||||||
|
static TOOL_ACTION zoneDisplayDisable;
|
||||||
|
static TOOL_ACTION zoneDisplayOutlines;
|
||||||
|
static TOOL_ACTION highContrastMode;
|
||||||
|
static TOOL_ACTION highContrastInc;
|
||||||
|
static TOOL_ACTION highContrastDec;
|
||||||
|
|
||||||
|
// Layer control
|
||||||
|
static TOOL_ACTION layerPrev;
|
||||||
|
static TOOL_ACTION layerAlphaInc;
|
||||||
|
static TOOL_ACTION layerAlphaDec;
|
||||||
|
static TOOL_ACTION layerToggle;
|
||||||
|
|
||||||
|
static TOOL_ACTION layerChanged; // notification
|
||||||
|
|
||||||
|
// Grid control
|
||||||
|
static TOOL_ACTION gridFast1;
|
||||||
|
static TOOL_ACTION gridFast2;
|
||||||
|
static TOOL_ACTION gridNext;
|
||||||
|
static TOOL_ACTION gridPrev;
|
||||||
|
static TOOL_ACTION gridSetOrigin;
|
||||||
|
static TOOL_ACTION gridResetOrigin;
|
||||||
|
static TOOL_ACTION gridPreset;
|
||||||
|
|
||||||
|
/// Cursor control with keyboard
|
||||||
|
static TOOL_ACTION cursorUp;
|
||||||
|
static TOOL_ACTION cursorDown;
|
||||||
|
static TOOL_ACTION cursorLeft;
|
||||||
|
static TOOL_ACTION cursorRight;
|
||||||
|
|
||||||
|
static TOOL_ACTION cursorUpFast;
|
||||||
|
static TOOL_ACTION cursorDownFast;
|
||||||
|
static TOOL_ACTION cursorLeftFast;
|
||||||
|
static TOOL_ACTION cursorRightFast;
|
||||||
|
|
||||||
|
static TOOL_ACTION cursorClick;
|
||||||
|
static TOOL_ACTION cursorDblClick;
|
||||||
|
|
||||||
|
// Panning with keyboard
|
||||||
|
static TOOL_ACTION panUp;
|
||||||
|
static TOOL_ACTION panDown;
|
||||||
|
static TOOL_ACTION panLeft;
|
||||||
|
static TOOL_ACTION panRight;
|
||||||
|
|
||||||
|
// Miscellaneous
|
||||||
|
static TOOL_ACTION selectionTool;
|
||||||
|
static TOOL_ACTION zoomTool;
|
||||||
|
static TOOL_ACTION panTool;
|
||||||
|
static TOOL_ACTION pickerTool;
|
||||||
|
static TOOL_ACTION resetCoords;
|
||||||
|
static TOOL_ACTION switchCursor;
|
||||||
|
static TOOL_ACTION switchUnits;
|
||||||
|
static TOOL_ACTION showHelp;
|
||||||
|
static TOOL_ACTION toBeDone;
|
||||||
|
|
||||||
|
// Highlighting
|
||||||
|
static TOOL_ACTION highlightClear;
|
||||||
|
static TOOL_ACTION highlightNet;
|
||||||
|
static TOOL_ACTION highlightComponent;
|
||||||
|
static TOOL_ACTION highlightAttribute;
|
||||||
|
|
||||||
|
///> @copydoc COMMON_ACTIONS::TranslateLegacyId()
|
||||||
|
virtual boost::optional<TOOL_EVENT> TranslateLegacyId( int aId ) override;
|
||||||
|
|
||||||
|
///> @copydoc COMMON_ACTIONS::RegisterAllTools()
|
||||||
|
virtual void RegisterAllTools( TOOL_MANAGER* aToolManager ) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __GERBVIEW_ACTIONS_H
|
|
@ -0,0 +1,128 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 Jon Evans <jon@craftyjon.com>
|
||||||
|
* Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <view/view.h>
|
||||||
|
#include <gerbview_painter.h>
|
||||||
|
#include <gerbview_frame.h>
|
||||||
|
#include <tool/tool_manager.h>
|
||||||
|
|
||||||
|
#include "gerbview_actions.h"
|
||||||
|
#include "gerbview_control.h"
|
||||||
|
#include "selection_tool.h"
|
||||||
|
|
||||||
|
TOOL_ACTION GERBVIEW_ACTIONS::selectionTool( "gerbview.Control.selectionTool",
|
||||||
|
AS_GLOBAL, 0,
|
||||||
|
"", "", NULL, AF_ACTIVATE );
|
||||||
|
|
||||||
|
TOOL_ACTION GERBVIEW_ACTIONS::layerChanged( "gerbview.Control.layerChanged",
|
||||||
|
AS_GLOBAL, 0,
|
||||||
|
"", "", NULL, AF_NOTIFY );
|
||||||
|
|
||||||
|
TOOL_ACTION GERBVIEW_ACTIONS::highlightClear( "gerbview.Control.highlightClear",
|
||||||
|
AS_GLOBAL, 0,
|
||||||
|
_( "Clear Highlight" ), "" );
|
||||||
|
|
||||||
|
TOOL_ACTION GERBVIEW_ACTIONS::highlightNet( "gerbview.Control.highlightNet",
|
||||||
|
AS_GLOBAL, 0,
|
||||||
|
_( "Highlight Net" ), "" );
|
||||||
|
|
||||||
|
TOOL_ACTION GERBVIEW_ACTIONS::highlightComponent( "gerbview.Control.highlightComponent",
|
||||||
|
AS_GLOBAL, 0,
|
||||||
|
_( "Highlight Component" ), "" );
|
||||||
|
|
||||||
|
TOOL_ACTION GERBVIEW_ACTIONS::highlightAttribute( "gerbview.Control.highlightAttribute",
|
||||||
|
AS_GLOBAL, 0,
|
||||||
|
_( "Highlight Attribute" ), "" );
|
||||||
|
|
||||||
|
GERBVIEW_CONTROL::GERBVIEW_CONTROL() :
|
||||||
|
TOOL_INTERACTIVE( "gerbview.Control" ), m_frame( NULL )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GERBVIEW_CONTROL::~GERBVIEW_CONTROL()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GERBVIEW_CONTROL::Reset( RESET_REASON aReason )
|
||||||
|
{
|
||||||
|
m_frame = getEditFrame<GERBVIEW_FRAME>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int GERBVIEW_CONTROL::HighlightControl( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
auto settings = static_cast<KIGFX::GERBVIEW_PAINTER*>( getView()->GetPainter() )->GetSettings();
|
||||||
|
const auto& selection = m_toolMgr->GetTool<GERBVIEW_SELECTION_TOOL>()->GetSelection();
|
||||||
|
GERBER_DRAW_ITEM* item = NULL;
|
||||||
|
|
||||||
|
if( selection.Size() == 1 )
|
||||||
|
{
|
||||||
|
item = static_cast<GERBER_DRAW_ITEM*>( selection[0] );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( aEvent.IsAction( &GERBVIEW_ACTIONS::highlightClear ) )
|
||||||
|
{
|
||||||
|
m_frame->m_SelComponentBox->SetSelection( 0 );
|
||||||
|
m_frame->m_SelNetnameBox->SetSelection( 0 );
|
||||||
|
m_frame->m_SelAperAttributesBox->SetSelection( 0 );
|
||||||
|
|
||||||
|
settings->m_netHighlightString = "";
|
||||||
|
settings->m_componentHighlightString = "";
|
||||||
|
settings->m_attributeHighlightString = "";
|
||||||
|
}
|
||||||
|
else if( item && aEvent.IsAction( &GERBVIEW_ACTIONS::highlightNet ) )
|
||||||
|
{
|
||||||
|
auto string = item->GetNetAttributes().m_Netname;
|
||||||
|
settings->m_netHighlightString = string;
|
||||||
|
m_frame->m_SelNetnameBox->SetStringSelection( string );
|
||||||
|
}
|
||||||
|
else if( item && aEvent.IsAction( &GERBVIEW_ACTIONS::highlightComponent ) )
|
||||||
|
{
|
||||||
|
auto string = item->GetNetAttributes().m_Cmpref;
|
||||||
|
settings->m_componentHighlightString = string;
|
||||||
|
m_frame->m_SelComponentBox->SetStringSelection( string );
|
||||||
|
}
|
||||||
|
else if( item && aEvent.IsAction( &GERBVIEW_ACTIONS::highlightAttribute ) )
|
||||||
|
{
|
||||||
|
D_CODE* apertDescr = item->GetDcodeDescr();
|
||||||
|
if( apertDescr )
|
||||||
|
{
|
||||||
|
auto string = apertDescr->m_AperFunction;
|
||||||
|
settings->m_attributeHighlightString = string;
|
||||||
|
m_frame->m_SelAperAttributesBox->SetStringSelection( string );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_frame->GetGalCanvas()->GetView()->RecacheAllItems();
|
||||||
|
m_frame->GetGalCanvas()->Refresh();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GERBVIEW_CONTROL::setTransitions()
|
||||||
|
{
|
||||||
|
Go( &GERBVIEW_CONTROL::HighlightControl, GERBVIEW_ACTIONS::highlightClear.MakeEvent() );
|
||||||
|
Go( &GERBVIEW_CONTROL::HighlightControl, GERBVIEW_ACTIONS::highlightNet.MakeEvent() );
|
||||||
|
Go( &GERBVIEW_CONTROL::HighlightControl, GERBVIEW_ACTIONS::highlightComponent.MakeEvent() );
|
||||||
|
Go( &GERBVIEW_CONTROL::HighlightControl, GERBVIEW_ACTIONS::highlightAttribute.MakeEvent() );
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 Jon Evans <jon@craftyjon.com>
|
||||||
|
* Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GERBVIEW_CONTROL_H
|
||||||
|
#define GERBVIEW_CONTROL_H
|
||||||
|
|
||||||
|
#include <tool/tool_interactive.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class PCBNEW_CONTROL
|
||||||
|
*
|
||||||
|
* Handles actions that are shared between different frames in pcbnew.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class GERBVIEW_CONTROL : public TOOL_INTERACTIVE
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GERBVIEW_CONTROL();
|
||||||
|
~GERBVIEW_CONTROL();
|
||||||
|
|
||||||
|
/// @copydoc TOOL_INTERACTIVE::Reset()
|
||||||
|
void Reset( RESET_REASON aReason ) override;
|
||||||
|
|
||||||
|
// Display modes
|
||||||
|
int HighContrastMode( const TOOL_EVENT& aEvent );
|
||||||
|
int HighContrastInc( const TOOL_EVENT& aEvent );
|
||||||
|
int HighContrastDec( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
// Layer control
|
||||||
|
int LayerSwitch( const TOOL_EVENT& aEvent );
|
||||||
|
int LayerNext( const TOOL_EVENT& aEvent );
|
||||||
|
int LayerPrev( const TOOL_EVENT& aEvent );
|
||||||
|
int LayerToggle( const TOOL_EVENT& aEvent );
|
||||||
|
int LayerAlphaInc( const TOOL_EVENT& aEvent );
|
||||||
|
int LayerAlphaDec( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
// Highlight control
|
||||||
|
int HighlightControl( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
///> Sets up handlers for various events.
|
||||||
|
void setTransitions() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
GERBVIEW_FRAME* m_frame;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,968 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 Jon Evans <jon@craftyjon.com>
|
||||||
|
* Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
using namespace std::placeholders;
|
||||||
|
|
||||||
|
#include <base_struct.h>
|
||||||
|
|
||||||
|
#include <gerber_collectors.h>
|
||||||
|
//#include <confirm.h>
|
||||||
|
|
||||||
|
#include <class_draw_panel_gal.h>
|
||||||
|
#include <view/view.h>
|
||||||
|
#include <view/view_controls.h>
|
||||||
|
#include <view/view_group.h>
|
||||||
|
#include <painter.h>
|
||||||
|
#include <bitmaps.h>
|
||||||
|
#include <hotkeys.h>
|
||||||
|
|
||||||
|
#include <tool/tool_event.h>
|
||||||
|
#include <tool/tool_manager.h>
|
||||||
|
#include <preview_items/bright_box.h>
|
||||||
|
#include <preview_items/ruler_item.h>
|
||||||
|
#include <preview_items/selection_area.h>
|
||||||
|
|
||||||
|
#include <gerbview_id.h>
|
||||||
|
#include <gerbview_painter.h>
|
||||||
|
|
||||||
|
#include "selection_tool.h"
|
||||||
|
#include "gerbview_actions.h"
|
||||||
|
|
||||||
|
// Selection tool actions
|
||||||
|
TOOL_ACTION GERBVIEW_ACTIONS::selectionActivate( "gerbview.InteractiveSelection",
|
||||||
|
AS_GLOBAL, 0,
|
||||||
|
"", "", NULL, AF_ACTIVATE ); // No description, it is not supposed to be shown anywhere
|
||||||
|
|
||||||
|
TOOL_ACTION GERBVIEW_ACTIONS::selectionCursor( "gerbview.InteractiveSelection.Cursor",
|
||||||
|
AS_GLOBAL, 0,
|
||||||
|
"", "" ); // No description, it is not supposed to be shown anywhere
|
||||||
|
|
||||||
|
TOOL_ACTION GERBVIEW_ACTIONS::selectItem( "gerbview.InteractiveSelection.SelectItem",
|
||||||
|
AS_GLOBAL, 0,
|
||||||
|
"", "" ); // No description, it is not supposed to be shown anywhere
|
||||||
|
|
||||||
|
TOOL_ACTION GERBVIEW_ACTIONS::unselectItem( "gerbview.InteractiveSelection.UnselectItem",
|
||||||
|
AS_GLOBAL, 0,
|
||||||
|
"", "" ); // No description, it is not supposed to be shown anywhere
|
||||||
|
|
||||||
|
TOOL_ACTION GERBVIEW_ACTIONS::selectionClear( "gerbview.InteractiveSelection.Clear",
|
||||||
|
AS_GLOBAL, 0,
|
||||||
|
"", "" ); // No description, it is not supposed to be shown anywhere
|
||||||
|
|
||||||
|
TOOL_ACTION GERBVIEW_ACTIONS::measureTool( "gerbview.InteractiveSelection.measureTool",
|
||||||
|
AS_GLOBAL, MD_CTRL + MD_SHIFT + 'M',
|
||||||
|
_( "Measure tool" ), _( "Interactively measure distance between points" ),
|
||||||
|
nullptr, AF_ACTIVATE );
|
||||||
|
|
||||||
|
|
||||||
|
class HIGHLIGHT_MENU: public CONTEXT_MENU
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HIGHLIGHT_MENU()
|
||||||
|
{
|
||||||
|
SetTitle( _( "Highlight..." ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void update() override
|
||||||
|
{
|
||||||
|
const auto& selection = getToolManager()->GetTool<GERBVIEW_SELECTION_TOOL>()->GetSelection();
|
||||||
|
|
||||||
|
if( selection.Size() == 1 )
|
||||||
|
{
|
||||||
|
auto item = static_cast<GERBER_DRAW_ITEM*>( selection[0] );
|
||||||
|
const auto& net_attr = item->GetNetAttributes();
|
||||||
|
|
||||||
|
if( ( net_attr.m_NetAttribType & GBR_NETLIST_METADATA::GBR_NETINFO_PAD ) ||
|
||||||
|
( net_attr.m_NetAttribType & GBR_NETLIST_METADATA::GBR_NETINFO_CMP ) )
|
||||||
|
{
|
||||||
|
auto menuEntry = Add( GERBVIEW_ACTIONS::highlightComponent );
|
||||||
|
menuEntry->SetItemLabel( wxString::Format( _( "Highlight items of component '%s'" ),
|
||||||
|
GetChars( net_attr.m_Cmpref ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ( net_attr.m_NetAttribType & GBR_NETLIST_METADATA::GBR_NETINFO_NET ) )
|
||||||
|
{
|
||||||
|
auto menuEntry = Add( GERBVIEW_ACTIONS::highlightNet );
|
||||||
|
menuEntry->SetItemLabel( wxString::Format( _( "Highlight items of net '%s'" ),
|
||||||
|
GetChars( net_attr.m_Netname ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
D_CODE* apertDescr = item->GetDcodeDescr();
|
||||||
|
|
||||||
|
if( apertDescr && !apertDescr->m_AperFunction.IsEmpty() )
|
||||||
|
{
|
||||||
|
auto menuEntry = Add( GERBVIEW_ACTIONS::highlightAttribute );
|
||||||
|
menuEntry->SetItemLabel( wxString::Format( _( "Highlight aperture type '%s'" ),
|
||||||
|
GetChars( apertDescr->m_AperFunction ) ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Add( GERBVIEW_ACTIONS::highlightClear );
|
||||||
|
}
|
||||||
|
|
||||||
|
CONTEXT_MENU* create() const override
|
||||||
|
{
|
||||||
|
return new HIGHLIGHT_MENU();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
GERBVIEW_SELECTION_TOOL::GERBVIEW_SELECTION_TOOL() :
|
||||||
|
TOOL_INTERACTIVE( "gerbview.InteractiveSelection" ),
|
||||||
|
m_frame( NULL ), m_additive( false ), m_subtractive( false ),
|
||||||
|
m_multiple( false ),
|
||||||
|
m_menu( *this )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GERBVIEW_SELECTION_TOOL::~GERBVIEW_SELECTION_TOOL()
|
||||||
|
{
|
||||||
|
getView()->Remove( &m_selection );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool GERBVIEW_SELECTION_TOOL::Init()
|
||||||
|
{
|
||||||
|
auto selectMenu = std::make_shared<HIGHLIGHT_MENU>();
|
||||||
|
selectMenu->SetTool( this );
|
||||||
|
m_menu.AddSubMenu( selectMenu );
|
||||||
|
|
||||||
|
auto& menu = m_menu.GetMenu();
|
||||||
|
|
||||||
|
menu.AddMenu( selectMenu.get(), false );
|
||||||
|
menu.AddSeparator( SELECTION_CONDITIONS::ShowAlways, 1000 );
|
||||||
|
|
||||||
|
m_menu.AddStandardSubMenus( *getEditFrame<GERBVIEW_FRAME>() );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GERBVIEW_SELECTION_TOOL::Reset( RESET_REASON aReason )
|
||||||
|
{
|
||||||
|
m_frame = getEditFrame<GERBVIEW_FRAME>();
|
||||||
|
m_preliminary = true;
|
||||||
|
|
||||||
|
if( aReason == TOOL_BASE::MODEL_RELOAD )
|
||||||
|
{
|
||||||
|
// Remove pointers to the selected items from containers
|
||||||
|
// without changing their properties (as they are already deleted
|
||||||
|
// while a new file is loaded)
|
||||||
|
m_selection.Clear();
|
||||||
|
getView()->GetPainter()->GetSettings()->SetHighlight( false );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
// Restore previous properties of selected items and remove them from containers
|
||||||
|
clearSelection();
|
||||||
|
|
||||||
|
// Reinsert the VIEW_GROUP, in case it was removed from the VIEW
|
||||||
|
getView()->Remove( &m_selection );
|
||||||
|
getView()->Add( &m_selection );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int GERBVIEW_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
// Main loop: keep receiving events
|
||||||
|
while( OPT_TOOL_EVENT evt = Wait() )
|
||||||
|
{
|
||||||
|
// This is kind of hacky: activate RMB drag on any event.
|
||||||
|
// There doesn't seem to be any other good way to tell when another tool
|
||||||
|
// is canceled and control returns to the selection tool, except by the
|
||||||
|
// fact that the selection tool starts to get events again.
|
||||||
|
if( m_frame->GetToolId() == ID_NO_TOOL_SELECTED)
|
||||||
|
{
|
||||||
|
getViewControls()->SetAdditionalPanButtons( false, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable RMB pan for other tools; they can re-enable if desired
|
||||||
|
if( evt->IsActivate() )
|
||||||
|
{
|
||||||
|
getViewControls()->SetAdditionalPanButtons( false, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
// single click? Select single object
|
||||||
|
if( evt->IsClick( BUT_LEFT ) )
|
||||||
|
{
|
||||||
|
if( !m_additive )
|
||||||
|
clearSelection();
|
||||||
|
|
||||||
|
selectPoint( evt->Position() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// right click? if there is any object - show the context menu
|
||||||
|
else if( evt->IsClick( BUT_RIGHT ) )
|
||||||
|
{
|
||||||
|
if( m_selection.Empty() )
|
||||||
|
{
|
||||||
|
selectPoint( evt->Position() );
|
||||||
|
m_selection.SetIsHover( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_menu.ShowContextMenu( m_selection );
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( evt->IsCancel() || evt->Action() == TA_UNDO_REDO_PRE )
|
||||||
|
{
|
||||||
|
clearSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( evt->Action() == TA_CONTEXT_MENU_CLOSED )
|
||||||
|
{
|
||||||
|
m_menu.CloseContextMenu( evt );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This tool is supposed to be active forever
|
||||||
|
assert( false );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SELECTION& GERBVIEW_SELECTION_TOOL::GetSelection()
|
||||||
|
{
|
||||||
|
return m_selection;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SELECTION& GERBVIEW_SELECTION_TOOL::RequestSelection( int aFlags )
|
||||||
|
{
|
||||||
|
if( m_selection.Empty() )
|
||||||
|
{
|
||||||
|
m_toolMgr->RunAction( GERBVIEW_ACTIONS::selectionCursor, true, 0 );
|
||||||
|
m_selection.SetIsHover( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Be careful with iterators: items can be removed from list
|
||||||
|
// that invalidate iterators.
|
||||||
|
for( unsigned ii = 0; ii < m_selection.GetSize(); ii++ )
|
||||||
|
{
|
||||||
|
EDA_ITEM* item = m_selection[ii];
|
||||||
|
|
||||||
|
if( ( aFlags & SELECTION_EDITABLE ) && item->Type() == PCB_MARKER_T )
|
||||||
|
{
|
||||||
|
unselect( static_cast<EDA_ITEM *>( item ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_selection;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GERBVIEW_SELECTION_TOOL::toggleSelection( EDA_ITEM* aItem )
|
||||||
|
{
|
||||||
|
if( aItem->IsSelected() )
|
||||||
|
{
|
||||||
|
unselect( aItem );
|
||||||
|
|
||||||
|
// Inform other potentially interested tools
|
||||||
|
m_toolMgr->ProcessEvent( UnselectedEvent );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( !m_additive )
|
||||||
|
clearSelection();
|
||||||
|
|
||||||
|
// Prevent selection of invisible or inactive items
|
||||||
|
if( selectable( aItem ) )
|
||||||
|
{
|
||||||
|
select( aItem );
|
||||||
|
|
||||||
|
// Inform other potentially interested tools
|
||||||
|
m_toolMgr->ProcessEvent( SelectedEvent );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_frame->GetGalCanvas()->ForceRefresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool GERBVIEW_SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere, bool aOnDrag )
|
||||||
|
{
|
||||||
|
EDA_ITEM* item = NULL;
|
||||||
|
GERBER_COLLECTOR collector;
|
||||||
|
EDA_ITEM* model = getModel<EDA_ITEM>();
|
||||||
|
|
||||||
|
collector.Collect( model, GERBER_COLLECTOR::AllItems, wxPoint( aWhere.x, aWhere.y ) );
|
||||||
|
|
||||||
|
bool anyCollected = collector.GetCount() != 0;
|
||||||
|
|
||||||
|
// Remove unselectable items
|
||||||
|
for( int i = collector.GetCount() - 1; i >= 0; --i )
|
||||||
|
{
|
||||||
|
if( !selectable( collector[i] ) )
|
||||||
|
collector.Remove( i );
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( collector.GetCount() )
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
if( !m_additive && anyCollected )
|
||||||
|
clearSelection();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
toggleSelection( collector[0] );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Let's see if there is still disambiguation in selection..
|
||||||
|
if( collector.GetCount() == 1 )
|
||||||
|
{
|
||||||
|
toggleSelection( collector[0] );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if( collector.GetCount() > 1 )
|
||||||
|
{
|
||||||
|
if( aOnDrag )
|
||||||
|
Wait( TOOL_EVENT( TC_ANY, TA_MOUSE_UP, BUT_LEFT ) );
|
||||||
|
|
||||||
|
item = disambiguationMenu( &collector );
|
||||||
|
|
||||||
|
if( item )
|
||||||
|
{
|
||||||
|
toggleSelection( item );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool GERBVIEW_SELECTION_TOOL::selectCursor( bool aSelectAlways )
|
||||||
|
{
|
||||||
|
if( aSelectAlways || m_selection.Empty() )
|
||||||
|
{
|
||||||
|
clearSelection();
|
||||||
|
selectPoint( getViewControls()->GetCursorPosition( false ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return !m_selection.Empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool GERBVIEW_SELECTION_TOOL::selectMultiple()
|
||||||
|
{
|
||||||
|
bool cancelled = false; // Was the tool cancelled while it was running?
|
||||||
|
m_multiple = true; // Multiple selection mode is active
|
||||||
|
KIGFX::VIEW* view = getView();
|
||||||
|
getViewControls()->SetAutoPan( true );
|
||||||
|
|
||||||
|
KIGFX::PREVIEW::SELECTION_AREA area;
|
||||||
|
view->Add( &area );
|
||||||
|
|
||||||
|
while( OPT_TOOL_EVENT evt = Wait() )
|
||||||
|
{
|
||||||
|
if( evt->IsCancel() )
|
||||||
|
{
|
||||||
|
cancelled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( evt->IsDrag( BUT_LEFT ) )
|
||||||
|
{
|
||||||
|
|
||||||
|
// Start drawing a selection box
|
||||||
|
area.SetOrigin( evt->DragOrigin() );
|
||||||
|
area.SetEnd( evt->Position() );
|
||||||
|
area.SetAdditive( m_additive );
|
||||||
|
area.SetSubtractive( m_subtractive );
|
||||||
|
|
||||||
|
view->SetVisible( &area, true );
|
||||||
|
view->Update( &area );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( evt->IsMouseUp( BUT_LEFT ) )
|
||||||
|
{
|
||||||
|
// End drawing the selection box
|
||||||
|
view->SetVisible( &area, false );
|
||||||
|
|
||||||
|
// Mark items within the selection box as selected
|
||||||
|
std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> selectedItems;
|
||||||
|
|
||||||
|
// Filter the view items based on the selection box
|
||||||
|
BOX2I selectionBox = area.ViewBBox();
|
||||||
|
view->Query( selectionBox, selectedItems ); // Get the list of selected items
|
||||||
|
|
||||||
|
std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR>::iterator it, it_end;
|
||||||
|
|
||||||
|
int width = area.GetEnd().x - area.GetOrigin().x;
|
||||||
|
int height = area.GetEnd().y - area.GetOrigin().y;
|
||||||
|
|
||||||
|
// Construct an EDA_RECT to determine EDA_ITEM selection
|
||||||
|
EDA_RECT selectionRect( wxPoint( area.GetOrigin().x, area.GetOrigin().y ),
|
||||||
|
wxSize( width, height ) );
|
||||||
|
|
||||||
|
selectionRect.Normalize();
|
||||||
|
|
||||||
|
for( it = selectedItems.begin(), it_end = selectedItems.end(); it != it_end; ++it )
|
||||||
|
{
|
||||||
|
auto item = static_cast<GERBER_DRAW_ITEM*>( it->first );
|
||||||
|
|
||||||
|
if( !item || !selectable( item ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Selection mode depends on direction of drag-selection:
|
||||||
|
* Left > Right : Select objects that are fully enclosed by selection
|
||||||
|
* Right > Left : Select objects that are crossed by selection
|
||||||
|
*/
|
||||||
|
|
||||||
|
if( width >= 0 )
|
||||||
|
{
|
||||||
|
if( selectionBox.Contains( item->ViewBBox() ) )
|
||||||
|
{
|
||||||
|
if( m_subtractive )
|
||||||
|
unselect( item );
|
||||||
|
else
|
||||||
|
select( item );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( item->HitTest( selectionRect ) )
|
||||||
|
{
|
||||||
|
if( m_subtractive )
|
||||||
|
unselect( item );
|
||||||
|
else
|
||||||
|
select( item );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_selection.Size() == 1 )
|
||||||
|
m_frame->SetCurItem( static_cast<GERBER_DRAW_ITEM*>( m_selection.Front() ) );
|
||||||
|
else
|
||||||
|
m_frame->SetCurItem( NULL );
|
||||||
|
|
||||||
|
// Inform other potentially interested tools
|
||||||
|
if( !m_selection.Empty() )
|
||||||
|
m_toolMgr->ProcessEvent( SelectedEvent );
|
||||||
|
|
||||||
|
break; // Stop waiting for events
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop drawing the selection box
|
||||||
|
view->Remove( &area );
|
||||||
|
m_multiple = false; // Multiple selection mode is inactive
|
||||||
|
getViewControls()->SetAutoPan( false );
|
||||||
|
|
||||||
|
return cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GERBVIEW_SELECTION_TOOL::setTransitions()
|
||||||
|
{
|
||||||
|
Go( &GERBVIEW_SELECTION_TOOL::Main, GERBVIEW_ACTIONS::selectionActivate.MakeEvent() );
|
||||||
|
Go( &GERBVIEW_SELECTION_TOOL::CursorSelection, GERBVIEW_ACTIONS::selectionCursor.MakeEvent() );
|
||||||
|
Go( &GERBVIEW_SELECTION_TOOL::ClearSelection, GERBVIEW_ACTIONS::selectionClear.MakeEvent() );
|
||||||
|
Go( &GERBVIEW_SELECTION_TOOL::SelectItem, GERBVIEW_ACTIONS::selectItem.MakeEvent() );
|
||||||
|
Go( &GERBVIEW_SELECTION_TOOL::UnselectItem, GERBVIEW_ACTIONS::unselectItem.MakeEvent() );
|
||||||
|
Go( &GERBVIEW_SELECTION_TOOL::MeasureTool, GERBVIEW_ACTIONS::measureTool.MakeEvent() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int GERBVIEW_SELECTION_TOOL::CursorSelection( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
if( m_selection.Empty() ) // Try to find an item that could be modified
|
||||||
|
{
|
||||||
|
selectCursor( true );
|
||||||
|
|
||||||
|
clearSelection();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int GERBVIEW_SELECTION_TOOL::ClearSelection( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
clearSelection();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int GERBVIEW_SELECTION_TOOL::SelectItems( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
std::vector<EDA_ITEM*>* items = aEvent.Parameter<std::vector<EDA_ITEM*>*>();
|
||||||
|
|
||||||
|
if( items )
|
||||||
|
{
|
||||||
|
// Perform individual selection of each item
|
||||||
|
// before processing the event.
|
||||||
|
for( auto item : *items )
|
||||||
|
{
|
||||||
|
select( item );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_toolMgr->ProcessEvent( SelectedEvent );
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int GERBVIEW_SELECTION_TOOL::SelectItem( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
// Check if there is an item to be selected
|
||||||
|
EDA_ITEM* item = aEvent.Parameter<EDA_ITEM*>();
|
||||||
|
|
||||||
|
if( item )
|
||||||
|
{
|
||||||
|
select( item );
|
||||||
|
|
||||||
|
// Inform other potentially interested tools
|
||||||
|
m_toolMgr->ProcessEvent( SelectedEvent );
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int GERBVIEW_SELECTION_TOOL::UnselectItems( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
std::vector<EDA_ITEM*>* items = aEvent.Parameter<std::vector<EDA_ITEM*>*>();
|
||||||
|
|
||||||
|
if( items )
|
||||||
|
{
|
||||||
|
// Perform individual unselection of each item
|
||||||
|
// before processing the event
|
||||||
|
for( auto item : *items )
|
||||||
|
{
|
||||||
|
unselect( item );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_toolMgr->ProcessEvent( UnselectedEvent );
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int GERBVIEW_SELECTION_TOOL::UnselectItem( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
// Check if there is an item to be selected
|
||||||
|
EDA_ITEM* item = aEvent.Parameter<EDA_ITEM*>();
|
||||||
|
|
||||||
|
if( item )
|
||||||
|
{
|
||||||
|
unselect( item );
|
||||||
|
|
||||||
|
// Inform other potentially interested tools
|
||||||
|
m_toolMgr->ProcessEvent( UnselectedEvent );
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GERBVIEW_SELECTION_TOOL::clearSelection()
|
||||||
|
{
|
||||||
|
if( m_selection.Empty() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
for( auto item : m_selection )
|
||||||
|
unselectVisually( static_cast<EDA_ITEM*>( item ) );
|
||||||
|
|
||||||
|
m_selection.Clear();
|
||||||
|
|
||||||
|
m_frame->SetCurItem( NULL );
|
||||||
|
|
||||||
|
// Inform other potentially interested tools
|
||||||
|
m_toolMgr->ProcessEvent( ClearedEvent );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GERBVIEW_SELECTION_TOOL::zoomFitSelection( void )
|
||||||
|
{
|
||||||
|
//Should recalculate the view to zoom in on the selection
|
||||||
|
auto selectionBox = m_selection.ViewBBox();
|
||||||
|
auto canvas = m_frame->GetGalCanvas();
|
||||||
|
auto view = getView();
|
||||||
|
|
||||||
|
VECTOR2D screenSize = view->ToWorld( canvas->GetClientSize(), false );
|
||||||
|
|
||||||
|
if( !( selectionBox.GetWidth() == 0 ) || !( selectionBox.GetHeight() == 0 ) )
|
||||||
|
{
|
||||||
|
VECTOR2D vsize = selectionBox.GetSize();
|
||||||
|
double scale = view->GetScale() / std::max( fabs( vsize.x / screenSize.x ),
|
||||||
|
fabs( vsize.y / screenSize.y ) );
|
||||||
|
view->SetScale( scale );
|
||||||
|
view->SetCenter( selectionBox.Centre() );
|
||||||
|
view->Add( &m_selection );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_frame->GetGalCanvas()->ForceRefresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EDA_ITEM* GERBVIEW_SELECTION_TOOL::disambiguationMenu( GERBER_COLLECTOR* aCollector )
|
||||||
|
{
|
||||||
|
EDA_ITEM* current = NULL;
|
||||||
|
KIGFX::VIEW_GROUP highlightGroup;
|
||||||
|
CONTEXT_MENU menu;
|
||||||
|
|
||||||
|
highlightGroup.SetLayer( LAYER_GP_OVERLAY );
|
||||||
|
getView()->Add( &highlightGroup );
|
||||||
|
|
||||||
|
int limit = std::min( 10, aCollector->GetCount() );
|
||||||
|
|
||||||
|
for( int i = 0; i < limit; ++i )
|
||||||
|
{
|
||||||
|
wxString text;
|
||||||
|
EDA_ITEM* item = ( *aCollector )[i];
|
||||||
|
text = item->GetSelectMenuText();
|
||||||
|
menu.Add( text, i + 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
menu.SetTitle( _( "Clarify selection" ) );
|
||||||
|
menu.DisplayTitle( true );
|
||||||
|
SetContextMenu( &menu, CMENU_NOW );
|
||||||
|
|
||||||
|
while( OPT_TOOL_EVENT evt = Wait() )
|
||||||
|
{
|
||||||
|
if( evt->Action() == TA_CONTEXT_MENU_UPDATE )
|
||||||
|
{
|
||||||
|
if( current )
|
||||||
|
{
|
||||||
|
current->ClearBrightened();
|
||||||
|
getView()->Hide( current, false );
|
||||||
|
highlightGroup.Remove( current );
|
||||||
|
getView()->MarkTargetDirty( KIGFX::TARGET_OVERLAY );
|
||||||
|
}
|
||||||
|
|
||||||
|
int id = *evt->GetCommandId();
|
||||||
|
|
||||||
|
// User has pointed an item, so show it in a different way
|
||||||
|
if( id > 0 && id <= limit )
|
||||||
|
{
|
||||||
|
current = ( *aCollector )[id - 1];
|
||||||
|
current->SetBrightened();
|
||||||
|
getView()->Hide( current, true );
|
||||||
|
highlightGroup.Add( current );
|
||||||
|
getView()->MarkTargetDirty( KIGFX::TARGET_OVERLAY );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
current = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( evt->Action() == TA_CONTEXT_MENU_CHOICE )
|
||||||
|
{
|
||||||
|
boost::optional<int> id = evt->GetCommandId();
|
||||||
|
|
||||||
|
// User has selected an item, so this one will be returned
|
||||||
|
if( id && ( *id > 0 ) )
|
||||||
|
current = ( *aCollector )[*id - 1];
|
||||||
|
else
|
||||||
|
current = NULL;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( current && current->IsBrightened() )
|
||||||
|
{
|
||||||
|
current->ClearBrightened();
|
||||||
|
getView()->Hide( current, false );
|
||||||
|
getView()->MarkTargetDirty( KIGFX::TARGET_OVERLAY );
|
||||||
|
}
|
||||||
|
|
||||||
|
getView()->Remove( &highlightGroup );
|
||||||
|
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool GERBVIEW_SELECTION_TOOL::selectable( const EDA_ITEM* aItem ) const
|
||||||
|
{
|
||||||
|
auto item = static_cast<const GERBER_DRAW_ITEM*>( aItem );
|
||||||
|
|
||||||
|
if( item->GetLayerPolarity() )
|
||||||
|
{
|
||||||
|
// Don't allow selection of invisible negative items
|
||||||
|
auto rs = static_cast<KIGFX::GERBVIEW_RENDER_SETTINGS*>( getView()->GetPainter()->GetSettings() );
|
||||||
|
if( !rs->IsShowNegativeItems() )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getEditFrame<GERBVIEW_FRAME>()->IsLayerVisible( item->GetLayer() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GERBVIEW_SELECTION_TOOL::select( EDA_ITEM* aItem )
|
||||||
|
{
|
||||||
|
if( aItem->IsSelected() )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_selection.Add( aItem );
|
||||||
|
getView()->Add( &m_selection );
|
||||||
|
selectVisually( aItem );
|
||||||
|
|
||||||
|
if( m_selection.Size() == 1 )
|
||||||
|
{
|
||||||
|
// Set as the current item, so the information about selection is displayed
|
||||||
|
m_frame->SetCurItem( static_cast<GERBER_DRAW_ITEM*>( aItem ), true );
|
||||||
|
}
|
||||||
|
else if( m_selection.Size() == 2 ) // Check only for 2, so it will not be
|
||||||
|
{ // called for every next selected item
|
||||||
|
// If multiple items are selected, do not show the information about the selected item
|
||||||
|
m_frame->SetCurItem( NULL, true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GERBVIEW_SELECTION_TOOL::unselect( EDA_ITEM* aItem )
|
||||||
|
{
|
||||||
|
if( !aItem->IsSelected() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
unselectVisually( aItem );
|
||||||
|
m_selection.Remove( aItem );
|
||||||
|
|
||||||
|
if( m_selection.Empty() )
|
||||||
|
{
|
||||||
|
m_frame->SetCurItem( NULL );
|
||||||
|
getView()->Remove( &m_selection );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GERBVIEW_SELECTION_TOOL::selectVisually( EDA_ITEM* aItem )
|
||||||
|
{
|
||||||
|
// Move the item's layer to the front
|
||||||
|
int layer = static_cast<GERBER_DRAW_ITEM*>( aItem )->GetLayer();
|
||||||
|
m_frame->SetActiveLayer( layer, true );
|
||||||
|
|
||||||
|
// Hide the original item, so it is shown only on overlay
|
||||||
|
aItem->SetSelected();
|
||||||
|
getView()->Hide( aItem, true );
|
||||||
|
|
||||||
|
getView()->Update( &m_selection );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GERBVIEW_SELECTION_TOOL::unselectVisually( EDA_ITEM* aItem )
|
||||||
|
{
|
||||||
|
// Restore original item visibility
|
||||||
|
aItem->ClearSelected();
|
||||||
|
getView()->Hide( aItem, false );
|
||||||
|
getView()->Update( aItem, KIGFX::ALL );
|
||||||
|
|
||||||
|
getView()->Update( &m_selection );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool GERBVIEW_SELECTION_TOOL::selectionContains( const VECTOR2I& aPoint ) const
|
||||||
|
{
|
||||||
|
const unsigned GRIP_MARGIN = 20;
|
||||||
|
VECTOR2D margin = getView()->ToWorld( VECTOR2D( GRIP_MARGIN, GRIP_MARGIN ), false );
|
||||||
|
|
||||||
|
// Check if the point is located within any of the currently selected items bounding boxes
|
||||||
|
for( auto item : m_selection )
|
||||||
|
{
|
||||||
|
BOX2I itemBox = item->ViewBBox();
|
||||||
|
itemBox.Inflate( margin.x, margin.y ); // Give some margin for gripping an item
|
||||||
|
|
||||||
|
if( itemBox.Contains( aPoint ) )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int GERBVIEW_SELECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
auto& view = *getView();
|
||||||
|
auto& controls = *getViewControls();
|
||||||
|
|
||||||
|
Activate();
|
||||||
|
getEditFrame<GERBVIEW_FRAME>()->SetToolID( ID_TB_MEASUREMENT_TOOL,
|
||||||
|
wxCURSOR_PENCIL, _( "Measure distance between two points" ) );
|
||||||
|
|
||||||
|
KIGFX::PREVIEW::TWO_POINT_GEOMETRY_MANAGER twoPtMgr;
|
||||||
|
KIGFX::PREVIEW::RULER_ITEM ruler( twoPtMgr );
|
||||||
|
|
||||||
|
view.Add( &ruler );
|
||||||
|
view.SetVisible( &ruler, false );
|
||||||
|
|
||||||
|
bool originSet = false;
|
||||||
|
|
||||||
|
controls.ShowCursor( true );
|
||||||
|
controls.SetSnapping( true );
|
||||||
|
getViewControls()->SetAdditionalPanButtons( false, true );
|
||||||
|
|
||||||
|
while( auto evt = Wait() )
|
||||||
|
{
|
||||||
|
const VECTOR2I cursorPos = controls.GetCursorPosition();
|
||||||
|
|
||||||
|
if( evt->IsCancel() || evt->IsActivate() )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// click or drag starts
|
||||||
|
else if( !originSet &&
|
||||||
|
( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) )
|
||||||
|
{
|
||||||
|
if( !evt->IsDrag( BUT_LEFT ) )
|
||||||
|
{
|
||||||
|
twoPtMgr.SetOrigin( cursorPos );
|
||||||
|
twoPtMgr.SetEnd( cursorPos );
|
||||||
|
}
|
||||||
|
|
||||||
|
controls.CaptureCursor( true );
|
||||||
|
controls.SetAutoPan( true );
|
||||||
|
|
||||||
|
originSet = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( !originSet && evt->IsMotion() )
|
||||||
|
{
|
||||||
|
// make sure the origin is set before a drag starts
|
||||||
|
// otherwise you can miss a step
|
||||||
|
twoPtMgr.SetOrigin( cursorPos );
|
||||||
|
twoPtMgr.SetEnd( cursorPos );
|
||||||
|
}
|
||||||
|
|
||||||
|
// second click or mouse up after drag ends
|
||||||
|
else if( originSet &&
|
||||||
|
( evt->IsClick( BUT_LEFT ) || evt->IsMouseUp( BUT_LEFT ) ) )
|
||||||
|
{
|
||||||
|
originSet = false;
|
||||||
|
|
||||||
|
controls.SetAutoPan( false );
|
||||||
|
controls.CaptureCursor( false );
|
||||||
|
|
||||||
|
view.SetVisible( &ruler, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
// move or drag when origin set updates rules
|
||||||
|
else if( originSet &&
|
||||||
|
( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
|
||||||
|
{
|
||||||
|
twoPtMgr.SetAngleSnap( evt->Modifier( MD_CTRL ) );
|
||||||
|
twoPtMgr.SetEnd( cursorPos );
|
||||||
|
|
||||||
|
view.SetVisible( &ruler, true );
|
||||||
|
view.Update( &ruler, KIGFX::GEOMETRY );
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( evt->IsClick( BUT_RIGHT ) )
|
||||||
|
{
|
||||||
|
m_menu.ShowContextMenu( m_selection );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
view.SetVisible( &ruler, false );
|
||||||
|
view.Remove( &ruler );
|
||||||
|
getViewControls()->SetAdditionalPanButtons( false, false );
|
||||||
|
|
||||||
|
getEditFrame<GERBVIEW_FRAME>()->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VECTOR2I SELECTION::GetCenter() const
|
||||||
|
{
|
||||||
|
VECTOR2I centre;
|
||||||
|
|
||||||
|
if( Size() == 1 )
|
||||||
|
{
|
||||||
|
centre = static_cast<GERBER_DRAW_ITEM*>( Front() )->GetPosition();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EDA_RECT bbox = Front()->GetBoundingBox();
|
||||||
|
auto i = m_items.begin();
|
||||||
|
++i;
|
||||||
|
|
||||||
|
for( ; i != m_items.end(); ++i )
|
||||||
|
{
|
||||||
|
bbox.Merge( (*i)->GetBoundingBox() );
|
||||||
|
}
|
||||||
|
|
||||||
|
centre = bbox.Centre();
|
||||||
|
}
|
||||||
|
|
||||||
|
return centre;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const BOX2I SELECTION::ViewBBox() const
|
||||||
|
{
|
||||||
|
EDA_RECT eda_bbox;
|
||||||
|
|
||||||
|
if( Size() == 1 )
|
||||||
|
{
|
||||||
|
eda_bbox = Front()->GetBoundingBox();
|
||||||
|
}
|
||||||
|
else if( Size() > 1 )
|
||||||
|
{
|
||||||
|
eda_bbox = Front()->GetBoundingBox();
|
||||||
|
auto i = m_items.begin();
|
||||||
|
++i;
|
||||||
|
|
||||||
|
for( ; i != m_items.end(); ++i )
|
||||||
|
{
|
||||||
|
eda_bbox.Merge( (*i)->GetBoundingBox() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return BOX2I( eda_bbox.GetOrigin(), eda_bbox.GetSize() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const KIGFX::VIEW_GROUP::ITEMS SELECTION::updateDrawList() const
|
||||||
|
{
|
||||||
|
std::vector<VIEW_ITEM*> items;
|
||||||
|
|
||||||
|
for( auto item : m_items )
|
||||||
|
items.push_back( item );
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const TOOL_EVENT GERBVIEW_SELECTION_TOOL::SelectedEvent( TC_MESSAGE, TA_ACTION, "gerbview.InteractiveSelection.selected" );
|
||||||
|
const TOOL_EVENT GERBVIEW_SELECTION_TOOL::UnselectedEvent( TC_MESSAGE, TA_ACTION, "gerbview.InteractiveSelection.unselected" );
|
||||||
|
const TOOL_EVENT GERBVIEW_SELECTION_TOOL::ClearedEvent( TC_MESSAGE, TA_ACTION, "gerbview.InteractiveSelection.cleared" );
|
|
@ -0,0 +1,253 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 Jon Evans <jon@craftyjon.com>
|
||||||
|
* Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GERBVIEW_SELECTION_TOOL_H
|
||||||
|
#define __GERBVIEW_SELECTION_TOOL_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <math/vector2d.h>
|
||||||
|
|
||||||
|
#include <tool/tool_interactive.h>
|
||||||
|
#include <tool/context_menu.h>
|
||||||
|
#include <tool/selection.h>
|
||||||
|
#include <tool/selection_conditions.h>
|
||||||
|
#include <tool/tool_menu.h>
|
||||||
|
|
||||||
|
#include <gerbview_frame.h>
|
||||||
|
|
||||||
|
class SELECTION_AREA;
|
||||||
|
class GERBER_COLLECTOR;
|
||||||
|
|
||||||
|
namespace KIGFX
|
||||||
|
{
|
||||||
|
class GAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class GERBVIEW_SELECTION_TOOL
|
||||||
|
*
|
||||||
|
* Selection tool for GerbView, based on the one in PcbNew
|
||||||
|
*/
|
||||||
|
class GERBVIEW_SELECTION_TOOL : public TOOL_INTERACTIVE
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GERBVIEW_SELECTION_TOOL();
|
||||||
|
~GERBVIEW_SELECTION_TOOL();
|
||||||
|
|
||||||
|
/// @copydoc TOOL_BASE::Init()
|
||||||
|
bool Init() override;
|
||||||
|
|
||||||
|
/// @copydoc TOOL_BASE::Reset()
|
||||||
|
void Reset( RESET_REASON aReason ) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Main()
|
||||||
|
*
|
||||||
|
* The main loop.
|
||||||
|
*/
|
||||||
|
int Main( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function GetSelection()
|
||||||
|
*
|
||||||
|
* Returns the set of currently selected items.
|
||||||
|
*/
|
||||||
|
SELECTION& GetSelection();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function RequestSelection()
|
||||||
|
*
|
||||||
|
* Returns the current selection set, filtered according to aFlags.
|
||||||
|
* If the set is empty, performs the legacy-style hover selection.
|
||||||
|
*/
|
||||||
|
SELECTION& RequestSelection( int aFlags = SELECTION_DEFAULT );
|
||||||
|
|
||||||
|
inline TOOL_MENU& GetToolMenu()
|
||||||
|
{
|
||||||
|
return m_menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
///> Select a single item under cursor event handler.
|
||||||
|
int CursorSelection( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
///> Clear current selection event handler.
|
||||||
|
int ClearSelection( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
///> Item selection event handler.
|
||||||
|
int SelectItem( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
///> Multiple item selection event handler
|
||||||
|
int SelectItems( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
///> Item unselection event handler.
|
||||||
|
int UnselectItem( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
///> Multiple item unselection event handler
|
||||||
|
int UnselectItems( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
///> Launches a tool to measure between points
|
||||||
|
int MeasureTool( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
///> Event sent after an item is selected.
|
||||||
|
static const TOOL_EVENT SelectedEvent;
|
||||||
|
|
||||||
|
///> Event sent after an item is unselected.
|
||||||
|
static const TOOL_EVENT UnselectedEvent;
|
||||||
|
|
||||||
|
///> Event sent after selection is cleared.
|
||||||
|
static const TOOL_EVENT ClearedEvent;
|
||||||
|
|
||||||
|
///> Sets up handlers for various events.
|
||||||
|
void setTransitions() override;
|
||||||
|
|
||||||
|
///> Zooms the screen to center and fit the current selection.
|
||||||
|
void zoomFitSelection( void );
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Function selectPoint()
|
||||||
|
* Selects an item pointed by the parameter aWhere. If there is more than one item at that
|
||||||
|
* place, there is a menu displayed that allows to choose the item.
|
||||||
|
*
|
||||||
|
* @param aWhere is the place where the item should be selected.
|
||||||
|
* @param aAllowDisambiguation decides what to do in case of disambiguation. If true, then
|
||||||
|
* a menu is shown, otherise function finishes without selecting anything.
|
||||||
|
* @return True if an item was selected, false otherwise.
|
||||||
|
*/
|
||||||
|
bool selectPoint( const VECTOR2I& aWhere, bool aOnDrag = false );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function selectCursor()
|
||||||
|
* Selects an item under the cursor unless there is something already selected or aSelectAlways
|
||||||
|
* is true.
|
||||||
|
* @param aSelectAlways forces to select an item even if there is an item already selected.
|
||||||
|
* @return true if eventually there is an item selected, false otherwise.
|
||||||
|
*/
|
||||||
|
bool selectCursor( bool aSelectAlways = false );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function selectMultiple()
|
||||||
|
* Handles drawing a selection box that allows to select many items at the same time.
|
||||||
|
*
|
||||||
|
* @return true if the function was cancelled (i.e. CancelEvent was received).
|
||||||
|
*/
|
||||||
|
bool selectMultiple();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function clearSelection()
|
||||||
|
* Clears the current selection.
|
||||||
|
*/
|
||||||
|
void clearSelection();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function disambiguationMenu()
|
||||||
|
* Handles the menu that allows to select one of many items in case there is more than one
|
||||||
|
* item at the selected point (@see selectCursor()).
|
||||||
|
*
|
||||||
|
* @param aItems contains list of items that are displayed to the user.
|
||||||
|
*/
|
||||||
|
EDA_ITEM* disambiguationMenu( GERBER_COLLECTOR* aItems );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function toggleSelection()
|
||||||
|
* Changes selection status of a given item.
|
||||||
|
*
|
||||||
|
* @param aItem is the item to have selection status changed.
|
||||||
|
*/
|
||||||
|
void toggleSelection( EDA_ITEM* aItem );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function selectable()
|
||||||
|
* Checks conditions for an item to be selected.
|
||||||
|
*
|
||||||
|
* @return True if the item fulfills conditions to be selected.
|
||||||
|
*/
|
||||||
|
bool selectable( const EDA_ITEM* aItem ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function select()
|
||||||
|
* Takes necessary action mark an item as selected.
|
||||||
|
*
|
||||||
|
* @param aItem is an item to be selected.
|
||||||
|
*/
|
||||||
|
void select( EDA_ITEM* aItem );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function unselect()
|
||||||
|
* Takes necessary action mark an item as unselected.
|
||||||
|
*
|
||||||
|
* @param aItem is an item to be unselected.
|
||||||
|
*/
|
||||||
|
void unselect( EDA_ITEM* aItem );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function selectVisually()
|
||||||
|
* Marks item as selected, but does not add it to the ITEMS_PICKED_LIST.
|
||||||
|
* @param aItem is an item to be be marked.
|
||||||
|
*/
|
||||||
|
void selectVisually( EDA_ITEM* aItem );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function unselectVisually()
|
||||||
|
* Marks item as selected, but does not add it to the ITEMS_PICKED_LIST.
|
||||||
|
* @param aItem is an item to be be marked.
|
||||||
|
*/
|
||||||
|
void unselectVisually( EDA_ITEM* aItem );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function selectionContains()
|
||||||
|
* Checks if the given point is placed within any of selected items' bounding box.
|
||||||
|
*
|
||||||
|
* @return True if the given point is contained in any of selected items' bouding box.
|
||||||
|
*/
|
||||||
|
bool selectionContains( const VECTOR2I& aPoint ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function guessSelectionCandidates()
|
||||||
|
* Tries to guess best selection candidates in case multiple items are clicked, by
|
||||||
|
* doing some braindead heuristics.
|
||||||
|
* @param aCollector is the collector that has a list of items to be queried.
|
||||||
|
*/
|
||||||
|
void guessSelectionCandidates( GERBER_COLLECTOR& aCollector ) const;
|
||||||
|
|
||||||
|
/// Pointer to the parent frame.
|
||||||
|
GERBVIEW_FRAME* m_frame;
|
||||||
|
|
||||||
|
/// Current state of selection.
|
||||||
|
SELECTION m_selection;
|
||||||
|
|
||||||
|
/// Flag saying if items should be added to the current selection or rather replace it.
|
||||||
|
bool m_additive;
|
||||||
|
|
||||||
|
/// Flag saying if items should be removed from the current selection
|
||||||
|
bool m_subtractive;
|
||||||
|
|
||||||
|
/// Flag saying if multiple selection mode is active.
|
||||||
|
bool m_multiple;
|
||||||
|
|
||||||
|
/// Determines if the selection is preliminary or final.
|
||||||
|
bool m_preliminary;
|
||||||
|
|
||||||
|
/// Menu model displayed by the tool.
|
||||||
|
TOOL_MENU m_menu;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -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
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <gal/gal_display_options.h>
|
#include <gal/gal_display_options.h>
|
||||||
#include <gal/color4d.h>
|
#include <gal/color4d.h>
|
||||||
|
#include <class_draw_panel_gal.h>
|
||||||
|
|
||||||
class wxSingleInstanceChecker;
|
class wxSingleInstanceChecker;
|
||||||
class EDA_HOTKEY;
|
class EDA_HOTKEY;
|
||||||
|
@ -148,6 +149,12 @@ protected:
|
||||||
*/
|
*/
|
||||||
virtual void unitsChangeRefresh();
|
virtual void unitsChangeRefresh();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to coerce all colors to legacy-compatible when
|
||||||
|
* switching from GAL to legacy canvas
|
||||||
|
*/
|
||||||
|
virtual void forceColorsToLegacy() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GeneralControlKeyMovement
|
* Function GeneralControlKeyMovement
|
||||||
* Handle the common part of GeneralControl dedicated to global
|
* Handle the common part of GeneralControl dedicated to global
|
||||||
|
@ -164,6 +171,19 @@ protected:
|
||||||
*/
|
*/
|
||||||
bool isBusy() const;
|
bool isBusy() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the canvas type stored in the application settings.
|
||||||
|
*/
|
||||||
|
EDA_DRAW_PANEL_GAL::GAL_TYPE loadCanvasTypeSetting() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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[];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EDA_DRAW_FRAME( KIWAY* aKiway, wxWindow* aParent,
|
EDA_DRAW_FRAME( KIWAY* aKiway, wxWindow* aParent,
|
||||||
FRAME_T aFrameType,
|
FRAME_T aFrameType,
|
||||||
|
|
|
@ -240,6 +240,9 @@ public:
|
||||||
/// @copydoc GAL::ClearTarget()
|
/// @copydoc GAL::ClearTarget()
|
||||||
virtual void ClearTarget( RENDER_TARGET aTarget ) override;
|
virtual void ClearTarget( RENDER_TARGET aTarget ) override;
|
||||||
|
|
||||||
|
/// @copydoc GAL::SetNegativeDrawMode()
|
||||||
|
virtual void SetNegativeDrawMode( bool aSetting ) override;
|
||||||
|
|
||||||
// -------
|
// -------
|
||||||
// Cursor
|
// Cursor
|
||||||
// -------
|
// -------
|
||||||
|
|
|
@ -772,6 +772,19 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void ClearTarget( RENDER_TARGET aTarget ) {};
|
virtual void ClearTarget( RENDER_TARGET aTarget ) {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets negative draw mode in the renderer
|
||||||
|
*
|
||||||
|
* When negative mode is enabled, drawn items will subtract from
|
||||||
|
* previously drawn items. This is mainly needed for Gerber
|
||||||
|
* negative item support in Cairo, since unlike in OpenGL, objects
|
||||||
|
* drawn with zero opacity on top of other objects would not normally
|
||||||
|
* mask objects in Cairo. This method is a no-op in OpenGL.
|
||||||
|
*
|
||||||
|
* @param aSetting is true if negative mode should be enabled
|
||||||
|
*/
|
||||||
|
virtual void SetNegativeDrawMode( bool aSetting ) {};
|
||||||
|
|
||||||
// -------------
|
// -------------
|
||||||
// Grid methods
|
// Grid methods
|
||||||
// -------------
|
// -------------
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
|
|
||||||
#include <wx/glcanvas.h>
|
#include <wx/glcanvas.h>
|
||||||
|
|
||||||
#include <map>
|
#include <unordered_map>
|
||||||
#include <boost/smart_ptr/shared_array.hpp>
|
#include <boost/smart_ptr/shared_array.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
@ -239,6 +239,9 @@ public:
|
||||||
/// @copydoc GAL::ClearTarget()
|
/// @copydoc GAL::ClearTarget()
|
||||||
virtual void ClearTarget( RENDER_TARGET aTarget ) override;
|
virtual void ClearTarget( RENDER_TARGET aTarget ) override;
|
||||||
|
|
||||||
|
/// @copydoc GAL::SetNegativeDrawMode()
|
||||||
|
virtual void SetNegativeDrawMode( bool aSetting ) override {}
|
||||||
|
|
||||||
// -------
|
// -------
|
||||||
// Cursor
|
// Cursor
|
||||||
// -------
|
// -------
|
||||||
|
@ -296,7 +299,7 @@ private:
|
||||||
static GLuint fontTexture; ///< Bitmap font texture handle (shared)
|
static GLuint fontTexture; ///< Bitmap font texture handle (shared)
|
||||||
|
|
||||||
// Vertex buffer objects related fields
|
// Vertex buffer objects related fields
|
||||||
typedef std::map< unsigned int, std::shared_ptr<VERTEX_ITEM> > GROUPS_MAP;
|
typedef std::unordered_map< unsigned int, std::shared_ptr<VERTEX_ITEM> > GROUPS_MAP;
|
||||||
GROUPS_MAP groups; ///< Stores informations about VBO objects (groups)
|
GROUPS_MAP groups; ///< Stores informations about VBO objects (groups)
|
||||||
unsigned int groupCounter; ///< Counter used for generating keys for groups
|
unsigned int groupCounter; ///< Counter used for generating keys for groups
|
||||||
VERTEX_MANAGER* currentManager; ///< Currently used VERTEX_MANAGER (for storing VERTEX_ITEMs)
|
VERTEX_MANAGER* currentManager; ///< Currently used VERTEX_MANAGER (for storing VERTEX_ITEMs)
|
||||||
|
|
|
@ -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_
|
||||||
|
|
|
@ -630,6 +630,25 @@ public:
|
||||||
m_useDrawPriority = aFlag;
|
m_useDrawPriority = aFlag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function IsDrawOrderReversed()
|
||||||
|
* @return true if draw order is reversed
|
||||||
|
*/
|
||||||
|
bool IsDrawOrderReversed() const
|
||||||
|
{
|
||||||
|
return m_reverseDrawOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function ReverseDrawOrder()
|
||||||
|
* Only takes effect if UseDrawPriority is true.
|
||||||
|
* @param aFlag is true if draw order should be reversed
|
||||||
|
*/
|
||||||
|
void ReverseDrawOrder( bool aFlag )
|
||||||
|
{
|
||||||
|
m_reverseDrawOrder = aFlag;
|
||||||
|
}
|
||||||
|
|
||||||
static const int VIEW_MAX_LAYERS = 512; ///< maximum number of layers that may be shown
|
static const int VIEW_MAX_LAYERS = 512; ///< maximum number of layers that may be shown
|
||||||
|
|
||||||
|
|
||||||
|
@ -796,6 +815,9 @@ private:
|
||||||
|
|
||||||
/// The next sequential drawing priority
|
/// The next sequential drawing priority
|
||||||
int m_nextDrawPriority;
|
int m_nextDrawPriority;
|
||||||
|
|
||||||
|
/// Flag to reverse the draw order when using draw priority
|
||||||
|
bool m_reverseDrawOrder;
|
||||||
};
|
};
|
||||||
} // namespace KIGFX
|
} // namespace KIGFX
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,8 @@ enum VIEW_UPDATE_FLAGS {
|
||||||
COLOR = 0x02, /// Color has changed
|
COLOR = 0x02, /// Color has changed
|
||||||
GEOMETRY = 0x04, /// Position or shape has changed
|
GEOMETRY = 0x04, /// Position or shape has changed
|
||||||
LAYERS = 0x08, /// Layers have changed
|
LAYERS = 0x08, /// Layers have changed
|
||||||
ALL = 0xff
|
INITIAL_ADD = 0x10, /// Item is being added to the view
|
||||||
|
ALL = 0xef /// All except INITIAL_ADD
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
#include <richio.h>
|
#include <richio.h>
|
||||||
#include <class_pcb_screen.h>
|
#include <class_pcb_screen.h>
|
||||||
#include <pcbstruct.h>
|
#include <pcbstruct.h>
|
||||||
#include <class_draw_panel_gal.h>
|
|
||||||
|
|
||||||
#include <pcb_general_settings.h>
|
#include <pcb_general_settings.h>
|
||||||
|
|
||||||
|
@ -694,18 +693,6 @@ public:
|
||||||
*/
|
*/
|
||||||
void OnUpdateSwitchCanvas( wxUpdateUIEvent& aEvent );
|
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 );
|
|
||||||
|
|
||||||
PCB_GENERAL_SETTINGS& Settings()
|
PCB_GENERAL_SETTINGS& Settings()
|
||||||
{
|
{
|
||||||
return m_configSettings;
|
return m_configSettings;
|
||||||
|
|
|
@ -123,11 +123,8 @@ protected:
|
||||||
*/
|
*/
|
||||||
virtual void SwitchCanvas( wxCommandEvent& aEvent ) override;
|
virtual void SwitchCanvas( wxCommandEvent& aEvent ) override;
|
||||||
|
|
||||||
/**
|
///> @copydoc EDA_DRAW_FRAME::forceColorsToLegacy()
|
||||||
* Helper function to coerce all colors to legacy-compatible when
|
virtual void forceColorsToLegacy() override;
|
||||||
* switching from GAL to legacy canvas
|
|
||||||
*/
|
|
||||||
void forceColorsToLegacy();
|
|
||||||
|
|
||||||
#if defined(KICAD_SCRIPTING) && defined(KICAD_SCRIPTING_ACTION_MENU)
|
#if defined(KICAD_SCRIPTING) && defined(KICAD_SCRIPTING_ACTION_MENU)
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -958,7 +958,7 @@ void PCB_BASE_FRAME::SwitchCanvas( wxCommandEvent& aEvent )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SaveCanvasTypeSetting( canvasType );
|
saveCanvasTypeSetting( canvasType );
|
||||||
UseGalCanvas( use_gal );
|
UseGalCanvas( use_gal );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1001,44 +1001,6 @@ void PCB_BASE_FRAME::UseGalCanvas( bool aEnable )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EDA_DRAW_PANEL_GAL::GAL_TYPE PCB_BASE_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 PCB_BASE_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 PCB_BASE_FRAME::OnUpdateSwitchCanvas( wxUpdateUIEvent& aEvent )
|
void PCB_BASE_FRAME::OnUpdateSwitchCanvas( wxUpdateUIEvent& aEvent )
|
||||||
{
|
{
|
||||||
wxMenuBar* menuBar = GetMenuBar();
|
wxMenuBar* menuBar = GetMenuBar();
|
||||||
|
|
|
@ -53,6 +53,7 @@ PCB_RENDER_SETTINGS::PCB_RENDER_SETTINGS()
|
||||||
m_clearance = CL_NONE;
|
m_clearance = CL_NONE;
|
||||||
m_sketchBoardGfx = false;
|
m_sketchBoardGfx = false;
|
||||||
m_sketchFpGfx = false;
|
m_sketchFpGfx = false;
|
||||||
|
m_selectionCandidateColor = COLOR4D( 0.0, 1.0, 0.0, 0.75 );
|
||||||
|
|
||||||
// By default everything should be displayed as filled
|
// By default everything should be displayed as filled
|
||||||
for( unsigned int i = 0; i < PCB_LAYER_ID_COUNT; ++i )
|
for( unsigned int i = 0; i < PCB_LAYER_ID_COUNT; ++i )
|
||||||
|
@ -210,6 +211,12 @@ const COLOR4D& PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer
|
||||||
|
|
||||||
if( item )
|
if( item )
|
||||||
{
|
{
|
||||||
|
// Selection disambiguation
|
||||||
|
if( item->IsBrightened() )
|
||||||
|
{
|
||||||
|
return m_selectionCandidateColor;
|
||||||
|
}
|
||||||
|
|
||||||
if( item->IsSelected() )
|
if( item->IsSelected() )
|
||||||
{
|
{
|
||||||
return m_layerColorsSel[aLayer];
|
return m_layerColorsSel[aLayer];
|
||||||
|
|
|
@ -163,6 +163,9 @@ protected:
|
||||||
|
|
||||||
///> Clearance visibility settings
|
///> Clearance visibility settings
|
||||||
int m_clearance;
|
int m_clearance;
|
||||||
|
|
||||||
|
///> Color used for highlighting selection candidates
|
||||||
|
COLOR4D m_selectionCandidateColor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -468,7 +468,7 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
||||||
|
|
||||||
Zoom_Automatique( false );
|
Zoom_Automatique( false );
|
||||||
|
|
||||||
EDA_DRAW_PANEL_GAL::GAL_TYPE canvasType = LoadCanvasTypeSetting();
|
EDA_DRAW_PANEL_GAL::GAL_TYPE canvasType = loadCanvasTypeSetting();
|
||||||
|
|
||||||
if( canvasType != EDA_DRAW_PANEL_GAL::GAL_TYPE_NONE )
|
if( canvasType != EDA_DRAW_PANEL_GAL::GAL_TYPE_NONE )
|
||||||
{
|
{
|
||||||
|
|
|
@ -1268,10 +1268,11 @@ void SELECTION_TOOL::clearSelection()
|
||||||
BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector )
|
BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector )
|
||||||
{
|
{
|
||||||
BOARD_ITEM* current = NULL;
|
BOARD_ITEM* current = NULL;
|
||||||
PCB_BRIGHT_BOX brightBox;
|
KIGFX::VIEW_GROUP highlightGroup;
|
||||||
CONTEXT_MENU menu;
|
CONTEXT_MENU menu;
|
||||||
|
|
||||||
getView()->Add( &brightBox );
|
highlightGroup.SetLayer( LAYER_GP_OVERLAY );
|
||||||
|
getView()->Add( &highlightGroup );
|
||||||
|
|
||||||
int limit = std::min( 9, aCollector->GetCount() );
|
int limit = std::min( 9, aCollector->GetCount() );
|
||||||
|
|
||||||
|
@ -1294,7 +1295,12 @@ BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector )
|
||||||
if( evt->Action() == TA_CONTEXT_MENU_UPDATE )
|
if( evt->Action() == TA_CONTEXT_MENU_UPDATE )
|
||||||
{
|
{
|
||||||
if( current )
|
if( current )
|
||||||
|
{
|
||||||
current->ClearBrightened();
|
current->ClearBrightened();
|
||||||
|
getView()->Hide( current, false );
|
||||||
|
highlightGroup.Remove( current );
|
||||||
|
getView()->MarkTargetDirty( KIGFX::TARGET_OVERLAY );
|
||||||
|
}
|
||||||
|
|
||||||
int id = *evt->GetCommandId();
|
int id = *evt->GetCommandId();
|
||||||
|
|
||||||
|
@ -1303,6 +1309,9 @@ BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector )
|
||||||
{
|
{
|
||||||
current = ( *aCollector )[id - 1];
|
current = ( *aCollector )[id - 1];
|
||||||
current->SetBrightened();
|
current->SetBrightened();
|
||||||
|
getView()->Hide( current, true );
|
||||||
|
highlightGroup.Add( current );
|
||||||
|
getView()->MarkTargetDirty( KIGFX::TARGET_OVERLAY );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1321,19 +1330,16 @@ BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector )
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a mark to show which item is available to be selected
|
|
||||||
if( current && current->IsBrightened() )
|
|
||||||
{
|
|
||||||
brightBox.SetItem( current );
|
|
||||||
getView()->SetVisible( &brightBox, true );
|
|
||||||
// getView()->Hide( &brightBox, false );
|
|
||||||
getView()->Update( &brightBox, KIGFX::GEOMETRY );
|
|
||||||
getView()->MarkTargetDirty( KIGFX::TARGET_OVERLAY );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getView()->Remove( &brightBox );
|
if( current && current->IsBrightened() )
|
||||||
|
{
|
||||||
|
current->ClearBrightened();
|
||||||
|
getView()->Hide( current, false );
|
||||||
|
getView()->MarkTargetDirty( KIGFX::TARGET_OVERLAY );
|
||||||
|
}
|
||||||
|
|
||||||
|
getView()->Remove( &highlightGroup );
|
||||||
|
|
||||||
|
|
||||||
return current;
|
return current;
|
||||||
|
|
Loading…
Reference in New Issue