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 (C) 2018-2021 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 along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
21#include <sch_view.h>
24#include <math/vector2wx.h>
25#include <symbol_lib_table.h>
26#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 auto common_settings = Pgm().GetCommonSettings();
49 auto app_settings = Pgm().GetSettingsManager().GetAppSettings<EESCHEMA_SETTINGS>();
50
51 m_galDisplayOptions.ReadConfig( *common_settings, app_settings->m_Window, this );
53
54 EDA_DRAW_PANEL_GAL::GAL_TYPE canvasType = aCanvasType;
55
56 // Allows only a CAIRO or OPENGL canvas:
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...).
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 auto settings = static_cast<SCH_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
79
80 if( auto* theme = Pgm().GetSettingsManager().GetColorSettings( app_settings->m_ColorTheme ) )
81 settings->LoadColors( theme );
82
83 const COLOR4D& backgroundColor = settings->GetBackgroundColor();
84 const COLOR4D& foregroundColor = settings->GetCursorColor();
85
86 m_preview->GetGAL()->SetClearColor( backgroundColor );
87
88 settings->m_ShowPinsElectricalType = app_settings->m_LibViewPanel.show_pin_electrical_type;
89 settings->m_ShowPinNumbers = app_settings->m_LibViewPanel.show_pin_numbers;
90 settings->m_ShowHiddenPins = false;
91 settings->m_ShowHiddenFields = false;
92
93 m_outerSizer = new wxBoxSizer( wxVERTICAL );
94
95 if( aIncludeStatus )
96 {
97 m_statusPanel = new wxPanel( this );
98 m_statusPanel->SetBackgroundColour( backgroundColor.ToColour() );
99 m_status = new wxStaticText( m_statusPanel, wxID_ANY, wxEmptyString );
100 m_status->SetForegroundColour( settings->GetLayerColor( LAYER_REFERENCEPART ).ToColour() );
101 m_statusSizer = new wxBoxSizer( wxVERTICAL );
102 m_statusSizer->Add( 0, 0, 1 ); // add a spacer
103 m_statusSizer->Add( m_status, 0, wxALIGN_CENTER );
104 m_statusSizer->Add( 0, 0, 1 ); // add a spacer
105 m_statusPanel->SetSizer( m_statusSizer );
106
107 // Give the status panel the same color scheme as the canvas so it isn't jarring when
108 // switched to.
109 m_statusPanel->SetBackgroundColour( backgroundColor.ToColour() );
110 m_statusPanel->SetForegroundColour( foregroundColor.ToColour() );
111
112 // Give the preview panel a small top border to align its top with the status panel,
113 // and give the status panel a small bottom border to align its bottom with the preview
114 // panel.
115 m_outerSizer->Add( m_preview, 1, wxTOP | wxEXPAND, 5 );
116 m_outerSizer->Add( m_statusPanel, 1, wxBOTTOM | wxEXPAND, 5 );
117
118 // Hide the status panel to start
119 m_statusPanel->Hide();
120 }
121 else
122 {
123 m_outerSizer->Add( m_preview, 1, wxEXPAND, 0 );
124 }
125
126 SetSizer( m_outerSizer );
127 Layout();
128
129 Connect( wxEVT_SIZE, wxSizeEventHandler( SYMBOL_PREVIEW_WIDGET::onSize ), nullptr, this );
130}
131
132
134{
135 if( m_previewItem )
137
138 delete m_previewItem;
139}
140
141
142void SYMBOL_PREVIEW_WIDGET::SetStatusText( wxString const& aText )
143{
144 wxCHECK( m_statusPanel, /* void */ );
145
146 m_status->SetLabel( aText );
147 m_preview->Hide();
148 m_statusPanel->Show();
149 Layout();
150}
151
152
153void SYMBOL_PREVIEW_WIDGET::onSize( wxSizeEvent& aEvent )
154{
155 if( m_previewItem )
156 {
159 }
160
161 aEvent.Skip();
162}
163
164
166{
167 if( !m_previewItem )
168 return;
169
170 // set the view scale to fit the item on screen
171 KIGFX::VIEW* view = m_preview->GetView();
172
173 // Calculate the drawing area size, in internal units, for a scaling factor = 1.0
174 view->SetScale( 1.0 );
175 VECTOR2D clientSize = view->ToWorld( ToVECTOR2D( m_preview->GetClientSize() ), false );
176 // Calculate the draw scale to fit the drawing area
177 double scale = std::min( fabs( clientSize.x / m_itemBBox.GetWidth() ),
178 fabs( clientSize.y / m_itemBBox.GetHeight() ) );
179
180 // Above calculation will yield an exact fit; add a bit of whitespace around symbol
181 scale /= 1.2;
182
183 // Now fix the best scale
184 view->SetScale( scale );
185 view->SetCenter( m_itemBBox.Centre() );
186}
187
188
189void SYMBOL_PREVIEW_WIDGET::DisplaySymbol( const LIB_ID& aSymbolID, int aUnit, int aBodyStyle )
190{
191 KIGFX::VIEW* view = m_preview->GetView();
192 auto settings = static_cast<SCH_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
193 std::unique_ptr< LIB_SYMBOL > symbol;
194
195 try
196 {
198
199 if( tmp )
200 symbol = tmp->Flatten();
201 }
202 catch( const IO_ERROR& ioe )
203 {
204 wxLogError( _( "Error loading symbol %s from library '%s'." ) + wxS( "\n%s" ),
205 aSymbolID.GetLibItemName().wx_str(),
206 aSymbolID.GetLibNickname().wx_str(),
207 ioe.What() );
208 }
209
210 if( m_previewItem )
211 {
212 view->Remove( m_previewItem );
213 delete m_previewItem;
214 m_previewItem = nullptr;
215 }
216
217 if( symbol )
218 {
219 // This will flatten derived parts so that the correct final symbol can be shown.
220 m_previewItem = symbol.release();
221
222 // Hide fields that were added automatically by the library (for example, when using
223 // database libraries) as they don't have a valid position yet, and we don't support
224 // autoplacing fields on library symbols yet.
225 std::vector<SCH_FIELD*> previewFields;
226 m_previewItem->GetFields( previewFields );
227
228 for( SCH_FIELD* field : previewFields )
229 {
230 if( field->IsAutoAdded() )
231 field->SetVisible( false );
232 }
233
234 // If unit isn't specified for a multi-unit part, pick the first. (Otherwise we'll
235 // draw all of them.)
236 settings->m_ShowUnit = ( m_previewItem->IsMulti() && aUnit == 0 ) ? 1 : aUnit;
237
238 // For symbols having a De Morgan body style, use the first style
239 settings->m_ShowBodyStyle =
240 ( m_previewItem->HasAlternateBodyStyle() && aBodyStyle == 0 ) ? 1 : aBodyStyle;
241
242 view->Add( m_previewItem );
243
244 // Get the symbol size, in internal units
245 m_itemBBox = m_previewItem->GetUnitBoundingBox( settings->m_ShowUnit,
246 settings->m_ShowBodyStyle );
247
248 if( !m_preview->IsShownOnScreen() )
249 {
250 m_preview->Show();
251
252 if( m_statusPanel )
253 m_statusPanel->Hide();
254
255 Layout(); // Ensure panel size is up to date.
256 }
257
258 // Calculate the draw scale to fit the drawing area
260 }
261
263}
264
265
266void SYMBOL_PREVIEW_WIDGET::DisplayPart( LIB_SYMBOL* aSymbol, int aUnit, int aBodyStyle )
267{
268 KIGFX::VIEW* view = m_preview->GetView();
269
270 if( m_previewItem )
271 {
272 view->Remove( m_previewItem );
273 delete m_previewItem;
274 m_previewItem = nullptr;
275 }
276
277 if( aSymbol )
278 {
279 m_previewItem = new LIB_SYMBOL( *aSymbol );
280
281 // For symbols having a De Morgan body style, use the first style
282 auto settings = static_cast<SCH_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
283
284 // If unit isn't specified for a multi-unit part, pick the first. (Otherwise we'll
285 // draw all of them.)
286 settings->m_ShowUnit = ( m_previewItem->IsMulti() && aUnit == 0 ) ? 1 : aUnit;
287
288 settings->m_ShowBodyStyle =
289 ( m_previewItem->HasAlternateBodyStyle() && aBodyStyle == 0 ) ? 1 : aBodyStyle;
290
291 view->Add( m_previewItem );
292
293 // Get the symbol size, in internal units
294 m_itemBBox = aSymbol->GetUnitBoundingBox( settings->m_ShowUnit, settings->m_ShowBodyStyle );
295
296 // Calculate the draw scale to fit the drawing area
298 }
299
301 m_preview->Show();
302
303 if( m_statusPanel )
304 m_statusPanel->Hide();
305
306 Layout();
307}
size_type GetHeight() const
Definition: box2.h:205
size_type GetWidth() const
Definition: box2.h:204
Vec Centre() const
Definition: box2.h:87
static constexpr GAL_TYPE GAL_FALLBACK
virtual KIGFX::VIEW * GetView() const
Return a pointer to the #VIEW instance used in the panel.
void ForceRefresh()
Force a redraw.
@ GAL_TYPE_OPENGL
OpenGL implementation.
KIGFX::GAL * GetGAL() const
Return a pointer to the GAL instance used in the panel.
void SetStealsFocus(bool aStealsFocus)
Set whether focus is taken on certain events (mouseover, keys, etc).
void ReadConfig(COMMON_SETTINGS &aCommonConfig, WINDOW_SETTINGS &aWindowConfig, wxWindow *aWindow)
Read application and common configs.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:77
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
wxColour ToColour() const
Definition: color4d.cpp:220
bool m_forceDisplayCursor
The pixel scale factor (>1 for hi-DPI scaled displays)
void SetAxesEnabled(bool aAxesEnabled)
Enable drawing the axes.
void SetClearColor(const COLOR4D &aColor)
void SetGridVisibility(bool aVisibility)
Set the visibility setting of the grid.
virtual RENDER_SETTINGS * GetSettings()=0
Return a pointer to current settings that are going to be used when drawing items.
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:552
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition: view.cpp:315
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition: view.cpp:354
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:449
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:215
void SetCenter(const VECTOR2D &aCenter)
Set the center point of the VIEW (i.e.
Definition: view.cpp:578
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition: kiway.h:279
virtual PROJECT & Prj() const
Return the PROJECT associated with this KIWAY.
Definition: kiway.cpp:196
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
const UTF8 & GetLibItemName() const
Definition: lib_id.h:102
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:87
Define a library symbol object.
Definition: lib_symbol.h:77
bool IsMulti() const override
Definition: lib_symbol.h:541
const BOX2I GetUnitBoundingBox(int aUnit, int aBodyStyle, bool aIgnoreHiddenFields=true) const
Get the bounding box for the symbol.
void GetFields(std::vector< SCH_FIELD * > &aList)
Return a list of fields within this symbol.
bool HasAlternateBodyStyle() const override
Test if symbol has more than one body conversion type (DeMorgan).
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
Definition: lib_symbol.cpp:579
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition: pgm_base.cpp:678
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition: pgm_base.h:142
static SYMBOL_LIB_TABLE * SchSymbolLibTable(PROJECT *aProject)
Accessor for project symbol library table.
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:51
void LoadColors(const COLOR_SETTINGS *aSettings) override
T * GetAppSettings()
Returns a handle to the a given settings by type If the settings have already been loaded,...
COLOR_SETTINGS * GetColorSettings(const wxString &aName="user")
Retrieves a color settings object that applications can read colors from.
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)
BOX2I m_itemBBox
The bounding box of the current item.
GAL_DISPLAY_OPTIONS_IMPL m_galDisplayOptions
void DisplaySymbol(const LIB_ID &aSymbolID, int aUnit, int aBodyStyle=0)
Set the currently displayed symbol.
void DisplayPart(LIB_SYMBOL *aSymbol, int aUnit, int aBodyStyle=0)
wxString wx_str() const
Definition: utf8.cpp:45
#define _(s)
@ LAYER_REFERENCEPART
Definition: layer_ids.h:364
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp:1059
see class PGM_BASE
const int scale
VECTOR2D ToVECTOR2D(const wxPoint &aPoint)
Definition: vector2wx.h:40