Implement an app progress indicator in the taskbar

ADDED: Progress indicator in the taskbar

This adds a progress indicator to the Windows and macOS taskbar
icons to display the progress of some operations.

Note, this requires wxWidgets 3.1+
This commit is contained in:
Mark Roszko 2020-08-09 10:55:00 +00:00 committed by Ian McInerney
parent 4d460ec073
commit c6e388db14
15 changed files with 183 additions and 44 deletions

View File

@ -200,6 +200,7 @@ set( COMMON_DLG_SRCS
)
set( COMMON_WIDGET_SRCS
widgets/app_progress_dialog.cpp
widgets/button_row_panel.cpp
widgets/color_swatch.cpp
widgets/footprint_choice.cpp

View File

@ -0,0 +1,56 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <wx/version.h>
#include <widgets/app_progress_dialog.h>
APP_PROGRESS_DIALOG::APP_PROGRESS_DIALOG( const wxString& aTitle, const wxString& aMessage,
int aMaximum, wxWindow* aParent,
bool aIndeterminateTaskBarStatus, int aStyle )
: wxProgressDialog( aTitle, aMessage, aMaximum, aParent, aStyle ),
#if wxCHECK_VERSION( 3, 1, 0 )
m_appProgressIndicator( aParent, aMaximum ),
#endif
m_indeterminateTaskBarStatus( aIndeterminateTaskBarStatus )
{
#if wxCHECK_VERSION( 3, 1, 0 )
if( m_indeterminateTaskBarStatus )
{
m_appProgressIndicator.Pulse();
}
#endif
}
bool APP_PROGRESS_DIALOG::Update( int aValue, const wxString& aNewMsg, bool* aSkip )
{
#if wxCHECK_VERSION( 3, 1, 0 )
if( !m_indeterminateTaskBarStatus )
{
m_appProgressIndicator.SetValue( aValue );
}
#endif
return wxProgressDialog::Update( aValue, aNewMsg, aSkip );
}

View File

@ -18,6 +18,7 @@
*/
#include <dialog_shim.h>
#include <eda_draw_frame.h>
#include <kiway.h>
#include <kiway_player.h>
#include <project.h>
@ -41,15 +42,16 @@ enum
wxDEFINE_EVENT( EVT_FOOTPRINT_SELECTED, wxCommandEvent );
FOOTPRINT_SELECT_WIDGET::FOOTPRINT_SELECT_WIDGET( wxWindow* aParent, FOOTPRINT_LIST* aFpList,
bool aUpdate, int aMaxItems ) :
FOOTPRINT_SELECT_WIDGET::FOOTPRINT_SELECT_WIDGET( EDA_DRAW_FRAME* aFrame, wxWindow* aParent,
FOOTPRINT_LIST* aFpList, bool aUpdate, int aMaxItems ) :
wxPanel( aParent ),
m_kiway( nullptr ),
m_update( aUpdate ),
m_finished_loading( false ),
m_max_items( aMaxItems ),
m_last_item( 0 ),
m_fp_list( aFpList )
m_fp_list( aFpList ),
m_eda_frame( aFrame )
{
m_zero_filter = true;
m_sizer = new wxBoxSizer( wxVERTICAL );
@ -74,7 +76,8 @@ void FOOTPRINT_SELECT_WIDGET::Load( KIWAY& aKiway, PROJECT& aProject )
auto fp_lib_table = aProject.PcbFootprintLibs( aKiway );
m_fp_list = FOOTPRINT_LIST::GetInstance( aKiway );
WX_PROGRESS_REPORTER progressReporter( this, _( "Loading Footprint Libraries" ), 2 );
// We parent to the eda frame so that the taskbar progress indicator displays on it
WX_PROGRESS_REPORTER progressReporter( m_eda_frame, _( "Loading Footprint Libraries" ), 2 );
m_fp_list->ReadFootprintFiles( fp_lib_table, nullptr, &progressReporter );
FootprintsLoaded();
}

View File

@ -124,7 +124,16 @@ WX_PROGRESS_REPORTER::WX_PROGRESS_REPORTER( wxWindow* aParent, const wxString& a
// causes all sorts of grief
( aCanAbort ? wxPD_CAN_ABORT : 0 ) |
wxPD_ELAPSED_TIME )
#if wxCHECK_VERSION( 3, 1, 0 )
,m_appProgressIndicator( aParent )
#endif
{
#if wxCHECK_VERSION( 3, 1, 0 )
// wxAppProgressIndicator doesn't like value > max, ever. However there are some risks
// with multithreaded setting of those values making a mess
// the cop out is just to set the progress to "indeterminate"
m_appProgressIndicator.Pulse();
#endif
}

View File

@ -42,6 +42,7 @@
#include <project/project_file.h>
#include <project_rescue.h>
#include <properties.h>
#include <widgets/app_progress_dialog.h>
#include <general.h>
#include <class_library.h>
@ -494,10 +495,11 @@ void PART_LIBS::LoadAllLibraries( PROJECT* aProject, bool aShowProgress )
// Post symbol library table, this should be empty. Only the cache library should get loaded.
if( !lib_names.empty() )
{
wxProgressDialog lib_dialog( _( "Loading Symbol Libraries" ),
APP_PROGRESS_DIALOG lib_dialog( _( "Loading Symbol Libraries" ),
wxEmptyString,
lib_names.GetCount(),
NULL,
false,
wxPD_APP_MODAL );
if( aShowProgress )

View File

@ -244,7 +244,7 @@ wxPanel* DIALOG_CHOOSE_COMPONENT::ConstructRightPanel( wxWindow* aParent )
if ( fp_list )
{
if( m_allow_field_edits )
m_fp_sel_ctrl = new FOOTPRINT_SELECT_WIDGET( panel, fp_list, true );
m_fp_sel_ctrl = new FOOTPRINT_SELECT_WIDGET( m_parent, panel, fp_list, true );
m_fp_preview = new FOOTPRINT_PREVIEW_WIDGET( panel, Kiway() );
}

View File

@ -58,11 +58,11 @@
#include <tools/lib_edit_tool.h>
#include <tools/lib_move_tool.h>
#include <tools/lib_pin_tool.h>
#include <widgets/app_progress_dialog.h>
#include <widgets/infobar.h>
#include <widgets/lib_tree.h>
#include <widgets/symbol_tree_pane.h>
#include <wildcards_and_files_ext.h>
#include <wx/progdlg.h>
bool LIB_EDIT_FRAME:: m_showDeMorgan = false;
@ -593,7 +593,7 @@ void LIB_EDIT_FRAME::SyncLibraries( bool aShowProgress )
if( aShowProgress )
{
wxProgressDialog progressDlg( _( "Loading Symbol Libraries" ), wxEmptyString,
APP_PROGRESS_DIALOG progressDlg( _( "Loading Symbol Libraries" ), wxEmptyString,
m_libMgr->GetAdapter()->GetLibrariesCount(), this );
m_libMgr->Sync( true, [&]( int progress, int max, const wxString& libName )

View File

@ -20,7 +20,8 @@
*/
#include <wx/tokenzr.h>
#include <wx/progdlg.h>
#include <wx/window.h>
#include <widgets/app_progress_dialog.h>
#include <eda_pattern_match.h>
#include <symbol_lib_table.h>
@ -55,12 +56,12 @@ SYMBOL_TREE_MODEL_ADAPTER::~SYMBOL_TREE_MODEL_ADAPTER()
void SYMBOL_TREE_MODEL_ADAPTER::AddLibraries( const std::vector<wxString>& aNicknames,
wxWindow* aParent )
{
wxProgressDialog* prg = nullptr;
APP_PROGRESS_DIALOG* prg = nullptr;
wxLongLong nextUpdate = wxGetUTCTimeMillis() + (PROGRESS_INTERVAL_MILLIS / 2);
if( m_show_progress )
{
prg = new wxProgressDialog( _( "Loading Symbol Libraries" ), wxEmptyString,
prg = new APP_PROGRESS_DIALOG( _( "Loading Symbol Libraries" ), wxEmptyString,
aNicknames.size(), aParent );
}
@ -71,6 +72,7 @@ void SYMBOL_TREE_MODEL_ADAPTER::AddLibraries( const std::vector<wxString>& aNick
if( prg && wxGetUTCTimeMillis() > nextUpdate )
{
prg->Update( ii, wxString::Format( _( "Loading library \"%s\"" ), nickname ) );
nextUpdate = wxGetUTCTimeMillis() + PROGRESS_INTERVAL_MILLIS;
}

View File

@ -0,0 +1,53 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __APP_PROGRESS_REPORTER
#define __APP_PROGRESS_REPORTER
#include <wx/progdlg.h>
#if wxCHECK_VERSION(3, 1, 0)
#include <wx/appprogress.h>
#endif
/**
* wxProgressDialog with the option to also update the application progress on the taskbar
*/
class APP_PROGRESS_DIALOG : public wxProgressDialog
{
public:
APP_PROGRESS_DIALOG( const wxString& aTitle, const wxString& aMessage, int aMaximum = 100,
wxWindow* aParent = NULL, bool aIndeterminateTaskBarStatus = false,
int aStyle = wxPD_APP_MODAL | wxPD_AUTO_HIDE );
virtual bool Update(
int aValue, const wxString& aNewMsg = wxEmptyString, bool* aSkip = NULL ) override;
private:
#if wxCHECK_VERSION( 3, 1, 0 )
wxAppProgressIndicator m_appProgressIndicator;
#endif
bool m_indeterminateTaskBarStatus;
};
#endif

View File

@ -59,7 +59,7 @@ public:
* @param aMaxItems - maximum number of filter items to display, in addition to
* Default and Other
*/
FOOTPRINT_SELECT_WIDGET( wxWindow* aParent, FOOTPRINT_LIST* aFpList,
FOOTPRINT_SELECT_WIDGET( EDA_DRAW_FRAME* aFrame, wxWindow* aParent, FOOTPRINT_LIST* aFpList,
bool aUpdate = true, int aMaxItems = 400 );
virtual ~FOOTPRINT_SELECT_WIDGET()
@ -138,6 +138,7 @@ private:
FOOTPRINT_LIST* m_fp_list;
FOOTPRINT_FILTER m_fp_filter;
bool m_zero_filter;
EDA_DRAW_FRAME* m_eda_frame;
void FootprintsLoaded();
void OnComboBox( wxCommandEvent& aEvent );

View File

@ -30,6 +30,9 @@
#include <wx/progdlg.h>
#include <wx/gauge.h>
#if wxCHECK_VERSION(3, 1, 0)
#include <wx/appprogress.h>
#endif
/**
* A progress reporter for use in multi-threaded environments. The various advancement
@ -109,7 +112,10 @@ class PROGRESS_REPORTER
std::atomic_bool m_cancelled;
};
/**
* Multi-thread safe progress reporter dialog, intended for use of tasks that paralleize reporting back of work status
* See PROGRESS_REPORTER
*/
class WX_PROGRESS_REPORTER : public PROGRESS_REPORTER, public wxProgressDialog
{
public:
@ -136,6 +142,9 @@ public:
}
private:
#if wxCHECK_VERSION(3, 1, 0)
wxAppProgressIndicator m_appProgressIndicator;
#endif
virtual bool updateUI() override;
};

View File

@ -35,7 +35,7 @@
#include <wx/wx.h>
#include <wx/uri.h>
#include <wx/dir.h>
#include <wx/progdlg.h>
#include <widgets/app_progress_dialog.h>
#include <pgm_base.h>
#include <project.h>
@ -352,8 +352,8 @@ bool WIZARD_3DSHAPE_LIBS_DOWNLOADER::downloadGithubLibsFromList( wxArrayString&
// The title is updated for each downloaded library.
// the state will be updated by downloadOneLib() for each file.
// for OSX do not enable wPD_APP_MODAL, keep wxPD_AUTO_HIDE
wxProgressDialog pdlg( _( "Downloading 3D libraries" ), wxEmptyString,
aUrlList.GetCount(), this,
APP_PROGRESS_DIALOG pdlg( _( "Downloading 3D libraries" ), wxEmptyString,
aUrlList.GetCount(), this, true,
#ifndef __WXMAC__
wxPD_APP_MODAL |
#endif

View File

@ -47,7 +47,6 @@
#include <netlist_reader/pcb_netlist.h>
#include <math/util.h> // for KiROUND
#include <dialog_drc.h>
#include <wx/progdlg.h>
#include <board_commit.h>
#include <geometry/shape_segment.h>
#include <geometry/shape_arc.h>
@ -61,6 +60,8 @@
#include <drc/footprint_tester.h>
#include <dialogs/panel_setup_rules.h>
#include <reporter.h>
#include <widgets/app_progress_dialog.h>
DRC::DRC() :
PCB_TOOL_BASE( "pcbnew.DRCTool" ),
@ -541,7 +542,7 @@ void DRC::testPadClearances( BOARD_COMMIT& aCommit )
void DRC::testTracks( BOARD_COMMIT& aCommit, wxWindow *aActiveWindow, bool aShowProgressBar )
{
wxProgressDialog* progressDialog = NULL;
APP_PROGRESS_DIALOG* progressDialog = NULL;
const int delta = 500; // This is the number of tests between 2 calls to the
// progress bar
int count = m_pcb->Tracks().size();
@ -551,8 +552,8 @@ void DRC::testTracks( BOARD_COMMIT& aCommit, wxWindow *aActiveWindow, bool aShow
{
// Do not use wxPD_APP_MODAL style here: it is not necessary and create issues
// on OSX
progressDialog = new wxProgressDialog( _( "Track clearances" ), wxEmptyString,
deltamax, aActiveWindow,
progressDialog = new APP_PROGRESS_DIALOG( _( "Track clearances" ), wxEmptyString,
deltamax, aActiveWindow, false,
wxPD_AUTO_HIDE | wxPD_CAN_ABORT | wxPD_ELAPSED_TIME );
progressDialog->Update( 0, wxEmptyString );
}

View File

@ -124,6 +124,13 @@ bool FOOTPRINT_LIST_IMPL::ReadFootprintFiles( FP_LIB_TABLE* aTable, const wxStri
return true;
m_progress_reporter = aProgressReporter;
if( m_progress_reporter )
{
m_progress_reporter->SetMaxProgress( m_queue_in.size() );
m_progress_reporter->Report( _( "Fetching Footprint Libraries" ) );
}
m_cancelled = false;
FOOTPRINT_ASYNC_LOADER loader;
@ -131,11 +138,6 @@ bool FOOTPRINT_LIST_IMPL::ReadFootprintFiles( FP_LIB_TABLE* aTable, const wxStri
loader.SetList( this );
loader.Start( aTable, aNickname );
if( m_progress_reporter )
{
m_progress_reporter->SetMaxProgress( m_queue_in.size() );
m_progress_reporter->Report( _( "Fetching Footprint Libraries" ) );
}
while( !m_cancelled && (int)m_count_finished.load() < m_loader->m_total_libs )
{
@ -153,8 +155,8 @@ bool FOOTPRINT_LIST_IMPL::ReadFootprintFiles( FP_LIB_TABLE* aTable, const wxStri
{
if( m_progress_reporter )
{
m_progress_reporter->AdvancePhase();
m_progress_reporter->SetMaxProgress( m_queue_out.size() );
m_progress_reporter->AdvancePhase();
m_progress_reporter->Report( _( "Loading Footprints" ) );
}

View File

@ -47,7 +47,6 @@
#include <netlist_reader/pcb_netlist.h>
#include <math/util.h> // for KiROUND
#include <dialog_drc.h>
#include <wx/progdlg.h>
#include <board_commit.h>
#include <geometry/shape_arc.h>
#include <drc/drc.h>
@ -60,6 +59,7 @@
#include <drc/drc_textvar_tester.h>
#include <drc/footprint_tester.h>
#include <dialogs/panel_setup_rules.h>
#include <widgets/app_progress_dialog.h>
DRC::DRC() :
PCB_TOOL_BASE( "pcbnew.DRCTool" ),
@ -575,7 +575,7 @@ void DRC::testPadClearances( BOARD_COMMIT& aCommit )
void DRC::testTracks( BOARD_COMMIT& aCommit, wxWindow *aActiveWindow, bool aShowProgressBar )
{
wxProgressDialog* progressDialog = NULL;
APP_PROGRESS_DIALOG* progressDialog = NULL;
const int delta = 500; // This is the number of tests between 2 calls to the
// progress bar
int count = m_pcb->Tracks().size();
@ -585,8 +585,8 @@ void DRC::testTracks( BOARD_COMMIT& aCommit, wxWindow *aActiveWindow, bool aShow
{
// Do not use wxPD_APP_MODAL style here: it is not necessary and create issues
// on OSX
progressDialog = new wxProgressDialog( _( "Track clearances" ), wxEmptyString,
deltamax, aActiveWindow,
progressDialog = new APP_PROGRESS_DIALOG( _( "Track clearances" ), wxEmptyString,
deltamax, aActiveWindow, false,
wxPD_AUTO_HIDE | wxPD_CAN_ABORT | wxPD_ELAPSED_TIME );
progressDialog->Update( 0, wxEmptyString );
}