KiCad PCB EDA Suite
panel_package.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) 2021 Andrew Lutsenko, anlutsenko at gmail dot com
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 modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <math/util.h>
22#include <wx/dcclient.h>
23
24#include "panel_package.h"
25
26PANEL_PACKAGE::PANEL_PACKAGE( wxWindow* parent, const ActionCallback& aCallback,
27 const PinCallback& aPinCallback, const PACKAGE_VIEW_DATA& aData ) :
28 PANEL_PACKAGE_BASE( parent ),
29 m_actionCallback( aCallback ),
30 m_pinCallback( aPinCallback ),
31 m_data( aData )
32{
33 // Propagate clicks on static elements to the panel handler.
34 m_name->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( PANEL_PACKAGE::OnClick ), NULL, this );
35 m_desc->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( PANEL_PACKAGE::OnClick ), NULL, this );
36 m_bitmap->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( PANEL_PACKAGE::OnClick ), NULL, this );
37
38 wxColour bgColor = wxSystemSettings::GetColour( wxSYS_COLOUR_FRAMEBK );
39 m_desc->SetBackgroundColour( bgColor );
40 m_name->SetBackgroundColour( bgColor );
41 m_bitmap->SetBackgroundColour( bgColor );
42
43 m_name->SetFont( m_name->GetFont().Bold() );
44
45 m_name->SetLabel( m_data.package.name );
46 m_bitmap->SetBitmap( *m_data.bitmap );
47
48 // Set min width to 0 otherwise wxStaticLabel really doesn't want to shrink on resize
49 m_desc->SetMinSize( wxSize( 0, -1 ) );
50
51 m_minHeight = GetMinHeight();
52
53 double descLineHeight = m_desc->GetTextExtent( wxT( "X" ) ).GetHeight() * 1.2 /* leading */;
54 m_desc->SetLabel( m_data.package.description );
55 descLineHeight = wxSplit( m_desc->GetLabel(), '\n' ).size() * descLineHeight;
56
57 int nameLineHeight = m_name->GetTextExtent( wxT( "X" ) ).GetHeight();
58 wxSize minSize = GetMinSize();
59 minSize.y = std::max( nameLineHeight + KiROUND( descLineHeight ) + 15, m_minHeight );
60 SetMinSize( minSize );
61
62 m_splitButton->SetLabel( _( "Update" ) );
63 m_splitButton->Bind( wxEVT_BUTTON, &PANEL_PACKAGE::OnButtonClicked, this );
64
65 wxMenu* splitMenu = m_splitButton->GetSplitButtonMenu();
67 splitMenu->Append( wxID_ANY, _( "Pin package" ),
68 _( "Pinned packages don't affect available update notification and "
69 "will not be updated with 'Update All' button." ),
70 wxITEM_CHECK );
71 splitMenu->Bind( wxEVT_COMMAND_MENU_SELECTED, &PANEL_PACKAGE::OnPinVersionClick, this,
72 m_pinVersionMenuItem->GetId() );
73
74 m_actionMenuItem = splitMenu->Append( wxID_ANY, _( "Uninstall" ) );
75
77}
78
79
80void PANEL_PACKAGE::OnSize( wxSizeEvent& event )
81{
82 Layout();
83}
84
85
86void PANEL_PACKAGE::SetState( PCM_PACKAGE_STATE aState, bool aPinned )
87{
88 m_data.state = aState;
89 m_data.pinned = aPinned;
90 m_splitButton->GetSplitButtonMenu()->Check( m_pinVersionMenuItem->GetId(), aPinned );
91
92 switch( aState )
93 {
95 m_splitButton->Hide();
96 m_button->Show();
97 m_button->SetLabel( _( "Install" ) );
98 m_button->Enable();
99 break;
101 m_splitButton->Hide();
102 m_button->Show();
103 m_button->SetLabel( _( "Install" ) );
104 m_button->Disable();
105 break;
107 m_button->Hide();
108 m_splitButton->Show();
109
110 m_splitButton->SetLabel( _( "Uninstall" ) );
111 m_splitButton->Bind( wxEVT_BUTTON, &PANEL_PACKAGE::OnButtonClicked, this );
112
113 m_actionMenuItem->SetItemLabel( _( "Update" ) );
114 m_splitButton->GetSplitButtonMenu()->Enable( m_actionMenuItem->GetId(), false );
115
116 break;
118 m_splitButton->Hide();
119 m_button->Show();
120 m_button->SetLabel( _( "Install Pending" ) );
121 m_button->Disable();
122 break;
124 m_splitButton->Hide();
125 m_button->Show();
126 m_button->SetLabel( _( "Uninstall Pending" ) );
127 m_button->Disable();
128 break;
130 m_button->Hide();
131 m_splitButton->Show();
132
133 if( aPinned )
134 {
135 m_splitButton->SetLabel( _( "Uninstall" ) );
136 m_splitButton->Bind( wxEVT_BUTTON, &PANEL_PACKAGE::OnUninstallClick, this );
137
138 m_actionMenuItem->SetItemLabel( _( "Update" ) );
139 m_splitButton->GetSplitButtonMenu()->Enable( m_actionMenuItem->GetId(), true );
140 m_splitButton->GetSplitButtonMenu()->Bind( wxEVT_COMMAND_MENU_SELECTED,
142 m_actionMenuItem->GetId() );
143 }
144 else
145 {
146 m_splitButton->SetLabel( _( "Update" ) );
147 m_splitButton->Bind( wxEVT_BUTTON, &PANEL_PACKAGE::OnButtonClicked, this );
148
149 m_actionMenuItem->SetItemLabel( _( "Uninstall" ) );
150 m_splitButton->GetSplitButtonMenu()->Enable( m_actionMenuItem->GetId(), true );
151 m_splitButton->GetSplitButtonMenu()->Bind( wxEVT_COMMAND_MENU_SELECTED,
153 m_actionMenuItem->GetId() );
154 }
155 break;
157 m_splitButton->Hide();
158 m_button->Show();
159 m_button->SetLabel( _( "Update Pending" ) );
160 m_button->Disable();
161 break;
162 }
163
164 // Relayout to change button size to fit the label.
165 Layout();
166}
167
168
169void PANEL_PACKAGE::OnButtonClicked( wxCommandEvent& event )
170{
171 if( m_data.state == PPS_AVAILABLE )
172 {
173 wxString version = GetPreferredVersion();
174
175 if( version.IsEmpty() )
176 return;
177
179 }
180 else if( m_data.state == PPS_UPDATE_AVAILABLE )
181 {
183 }
184 else
185 {
187 }
188}
189
190
191void PANEL_PACKAGE::OnPinVersionClick( wxCommandEvent& event )
192{
193 m_data.pinned = event.IsChecked();
194
196}
197
198
199void PANEL_PACKAGE::OnUninstallClick( wxCommandEvent& event )
200{
202 {
204 }
205 else
206 {
207 // Clicking uninstall menu item of the split button should not be possible
208 // for any state other than UPDATE_AVAILABLE
209 wxLogError( wxT( "Uninstall clicked in unexpected state" ) );
210 }
211}
212
213
214void PANEL_PACKAGE::SetSelectCallback( const std::function<void()>& aCallback )
215{
216 m_selectCallback = aCallback;
217}
218
219
220void PANEL_PACKAGE::OnClick( wxMouseEvent& event )
221{
223}
224
225
226void PANEL_PACKAGE::OnPaint( wxPaintEvent& event )
227{
228 wxRect rect( wxPoint( 1, 1 ), GetClientSize() - wxSize( 1, 1 ) );
229 wxPaintDC dc( this );
230 dc.SetBrush( wxSystemSettings::GetColour( wxSYS_COLOUR_FRAMEBK ) );
231 dc.SetPen( wxPen( wxSystemSettings::GetColour( wxSYS_COLOUR_ACTIVEBORDER ), 1 ) );
232
233 if( m_selected )
234 {
235 rect.Deflate( 1 );
236 dc.SetPen( wxPen( wxSystemSettings::GetColour( wxSYS_COLOUR_HOTLIGHT ), 3 ) );
237 }
238
239 dc.DrawRectangle( rect );
240}
241
242
243void PANEL_PACKAGE::SetSelected( bool aSelected )
244{
245 m_selected = aSelected;
246 Refresh();
247}
248
249
251{
252 // Versions are already presorted in descending order
253
254 // Find last stable compatible version
255 auto ver_it = std::find_if( m_data.package.versions.begin(), m_data.package.versions.end(),
256 []( const PACKAGE_VERSION& ver )
257 {
258 return ver.compatible && ver.status == PVS_STABLE;
259 } );
260
261 // If not found then find any compatible version
262 if( ver_it == m_data.package.versions.end() )
263 {
264 ver_it = std::find_if( m_data.package.versions.begin(), m_data.package.versions.end(),
265 []( const PACKAGE_VERSION& ver )
266 {
267 return ver.compatible;
268 } );
269 }
270
271 if( ver_it == m_data.package.versions.end() )
272 return wxEmptyString; // Shouldn't happen
273
274 return ver_it->version;
275}
Class PANEL_PACKAGE_BASE.
wxStaticText * m_name
wxStaticBitmap * m_bitmap
wxStaticText * m_desc
SPLIT_BUTTON * m_splitButton
void OnClick(wxMouseEvent &event) override
void OnUninstallClick(wxCommandEvent &event)
wxMenuItem * m_actionMenuItem
Definition: panel_package.h:99
void OnPinVersionClick(wxCommandEvent &event)
void OnPaint(wxPaintEvent &event) override
void SetSelected(bool aSelected)
void OnButtonClicked(wxCommandEvent &event) override
Changes state of the (un)install button.
const ActionCallback & m_actionCallback
const PinCallback & m_pinCallback
wxMenuItem * m_pinVersionMenuItem
Definition: panel_package.h:98
PACKAGE_VIEW_DATA m_data
void SetState(PCM_PACKAGE_STATE aState, bool aPinned)
Called when anywhere on the panel is clicked (except install button)
PANEL_PACKAGE(wxWindow *parent, const ActionCallback &aCallback, const PinCallback &aPinCallback, const PACKAGE_VIEW_DATA &aData)
Sets callback for OnClick action.
void OnSize(wxSizeEvent &event) override
Get preferred version. If criteria are not met, return wxEmptyString.
std::function< void()> m_selectCallback
void SetSelectCallback(const std::function< void()> &aCallback)
Marks panel as selected.
wxString GetPreferredVersion() const
void SetLabel(const wxString &aLabel) override
wxMenu * GetSplitButtonMenu()
const int minSize
Push and Shove router track width and via size dialog.
#define _(s)
std::function< void(const wxString &aPackageId, const PCM_PACKAGE_STATE aState, const bool aPinned)> PinCallback
Definition: panel_package.h:60
std::function< void(const PACKAGE_VIEW_DATA &aData, PCM_PACKAGE_ACTION aAction, const wxString &aVersion)> ActionCallback
Definition: panel_package.h:57
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
PCM_PACKAGE_STATE
Definition: pcm.h:55
@ PPS_INSTALLED
Definition: pcm.h:58
@ PPS_PENDING_UPDATE
Definition: pcm.h:62
@ PPS_UNAVAILABLE
Definition: pcm.h:57
@ PPS_UPDATE_AVAILABLE
Definition: pcm.h:61
@ PPS_PENDING_UNINSTALL
Definition: pcm.h:60
@ PPS_PENDING_INSTALL
Definition: pcm.h:59
@ PPS_AVAILABLE
Definition: pcm.h:56
@ PPA_UNINSTALL
Definition: pcm.h:70
@ PPA_UPDATE
Definition: pcm.h:71
@ PPA_INSTALL
Definition: pcm.h:69
< Package version metadata Package metadata
Definition: pcm_data.h:74
< Collection of data relevant to the package display panel Callback for (un)install button
Definition: panel_package.h:31
wxString update_version
Definition: panel_package.h:39
wxString current_version
Definition: panel_package.h:38
const PCM_PACKAGE package
Definition: panel_package.h:32
wxBitmap * bitmap
Definition: panel_package.h:33
PCM_PACKAGE_STATE state
Definition: panel_package.h:34
wxString description
Definition: pcm_data.h:97
wxString identifier
Definition: pcm_data.h:99
wxString name
Definition: pcm_data.h:96
std::vector< PACKAGE_VERSION > versions
Definition: pcm_data.h:107
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:85