From 8414ebffa50a9b5258ce7bfb7411f46c116e23d5 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Thu, 4 Jul 2019 09:22:20 -0400 Subject: [PATCH] ScrubbingOverlay declared and defined entirely within ScrubUI.cpp --- src/ProjectManager.cpp | 11 -- src/tracks/ui/ScrubUI.cpp | 209 ++++++++++++++++++++++++++++++++++++ src/tracks/ui/ScrubUI.h | 16 +++ src/tracks/ui/Scrubbing.cpp | 154 -------------------------- src/tracks/ui/Scrubbing.h | 27 +---- 5 files changed, 226 insertions(+), 191 deletions(-) diff --git a/src/ProjectManager.cpp b/src/ProjectManager.cpp index 392acb6dc..89d312058 100644 --- a/src/ProjectManager.cpp +++ b/src/ProjectManager.cpp @@ -1079,14 +1079,3 @@ int ProjectManager::GetEstimatedRecordingMinsLeftOnDisk(long lCaptureChannels) { int iRecMins = (int)round(dRecTime / 60.0); return iRecMins; } - -/// This was moved here to eliminate dependency of Scrubbing.cpp on -/// TrackPanel, but perhaps a better home should be found for it in future -#include "tracks/ui/Scrubbing.h" -static const AudacityProject::AttachedObjects::RegisteredFactory sOverlayKey{ - []( AudacityProject &parent ){ - auto result = std::make_shared< ScrubbingOverlay >( &parent ); - TrackPanel::Get( parent ).AddOverlay( result ); - return result; - } -}; diff --git a/src/tracks/ui/ScrubUI.cpp b/src/tracks/ui/ScrubUI.cpp index e69de29bb..1f594d38d 100644 --- a/src/tracks/ui/ScrubUI.cpp +++ b/src/tracks/ui/ScrubUI.cpp @@ -0,0 +1,209 @@ +/********************************************************************** + + Audacity: A Digital Audio Editor + + ScrubUI.cpp + + Paul Licameli split from Scrubbing.cpp + + **********************************************************************/ + +#include "ScrubUI.h" + +#include "Scrubbing.h" +#include "../../widgets/Overlay.h" +#include "../../ClientData.h" +#include "../../AdornedRulerPanel.h" +#include "../../Project.h" +#include "../../TrackPanel.h" + +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +// class ScrubbingOverlay is responsible for drawing the speed numbers + +// Specialist in drawing the scrub speed, and listening for certain events +class ScrubbingOverlay final + : public wxEvtHandler + , public Overlay + , public ClientData::Base +{ +public: + explicit + ScrubbingOverlay(AudacityProject *project); + +private: + unsigned SequenceNumber() const override; + std::pair DoGetRectangle(wxSize size) override; + void Draw(OverlayPanel &panel, wxDC &dc) override; + + void OnTimer(wxCommandEvent &event); + + const Scrubber &GetScrubber() const; + Scrubber &GetScrubber(); + + AudacityProject *mProject; + + wxRect mLastScrubRect, mNextScrubRect; + wxString mLastScrubSpeedText, mNextScrubSpeedText; +}; + +ScrubbingOverlay::ScrubbingOverlay(AudacityProject *project) + : mProject(project) + , mLastScrubRect() + , mNextScrubRect() + , mLastScrubSpeedText() + , mNextScrubSpeedText() +{ + mProject->Bind(EVT_TRACK_PANEL_TIMER, + &ScrubbingOverlay::OnTimer, + this); +} + +unsigned ScrubbingOverlay::SequenceNumber() const +{ + return 40; +} + +std::pair ScrubbingOverlay::DoGetRectangle(wxSize) +{ + wxRect rect(mLastScrubRect); + const bool outdated = + (mLastScrubRect != mNextScrubRect) || + (!mLastScrubRect.IsEmpty() && !GetScrubber().ShouldDrawScrubSpeed()) || + (mLastScrubSpeedText != mNextScrubSpeedText); + return std::make_pair( + rect, + outdated + ); +} + +void ScrubbingOverlay::Draw(OverlayPanel &, wxDC &dc) +{ + mLastScrubRect = mNextScrubRect; + mLastScrubSpeedText = mNextScrubSpeedText; + + Scrubber &scrubber = GetScrubber(); + if (!scrubber.ShouldDrawScrubSpeed()) + return; + + static const wxFont labelFont(24, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL); + dc.SetFont(labelFont); + + // These two colors were previously saturated red and green. However + // we have a rule to try to only use red for reserved purposes of + // (a) Recording + // (b) Error alerts + // So they were changed to 'orange' and 'lime'. + static const wxColour clrNoScroll(215, 162, 0), clrScroll(0, 204, 153); + if (scrubber.IsScrollScrubbing()) + dc.SetTextForeground(clrScroll); + else + dc.SetTextForeground(clrNoScroll); + + dc.DrawText(mLastScrubSpeedText, mLastScrubRect.GetX(), mLastScrubRect.GetY()); +} + +void ScrubbingOverlay::OnTimer(wxCommandEvent &event) +{ + // Let other listeners get the notification + event.Skip(); + + Scrubber &scrubber = GetScrubber(); + const auto isScrubbing = scrubber.IsScrubbing(); + auto &ruler = AdornedRulerPanel::Get( *mProject ); + auto position = ::wxGetMousePosition(); + + if (scrubber.IsSpeedPlaying()) + return; + + { + if(scrubber.HasMark()) { + auto xx = ruler.ScreenToClient(position).x; + ruler.UpdateQuickPlayPos( xx, false ); + + if (!isScrubbing) + // Really start scrub if motion is far enough + scrubber.MaybeStartScrubbing(xx); + } + + if (!isScrubbing) { + mNextScrubRect = wxRect(); + return; + } + else + ruler.DrawBothOverlays(); + } + + if (!scrubber.ShouldDrawScrubSpeed()) { + mNextScrubRect = wxRect(); + } + else { + auto &trackPanel = GetProjectPanel( *mProject ); + auto &viewInfo = ViewInfo::Get( *mProject ); + int panelWidth, panelHeight; + trackPanel.GetSize(&panelWidth, &panelHeight); + + // Where's the mouse? + position = trackPanel.ScreenToClient(position); + + const bool seeking = scrubber.Seeks() || scrubber.TemporarilySeeks(); + + // Find the text + const double maxScrubSpeed = GetScrubber().GetMaxScrubSpeed(); + const double speed = + scrubber.IsScrollScrubbing() + ? scrubber.FindScrubSpeed( seeking, + ViewInfo::Get( *mProject ) + .PositionToTime(position.x, viewInfo.GetLeftOffset())) + : maxScrubSpeed; + + const wxChar *format = + scrubber.IsScrollScrubbing() + ? seeking + ? wxT("%+.2fX") + : wxT("%+.2f") + : wxT("%.2f"); + + mNextScrubSpeedText = wxString::Format(format, speed); + + // Find the origin for drawing text + wxCoord width, height; + { + wxClientDC dc( &trackPanel ); + static const wxFont labelFont(24, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL); + dc.SetFont(labelFont); + dc.GetTextExtent(mNextScrubSpeedText, &width, &height); + } + const auto xx = + std::max(0, std::min(panelWidth - width, position.x - width / 2)); + + // Put the text above the cursor, if it fits. + enum { offset = 20 }; + auto yy = position.y - height + offset; + if (yy < 0) + yy += height + 2 * offset; + yy = std::max(0, std::min(panelHeight - height, yy)); + + mNextScrubRect = wxRect(xx, yy, width, height); + } +} + +const Scrubber &ScrubbingOverlay::GetScrubber() const +{ + return Scrubber::Get( *mProject ); +} + +Scrubber &ScrubbingOverlay::GetScrubber() +{ + return Scrubber::Get( *mProject ); +} + +static const AudacityProject::AttachedObjects::RegisteredFactory sOverlayKey{ + []( AudacityProject &parent ){ + auto result = std::make_shared< ScrubbingOverlay >( &parent ); + TrackPanel::Get( parent ).AddOverlay( result ); + return result; + } +}; diff --git a/src/tracks/ui/ScrubUI.h b/src/tracks/ui/ScrubUI.h index e69de29bb..b66420ad4 100644 --- a/src/tracks/ui/ScrubUI.h +++ b/src/tracks/ui/ScrubUI.h @@ -0,0 +1,16 @@ +/********************************************************************** + + Audacity: A Digital Audio Editor + + ScrubUI.h + + Paul Licameli split from Scrubbing.h + + **********************************************************************/ + +#ifndef __AUDACITY_SCRUB_UI__ +#define __AUDACITY_SCRUB_UI__ + + + +#endif diff --git a/src/tracks/ui/Scrubbing.cpp b/src/tracks/ui/Scrubbing.cpp index 7ffbe6ef7..d350ee088 100644 --- a/src/tracks/ui/Scrubbing.cpp +++ b/src/tracks/ui/Scrubbing.cpp @@ -913,160 +913,6 @@ void Scrubber::Forwarder::OnMouse(wxMouseEvent &event) event.Skip(); } -/////////////////////////////////////////////////////////////////////////////// -// class ScrubbingOverlay is responsible for drawing the speed numbers - -ScrubbingOverlay::ScrubbingOverlay(AudacityProject *project) - : mProject(project) - , mLastScrubRect() - , mNextScrubRect() - , mLastScrubSpeedText() - , mNextScrubSpeedText() -{ - mProject->Bind(EVT_TRACK_PANEL_TIMER, - &ScrubbingOverlay::OnTimer, - this); -} - -unsigned ScrubbingOverlay::SequenceNumber() const -{ - return 40; -} - -std::pair ScrubbingOverlay::DoGetRectangle(wxSize) -{ - wxRect rect(mLastScrubRect); - const bool outdated = - (mLastScrubRect != mNextScrubRect) || - (!mLastScrubRect.IsEmpty() && !GetScrubber().ShouldDrawScrubSpeed()) || - (mLastScrubSpeedText != mNextScrubSpeedText); - return std::make_pair( - rect, - outdated - ); -} - -void ScrubbingOverlay::Draw(OverlayPanel &, wxDC &dc) -{ - mLastScrubRect = mNextScrubRect; - mLastScrubSpeedText = mNextScrubSpeedText; - - Scrubber &scrubber = GetScrubber(); - if (!scrubber.ShouldDrawScrubSpeed()) - return; - - static const wxFont labelFont(24, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL); - dc.SetFont(labelFont); - - // These two colors were previously saturated red and green. However - // we have a rule to try to only use red for reserved purposes of - // (a) Recording - // (b) Error alerts - // So they were changed to 'orange' and 'lime'. - static const wxColour clrNoScroll(215, 162, 0), clrScroll(0, 204, 153); - if (scrubber.IsScrollScrubbing()) - dc.SetTextForeground(clrScroll); - else - dc.SetTextForeground(clrNoScroll); - - dc.DrawText(mLastScrubSpeedText, mLastScrubRect.GetX(), mLastScrubRect.GetY()); -} - -void ScrubbingOverlay::OnTimer(wxCommandEvent &event) -{ - // Let other listeners get the notification - event.Skip(); - - Scrubber &scrubber = GetScrubber(); - const auto isScrubbing = scrubber.IsScrubbing(); - auto &ruler = AdornedRulerPanel::Get( *mProject ); - auto position = ::wxGetMousePosition(); - - if (scrubber.IsSpeedPlaying()) - return; - - { - if(scrubber.HasMark()) { - auto xx = ruler.ScreenToClient(position).x; - ruler.UpdateQuickPlayPos( xx, false ); - - if (!isScrubbing) - // Really start scrub if motion is far enough - scrubber.MaybeStartScrubbing(xx); - } - - if (!isScrubbing) { - mNextScrubRect = wxRect(); - return; - } - else - ruler.DrawBothOverlays(); - } - - if (!scrubber.ShouldDrawScrubSpeed()) { - mNextScrubRect = wxRect(); - } - else { - auto &trackPanel = GetProjectPanel( *mProject ); - auto &viewInfo = ViewInfo::Get( *mProject ); - int panelWidth, panelHeight; - trackPanel.GetSize(&panelWidth, &panelHeight); - - // Where's the mouse? - position = trackPanel.ScreenToClient(position); - - const bool seeking = scrubber.Seeks() || scrubber.TemporarilySeeks(); - - // Find the text - const double maxScrubSpeed = GetScrubber().GetMaxScrubSpeed(); - const double speed = - scrubber.IsScrollScrubbing() - ? scrubber.FindScrubSpeed( seeking, - ViewInfo::Get( *mProject ) - .PositionToTime(position.x, viewInfo.GetLeftOffset())) - : maxScrubSpeed; - - const wxChar *format = - scrubber.IsScrollScrubbing() - ? seeking - ? wxT("%+.2fX") - : wxT("%+.2f") - : wxT("%.2f"); - - mNextScrubSpeedText = wxString::Format(format, speed); - - // Find the origin for drawing text - wxCoord width, height; - { - wxClientDC dc( &trackPanel ); - static const wxFont labelFont(24, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL); - dc.SetFont(labelFont); - dc.GetTextExtent(mNextScrubSpeedText, &width, &height); - } - const auto xx = - std::max(0, std::min(panelWidth - width, position.x - width / 2)); - - // Put the text above the cursor, if it fits. - enum { offset = 20 }; - auto yy = position.y - height + offset; - if (yy < 0) - yy += height + 2 * offset; - yy = std::max(0, std::min(panelHeight - height, yy)); - - mNextScrubRect = wxRect(xx, yy, width, height); - } -} - -const Scrubber &ScrubbingOverlay::GetScrubber() const -{ - return Scrubber::Get( *mProject ); -} - -Scrubber &ScrubbingOverlay::GetScrubber() -{ - return Scrubber::Get( *mProject ); -} - void Scrubber::DoScrub(bool seek) { if( !CanScrub() ) diff --git a/src/tracks/ui/Scrubbing.h b/src/tracks/ui/Scrubbing.h index 10211a94f..db3d9f278 100644 --- a/src/tracks/ui/Scrubbing.h +++ b/src/tracks/ui/Scrubbing.h @@ -11,6 +11,7 @@ Paul Licameli split from TrackPanel.cpp #ifndef __AUDACITY_SCRUBBING__ #define __AUDACITY_SCRUBBING__ +#include "../../Audacity.h" #include "../../Experimental.h" #include @@ -193,30 +194,4 @@ private: bool mShowScrubbing { false }; }; -// Specialist in drawing the scrub speed, and listening for certain events -class ScrubbingOverlay final - : public wxEvtHandler - , public Overlay - , public ClientData::Base -{ -public: - explicit - ScrubbingOverlay(AudacityProject *project); - -private: - unsigned SequenceNumber() const override; - std::pair DoGetRectangle(wxSize size) override; - void Draw(OverlayPanel &panel, wxDC &dc) override; - - void OnTimer(wxCommandEvent &event); - - const Scrubber &GetScrubber() const; - Scrubber &GetScrubber(); - - AudacityProject *mProject; - - wxRect mLastScrubRect, mNextScrubRect; - wxString mLastScrubSpeedText, mNextScrubSpeedText; -}; - #endif