KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_template_selector.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) 2012 Brian Sidebotham <[email protected]>
5 * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
26#include <bitmaps.h>
28#include <widgets/ui_common.h>
29#include <wx_filename.h>
30#include <wx/dir.h>
31#include <wx/dirdlg.h>
32#include <wx/settings.h>
33
34
36 const wxString& aPath ) :
38{
39 m_parent = aParent;
40 m_templatesPath = aPath;
41 m_minHeight = 0;
42}
43
44
46{
47 m_SizerChoice->Add( aTemplateWidget );
48 int height = aTemplateWidget->GetBestSize().GetHeight();
49 m_minHeight = std::max( m_minHeight, height );
50}
51
52
54 TEMPLATE_WIDGET_BASE( aParent )
55{
56 m_parent = aParent;
57 m_dialog = aDialog;
58
59 // wxWidgets_3.xx way of doing the same...
60 // Bind(wxEVT_LEFT_DOWN, &TEMPLATE_WIDGET::OnMouse, this );
61
62 m_bitmapIcon->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( TEMPLATE_WIDGET::OnMouse ),
63 nullptr, this );
64 m_staticTitle->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( TEMPLATE_WIDGET::OnMouse ),
65 nullptr, this );
66
67 // We're not selected until we're clicked
68 Unselect();
69
70 // Start with template being NULL
71 m_currTemplate = nullptr;
72}
73
74
76{
77 m_dialog->SetWidget( this );
78 SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNHIGHLIGHT ) );
79 m_selected = true;
80 Refresh();
81}
82
83
85{
86 SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) );
87 m_selected = false;
88 Refresh();
89}
90
91
93{
94 m_currTemplate = aTemplate;
95 m_staticTitle->SetLabel( *aTemplate->GetTitle() );
96 m_staticTitle->SetFont( KIUI::GetInfoFont( this ) );
97 m_staticTitle->Wrap( 100 );
98 m_bitmapIcon->SetBitmap( *aTemplate->GetIcon() );
99}
100
101
102void TEMPLATE_WIDGET::OnMouse( wxMouseEvent& event )
103{
104 // Toggle selection here
105 Select();
106 event.Skip();
107}
108
109
111{
112 // Ensure all panels have the full available width:
113 for( size_t i = 0; i < m_notebook->GetPageCount(); i++ )
114 {
115 // Gives a little margin for panel horizontal size, especially to show the
116 // full scroll bars of wxScrolledWindow
117 // Fix me if a better way exists
118 const int h_margin = 10;
119 const int v_margin = 22;
120
121 int max_width = m_notebook->GetClientSize().GetWidth() - h_margin;
122 int min_height = m_panels[i]->GetMinHeight() + v_margin;
123 m_panels[i]->SetSize( max_width, std::max( m_panels[i]->GetSize().GetY(), min_height ) );
124 m_panels[i]->SetMinSize( wxSize( -1, min_height ) );
125 }
126
127 Refresh();
128
129 event.Skip();
130}
131
132
133void DIALOG_TEMPLATE_SELECTOR::OnPageChange( wxNotebookEvent& event )
134{
135 int page = event.GetSelection();
136
137 if( page != wxNOT_FOUND && (unsigned)page < m_panels.size() )
138 m_tcTemplatePath->SetValue( m_panels[page]->GetPath() );
139
140 event.Skip();
141}
142
143
144DIALOG_TEMPLATE_SELECTOR::DIALOG_TEMPLATE_SELECTOR( wxWindow* aParent, const wxPoint& aPos, const wxSize& aSize ) :
145 DIALOG_TEMPLATE_SELECTOR_BASE( aParent, wxID_ANY, wxEmptyString, aPos, aSize )
146{
147 m_browseButton->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) );
148 m_reloadButton->SetBitmap( KiBitmapBundle( BITMAPS::small_refresh ) );
149
150 m_htmlWin->SetPage( _( "<h1>Template Selector</h1>" ) );
151 m_notebook->Connect( wxEVT_SIZE,
152 wxSizeEventHandler( DIALOG_TEMPLATE_SELECTOR::onNotebookResize ),
153 nullptr, this );
154 m_selectedWidget = nullptr;
155
156 // When all widgets have the size fixed, call finishDialogSettings to update sizers
158}
159
160
162{
163 if( m_selectedWidget != nullptr )
165
166 m_selectedWidget = aWidget;
168}
169
170
172{
173 TEMPLATE_WIDGET* w = new TEMPLATE_WIDGET( m_panels[aPage]->m_scrolledWindow, this );
174 w->SetTemplate( aTemplate );
175 m_panels[aPage]->AddTemplateWidget( w );
176
177 m_notebook->Refresh();
178}
179
180
182{
183 return m_selectedWidget? m_selectedWidget->GetTemplate() : nullptr;
184}
185
186
187void DIALOG_TEMPLATE_SELECTOR::AddTemplatesPage( const wxString& aTitle, wxFileName& aPath )
188{
189 wxNotebookPage* newPage = new wxNotebookPage( m_notebook, wxID_ANY );
190
191 aPath.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS );
192 wxString path = aPath.GetFullPath(); // caller ensures this ends with file separator.
193
195 m_panels.push_back( tpanel );
196
197 m_notebook->AddPage( newPage, aTitle );
198
199 if( m_notebook->GetPageCount() == 1 )
200 m_tcTemplatePath->SetValue( path );
201
202 buildPageContent( path, m_notebook->GetPageCount() - 1 );
203
204 // Ensure m_notebook has a minimal height to show the template widgets:
205 // and add a margin for scroll bars and decorations
206 // FIX ME: find a better way to allow space for these items: the value works on MSW
207 // but is too big on GTK. But I did not find a better way (JPC)
208 const int margin = 50;
209 int min_height = tpanel->GetMinHeight() + margin;
210
211 if( m_notebook->GetMinClientSize().GetHeight() < min_height )
212 m_notebook->SetMinClientSize( wxSize( -1, min_height ) );
213}
214
215
216void DIALOG_TEMPLATE_SELECTOR::buildPageContent( const wxString& aPath, int aPage )
217{
218 // Get a list of files under the template path to include as choices...
219 wxDir dir;
220
221 if( dir.Open( aPath ) )
222 {
223 if( dir.HasSubDirs( "meta" ) )
224 {
225 AddTemplate( aPage, new PROJECT_TEMPLATE( aPath ) );
226 }
227 else
228 {
229 wxString sub_name;
230 wxArrayString subdirs;
231
232 bool cont = dir.GetFirst( &sub_name, wxEmptyString, wxDIR_DIRS );
233
234 while( cont )
235 {
236 subdirs.Add( wxString( sub_name ) );
237 cont = dir.GetNext( &sub_name );
238 }
239
240 if( !subdirs.IsEmpty() )
241 subdirs.Sort();
242
243 for( const wxString& dir_name : subdirs )
244 {
245 wxDir sub_dir;
246 wxString sub_full = aPath + dir_name;
247
248 if( sub_dir.Open( sub_full ) )
249 AddTemplate( aPage, new PROJECT_TEMPLATE( sub_full ) );
250 }
251 }
252 }
253
254 wxSizeEvent dummy;
256}
257
258
260{
261 wxFileName fn;
262 fn.AssignDir( m_tcTemplatePath->GetValue() );
263 fn.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS );
264 wxString currPath = fn.GetFullPath();
265
266 wxDirDialog dirDialog( this, _( "Select Templates Directory" ), currPath,
267 wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST );
268
269 if( dirDialog.ShowModal() != wxID_OK )
270 return;
271
272 wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() );
273
274 m_tcTemplatePath->SetValue( dirName.GetFullPath() );
275
276 // Rebuild the page from the new templates path:
278}
279
280
281void DIALOG_TEMPLATE_SELECTOR::onReload( wxCommandEvent& event )
282{
283 int page = m_notebook->GetSelection();
284
285 if( page < 0 )
286 return; // Should not happen
287
288 wxString currPath = m_tcTemplatePath->GetValue();
289
290 wxFileName fn;
291 fn.AssignDir( m_tcTemplatePath->GetValue() );
292 fn.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS );
293 currPath = fn.GetFullPath();
294 m_tcTemplatePath->SetValue( currPath );
295
297}
298
299
301{
302 // Rebuild the page from the new templates path:
303 int page = m_notebook->GetSelection();
304
305 if( page < 0 )
306 return; // Should not happen
307
308 wxString title = m_notebook->GetPageText( page );
309 wxString currPath = m_tcTemplatePath->GetValue();
310
311 m_notebook->DeletePage( page );
312
313 wxNotebookPage* newPage = new wxNotebookPage( m_notebook, wxID_ANY );
314 TEMPLATE_SELECTION_PANEL* tpanel = new TEMPLATE_SELECTION_PANEL( newPage, currPath );
315 m_panels[page] = tpanel;
316 m_notebook->InsertPage( page, newPage, title, true );
317
318 buildPageContent( m_tcTemplatePath->GetValue(), page );
319
320 m_selectedWidget = nullptr;
321 PostSizeEvent(); // A easy way to force refresh displays
322}
323
324
326{
327 wxString url = event.GetLinkInfo().GetHref();
328 wxLaunchDefaultBrowser( url );
329}
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:110
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
Class DIALOG_TEMPLATE_SELECTOR_BASE.
void AddTemplate(int aPage, PROJECT_TEMPLATE *aTemplate)
void OnPageChange(wxNotebookEvent &event) override
void AddTemplatesPage(const wxString &aTitle, wxFileName &aPath)
Add a new page with aTitle, populated with templates from aPath.
void onReload(wxCommandEvent &event) override
void SetHtml(const wxFileName &aFilename)
void onDirectoryBrowseClicked(wxCommandEvent &event) override
void onNotebookResize(wxSizeEvent &event)
DIALOG_TEMPLATE_SELECTOR(wxWindow *aParent, const wxPoint &aPos, const wxSize &aSize)
PROJECT_TEMPLATE * GetSelectedTemplate()
void SetWidget(TEMPLATE_WIDGET *aWidget)
void buildPageContent(const wxString &aPath, int aPage)
void OnHtmlLinkActivated(wxHtmlLinkEvent &event) override
std::vector< TEMPLATE_SELECTION_PANEL * > m_panels
bool SetPage(const wxString &aSource) override
Definition: html_window.cpp:50
A class which provides project template functionality.
wxBitmap * GetIcon()
Get the 64px^2 icon for the project template.
wxFileName GetHtmlFile()
Get the full Html filename for the project template.
wxString * GetTitle()
Get the title of the project (extracted from the html title tag)
void SetBitmap(const wxBitmapBundle &aBmp)
Class TEMPLATE_SELECTION_PANEL_BASE.
TEMPLATE_SELECTION_PANEL(wxNotebookPage *aParent, const wxString &aPath)
wxString m_templatesPath
the path to access to the folder containing the templates (which are also folders)
void AddTemplateWidget(TEMPLATE_WIDGET *aTemplateWidget)
int m_minHeight
minimal height to show templates (this is the height of the biggest template widget)
Class TEMPLATE_WIDGET_BASE.
PROJECT_TEMPLATE * GetTemplate()
void OnMouse(wxMouseEvent &event)
void SetTemplate(PROJECT_TEMPLATE *aTemplate)
Set the project template for this widget, which will determine the icon and title associated with thi...
DIALOG_TEMPLATE_SELECTOR * m_dialog
TEMPLATE_WIDGET(wxWindow *aParent, DIALOG_TEMPLATE_SELECTOR *aDialog)
PROJECT_TEMPLATE * m_currTemplate
#define _(s)
KICOMMON_API wxFont GetInfoFont(wxWindow *aWindow)
Definition: ui_common.cpp:154
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
std::vector< FAB_LAYER_COLOR > dummy
Functions to provide common constants and other functions to assist in making a consistent UI.
#define FN_NORMALIZE_FLAGS
Default flags to pass to wxFileName::Normalize().
Definition: wx_filename.h:39