1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-09-17 16:50:26 +02:00

Define BasicUI::MakeProgress as abstract factory for progress dialogs

This commit is contained in:
Paul Licameli 2021-03-01 19:49:11 -05:00
parent 98b1669e93
commit 0555c1139d
9 changed files with 116 additions and 11 deletions

View File

@ -17,6 +17,8 @@ WindowPlacement::~WindowPlacement() = default;
Services::~Services() = default;
ProgressDialog::~ProgressDialog() = default;
static Services *theInstance = nullptr;
Services *Get() { return theInstance; }

View File

@ -12,6 +12,7 @@ Paul Licameli
#define __AUDACITY_BASIC_UI__
#include <functional>
#include <memory>
#include "Identifier.h"
#include "Internat.h"
@ -133,6 +134,34 @@ enum class MessageBoxResult : int {
Cancel,
};
enum ProgressDialogOptions : unsigned {
ProgressShowStop = (1 << 0),
ProgressShowCancel = (1 << 1),
ProgressHideTime = (1 << 2),
ProgressConfirmStopOrCancel = (1 << 3),
};
enum class ProgressResult : unsigned
{
Cancelled = 0, //<! User says that whatever is happening is undesirable and shouldn't have happened at all
Success, //<! User says nothing, everything works fine, continue doing whatever we're doing
Failed, //<! Something has gone wrong, we should stop and cancel everything we did
Stopped //<! Nothing is wrong, but user says we should stop now and leave things as they are now
};
//! Abstraction of a progress dialog with well defined time-to-completion estimate
class BASIC_UI_API ProgressDialog
{
public:
virtual ~ProgressDialog();
//! Update the bar and poll for clicks. Call only on the main thread.
virtual ProgressResult Poll(
unsigned long long numerator,
unsigned long long denominator,
const TranslatableString &message = {}) = 0;
};
//! @}
//! Abstract class defines a few user interface services, not mentioning particular toolkits
@ -152,6 +181,11 @@ public:
virtual MessageBoxResult DoMessageBox(
const TranslatableString& message,
MessageBoxOptions options) = 0;
virtual std::unique_ptr<ProgressDialog>
DoMakeProgress(const TranslatableString &title,
const TranslatableString &message,
unsigned flag,
const TranslatableString &remainingLabelText) = 0;
};
//! Fetch the global instance, or nullptr if none is yet installed
@ -207,8 +241,25 @@ inline MessageBoxResult ShowMessageBox( const TranslatableString &message,
return MessageBoxResult::None;
}
//! Create and display a progress dialog
/*!
@param flags bitwise OR of values in ProgressDialogOptions
@param remainingLabelText if not empty substitutes for "Remaining Time:"
@return nullptr if Services not installed
*/
inline std::unique_ptr<ProgressDialog> MakeProgress(
const TranslatableString & title,
const TranslatableString & message,
unsigned flags = (ProgressShowStop | ProgressShowCancel),
const TranslatableString & remainingLabelText = {})
{
if (auto p = Get())
return p->DoMakeProgress(title, message, flags, remainingLabelText);
else
return nullptr;
}
//! @}
}
#endif

View File

