mirror of
https://github.com/cookiengineer/audacity
synced 2025-11-14 17:14:07 +01:00
Define TrackPanelOverlay, use it to reimplement play indicator and cursor...
... but scrub speed display is disabled
This commit is contained in:
committed by
Paul Licameli
parent
54ac17c086
commit
1722ee9e32
118
src/tracks/ui/EditCursorOverlay.cpp
Normal file
118
src/tracks/ui/EditCursorOverlay.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
EditCursorOverlay.cpp
|
||||
|
||||
Paul Licameli split from TrackPanel.cpp
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include "../../Audacity.h"
|
||||
#include "EditCursorOverlay.h"
|
||||
#include "../../Experimental.h"
|
||||
|
||||
#include "../../AColor.h"
|
||||
#include "../../widgets/Ruler.h"
|
||||
#include "../../Project.h"
|
||||
//#include "../../TrackPanel.h"
|
||||
#include "../../TrackPanelCell.h"
|
||||
#include "../../TrackPanelCellIterator.h"
|
||||
#include "../../TrackPanelAx.h"
|
||||
#include "../../ViewInfo.h"
|
||||
|
||||
#include <wx/dc.h>
|
||||
|
||||
namespace {
|
||||
template < class LOW, class MID, class HIGH >
|
||||
bool between_incexc(LOW l, MID m, HIGH h)
|
||||
{
|
||||
return (m >= l && m < h);
|
||||
}
|
||||
}
|
||||
|
||||
EditCursorOverlay::EditCursorOverlay(AudacityProject *project)
|
||||
: mProject(project)
|
||||
, mLastCursorX(-1)
|
||||
, mCursorTime(-1)
|
||||
, mNewCursorX(-1)
|
||||
{
|
||||
}
|
||||
|
||||
EditCursorOverlay::~EditCursorOverlay()
|
||||
{
|
||||
}
|
||||
|
||||
std::pair<wxRect, bool> EditCursorOverlay::DoGetRectangle(wxSize size)
|
||||
{
|
||||
const SelectedRegion &selection = mProject->GetSelection();
|
||||
if (!selection.isPoint()) {
|
||||
mCursorTime = -1.0;
|
||||
mNewCursorX = -1;
|
||||
}
|
||||
else {
|
||||
mCursorTime = selection.t0();
|
||||
mNewCursorX = mProject->GetZoomInfo().TimeToPosition
|
||||
(mCursorTime, mProject->GetTrackPanel()->GetLeftOffset());
|
||||
}
|
||||
|
||||
return std::make_pair(
|
||||
mLastCursorX == -1
|
||||
? wxRect()
|
||||
: wxRect(mLastCursorX, 0, 1, size.GetHeight()),
|
||||
mLastCursorX != mNewCursorX
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
36
src/tracks/ui/EditCursorOverlay.h
Normal file
36
src/tracks/ui/EditCursorOverlay.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
EditCursorOverlay.h
|
||||
|
||||
Paul Licameli split from TrackPanel.cpp
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef __AUDACITY_EDIT_CURSOR_OVERLAY__
|
||||
#define __AUDACITY_EDIT_CURSOR_OVERLAY__
|
||||
|
||||
#include "../../TrackPanelOverlay.h"
|
||||
|
||||
class AudacityProject;
|
||||
|
||||
class EditCursorOverlay final : public TrackPanelOverlay
|
||||
{
|
||||
public:
|
||||
EditCursorOverlay(AudacityProject *project);
|
||||
virtual ~EditCursorOverlay();
|
||||
|
||||
private:
|
||||
std::pair<wxRect, bool> DoGetRectangle(wxSize size) override;
|
||||
void Draw
|
||||
(wxDC &dc, TrackPanelCellIterator begin, TrackPanelCellIterator end) override;
|
||||
|
||||
AudacityProject *mProject;
|
||||
|
||||
int mLastCursorX;
|
||||
double mCursorTime;
|
||||
int mNewCursorX;
|
||||
};
|
||||
|
||||
#endif
|
||||
151
src/tracks/ui/PlayIndicatorOverlay.cpp
Normal file
151
src/tracks/ui/PlayIndicatorOverlay.cpp
Normal file
@@ -0,0 +1,151 @@
|
||||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
PlayIndicatorOverlay.cpp
|
||||
|
||||
Paul Licameli split from TrackPanel.cpp
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include "PlayIndicatorOverlay.h"
|
||||
|
||||
#include "../../AColor.h"
|
||||
#include "../../AudioIO.h"
|
||||
#include "../../Project.h"
|
||||
#include "../../TrackPanel.h"
|
||||
#include "../../TrackPanelCell.h"
|
||||
#include "../../TrackPanelCellIterator.h"
|
||||
#include "../../widgets/Ruler.h"
|
||||
|
||||
#include <wx/dc.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace {
|
||||
template < class LOW, class MID, class HIGH >
|
||||
bool between_incexc(LOW l, MID m, HIGH h)
|
||||
{
|
||||
return (m >= l && m < h);
|
||||
}
|
||||
}
|
||||
|
||||
PlayIndicatorOverlay::PlayIndicatorOverlay(AudacityProject *project)
|
||||
: mProject(project)
|
||||
, mLastIndicatorX(-1)
|
||||
, mNewIndicatorX(-1)
|
||||
{
|
||||
mProject->Connect(EVT_TRACK_PANEL_TIMER,
|
||||
wxCommandEventHandler(PlayIndicatorOverlay::OnTimer),
|
||||
NULL,
|
||||
this);
|
||||
}
|
||||
|
||||
PlayIndicatorOverlay::~PlayIndicatorOverlay()
|
||||
{
|
||||
mProject->Disconnect(EVT_TRACK_PANEL_TIMER,
|
||||
wxCommandEventHandler(PlayIndicatorOverlay::OnTimer),
|
||||
NULL,
|
||||
this);
|
||||
}
|
||||
|
||||
std::pair<wxRect, bool> PlayIndicatorOverlay::DoGetRectangle(wxSize size)
|
||||
{
|
||||
wxRect rect(mLastIndicatorX, 0, 1, size.GetHeight());
|
||||
return std::make_pair(
|
||||
rect,
|
||||
mLastIndicatorX != mNewIndicatorX
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void PlayIndicatorOverlay::Draw
|
||||
(wxDC &dc, TrackPanelCellIterator begin, TrackPanelCellIterator end)
|
||||
{
|
||||
mLastIndicatorX = mNewIndicatorX;
|
||||
if (!between_incexc(0, mLastIndicatorX, dc.GetSize().GetWidth()))
|
||||
return;
|
||||
|
||||
const ZoomInfo &viewInfo = mProject->GetZoomInfo();
|
||||
TrackPanel *const trackPanel = mProject->GetTrackPanel();
|
||||
|
||||
double pos = viewInfo.PositionToTime(mLastIndicatorX, trackPanel->GetLeftOffset());
|
||||
|
||||
// Set play/record color
|
||||
bool rec = (gAudioIO->GetNumCaptureChannels() > 0);
|
||||
AColor::IndicatorColor(&dc, !rec);
|
||||
|
||||
mProject->GetRulerPanel()->DrawIndicator(pos, rec);
|
||||
|
||||
// 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());
|
||||
}
|
||||
}
|
||||
|
||||
void PlayIndicatorOverlay::Erase(wxDC &dc, wxDC &src)
|
||||
{
|
||||
TrackPanelOverlay::Erase(dc, src);
|
||||
mProject->GetRulerPanel()->ClearIndicator();
|
||||
}
|
||||
|
||||
void PlayIndicatorOverlay::OnTimer(wxCommandEvent &event)
|
||||
{
|
||||
// Let other listeners get the notification
|
||||
event.Skip();
|
||||
|
||||
if (!mProject->IsAudioActive())
|
||||
mNewIndicatorX = -1;
|
||||
else {
|
||||
ViewInfo &viewInfo = mProject->GetViewInfo();
|
||||
|
||||
// Calculate the horizontal position of the indicator
|
||||
const double playPos = viewInfo.mRecentStreamTime;
|
||||
|
||||
const 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
|
||||
if (viewInfo.bUpdateTrackIndicator &&
|
||||
mProject->mLastPlayMode != loopedPlay &&
|
||||
mProject->mLastPlayMode != oneSecondPlay &&
|
||||
playPos >= 0 &&
|
||||
!onScreen &&
|
||||
!gAudioIO->IsPaused())
|
||||
{
|
||||
mProject->TP_ScrollWindow(playPos);
|
||||
}
|
||||
|
||||
// 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();
|
||||
|
||||
mNewIndicatorX = viewInfo.TimeToPosition(playPos, mProject->GetTrackPanel()->GetLeftOffset());
|
||||
}
|
||||
}
|
||||
40
src/tracks/ui/PlayIndicatorOverlay.h
Normal file
40
src/tracks/ui/PlayIndicatorOverlay.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
PlayIndicatorOverlay.h
|
||||
|
||||
Paul Licameli split from TrackPanel.cpp
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef __AUDACITY_PLAY_INDICATOR_OVERLAY__
|
||||
#define __AUDACITY_PLAY_INDICATOR_OVERLAY__
|
||||
|
||||
#include "../../TrackPanelOverlay.h"
|
||||
#include <wx/event.h>
|
||||
|
||||
class AudacityProject;
|
||||
|
||||
|
||||
class PlayIndicatorOverlay final : public wxEvtHandler, public TrackPanelOverlay
|
||||
{
|
||||
public:
|
||||
PlayIndicatorOverlay(AudacityProject *project);
|
||||
virtual ~PlayIndicatorOverlay();
|
||||
|
||||
private:
|
||||
std::pair<wxRect, bool> DoGetRectangle(wxSize size) override;
|
||||
void Draw
|
||||
(wxDC &dc, TrackPanelCellIterator begin, TrackPanelCellIterator end) override;
|
||||
void Erase(wxDC &dc, wxDC &src) override;
|
||||
|
||||
void OnTimer(wxCommandEvent &event);
|
||||
|
||||
|
||||
AudacityProject *mProject;
|
||||
int mLastIndicatorX;
|
||||
int mNewIndicatorX;
|
||||
};
|
||||
|
||||
#endif
|
||||
53
src/tracks/ui/Scrubbing.cpp
Normal file
53
src/tracks/ui/Scrubbing.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
Scrubbing.cpp
|
||||
|
||||
Paul Licameli split from TrackPanel.cpp
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include "Scrubbing.h"
|
||||
|
||||
#include "../../Project.h"
|
||||
#include "../../TrackPanel.h"
|
||||
#include "../../TrackPanelCell.h"
|
||||
#include "../../TrackPanelCellIterator.h"
|
||||
|
||||
#include <wx/dc.h>
|
||||
|
||||
ScrubbingOverlay::ScrubbingOverlay(AudacityProject *project)
|
||||
: mProject(project)
|
||||
{
|
||||
mProject->Connect(EVT_TRACK_PANEL_TIMER,
|
||||
wxCommandEventHandler(ScrubbingOverlay::OnTimer),
|
||||
NULL,
|
||||
this);
|
||||
}
|
||||
|
||||
ScrubbingOverlay::~ScrubbingOverlay()
|
||||
{
|
||||
mProject->Disconnect(EVT_TRACK_PANEL_TIMER,
|
||||
wxCommandEventHandler(ScrubbingOverlay::OnTimer),
|
||||
NULL,
|
||||
this);
|
||||
}
|
||||
|
||||
std::pair<wxRect, bool> ScrubbingOverlay::DoGetRectangle(wxSize)
|
||||
{
|
||||
return std::make_pair(wxRect(), false);
|
||||
}
|
||||
|
||||
void ScrubbingOverlay::Draw
|
||||
(wxDC &dc, TrackPanelCellIterator begin, TrackPanelCellIterator end)
|
||||
{
|
||||
}
|
||||
|
||||
void ScrubbingOverlay::OnTimer(wxCommandEvent &event)
|
||||
{
|
||||
// Let other listeners get the notification
|
||||
event.Skip();
|
||||
|
||||
// To do: move code here
|
||||
}
|
||||
36
src/tracks/ui/Scrubbing.h
Normal file
36
src/tracks/ui/Scrubbing.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
Scrubbing.h
|
||||
|
||||
Paul Licameli split from TrackPanel.cpp
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef __AUDACITY_SCRUBBING__
|
||||
#define __AUDACITY_SCRUBBING__
|
||||
|
||||
#include <wx/event.h>
|
||||
|
||||
#include "../../TrackPanelOverlay.h"
|
||||
|
||||
class AudacityProject;
|
||||
|
||||
class ScrubbingOverlay : public wxEvtHandler, public TrackPanelOverlay
|
||||
{
|
||||
public:
|
||||
ScrubbingOverlay(AudacityProject *project);
|
||||
virtual ~ScrubbingOverlay();
|
||||
|
||||
private:
|
||||
std::pair<wxRect, bool> DoGetRectangle(wxSize size) override;
|
||||
void Draw
|
||||
(wxDC &dc, TrackPanelCellIterator begin, TrackPanelCellIterator end) override;
|
||||
|
||||
void OnTimer(wxCommandEvent &event);
|
||||
|
||||
AudacityProject *mProject;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user