ADDED: Opacity control for filled graphic shapes

Fixes https://gitlab.com/kicad/code/kicad/-/issues/18253
This commit is contained in:
Jon Evans 2024-06-26 21:48:00 -04:00
parent 7102d9f72a
commit c70ef36739
13 changed files with 100 additions and 24 deletions

View File

@ -1085,6 +1085,7 @@ GAL_SET GAL_SET::DefaultVisible()
LAYER_DRAW_BITMAPS,
LAYER_PADS,
LAYER_ZONES,
LAYER_SHAPES,
LAYER_LOCKED_ITEM_SHADOW,
LAYER_CONFLICTS_SHADOW
};

View File

@ -24,7 +24,7 @@
#include <settings/json_settings_internals.h>
#include <settings/parameters.h>
const int projectLocalSettingsVersion = 3;
const int projectLocalSettingsVersion = 4;
PROJECT_LOCAL_SETTINGS::PROJECT_LOCAL_SETTINGS( PROJECT* aProject, const wxString& aFilename ) :
@ -41,6 +41,7 @@ PROJECT_LOCAL_SETTINGS::PROJECT_LOCAL_SETTINGS( PROJECT* aProject, const wxStrin
m_PadOpacity( 1.0 ),
m_ZoneOpacity( 0.6 ),
m_ImageOpacity( 0.6 ),
m_ShapeOpacity( 1.0 ),
m_PcbSelectionFilter(),
m_project( aProject )
{
@ -159,6 +160,7 @@ PROJECT_LOCAL_SETTINGS::PROJECT_LOCAL_SETTINGS( PROJECT* aProject, const wxStrin
m_params.emplace_back( new PARAM<double>( "board.opacity.pads", &m_PadOpacity, 1.0 ) );
m_params.emplace_back( new PARAM<double>( "board.opacity.zones", &m_ZoneOpacity, 0.6 ) );
m_params.emplace_back( new PARAM<double>( "board.opacity.images", &m_ImageOpacity, 0.6 ) );
m_params.emplace_back( new PARAM<double>( "board.opacity.shapes", &m_ShapeOpacity, 1.0 ) );
m_params.emplace_back( new PARAM_LIST<wxString>( "board.hidden_nets", &m_HiddenNets, {} ) );
@ -406,6 +408,24 @@ PROJECT_LOCAL_SETTINGS::PROJECT_LOCAL_SETTINGS( PROJECT* aProject, const wxStrin
At( "board" )["visible_items"] = visible;
}
return true;
} );
registerMigration( 3, 4,
[&]()
{
// Schema version 3 to 4: LAYER_SHAPES added to visibility controls
std::string ptr( "board.visible_items" );
if( Contains( ptr ) )
{
if( At( ptr ).is_array() )
At( ptr ).push_back( LAYER_SHAPES - GAL_LAYER_ID_START );
else
At( "board" ).erase( "visible_items" );
}
return true;
} );
}

View File

@ -243,6 +243,7 @@ enum GAL_LAYER_ID: int
LAYER_LOCKED_ITEM_SHADOW = GAL_LAYER_ID_START + 39, ///< shadow layer for locked items
LAYER_CONFLICTS_SHADOW = GAL_LAYER_ID_START + 40, ///< shadow layer for items flagged conficting
LAYER_SHAPES = GAL_LAYER_ID_START + 41, ///< Copper graphic shape opacity/visibility (color ignored)
// Add layers below this point that do not have visibility controls, so don't need explicit
// enum values

View File

@ -41,6 +41,7 @@ public:
m_PadOpacity = 1.0;
m_ZoneOpacity = 1.0;
m_ImageOpacity = 1.0;
m_FilledShapeOpacity = 1.0;
}
/// @see ZONE_DISPLAY_MODE - stored in the project
@ -59,6 +60,7 @@ public:
double m_PadOpacity; ///< Opacity override for SMD pads and PTHs
double m_ZoneOpacity; ///< Opacity override for filled zone areas
double m_ImageOpacity; ///< Opacity override for user images
double m_FilledShapeOpacity; ///< Opacity override for graphic shapes
};
#endif // PCBSTRUCT_H_

View File

