From 0440aa3d836baa8f08731af37ca31bb2ffa022bb Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Mon, 7 Mar 2022 18:03:06 +0100 Subject: [PATCH] Extend layer LAYER_LOCKED_ITEM_SHADOW to draw shadow markers on other locked items: tracks, texts, graphics. --- pcbnew/board_item.cpp | 3 + pcbnew/footprint.cpp | 3 +- pcbnew/pcb_draw_panel_gal.cpp | 2 +- pcbnew/pcb_painter.cpp | 95 +++++++++++++++++++++++--- pcbnew/pcb_shape.cpp | 27 ++++++++ pcbnew/pcb_shape.h | 3 + pcbnew/pcb_text.cpp | 27 +++++++- pcbnew/pcb_text.h | 3 + pcbnew/pcb_textbox.cpp | 27 +++++++- pcbnew/pcb_textbox.h | 3 + pcbnew/pcb_track.cpp | 20 ++++++ pcbnew/widgets/appearance_controls.cpp | 2 +- 12 files changed, 197 insertions(+), 18 deletions(-) diff --git a/pcbnew/board_item.cpp b/pcbnew/board_item.cpp index ed3ae57e71..ef424d0ad8 100644 --- a/pcbnew/board_item.cpp +++ b/pcbnew/board_item.cpp @@ -135,6 +135,9 @@ void BOARD_ITEM::ViewGetLayers( int aLayers[], int& aCount ) const // Basic fallback aCount = 1; aLayers[0] = m_layer; + + if( IsLocked() ) + aLayers[aCount++] = LAYER_LOCKED_ITEM_SHADOW; } diff --git a/pcbnew/footprint.cpp b/pcbnew/footprint.cpp index 52ba89be57..70f6f23513 100644 --- a/pcbnew/footprint.cpp +++ b/pcbnew/footprint.cpp @@ -1399,7 +1399,8 @@ void FOOTPRINT::ViewGetLayers( int aLayers[], int& aCount ) const break; } - aLayers[ aCount++ ] = LAYER_LOCKED_ITEM_SHADOW; + if( IsLocked() ) + aLayers[ aCount++ ] = LAYER_LOCKED_ITEM_SHADOW; // If there are no pads, and only drawings on a silkscreen layer, then report the silkscreen // layer as well so that the component can be edited with the silkscreen layer diff --git a/pcbnew/pcb_draw_panel_gal.cpp b/pcbnew/pcb_draw_panel_gal.cpp index f36b428428..2d932b0411 100644 --- a/pcbnew/pcb_draw_panel_gal.cpp +++ b/pcbnew/pcb_draw_panel_gal.cpp @@ -561,7 +561,7 @@ void PCB_DRAW_PANEL_GAL::setDefaultLayerDeps() m_view->SetLayerTarget( LAYER_ANCHOR, KIGFX::TARGET_NONCACHED ); m_view->SetLayerDisplayOnly( LAYER_ANCHOR ); - m_view->SetLayerTarget( LAYER_LOCKED_ITEM_SHADOW, KIGFX::TARGET_NONCACHED ); + m_view->SetLayerTarget( LAYER_LOCKED_ITEM_SHADOW, KIGFX::TARGET_OVERLAY ); m_view->SetLayerDisplayOnly( LAYER_LOCKED_ITEM_SHADOW ); // Some more required layers settings diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index 9c1caed26a..0d9410880c 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -636,22 +636,27 @@ void PCB_PAINTER::draw( const PCB_TRACK* aTrack, int aLayer ) return; } - else if( IsCopperLayer( aLayer ) ) + else if( IsCopperLayer( aLayer ) || aLayer == LAYER_LOCKED_ITEM_SHADOW ) { // Draw a regular track - bool outline_mode = pcbconfig() && !pcbconfig()->m_Display.m_DisplayPcbTrackFill; + bool outline_mode = pcbconfig() + && !pcbconfig()->m_Display.m_DisplayPcbTrackFill + && aLayer != LAYER_LOCKED_ITEM_SHADOW; m_gal->SetStrokeColor( color ); m_gal->SetFillColor( color ); m_gal->SetIsStroke( outline_mode ); m_gal->SetIsFill( not outline_mode ); m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth ); + if( aLayer == LAYER_LOCKED_ITEM_SHADOW ) + width = width * 1.5; + m_gal->DrawSegment( start, end, width ); } // Clearance lines if( pcbconfig() && pcbconfig()->m_Display.m_TrackClearance == SHOW_WITH_VIA_ALWAYS - && !m_pcbSettings.m_isPrinting ) + && !m_pcbSettings.m_isPrinting && aLayer != LAYER_LOCKED_ITEM_SHADOW ) { int clearance = aTrack->GetOwnClearance( m_pcbSettings.GetActiveLayer() ); @@ -678,23 +683,28 @@ void PCB_PAINTER::draw( const PCB_ARC* aArc, int aLayer ) // Ummm, yeah. Anyone fancy implementing text on a path? return; } - else if( IsCopperLayer( aLayer ) ) + else if( IsCopperLayer( aLayer ) || aLayer == LAYER_LOCKED_ITEM_SHADOW ) { // Draw a regular track - bool outline_mode = pcbconfig() && !pcbconfig()->m_Display.m_DisplayPcbTrackFill; + bool outline_mode = pcbconfig() + && !pcbconfig()->m_Display.m_DisplayPcbTrackFill + && aLayer != LAYER_LOCKED_ITEM_SHADOW; m_gal->SetStrokeColor( color ); m_gal->SetFillColor( color ); m_gal->SetIsStroke( outline_mode ); m_gal->SetIsFill( not outline_mode ); m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth ); + if( aLayer == LAYER_LOCKED_ITEM_SHADOW ) + width = width * 1.5; + m_gal->DrawArcSegment( center, radius, start_angle, start_angle + angle, width, m_maxError ); } // Clearance lines if( pcbconfig() && pcbconfig()->m_Display.m_TrackClearance == SHOW_WITH_VIA_ALWAYS - && !m_pcbSettings.m_isPrinting ) + && !m_pcbSettings.m_isPrinting && aLayer != LAYER_LOCKED_ITEM_SHADOW ) { int clearance = aArc->GetOwnClearance( m_pcbSettings.GetActiveLayer() ); @@ -809,7 +819,9 @@ void PCB_PAINTER::draw( const PCB_VIA* aVia, int aLayer ) return; } - bool outline_mode = pcbconfig() && !pcbconfig()->m_Display.m_DisplayViaFill; + bool outline_mode = pcbconfig() + && !pcbconfig()->m_Display.m_DisplayViaFill + && aLayer != LAYER_LOCKED_ITEM_SHADOW; if( outline_mode ) { @@ -863,6 +875,19 @@ void PCB_PAINTER::draw( const PCB_VIA* aVia, int aLayer ) m_gal->DrawArc( center, radius, EDA_ANGLE( 60, DEGREES_T ), EDA_ANGLE( 120, DEGREES_T ) ); } + if( aLayer == LAYER_LOCKED_ITEM_SHADOW ) // draw a ring around the via + { + m_gal->SetIsFill( false ); + m_gal->SetIsStroke( true ); + m_gal->SetStrokeColor( color ); + + int ring_width = aVia->GetWidth() * 0.2; + m_gal->SetLineWidth( ring_width ); + + m_gal->DrawCircle( center, ( aVia->GetWidth() + ring_width ) / 2.0 ); + return; + } + // Clearance lines if( pcbconfig() && pcbconfig()->m_Display.m_TrackClearance == SHOW_WITH_VIA_ALWAYS && aLayer != LAYER_VIA_HOLES @@ -1341,11 +1366,17 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer ) void PCB_PAINTER::draw( const PCB_SHAPE* aShape, int aLayer ) { - const COLOR4D& color = m_pcbSettings.GetColor( aShape, aShape->GetLayer() ); + COLOR4D color = m_pcbSettings.GetColor( aShape, aShape->GetLayer() ); bool outline_mode = pcbconfig() && !pcbconfig()->m_Display.m_DisplayGraphicsFill; int thickness = getLineThickness( aShape->GetWidth() ); PLOT_DASH_TYPE lineStyle = aShape->GetStroke().GetPlotStyle(); + if( aLayer == LAYER_LOCKED_ITEM_SHADOW ) + { + color = m_pcbSettings.GetColor( aShape, aLayer ); + thickness = std::max( thickness * 3, Millimeter2iu( 0.2 ) ); + } + if( outline_mode ) { m_gal->SetIsFill( false ); @@ -1592,9 +1623,25 @@ void PCB_PAINTER::draw( const PCB_TEXT* aText, int aLayer ) if( resolvedText.Length() == 0 ) return; - const COLOR4D& color = m_pcbSettings.GetColor( aText, aText->GetLayer() ); - bool outline_mode = pcbconfig() && !pcbconfig()->m_Display.m_DisplayTextFill; + if( aLayer == LAYER_LOCKED_ITEM_SHADOW ) // happens only if locked + { + const COLOR4D color = m_pcbSettings.GetColor( aText, aLayer ); + + m_gal->SetIsFill( true ); + m_gal->SetIsStroke( false ); + m_gal->SetFillColor( color ); + + SHAPE_POLY_SET poly; + aText->TransformShapeWithClearanceToPolygon( poly, aText->GetLayer(), 0, m_maxError, + ERROR_OUTSIDE ); + m_gal->DrawPolygon( poly ); + + return; + } + TEXT_ATTRIBUTES attrs = aText->GetAttributes(); + const COLOR4D& color = m_pcbSettings.GetColor( aText, aText->GetLayer() ); + bool outline_mode = pcbconfig() && !pcbconfig()->m_Display.m_DisplayTextFill; m_gal->SetStrokeColor( color ); m_gal->SetFillColor( color ); @@ -1660,6 +1707,24 @@ void PCB_PAINTER::draw( const PCB_TEXTBOX* aTextBox, int aLayer ) PLOT_DASH_TYPE lineStyle = aTextBox->GetStroke().GetPlotStyle(); wxString resolvedText( aTextBox->GetShownText() ); + if( aLayer == LAYER_LOCKED_ITEM_SHADOW ) // happens only if locked + { + const COLOR4D sh_color = m_pcbSettings.GetColor( aTextBox, aLayer ); + + m_gal->SetIsFill( true ); + m_gal->SetIsStroke( false ); + m_gal->SetFillColor( sh_color ); + m_gal->SetStrokeColor( sh_color ); + + // Draw the box with a larger thickness than box thickness to show + // the shadow mask + std::vector pts = aTextBox->GetCorners(); + int line_thickness = std::max( thickness*3, Millimeter2iu( 0.2 ) ); + + for( size_t ii = 0; ii < pts.size(); ++ii ) + m_gal->DrawSegment( pts[ ii ], pts[ (ii + 1) % pts.size() ], line_thickness ); + } + m_gal->SetFillColor( color ); m_gal->SetStrokeColor( color ); m_gal->SetIsFill( true ); @@ -1700,6 +1765,14 @@ void PCB_PAINTER::draw( const PCB_TEXTBOX* aTextBox, int aLayer ) std::vector>* cache = aTextBox->GetRenderCache( resolvedText ); + if( aLayer == LAYER_LOCKED_ITEM_SHADOW ) + { + const COLOR4D sh_color = m_pcbSettings.GetColor( aTextBox, aLayer ); + m_gal->SetFillColor( sh_color ); + m_gal->SetStrokeColor( sh_color ); + attrs.m_StrokeWidth *= 3; + } + if( cache ) { for( const std::unique_ptr& glyph : *cache ) @@ -1873,7 +1946,7 @@ void PCB_PAINTER::draw( const FOOTPRINT* aFootprint, int aLayer ) m_gal->DrawLine( center - VECTOR2D( 0, anchorSize ), center + VECTOR2D( 0, anchorSize ) ); } - if( aLayer == LAYER_LOCKED_ITEM_SHADOW && aFootprint->IsLocked() ) + if( aLayer == LAYER_LOCKED_ITEM_SHADOW ) // happens only if locked { const COLOR4D color = m_pcbSettings.GetColor( aFootprint, aLayer ); diff --git a/pcbnew/pcb_shape.cpp b/pcbnew/pcb_shape.cpp index 1e467e5c15..9b4ee1efd0 100644 --- a/pcbnew/pcb_shape.cpp +++ b/pcbnew/pcb_shape.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include "macros.h" PCB_SHAPE::PCB_SHAPE( BOARD_ITEM* aParent, KICAD_T aItemType, SHAPE_T aShapeType ) : @@ -172,6 +173,32 @@ VECTOR2I PCB_SHAPE::getParentPosition() const } +double PCB_SHAPE::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const +{ + constexpr double HIDE = std::numeric_limits::max(); + constexpr double SHOW = 0.0; + + KIGFX::PCB_PAINTER* painter = static_cast( aView->GetPainter() ); + KIGFX::PCB_RENDER_SETTINGS* renderSettings = painter->GetSettings(); + + if( aLayer == LAYER_LOCKED_ITEM_SHADOW ) + { + // Hide shadow if the main layer is not shown + if( !aView->IsLayerVisible( m_layer ) ) + return HIDE; + + // Hide shadow on dimmed tracks + if( renderSettings->GetHighContrast() ) + { + if( m_layer != renderSettings->GetPrimaryHighContrastLayer() ) + return HIDE; + } + } + + return SHOW; +} + + void PCB_SHAPE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector& aList ) { aList.emplace_back( _( "Type" ), _( "Drawing" ) ); diff --git a/pcbnew/pcb_shape.h b/pcbnew/pcb_shape.h index 786af5da8b..118bade45b 100644 --- a/pcbnew/pcb_shape.h +++ b/pcbnew/pcb_shape.h @@ -154,6 +154,9 @@ public: virtual const BOX2I ViewBBox() const override; + ///< @copydoc VIEW_ITEM::ViewGetLOD + double ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const override; + virtual void SwapData( BOARD_ITEM* aImage ) override; struct cmp_drawings diff --git a/pcbnew/pcb_text.cpp b/pcbnew/pcb_text.cpp index 8b93ed8443..446a5d16b9 100644 --- a/pcbnew/pcb_text.cpp +++ b/pcbnew/pcb_text.cpp @@ -38,8 +38,6 @@ #include #include -using KIGFX::PCB_RENDER_SETTINGS; - PCB_TEXT::PCB_TEXT( BOARD_ITEM* parent ) : BOARD_ITEM( parent, PCB_TEXT_T ), @@ -102,6 +100,31 @@ wxString PCB_TEXT::GetShownText( int aDepth ) const } +double PCB_TEXT::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const +{ + constexpr double HIDE = std::numeric_limits::max(); + + KIGFX::PCB_PAINTER* painter = static_cast( aView->GetPainter() ); + KIGFX::PCB_RENDER_SETTINGS* renderSettings = painter->GetSettings(); + + if( aLayer == LAYER_LOCKED_ITEM_SHADOW ) + { + // Hide shadow if the main layer is not shown + if( !aView->IsLayerVisible( m_layer ) ) + return HIDE; + + // Hide shadow on dimmed tracks + if( renderSettings->GetHighContrast() ) + { + if( m_layer != renderSettings->GetPrimaryHighContrastLayer() ) + return HIDE; + } + } + + return 0.0; +} + + void PCB_TEXT::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector& aList ) { EDA_UNITS units = aFrame->GetUserUnits(); diff --git a/pcbnew/pcb_text.h b/pcbnew/pcb_text.h index 54a446e9da..c2e668008a 100644 --- a/pcbnew/pcb_text.h +++ b/pcbnew/pcb_text.h @@ -139,6 +139,9 @@ public: BITMAPS GetMenuImage() const override; + ///< @copydoc VIEW_ITEM::ViewGetLOD + double ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const override; + // Virtual function const EDA_RECT GetBoundingBox() const override; diff --git a/pcbnew/pcb_textbox.cpp b/pcbnew/pcb_textbox.cpp index 45a4b03da2..e267cad1d4 100644 --- a/pcbnew/pcb_textbox.cpp +++ b/pcbnew/pcb_textbox.cpp @@ -36,8 +36,6 @@ #include #include "macros.h" -using KIGFX::PCB_RENDER_SETTINGS; - PCB_TEXTBOX::PCB_TEXTBOX( BOARD_ITEM* parent ) : PCB_SHAPE( parent, PCB_TEXTBOX_T, SHAPE_T::RECT ), @@ -121,6 +119,31 @@ VECTOR2I PCB_TEXTBOX::GetDrawPos() const } +double PCB_TEXTBOX::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const +{ + constexpr double HIDE = std::numeric_limits::max(); + + KIGFX::PCB_PAINTER* painter = static_cast( aView->GetPainter() ); + KIGFX::PCB_RENDER_SETTINGS* renderSettings = painter->GetSettings(); + + if( aLayer == LAYER_LOCKED_ITEM_SHADOW ) + { + // Hide shadow if the main layer is not shown + if( !aView->IsLayerVisible( m_layer ) ) + return HIDE; + + // Hide shadow on dimmed tracks + if( renderSettings->GetHighContrast() ) + { + if( m_layer != renderSettings->GetPrimaryHighContrastLayer() ) + return HIDE; + } + } + + return 0.0; +} + + wxString PCB_TEXTBOX::GetShownText( int aDepth ) const { BOARD* board = dynamic_cast( GetParent() ); diff --git a/pcbnew/pcb_textbox.h b/pcbnew/pcb_textbox.h index daa947967b..7bb7f5fb04 100644 --- a/pcbnew/pcb_textbox.h +++ b/pcbnew/pcb_textbox.h @@ -118,6 +118,9 @@ public: BITMAPS GetMenuImage() const override; + ///< @copydoc VIEW_ITEM::ViewGetLOD + double ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const override; + // Virtual function EDA_ITEM* Clone() const override; diff --git a/pcbnew/pcb_track.cpp b/pcbnew/pcb_track.cpp index f109599070..5bae3d29a1 100644 --- a/pcbnew/pcb_track.cpp +++ b/pcbnew/pcb_track.cpp @@ -558,6 +558,9 @@ void PCB_TRACK::ViewGetLayers( int aLayers[], int& aCount ) const aLayers[0] = GetLayer(); aLayers[1] = GetNetnameLayer( aLayers[0] ); aCount = 2; + + if( IsLocked() ) + aLayers[ aCount++ ] = LAYER_LOCKED_ITEM_SHADOW; } @@ -601,6 +604,20 @@ double PCB_TRACK::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const return ( double ) Millimeter2iu( 4 ) / ( m_Width + 1 ); } + if( aLayer == LAYER_LOCKED_ITEM_SHADOW ) + { + // Hide shadow if the main layer is not shown + if( !aView->IsLayerVisible( m_layer ) ) + return HIDE; + + // Hide shadow on dimmed tracks + if( renderSettings->GetHighContrast() ) + { + if( m_layer != renderSettings->GetPrimaryHighContrastLayer() ) + return HIDE; + } + } + // Other layers are shown without any conditions return 0.0; } @@ -636,6 +653,9 @@ void PCB_VIA::ViewGetLayers( int aLayers[], int& aCount ) const } aCount = 4; + + if( IsLocked() ) + aLayers[ aCount++ ] = LAYER_LOCKED_ITEM_SHADOW; } diff --git a/pcbnew/widgets/appearance_controls.cpp b/pcbnew/widgets/appearance_controls.cpp index 570eaa046d..a56393277a 100644 --- a/pcbnew/widgets/appearance_controls.cpp +++ b/pcbnew/widgets/appearance_controls.cpp @@ -352,7 +352,7 @@ const APPEARANCE_CONTROLS::APPEARANCE_SETTING APPEARANCE_CONTROLS::s_objectSetti RR( _HKI( "DRC Errors" ), LAYER_DRC_ERROR, _HKI( "DRC violations with an Error severity" ) ), RR( _HKI( "DRC Exclusions" ), LAYER_DRC_EXCLUSION, _HKI( "DRC violations which have been individually excluded" ) ), RR( _HKI( "Anchors" ), LAYER_ANCHOR, _HKI( "Show footprint and text origins as a cross" ) ), - RR( _HKI( "Locked Marker" ), LAYER_LOCKED_ITEM_SHADOW, _HKI( "Show marker shadow on locked footprints" ) ), + RR( _HKI( "Shadow on Locked Items" ), LAYER_LOCKED_ITEM_SHADOW, _HKI( "Show a shadow marker on locked items" ) ), RR( _HKI( "Drawing Sheet" ), LAYER_DRAWINGSHEET, _HKI( "Show drawing sheet borders and title block" ) ), RR( _HKI( "Grid" ), LAYER_GRID, _HKI( "Show the (x,y) grid dots" ) ) };