mirror of
https://github.com/cookiengineer/audacity
synced 2025-08-09 16:41:14 +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);
|
||||
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();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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)
|
||||
{
|
||||
if( !CanScrub() )
|
||||
|
@ -11,6 +11,7 @@ Paul Licameli split from TrackPanel.cpp
|
||||
#ifndef __AUDACITY_SCRUBBING__
|
||||
#define __AUDACITY_SCRUBBING__
|
||||
|
||||
#include "../../Audacity.h"
|
||||
#include "../../Experimental.h"
|
||||
|
||||
#include <vector>
|
||||
@ -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<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
|
||||
|
Loading…
x
Reference in New Issue
Block a user