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 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); }