KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcb_diff_canvas_context.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 3
9 * of the License, or (at your option) any later version.
10 */
11
13
14#include <board.h>
15#include <board_item.h>
16#include <eda_item.h>
17#include <footprint.h>
18#include <gal/painter.h>
19#include <layer_ids.h>
20#include <pad.h>
21#include <pcb_display_options.h>
22#include <pcb_draw_panel_gal.h>
23#include <pcb_track.h>
24#include <view/view.h>
26#include <zone.h>
27
28#include <memory>
29#include <set>
30
31
32namespace
33{
34
35class PCB_DIFF_PAINTER : public KIGFX::PCB_PAINTER
36{
37public:
38 PCB_DIFF_PAINTER( KIGFX::GAL* aGal, std::map<KIID, KIGFX::COLOR4D> aOverrides ) :
39 KIGFX::PCB_PAINTER( aGal, FRAME_PCB_EDITOR ),
40 m_overrides( std::move( aOverrides ) ),
41 m_dimmed( std::make_shared<std::set<KIID>>() )
42 {
43 }
44
47 std::shared_ptr<std::set<KIID>> DimmedSet() const { return m_dimmed; }
48
49 bool Draw( const KIGFX::VIEW_ITEM* aItem, int aLayer ) override
50 {
51 const EDA_ITEM* edaItem = dynamic_cast<const EDA_ITEM*>( aItem );
52
53 if( edaItem )
54 {
55 KIID key = edaItem->m_Uuid;
56
57 if( m_overrides.count( key ) == 0 )
58 {
59 if( const BOARD_ITEM* boardItem = dynamic_cast<const BOARD_ITEM*>( aItem ) )
60 {
61 if( const FOOTPRINT* fp = boardItem->GetParentFootprint() )
62 key = fp->m_Uuid;
63 }
64 }
65
66 auto it = m_overrides.find( key );
67
68 if( it != m_overrides.end() && m_dimmed->count( key ) == 0 )
69 {
70 // PCB_PAINTER tints normal items via the layer color, not via
71 // LAYER_BRIGHTENED. Swap the layer color we are drawing on so
72 // the override paints the changed item.
73 KIGFX::PCB_RENDER_SETTINGS* settings = GetSettings();
74 KIGFX::COLOR4D saved = settings->GetLayerColor( aLayer );
75 settings->SetLayerColor( aLayer, it->second );
76
77 bool result = KIGFX::PCB_PAINTER::Draw( aItem, aLayer );
78
79 settings->SetLayerColor( aLayer, saved );
80 return result;
81 }
82 }
83
84 return KIGFX::PCB_PAINTER::Draw( aItem, aLayer );
85 }
86
87private:
88 std::map<KIID, KIGFX::COLOR4D> m_overrides;
89 std::shared_ptr<std::set<KIID>> m_dimmed;
90};
91
92} // namespace
93
94
95namespace KICAD_DIFF
96{
97
98std::vector<KIGFX::VIEW_ITEM*> CollectFootprintDiffContextItems( FOOTPRINT& aFootprint )
99{
100 std::vector<KIGFX::VIEW_ITEM*> items;
101
102 items.push_back( &aFootprint );
103
104 for( PCB_FIELD* field : aFootprint.GetFields() )
105 items.push_back( field );
106
107 for( BOARD_ITEM* item : aFootprint.GraphicalItems() )
108 items.push_back( item );
109
110 for( PAD* pad : aFootprint.Pads() )
111 items.push_back( pad );
112
113 for( ZONE* zone : aFootprint.Zones() )
114 items.push_back( zone );
115
116 return items;
117}
118
119
120std::vector<KIGFX::VIEW_ITEM*> CollectBoardDiffContextItems( BOARD& aBoard )
121{
122 std::vector<KIGFX::VIEW_ITEM*> items;
123
124 for( PCB_TRACK* track : aBoard.Tracks() )
125 items.push_back( track );
126
127 for( ZONE* zone : aBoard.Zones() )
128 items.push_back( zone );
129
130 for( BOARD_ITEM* item : aBoard.Drawings() )
131 items.push_back( item );
132
133 for( FOOTPRINT* fp : aBoard.Footprints() )
134 {
135 std::vector<KIGFX::VIEW_ITEM*> fpItems = CollectFootprintDiffContextItems( *fp );
136 items.insert( items.end(), fpItems.begin(), fpItems.end() );
137 }
138
139 return items;
140}
141
142
144 const KIGFX::COLOR4D& aColor )
145{
146 const KIGFX::COLOR4D gray( 0.45, 0.45, 0.45, 1.0 );
147 const KIGFX::COLOR4D background( 0.97, 0.97, 0.97, 1.0 );
148
149 for( int layer = 0; layer < LAYER_ID_COUNT; ++layer )
150 aSettings.SetLayerColor( layer, gray );
151
152 aSettings.SetLayerColor( LAYER_BRIGHTENED, aColor );
153 aSettings.SetLayerColor( LAYER_PCB_BACKGROUND, background );
154 aSettings.SetBackgroundColor( background );
155
156 PCB_DISPLAY_OPTIONS displayOptions;
159 displayOptions.m_TrackOpacity = 1.0;
160 displayOptions.m_ViaOpacity = 1.0;
161 displayOptions.m_PadOpacity = 1.0;
162 // Zones fill translucent so footprints and traces under a copper pour
163 // stay visible in the compare view.
164 displayOptions.m_ZoneOpacity = 0.5;
165 displayOptions.m_ImageOpacity = 1.0;
166 displayOptions.m_FilledShapeOpacity = 1.0;
167 aSettings.LoadDisplayOptions( displayOptions );
168 aSettings.SetHighContrast( false );
169 aSettings.SetHighlight( false );
170}
171
172
173std::unique_ptr<KIGFX::PAINTER> MakePcbDiffContextPainter( KIGFX::GAL* aGal, const KIGFX::COLOR4D& aColor,
174 std::map<KIID, KIGFX::COLOR4D> aOverrides )
175{
176 auto painter = std::make_unique<PCB_DIFF_PAINTER>( aGal, std::move( aOverrides ) );
177 ConfigurePcbDiffContextRenderSettings( *painter->GetSettings(), aColor );
178
179 return painter;
180}
181
182
183void ConfigurePcbDiffCanvasContext( WIDGET_DIFF_CANVAS& aCanvas, BOARD* aReference, BOARD* aComparison,
184 const KIGFX::COLOR4D& aColor, const std::map<KIID, KIGFX::COLOR4D>& aOverrides,
185 const std::vector<KIGFX::VIEW_ITEM*>& aExtraItems,
186 const std::map<KIID, KICAD_DIFF::CATEGORY>& aCategories )
187{
188 auto painter = std::make_unique<PCB_DIFF_PAINTER>( aCanvas.GetGAL(), aOverrides );
189 ConfigurePcbDiffContextRenderSettings( *painter->GetSettings(), aColor );
190
191 std::shared_ptr<std::set<KIID>> dimmed = painter->DimmedSet();
192 aCanvas.SetContextPainter( std::move( painter ) );
193
194 aCanvas.SetItemDimmer(
195 [dimmed]( KIGFX::VIEW_ITEM* aItem, bool aDim )
196 {
197 EDA_ITEM* eda = dynamic_cast<EDA_ITEM*>( aItem );
198
199 if( !eda )
200 return;
201
202 if( aDim )
203 dimmed->insert( eda->m_Uuid );
204 else
205 dimmed->erase( eda->m_Uuid );
206 } );
207
208 std::vector<KIGFX::VIEW_ITEM*> items;
209
210 if( aReference )
211 {
212 std::vector<KIGFX::VIEW_ITEM*> refItems = CollectBoardDiffContextItems( *aReference );
213 items.insert( items.end(), refItems.begin(), refItems.end() );
214 }
215
216 if( aComparison )
217 {
218 std::vector<KIGFX::VIEW_ITEM*> compItems = CollectBoardDiffContextItems( *aComparison );
219 items.insert( items.end(), compItems.begin(), compItems.end() );
220 }
221
222 items.insert( items.end(), aExtraItems.begin(), aExtraItems.end() );
223
224 aCanvas.SetContextItems( items );
225
226 ApplyPcbGalLayerOrder( aCanvas.GetView() );
227
228 std::map<KIGFX::VIEW_ITEM*, KICAD_DIFF::CATEGORY> itemCategories;
229
230 for( KIGFX::VIEW_ITEM* viewItem : items )
231 {
232 EDA_ITEM* edaItem = dynamic_cast<EDA_ITEM*>( viewItem );
233
234 if( !edaItem )
235 continue;
236
237 auto it = aCategories.find( edaItem->m_Uuid );
238
239 if( it != aCategories.end() )
240 itemCategories[viewItem] = it->second;
241 }
242
243 aCanvas.SetItemCategories( std::move( itemCategories ) );
244}
245
246} // namespace KICAD_DIFF
@ NORMAL
Inactive layers are shown normally (no high-contrast mode)
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:80
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:320
const ZONES & Zones() const
Definition board.h:372
const FOOTPRINTS & Footprints() const
Definition board.h:368
const TRACKS & Tracks() const
Definition board.h:366
const DRAWINGS & Drawings() const
Definition board.h:370
virtual KIGFX::VIEW * GetView() const
Return a pointer to the #VIEW instance used in the panel.
KIGFX::GAL * GetGAL() const
Return a pointer to the GAL instance used in the panel.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:96
const KIID m_Uuid
Definition eda_item.h:531
ZONES & Zones()
Definition footprint.h:379
std::deque< PAD * > & Pads()
Definition footprint.h:373
void GetFields(std::vector< PCB_FIELD * > &aVector, bool aVisibleOnly) const
Populate a std::vector with PCB_TEXTs.
DRAWINGS & GraphicalItems()
Definition footprint.h:376
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:101
Abstract interface for drawing on a 2D-surface.
Contains methods for drawing PCB-specific items.
virtual bool Draw(const VIEW_ITEM *aItem, int aLayer) override
Takes an instance of VIEW_ITEM and passes it to a function that knows how to draw the item.
PCB specific render settings.
Definition pcb_painter.h:78
void SetBackgroundColor(const COLOR4D &aColor) override
Set the background color.
void LoadDisplayOptions(const PCB_DISPLAY_OPTIONS &aOptions)
Load settings related to display options (high-contrast mode, full or outline modes for vias/pads/tra...
void SetLayerColor(int aLayer, const COLOR4D &aColor)
Change the color used to draw a layer.
void SetHighContrast(bool aEnabled)
Turns on/off high contrast display mode.
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
void SetHighlight(bool aEnabled, int aNetcode=-1, bool aMulti=false)
Turns on/off highlighting.
An abstract base class for deriving all objects that can be added to a VIEW.
Definition view_item.h:82
Definition pad.h:61
double m_TrackOpacity
Opacity override for all tracks.
double m_FilledShapeOpacity
Opacity override for graphic shapes.
double m_ZoneOpacity
Opacity override for filled zone areas.
double m_ImageOpacity
Opacity override for user images.
double m_PadOpacity
Opacity override for SMD pads and PTHs.
double m_ViaOpacity
Opacity override for all types of via.
HIGH_CONTRAST_MODE m_ContrastModeDisplay
How inactive layers are displayed.
ZONE_DISPLAY_MODE m_ZoneDisplayMode
GAL-backed canvas for visualizing a KICAD_DIFF::DIFF_SCENE.
void SetContextItems(const std::vector< KIGFX::VIEW_ITEM * > &aItems)
Replace source document context items.
void SetItemCategories(std::map< KIGFX::VIEW_ITEM *, KICAD_DIFF::CATEGORY > aMap)
Tag context items by change category so SetCategoryVisible can hide / show them in lockstep with the ...
void SetContextPainter(std::unique_ptr< KIGFX::PAINTER > aPainter)
Install the native painter used for drawing source document context.
void SetItemDimmer(DIMMER aDimmer)
Handle a list of polygons defining a copper zone.
Definition zone.h:70
@ FRAME_PCB_EDITOR
Definition frame_type.h:38
#define LAYER_ID_COUNT
Must update this if you add any enums after Gerbview!
Definition layer_ids.h:624
@ LAYER_PCB_BACKGROUND
PCB background color.
Definition layer_ids.h:277
@ LAYER_BRIGHTENED
Definition layer_ids.h:489
std::vector< KIGFX::VIEW_ITEM * > CollectBoardDiffContextItems(BOARD &aBoard)
void ConfigurePcbDiffCanvasContext(WIDGET_DIFF_CANVAS &aCanvas, BOARD *aReference, BOARD *aComparison, const KIGFX::COLOR4D &aColor, const std::map< KIID, KIGFX::COLOR4D > &aOverrides, const std::vector< KIGFX::VIEW_ITEM * > &aExtraItems, const std::map< KIID, KICAD_DIFF::CATEGORY > &aCategories)
std::unique_ptr< KIGFX::PAINTER > MakePcbDiffContextPainter(KIGFX::GAL *aGal, const KIGFX::COLOR4D &aColor, std::map< KIID, KIGFX::COLOR4D > aOverrides)
void ConfigurePcbDiffContextRenderSettings(KIGFX::PCB_RENDER_SETTINGS &aSettings, const KIGFX::COLOR4D &aColor)
std::vector< KIGFX::VIEW_ITEM * > CollectFootprintDiffContextItems(FOOTPRINT &aFootprint)
void ApplyPcbGalLayerOrder(KIGFX::VIEW *aView)
Apply pcbnew's canonical GAL layer order (copper and zones below silk, fab and courtyard) to any view...
wxString result
Test unit parsing edge cases and error handling.