void EditCursorOverlay::Draw(OverlayPanel &panel, wxDC &dc) { if (mIsMaster && !mPartner) { auto ruler = mProject->GetRulerPanel(); if (ruler) { mPartner = std::make_unique<EditCursorOverlay>(mProject, false); ruler->AddOverlay(mPartner.get()); } } mLastCursorX = mNewCursorX; if (mLastCursorX == -1) return; const ZoomInfo &viewInfo = mProject->GetZoomInfo(); const bool onScreen = between_incexc(viewInfo.h, mCursorTime, mProject->GetScreenEndTime()); if (!onScreen) return; if (auto tp = dynamic_cast<TrackPanel*>(&panel)) { wxASSERT(mIsMaster); AColor::CursorColor(&dc); // Draw cursor in all selected tracks for ( const auto &data : tp->Cells() ) { Track *const pTrack = dynamic_cast<Track*>(data.first.get()); if (!pTrack) continue; if (pTrack->GetSelected() || mProject->GetTrackPanel()->GetAx().IsFocused(pTrack)) { const wxRect &rect = data.second; // AColor::Line includes both endpoints so use GetBottom() AColor::Line(dc, mLastCursorX, rect.GetTop(), mLastCursorX, rect.GetBottom()); // ^^^ The whole point of this routine. } } } else if (auto ruler = dynamic_cast<AdornedRulerPanel*>(&panel)) { wxASSERT(!mIsMaster); dc.SetPen(*wxBLACK_PEN); // AColor::Line includes both endpoints so use GetBottom() auto rect = ruler->GetInnerRect(); AColor::Line(dc, mLastCursorX, rect.GetTop(), mLastCursorX, rect.GetBottom()); } else wxASSERT(false); }
void PlayIndicatorOverlayBase::Draw(OverlayPanel &panel, wxDC &dc) { // Set play/record color bool rec = gAudioIO->IsCapturing(); AColor::IndicatorColor(&dc, !rec); if (mIsMaster && mLastIsCapturing != mNewIsCapturing) { // Detect transition to recording during punch and roll; make ruler // change its button color too const auto ruler = mProject->GetRulerPanel(); ruler->UpdateButtonStates(); ruler->Refresh(); } mLastIsCapturing = mNewIsCapturing; mLastIndicatorX = mNewIndicatorX; if (!between_incexc(0, mLastIndicatorX, dc.GetSize().GetWidth())) return; if(auto tp = dynamic_cast<TrackPanel*>(&panel)) { wxASSERT(mIsMaster); // Draw indicator in all visible tracks for ( const auto &data : tp->Cells() ) { Track *const pTrack = dynamic_cast<Track*>(data.first.get()); if (!pTrack) continue; // Don't draw the indicator in label tracks if (pTrack->GetKind() == Track::Label) { continue; } // Draw the NEW indicator in its NEW location // AColor::Line includes both endpoints so use GetBottom() const wxRect &rect = data.second; AColor::Line(dc, mLastIndicatorX, rect.GetTop(), mLastIndicatorX, rect.GetBottom()); } } else if(auto ruler = dynamic_cast<AdornedRulerPanel*>(&panel)) { wxASSERT(!mIsMaster); ruler->DoDrawIndicator(&dc, mLastIndicatorX, !rec, IndicatorMediumWidth, false, false); } else wxASSERT(false); }
void EditCursorOverlay::Draw (wxDC &dc, TrackPanelCellIterator begin, TrackPanelCellIterator end) { mLastCursorX = mNewCursorX; if (mLastCursorX == -1) return; const ZoomInfo &viewInfo = mProject->GetZoomInfo(); const bool onScreen = between_incexc(viewInfo.h, mCursorTime, mProject->GetScreenEndTime()); if (!onScreen) return; AColor::CursorColor(&dc); // Draw cursor in all selected tracks for (; begin != end; ++begin) { TrackPanelCellIterator::value_type data(*begin); Track *const pTrack = data.first; if (!pTrack) continue; if (pTrack->GetSelected() || mProject->GetTrackPanel()->GetAx().IsFocused(pTrack)) { const wxRect &rect = data.second; // AColor::Line includes both endpoints so use GetBottom() AColor::Line(dc, mLastCursorX, rect.GetTop(), mLastCursorX, rect.GetBottom()); // <-- The whole point of this routine. #ifdef EXPERIMENTAL_OUTPUT_DISPLAY if (MONO_WAVE_PAN(t)){ y = t->GetY(true) - mViewInfo->vpos + 1; top = y + kTopInset; bottom = y + t->GetHeight(true) - kTopInset; AColor::Line(dc, mLastCursorX, top, mLastCursorX, bottom); } #endif } } // AS: Ah, no, this is where we draw the blinky thing in the ruler. mProject->GetRulerPanel()->DrawCursor(mCursorTime); // This updates related displays such as numbers on the status bar mProject->TP_DisplaySelection(); }
void PlayIndicatorOverlayBase::Draw(OverlayPanel &panel, wxDC &dc) { // Set play/record color bool rec = (gAudioIO->GetNumCaptureChannels() > 0); AColor::IndicatorColor(&dc, !rec); mLastIndicatorX = mNewIndicatorX; if (!between_incexc(0, mLastIndicatorX, dc.GetSize().GetWidth())) return; if(auto tp = dynamic_cast<TrackPanel*>(&panel)) { wxASSERT(mIsMaster); TrackPanelCellIterator begin(tp, true); TrackPanelCellIterator end(tp, false); // Draw indicator in all visible tracks for (; begin != end; ++begin) { TrackPanelCellIterator::value_type data(*begin); Track *const pTrack = data.first; if (!pTrack) continue; // Don't draw the indicator in label tracks if (pTrack->GetKind() == Track::Label) { continue; } // Draw the NEW indicator in its NEW location // AColor::Line includes both endpoints so use GetBottom() const wxRect &rect = data.second; AColor::Line(dc, mLastIndicatorX, rect.GetTop(), mLastIndicatorX, rect.GetBottom()); } } else if(auto ruler = dynamic_cast<AdornedRulerPanel*>(&panel)) { wxASSERT(!mIsMaster); ruler->DoDrawIndicator(&dc, mLastIndicatorX, !rec, IndicatorMediumWidth, false); } else wxASSERT(false); }
void PlayIndicatorOverlay::OnTimer(wxCommandEvent &event) { // Let other listeners get the notification event.Skip(); // Ensure that there is an overlay attached to the ruler if (!mPartner) { auto ruler = mProject->GetRulerPanel(); if (ruler) { mPartner = std::make_unique<PlayIndicatorOverlayBase>(mProject, false); ruler->AddOverlay(mPartner.get()); } } auto trackPanel = mProject->GetTrackPanel(); if (!mProject->IsAudioActive()) { mNewIndicatorX = -1; const auto &scrubber = mProject->GetScrubber(); if (scrubber.HasStartedScrubbing()) { auto position = scrubber.GetScrubStartPosition(); int width; trackPanel->GetTracksUsableArea(&width, nullptr); const auto offset = trackPanel->GetLeftOffset(); if(position >= trackPanel->GetLeftOffset() && position < offset + width) mNewIndicatorX = position; } } else { ViewInfo &viewInfo = mProject->GetViewInfo(); // Calculate the horizontal position of the indicator const double playPos = viewInfo.mRecentStreamTime; bool onScreen = playPos >= 0.0 && between_incexc(viewInfo.h, playPos, mProject->GetScreenEndTime()); // This displays the audio time, too... mProject->TP_DisplaySelection(); // BG: Scroll screen if option is set // msmeyer: But only if not playing looped or in one-second mode // PRL: and not scrolling with play/record head fixed right if (viewInfo.bUpdateTrackIndicator && mProject->mLastPlayMode != PlayMode::loopedPlay && mProject->mLastPlayMode != PlayMode::oneSecondPlay && mProject->GetPlaybackScroller().GetMode() != AudacityProject::PlaybackScroller::Mode::Right && playPos >= 0 && !onScreen && !gAudioIO->IsPaused()) { mProject->TP_ScrollWindow(playPos); // Might yet be off screen, check it onScreen = playPos >= 0.0 && between_incexc(viewInfo.h, playPos, mProject->GetScreenEndTime()); } // Always update scrollbars even if not scrolling the window. This is // important when NEW audio is recorded, because this can change the // length of the project and therefore the appearance of the scrollbar. mProject->TP_RedrawScrollbars(); if (onScreen) mNewIndicatorX = viewInfo.TimeToPosition(playPos, trackPanel->GetLeftOffset()); else mNewIndicatorX = -1; } if(mPartner) mPartner->Update(mNewIndicatorX); }
void EditCursorOverlay::Draw(OverlayPanel &panel, wxDC &dc) { if (mIsMaster && !mPartner) { auto ruler = mProject->GetRulerPanel(); if (ruler) { mPartner = std::make_unique<EditCursorOverlay>(mProject, false); ruler->AddOverlay(mPartner.get()); } } mLastCursorX = mNewCursorX; if (mLastCursorX == -1) return; const ZoomInfo &viewInfo = mProject->GetZoomInfo(); const bool onScreen = between_incexc(viewInfo.h, mCursorTime, mProject->GetScreenEndTime()); if (!onScreen) return; if (auto tp = dynamic_cast<TrackPanel*>(&panel)) { wxASSERT(mIsMaster); AColor::CursorColor(&dc); TrackPanelCellIterator begin(tp, true); TrackPanelCellIterator end(tp, false); // Draw cursor in all selected tracks for (; begin != end; ++begin) { TrackPanelCellIterator::value_type data(*begin); Track *const pTrack = data.first; if (!pTrack) continue; if (pTrack->GetSelected() || mProject->GetTrackPanel()->GetAx().IsFocused(pTrack)) { const wxRect &rect = data.second; // AColor::Line includes both endpoints so use GetBottom() AColor::Line(dc, mLastCursorX, rect.GetTop(), mLastCursorX, rect.GetBottom()); // ^^^ The whole point of this routine. #ifdef EXPERIMENTAL_OUTPUT_DISPLAY if (MONO_WAVE_PAN(pTrack)){ auto y = pTrack->GetY(true) - viewInfo.vpos + 1; auto top = y + kTopInset; auto bottom = y + pTrack->GetHeight(true) - kTopInset; AColor::Line(dc, mLastCursorX, top, mLastCursorX, bottom); } #endif } } } else if (auto ruler = dynamic_cast<AdornedRulerPanel*>(&panel)) { wxASSERT(!mIsMaster); dc.SetPen(*wxBLACK_PEN); // AColor::Line includes both endpoints so use GetBottom() auto rect = ruler->GetInnerRect(); AColor::Line(dc, mLastCursorX, rect.GetTop(), mLastCursorX, rect.GetBottom()); } else wxASSERT(false); }