Audacity  2.2.2
PlayIndicatorOverlay.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3 Audacity: A Digital Audio Editor
4 
5 PlayIndicatorOverlay.cpp
6 
7 Paul Licameli split from TrackPanel.cpp
8 
9 **********************************************************************/
10 
11 #include "../../Audacity.h"
12 #include "PlayIndicatorOverlay.h"
13 
14 #include "../../AColor.h"
15 #include "../../AudioIO.h"
16 #include "../../Project.h"
17 #include "../../TrackPanel.h"
18 #include "../../TrackPanelCell.h"
19 #include "../../TrackPanelCellIterator.h"
20 #include "../../widgets/Ruler.h"
21 #include "Scrubbing.h"
22 
23 #include <wx/dc.h>
24 
25 #include <algorithm>
26 
27 namespace {
28  template < class LOW, class MID, class HIGH >
29  bool between_incexc(LOW l, MID m, HIGH h)
30  {
31  return (m >= l && m < h);
32  }
33 
34  enum { IndicatorMediumWidth = 13 };
35 }
36 
38 : mProject(project)
39 , mIsMaster(isMaster)
40 {
41 }
42 
44 {
45 }
46 
47 std::pair<wxRect, bool> PlayIndicatorOverlayBase::DoGetRectangle(wxSize size)
48 {
49  auto width = mIsMaster ? 1 : IndicatorMediumWidth;
50 
51  // May be excessive height, but little matter
52  wxRect rect(mLastIndicatorX - width / 2, 0, width, size.GetHeight());
53  return std::make_pair(
54  rect,
56  );
57 }
58 
59 
61 {
62  // Set play/record color
63  bool rec = gAudioIO->IsCapturing();
64  AColor::IndicatorColor(&dc, !rec);
66  if (!between_incexc(0, mLastIndicatorX, dc.GetSize().GetWidth()))
67  return;
68 
69  if(auto tp = dynamic_cast<TrackPanel*>(&panel)) {
70  wxASSERT(mIsMaster);
71 
72  // Draw indicator in all visible tracks
73  for ( const auto &data : tp->Cells() )
74  {
75  Track *const pTrack = dynamic_cast<Track*>(data.first.get());
76  if (!pTrack)
77  continue;
78 
79  // Don't draw the indicator in label tracks
80  if (pTrack->GetKind() == Track::Label)
81  {
82  continue;
83  }
84 
85  // Draw the NEW indicator in its NEW location
86  // AColor::Line includes both endpoints so use GetBottom()
87  const wxRect &rect = data.second;
88  AColor::Line(dc,
90  rect.GetTop(),
92  rect.GetBottom());
93  }
94  }
95  else if(auto ruler = dynamic_cast<AdornedRulerPanel*>(&panel)) {
96  wxASSERT(!mIsMaster);
97 
98  ruler->DoDrawIndicator(&dc, mLastIndicatorX, !rec, IndicatorMediumWidth, false, false);
99  }
100  else
101  wxASSERT(false);
102 }
103 
105 : PlayIndicatorOverlayBase(project, true)
106 {
107  mProject->Bind(EVT_TRACK_PANEL_TIMER,
109  this);
110 }
111 
113 {
114  if (mPartner) {
115  auto ruler = mProject->GetRulerPanel();
116  if(ruler)
117  ruler->RemoveOverlay(mPartner.get());
118  }
119 }
120 
121 void PlayIndicatorOverlay::OnTimer(wxCommandEvent &event)
122 {
123  // Let other listeners get the notification
124  event.Skip();
125 
126  // Ensure that there is an overlay attached to the ruler
127  if (!mPartner) {
128  auto ruler = mProject->GetRulerPanel();
129  if (ruler) {
130  mPartner = std::make_unique<PlayIndicatorOverlayBase>(mProject, false);
131  ruler->AddOverlay(mPartner.get());
132  }
133  }
134 
135  auto trackPanel = mProject->GetTrackPanel();
136 
137  if (!mProject->IsAudioActive()) {
138  mNewIndicatorX = -1;
139  const auto &scrubber = mProject->GetScrubber();
140  if (scrubber.HasStartedScrubbing()) {
141  auto position = scrubber.GetScrubStartPosition();
142  int width;
143  trackPanel->GetTracksUsableArea(&width, nullptr);
144  const auto offset = trackPanel->GetLeftOffset();
145  if(position >= trackPanel->GetLeftOffset() &&
146  position < offset + width)
147  mNewIndicatorX = position;
148  }
149  }
150  else {
151  ViewInfo &viewInfo = mProject->GetViewInfo();
152 
153  // Calculate the horizontal position of the indicator
154  const double playPos = viewInfo.mRecentStreamTime;
155 
156  bool onScreen = playPos >= 0.0 &&
157  between_incexc(viewInfo.h,
158  playPos,
160 
161  // This displays the audio time, too...
163 
164  // BG: Scroll screen if option is set
165  // msmeyer: But only if not playing looped or in one-second mode
166  // PRL: and not scrolling with play/record head fixed right
167  if (viewInfo.bUpdateTrackIndicator &&
172  playPos >= 0 &&
173  !onScreen &&
174  !gAudioIO->IsPaused())
175  {
176  mProject->TP_ScrollWindow(playPos);
177  // Might yet be off screen, check it
178  onScreen = playPos >= 0.0 &&
179  between_incexc(viewInfo.h,
180  playPos,
182  }
183 
184  // Always update scrollbars even if not scrolling the window. This is
185  // important when NEW audio is recorded, because this can change the
186  // length of the project and therefore the appearance of the scrollbar.
188 
189  if (onScreen)
190  mNewIndicatorX = viewInfo.TimeToPosition(playPos, trackPanel->GetLeftOffset());
191  else
192  mNewIndicatorX = -1;
193  }
194 
195  if(mPartner)
196  mPartner->Update(mNewIndicatorX);
197 }
bool bUpdateTrackIndicator
Definition: ViewInfo.h:182
ViewInfo is used mainly to hold the zooming, selection and scroll information. It also has some statu...
Definition: ViewInfo.h:141
Scrubber & GetScrubber()
Definition: Project.h:801
std::unique_ptr< PlayIndicatorOverlayBase > mPartner
bool IsCapturing() const
Definition: AudioIO.cpp:5481
PlayIndicatorOverlayBase(AudacityProject *project, bool isMaster)
bool RemoveOverlay(Overlay *pOverlay)
double h
Definition: ViewInfo.h:47
void TP_RedrawScrollbars() override
Definition: Project.cpp:5438
virtual int GetKind() const
Definition: Track.h:330
AudacityProject *const mProject
static void IndicatorColor(wxDC *dc, bool bIsNotRecording)
Definition: AColor.cpp:367
AudacityProject provides the main window, with tools and tracks contained within it.
Definition: Project.h:176
void TP_ScrollWindow(double scrollto) override
Definition: Project.cpp:1856
AdornedRulerPanel * GetRulerPanel()
Definition: Project.cpp:1439
bool IsPaused()
Find out if playback / recording is currently paused.
Definition: AudioIO.cpp:2857
Fundamental data object of Audacity, placed in the TrackPanel. Classes derived form it include the Wa...
Definition: Track.h:102
wxInt64 TimeToPosition(double time, wxInt64 origin=0, bool ignoreFisheye=false) const
STM: Converts a project time to screen x position.
Definition: ViewInfo.cpp:59
bool IsAudioActive() const
Definition: Project.cpp:1454
PlayIndicatorOverlay(AudacityProject *project)
static void Line(wxDC &dc, wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
Definition: AColor.cpp:122
PlayMode mLastPlayMode
Definition: Project.h:557
std::pair< wxRect, bool > DoGetRectangle(wxSize size) override
AudioIO * gAudioIO
Definition: AudioIO.cpp:482
PlaybackScroller & GetPlaybackScroller()
Definition: Project.h:832
double GetScreenEndTime() const
Definition: Menus.cpp:6741
double mRecentStreamTime
Definition: ViewInfo.h:189
void OnTimer(wxCommandEvent &event)
TrackPanel * GetTrackPanel()
Definition: Project.h:307
void TP_DisplaySelection() override
Definition: Project.cpp:5367
wxCoord GetScrubStartPosition() const
Definition: Scrubbing.h:90
const ViewInfo & GetViewInfo() const
Definition: Project.h:207
void Draw(OverlayPanel &panel, wxDC &dc) override