File: ProjectStatus.h

package info (click to toggle)
audacity 3.7.3%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 125,252 kB
  • sloc: cpp: 358,238; ansic: 75,458; lisp: 7,761; sh: 3,410; python: 1,503; xml: 1,385; perl: 854; makefile: 122
file content (155 lines) | stat: -rw-r--r-- 5,813 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/**********************************************************************

Audacity: A Digital Audio Editor

ProjectStatus.h

Paul Licameli

**********************************************************************/

#ifndef __AUDACITY_PROJECT_STATUS__
#define __AUDACITY_PROJECT_STATUS__
#endif

#include <utility>
#include <unordered_map>
#include <vector>
#include "ClientData.h" // to inherit
#include "Prefs.h"
#include "Observer.h"
#include "Registry.h"

class AudacityProject;
class wxWindow;

using StatusBarField = Identifier;

//! ID of the first field in the status bar. This filed is used to display playback state.
PROJECT_API StatusBarField StateStatusBarField();
//! ID of the second field in the status bar. This field is expandable.
PROJECT_API StatusBarField MainStatusBarField();
//! ID of the third field in the status bar. This field is used to display the current rate.
PROJECT_API StatusBarField RateStatusBarField();

//! Abstract base class for status bar fields
class PROJECT_API StatusBarFieldItem /* not final */
    : public Registry::SingleItem
{
public:
   explicit StatusBarFieldItem(StatusBarField identifier);
   virtual ~StatusBarFieldItem();

   /*! Return the default width of the field in pixels.
    * This is used to determine the initial width of the field in the status bar.
    * The value may be overridden using StatusWidthFunctions.
    * Returning -1 means that the field is expandable.In this case StatusWidthFunctions
    * have no effect.
    */
   virtual int GetDefaultWidth(const AudacityProject& project) const = 0;

   /*! Called when the status bar associated with the project is resized.
    * Could be used to update the position of the custom status bar field.
    * Default implementation does nothing.
    *
    * @param project The project whose status bar has been resized. The reference is non constant, as
    *                the field is likely implemented as a client site. 
    */
   virtual void OnSize(AudacityProject& project);

   //! Sets the current text of the field.
   virtual void SetText(AudacityProject& project, const TranslatableString& msg) = 0;
   //! Retrieves the current text of the field.
   virtual TranslatableString GetText(const AudacityProject& project) const = 0;

   //! Returns true if the field is visible in the status bar of the given project.
   virtual bool IsVisible(const AudacityProject& project) const = 0;

protected:
   //! Derived classes should call this method to notify the status bar that the field has changed.
   void DispatchFieldChanged(const AudacityProject& project);
};

struct PROJECT_API StatusBarFieldRegistryTraits final
   : Registry::DefaultTraits
{
   using LeafTypes = List<StatusBarFieldItem>;
};

using StatusBarFieldRegistryVisitor = Registry::VisitorFunctions<StatusBarFieldRegistryTraits>;

//! Registry of status bar fields
struct PROJECT_API ProjectStatusFieldsRegistry final
{
   //! Returns the registry
   static Registry::GroupItem<StatusBarFieldRegistryTraits>& Registry();
   //! Visits all fields in the registry in order
   static void Visit(const StatusBarFieldRegistryVisitor& visitor);
   //! Returns the number of fields in the registry. If project is no null, only visible fields are counted.
   static std::size_t Count(const AudacityProject* project);
   //! Returns the field with the given identifier or nullptr if field is not present
   static StatusBarFieldItem* Get(const StatusBarField& identifier);
   //! Returns the zero based index of the field or -1 if field is not present 
   static int GetFieldIndex(
      const AudacityProject& project, const StatusBarField& identifier);
   //! Handle OnSize event for all fields in the registry
   static void OnSize(AudacityProject& project);

   static Observer::Subscription
   Subscribe(std::function<void(const AudacityProject&, const StatusBarField&)>
                handler);
};

using StatusBarFieldItemRegistrator =
   Registry::RegisteredItem<ProjectStatusFieldsRegistry>;

class PROJECT_API ProjectStatus final
   : public ClientData::Base
   , public PrefsListener
   , public Observer::Publisher<StatusBarField>
{
public:
   static ProjectStatus &Get( AudacityProject &project );
   static const ProjectStatus &Get( const AudacityProject &project );

   explicit ProjectStatus( AudacityProject &project );
   ProjectStatus( const ProjectStatus & ) = delete;
   ProjectStatus &operator= ( const ProjectStatus & ) = delete;
   ~ProjectStatus() override;

   // Type of a function to report translatable strings, and also report an extra
   // margin, to request that the corresponding field of the status bar should
   // be wide enough to contain any of those strings plus the margin.
   using StatusWidthResult = std::pair< std::vector<TranslatableString>, unsigned >;
   using StatusWidthFunction = std::function<
      StatusWidthResult( const AudacityProject &, StatusBarField )
   >;
   using StatusWidthFunctions = std::vector< StatusWidthFunction >;

   // Typically a static instance of this struct is used.
   struct PROJECT_API RegisteredStatusWidthFunction
   {
      explicit
      RegisteredStatusWidthFunction( const StatusWidthFunction &function );
   };

   static const StatusWidthFunctions &GetStatusWidthFunctions();

   TranslatableString Get( StatusBarField field = MainStatusBarField() ) const;
   void Set(const TranslatableString &msg,
      StatusBarField field = MainStatusBarField());

   // PrefsListener implementation
   void UpdatePrefs() override;

private:
   class ProjectStatusTextField;
   static struct DefaultFieldsRegistrator final
   {
      DefaultFieldsRegistrator();
   } sDefaultFieldsRegistrator;

   AudacityProject &mProject;
   std::unordered_map<StatusBarField, TranslatableString> mCurrentStatus;
   Observer::Subscription mFieldChangedSubscription;
};