@ -127,6 +127,7 @@ public:
double m_ViaOpacity; ///< Opacity override for all types of via
double m_PadOpacity; ///< Opacity override for SMD pads and PTH
double m_ZoneOpacity; ///< Opacity override for filled zones
double m_ShapeOpacity; ///< Opacity override for graphic shapes
double m_ImageOpacity; ///< Opacity override for user images
/**

View File

@ -114,6 +114,7 @@ PCB_RENDER_SETTINGS::PCB_RENDER_SETTINGS()
m_padOpacity = 1.0;
m_zoneOpacity = 1.0;
m_imageOpacity = 1.0;
m_filledShapeOpacity = 1.0;
m_ForcePadSketchModeOn = false;
@ -189,6 +190,7 @@ void PCB_RENDER_SETTINGS::LoadDisplayOptions( const PCB_DISPLAY_OPTIONS& aOption
m_padOpacity = aOptions.m_PadOpacity;
m_zoneOpacity = aOptions.m_ZoneOpacity;
m_imageOpacity = aOptions.m_ImageOpacity;
m_filledShapeOpacity = aOptions.m_FilledShapeOpacity;
}
@ -481,6 +483,8 @@ COLOR4D PCB_RENDER_SETTINGS::GetColor( const BOARD_ITEM* aItem, int aLayer ) con
color.a *= m_zoneOpacity;
else if( aItem->Type() == PCB_REFERENCE_IMAGE_T )
color.a *= m_imageOpacity;
else if( aItem->Type() == PCB_SHAPE_T && static_cast<const PCB_SHAPE*>( aItem )->IsFilled() )
color.a *= m_filledShapeOpacity;
else if( aItem->Type() == PCB_SHAPE_T && aItem->IsOnCopperLayer() )
color.a *= m_trackOpacity;

View File

@ -164,6 +164,7 @@ protected:
double m_padOpacity; ///< Opacity override for SMD pads and PTHs
double m_zoneOpacity; ///< Opacity override for filled zones
double m_imageOpacity; ///< Opacity override for user images
double m_filledShapeOpacity; ///< Opacity override for graphic shapes
};

View File

@ -113,6 +113,7 @@ bool PCB_EDIT_FRAME::LoadProjectSettings()
opts.m_ZoneOpacity = localSettings.m_ZoneOpacity;
opts.m_ZoneDisplayMode = localSettings.m_ZoneDisplayMode;
opts.m_ImageOpacity = localSettings.m_ImageOpacity;
opts.m_FilledShapeOpacity = localSettings.m_ShapeOpacity;
// No refresh here: callers of LoadProjectSettings refresh later
SetDisplayOptions( opts, false );
@ -218,6 +219,7 @@ void PCB_EDIT_FRAME::saveProjectSettings()
localSettings.m_ZoneOpacity = displayOpts.m_ZoneOpacity;
localSettings.m_ZoneDisplayMode = displayOpts.m_ZoneDisplayMode;
localSettings.m_ImageOpacity = displayOpts.m_ImageOpacity;
localSettings.m_ShapeOpacity = displayOpts.m_FilledShapeOpacity;
// Save Design settings
const BOARD_DESIGN_SETTINGS& bds = GetDesignSettings();

View File

@ -181,6 +181,7 @@ void PCBNEW_PRINTOUT::setupViewLayers( KIGFX::VIEW& aView, const LSET& aLayerSet
setVisibility( LAYER_VIA_BBLIND );
setVisibility( LAYER_VIA_THROUGH );
setVisibility( LAYER_ZONES );
setVisibility( LAYER_SHAPES );
setVisibility( LAYER_DRC_WARNING );
setVisibility( LAYER_DRC_ERROR );
@ -218,7 +219,7 @@ void PCBNEW_PRINTOUT::setupViewLayers( KIGFX::VIEW& aView, const LSET& aLayerSet
LAYER_FP_TEXT, LAYER_FP_VALUES, LAYER_FP_REFERENCES,
LAYER_FOOTPRINTS_FR, LAYER_FOOTPRINTS_BK,
LAYER_TRACKS, LAYER_VIAS,
LAYER_ZONES,
LAYER_ZONES, LAYER_SHAPES,
LAYER_PADS, LAYER_PADS_SMD_FR, LAYER_PADS_SMD_BK, LAYER_PADS_TH
};

View File

@ -1811,6 +1811,9 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent )
return 0;
}
// Turn shapes on if they are off, so that the created object will be visible after completion
m_frame->SetObjectVisible( LAYER_SHAPES );
if( !m_view->IsLayerVisible( layer ) )
{
m_frame->GetAppearancePanel()->SetLayerVisible( layer, true );
@ -2070,6 +2073,9 @@ bool DRAWING_TOOL::drawShape( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
m_textAttrs.m_Valign = GR_TEXT_V_ALIGN_TOP;
}
// Turn shapes on if they are off, so that the created object will be visible after completion
m_frame->SetObjectVisible( LAYER_SHAPES );
// geometric construction manager
KIGFX::PREVIEW::TWO_POINT_GEOMETRY_MANAGER twoPointMgr;
@ -2463,6 +2469,9 @@ bool DRAWING_TOOL::drawArc( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
m_stroke.SetColor( COLOR4D::UNSPECIFIED );
}
// Turn shapes on if they are off, so that the created object will be visible after completion
m_frame->SetObjectVisible( LAYER_SHAPES );
// Arc geometric construction manager
KIGFX::PREVIEW::ARC_GEOM_MANAGER arcManager;

View File

@ -2974,6 +2974,11 @@ bool PCB_SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibili
KI_FALLTHROUGH;
case PCB_SHAPE_T:
if( !board()->IsElementVisible( LAYER_SHAPES ) || ( options.m_FilledShapeOpacity == 0.0 ) )
return false;
KI_FALLTHROUGH;
case PCB_TEXTBOX_T:
case PCB_TABLE_T:
case PCB_TABLECELL_T:

View File

@ -325,11 +325,12 @@ const APPEARANCE_CONTROLS::APPEARANCE_SETTING APPEARANCE_CONTROLS::s_objectSetti
#define RR APPEARANCE_CONTROLS::APPEARANCE_SETTING // Render Row abbreviation to reduce source width
// text id tooltip opacity slider
// text id tooltip opacity slider visibility checkbox
RR( _HKI( "Tracks" ), LAYER_TRACKS, _HKI( "Show tracks" ), true ),
RR( _HKI( "Vias" ), LAYER_VIAS, _HKI( "Show all vias" ), true ),
RR( _HKI( "Pads" ), LAYER_PADS, _HKI( "Show all pads" ), true ),
RR( _HKI( "Zones" ), LAYER_ZONES, _HKI( "Show copper zones" ), true ),
RR( _HKI( "Filled Shapes" ), LAYER_SHAPES, _HKI( "Opacity of filled shapes" ), true, false ),
RR( _HKI( "Images" ), LAYER_DRAW_BITMAPS, _HKI( "Show user images" ), true ),
RR(),
RR( _HKI( "Footprints Front" ), LAYER_FOOTPRINTS_FR, _HKI( "Show footprints that are on board's front" ) ),
@ -359,6 +360,7 @@ static std::set<int> s_allowedInFpEditor =
LAYER_VIAS,
LAYER_PADS,
LAYER_ZONES,
LAYER_SHAPES,
LAYER_PADS_TH,
LAYER_FP_VALUES,
LAYER_FP_REFERENCES,
@ -2149,6 +2151,9 @@ void APPEARANCE_CONTROLS::rebuildObjects()
int swatchWidth = m_windowObjects->ConvertDialogToPixels( wxSize( 8, 0 ) ).x;
int labelWidth = 0;
int btnWidth =
KiBitmapBundle( BITMAPS::visibility ).GetPreferredLogicalSizeFor( m_windowObjects ).x;
m_objectSettings.clear();
m_objectsOuterSizer->Clear( true );
m_objectsOuterSizer->AddSpacer( 5 );
@ -2181,29 +2186,34 @@ void APPEARANCE_CONTROLS::rebuildObjects()
}
else
{
sizer->AddSpacer( swatchWidth );
sizer->AddSpacer( swatchWidth );
}
BITMAP_TOGGLE* btn_visible = new BITMAP_TOGGLE(
m_windowObjects, layer, KiBitmapBundle( BITMAPS::visibility ),
KiBitmapBundle( BITMAPS::visibility_off ), aSetting->visible );
BITMAP_TOGGLE* btn_visible = nullptr;
wxString tip;
tip.Printf( _( "Show or hide %s" ), aSetting->label.Lower() );
btn_visible->SetToolTip( tip );
aSetting->ctl_visibility = btn_visible;
if( aSetting->can_control_visibility )
{
btn_visible = new BITMAP_TOGGLE(
m_windowObjects, layer, KiBitmapBundle( BITMAPS::visibility ),
KiBitmapBundle( BITMAPS::visibility_off ), aSetting->visible );
tip.Printf( _( "Show or hide %s" ), aSetting->label.Lower() );
btn_visible->SetToolTip( tip );
aSetting->ctl_visibility = btn_visible;
btn_visible->Bind( TOGGLE_CHANGED,
[&]( wxCommandEvent& aEvent )
{
int id = static_cast<wxWindow*>( aEvent.GetEventObject() )->GetId();
bool isVisible = aEvent.GetInt();
onObjectVisibilityChanged( ToGalLayer( id ), isVisible, true );
} );
}
sizer->AddSpacer( 5 );
btn_visible->Bind( TOGGLE_CHANGED,
[&]( wxCommandEvent& aEvent )
{
int id = static_cast<wxWindow*>( aEvent.GetEventObject() )->GetId();
bool isVisible = aEvent.GetInt();
onObjectVisibilityChanged( ToGalLayer( id ), isVisible, true );
} );
wxStaticText* label = new wxStaticText( m_windowObjects, layer, aSetting->label );
label->Wrap( -1 );
label->SetToolTip( aSetting->tooltip );
@ -2212,11 +2222,19 @@ void APPEARANCE_CONTROLS::rebuildObjects()
{
label->SetMinSize( wxSize( labelWidth, -1 ) );
#ifdef __WXMAC__
sizer->Add( btn_visible, 0, wxALIGN_CENTER_VERTICAL | wxBOTTOM, 10 );
if( btn_visible )
sizer->Add( btn_visible, 0, wxALIGN_CENTER_VERTICAL | wxBOTTOM, 10 );
else
sizer->AddSpacer( btnWidth );
sizer->AddSpacer( 5 );
sizer->Add( label, 0, wxALIGN_CENTER_VERTICAL | wxBOTTOM, 10 );
#else
sizer->Add( btn_visible, 0, wxALIGN_CENTER_VERTICAL, 0 );
if( btn_visible )
sizer->Add( btn_visible, 0, wxALIGN_CENTER_VERTICAL, 0 );
else
sizer->AddSpacer( btnWidth );
sizer->AddSpacer( 5 );
sizer->Add( label, 0, wxALIGN_CENTER_VERTICAL, 0 );
#endif
@ -2250,7 +2268,11 @@ void APPEARANCE_CONTROLS::rebuildObjects()
}
else
{
sizer->Add( btn_visible, 0, wxALIGN_CENTER_VERTICAL, 0 );
if( btn_visible )
sizer->Add( btn_visible, 0, wxALIGN_CENTER_VERTICAL, 0 );
else
sizer->AddSpacer( btnWidth );
sizer->AddSpacer( 5 );
sizer->Add( label, 0, wxALIGN_CENTER_VERTICAL, 0 );
}
@ -2325,13 +2347,15 @@ void APPEARANCE_CONTROLS::syncObjectSettings()
&& m_objectSettingsMap.count( LAYER_VIAS )
&& m_objectSettingsMap.count( LAYER_PADS )
&& m_objectSettingsMap.count( LAYER_ZONES )
&& m_objectSettingsMap.count( LAYER_DRAW_BITMAPS ) );
&& m_objectSettingsMap.count( LAYER_DRAW_BITMAPS )
&& m_objectSettingsMap.count( LAYER_SHAPES ) );
m_objectSettingsMap[LAYER_TRACKS]->ctl_opacity->SetValue( opts.m_TrackOpacity * 100 );
m_objectSettingsMap[LAYER_VIAS]->ctl_opacity->SetValue( opts.m_ViaOpacity * 100 );
m_objectSettingsMap[LAYER_PADS]->ctl_opacity->SetValue( opts.m_PadOpacity * 100 );
m_objectSettingsMap[LAYER_ZONES]->ctl_opacity->SetValue( opts.m_ZoneOpacity * 100 );
m_objectSettingsMap[LAYER_DRAW_BITMAPS]->ctl_opacity->SetValue( opts.m_ImageOpacity * 100 );
m_objectSettingsMap[LAYER_SHAPES]->ctl_opacity->SetValue( opts.m_FilledShapeOpacity * 100 );
}
@ -3039,6 +3063,7 @@ void APPEARANCE_CONTROLS::onObjectOpacitySlider( int aLayer, float aOpacity )
case static_cast<int>( LAYER_PADS ): options.m_PadOpacity = aOpacity; break;
case static_cast<int>( LAYER_ZONES ): options.m_ZoneOpacity = aOpacity; break;
case static_cast<int>( LAYER_DRAW_BITMAPS ): options.m_ImageOpacity = aOpacity; break;
case static_cast<int>( LAYER_SHAPES ): options.m_FilledShapeOpacity = aOpacity; break;
default: return;
}

View File

@ -153,6 +153,7 @@ public:
wxString tooltip;
bool visible;
bool can_control_opacity;
bool can_control_visibility;
bool spacer;
wxPanel* ctl_panel;
@ -164,12 +165,14 @@ public:
APPEARANCE_SETTING( const wxString& aLabel, int aId,
const wxString& aTooltip = wxEmptyString,
bool aCanControlOpacity = false ) :
bool aCanControlOpacity = false,
bool aCanControlVisibility = true ) :
id( aId ),
label( aLabel ),
tooltip( aTooltip ),
visible( true ),
can_control_opacity( aCanControlOpacity ),
can_control_visibility( aCanControlVisibility ),
spacer( false ),
ctl_panel( nullptr ),
ctl_indicator( nullptr ),
@ -184,6 +187,7 @@ public:
id( -1 ),
visible( false ),
can_control_opacity( false ),
can_control_visibility( true ),
spacer( true ),
ctl_panel( nullptr ),
ctl_indicator( nullptr ),