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
14
15#include <board.h>
16#include <board_item.h>
17#include <eda_item.h>
18#include <footprint.h>
19#include <gal/painter.h>
20#include <layer_ids.h>
21#include <pad.h>
22#include <pcb_display_options.h>
23#include <pcb_draw_panel_gal.h>
24#include <pcb_track.h>
25#include <view/view.h>
27#include <zone.h>
28
29#include <memory>
30#include <set>
31
32
33namespace
34{
35
36class PCB_DIFF_PAINTER : public KIGFX::PCB_PAINTER
37{
38public:
39 PCB_DIFF_PAINTER( KIGFX::GAL* aGal, std::map<KIID, KIGFX::COLOR4D> aOverrides ) :
40 KIGFX::PCB_PAINTER( aGal, FRAME_PCB_EDITOR ),
41 m_overrides( std::move( aOverrides ) ),
42 m_dimmed( std::make_shared<std::set<KIID>>() )
43 {
44 }
45
48 std::shared_ptr<std::set<KIID>> DimmedSet() const { return m_dimmed; }
49
50 bool Draw( const KIGFX::VIEW_ITEM* aItem, int aLayer ) override
51 {
52 const EDA_ITEM* edaItem = dynamic_cast<const EDA_ITEM*>( aItem );
53
54 if( edaItem )
55 {
56 KIID key = KICAD_DIFF::PcbDiffItemId( *edaItem );
57
58 if( m_overrides.count( key ) == 0 )
59 {
60 if( const BOARD_ITEM* boardItem = dynamic_cast<const BOARD_ITEM*>( aItem ) )
61 {
62 if( const FOOTPRINT* fp = boardItem->GetParentFootprint() )
63 key = fp->m_Uuid;
64 }
65 }
66
67 auto it = m_overrides.find( key );
68
69 if( it != m_overrides.end() && m_dimmed->count( key ) == 0 )
70 {
71 // PCB_PAINTER tints normal items via the layer color, not via
72 // LAYER_BRIGHTENED. Swap the layer color we are drawing on so
73 // the override paints the changed item.
74 KIGFX::PCB_RENDER_SETTINGS* settings = GetSettings();
75 KIGFX::COLOR4D saved = settings->GetLayerColor( aLayer );
76 settings->SetLayerColor( aLayer, it->second );
77
78 bool result = KIGFX::PCB_PAINTER::Draw( aItem, aLayer );
79
80 settings->SetLayerColor( aLayer, saved );
81 return result;
82 }
83 }
84
85 return KIGFX::PCB_PAINTER::Draw( aItem, aLayer );
86 }
87
88private:
89 std::map<KIID, KIGFX::COLOR4D> m_overrides;
90 std::shared_ptr<std::set<KIID>> m_dimmed;
91};
92
93} // namespace
94
95
96namespace KICAD_DIFF
97{
98
99std::vector<KIGFX::VIEW_ITEM*> CollectFootprintDiffContextItems( FOOTPRINT& aFootprint )
100{
101 std::vector<KIGFX::VIEW_ITEM*> items;
102
103 items.push_back( &aFootprint );
104
105 for( PCB_FIELD* field : aFootprint.GetFields() )
106 items.push_back( field );
107
108 for( BOARD_ITEM* item : aFootprint.GraphicalItems() )
109 items.push_back( item );
110
111 for( PAD* pad : aFootprint.Pads() )
112 items.push_back( pad );
113
114 for( ZONE* zone : aFootprint.Zones() )
115 items.push_back( zone );
116
117 return items;
118}
119
120
121std::vector<KIGFX::VIEW_ITEM*> CollectBoardDiffContextItems( BOARD& aBoard )
122{
123 std::vector<KIGFX::VIEW_ITEM*> items;
124
125 for( PCB_TRACK* track : aBoard.Tracks() )
126 items.push_back( track );
127
128 for( ZONE* zone : aBoard.Zones() )
129 items.push_back( zone );
130
131 for( BOARD_ITEM* item : aBoard.Drawings() )
132 items.push_back( item );
133
134 for( FOOTPRINT* fp : aBoard.Footprints() )
135 {
136 std::vector<KIGFX::VIEW_ITEM*> fpItems = CollectFootprintDiffContextItems( *fp );
137 items.insert( items.end(), fpItems.begin(), fpItems.end() );
138 }
139
140 return items;
141}
142
143
145 const KIGFX::COLOR4D& aColor )
146{
147 const KIGFX::COLOR4D gray( 0.45, 0.45, 0.45, 1.0 );
148 const KIGFX::COLOR4D background( 0.97, 0.97, 0.97, 1.0 );
149
150 for( int layer = 0; layer < LAYER_ID_COUNT; ++layer )
151 aSettings.SetLayerColor( layer, gray );
152
153 aSettings.SetLayerColor( LAYER_BRIGHTENED, aColor );
154 aSettings.SetLayerColor( LAYER_PCB_BACKGROUND, background );
155 aSettings.SetBackgroundColor( background );
156
157 PCB_DISPLAY_OPTIONS displayOptions;
160 displayOptions.m_TrackOpacity = 1.0;
161 displayOptions.m_ViaOpacity = 1.0;
162 displayOptions.m_PadOpacity = 1.0;
163 // Zones fill translucent so footprints and traces under a copper pour
164 // stay visible in the compare view.
165 displayOptions.m_ZoneOpacity = 0.5;
166 displayOptions.m_ImageOpacity = 1.0;
167 displayOptions.m_FilledShapeOpacity = 1.0;
168 aSettings.LoadDisplayOptions( displayOptions );
169 aSettings.SetHighContrast( false );
170 aSettings.SetHighlight( false );
171}
172
173
174std::unique_ptr<KIGFX::PAINTER> MakePcbDiffContextPainter( KIGFX::GAL* aGal, const KIGFX::COLOR4D& aColor,
175 std::map<KIID, KIGFX::COLOR4D> aOverrides )
176{
177 auto painter = std::make_unique<PCB_DIFF_PAINTER>( aGal, std::move( aOverrides ) );
178 ConfigurePcbDiffContextRenderSettings( *painter->GetSettings(), aColor );
179
180 return painter;
181}
182
183
184void ConfigurePcbDiffCanvasContext( WIDGET_DIFF_CANVAS& aCanvas, BOARD* aReference, BOARD* aComparison,
185 const KIGFX::COLOR4D& aColor, const std::map<KIID, KIGFX::COLOR4D>& aOverrides,
186 const std::vector<KIGFX::VIEW_ITEM*>& aExtraItems,
187 const std::map<KIID, KICAD_DIFF::CATEGORY>& aCategories )
188{
189 auto painter = std::make_unique<PCB_DIFF_PAINTER>( aCanvas.GetGAL(), aOverrides );
190 ConfigurePcbDiffContextRenderSettings( *painter->GetSettings(), aColor );
191
192 std::shared_ptr<std::set<KIID>> dimmed = painter->DimmedSet();
193 aCanvas.SetContextPainter( std::move( painter ) );
195
196 aCanvas.SetItemDimmer(
197 [dimmed]( KIGFX::VIEW_ITEM* aItem, bool aDim )
198 {
199 EDA_ITEM* eda = dynamic_cast<EDA_ITEM*>( aItem );
200
201 if( !eda )
202 return;
203
204 if( aDim )
205 dimmed->insert( PcbDiffItemId( *eda ) );
206 else
207 dimmed->erase( PcbDiffItemId( *eda ) );
208 } );
209
210 std::vector<KIGFX::VIEW_ITEM*> items;
211
212 if( aReference )
213 {
214 std::vector<KIGFX::VIEW_ITEM*> refItems = CollectBoardDiffContextItems( *aReference );
215 items.insert( items.end(), refItems.begin(), refItems.end() );
216 }
217
218 if( aComparison )
219 {
220 std::vector<KIGFX::VIEW_ITEM*> compItems = CollectBoardDiffContextItems( *aComparison );
221 items.insert( items.end(), compItems.begin(), compItems.end() );
222 }
223
224 items.insert( items.end(), aExtraItems.begin(), aExtraItems.end() );
225
226 aCanvas.SetContextItems( items );
227
228 ApplyPcbGalLayerOrder( aCanvas.GetView() );
229
230 std::map<KIGFX::VIEW_ITEM*, KICAD_DIFF::CATEGORY> itemCategories;
231
232 for( KIGFX::VIEW_ITEM* viewItem : items )
233 {
234 EDA_ITEM* edaItem = dynamic_cast<EDA_ITEM*>( viewItem );
235
236 if( !edaItem )
237 continue;
238
239 auto it = aCategories.find( PcbDiffItemId( *edaItem ) );
240
241 if( it != aCategories.end() )
242 itemCategories[viewItem] = it->second;
243 }
244
245 aCanvas.SetItemCategories( std::move( itemCategories ) );
246}
247
248} // 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:84
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:410
const ZONES & Zones() const
Definition board.h:468
const FOOTPRINTS & Footprints() const
Definition board.h:464
const TRACKS & Tracks() const
Definition board.h:462
const DRAWINGS & Drawings() const
Definition board.h:466
virtual KIGFX::VIEW * GetView() const
Return a pointer to the KIGFX::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:98
ZONES & Zones()
Definition footprint.h:411
std::deque< PAD * > & Pads()
Definition footprint.h:405
void GetFields(std::vector< PCB_FIELD * > &aVector, bool aVisibleOnly) const
Populate a std::vector with PCB_TEXTs.
DRAWINGS & GraphicalItems()
Definition footprint.h:408
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:84
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 SetItemIdGetter(const ITEM_ID_GETTER &aGetter)
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:652
@ LAYER_PCB_BACKGROUND
PCB background color.
Definition layer_ids.h:277
@ LAYER_BRIGHTENED
Definition layer_ids.h:513
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)
KIID PcbDiffItemId(const EDA_ITEM &aItem)
Fields match by parent footprint and untranslated name, including after a library refresh.
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.