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