KiCad PCB EDA Suite
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 <wx_filename.h>
29#include <wx/dir.h>
30#include <wx/dirdlg.h>
31#include <wx/settings.h>
32
33
35 const wxString& aPath ) :
37{
38 m_parent = aParent;
39 m_templatesPath = aPath;
40 m_minHeight = 0;
41}
42
43
45{
46 m_SizerChoice->Add( aTemplateWidget );
47 int height = aTemplateWidget->GetBestSize().GetHeight();
48 m_minHeight = std::max( m_minHeight, height );
49}
50
51
53 TEMPLATE_WIDGET_BASE( aParent )
54{
55 m_parent = aParent;
56 m_dialog = aDialog;
57
58 // wxWidgets_3.xx way of doing the same...
59 // Bind(wxEVT_LEFT_DOWN, &TEMPLATE_WIDGET::OnMouse, this );
60
61 m_bitmapIcon->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( TEMPLATE_WIDGET::OnMouse ),
62 nullptr, this );
63 m_staticTitle->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( TEMPLATE_WIDGET::OnMouse ),
64 nullptr, this );
65
66 // We're not selected until we're clicked
67 Unselect();
68
69 // Start with template being NULL
70 m_currTemplate = nullptr;
71}
72
73
75{
76 m_dialog->SetWidget( this );
77 SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNHIGHLIGHT ) );
78 m_selected = true;
79 Refresh();
80}
81
82
84{
85 SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) );
86 m_selected = false;
87 Refresh();
88}
89
90
92{
93 m_currTemplate = aTemplate;
94 m_staticTitle->SetLabel( *aTemplate->GetTitle() );
95 m_staticTitle->SetFont( KIUI::GetInfoFont( this ) );
96 m_staticTitle->Wrap( 100 );
97 m_bitmapIcon->SetBitmap( *aTemplate->GetIcon() );
98}
99
100
101void TEMPLATE_WIDGET::OnMouse( wxMouseEvent& event )
102{
103 // Toggle selection here
104 Select();
105 event.Skip();
106}
107
108
110{
111 // Ensure all panels have the full available width:
112 for( size_t i = 0; i < m_notebook->GetPageCount(); i++ )
113 {
114 // Gives a little margin for panel horizontal size, especially to show the
115 // full scroll bars of wxScrolledWindow
116 // Fix me if a better way exists
117 const int h_margin = 10;
118 const int v_margin = 22;
119
120 int max_width = m_notebook->GetClientSize().GetWidth() - h_margin;
121 int min_height = m_panels[i]->GetMinHeight() + v_margin;
122 m_panels[i]->SetSize( max_width, std::max( m_panels[i]->GetSize().GetY(), min_height ) );
123 m_panels[i]->SetMinSize( wxSize( -1, min_height ) );
124 }
125
126 Refresh();
127
128 event.Skip();
129}
130
131
132void DIALOG_TEMPLATE_SELECTOR::OnPageChange( wxNotebookEvent& event )
133{
134 int page = event.GetSelection();
135
136 if( page != wxNOT_FOUND && (unsigned)page < m_panels.size() )
137 m_tcTemplatePath->SetValue( m_panels[page]->GetPath() );
138
139 event.Skip();
140}
141
142
145{
148
149 m_htmlWin->SetPage( _( "<h1>Template Selector</h1>" ) );
150 m_notebook->Connect( wxEVT_SIZE,
151 wxSizeEventHandler( DIALOG_TEMPLATE_SELECTOR::onNotebookResize ),
152 nullptr, this );
153 m_selectedWidget = nullptr;
154}
155
156
158{
159 if( m_selectedWidget != nullptr )
161
162 m_selectedWidget = aWidget;
164}
165
166
168{
169 TEMPLATE_WIDGET* w = new TEMPLATE_WIDGET( m_panels[aPage]->m_scrolledWindow, this );
170 w->SetTemplate( aTemplate );
171 m_panels[aPage]->AddTemplateWidget( w );
172
173 m_notebook->Refresh();
174}
175
176
178{
179 return m_selectedWidget? m_selectedWidget->GetTemplate() : nullptr;
180}
181
182
183void DIALOG_TEMPLATE_SELECTOR::AddTemplatesPage( const wxString& aTitle, wxFileName& aPath )
184{
185 wxNotebookPage* newPage = new wxNotebookPage( m_notebook, wxID_ANY );
186
187 aPath.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS );
188 wxString path = aPath.GetFullPath(); // caller ensures this ends with file separator.
189
191 m_panels.push_back( tpanel );
192
193 m_notebook->AddPage( newPage, aTitle );
194
195 if( m_notebook->GetPageCount() == 1 )
196 m_tcTemplatePath->SetValue( path );
197
198 buildPageContent( path, m_notebook->GetPageCount() - 1 );
199
200 // Ensure m_notebook has a minimal height to show the template widgets:
201 // and add a margin for scroll bars and decorations
202 // FIX ME: find a better way to allow space for these items: the value works on MSW
203 // but is too big on GTK. But I did not find a better way (JPC)
204 const int margin = 50;
205 int min_height = tpanel->GetMinHeight() + margin;
206
207 if( m_notebook->GetMinClientSize().GetHeight() < min_height )
208 m_notebook->SetMinClientSize( wxSize( -1, min_height ) );
209}
210
211
212void DIALOG_TEMPLATE_SELECTOR::buildPageContent( const wxString& aPath, int aPage )
213{
214 // Get a list of files under the template path to include as choices...
215 wxDir dir;
216
217 if( dir.Open( aPath ) )
218 {
219 if( dir.HasSubDirs( "meta" ) )
220 {
221 AddTemplate( aPage, new PROJECT_TEMPLATE( aPath ) );
222 }
223 else
224 {
225 wxDir sub_dir;
226 wxString sub_name;
227
228 bool cont = dir.GetFirst( &sub_name, wxEmptyString, wxDIR_DIRS );
229
230 while( cont )
231 {
232 wxString sub_full = aPath + sub_name;
233
234 if( sub_dir.Open( sub_full ) )
235 AddTemplate( aPage, new PROJECT_TEMPLATE( sub_full ) );
236
237 cont = dir.GetNext( &sub_name );
238 }
239 }
240 }
241
242 wxSizeEvent dummy;
244}
245
246
248{
249 wxFileName fn;
250 fn.AssignDir( m_tcTemplatePath->GetValue() );
251 fn.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS );
252 wxString currPath = fn.GetFullPath();
253
254 wxDirDialog dirDialog( this, _( "Select Templates Directory" ), currPath,
255 wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST );
256
257 if( dirDialog.ShowModal() != wxID_OK )
258 return;
259
260 wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() );
261
262 m_tcTemplatePath->SetValue( dirName.GetFullPath() );
263
264 // Rebuild the page from the new templates path:
266}
267
268
269void DIALOG_TEMPLATE_SELECTOR::onReload( wxCommandEvent& event )
270{
271 int page = m_notebook->GetSelection();
272
273 if( page < 0 )
274 return; // Should not happen
275
276 wxString currPath = m_tcTemplatePath->GetValue();
277
278 wxFileName fn;
279 fn.AssignDir( m_tcTemplatePath->GetValue() );
280 fn.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS );
281 currPath = fn.GetFullPath();
282 m_tcTemplatePath->SetValue( currPath );
283
285}
286
287
289{
290 // Rebuild the page from the new templates path:
291 int page = m_notebook->GetSelection();
292
293 if( page < 0 )
294 return; // Should not happen
295
296 wxString title = m_notebook->GetPageText( page );
297 wxString currPath = m_tcTemplatePath->GetValue();
298
299 m_notebook->DeletePage( page );
300
301 wxNotebookPage* newPage = new wxNotebookPage( m_notebook, wxID_ANY );
302 TEMPLATE_SELECTION_PANEL* tpanel = new TEMPLATE_SELECTION_PANEL( newPage, currPath );
303 m_panels[page] = tpanel;
304 m_notebook->InsertPage( page, newPage, title, true );
305
306 buildPageContent( m_tcTemplatePath->GetValue(), page );
307
308 m_selectedWidget = nullptr;
309 PostSizeEvent(); // A easy way to force refresh displays
310}
311
312
314{
315 wxString url = event.GetLinkInfo().GetHref();
316 wxLaunchDefaultBrowser( url );
317}
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition: bitmap.cpp:105
@ small_folder
@ small_refresh
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)
PROJECT_TEMPLATE * GetSelectedTemplate()
void SetWidget(TEMPLATE_WIDGET *aWidget)
void buildPageContent(const wxString &aPath, int aPage)
DIALOG_TEMPLATE_SELECTOR(wxWindow *aParent)
void OnHtmlLinkActivated(wxHtmlLinkEvent &event) override
std::vector< TEMPLATE_SELECTION_PANEL * > m_panels
bool SetPage(const wxString &aSource) override
Definition: html_window.cpp:38
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 wxBitmap &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)
wxFont GetInfoFont(wxWindow *aWindow)
Definition: ui_common.cpp:156
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
#define FN_NORMALIZE_FLAGS
Default flags to pass to wxFileName::Normalize().
Definition: wx_filename.h:38