KiCad PCB EDA Suite
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 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 
20 #include "symbol_preview_widget.h"
21 #include <wx/stattext.h>
22 #include <wx/sizer.h>
23 #include <kiway.h>
24 #include <sch_view.h>
26 #include <class_libentry.h>
27 #include <symbol_lib_table.h>
28 #include <sch_preview_panel.h>
29 #include <pgm_base.h>
30 #include <sch_painter.h>
31 #include <draw_frame.h>
32 
33 
35  EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType ) :
36  wxPanel( aParent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ),
37  m_kiway( aKiway ),
38  m_preview( nullptr ),
39  m_status( nullptr ),
40  m_statusSizer( nullptr ),
41  m_previewItem( nullptr )
42 {
43  wxString eeschemaFrameKey( SCH_EDIT_FRAME_NAME );
44  wxConfigBase* eeschemaConfig = GetNewConfig( Pgm().App().GetAppName() );
45  m_galDisplayOptions.ReadConfig( eeschemaConfig, eeschemaFrameKey + GAL_DISPLAY_OPTIONS_KEY );
46 
47  EDA_DRAW_PANEL_GAL::GAL_TYPE canvasType = aCanvasType;
48 
49  // Allows only a CAIRO or OPENGL canvas:
50  if( canvasType != EDA_DRAW_PANEL_GAL::GAL_TYPE_OPENGL &&
53 
54  m_preview = new SCH_PREVIEW_PANEL( aParent, wxID_ANY, wxDefaultPosition, wxSize( -1, -1 ),
55  m_galDisplayOptions, canvasType );
56  m_preview->SetStealsFocus( false );
57 
58  // Do not display the grid: the look is not good for a small canvas area.
59  // But mainly, due to some strange bug I (JPC) was unable to fix, the grid creates
60  // strange artifacts on Windows when eeschema is run from Kicad manager (but not in stand alone...).
61  m_preview->GetGAL()->SetGridVisibility( false );
62 
63  SetBackgroundColour( *wxWHITE );
64  SetForegroundColour( *wxBLACK );
65 
66  m_status = new wxStaticText( this, wxID_ANY, wxEmptyString );
67  m_statusSizer = new wxBoxSizer( wxVERTICAL );
68  m_statusSizer->Add( 0, 0, 1 ); // add a spacer
69  m_statusSizer->Add( m_status, 0, wxALIGN_CENTER );
70  m_statusSizer->Add( 0, 0, 1 ); // add a spacer
71 
72  auto outer_sizer = new wxBoxSizer( wxVERTICAL );
73  outer_sizer->Add( m_preview, 1, wxTOP | wxEXPAND, 5 );
74  outer_sizer->Add( m_statusSizer, 1, wxALIGN_CENTER );
75 
76  m_statusSizer->ShowItems( false );
77 
78  SetSizer( outer_sizer );
79 
80  Connect( wxEVT_SIZE, wxSizeEventHandler( SYMBOL_PREVIEW_WIDGET::onSize ), NULL, this );
81 }
82 
83 
85 {
86  if( m_previewItem )
88 
89  delete m_previewItem;
90 }
91 
92 
93 void SYMBOL_PREVIEW_WIDGET::SetStatusText( wxString const& aText )
94 {
95  m_status->SetLabel( aText );
96  m_statusSizer->ShowItems( true );
97  m_preview->Hide();
98  Layout();
99 }
100 
101 
102 void SYMBOL_PREVIEW_WIDGET::onSize( wxSizeEvent& aEvent )
103 {
104  if( m_previewItem )
105  {
106  fitOnDrawArea();
108  }
109 
110  aEvent.Skip();
111 }
112 
113 
115 {
116  if( !m_previewItem )
117  return;
118 
119  // set the view scale to fit the item on screen
120  KIGFX::VIEW* view = m_preview->GetView();
121 
122  // Calculate the drawing area size, in internal units, for a scaling factor = 1.0
123  view->SetScale( 1.0 );
124  VECTOR2D clientSize = view->ToWorld( m_preview->GetClientSize(), false );
125  // Calculate the draw scale to fit the drawing area
126  double scale = std::min( fabs( clientSize.x / m_itemBBox.GetWidth() ),
127  fabs( clientSize.y / m_itemBBox.GetHeight() ) );
128 
129  // Above calculation will yield an exact fit; add a bit of whitespace around symbol
130  scale /= 1.2;
131 
132  // Now fix the best scale
133  view->SetScale( scale );
134  view->SetCenter( m_itemBBox.Centre() );
135 }
136 
137 
138 void SYMBOL_PREVIEW_WIDGET::DisplaySymbol( const LIB_ID& aSymbolID, int aUnit )
139 {
140  KIGFX::VIEW* view = m_preview->GetView();
141  auto settings = static_cast<KIGFX::SCH_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
142  LIB_ALIAS* alias = nullptr;
143 
144  try
145  {
146  alias = m_kiway.Prj().SchSymbolLibTable()->LoadSymbol( aSymbolID );
147  }
148  catch( const IO_ERROR& ioe )
149  {
150  wxLogError( wxString::Format( _( "Error loading symbol %s from library %s.\n\n%s" ),
151  aSymbolID.GetLibItemName().wx_str(),
152  aSymbolID.GetLibNickname().wx_str(),
153  ioe.What() ) );
154  }
155 
156  if( m_previewItem )
157  {
158  view->Remove( m_previewItem );
159  delete m_previewItem;
160  m_previewItem = nullptr;
161  }
162 
163  if( alias )
164  {
165  LIB_PART* part = alias->GetPart();
166 
167  // If unit isn't specified for a multi-unit part, pick the first. (Otherwise we'll
168  // draw all of them.)
169  if( part->IsMulti() && aUnit == 0 )
170  aUnit = 1;
171 
172  settings->m_ShowUnit = aUnit;
173 
174  // For symbols having a De Morgan body style, use the first style
175  settings->m_ShowConvert = part->HasConversion() ? 1 : 0;
176 
177  m_previewItem = new LIB_ALIAS( *alias, part );
178  view->Add( m_previewItem );
179 
180  // Get the symbole size, in internal units
181  m_itemBBox = part->GetUnitBoundingBox( aUnit, 0 );
182 
183  if( !m_preview->IsShown() )
184  {
185  m_preview->Show();
186  m_statusSizer->ShowItems( false );
187  Layout(); // Ensure panel size is up to date.
188  }
189 
190  // Calculate the draw scale to fit the drawing area
191  fitOnDrawArea();
192  }
193 
195 }
196 
197 
199 {
200  KIGFX::VIEW* view = m_preview->GetView();
201 
202  if( m_previewItem )
203  {
204  view->Remove( m_previewItem );
205  delete m_previewItem;
206  m_previewItem = nullptr;
207  }
208 
209  if( aPart )
210  {
211  // If unit isn't specified for a multi-unit part, pick the first. (Otherwise we'll
212  // draw all of them.)
213  if( aPart->IsMulti() && aUnit == 0 )
214  aUnit = 1;
215 
216  // For symbols having a De Morgan body style, use the first style
217  auto settings = static_cast<KIGFX::SCH_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
218  settings->m_ShowConvert = aPart->HasConversion() ? 1 : 0;
219  m_previewItem = new LIB_PART( *aPart );
220  view->Add( m_previewItem );
221 
222  // Get the symbole size, in internal units
223  m_itemBBox = aPart->GetUnitBoundingBox( aUnit, 0 );
224 
225  // Calculate the draw scale to fit the drawing area
226  fitOnDrawArea();
227  }
228 
230 
231  m_preview->Show();
232  m_statusSizer->ShowItems( false );
233 }
SYMBOL_PREVIEW_WIDGET(wxWindow *aParent, KIWAY &aKiway, EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType)
Construct a symbol preview widget.
const EDA_RECT GetUnitBoundingBox(int aUnit, int aConvert) const
Get the bounding box for the symbol.
Part library alias object definition.
bool IsMulti() const
void ForceRefresh()
Function ForceRefresh() Forces a redraw.
void onSize(wxSizeEvent &aEvent)
bool HasConversion() const
Test if part has more than one body conversion type (DeMorgan).
VECTOR2D ToWorld(const VECTOR2D &aCoord, bool aAbsolute=true) const
Function ToWorld() Converts a screen space point/vector to a point/vector in world space coordinates...
Definition: view.cpp:464
wxConfigBase * GetNewConfig(const wxString &aProgName)
Create a new wxConfig so we can put configuration files in a more proper place for each platform...
Definition: common.cpp:251
virtual void Remove(VIEW_ITEM *aItem)
Function Remove() Removes a VIEW_ITEM from the view.
Definition: view.cpp:365
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: kicad.cpp:66
KIGFX::VIEW * GetView() const
Function GetView() Returns a pointer to the VIEW instance used in the panel.
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
void SetScale(double aScale)
Function SetScale() Sets the scaling factor.
Definition: view.h:250
void SetStatusText(wxString const &aText)
Set the contents of the status label and display it.
#define SCH_EDIT_FRAME_NAME
Definition: draw_frame.h:50
void DisplaySymbol(const LIB_ID &aSymbolID, int aUnit)
Set the currently displayed symbol.
coord_type GetWidth() const
Definition: box2.h:195
#define GAL_DISPLAY_OPTIONS_KEY
Definition: pgm_base.h:52
void ReadConfig(wxConfigBase *aCfg, const wxString &aBaseName)
KIGFX::GAL * GetGAL() const
Function GetGAL() Returns a pointer to the GAL instance used in the panel.
wxString wx_str() const
Definition: utf8.cpp:51
void SetCenter(const VECTOR2D &aCenter)
Function SetCenter() Sets the center point of the VIEW (i.e.
Definition: view.cpp:590
KIGFX::GAL_DISPLAY_OPTIONS m_galDisplayOptions
const UTF8 & GetLibItemName() const
Definition: lib_id.h:114
Class LIB_ITEM definition.
void DisplayPart(LIB_PART *aPart, int aUnit)
VTBL_ENTRY PROJECT & Prj() const
Function Prj returns the PROJECT associated with this KIWAY.
Definition: kiway.cpp:142
EDA_DRAW_PANEL_GAL * m_preview
void SetStealsFocus(bool aStealsFocus)
Set whether focus is taken on certain events (mouseover, keys, etc).
Define a library symbol object.
Class KIWAY is a minimalistic software bus for communications between various DLLs/DSOs (DSOs) within...
Definition: kiway.h:258
EDA_ITEM * m_previewItem
a local copy of the LIB_ALIAS or the LIB_PART to display on the canvas
PAINTER * GetPainter() const
Function GetPainter() Returns the painter object used by the view for drawing VIEW_ITEMS.
Definition: view.h:199
Vec Centre() const
Definition: box2.h:77
LIB_PART * GetPart() const
Get the shared LIB_PART.
coord_type GetHeight() const
Definition: box2.h:196
virtual RENDER_SETTINGS * GetSettings()=0
Function GetSettings Returns pointer to current settings that are going to be used when drawing items...
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:33
const int scale
see class PGM_BASE
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
void SetGridVisibility(bool aVisibility)
Sets the visibility setting of the grid.
Class SCH_RENDER_SETTINGS Stores schematic-specific render settings.
Definition: sch_painter.h:66
BOX2I m_itemBBox
The bounding box of the current item.
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Function Add() Adds a VIEW_ITEM to the view.
Definition: view.cpp:335
Class VIEW.
Definition: view.h:61
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:97
Struct IO_ERROR is a class used to hold an error message and may be used when throwing exceptions con...
Definition: ki_exception.h:76
#define min(a, b)
Definition: auxiliary.h:85