KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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 The 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
28
29PANEL_PACKAGE::PANEL_PACKAGE( wxWindow* parent, const ActionCallback& aCallback,
30 const PinCallback& aPinCallback, const PACKAGE_VIEW_DATA& aData ) :
31 PANEL_PACKAGE_BASE( parent ),
32 m_actionCallback( aCallback ),
33 m_pinCallback( aPinCallback ),
34 m_data( aData )
35{
36 // correct the min size from wxfb with fromdip
37 SetMinSize( FromDIP( GetMinSize() ) );
38
39 // Propagate clicks on static elements to the panel handler.
40 m_name->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( PANEL_PACKAGE::OnClick ), NULL, this );
41 m_desc->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( PANEL_PACKAGE::OnClick ), NULL, this );
42 m_bitmap->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( PANEL_PACKAGE::OnClick ), NULL, this );
43
44 wxColour bgColor = wxSystemSettings::GetColour( wxSYS_COLOUR_FRAMEBK );
45 m_desc->SetBackgroundColour( bgColor );
46 m_name->SetBackgroundColour( bgColor );
47 m_bitmap->SetBackgroundColour( bgColor );
48
49 m_name->SetFont( m_name->GetFont().Bold() );
50
51 m_name->SetLabelText( m_data.package.name );
52 m_bitmap->SetBitmap( *m_data.bitmap );
53
54 // Set min width to 0 otherwise wxStaticLabel really doesn't want to shrink on resize
55 m_desc->SetMinSize( wxSize( 0, -1 ) );
56
57 m_minHeight = GetMinHeight();
58
59 double descLineHeight = m_desc->GetTextExtent( wxT( "X" ) ).GetHeight() * 1.2 /* leading */;
60 m_desc->SetLabelText( m_data.package.description );
61
62#if wxCHECK_VERSION( 3, 3, 2 )
63 m_desc->SetWindowStyle( wxST_WRAP );
64#else
65 m_desc->Wrap( m_descSizer->GetSize().GetWidth() );
66#endif
67
68 descLineHeight = wxSplit( m_desc->GetLabel(), '\n' ).size() * descLineHeight;
69
70 int nameLineHeight = m_name->GetTextExtent( wxT( "X" ) ).GetHeight();
71 wxSize minSize = GetMinSize();
72 minSize.y = std::max( nameLineHeight + KiROUND( descLineHeight ) + FromDIP( 15 ), m_minHeight );
73 SetMinSize( minSize );
74
75 m_splitButton->SetLabel( _( "Update" ) );
76 m_splitButton->Bind( wxEVT_BUTTON, &PANEL_PACKAGE::OnButtonClicked, this );
77
78 wxMenu* splitMenu = m_splitButton->GetSplitButtonMenu();
80 splitMenu->Append( wxID_ANY, _( "Pin package" ),
81 _( "Pinned packages don't affect available update notification and "
82 "will not be updated with 'Update All' button." ),
83 wxITEM_CHECK );
84 splitMenu->Bind( wxEVT_COMMAND_MENU_SELECTED, &PANEL_PACKAGE::OnPinVersionClick, this,
85 m_pinVersionMenuItem->GetId() );
86
87 m_actionMenuItem = splitMenu->Append( wxID_ANY, _( "Uninstall" ) );
88
90 m_warningIcon->SetToolTip( _( "Warning: This plugin only supports the legacy Python API "
91 "and will not run in this KiCad version." ) );
92 m_warningIcon->Show( m_data.swig_warning );
93
94 SetState( m_data.state, m_data.pinned );
95}
96
97
98void PANEL_PACKAGE::OnSize( wxSizeEvent& event )
99{
100 Layout();
101
102 double descLineHeight = m_desc->GetTextExtent( wxT( "X" ) ).GetHeight() * 1.2 /* leading */;
103
104#if !wxCHECK_VERSION( 3, 3, 2 )
105 m_desc->SetLabelText( m_data.package.description );
106 m_desc->Wrap( m_descSizer->GetSize().GetWidth() );
107#endif
108
109 descLineHeight = wxSplit( m_desc->GetLabel(), '\n' ).size() * descLineHeight;
110
111 int nameLineHeight = m_name->GetTextExtent( wxT( "X" ) ).GetHeight();
112 wxSize minSize = GetMinSize();
113 minSize.y = std::max( nameLineHeight + KiROUND( descLineHeight ) + 15, m_minHeight );
114 SetMinSize( minSize );
115}
116
117
118void PANEL_PACKAGE::SetState( PCM_PACKAGE_STATE aState, bool aPinned )
119{
120 m_data.state = aState;
121 m_data.pinned = aPinned;
122 m_splitButton->GetSplitButtonMenu()->Check( m_pinVersionMenuItem->GetId(), aPinned );
123
124 switch( aState )
125 {
127 m_splitButton->Hide();
128 m_button->Show();
129 m_button->SetLabel( _( "Install" ) );
130 m_button->Enable();
131 break;
133 m_splitButton->Hide();
134 m_button->Show();
135 m_button->SetLabel( _( "Install" ) );
136 m_button->Disable();
137 break;
139 m_button->Hide();
140 m_splitButton->Show();
141
142 m_splitButton->SetLabel( _( "Uninstall" ) );
143 m_splitButton->Bind( wxEVT_BUTTON, &PANEL_PACKAGE::OnButtonClicked, this );
144
145 m_actionMenuItem->SetItemLabel( _( "Update" ) );
146 m_splitButton->GetSplitButtonMenu()->Enable( m_actionMenuItem->GetId(), false );
147
148 break;
150 m_splitButton->Hide();
151 m_button->Show();
152 m_button->SetLabel( _( "Install Pending" ) );
153 m_button->Disable();
154 break;
156 m_splitButton->Hide();
157 m_button->Show();
158 m_button->SetLabel( _( "Uninstall Pending" ) );
159 m_button->Disable();
160 break;
162 m_button->Hide();
163 m_splitButton->Show();
164
165 if( aPinned )
166 {
167 m_splitButton->SetLabel( _( "Uninstall" ) );
168 m_splitButton->Bind( wxEVT_BUTTON, &PANEL_PACKAGE::OnUninstallClick, this );
169
170 m_actionMenuItem->SetItemLabel( _( "Update" ) );
171 m_splitButton->GetSplitButtonMenu()->Enable( m_actionMenuItem->GetId(), true );
172 m_splitButton->GetSplitButtonMenu()->Bind( wxEVT_COMMAND_MENU_SELECTED,
174 m_actionMenuItem->GetId() );
175 }
176 else
177 {
178 m_splitButton->SetLabel( _( "Update" ) );
179 m_splitButton->Bind( wxEVT_BUTTON, &PANEL_PACKAGE::OnButtonClicked, this );
180
181 m_actionMenuItem->SetItemLabel( _( "Uninstall" ) );
182 m_splitButton->GetSplitButtonMenu()->Enable( m_actionMenuItem->GetId(), true );
183 m_splitButton->GetSplitButtonMenu()->Bind( wxEVT_COMMAND_MENU_SELECTED,
185 m_actionMenuItem->GetId() );
186 }
187 break;
189 m_splitButton->Hide();
190 m_button->Show();
191 m_button->SetLabel( _( "Update Pending" ) );
192 m_button->Disable();
193 break;
194 }
195
196 // Relayout to change button size to fit the label.
197 Layout();
198}
199
200
201void PANEL_PACKAGE::OnButtonClicked( wxCommandEvent& event )
202{
203 if( m_data.state == PPS_AVAILABLE )
204 {
205 wxString version = GetPreferredVersion();
206
207 if( version.IsEmpty() )
208 return;
209
211 }
212 else if( m_data.state == PPS_UPDATE_AVAILABLE )
213 {
214 m_actionCallback( m_data, PPA_UPDATE, m_data.update_version );
215 }
216 else
217 {
218 m_actionCallback( m_data, PPA_UNINSTALL, m_data.current_version );
219 }
220}
221
222
223void PANEL_PACKAGE::OnPinVersionClick( wxCommandEvent& event )
224{
225 m_data.pinned = event.IsChecked();
226
227 m_pinCallback( m_data.package.identifier, m_data.state, m_data.pinned );
228}
229
230
231void PANEL_PACKAGE::OnUninstallClick( wxCommandEvent& event )
232{
233 if( m_data.state == PPS_UPDATE_AVAILABLE )
234 {
235 m_actionCallback( m_data, PPA_UNINSTALL, m_data.current_version );
236 }
237 else
238 {
239 // Clicking uninstall menu item of the split button should not be possible
240 // for any state other than UPDATE_AVAILABLE
241 wxLogError( wxT( "Uninstall clicked in unexpected state" ) );
242 }
243}
244
245
246void PANEL_PACKAGE::SetSelectCallback( const std::function<void()>& aCallback )
247{
248 m_selectCallback = aCallback;
249}
250
251
252void PANEL_PACKAGE::OnClick( wxMouseEvent& event )
253{
255}
256
257
258void PANEL_PACKAGE::OnPaint( wxPaintEvent& event )
259{
260 wxRect rect( wxPoint( 1, 1 ), GetClientSize() - wxSize( 1, 1 ) );
261 wxPaintDC dc( this );
262 dc.SetBrush( wxSystemSettings::GetColour( wxSYS_COLOUR_FRAMEBK ) );
263 dc.SetPen( wxPen( wxSystemSettings::GetColour( wxSYS_COLOUR_ACTIVEBORDER ), 1 ) );
264
265 if( m_selected )
266 {
267 rect.Deflate( 1 );
268 dc.SetPen( wxPen( wxSystemSettings::GetColour( wxSYS_COLOUR_HOTLIGHT ), 3 ) );
269 }
270
271 dc.DrawRectangle( rect );
272}
273
274
275void PANEL_PACKAGE::SetSelected( bool aSelected )
276{
277 m_selected = aSelected;
278 Refresh();
279}
280
281
283{
284 // Versions are already presorted in descending order
285
286 // Find last stable compatible version
287 auto ver_it = std::find_if( m_data.package.versions.begin(), m_data.package.versions.end(),
288 []( const PACKAGE_VERSION& ver )
289 {
290 return ver.compatible && ver.status == PVS_STABLE;
291 } );
292
293 // If not found then find any compatible version
294 if( ver_it == m_data.package.versions.end() )
295 {
296 ver_it = std::find_if( m_data.package.versions.begin(), m_data.package.versions.end(),
297 []( const PACKAGE_VERSION& ver )
298 {
299 return ver.compatible;
300 } );
301 }
302
303 if( ver_it == m_data.package.versions.end() )
304 return wxEmptyString; // Shouldn't happen
305
306 return ver_it->version;
307}
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition bitmap.cpp:110
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:990
wxStaticBitmap * m_bitmap
PANEL_PACKAGE_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxBORDER_NONE|wxTAB_TRAVERSAL, const wxString &name=wxEmptyString)
SPLIT_BUTTON * m_splitButton
wxStaticBitmap * m_warningIcon
void OnClick(wxMouseEvent &event) override
void OnUninstallClick(wxCommandEvent &event)
wxMenuItem * m_actionMenuItem
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
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
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
std::function< void(const PACKAGE_VIEW_DATA &aData, PCM_PACKAGE_ACTION aAction, const wxString &aVersion)> ActionCallback
PCM_PACKAGE_STATE
Definition pcm.h:58
@ PPS_INSTALLED
Definition pcm.h:61
@ PPS_PENDING_UPDATE
Definition pcm.h:65
@ PPS_UNAVAILABLE
Definition pcm.h:60
@ PPS_UPDATE_AVAILABLE
Definition pcm.h:64
@ PPS_PENDING_UNINSTALL
Definition pcm.h:63
@ PPS_PENDING_INSTALL
Definition pcm.h:62
@ PPS_AVAILABLE
Definition pcm.h:59
@ PPA_UNINSTALL
Definition pcm.h:73
@ PPA_UPDATE
Definition pcm.h:74
@ PPA_INSTALL
Definition pcm.h:72
< Package version metadataPackage metadata
Definition pcm_data.h:92
< Collection of data relevant to the package display panelCallback for (un)install button