@ -55,6 +55,8 @@ class AudacityProject;
class TimerRecordDialog final : public wxDialogWrapper
{
public:
using ProgressResult = BasicUI::ProgressResult;
TimerRecordDialog(
wxWindow* parent, AudacityProject &project, bool bAlreadySaved);
~TimerRecordDialog();

View File

@ -36,7 +36,7 @@ class ProgressDialog;
class ShuttleGui;
class Mixer;
using WaveTrackConstArray = std::vector < std::shared_ptr < const WaveTrack > >;
enum class ProgressResult : unsigned;
namespace BasicUI{ enum class ProgressResult : unsigned; }
class wxFileNameWrapper;
class AUDACITY_DLL_API FormatInfo
@ -64,6 +64,7 @@ class AUDACITY_DLL_API FormatInfo
class AUDACITY_DLL_API ExportPlugin /* not final */
{
public:
using ProgressResult = BasicUI::ProgressResult;
ExportPlugin();
virtual ~ExportPlugin();

View File

@ -32,6 +32,7 @@ class Track;
class AUDACITY_DLL_API ExportMultipleDialog final : public wxDialogWrapper
{
public:
using ProgressResult = BasicUI::ProgressResult;
ExportMultipleDialog(AudacityProject *parent);
virtual ~ExportMultipleDialog();

View File

@ -55,7 +55,7 @@ but little else.
class AudacityProject;
class ProgressDialog;
enum class ProgressResult : unsigned;
namespace BasicUI{ enum class ProgressResult : unsigned; }
class WaveTrackFactory;
class Track;
class Tags;
@ -105,6 +105,8 @@ using TrackHolders = std::vector< std::vector< std::shared_ptr<WaveTrack> > >;
class AUDACITY_DLL_API ImportFileHandle /* not final */
{
public:
using ProgressResult = BasicUI::ProgressResult;
ImportFileHandle(const FilePath & filename);
virtual ~ImportFileHandle();

View File

@ -26,17 +26,12 @@
#include "wxPanelWrapper.h" // to inherit
#include "BasicUI.h" // For ProgressResult
using ProgressResult = BasicUI::ProgressResult;
class wxGauge;
class wxStaticText;
enum class ProgressResult : unsigned
{
Cancelled = 0, //<! User says that whatever is happening is undesirable and shouldn't have happened at all
Success, //<! User says nothing, everything works fine, continue doing whatever we're doing
Failed, //<! Something has gone wrong, we should stop and cancel everything we did
Stopped //<! Nothing is wrong, but user says we should stop now and leave things as they are now
};
enum ProgressDialogFlags
{
pdlgEmptyFlags = 0x00000000,

View File

@ -14,7 +14,9 @@ Paul Licameli
#include "widgets/ErrorReportDialog.h"
#endif
#include "widgets/AudacityMessageBox.h"
#include "ProgressDialog.h"
#include <wx/app.h>
#include <wx/windowptr.h>
using namespace BasicUI;
@ -158,3 +160,47 @@ wxWidgetsBasicUI::DoMessageBox(
return MessageBoxResult::None;
}
}
namespace {
struct MyProgressDialog : BasicUI::ProgressDialog {
wxWindowPtr<::ProgressDialog> mpDialog;
explicit MyProgressDialog(::ProgressDialog *pDialog)
: mpDialog{ pDialog }
{
wxASSERT(pDialog);
}
~MyProgressDialog() override = default;
ProgressResult Poll(
unsigned long long numerator,
unsigned long long denominator,
const TranslatableString &message) override
{
return mpDialog->Update(numerator, denominator, message);
}
};
}
std::unique_ptr<BasicUI::ProgressDialog>
wxWidgetsBasicUI::DoMakeProgress(const TranslatableString & title,
const TranslatableString &message,
unsigned flags,
const TranslatableString &remainingLabelText)
{
unsigned options = 0;
if (~(flags & ProgressShowStop))
options |= pdlgHideStopButton;
if (~(flags & ProgressShowCancel))
options |= pdlgHideCancelButton;
if ((flags & ProgressHideTime))
options |= pdlgHideElapsedTime;
if ((flags & ProgressConfirmStopOrCancel))
options |= pdlgConfirmStopCancel;
// Note that wxWindow objects should not be managed by std::unique_ptr
// See https://docs.wxwidgets.org/3.0/overview_windowdeletion.html
// So there is an extra indirection: return a deletable object that holds
// the proper kind of smart pointer to a wxWindow.
return std::make_unique<MyProgressDialog>(
safenew ::ProgressDialog(
title, message, options, remainingLabelText));
}

View File

@ -44,6 +44,11 @@ protected:
BasicUI::MessageBoxResult DoMessageBox(
const TranslatableString &message,
BasicUI::MessageBoxOptions options) override;
std::unique_ptr<BasicUI::ProgressDialog>
DoMakeProgress(const TranslatableString & title,
const TranslatableString &message,
unsigned flags,
const TranslatableString &remainingLabelText) override;
};
#endif