KiCad PCB EDA Suite
Loading...
Searching...
No Matches
symbol_preview_widget.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 modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
21#include <sch_view.h>
24#include <math/vector2wx.h>
25#include <lib_symbol.h>
27#include <sch_preview_panel.h>
28#include <pgm_base.h>
29#include <sch_painter.h>
30#include <eda_draw_frame.h>
31#include <project_sch.h>
32#include <eeschema_settings.h>
34#include <wx/log.h>
35#include <wx/stattext.h>
36
37
38SYMBOL_PREVIEW_WIDGET::SYMBOL_PREVIEW_WIDGET( wxWindow* aParent, KIWAY* aKiway, bool aIncludeStatus,
39 EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType ) :
40 wxPanel( aParent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ),
41 m_kiway( aKiway ),
42 m_preview( nullptr ),
43 m_status( nullptr ),
44 m_statusPanel( nullptr ),
45 m_statusSizer( nullptr ),
46 m_previewItem( nullptr )
47{
48 COMMON_SETTINGS* common_settings = Pgm().GetCommonSettings();
49 EESCHEMA_SETTINGS* app_settings = GetAppSettings<EESCHEMA_SETTINGS>( "eeschema" );
50
51 m_galDisplayOptions.ReadConfig( *common_settings, app_settings->m_Window, this );
52 m_galDisplayOptions.m_forceDisplayCursor = false;
53
54 EDA_DRAW_PANEL_GAL::GAL_TYPE canvasType = aCanvasType;
55
56 // Only a canvas that can draw is allowed
58 && canvasType != EDA_DRAW_PANEL_GAL::GAL_FALLBACK )
59 {
61 }
62
63 m_preview = new SCH_PREVIEW_PANEL( this, wxID_ANY, wxDefaultPosition, wxSize( -1, -1 ),
64 m_galDisplayOptions, canvasType );
65 m_preview->SetStealsFocus( false );
66 m_preview->ShowScrollbars( wxSHOW_SB_NEVER, wxSHOW_SB_NEVER );
67 m_preview->GetGAL()->SetAxesEnabled( false );
68
69 // Do not display the grid: the look is not good for a small canvas area.
70 // But mainly, due to some strange bug I (JPC) was unable to fix, the grid creates
71 // strange artifacts on Windows when Eeschema is run from KiCad manager (but not in
72 // stand alone...).
73 m_preview->GetGAL()->SetGridVisibility( false );
74
75 // Early initialization of the canvas background color,
76 // before any OnPaint event is fired for the canvas using a wrong bg color
77 KIGFX::VIEW* view = m_preview->GetView();
78 m_renderSettings = static_cast<SCH_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
79
80 if( COLOR_SETTINGS* cs = ::GetColorSettings( app_settings ? app_settings->m_ColorTheme : DEFAULT_THEME ) )
81 m_renderSettings->LoadColors( cs );
82
83 const COLOR4D& backgroundColor = m_renderSettings->GetBackgroundColor();
84 const COLOR4D& foregroundColor = m_renderSettings->GetCursorColor();
85
86 m_preview->GetGAL()->SetClearColor( backgroundColor );
87
88 m_renderSettings->m_ShowPinsElectricalType = app_settings->m_LibViewPanel.show_pin_electrical_type;
89 m_renderSettings->m_ShowPinNumbers = app_settings->m_LibViewPanel.show_pin_numbers;
90 m_renderSettings->m_ShowHiddenPins = false;
91 m_renderSettings->m_ShowHiddenFields = false;
92 m_renderSettings->m_ShowPinAltIcons = false;
93 m_renderSettings->m_ShowPinsElectricalType = false;
94
95 m_outerSizer = new wxBoxSizer( wxVERTICAL );
96
97 if( aIncludeStatus )
98 {
99 m_statusPanel = new wxPanel( this );
100 m_statusPanel->SetBackgroundColour( backgroundColor.ToColour() );
101 m_status = new wxStaticText( m_statusPanel, wxID_ANY, wxEmptyString );
102 m_status->SetForegroundColour( m_renderSettings->GetLayerColor( LAYER_REFERENCEPART ).ToColour() );
103 m_statusSizer = new wxBoxSizer( wxVERTICAL );
104 m_statusSizer->Add( 0, 0, 1 ); // add a spacer
105 m_statusSizer->Add( m_status, 0, wxALIGN_CENTER );
106 m_statusSizer->Add( 0, 0, 1 ); // add a spacer
107 m_statusPanel->SetSizer( m_statusSizer );
108
109 // Give the status panel the same color scheme as the canvas so it isn't jarring when
110 // switched to.
111 m_statusPanel->SetBackgroundColour( backgroundColor.ToColour() );
112 m_statusPanel->SetForegroundColour( foregroundColor.ToColour() );
113
114 // Give the preview panel a small top border to align its top with the status panel,
115 // and give the status panel a small bottom border to align its bottom with the preview
116 // panel.
117 m_outerSizer->Add( m_preview, 1, wxTOP | wxEXPAND, 5 );
118 m_outerSizer->Add( m_statusPanel, 1, wxBOTTOM | wxEXPAND, 5 );
119
120 // Hide the status panel to start
121 m_statusPanel->Hide();
122 }
123 else
124 {
125 m_outerSizer->Add( m_preview, 1, wxEXPAND, 0 );
126 }
127
128 SetSizer( m_outerSizer );
129 Layout();
130
131 Connect( wxEVT_SIZE, wxSizeEventHandler( SYMBOL_PREVIEW_WIDGET::onSize ), nullptr, this );
132}
133
134
136{
137 if( m_previewItem )
138 m_preview->GetView()->Remove( m_previewItem );
139
140 delete m_previewItem;
141}
142
143
144void SYMBOL_PREVIEW_WIDGET::SetStatusText( wxString const& aText )
145{
146 wxCHECK( m_statusPanel, /* void */ );
147
148 m_status->SetLabel( aText );
149 m_preview->Hide();
150 m_statusPanel->Show();
151 Layout();
152}
153
154
155void SYMBOL_PREVIEW_WIDGET::onSize( wxSizeEvent& aEvent )
156{
157 if( m_previewItem )
158 {
160 m_preview->ForceRefresh();
161 }
162
163 aEvent.Skip();
164}
165
166
168{
169 if( !m_previewItem )
170 return;
171
172 // set the view scale to fit the item on screen
173 KIGFX::VIEW* view = m_preview->GetView();
174
175 // Calculate the drawing area size, in internal units, for a scaling factor = 1.0
176 view->SetScale( 1.0 );
177 VECTOR2D clientSize = view->ToWorld( ToVECTOR2D( m_preview->GetClientSize() ), false );
178 // Calculate the draw scale to fit the drawing area
179 double scale = std::min( fabs( clientSize.x / (double) m_itemBBox.GetWidth() ),
180 fabs( clientSize.y / (double) m_itemBBox.GetHeight() ) );
181
182 // Above calculation will yield an exact fit; add a bit of whitespace around symbol
183 scale /= 1.2;
184
185 // Now fix the best scale
186 view->SetScale( scale );
187 view->SetCenter( m_itemBBox.Centre() );
188}
189
190
191void SYMBOL_PREVIEW_WIDGET::DisplaySymbol( const LIB_ID& aSymbolID, int aUnit, int aBodyStyle )
192{
193 KIGFX::VIEW* view = m_preview->GetView();
194 std::unique_ptr< LIB_SYMBOL > symbol;
195
196 try
197 {
198 LIB_SYMBOL* tmp = PROJECT_SCH::SymbolLibAdapter( &m_kiway->Prj() )->LoadSymbol( aSymbolID );
199
200 if( tmp )
201 symbol = tmp->Flatten();
202 }
203 catch( const IO_ERROR& ioe )
204 {
205 wxLogError( _( "Error loading symbol %s from library '%s'." ) + wxS( "\n%s" ),
206 aSymbolID.GetLibItemName().wx_str(),
207 aSymbolID.GetLibNickname().wx_str(),
208 ioe.What() );
209 }
210
211 if( m_previewItem )
212 {
213 view->Remove( m_previewItem );
214 delete m_previewItem;
215 m_previewItem = nullptr;
216 }
217
218 if( symbol )
219 {
220 // This will flatten derived parts so that the correct final symbol can be shown.
221 m_previewItem = symbol.release();
222
223 // If unit isn't specified for a multi-unit part, pick the first. (Otherwise we'll draw all of them.)
224 m_renderSettings->m_ShowUnit = ( m_previewItem->IsMultiUnit() && aUnit == 0 ) ? 1 : aUnit;
225
226 // For symbols having multiple body styles, use the first style.
227 m_renderSettings->m_ShowBodyStyle = ( m_previewItem->IsMultiBodyStyle() && aBodyStyle == 0 ) ? 1 : aBodyStyle;
228
229 m_previewItem->SetPreviewUnit( m_renderSettings->m_ShowUnit );
230 m_previewItem->SetPreviewBodyStyle( m_renderSettings->m_ShowBodyStyle );
231
233 {
234 if( cfg->m_AutoplaceFields.enable )
235 m_previewItem->AutoplaceFields( nullptr, AUTOPLACE_AUTO );
236 }
237
238 view->Add( m_previewItem );
239
240 // Get the symbol size, in internal units
241 m_itemBBox = m_previewItem->GetUnitBoundingBox( m_renderSettings->m_ShowUnit,
242 m_renderSettings->m_ShowBodyStyle );
243
244 if( !m_preview->IsShownOnScreen() )
245 {
246 m_preview->Show();
247
248 if( m_statusPanel )
249 m_statusPanel->Hide();
250
251 Layout(); // Ensure panel size is up to date.
252 }
253
254 // Calculate the draw scale to fit the drawing area
256 }
257
258 m_preview->ForceRefresh();
259}
260
261
262void SYMBOL_PREVIEW_WIDGET::DisplayPart( const LIB_SYMBOL* aSymbol, int aUnit, int aBodyStyle )
263{
264 KIGFX::VIEW* view = m_preview->GetView();
265
266 if( m_previewItem )
267 {
268 view->Remove( m_previewItem );
269 delete m_previewItem;
270 m_previewItem = nullptr;
271 }
272
273 if( aSymbol )
274 {
275 m_previewItem = new LIB_SYMBOL( *aSymbol );
276
277 // For symbols having a De Morgan body style, use the first style
278
279 // If unit isn't specified for a multi-unit part, pick the first. (Otherwise we'll draw all of them.)
280 m_renderSettings->m_ShowUnit = ( m_previewItem->IsMultiUnit() && aUnit == 0 ) ? 1 : aUnit;
281
282 m_renderSettings->m_ShowBodyStyle = ( m_previewItem->IsMultiBodyStyle() && aBodyStyle == 0 ) ? 1 : aBodyStyle;
283
284 m_previewItem->SetPreviewUnit( m_renderSettings->m_ShowUnit );
285 m_previewItem->SetPreviewBodyStyle( m_renderSettings->m_ShowBodyStyle );
286
288 {
289 if( cfg->m_AutoplaceFields.enable )
290 m_previewItem->AutoplaceFields( nullptr, AUTOPLACE_AUTO );
291 }
292
293 view->Add( m_previewItem );
294
295 // Get the symbol size, in internal units
296 m_itemBBox = m_previewItem->GetUnitBoundingBox( m_renderSettings->m_ShowUnit,
297 m_renderSettings->m_ShowBodyStyle,
298 true, false );
299
300 // Calculate the draw scale to fit the drawing area
302 }
303
304 m_preview->ForceRefresh();
305 m_preview->Show();
306
307 if( m_statusPanel )
308 m_statusPanel->Hide();
309
310 Layout();
311}
WINDOW_SETTINGS m_Window
wxString m_ColorTheme
Active color theme name.
Color settings are a bit different than most of the settings objects in that there can be more than o...
static constexpr GAL_TYPE GAL_FALLBACK
@ GAL_TYPE_OPENGL
OpenGL implementation.
@ GAL_TYPE_MODERN
RHI implementation, Vulkan or Metal on macOS.
PANEL_LIB_VIEW m_LibViewPanel
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:101
wxColour ToColour() const
Definition color4d.cpp:221
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition view.h:68
virtual void SetScale(double aScale, VECTOR2D aAnchor={ 0, 0 })
Set the scaling factor, zooming around a given anchor point.
Definition view.cpp:901
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition view.cpp:365
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition view.cpp:488
VECTOR2D ToWorld(const VECTOR2D &aCoord, bool aAbsolute=true) const
Converts a screen space point/vector to a point/vector in world space coordinates.
Definition view.cpp:791
PAINTER * GetPainter() const
Return the painter object used by the view for drawing VIEW_ITEM objects.
Definition view.h:242
void SetCenter(const VECTOR2D &aCenter)
Set the center point of the VIEW (i.e.
Definition view.cpp:971
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition kiway.h:348
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:45
const UTF8 & GetLibItemName() const
Definition lib_id.h:98
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition lib_id.h:83
Define a library symbol object.
Definition lib_symbol.h:114
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition pgm_base.cpp:562
static SYMBOL_LIBRARY_ADAPTER * SymbolLibAdapter(PROJECT *aProject)
Accessor for project symbol library manager adapter.
LIB_SYMBOL * LoadSymbol(const wxString &aNickname, const wxString &aName)
Load a LIB_SYMBOL having aName from the library given by aNickname.
LIB_SYMBOL * m_previewItem
A local copy of the LIB_SYMBOL to display on the canvas.
SYMBOL_PREVIEW_WIDGET(wxWindow *aParent, KIWAY *aKiway, bool aIncludeStatus, EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType)
Construct a symbol preview widget.
void SetStatusText(const wxString &aText)
Set the contents of the status label and display it.
EDA_DRAW_PANEL_GAL * m_preview
void onSize(wxSizeEvent &aEvent)
void DisplayPart(const LIB_SYMBOL *aSymbol, int aUnit, int aBodyStyle=0)
BOX2I m_itemBBox
The bounding box of the current item.
GAL_DISPLAY_OPTIONS_IMPL m_galDisplayOptions
SCH_RENDER_SETTINGS * m_renderSettings
void DisplaySymbol(const LIB_ID &aSymbolID, int aUnit, int aBodyStyle=0)
Set the currently displayed symbol.
wxString wx_str() const
Definition utf8.cpp:41
#define _(s)
@ LAYER_REFERENCEPART
Definition layer_ids.h:488
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
@ AUTOPLACE_AUTO
Definition sch_item.h:75
#define DEFAULT_THEME
COLOR_SETTINGS * GetColorSettings(const wxString &aName)
T * GetAppSettings(const char *aFilename)
const int scale
VECTOR2< double > VECTOR2D
Definition vector2d.h:707
VECTOR2D ToVECTOR2D(const wxPoint &aPoint)
Definition vector2wx.h:36