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
147enum class ProgressResult : unsigned
148{
149 Cancelled = 0, //<! User says that whatever is happening is undesirable and shouldn't have happened at all
150 Success, //<! User says nothing, everything works fine, continue doing whatever we're doing
151 Failed, //<! Something has gone wrong, we should stop and cancel everything we did
152 Stopped //<! Nothing is wrong, but user says we should stop now and leave things as they are now
153};
154
156class BASIC_UI_API ProgressDialog
157{
158public:
160
163 unsigned long long numerator,
164 unsigned long long denominator,
165 const TranslatableString &message = {}) = 0;
166
168 virtual void SetMessage(const TranslatableString & message) = 0;
169
171 virtual void SetDialogTitle(const TranslatableString & title) = 0;
172
174 virtual void Reinit() = 0;
175};
176
178class BASIC_UI_API GenericProgressDialog
179{
180public:
183 virtual ProgressResult Pulse() = 0;
184};
185
187
189
192class BASIC_UI_API Services {
193public:
194 virtual ~Services();
195 virtual void DoCallAfter(const Action &action) = 0;
196 virtual void DoYield() = 0;
197 virtual void DoShowErrorDialog(const WindowPlacement &placement,
198 const TranslatableString &dlogTitle,
199 const TranslatableString &message,
200 const ManualPageID &helpPage,
201 const ErrorDialogOptions &options) = 0;
203 const TranslatableString& message,
204 MessageBoxOptions options) = 0;
205 virtual std::unique_ptr<ProgressDialog>
207 const TranslatableString &message,
208 unsigned flag,
209 const TranslatableString &remainingLabelText) = 0;
210 virtual std::unique_ptr<GenericProgressDialog>
213 const TranslatableString &message) = 0;
214 virtual int DoMultiDialog(const TranslatableString &message,
216 const TranslatableStrings &buttons,
217 const ManualPageID &helpPage,
218 const TranslatableString &boxMsg, bool log) = 0;
219
220 virtual bool DoOpenInDefaultBrowser(const wxString &url) = 0;
221
222 virtual std::unique_ptr<WindowPlacement> DoFindFocus() = 0;
223 virtual void DoSetFocus(const WindowPlacement &focus) = 0;
224
225 virtual bool IsUsingRtlLayout() const = 0;
226
227 virtual bool IsUiThread() const = 0;
228};
229
231BASIC_UI_API Services *Get();
232
234BASIC_UI_API Services *Install(Services *pInstance);
235
242
244
248BASIC_UI_API void CallAfter(Action action);
249
251
256BASIC_UI_API void Yield();
257
259
261BASIC_UI_API bool OpenInDefaultBrowser(const wxString &url);
262
264inline void ShowErrorDialog(
265 const WindowPlacement &placement,
266 const TranslatableString &dlogTitle,
267 const TranslatableString &message,
268 const ManualPageID &helpPage,
269 const ErrorDialogOptions &options = {})
270{
271 if (auto p = Get())
272 p->DoShowErrorDialog(placement, dlogTitle, message, helpPage, options);
273}
274
276
280 MessageBoxOptions options = {})
281{
282 if (auto p = Get())
283 return p->DoMessageBox(message, std::move(options));
284 else
286}
287
289
294inline std::unique_ptr<ProgressDialog> MakeProgress(
296 const TranslatableString & message,
297 unsigned flags = (ProgressShowStop | ProgressShowCancel),
298 const TranslatableString & remainingLabelText = {})
299{
300 if (auto p = Get())
301 return p->DoMakeProgress(title, message, flags, remainingLabelText);
302 else
303 return nullptr;
304}
305
307
312inline std::unique_ptr<GenericProgressDialog> MakeGenericProgress(
313 const WindowPlacement &placement,
314 const TranslatableString &title, const TranslatableString &message)
315{
316 if (auto p = Get())
317 return p->DoMakeGenericProgress(placement, title, message);
318 else
319 return nullptr;
320}
321
330template <typename ItType, typename FnType>
332 ItType first, ItType last, FnType action, ProgressReporter parent)
333{
334 auto count = 0;
335 const auto numIters = std::distance(first, last);
336 if (numIters == 0)
337 return;
338 const ProgressReporter child =
339 parent ? [&](double progress) { parent((count + progress) / numIters); } :
341
342 for (; first != last; ++first)
343 {
344 action(*first, child);
345 ++count;
346 }
347}
348
350
359inline int ShowMultiDialog(const TranslatableString &message,
361 const TranslatableStrings &buttons,
362 const ManualPageID &helpPage,
363 const TranslatableString &boxMsg, bool log)
364{
365 if (auto p = Get())
366 return p->DoMultiDialog(message, title, buttons, helpPage, boxMsg, log);
367 else
368 return -1;
369}
370
372
375inline std::unique_ptr<WindowPlacement> FindFocus()
376{
377 if (auto p = Get())
378 if (auto result = p->DoFindFocus())
379 return result;
380 return std::make_unique<WindowPlacement>();
381}
382
384inline void SetFocus(const WindowPlacement &focus)
385{
386 if (auto p = Get())
387 p->DoSetFocus(focus);
388}
389
391inline bool IsUsingRtlLayout()
392{
393 if (auto p = Get())
394 return p->IsUsingRtlLayout();
395 return false;
396}
397
399inline bool IsUiThread ()
400{
401 if (auto p = Get())
402 return p->IsUiThread();
403 return true;
404}
405
406#define ASSERT_MAIN_THREAD() \
407 assert( \
408 BasicUI::IsUiThread() && \
409 "This function should only be called on the main thread")
410
412}
413
414#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:179
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:157
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:192
virtual std::unique_ptr< GenericProgressDialog > DoMakeGenericProgress(const WindowPlacement &placement, const TranslatableString &title, const TranslatableString &message)=0
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 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::unique_ptr< GenericProgressDialog > MakeGenericProgress(const WindowPlacement &placement, const TranslatableString &title, const TranslatableString &message)
Create and display a progress dialog (return nullptr if Services not installed)
Definition: BasicUI.h:312
std::function< void(double)> ProgressReporter
Definition: BasicUI.h:25
TranslatableString DefaultCaption()
"Message", suitably translated
Definition: BasicUI.cpp:258
void SetFocus(const WindowPlacement &focus)
Set the window that accepts keyboard input.
Definition: BasicUI.h:384
ProgressResult
Definition: BasicUI.h:148
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:245
Services * Install(Services *pInstance)
Install an implementation; return the previously installed instance.
Definition: BasicUI.cpp:203
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:331
void CallAfter(Action action)
Schedule an action to be done later, and in the main thread.
Definition: BasicUI.cpp:213
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:264
bool IsUiThread()
Whether the current thread is the UI thread.
Definition: BasicUI.h:399
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:201
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:359
std::function< void()> Action
Definition: BasicUI.h:24
bool IsUsingRtlLayout()
Whether using a right-to-left language layout.
Definition: BasicUI.h:391
MessageBoxResult
Definition: BasicUI.h:132
@ None
May be returned if no Services are installed.
void Yield()
Dispatch waiting events, including actions enqueued by CallAfter.
Definition: BasicUI.cpp:224
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:279
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:294
std::unique_ptr< WindowPlacement > FindFocus()
Find the window that is accepting keyboard input, if any.
Definition: BasicUI.h:375
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