Audacity 3.2.0
BasicUI.h
Go to the documentation of this file.
1/*!********************************************************************
2
3Audacity: A Digital Audio Editor
4
5@file BasicUI.h
6@brief Toolkit-neutral facade for basic user interface services
7
8Paul Licameli
9
10**********************************************************************/
11#ifndef __AUDACITY_BASIC_UI__
12#define __AUDACITY_BASIC_UI__
13
14#include <functional>
15#include <memory>
16#include "Identifier.h"
17#include "Internat.h"
18
19namespace BasicUI {
20
23
24using Action = std::function<void()>;
25using ProgressReporter = std::function<void(double)>;
26
28
30class BASIC_UI_API WindowPlacement {
31public:
32 WindowPlacement() = default;
33
35 WindowPlacement( const WindowPlacement& ) = delete;
39 virtual explicit operator bool() const;
41};
42
43enum class ErrorDialogType {
49};
50
53
54 ErrorDialogOptions() = default;
57
60
61 ErrorDialogOptions &&ModalHelp( bool modalHelp_ ) &&
62 { modalHelp = modalHelp_; return std::move(*this); }
63
64 ErrorDialogOptions &&Log( std::wstring log_ ) &&
65 { log = std::move(log_); return std::move(*this); }
66
68
72 bool modalHelp{ true };
74 std::wstring log;
75};
76
79
80enum class Icon {
81 None,
82 Warning,
83 Error,
86};
87
88enum class Button {
89 Default,
90 Ok,
91 YesNo
92};
93
97
99 { parent = parent_; return std::move(*this); }
100
102 { caption = std::move(caption_); return std::move(*this); }
103
105 { iconStyle = style; return std::move(*this); }
106
108 { buttonStyle = style; return std::move(*this); }
109
112 { yesOrOkDefaultButton = false; return std::move(*this); }
113
115 { cancelButton = true; return std::move(*this); }
116
119 { centered = true; return std::move(*this); }
120
122
128 bool cancelButton{ false };
129 bool centered{ false };
130};
131
132enum class MessageBoxResult : int {
133 None,
134 Yes,
135 No,
136 Ok,
137 Cancel,
138};
139
140enum ProgressDialogOptions : unsigned {
145};
146
151 ProgressSmooth = (1 << 3),
152};
153
154enum class ProgressResult : unsigned
155{
156 Cancelled = 0, //<! User says that whatever is happening is undesirable and shouldn't have happened at all
157 Success, //<! User says nothing, everything works fine, continue doing whatever we're doing
158 Failed, //<! Something has gone wrong, we should stop and cancel everything we did
159 Stopped //<! Nothing is wrong, but user says we should stop now and leave things as they are now
160};
161
163class BASIC_UI_API ProgressDialog
164{
165public:
167
170 unsigned long long numerator,
171 unsigned long long denominator,
172 const TranslatableString &message = {}) = 0;
173
175 virtual void SetMessage(const TranslatableString & message) = 0;
176
178 virtual void SetDialogTitle(const TranslatableString & title) = 0;
179
181 virtual void Reinit() = 0;
182};
183
185class BASIC_UI_API GenericProgressDialog
186{
187public:
190 virtual ProgressResult Pulse() = 0;
191};
192
194
196
199class BASIC_UI_API Services {
200public:
201 virtual ~Services();
202 virtual void DoCallAfter(const Action &action) = 0;
203 virtual void DoYield() = 0;
204 virtual void DoShowErrorDialog(const WindowPlacement &placement,
205 const TranslatableString &dlogTitle,
206 const TranslatableString &message,
207 const ManualPageID &helpPage,
208 const ErrorDialogOptions &options) = 0;
210 const TranslatableString& message,
211 MessageBoxOptions options) = 0;
212 virtual std::unique_ptr<ProgressDialog>
214 const TranslatableString &message,
215 unsigned flag,
216 const TranslatableString &remainingLabelText) = 0;
217 virtual std::unique_ptr<GenericProgressDialog>
220 const TranslatableString &message,
221 int style) = 0;
222 virtual int DoMultiDialog(const TranslatableString &message,
224 const TranslatableStrings &buttons,
225 const ManualPageID &helpPage,
226 const TranslatableString &boxMsg, bool log) = 0;
227
228 virtual bool DoOpenInDefaultBrowser(const wxString &url) = 0;
229
230 virtual std::unique_ptr<WindowPlacement> DoFindFocus() = 0;
231 virtual void DoSetFocus(const WindowPlacement &focus) = 0;
232
233 virtual bool IsUsingRtlLayout() const = 0;
234
235 virtual bool IsUiThread() const = 0;
236};
237
239BASIC_UI_API Services *Get();
240
242BASIC_UI_API Services *Install(Services *pInstance);
243
250
252
256BASIC_UI_API void CallAfter(Action action);
257
259
264BASIC_UI_API void Yield();
265
267
269BASIC_UI_API bool OpenInDefaultBrowser(const wxString &url);
270
272inline void ShowErrorDialog(
273 const WindowPlacement &placement,
274 const TranslatableString &dlogTitle,
275 const TranslatableString &message,
276 const ManualPageID &helpPage,
277 const ErrorDialogOptions &options = {})
278{
279 if (auto p = Get())
280 p->DoShowErrorDialog(placement, dlogTitle, message, helpPage, options);
281}
282
284
288 MessageBoxOptions options = {})
289{
290 if (auto p = Get())
291 return p->DoMessageBox(message, std::move(options));
292 else
294}
295
297
302inline std::unique_ptr<ProgressDialog> MakeProgress(
304 const TranslatableString & message,
305 unsigned flags = (ProgressShowStop | ProgressShowCancel),
306 const TranslatableString & remainingLabelText = {})
307{
308 if (auto p = Get())
309 return p->DoMakeProgress(title, message, flags, remainingLabelText);
310 else
311 return nullptr;
312}
313
315
320inline std::unique_ptr<GenericProgressDialog> MakeGenericProgress(
321 const WindowPlacement &placement,
323{
324 if (auto p = Get())
325 return p->DoMakeGenericProgress(placement, title, message, style);
326 else
327 return nullptr;
328}
329
338template <typename ItType, typename FnType>
340 ItType first, ItType last, FnType action, ProgressReporter parent)
341{
342 auto count = 0;
343 const auto numIters = std::distance(first, last);
344 if (numIters == 0)
345 return;
346 const ProgressReporter child =
347 parent ? [&](double progress) { parent((count + progress) / numIters); } :
349
350 for (; first != last; ++first)
351 {
352 action(*first, child);
353 ++count;
354 }
355}
356
358
367inline int ShowMultiDialog(const TranslatableString &message,
369 const TranslatableStrings &buttons,
370 const ManualPageID &helpPage,
371 const TranslatableString &boxMsg, bool log)
372{
373 if (auto p = Get())
374 return p->DoMultiDialog(message, title, buttons, helpPage, boxMsg, log);
375 else
376 return -1;
377}
378
380
383inline std::unique_ptr<WindowPlacement> FindFocus()
384{
385 if (auto p = Get())
386 if (auto result = p->DoFindFocus())
387 return result;
388 return std::make_unique<WindowPlacement>();
389}
390
392inline void SetFocus(const WindowPlacement &focus)
393{
394 if (auto p = Get())
395 p->DoSetFocus(focus);
396}
397
399inline bool IsUsingRtlLayout()
400{
401 if (auto p = Get())
402 return p->IsUsingRtlLayout();
403 return false;
404}
405
407inline bool IsUiThread ()
408{
409 if (auto p = Get())
410 return p->IsUiThread();
411 return true;
412}
413
414#define ASSERT_MAIN_THREAD() \
415 assert( \
416 BasicUI::IsUiThread() && \
417 "This function should only be called on the main thread")
418
420}
421
422#endif
static const auto title
std::vector< TranslatableString > TranslatableStrings
static std::once_flag flag
Abstraction of a progress dialog with undefined time-to-completion estimate.
Definition: BasicUI.h:186
virtual ProgressResult Pulse()=0
Give some visual indication of progress. Call only on the main thread.
Abstraction of a progress dialog with well defined time-to-completion estimate.
Definition: BasicUI.h:164
virtual ProgressResult Poll(unsigned long long numerator, unsigned long long denominator, const TranslatableString &message={})=0
Update the bar and poll for clicks. Call only on the main thread.
virtual void SetMessage(const TranslatableString &message)=0
Change an existing dialog's message.
virtual void SetDialogTitle(const TranslatableString &title)=0
Change the dialog's title.
virtual void Reinit()=0
Reset the dialog state.
Abstract class defines a few user interface services, not mentioning particular toolkits.
Definition: BasicUI.h:199
virtual std::unique_ptr< WindowPlacement > DoFindFocus()=0
virtual void DoShowErrorDialog(const WindowPlacement &placement, const TranslatableString &dlogTitle, const TranslatableString &message, const ManualPageID &helpPage, const ErrorDialogOptions &options)=0
virtual ~Services()
virtual void DoSetFocus(const WindowPlacement &focus)=0
virtual std::unique_ptr< GenericProgressDialog > DoMakeGenericProgress(const WindowPlacement &placement, const TranslatableString &title, const TranslatableString &message, int style)=0
virtual bool IsUsingRtlLayout() const =0
virtual std::unique_ptr< ProgressDialog > DoMakeProgress(const TranslatableString &title, const TranslatableString &message, unsigned flag, const TranslatableString &remainingLabelText)=0
virtual MessageBoxResult DoMessageBox(const TranslatableString &message, MessageBoxOptions options)=0
virtual int DoMultiDialog(const TranslatableString &message, const TranslatableString &title, const TranslatableStrings &buttons, const ManualPageID &helpPage, const TranslatableString &boxMsg, bool log)=0
virtual void DoCallAfter(const Action &action)=0
virtual bool DoOpenInDefaultBrowser(const wxString &url)=0
virtual void DoYield()=0
virtual bool IsUiThread() const =0
Subclasses may hold information such as a parent window pointer for a dialog.
Definition: BasicUI.h:30
WindowPlacement & operator=(const WindowPlacement &)=delete
Don't slice.
WindowPlacement(const WindowPlacement &)=delete
Don't slice.
Holds a msgid for the translation catalog; may also bind format arguments.
std::function< void(double)> ProgressReporter
Definition: BasicUI.h:25
TranslatableString DefaultCaption()
"Message", suitably translated
Definition: BasicUI.cpp:259
void SetFocus(const WindowPlacement &focus)
Set the window that accepts keyboard input.
Definition: BasicUI.h:392
ProgressResult
Definition: BasicUI.h:155
std::unique_ptr< GenericProgressDialog > MakeGenericProgress(const WindowPlacement &placement, const TranslatableString &title, const TranslatableString &message, int style=(ProgressAppModal|ProgressShowElapsedTime|ProgressSmooth))
Create and display a progress dialog (return nullptr if Services not installed)
Definition: BasicUI.h:320
ProgressDialogOptions
Definition: BasicUI.h:140
@ ProgressHideTime
Definition: BasicUI.h:143
@ ProgressShowCancel
Definition: BasicUI.h:142
@ ProgressConfirmStopOrCancel
Definition: BasicUI.h:144
@ ProgressShowStop
Definition: BasicUI.h:141
bool OpenInDefaultBrowser(const wxString &url)
Open an URL in default browser.
Definition: BasicUI.cpp:246
Services * Install(Services *pInstance)
Install an implementation; return the previously installed instance.
Definition: BasicUI.cpp:204
void SplitProgress(ItType first, ItType last, FnType action, ProgressReporter parent)
Helper for the update of a task's progress bar when this task is made of a range's subtasks.
Definition: BasicUI.h:339
void CallAfter(Action action)
Schedule an action to be done later, and in the main thread.
Definition: BasicUI.cpp:214
void ShowErrorDialog(const WindowPlacement &placement, const TranslatableString &dlogTitle, const TranslatableString &message, const ManualPageID &helpPage, const ErrorDialogOptions &options={})
Show an error dialog with a link to the manual for further help.
Definition: BasicUI.h:272
bool IsUiThread()
Whether the current thread is the UI thread.
Definition: BasicUI.h:407
ErrorDialogType
Definition: BasicUI.h:43
Button
Definition: BasicUI.h:88
@ Default
Like Ok, except maybe minor difference of dialog position.
@ Ok
One button.
@ YesNo
Two buttons.
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
Definition: BasicUI.cpp:202
int ShowMultiDialog(const TranslatableString &message, const TranslatableString &title, const TranslatableStrings &buttons, const ManualPageID &helpPage, const TranslatableString &boxMsg, bool log)
Display a dialog with radio buttons.
Definition: BasicUI.h:367
std::function< void()> Action
Definition: BasicUI.h:24
bool IsUsingRtlLayout()
Whether using a right-to-left language layout.
Definition: BasicUI.h:399
MessageBoxResult
Definition: BasicUI.h:132
@ None
May be returned if no Services are installed.
GenericProgressDialogStyle
Definition: BasicUI.h:147
@ ProgressCanAbort
Definition: BasicUI.h:148
@ ProgressShowElapsedTime
Definition: BasicUI.h:150
@ ProgressSmooth
Definition: BasicUI.h:151
@ ProgressAppModal
Definition: BasicUI.h:149
void Yield()
Dispatch waiting events, including actions enqueued by CallAfter.
Definition: BasicUI.cpp:225
MessageBoxResult ShowMessageBox(const TranslatableString &message, MessageBoxOptions options={})
Show a modal message box with either Ok or Yes and No, and optionally Cancel.
Definition: BasicUI.h:287
std::unique_ptr< ProgressDialog > MakeProgress(const TranslatableString &title, const TranslatableString &message, unsigned flags=(ProgressShowStop|ProgressShowCancel), const TranslatableString &remainingLabelText={})
Create and display a progress dialog.
Definition: BasicUI.h:302
std::unique_ptr< WindowPlacement > FindFocus()
Find the window that is accepting keyboard input, if any.
Definition: BasicUI.h:383
Options for variations of error dialogs; the default is for modal dialogs.
Definition: BasicUI.h:52
ErrorDialogType type
Type of help dialog.
Definition: BasicUI.h:70
std::wstring log
Optional extra logging information to be shown.
Definition: BasicUI.h:74
ErrorDialogOptions && ModalHelp(bool modalHelp_) &&
Definition: BasicUI.h:61
ErrorDialogOptions && Log(std::wstring log_) &&
Definition: BasicUI.h:64
ErrorDialogOptions(ErrorDialogType type)
Non-explicit.
Definition: BasicUI.h:56
bool modalHelp
Whether the secondary help dialog with more information should be modal.
Definition: BasicUI.h:72
MessageBoxOptions && CancelButton() &&
Definition: BasicUI.h:114
MessageBoxOptions && Parent(WindowPlacement *parent_) &&
Definition: BasicUI.h:98
TranslatableString caption
Definition: BasicUI.h:124
MessageBoxOptions && Caption(TranslatableString caption_) &&
Definition: BasicUI.h:101
MessageBoxOptions && Centered() &&
Center the dialog on its parent window, if any.
Definition: BasicUI.h:118
WindowPlacement * parent
Definition: BasicUI.h:123
MessageBoxOptions && ButtonStyle(Button style) &&
Definition: BasicUI.h:107
MessageBoxOptions && DefaultIsNo() &&
Override the usual defaulting to Yes; affects only the YesNo case.
Definition: BasicUI.h:111
MessageBoxOptions && IconStyle(Icon style) &&
Definition: BasicUI.h:104