mirror of
https://github.com/cookiengineer/audacity
synced 2025-08-10 17:11:17 +02:00
ScrubbingOverlay declared and defined entirely within ScrubUI.cpp
This commit is contained in:
parent
24bd7cf571
commit
8414ebffa5
@ -1079,14 +1079,3 @@ int ProjectManager::GetEstimatedRecordingMinsLeftOnDisk(long lCaptureChannels) {
|
|||||||
int iRecMins = (int)round(dRecTime / 60.0);
|
int iRecMins = (int)round(dRecTime / 60.0);
|
||||||
return iRecMins;
|
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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
@ -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 <wx/dcclient.h>
|
||||||
|
#include <wx/event.h>
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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<wxRect, bool> 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<wxRect, bool> 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;
|
||||||
|
}
|
||||||
|
};
|
@ -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
|
@ -913,160 +913,6 @@ void Scrubber::Forwarder::OnMouse(wxMouseEvent &event)
|
|||||||
event.Skip();
|
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<wxRect, bool> 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)
|
void Scrubber::DoScrub(bool seek)
|
||||||
{
|
{
|
||||||
if( !CanScrub() )
|
if( !CanScrub() )
|
||||||
|
@ -11,6 +11,7 @@ Paul Licameli split from TrackPanel.cpp
|
|||||||
#ifndef __AUDACITY_SCRUBBING__
|
#ifndef __AUDACITY_SCRUBBING__
|
||||||
#define __AUDACITY_SCRUBBING__
|
#define __AUDACITY_SCRUBBING__
|
||||||
|
|
||||||
|
#include "../../Audacity.h"
|
||||||
#include "../../Experimental.h"
|
#include "../../Experimental.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -193,30 +194,4 @@ private:
|
|||||||
bool mShowScrubbing { false };
|
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<wxRect, bool> 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
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user