KiCad PCB EDA Suite
Loading...
Searching...
No Matches
panel_fp_properties_3d_model.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 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2015 Dick Hollenbeck, [email protected]
6 * Copyright (C) 2008 Wayne Stambaugh <[email protected]>
7 * Copyright (C) 2004-2022 KiCad Developers, see AUTHORS.txt for contributors.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, you may find one here:
21 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22 * or you may search the http://www.gnu.org website for the version 2 license,
23 * or you may write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 */
26
28
31#include <env_vars.h>
32#include <bitmaps.h>
35#include <widgets/wx_grid.h>
37#include <footprint.h>
38#include <fp_lib_table.h>
39#include <footprint.h>
43#include "filename_resolver.h"
44#include <pgm_base.h>
45#include <kiplatform/ui.h>
49#include <project_pcb.h>
50
51#include <wx/defs.h>
52#include <wx/msgdlg.h>
53
55{
58 COL_SHOWN = 2
59};
60
61wxDEFINE_EVENT( wxCUSTOM_PANEL_SHOWN_EVENT, wxCommandEvent );
62
64 FOOTPRINT* aFootprint,
65 DIALOG_SHIM* aDialogParent,
66 wxWindow* aParent, wxWindowID aId,
67 const wxPoint& aPos,
68 const wxSize& aSize, long aStyle,
69 const wxString& aName ) :
70 PANEL_FP_PROPERTIES_3D_MODEL_BASE( aParent, aId, aPos, aSize, aStyle, aName ),
71 m_parentDialog( aDialogParent ),
72 m_frame( aFrame ),
73 m_footprint( aFootprint ),
74 m_inSelect( false )
75{
76 m_modelsGrid->SetDefaultRowSize( m_modelsGrid->GetDefaultRowSize() + 4 );
77
78 GRID_TRICKS* trick = new GRID_TRICKS( m_modelsGrid, [this]( wxCommandEvent& aEvent )
79 {
80 OnAdd3DRow( aEvent );
81 } );
83
84 m_modelsGrid->PushEventHandler( trick );
85
86 // Get the last 3D directory
88
89 if( cfg->m_lastFootprint3dDir.IsEmpty() )
90 {
91 wxGetEnv( ENV_VAR::GetVersionedEnvVarName( wxS( "3DMODEL_DIR" ) ),
93 }
94
95 // Icon showing warning/error information
96 wxGridCellAttr* attr = new wxGridCellAttr;
97 attr->SetReadOnly();
98 m_modelsGrid->SetColAttr( COL_PROBLEM, attr );
99
100 // Filename
101 attr = new wxGridCellAttr;
103 &cfg->m_lastFootprint3dDir, wxT( "*.*" ), true,
104 m_frame->Prj().GetProjectPath() ) );
105 m_modelsGrid->SetColAttr( COL_FILENAME, attr );
106
107 // Show checkbox
108 attr = new wxGridCellAttr;
109 attr->SetRenderer( new wxGridCellBoolRenderer() );
110 attr->SetReadOnly(); // not really; we delegate interactivity to GRID_TRICKS
111 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
112 m_modelsGrid->SetColAttr( COL_SHOWN, attr );
113 m_modelsGrid->SetWindowStyleFlag( m_modelsGrid->GetWindowStyle() & ~wxHSCROLL );
114
116
119
120 m_LowerSizer3D->Add( m_previewPane, 1, wxEXPAND, 5 );
121
122 // Configure button logos
123 m_button3DShapeAdd->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
124 m_button3DShapeBrowse->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) );
125 m_button3DShapeRemove->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
126
127 Bind( wxEVT_SHOW, &PANEL_FP_PROPERTIES_3D_MODEL::onShowEvent, this );
129 this );
130}
131
132
134{
135 // Delete the GRID_TRICKS.
136 m_modelsGrid->PopEventHandler( true );
137
138 // Unbind OnShowEvent to prevent unnecessary event handling.
139 Unbind( wxEVT_SHOW, &PANEL_FP_PROPERTIES_3D_MODEL::onShowEvent, this );
140
141 // free the memory used by all models, otherwise models which were
142 // browsed but not used would consume memory
144
145 delete m_previewPane;
146}
147
148
150{
152 return true;
153}
154
155
157{
158 // Only commit changes in the editor, not the models
159 // The container dialog is responsible for moving the new models into
160 // the footprint inside a commit.
162 return false;
163
165
166 for( const auto& [name, file] : fp->EmbeddedFileMap() )
167 {
168 if( !m_footprint->HasFile( name ) )
170 }
171 return true;
172}
173
174
176{
177 wxString default_path;
178 wxGetEnv( ENV_VAR::GetVersionedEnvVarName( wxS( "3DMODEL_DIR" ) ), &default_path );
179
180#ifdef __WINDOWS__
181 default_path.Replace( wxT( "/" ), wxT( "\\" ) );
182#endif
183
184 m_shapes3D_list.clear();
186
187 wxString origPath, alias, shortPath;
189
190 for( const FP_3DMODEL& model : m_footprint->Models() )
191 {
192 m_shapes3D_list.push_back( model );
193 origPath = model.m_Filename;
194
195 if( res && res->SplitAlias( origPath, alias, shortPath ) )
196 origPath = alias + wxT( ":" ) + shortPath;
197
198 m_modelsGrid->AppendRows( 1 );
199 int row = m_modelsGrid->GetNumberRows() - 1;
200 m_modelsGrid->SetCellValue( row, COL_FILENAME, origPath );
201 m_modelsGrid->SetCellValue( row, COL_SHOWN, model.m_Show ? wxT( "1" ) : wxT( "0" ) );
202
203 // Must be after the filename is set
205 }
206
207 select3DModel( 0 );
208
210 m_modelsGrid->SetColSize( COL_SHOWN, m_modelsGrid->GetVisibleWidth( COL_SHOWN, true, false ) );
211
212 Layout();
213}
214
215
217{
218 m_inSelect = true;
219
220 aModelIdx = std::max( 0, aModelIdx );
221 aModelIdx = std::min( aModelIdx, m_modelsGrid->GetNumberRows() - 1 );
222
223 if( m_modelsGrid->GetNumberRows() )
224 {
225 m_modelsGrid->SelectRow( aModelIdx );
226 m_modelsGrid->SetGridCursor( aModelIdx, COL_FILENAME );
227 }
228
229 m_previewPane->SetSelectedModel( aModelIdx );
230
231 m_inSelect = false;
232}
233
234
236{
237 if( !m_inSelect )
238 select3DModel( aEvent.GetRow() );
239}
240
241
243{
244 if( aEvent.GetCol() == COL_FILENAME )
245 {
246 bool hasAlias = false;
248 wxString filename = m_modelsGrid->GetCellValue( aEvent.GetRow(), COL_FILENAME );
249
250 // Perform cleanup and validation on the filename if it isn't empty
251 if( !filename.empty() )
252 {
253 filename.Replace( wxT( "\n" ), wxT( "" ) );
254 filename.Replace( wxT( "\r" ), wxT( "" ) );
255 filename.Replace( wxT( "\t" ), wxT( "" ) );
256
257 res->ValidateFileName( filename, hasAlias );
258
259 // If the user has specified an alias in the name then prepend ':'
260 if( hasAlias )
261 filename.insert( 0, wxT( ":" ) );
262
263#ifdef __WINDOWS__
264 // In KiCad files, filenames and paths are stored using Unix notation
265 filename.Replace( wxT( "\\" ), wxT( "/" ) );
266#endif
267
268 // Update the grid with the modified filename
269 m_modelsGrid->SetCellValue( aEvent.GetRow(), COL_FILENAME, filename );
270 }
271
272 // Save the filename in the 3D shapes table
273 m_shapes3D_list[ aEvent.GetRow() ].m_Filename = filename;
274
275 // Update the validation status
276 updateValidateStatus( aEvent.GetRow() );
277 }
278 else if( aEvent.GetCol() == COL_SHOWN )
279 {
280 wxString showValue = m_modelsGrid->GetCellValue( aEvent.GetRow(), COL_SHOWN );
281
282 m_shapes3D_list[ aEvent.GetRow() ].m_Show = ( showValue == wxT( "1" ) );
283 }
284
286 onModify();
287}
288
289
291{
293 return;
294
295 int idx = m_modelsGrid->GetGridCursorRow();
296
297 if( idx >= 0 && m_modelsGrid->GetNumberRows() && !m_shapes3D_list.empty() )
298 {
299 // Don't allow selection until we call select3DModel(), below. Otherwise wxWidgets
300 // has a tendency to get its knickers in a knot....
301 m_inSelect = true;
302
303 m_shapes3D_list.erase( m_shapes3D_list.begin() + idx );
304 m_modelsGrid->DeleteRows( idx );
305
306 select3DModel( idx ); // will clamp idx within bounds
308 }
309
310 onModify();
311}
312
313
315{
317 return;
318
319 int selected = m_modelsGrid->GetGridCursorRow();
320
321 PROJECT& prj = m_frame->Prj();
322 FP_3DMODEL model;
325
326 wxString initialpath = prj.GetRString( PROJECT::VIEWER_3D_PATH );
327 wxString sidx = prj.GetRString( PROJECT::VIEWER_3D_FILTER_INDEX );
328 int filter = 0;
329
330 // If the PROJECT::VIEWER_3D_PATH hasn't been set yet, use the 3DMODEL_DIR environment
331 // variable and fall back to the project path if necessary.
332 if( initialpath.IsEmpty() )
333 {
334 if( !wxGetEnv( ENV_VAR::GetVersionedEnvVarName( wxS( "3DMODEL_DIR" ) ), &initialpath )
335 || initialpath.IsEmpty() )
336 {
337 initialpath = prj.GetProjectPath();
338 }
339 }
340
341 if( !sidx.empty() )
342 {
343 long tmp;
344 sidx.ToLong( &tmp );
345
346 if( tmp > 0 && tmp <= INT_MAX )
347 filter = (int) tmp;
348 }
349
350
351 DIALOG_SELECT_3DMODEL dm( m_parentDialog, cache, &model, initialpath, filter );
352
353 // Use QuasiModal so that Configure3DPaths (and its help window) will work
354 int retval = dm.ShowQuasiModal();
355
356 if( retval != wxID_OK || model.m_Filename.empty() )
357 {
358 if( selected >= 0 )
359 {
360 select3DModel( selected );
361 updateValidateStatus( selected );
362 }
363
364 return;
365 }
366
367 if( dm.IsEmbedded3DModel() )
368 {
369 wxString libraryName = m_footprint->GetFPID().GetLibNickname();
370 const FP_LIB_TABLE_ROW* fpRow = nullptr;
371
372 wxString footprintBasePath = wxEmptyString;
373
374 try
375 {
376 fpRow = PROJECT_PCB::PcbFootprintLibs( &m_frame->Prj() )->FindRow( libraryName, false );
377
378 if( fpRow )
379 footprintBasePath = fpRow->GetFullURI( true );
380 }
381 catch( ... )
382 {
383 // if libraryName is not found in table, do nothing
384 }
385
386
387 wxString fullPath = res->ResolvePath( model.m_Filename, footprintBasePath, nullptr );
388 wxFileName fname( fullPath );
389
391
392 if( !result )
393 {
394
395 wxString msg = wxString::Format( _( "Error adding 3D model" ) );
396 wxMessageBox( msg, _( "Error" ), wxICON_ERROR | wxOK, this );
397 return;
398 }
399
400 model.m_Filename = result->GetLink();
401 }
402
403
404 prj.SetRString( PROJECT::VIEWER_3D_PATH, initialpath );
405 sidx = wxString::Format( wxT( "%i" ), filter );
407
408 wxString alias;
409 wxString shortPath;
410 wxString filename = model.m_Filename;
411
412 if( res && res->SplitAlias( filename, alias, shortPath ) )
413 filename = alias + wxT( ":" ) + shortPath;
414
415#ifdef __WINDOWS__
416 // In KiCad files, filenames and paths are stored using Unix notation
417 model.m_Filename.Replace( wxT( "\\" ), wxT( "/" ) );
418#endif
419
420 model.m_Show = true;
421 m_shapes3D_list.push_back( model );
422
423 int idx = m_modelsGrid->GetNumberRows();
424 m_modelsGrid->AppendRows( 1 );
425 m_modelsGrid->SetCellValue( idx, COL_FILENAME, filename );
426 m_modelsGrid->SetCellValue( idx, COL_SHOWN, wxT( "1" ) );
427
428 select3DModel( idx );
430
432 onModify();
433}
434
435
437{
439 return;
440
441 FP_3DMODEL model;
442
443 model.m_Show = true;
444 m_shapes3D_list.push_back( model );
445
446 int row = m_modelsGrid->GetNumberRows();
447 m_modelsGrid->AppendRows( 1 );
448 m_modelsGrid->SetCellValue( row, COL_SHOWN, wxT( "1" ) );
449 m_modelsGrid->SetCellValue( row, COL_PROBLEM, "" );
450
451 select3DModel( row );
452
453 m_modelsGrid->SetFocus();
454 m_modelsGrid->MakeCellVisible( row, COL_FILENAME );
455 m_modelsGrid->SetGridCursor( row, COL_FILENAME );
456
457 m_modelsGrid->EnableCellEditControl( true );
458 m_modelsGrid->ShowCellEditControl();
459
461 onModify();
462}
463
464
466{
467 int icon = 0;
468 wxString errStr;
469
470 switch( validateModelExists( m_modelsGrid->GetCellValue( aRow, COL_FILENAME) ) )
471 {
472 case MODEL_VALIDATE_ERRORS::MODEL_NO_ERROR:
473 icon = 0;
474 errStr = "";
475 break;
476
477 case MODEL_VALIDATE_ERRORS::NO_FILENAME:
478 icon = wxICON_WARNING;
479 errStr = _( "No filename entered" );
480 break;
481
482 case MODEL_VALIDATE_ERRORS::ILLEGAL_FILENAME:
483 icon = wxICON_ERROR;
484 errStr = _( "Illegal filename" );
485 break;
486
487 case MODEL_VALIDATE_ERRORS::RESOLVE_FAIL:
488 icon = wxICON_ERROR;
489 errStr = _( "File not found" );
490 break;
491
492 case MODEL_VALIDATE_ERRORS::OPEN_FAIL:
493 icon = wxICON_ERROR;
494 errStr = _( "Unable to open file" );
495 break;
496
497 default:
498 icon = wxICON_ERROR;
499 errStr = _( "Unknown error" );
500 break;
501 }
502
503 m_modelsGrid->SetCellValue( aRow, COL_PROBLEM, errStr );
504 m_modelsGrid->SetCellRenderer( aRow, COL_PROBLEM,
505 new GRID_CELL_STATUS_ICON_RENDERER( icon ) );
506}
507
508
510{
511 if( aFilename.empty() )
512 return MODEL_VALIDATE_ERRORS::NO_FILENAME;
513
514 bool hasAlias = false;
516
517 if( !resolv )
518 return MODEL_VALIDATE_ERRORS::RESOLVE_FAIL;
519
520 if( !resolv->ValidateFileName( aFilename, hasAlias ) )
521 return MODEL_VALIDATE_ERRORS::ILLEGAL_FILENAME;
522
523 wxString libraryName = m_footprint->GetFPID().GetLibNickname();
524 const FP_LIB_TABLE_ROW* fpRow = nullptr;
525 try
526 {
527 fpRow = PROJECT_PCB::PcbFootprintLibs( &m_frame->Prj() )->FindRow( libraryName, false );
528 }
529 catch( ... )
530 {
531 // if libraryName is not found in table, do nothing
532 }
533
534 wxString footprintBasePath = wxEmptyString;
535
536 if( fpRow )
537 footprintBasePath = fpRow->GetFullURI( true );
538
539 wxString fullPath = resolv->ResolvePath( aFilename, footprintBasePath, m_footprint );
540
541 if( fullPath.IsEmpty() )
542 return MODEL_VALIDATE_ERRORS::RESOLVE_FAIL;
543
544 if( !wxFileName::IsFileReadable( fullPath ) )
545 return MODEL_VALIDATE_ERRORS::OPEN_FAIL;
546
547 return MODEL_VALIDATE_ERRORS::MODEL_NO_ERROR;
548}
549
550
551void PANEL_FP_PROPERTIES_3D_MODEL::Cfg3DPath( wxCommandEvent& event )
552{
553 DIALOG_CONFIGURE_PATHS dlg( this );
554
555 if( dlg.ShowQuasiModal() == wxID_OK )
557}
558
559
561{
562 // Account for scroll bars
563 int modelsWidth = KIPLATFORM::UI::GetUnobscuredSize( m_modelsGrid ).x;
564
565 int width = modelsWidth - m_modelsGrid->GetColSize( COL_SHOWN )
566 - m_modelsGrid->GetColSize( COL_PROBLEM );
567
568 if( width > 0 )
569 m_modelsGrid->SetColSize( COL_FILENAME, width );
570}
571
572
574{
576
577 event.Skip();
578}
579
580
581void PANEL_FP_PROPERTIES_3D_MODEL::OnUpdateUI( wxUpdateUIEvent& event )
582{
583 m_button3DShapeRemove->Enable( m_modelsGrid->GetNumberRows() > 0 );
584}
585
586
588{
589 if( DIALOG_SHIM* dlg = dynamic_cast<DIALOG_SHIM*>( wxGetTopLevelParent( this ) ) )
590 dlg->OnModify();
591}
592
593
595{
596 postCustomPanelShownEventWithPredicate( static_cast<int>( aEvent.IsShown() ) );
597 aEvent.Skip();
598}
599
600
602{
604 && m_previewPane->IsShownOnScreen() );
605 aEvent.Skip();
606}
607
608
610{
611 wxCommandEvent event( wxCUSTOM_PANEL_SHOWN_EVENT );
612 event.SetEventObject( m_previewPane );
613 event.SetInt( static_cast<int>( predicate ) );
614 m_previewPane->ProcessWindowEvent( event );
615}
const char * name
Definition: DXF_plotter.cpp:57
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:110
Dialog helper object to sit in the inheritance tree between wxDialog and any class written by wxFormB...
Definition: dialog_shim.h:88
int ShowQuasiModal()
bool HasFile(const wxString &name) const
EMBEDDED_FILE * AddFile(const wxFileName &aName, bool aOverwrite)
Loads a file from disk and adds it to the collection.
const std::map< wxString, EMBEDDED_FILE * > & EmbeddedFileMap() const
Provide an extensible class to resolve 3D model paths.
bool ValidateFileName(const wxString &aFileName, bool &hasAlias) const
Returns true if the given path is a valid aliased relative path.
void SetProgramBase(PGM_BASE *aBase)
Set a pointer to the application's PGM_BASE instance used to extract the local env vars.
wxString ResolvePath(const wxString &aFileName, const wxString &aWorkingPath, const EMBEDDED_FILES *aFiles)
Determines the full path of the given file name.
const LIB_ID & GetFPID() const
Definition: footprint.h:248
std::vector< FP_3DMODEL > & Models()
Definition: footprint.h:220
wxString m_Filename
The 3D shape filename in 3D library.
Definition: footprint.h:103
bool m_Show
Include model in rendering.
Definition: footprint.h:104
Hold a record identifying a library accessed by the appropriate footprint library #PLUGIN object in t...
Definition: fp_lib_table.h:42
const FP_LIB_TABLE_ROW * FindRow(const wxString &aNickName, bool aCheckIfEnabled=false)
Return an FP_LIB_TABLE_ROW if aNickName is found in this table or in any chained fall back table frag...
Editor for wxGrid cells that adds a file/folder browser to the grid input field.
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Definition: grid_tricks.h:61
void SetTooltipEnable(int aCol, bool aEnable=true)
Enable the tooltip for a column.
Definition: grid_tricks.h:75
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:87
const wxString GetFullURI(bool aSubstituted=false) const
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
Class PANEL_FP_PROPERTIES_3D_MODEL_BASE.
void OnUpdateUI(wxUpdateUIEvent &event) override
void Cfg3DPath(wxCommandEvent &event) override
void OnRemove3DModel(wxCommandEvent &event) override
virtual void onShowEvent(wxShowEvent &aEvent)
void On3DModelCellChanged(wxGridEvent &aEvent) override
virtual void onDialogActivateEvent(wxActivateEvent &aEvent)
PANEL_FP_PROPERTIES_3D_MODEL(PCB_BASE_EDIT_FRAME *aFrame, FOOTPRINT *aFootprint, DIALOG_SHIM *aDialogParent, wxWindow *aParent, wxWindowID aId=wxID_ANY, const wxPoint &aPos=wxDefaultPosition, const wxSize &aSize=wxDefaultSize, long aStyle=wxTAB_TRAVERSAL, const wxString &aName=wxEmptyString)
void OnGridSize(wxSizeEvent &event) override
void postCustomPanelShownEventWithPredicate(bool predicate)
MODEL_VALIDATE_ERRORS validateModelExists(const wxString &aFilename)
void OnAdd3DModel(wxCommandEvent &event) override
void OnAdd3DRow(wxCommandEvent &event) override
std::vector< FP_3DMODEL > m_shapes3D_list
void On3DModelSelected(wxGridEvent &) override
void UpdateDummyFootprint(bool aRelaodRequired=true)
Copy shapes from the current shape list which are flagged for preview to the copy of footprint that i...
FOOTPRINT * GetDummyFootprint() const
Get the dummy footprint that is used for previewing the 3D model.
void SetSelectedModel(int idx)
Set the currently selected index in the model list so that the scale/rotation/offset controls can be ...
wxString m_lastFootprint3dDir
Common, abstract interface for edit frames.
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition: pgm_base.h:142
static FP_LIB_TABLE * PcbFootprintLibs(PROJECT *aProject)
Return the table of footprint libraries without Kiway.
Definition: project_pcb.cpp:37
static S3D_CACHE * Get3DCacheManager(PROJECT *aProject, bool updateProjDir=false)
Return a pointer to an instance of the 3D cache manager.
Definition: project_pcb.cpp:77
static FILENAME_RESOLVER * Get3DFilenameResolver(PROJECT *aProject)
Accessor for 3D path resolver.
Container for project specific data.
Definition: project.h:64
@ VIEWER_3D_FILTER_INDEX
Definition: project.h:222
@ VIEWER_3D_PATH
Definition: project.h:221
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition: project.cpp:135
virtual void SetRString(RSTRING_T aStringId, const wxString &aString)
Store a "retained string", which is any session and project specific string identified in enum RSTRIN...
Definition: project.cpp:307
virtual const wxString & GetRString(RSTRING_T aStringId)
Return a "retained string", which is any session and project specific string identified in enum RSTRI...
Definition: project.cpp:318
Cache for storing the 3D shapes.
Definition: 3d_cache.h:55
void FlushCache(bool closePlugins=true)
Free all data in the cache and by default closes all plugins.
Definition: 3d_cache.cpp:523
FILENAME_RESOLVER * GetResolver() noexcept
Definition: 3d_cache.cpp:511
T * GetAppSettings()
Returns a handle to the a given settings by type If the settings have already been loaded,...
bool Enable(bool aEnable=true) override
void SetBitmap(const wxBitmapBundle &aBmp)
int GetVisibleWidth(int aCol, bool aHeader=true, bool aContents=true, bool aKeep=false)
Calculates the specified column based on the actual size of the text on screen.
Definition: wx_grid.cpp:769
void ClearRows()
wxWidgets recently added an ASSERT which fires if the position is greater than or equal to the number...
Definition: wx_grid.h:184
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:637
#define _(s)
Declaration of the eda_3d_viewer class.
Functions related to environment variables, including help functions.
KICOMMON_API wxString GetVersionedEnvVarName(const wxString &aBaseName)
Constructs a versioned environment variable based on this KiCad major version.
Definition: env_vars.cpp:74
wxSize GetUnobscuredSize(const wxWindow *aWindow)
Tries to determine the size of the viewport of a scrollable widget (wxDataViewCtrl,...
Definition: wxgtk/ui.cpp:195
wxDEFINE_EVENT(wxCUSTOM_PANEL_SHOWN_EVENT, wxCommandEvent)
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp:1060
see class PGM_BASE
VECTOR3I res