1 /*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2016-2020 KiCad Developers, see AUTHORS.txt for contributors.
5 * Copyright (C) 2017 Chris Pavlina <pavlina.chris@gmail.com>
6 * Copyright (C) 2016 Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include <memory>
23 #include <utility>
24
25 #include "pcbnew_settings.h"
26 #include <board.h>
27 #include <footprint.h>
28 #include <eda_draw_frame.h>
29 #include <footprint_preview_panel.h>
30 #include <fp_lib_table.h>
31 #include <kiway.h>
32 #include <math/box2.h>
33 #include <pcb_painter.h>
34 #include <pcb_draw_panel_gal.h>
35 #include <pcb_edit_frame.h>
36 #include <pgm_base.h>
37 #include <settings/settings_manager.h>
38 #include <view/view.h>
39 #include <wx/stattext.h>
40 #include <zoom_defines.h>
41
FOOTPRINT_PREVIEW_PANEL(KIWAY * aKiway,wxWindow * aParent,std::unique_ptr<KIGFX::GAL_DISPLAY_OPTIONS> aOpts,GAL_TYPE aGalType)42 FOOTPRINT_PREVIEW_PANEL::FOOTPRINT_PREVIEW_PANEL( KIWAY* aKiway, wxWindow* aParent,
43 std::unique_ptr<KIGFX::GAL_DISPLAY_OPTIONS> aOpts,
44 GAL_TYPE aGalType ) :
45 PCB_DRAW_PANEL_GAL( aParent, -1, wxPoint( 0, 0 ), wxSize( 200, 200 ), *aOpts, aGalType ),
46 KIWAY_HOLDER( aKiway, KIWAY_HOLDER::PANEL ),
47 m_displayOptions( std::move( aOpts ) ),
48 m_currentFootprint( nullptr )
49 {
50 SetStealsFocus( false );
51 ShowScrollbars( wxSHOW_SB_NEVER, wxSHOW_SB_NEVER );
52 EnableScrolling( false, false ); // otherwise Zoom Auto disables GAL canvas
53
54 m_dummyBoard = std::make_unique<BOARD>();
55 UpdateColors();
56 SyncLayersVisibility( m_dummyBoard.get() );
57
58 Raise();
59 Show( true );
60 StartDrawing();
61 }
62
63
~FOOTPRINT_PREVIEW_PANEL()64 FOOTPRINT_PREVIEW_PANEL::~FOOTPRINT_PREVIEW_PANEL( )
65 {
66 if( m_currentFootprint )
67 {
68 GetView()->Remove( m_currentFootprint.get() );
69 GetView()->Clear();
70 m_currentFootprint->SetParent( nullptr );
71 }
72 }
73
74
GetBackgroundColor()75 const COLOR4D& FOOTPRINT_PREVIEW_PANEL::GetBackgroundColor()
76 {
77 KIGFX::PAINTER* painter = GetView()->GetPainter();
78 auto settings = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( painter->GetSettings() );
79
80 return settings->GetBackgroundColor();
81 }
82
83
GetForegroundColor()84 const COLOR4D& FOOTPRINT_PREVIEW_PANEL::GetForegroundColor()
85 {
86 KIGFX::PAINTER* painter = GetView()->GetPainter();
87 auto settings = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( painter->GetSettings() );
88
89 return settings->GetCursorColor();
90 }
91
92
renderFootprint(std::shared_ptr<FOOTPRINT> aFootprint)93 void FOOTPRINT_PREVIEW_PANEL::renderFootprint( std::shared_ptr<FOOTPRINT> aFootprint )
94 {
95 if( m_currentFootprint )
96 {
97 GetView()->Remove( m_currentFootprint.get() );
98 GetView()->Clear();
99 m_currentFootprint->SetParent( nullptr );
100 }
101
102 m_currentFootprint = aFootprint;
103
104 if( !m_currentFootprint )
105 return;
106
107 m_currentFootprint->SetParent( m_dummyBoard.get() );
108
109 // Ensure we are not using the high contrast mode to display the selected footprint
110 KIGFX::PAINTER* painter = GetView()->GetPainter();
111 auto settings = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( painter->GetSettings() );
112 settings->SetContrastModeDisplay( HIGH_CONTRAST_MODE::NORMAL );
113
114 GetView()->Add( m_currentFootprint.get() );
115 GetView()->SetVisible( m_currentFootprint.get(), true );
116 GetView()->Update( m_currentFootprint.get(), KIGFX::ALL );
117
118 BOX2I bbox = m_currentFootprint->ViewBBox();
119 bbox.Merge( m_currentFootprint->Value().ViewBBox() );
120 bbox.Merge( m_currentFootprint->Reference().ViewBBox() );
121
122 if( bbox.GetSize().x > 0 && bbox.GetSize().y > 0 )
123 {
124 // Autozoom
125 GetView()->SetViewport( BOX2D( bbox.GetOrigin(), bbox.GetSize() ) );
126
127 // Add a margin
128 GetView()->SetScale( GetView()->GetScale() * 0.7 );
129
130 Refresh();
131 }
132 }
133
134
DisplayFootprint(const LIB_ID & aFPID)135 bool FOOTPRINT_PREVIEW_PANEL::DisplayFootprint( const LIB_ID& aFPID )
136 {
137 FP_LIB_TABLE* fptbl = Prj().PcbFootprintLibs();
138
139 try
140 {
141 const FOOTPRINT* fp = fptbl->GetEnumeratedFootprint( aFPID.GetLibNickname(), aFPID.GetLibItemName() );
142
143 if( fp )
144 m_currentFootprint.reset( static_cast<FOOTPRINT*>( fp->Duplicate() ) );
145 else
146 m_currentFootprint.reset();
147 }
148 catch( ... )
149 {
150 m_currentFootprint.reset();
151 }
152
153 renderFootprint( m_currentFootprint );
154 Refresh();
155
156 return m_currentFootprint != nullptr;
157 }
158
159
GetWindow()160 wxWindow* FOOTPRINT_PREVIEW_PANEL::GetWindow()
161 {
162 return static_cast<wxWindow*>( this );
163 }
164
165
New(KIWAY * aKiway,wxWindow * aParent)166 FOOTPRINT_PREVIEW_PANEL* FOOTPRINT_PREVIEW_PANEL::New( KIWAY* aKiway, wxWindow* aParent )
167 {
168 PCBNEW_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings<PCBNEW_SETTINGS>();
169
170 if( cfg->m_Window.grid.sizes.empty() )
171 cfg->m_Window.grid.sizes = cfg->DefaultGridSizeList();
172
173 // Currently values read from config file are not used because the user cannot
174 // change this config
175 //if( cfg->m_Window.zoom_factors.empty() )
176 {
177 cfg->m_Window.zoom_factors = { ZOOM_LIST_PCBNEW };
178 }
179
180 std::unique_ptr<KIGFX::GAL_DISPLAY_OPTIONS> gal_opts;
181
182 gal_opts = std::make_unique<KIGFX::GAL_DISPLAY_OPTIONS>();
183 gal_opts->ReadConfig( *Pgm().GetCommonSettings(), cfg->m_Window, aParent );
184
185 auto canvasType = static_cast<EDA_DRAW_PANEL_GAL::GAL_TYPE>( cfg->m_Graphics.canvas_type );
186 auto panel = new FOOTPRINT_PREVIEW_PANEL( aKiway, aParent, std::move( gal_opts ), canvasType );
187
188 panel->UpdateColors();
189
190 const GRID_SETTINGS& gridCfg = cfg->m_Window.grid;
191
192 panel->GetGAL()->SetGridVisibility( gridCfg.show );
193
194 //Bounds checking cannot include number of elements as an index!
195 int gridIdx = std::max( 0, std::min( gridCfg.last_size_idx, (int) gridCfg.sizes.size() - 1 ) );
196 int gridSize = (int) ValueFromString( EDA_UNITS::MILS, gridCfg.sizes[ gridIdx ] );
197 panel->GetGAL()->SetGridSize( VECTOR2D( gridSize, gridSize ) );
198
199 return panel;
200 }
201