Audacity 3.2.0
Scrubbing.h
Go to the documentation of this file.
1/**********************************************************************
2
3Audacity: A Digital Audio Editor
4
5Scrubbing.h
6
7Paul Licameli split from TrackPanel.cpp
8
9**********************************************************************/
10
11#ifndef __AUDACITY_SCRUBBING__
12#define __AUDACITY_SCRUBBING__
13
14#include <thread>
15#include <vector>
16#include <wx/longlong.h>
17
18#include "../../ScrubState.h" // for ScrubbingOptions
19#include "ClientData.h" // to inherit
20#include "Prefs.h" // to inherit
21#include "../../widgets/Overlay.h" // to inherit
22#include "CommandContext.h"
23#include "Identifier.h"
24
25class AudacityProject;
27
28// Conditionally compile either a separate thead, or else use a timer in the main
29// thread, to poll the mouse and update scrubbing speed and direction. The advantage of
30// a thread may be immunity to choppy scrubbing in case redrawing takes too much time.
31#ifdef __WXGTK__
32// Unfortunately some things the thread needs to do are not thread safe
33#else
34#define USE_SCRUB_THREAD
35#endif
36
37// Scrub state object
38class AUDACITY_DLL_API Scrubber final
39 : public wxEvtHandler
40 , public ClientData::Base
41 , private PrefsListener
42 , public std::enable_shared_from_this< Scrubber >
43{
44public:
46 static const Scrubber &Get( const AudacityProject &project );
47
48 explicit
50 Scrubber( const Scrubber & ) = delete;
51 Scrubber &operator=( const Scrubber & ) = delete;
52 ~Scrubber();
53
54 static bool ShouldScrubPinned();
55
56 // Assume xx is relative to the left edge of TrackPanel!
57 void MarkScrubStart(wxCoord xx, bool smoothScrolling, bool seek);
58
59 // Returns true iff the event should be considered consumed by this:
60 // Assume xx is relative to the left edge of TrackPanel!
61 bool MaybeStartScrubbing(wxCoord xx);
62 bool StartKeyboardScrubbing(double time0, bool backwards);
63 double GetKeyboardScrubbingSpeed();
64
65 void ContinueScrubbingUI();
66 void ContinueScrubbingPoll();
67
68 // This is meant to be called only from ProjectAudioManager
69 void StopScrubbing();
70
71 wxCoord GetScrubStartPosition() const
72 { return mScrubStartPosition; }
73
74 bool WasSpeedPlaying() const
75 { return mSpeedPlaying;}
76 bool IsSpeedPlaying() const
77 { return IsScrubbing() && mSpeedPlaying; }
79 { return mKeyboardScrubbing; }
81 { return IsScrubbing() && mKeyboardScrubbing; }
82 void SetBackwards(bool backwards)
83 { mBackwards = backwards;}
84 bool IsBackwards() const
85 { return mBackwards;}
86 // True iff the user has clicked to start scrub and not yet stopped,
87 // but IsScrubbing() may yet be false
88 bool HasMark() const
89 { return GetScrubStartPosition() >= 0; }
90 bool IsScrubbing() const;
91
92 bool IsScrollScrubbing() const // If true, implies HasMark()
93 { return mSmoothScrollingScrub; }
94 void SetScrollScrubbing(bool value)
95 { mSmoothScrollingScrub = value; }
96
97 bool ChoseSeeking() const;
98 void SetMayDragToSeek( bool value ) { mMayDragToSeek = value; }
99 bool MayDragToSeek() const { return mMayDragToSeek; }
100 bool TemporarilySeeks() const;
101 bool Seeks() const;
102 bool Scrubs() const;
103 bool ShowsBar() const;
104
105 void Cancel()
106 { mCancelled = true; }
107
108 bool ShouldDrawScrubSpeed();
109 double FindScrubSpeed(bool seeking, double time) const;
110 double GetMaxScrubSpeed() const { return mOptions.maxSpeed; }
111
112 void HandleScrollWheel(int steps);
113
114 // This returns the same as the enabled state of the menu items:
115 bool CanScrub() const;
116
117 // For popup
118 void PopulatePopupMenu(wxMenu &menu);
119
120 void OnScrubOrSeek(bool seek);
121 void OnScrub(const CommandContext&);
122 void OnSeek(const CommandContext&);
123 void OnToggleScrubRuler(const CommandContext&);
124
125 void OnKeyboardScrubBackwards(const CommandContext&);
126 void OnKeyboardScrubForwards(const CommandContext&);
127 void DoKeyboardScrub(bool backwards, bool keyUp);
128
129 // Convenience wrapper for the above
130 template<void (Scrubber::*pfn)(const CommandContext&)>
131 void Thunk(wxCommandEvent &)
132 { (this->*pfn)(*mProject); }
133
134 // A string to put in the leftmost part of the status bar
135 // when scrub or seek is in progress, or else empty.
136 const TranslatableString &GetUntranslatedStateString() const;
137 wxString StatusMessageForWave() const;
138
139 void Pause(bool paused);
140 bool IsPaused() const;
141 void CheckMenuItems();
142
143 bool IsTransportingPinned() const;
144
145 void SetSeekPress( bool value ) { mScrubSeekPress = value; }
146
147private:
148 void UpdatePrefs() override;
149
151 void StartPolling();
152 void StopPolling();
153 void DoScrub(bool seek);
154 void OnActivateOrDeactivateApp(wxActivateEvent & event);
155
157 void JoinThread();
158
159private:
163 wxCoord mLastScrubPosition {};
164 bool mScrubSeekPress {};
166
167 bool mPaused{};
168 bool mSeeking {};
169 bool mSpeedPlaying{true};
170 bool mKeyboardScrubbing{};
171 bool mBackwards{};
172 bool mDragging {};
173
174 bool mCancelled {};
175
177
179
180 DECLARE_EVENT_TABLE()
181
182#ifdef USE_SCRUB_THREAD
183 // Course corrections in playback are done in a helper thread, unhindered by
184 // the complications of the main event dispatch loop
185 std::thread mThread;
186 std::atomic<bool> mFinishThread{ false };
187#endif
188
189 // Other periodic update of the UI must be done in the main thread,
190 // by this object which is driven by timer events.
191 class ScrubPoller;
192 std::unique_ptr<ScrubPoller> mPoller;
193
195 double mMaxSpeed { 1.0 };
196
197 bool mShowScrubbing { false };
198 bool mMayDragToSeek{ false };
199};
200
201#endif
Utility ClientData::Site to register hooks into a host class that attach client data.
const auto project
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
A listener notified of changes in preferences.
Definition: Prefs.h:652
virtual void UpdatePrefs()=0
Definition: Prefs.cpp:154
bool IsKeyboardScrubbing() const
Definition: Scrubbing.h:80
int mScrubToken
Definition: Scrubbing.h:160
Scrubber & operator=(const Scrubber &)=delete
Scrubber(const Scrubber &)=delete
double GetMaxScrubSpeed() const
Definition: Scrubbing.h:110
bool IsScrollScrubbing() const
Definition: Scrubbing.h:92
wxCoord mScrubStartPosition
Definition: Scrubbing.h:162
bool mSmoothScrollingScrub
Definition: Scrubbing.h:165
std::unique_ptr< ScrubPoller > mPoller
Definition: Scrubbing.h:191
bool WasKeyboardScrubbing() const
Definition: Scrubbing.h:78
int mScrubSpeedDisplayCountdown
Definition: Scrubbing.h:161
AudacityProject * mProject
Definition: Scrubbing.h:178
void SetBackwards(bool backwards)
Definition: Scrubbing.h:82
ScrubbingOptions mOptions
Definition: Scrubbing.h:194
void SetSeekPress(bool value)
Definition: Scrubbing.h:145
void ScrubPollerThread()
void Cancel()
Definition: Scrubbing.h:105
int mLogMaxScrubSpeed
Definition: Scrubbing.h:176
bool MayDragToSeek() const
Definition: Scrubbing.h:99
bool WasSpeedPlaying() const
Definition: Scrubbing.h:74
bool IsSpeedPlaying() const
Definition: Scrubbing.h:76
void SetScrollScrubbing(bool value)
Definition: Scrubbing.h:94
bool HasMark() const
Definition: Scrubbing.h:88
wxCoord GetScrubStartPosition() const
Definition: Scrubbing.h:71
bool IsBackwards() const
Definition: Scrubbing.h:84
void SetMayDragToSeek(bool value)
Definition: Scrubbing.h:98
void Thunk(wxCommandEvent &)
Definition: Scrubbing.h:131
Holds a msgid for the translation catalog; may also bind format arguments.
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
Definition: BasicUI.cpp:201
A convenient default parameter for class template Site.
Definition: ClientData.h:29