26#include <wx/tooltip.h>
34#include "../images/Cursors.h"
66#include <wx/dcclient.h>
74#define SELECT_TOLERANCE_PIXEL 4
76#define PLAY_REGION_TRIANGLE_SIZE 7
77#define PLAY_REGION_RECT_WIDTH 1
78#define PLAY_REGION_RECT_HEIGHT 3
79#define PLAY_REGION_GLOBAL_OFFSET_Y 7
100 return ((width / 2) * 3) / 2;
107 (((height) * 2) / 3) * 2
141 if (oldState.
mX != newState.
mX)
168 const auto pos =
event.event.GetPosition();
177 return viewInfo.PositionToTime(
mX, viewInfo.GetLeftOffset());
189 auto saveMe =
ruler.Target();
192 ruler.StartQPPlay(!event.ShiftDown(),
false, &startTime);
221 size_t numGuides = 1)
233 size_t numGuides = 1)
249 const auto message =
XO(
"Click and drag to define a looping region.");
266 mX =
event.event.m_x;
303 auto &playRegion = viewInfo.playRegion;
319 auto &playRegion = viewInfo.playRegion;
322 playRegion.SetActive(
false);
333 auto identity = [](
auto x){
return x; };
351 bool isSnapped =
ruler.mIsSnapped[ii];
353 ?
ruler.mQuickPlayPos[ii]
354 :
ruler.mQuickPlayPosUnsnapped[ii];
360 for (
size_t ii = 0; ii <
ruler.mNumGuides; ++ii)
361 if (
ruler.mIsSnapped[ii]) {
362 double time0 =
ruler.mQuickPlayPos[ii];
363 double delta = time0 -
ruler.mQuickPlayPosUnsnapped[ii];
364 double time1 =
ruler.mQuickPlayPosUnsnapped[1 - ii] + delta;
366 return { time1, time0 };
368 return { time0, time1 };
371 return {
ruler.mQuickPlayPos[0],
ruler.mQuickPlayPos[1] };
377 std::fill(
ruler.mIsSnapped,
ruler.mIsSnapped +
ruler.mNumGuides,
false );
391 auto &playRegion = viewInfo.playRegion;
393 mOldStart = playRegion.GetLastActiveStart();
394 mOldEnd = playRegion.GetLastActiveEnd();
396 playRegion.SetActive(
true);
478 { std::make_shared<ScrubbingRulerOverlay>(*
this) };
501 return &
Get( *mPartner.mProject );
506 const auto project = mPartner.mProject;
508 auto ruler = GetRuler();
510 bool scrubbing = (scrubber.IsScrubbing()
511 && !scrubber.IsSpeedPlaying()
512 && !scrubber.IsKeyboardScrubbing());
517 mNewQPIndicatorPos = -1;
521 std::max(
ruler->mTracks->GetEndTime(), selectedRegion.t1());
526 mNewIndicatorSnapped = -1;
528 mNewIndicatorSnapped == -1 && ii <
ruler->mNumGuides; ++ii) {
529 if (
ruler->mIsSnapped[ii]) {
530 mNewIndicatorSnapped = ii;
533 mNewQPIndicatorPos =
ruler->Time2Pos(
534 ruler->mQuickPlayPos[std::max(0, mNewIndicatorSnapped)]);
539 !
ruler->IsMouseCaptured() &&
540 (
ruler->LastCell() ==
ruler->mScrubbingCell ||
541 (scrubber.HasMark()));
542 mNewSeek = mNewScrub &&
543 (scrubber.Seeks() || scrubber.TemporarilySeeks());
553std::pair<wxRect, bool>
558 const auto x = mOldQPIndicatorPos;
565 const int indsize = width / 2;
567 auto xx = x - indsize;
572 GetRuler()->GetSize().GetHeight() },
573 (x != mNewQPIndicatorPos
574 || (mOldScrub != mNewScrub)
575 || (mOldSeek != mNewSeek) )
579 return { {}, mNewQPIndicatorPos >= 0 };
585 mOldQPIndicatorPos = mNewQPIndicatorPos;
586 mOldScrub = mNewScrub;
588 if (mOldQPIndicatorPos >= 0) {
589 auto ruler = GetRuler();
591 ruler->DoDrawScrubIndicator(
592 &dc, mOldQPIndicatorPos, width, mOldScrub, mOldSeek);
622 mNewPreviewingScrub =
624 !scrubber.IsScrubbing();
627std::pair<wxRect, bool>
632 wxRect rect(mOldQPIndicatorPos, 0, 1,
size.GetHeight());
633 return std::make_pair(
635 (mOldQPIndicatorPos != mPartner->mNewQPIndicatorPos ||
636 mOldIndicatorSnapped != mPartner->mNewIndicatorSnapped ||
637 mOldPreviewingScrub != mNewPreviewingScrub)
644 mOldQPIndicatorPos = mPartner->mNewQPIndicatorPos;
645 mOldIndicatorSnapped = mPartner->mNewIndicatorSnapped;
646 mOldPreviewingScrub = mNewPreviewingScrub;
648 if (mOldQPIndicatorPos >= 0) {
649 if (!mOldPreviewingScrub && mOldIndicatorSnapped < 0) {
653 pHandle !=
nullptr && pHandle->
Clicked())
660 : (mOldIndicatorSnapped >= 0)
665 auto pCellularPanel =
dynamic_cast<CellularPanel*
>( &panel );
666 if ( !pCellularPanel ) {
672 const auto pChannelView =
dynamic_cast<ChannelView*
>(&cell);
734 , mMenuChoice{ menuChoice }
745 static wxCursor cursor{ wxCURSOR_DEFAULT };
757 mParent->ShowContextMenu(mMenuChoice, pPosition);
766#undef QUICK_PLAY_HANDLE
767#ifdef QUICK_PLAY_HANDLE
790 wxWindow *pParent)
override;
813 mParent->mQuickPlayOffset[0] = 0;
814 mParent->mQuickPlayOffset[1] = 0;
823 mParent->mQuickPlayOffset[0] = playRegion.GetStart() - time;
824 mParent->mQuickPlayOffset[1] = playRegion.GetEnd() - time;
834 playRegion.
SetTimes(times.first, times.second);
864 playRegion.SetEnd(time);
903 auto width = viewInfo.GetTracksUsableWidth();
904 return viewInfo.GetLeftOffset()
911 auto width = viewInfo.GetTracksUsableWidth();
912 auto fraction = (xx - viewInfo.GetLeftOffset()) /
double(width);
913 return std::max(0.0,
std::min(1.0, fraction));
922 : mpParent{ &parent }
932 if (oldState.
mX != newState.
mX)
937 static std::shared_ptr<PlayheadHandle>
942 .IsTransportingPinned() &&
947 return std::make_shared<PlayheadHandle>( parent, xx );
956 if (event.
event.LeftDClick()) {
965 if (!event.
event.LeftIsDown())
985 mpParent->SetNumGuides(1);
986 static wxCursor cursor{ wxCURSOR_SIZEWE };
988 XO(
"Click and drag to adjust, double-click to reset" ),
992 XO(
"Record/Playhead" )
1018 double mOrigPreference {};
1031 std::vector<UIHandlePtr>
HitTest(
1040#ifdef QUICK_PLAY_HANDLE
1041 if (
auto ptr = mHolder.lock())
1042 return ptr->Clicked();
1047#ifdef QUICK_PLAY_HANDLE
1048 std::weak_ptr<QPHandle> mHolder;
1063 mParent->CreateOverlays();
1065 std::vector<UIHandlePtr> results;
1066 auto xx = state.
state.m_x;
1074 results.push_back( result );
1079 if (!mParent->mIsRecording) {
1080 mParent->UpdateQuickPlayPos( xx );
1083 auto result = std::make_shared<QPHandle>( mParent, xx );
1085 results.push_back( result );
1090 bool hitLeft =
false;
1093 mParent->IsWithinMarker(xx, playRegion.GetLastActiveStart())) ||
1094 mParent->IsWithinMarker(xx, playRegion.GetLastActiveEnd()))
1097 std::make_shared<ResizePlayRegionHandle>( mParent, xx, hitLeft );
1099 results.push_back(result);
1104 if (
auto time = mParent->Pos2Time(xx);
1105 playRegion.Active() &&
1106 time >= playRegion.GetStart() &&
1107 time <= playRegion.GetEnd())
1110 std::make_shared<MovePlayRegionHandle>( mParent, xx );
1112 results.push_back(result);
1117 auto result = std::make_shared<NewPlayRegionHandle>( mParent, xx );
1119 results.push_back(result);
1144 scrubber.CanScrub() &&
1150 if (!scrubber.HasMark()) {
1152 scrubber.MarkScrubStart(
1177 wxWindow *pParent)
override {
1210 std::vector<UIHandlePtr>
HitTest(
1220 if (
auto ptr =
mHolder.lock())
1221 return ptr->Clicked();
1234 mParent->CreateOverlays();
1236 std::vector<UIHandlePtr> results;
1239 if (!mParent->mIsRecording) {
1240 auto xx = state.
state.m_x;
1241 mParent->UpdateQuickPlayPos( xx );
1242 auto result = std::make_shared<ScrubbingHandle>( mParent, xx );
1244 results.push_back( result );
1251AttachedWindows::RegisteredFactory
sKey{
1280 pPanel->wxWindow::Destroy();
1296 SetLayoutDirection(wxLayout_LeftToRight);
1298 mQPCell = std::make_shared<QPCell>(
this );
1306 SetBackgroundStyle(wxBG_STYLE_PAINT);
1315 mOuter = GetClientRect();
1330 wxToolTip::Enable(
true);
1359 CellularPanel::Refresh( eraseBackground, rect );
1388 SetBackgroundColour(GetBackgroundColour());
1402 wxPoint position( 12, 0 );
1411 bmpRecoloredUpSmall, bmpRecoloredDownSmall,
1412 bmpRecoloredUpHiliteSmall, bmpRecoloredHiliteSmall,
1413 bmpCogwheel, bmpCogwheel, bmpCogwheel,
1417 position.x +=
size.GetWidth();
1432 if(scrubber.Seeks())
1437 return XO(
"Click or drag to begin Seek");
1443 return XO(
"Click or drag to begin Scrub");
1449 return XO(
"Click & move to Scrub. Click & drag to Seek.");
1454 const Scrubber &scrubber,
bool clicked)
1457 if(scrubber.
Seeks())
1462 return XO(
"Move to Seek");
1468 return XO(
"Move to Scrub");
1475 return XO(
"Drag to Seek. Release to stop seeking.");
1478 return XO(
"Drag to Seek. Release and move to Scrub.");
1481 return XO(
"Move to Scrub. Drag to Seek.");
1507 const auto &selectedRegion = viewInfo.selectedRegion;
1508 const auto &playRegion = viewInfo.playRegion;
1513 playRegion.GetLastActiveStart(), playRegion.GetLastActiveEnd() }
1551 const auto &playRegion = viewInfo.playRegion;
1552 const auto playRegionBounds = std::pair{
1553 playRegion.GetLastActiveStart(), playRegion.GetLastActiveEnd() };
1569 rectO = rectP.Intersect(rectS);
1572 const auto top = rectP.GetTop(),
1573 bottom = rectP.GetBottom();
1576 if (!rectO.IsEmpty()) {
1577 rectR = { wxPoint{ rectO.GetRight() + 1, top }, rectL.GetBottomRight() };
1578 rectL = { rectL.GetTopLeft(), wxPoint{ rectO.GetLeft() - 1, bottom } };
1596 dc.DestroyClippingRegion();
1602 mOuter = GetClientRect();
1653 auto bottom = &inner;
1661 top = &scrubZone, topHeight = scrubHeight;
1663 auto qpHeight = scrubZone.height - scrubHeight;
1664 bottom = &scrubZone, topHeight = qpHeight;
1670 top->height = topHeight;
1671 bottom->height -= topHeight;
1672 bottom->y += topHeight;
1717 int pixelPos =
Time2Pos(markerTime);
1721 return mousePosX >= boundLeft && mousePosX < boundRight;
1724#ifdef QUICK_PLAY_HANDLE
1725auto AdornedRulerPanel::QPHandle::Click(
1728 auto result = CommonRulerHandle::Click(event, pProject);
1730 if (mClicked == Button::Left) {
1735 if(scrubber.HasMark()) {
1743 const auto &playRegion = viewInfo.playRegion;
1744 mParent->mOldPlayRegion = playRegion;
1749 mParent->HandleQPClick( event.event, mX );
1750 mParent->HandleQPDrag( event.event, mX );
1770 if (isWithinStart || isWithinEnd) {
1794auto AdornedRulerPanel::QPHandle::Drag(
1797 auto result = CommonRulerHandle::Drag(event, pProject);
1799 if (mClicked == Button::Left) {
1801 mX =
event.event.m_x;
1802 mParent->UpdateQuickPlayPos( mX );
1803 mParent->HandleQPDrag( event.event, mX );
1812 bool isWithinClick =
1819 auto &playRegion = viewInfo.playRegion;
1825 if (isWithinStart || isWithinEnd) {
1852 if (isWithinStart) {
1872 if (isWithinClick) {
1897 mParent->SetNumGuides(1);
1906#ifdef QUICK_PLAY_HANDLE
1907auto AdornedRulerPanel::QPHandle::Preview(
1911 mParent->SetNumGuides(1);
1915 if (!mParent->mQuickPlayEnabled)
1916 tooltip =
XO(
"Quick-Play disabled");
1918 tooltip =
XO(
"Quick-Play enabled");
1924 const bool scrubbing = scrubber.HasMark();
1932 static wxCursor cursorHand{ wxCURSOR_HAND };
1933 static wxCursor cursorSizeWE{ wxCURSOR_SIZEWE };
1935 bool showArrows =
false;
1938 (mClicked == Button::Left)
1939 || mParent->IsWithinMarker(
1940 state.state.m_x, mParent->mOldPlayRegion.GetStart())
1941 || mParent->IsWithinMarker(
1942 state.state.m_x, mParent->mOldPlayRegion.GetEnd());
1946 showArrows ? &cursorSizeWE : &cursorHand,
1960 auto saveMe = mParent->mQPCell->mHolder.lock();
1964 if (mClicked == Button::Left) {
1966 mParent->HandleQPRelease( event.event );
1969 const auto &playRegion = viewInfo.playRegion;
1970 mParent->mOldPlayRegion = playRegion;
1980 auto &playRegion = viewInfo.playRegion;
1985 const auto &selectedRegion = viewInfo.selectedRegion;
1986 const double sel0 = selectedRegion.t0();
1987 const double sel1 = selectedRegion.t1();
1991 if (evt.ShiftDown() && playRegion.Empty()) {
1995 if (((sel1 < t0) || (sel0 > t1)) &&
1996 ((playRegion.GetStart() < t0) || (playRegion.GetStart() > t1))) {
2001 else if (playRegion.GetStart() >= t1) {
2007 playRegion.GetEnd() - playRegion.GetStart() > 0.0 &&
2008 playRegion.GetEnd() < t0
2017 auto cleanup =
finally( [&] {
2020 SetPlayRegion(mOldPlayRegion.GetStart(), mOldPlayRegion.GetEnd());
2021 SelectUtilities::ActivatePlayRegion(*mProject);
2023 mOldPlayRegion.SetActive( false );
2032 auto result = CommonRulerHandle::Cancel(pProject);
2034 if (mClicked == Button::Left) {
2037 mParent->mMouseEventState = mesNone;
2038 mParent->SetPlayRegion(
2039 mParent->mOldPlayRegion.GetStart(), mParent->mOldPlayRegion.GetEnd());
2040 if (mParent->mOldPlayRegion.Active()) {
2044 mParent->mOldPlayRegion.SetActive(
false );
2054 bool newDefault,
bool cutPreview,
const double *pStartTime)
2059 const auto &playRegion = viewInfo.playRegion;
2060 const auto &selectedRegion = viewInfo.selectedRegion;
2061 const double sel0 = selectedRegion.t0();
2062 const double sel1 = selectedRegion.t1();
2065 bool startPlaying =
true;
2068 bool loopEnabled =
true;
2069 auto oldStart = std::max(0.0, playRegion.GetStart());
2070 double start = oldStart,
end = 0;
2072 if (playRegion.Empty()) {
2074 if (oldStart > sel0 && oldStart < sel1) {
2085 end = std::max(start, playRegion.GetEnd());
2088 loopEnabled = ((
end - start) > 0.001)? true :
false;
2090 newDefault = (loopEnabled && newDefault);
2097 options.pStartTime.emplace(*pStartTime);
2100 options.envelope =
nullptr;
2110 projectAudioManager.Stop();
2127void AdornedRulerPanel::OnToggleScrubRulerFromMenu(wxCommandEvent&)
2130 scrubber.OnToggleScrubRuler(*
mProject);
2137 const auto oldSize = GetSize();
2139 if (
size != oldSize ) {
2142 PostSizeEventToParent();
2151 auto pCellularPanel =
2153 if ( !pCellularPanel ) {
2157 pCellularPanel->DrawOverlays(
false );
2163 auto common = [
this](
2174 timelineOptionsButton->
PopUp();
2177 const auto label =
XO(
"Timeline Options");
2178 common(*timelineOptionsButton,
wxT(
"PinnedHead"),
label);
2201 auto width = viewInfo.GetTracksUsableWidth();
2202 mousePosX = std::max(mousePosX, viewInfo.GetLeftOffset());
2203 mousePosX =
std::min(mousePosX, viewInfo.GetLeftOffset() + width - 1);
2204 const auto time =
Pos2Time(mousePosX);
2218 const auto &playRegion = viewInfo.playRegion;
2223 _(
"Minutes and Seconds"));
2229 _(
"Beats and Measures"));
2233 rulerMenu.AppendSeparator();
2235 auto pDrag = rulerMenu.AppendCheckItem(
OnSyncQuickPlaySelID,
_(
"Setting a loop region also makes an audio selection"));
2237 pDrag->Enable(playRegion.Active());
2242 item->Check(playRegion.Active());
2253 _(
"Set Loop To Selection"));
2256 rulerMenu.AppendSeparator();
2258 rulerMenu.AppendCheckItem(
OnAutoScrollID,
_(
"Scroll view to playhead"))->
2273 PushEventHandler(&scrubber);
2274 auto cleanup =
finally([
this]{ PopEventHandler(); });
2277 scrubber.PopulatePopupMenu(rulerMenu);
2287 const auto &playRegion = viewInfo.playRegion;
2288 auto &selectedRegion = viewInfo.selectedRegion;
2289 selectedRegion.setT0(playRegion.GetStart(),
false);
2290 selectedRegion.setT1(playRegion.GetEnd(),
true);
2304 auto results = snapManager.Snap(
nullptr,
mQuickPlayPos[index],
false);
2311 int id =
event.GetId();
2364 position = *pPosition;
2367 auto rect = GetRect();
2375 position = { rect.GetLeft() + 38, rect.GetHeight()/2 + 1 };
2394 return clrTimelineRulerBackground;
2399 return clrTrackPanelText;
2409 return clrRulerSelected;
2414 return isActive ? clrLoopEnabled : clrLoopDisabled;
2432 dc->DrawRectangle(
mOuter );
2439 ScrubRect.Inflate( 1,0 );
2440 dc->DrawRectangle(ScrubRect);
2447 dc->SetPen( *wxBLACK_PEN );
2482 const auto &playRegion = viewInfo.playRegion;
2483 const auto t0 = playRegion.GetLastActiveStart(),
2484 t1 = playRegion.GetLastActiveEnd();
2491 const auto &selectedRegion = viewInfo.selectedRegion;
2492 const auto t0 = selectedRegion.t0(), t1 = selectedRegion.t1();
2508 const int left = p0, top =
mInner.y, right = p1, bottom =
mInner.GetBottom();
2509 return { wxPoint{left, top}, wxPoint{right, bottom} };
2513 wxDC * dc,
const wxRect &rectP,
const wxRect &rectL,
const wxRect &rectR)
2516 const auto& playRegion = viewInfo.playRegion;
2520 if (playRegion.IsLastActiveRegionClear())
2528 dc->DrawRectangle( rectP.Intersect(rectL) );
2529 dc->DrawRectangle( rectP.Intersect(rectR) );
2537 dc->SetPen( { edgeColour } );
2538 dc->SetBrush( { edgeColour } );
2540 constexpr int side = 7;
2541 constexpr int sideLessOne = side - 1;
2544 const auto left = rect.GetLeft(),
2545 right = rect.GetRight(),
2546 bottom = rect.GetBottom(),
2547 top = rect.GetTop();
2550 {left, bottom - sideLessOne},
2551 {left - sideLessOne, bottom},
2555 dc->DrawPolygon( 4, points );
2562 {right + sideLessOne, bottom},
2563 {right, bottom - sideLessOne},
2565 dc->DrawPolygon( 4, points );
2576 dc->SetPen( *wxTRANSPARENT_PEN );
2577 dc->DrawRectangle( rect );
2581 wxDC * dc,
const wxRect &rectS,
const wxRect &rectL,
const wxRect &rectR)
2585 dc->SetPen( *wxTRANSPARENT_PEN );
2586 dc->DrawRectangle( rectS.Intersect(rectL) );
2587 dc->DrawRectangle( rectS.Intersect(rectR) );
2606 wxDC * dc, wxCoord xx,
int width,
bool scrub,
bool seek)
2614 const int TriangleWidth = width * 3 / 8;
2619 : (
mInner.GetBottom() + 1) - 1 - height;
2623 tri[ 1 ].y = yy + height;
2624 tri[ 2 ].x = xx - TriangleWidth;
2625 tri[ 2 ].y = yy + height / 2;
2626 dc->DrawPolygon( 3, tri );
2628 tri[ 0 ].x -= TriangleWidth;
2629 tri[ 1 ].x -= TriangleWidth;
2630 tri[ 2 ].x -= TriangleWidth;
2631 dc->DrawPolygon( 3, tri );
2634 tri[ 2 ].x = xx + TriangleWidth;
2635 dc->DrawPolygon( 3, tri );
2638 tri[ 0 ].x += TriangleWidth;
2639 tri[ 1 ].x += TriangleWidth;
2640 tri[ 2 ].x += TriangleWidth;
2641 dc->DrawPolygon( 3, tri );
2645 const int IndicatorHalfWidth = width / 2;
2650 : (
mInner.GetBottom() + 1) - 1 - height;
2654 tri[ 1 ].y = yy + height;
2655 tri[ 2 ].x = xx - IndicatorHalfWidth;
2656 tri[ 2 ].y = yy + height / 2;
2657 dc->DrawPolygon( 3, tri );
2659 tri[ 2 ].x = xx + IndicatorHalfWidth;
2660 dc->DrawPolygon( 3, tri );
2665 double playRegionStart,
double playRegionEnd)
2674 auto &playRegion = viewInfo.playRegion;
2675 playRegion.SetTimes( playRegionStart, playRegionEnd );
2685 auto &playRegion = viewInfo.playRegion;
2699 s_AcceptsFocus =
true;
2707 for (
size_t ii =
mNumGuides; ii < nn; ++ii) {
2758 return scrubber.ShowsBar();
2765 return std::make_shared< MainGroup >( *
this );
2801 std::make_shared<TrackPanelGuidelineOverlay>(
mProject );
2802 auto pCellularPanel =
2804 if ( !pCellularPanel ) {
2808 pCellularPanel->AddOverlay(
mOverlay );
2824 if (scrubber.HasMark())
2825 scrubber.SetScrollScrubbing(value);
EVT_MENU(OnSetPlayRegionToSelectionID, AdornedRulerPanel::OnSetPlayRegionToSelection) EVT_COMMAND(OnTogglePinnedStateID
ColorId TimelineLimitsColor()
decltype(clrTrackInfo) ColorId
ColorId TimelineLoopRegionColor(bool isActive)
static wxColour AlphaBlend(ColorId fg, ColorId bg, double alpha)
#define PLAY_REGION_TRIANGLE_SIZE
ColorId TimelineSelectionColor()
static std::unique_ptr< wxCursor > handOpenCursor
ColorId TimelineBackgroundColor()
@ OnSetPlayRegionToSelectionID
int IndicatorWidthForHeight(int height)
ColorId TimelineTextColor()
wxEVT_COMMAND_BUTTON_CLICKED
int IndicatorHeightForWidth(int width)
#define SELECT_TOLERANCE_PIXEL
constexpr double SelectionOpacity
constexpr CommandFlag AlwaysEnabledFlag
XXO("&Cut/Copy/Paste Toolbar")
EVT_COMMAND(wxID_ANY, EVT_FREQUENCYTEXTCTRL_UPDATED, LabelDialog::OnFreqUpdate) LabelDialog
audacity::BasicSettings * gPrefs
AUDACITY_DLL_API wxWindow & GetProjectPanel(AudacityProject &project)
Get the main sub-window of the project frame that displays track data.
AUDACITY_DLL_API AttachedWindows & GetAttachedWindows(AudacityProject &project)
accessors for certain important windows associated with each project
std::vector< SnapPoint > SnapPointArray
TimeDisplayModeSetting TimeDisplayModePreference
declares abstract base class Track, TrackList, and iterators over TrackList
std::unique_ptr< wxCursor > MakeCursor(int WXUNUSED(CursorId), const char *const pXpm[36], int HotX, int HotY)
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
std::shared_ptr< Subclass > AssignUIHandlePtr(std::weak_ptr< Subclass > &holder, const std::shared_ptr< Subclass > &pNew)
const TranslatableString LoopToggleText
static void IndicatorColor(wxDC *dc, bool bIsNotRecording)
static void Line(wxDC &dc, wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
static void SnapGuidePen(wxDC *dc)
static void Light(wxDC *dc, bool selected, bool highlight=false)
static void UseThemeColour(wxDC *dc, int iBrush, int iPen=-1, int alpha=255)
Makes temporary drawing context changes that you back out of, RAII style.
CommonCell(AdornedRulerPanel *parent, MenuChoice menuChoice)
unsigned DoContextMenu(const wxRect &, wxWindow *, const wxPoint *pPosition, AudacityProject *) final
AdornedRulerPanel * mParent
HitTestPreview DefaultPreview(const TrackPanelMouseState &, const AudacityProject *) override
const MenuChoice mMenuChoice
Result Click(const TrackPanelMouseEvent &event, AudacityProject *) override
Result Drag(const TrackPanelMouseEvent &, AudacityProject *) override
double Time(AudacityProject &project) const
bool HandlesRightClick() override
Whether the handle has any special right-button handling.
CommonRulerHandle(AdornedRulerPanel *pParent, wxCoord xx, MenuChoice menuChoice)
Result Release(const TrackPanelMouseEvent &event, AudacityProject *, wxWindow *) override
std::shared_ptr< const Track > FindTrack() const override
wxWeakRef< AdornedRulerPanel > mParent
void StartPlay(AudacityProject &project, const wxMouseEvent &event)
Result Cancel(AudacityProject *) override
static UIHandle::Result NeedChangeHighlight(const CommonRulerHandle &oldState, const CommonRulerHandle &newState)
void Enter(bool, AudacityProject *) override
void DoStartAdjust(AudacityProject &project, double) override
MovePlayRegionHandle(AdornedRulerPanel *pParent, wxCoord xx)
void DoAdjust(AudacityProject &project) override
NewPlayRegionHandle(AdornedRulerPanel *pParent, wxCoord xx)
void DoAdjust(AudacityProject &project) override
void DoStartAdjust(AudacityProject &project, double time) override
virtual void DoAdjust(AudacityProject &)=0
virtual void DoStartAdjust(AudacityProject &, double)=0
Result Drag(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
PlayRegionAdjustingHandle(AdornedRulerPanel *pParent, wxCoord xx, MenuChoice menuChoice, wxCursor *cursor, size_t numGuides=1)
HitTestPreview Preview(const TrackPanelMouseState &state, AudacityProject *pProject) override
void SetCursor(wxCursor cursor)
std::pair< double, double > SnappedTimes(AudacityProject &project)
Result Cancel(AudacityProject *pProject) override
Result Release(const TrackPanelMouseEvent &event, AudacityProject *pProject, wxWindow *pParent) override
void Unsnap(bool use, AudacityProject *pProject)
SelectedRegion mOldSelectedRegion
double SnappedTime(AudacityProject &project, size_t ii)
bool Escape(AudacityProject *pProject) override
PlayRegionAdjustingHandle(AdornedRulerPanel *pParent, wxCoord xx, MenuChoice menuChoice, wxCursor cursor, size_t numGuides=1)
void SavePlayRegion(AudacityProject &project)
bool HasEscape(AudacityProject *pProject) const override
std::vector< UIHandlePtr > HitTest(const TrackPanelMouseState &state, const AudacityProject *pProject) override
std::weak_ptr< NewPlayRegionHandle > mNewPlayRegionHolder
QPCell(AdornedRulerPanel *parent)
std::weak_ptr< PlayheadHandle > mPlayheadHolder
std::shared_ptr< TrackPanelCell > ContextMenuDelegate() override
std::weak_ptr< ResizePlayRegionHandle > mResizePlayRegionHolder
std::weak_ptr< MovePlayRegionHandle > mMovePlayRegionHolder
ResizePlayRegionHandle(AdornedRulerPanel *pParent, wxCoord xx, bool hitLeft)
void DoStartAdjust(AudacityProject &project, double time) override
void DoAdjust(AudacityProject &project) override
std::shared_ptr< TrackPanelCell > ContextMenuDelegate() override
ScrubbingCell(AdornedRulerPanel *parent)
std::weak_ptr< ScrubbingHandle > mHolder
std::vector< UIHandlePtr > HitTest(const TrackPanelMouseState &state, const AudacityProject *pProject) override
Result Cancel(AudacityProject *pProject) override
ScrubbingHandle(AdornedRulerPanel *pParent, wxCoord xx)
Result Drag(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
HitTestPreview Preview(const TrackPanelMouseState &state, AudacityProject *pProject) override
Result Click(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
Result Release(const TrackPanelMouseEvent &event, AudacityProject *pProject, wxWindow *pParent) override
AdornedRulerPanel * GetRuler() const
TrackPanelGuidelineOverlay & mPartner
std::pair< wxRect, bool > DoGetRectangle(wxSize size) override
void Draw(OverlayPanel &panel, wxDC &dc) override
unsigned SequenceNumber() const override
This number determines an ordering of overlays, so that those with higher numbers overpaint those wit...
ScrubbingRulerOverlay(TrackPanelGuidelineOverlay &partner)
void Draw(OverlayPanel &panel, wxDC &dc) override
friend ScrubbingRulerOverlay
TrackPanelGuidelineOverlay(AudacityProject *project)
std::shared_ptr< ScrubbingRulerOverlay > mPartner
std::pair< wxRect, bool > DoGetRectangle(wxSize size) override
AudacityProject * mProject
unsigned SequenceNumber() const override
This number determines an ordering of overlays, so that those with higher numbers overpaint those wit...
This is an Audacity Specific ruler panel which additionally has border, selection markers,...
void OnSelectionChange(Observer::Message)
void UpdatePrefs() override
wxRect PlayRegionRectangle() const
void OnPaint(wxPaintEvent &evt)
double mQuickPlayOffset[MAX_GUIDES]
void SetTimeDisplayMode(TimeDisplayMode rulerType)
void OnAudioStartStop(AudioIOEvent)
std::shared_ptr< ScrubbingCell > mScrubbingCell
Observer::Subscription mAudioIOSubscription
void OnTogglePinnedState(wxCommandEvent &event)
void DoSelectionChange(const SelectedRegion &selectedRegion)
void SetPlayRegion(double playRegionStart, double playRegionEnd)
void ShowContextMenu(MenuChoice choice, const wxPoint *pPosition)
PlayRegion mOldPlayRegion
wxRect RegionRectangle(double t0, double t1) const
void SetFocusFromKbd() override
void OnSetPlayRegionToSelection(wxCommandEvent &evt)
void DoDrawOverlap(wxDC *dc, const wxRect &rect)
void OnSize(wxSizeEvent &evt)
void OnTimelineFormatChange(wxCommandEvent &evt)
AudacityProject *const mProject
void DoDrawScrubIndicator(wxDC *dc, wxCoord xx, int width, bool scrub, bool seek)
void GetMaxSize(wxCoord *width, wxCoord *height)
void OnPinnedButton(wxCommandEvent &event)
void UpdateStatusMessage(const TranslatableString &) override
void OnClearPlayRegion(wxCommandEvent &evt)
wxRect SelectedRegionRectangle() const
void OnIdle(wxIdleEvent &evt)
void ShowScrubMenu(const wxPoint &pos)
bool IsWithinMarker(int mousePosX, double markerTime)
void DoDrawMarks(wxDC *dc, bool)
std::shared_ptr< TrackPanelGuidelineOverlay > mOverlay
bool mLastPlayRegionActive
void OnTogglePlayRegion(wxCommandEvent &evt)
static TempAllowFocus TemporarilyAllowFocus()
std::unique_ptr< bool, Resetter > TempAllowFocus
bool mPlayRegionDragsSelection
std::shared_ptr< TrackPanelCell > GetFocusedCell() override
void DoDrawPlayRegion(wxDC *dc, const wxRect &rectP, const wxRect &rectL, const wxRect &rectR)
void OnLeave(wxMouseEvent &evt)
std::pair< double, double > mLastDrawnPlayRegion
void DoDrawSelection(wxDC *dc, const wxRect &rectS, const wxRect &rectL, const wxRect &rectR)
static void DragSelection(AudacityProject &project)
void Refresh(bool eraseBackground=true, const wxRect *rect=(const wxRect *) NULL) override
static bool s_AcceptsFocus
void SetLeftOffset(int offset)
void OnAutoScroll(wxCommandEvent &evt)
void HandleQPClick(wxMouseEvent &event, wxCoord mousePosX)
std::shared_ptr< TrackPanelNode > Root() override
Observer::Subscription mPlayRegionSubscription
void HandleQPRelease(wxMouseEvent &event)
int Time2Pos(double t, bool ignoreFisheye=false) const
void ShowMenu(const wxPoint &pos)
AudacityProject * GetProject() const override
Observer::Subscription mRulerInvalidatedSubscription
TimeDisplayMode mTimeDisplayMode
bool ShowingScrubRuler() const
void UpdateButtonStates()
void HandleQPDrag(wxMouseEvent &event, wxCoord mousePosX)
void StartQPPlay(bool newDefault, bool cutPreview, const double *pStartTime=nullptr)
Observer::Subscription mThemeChangeSubscription
MouseEventState mMouseEventState
bool mIsSnapped[MAX_GUIDES]
TimeDisplayMode GetTimeDisplayMode() const
double mQuickPlayPos[MAX_GUIDES]
void DoDrawBackground(wxDC *dc)
std::shared_ptr< QPCell > mQPCell
void OnSyncSelToQuickPlay(wxCommandEvent &evt)
void UpdateQuickPlayPos(wxCoord &mousePosX)
void DoDrawPlayRegionLimits(wxDC *dc, const wxRect &rect)
static AdornedRulerPanel & Get(AudacityProject &project)
AdornedRulerPanel(AudacityProject *project, wxWindow *parent, wxWindowID id, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, ViewInfo *viewinfo=NULL)
static constexpr size_t MAX_GUIDES
void SetNumGuides(size_t nn)
void HandleSnapping(size_t index)
double mLeftDownClickUnsnapped
void DoDrawEdge(wxDC *dc)
void ProcessUIHandleResult(TrackPanelCell *pClickedTrack, TrackPanelCell *pLatestCell, unsigned refreshResult) override
double Pos2Time(int p, bool ignoreFisheye=false) const
@ mesSelectingPlayRegionRange
@ mesDraggingPlayRegionStart
@ mesDraggingPlayRegionEnd
@ mesSelectingPlayRegionClick
SelectedRegion mLastDrawnSelectedRegion
static void Destroy(AudacityProject &project)
void SetFocusedCell() override
void OnThemeChange(struct ThemeChangeMessage)
double mQuickPlayPosUnsnapped[MAX_GUIDES]
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
static AudioIOBase * Get()
wxDC & GetBackingDCForRepaint()
void OnSize(wxSizeEvent &event)
void DisplayBitmap(wxDC &dc)
void Popup(const BasicUI::WindowPlacement &window, const Point &pos={})
Display the menu at pos, invoke at most one action, then hide it.
Formerly part of TrackPanel, this abstract base class has no special knowledge of Track objects and i...
bool CancelDragging(bool escaping)
void HandleCursorForPresentMouseState(bool doHit=true)
Subclass * Find(const RegisteredFactory &key)
Get a (bare) pointer to an attachment, or null, down-cast it to Subclass *; will not create on demand...
Subclass & Get(const RegisteredFactory &key)
Get reference to an attachment, creating on demand if not present, down-cast it to Subclass.
void Assign(const RegisteredFactory &key, ReplacementPointer &&replacement)
Reassign Site's pointer to ClientData.
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
AudacityProject & project
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
void SetData(const ZoomInfo *pZoomInfo=nullptr, int leftOffset=0)
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
void DrawOverlays(bool repaint_all, wxDC *pDC=nullptr)
void AddOverlay(const std::weak_ptr< Overlay > &pOverlay)
void SetStart(double start)
void SetTimes(double start, double end)
static void Broadcast(int id=0)
Call this static function to notify all PrefsListener objects.
bool IsAudioActive() const
static AudioIOStartStreamOptions GetDefaultOptions(AudacityProject &project, bool newDefaults=false)
Invoke the global hook, supplying a default argument.
static ProjectAudioIO & Get(AudacityProject &project)
void Stop(bool stopStream=true)
static ProjectAudioManager & Get(AudacityProject &project)
static ProjectStatus & Get(AudacityProject &project)
void Set(const TranslatableString &msg, StatusBarField field=MainStatusBarField())
static ProjectWindow & Get(AudacityProject &project)
Generates classes whose instances register items at construction.
void SetTickColour(const wxColour &colour)
void Draw(wxDC &dc) const
void SetTickLengths(const TickLengths &tLengths)
void SetLabelEdges(bool labelEdges)
void GetMaxSize(wxCoord *width, wxCoord *height)
void SetBounds(int left, int top, int right, int bottom)
void SetRange(double min, double max)
static bool ShouldScrubPinned()
static Scrubber & Get(AudacityProject &project)
Defines a selected portion of a project.
wxColour & Colour(int iIndex)
wxSize ImageSize(int iIndex)
bool WriteEnum(TimeDisplayMode value)
double GetEndTime() const
Return the greatest end time of the tracks, or 0 when no tracks.
double GetStartTime() const
Return the least start time of the tracks, or 0 when no tracks.
static TrackList & Get(AudacityProject &project)
std::pair< Axis, Refinement > Subdivision
std::vector< Child > Refinement
static void SetPinnedHeadPreference(bool value, bool flush=false)
static bool GetPinnedHeadPreference()
static double GetPinnedHeadPositionPreference()
static void SetPinnedHeadPositionPreference(double value, bool flush=false)
Holds a msgid for the translation catalog; may also bind format arguments.
wxString Translation() const
TranslatableString Stripped(unsigned options=MenuCodes) const
non-mutating, constructs another TranslatableString object
Short-lived drawing and event-handling object associated with a TrackPanelCell.
virtual HitTestPreview Preview(const TrackPanelMouseState &state, AudacityProject *pProject)=0
bool bUpdateTrackIndicator
NotifyingSelectedRegion selectedRegion
static int UpdateScrollPrefsID()
static ViewInfo & Get(AudacityProject &project)
double PositionToTime(int64 position, int64 origin=0, bool ignoreFisheye=false) const
int64 TimeToPosition(double time, int64 origin=0, bool ignoreFisheye=false) const
STM: Converts a project time to screen x position.
Result Cancel(AudacityProject *) override
AdornedRulerPanel * mpParent
std::shared_ptr< const Track > FindTrack() const override
static UIHandle::Result NeedChangeHighlight(const PlayheadHandle &oldState, const PlayheadHandle &newState)
HitTestPreview Preview(const TrackPanelMouseState &, AudacityProject *) override
PlayheadHandle(AdornedRulerPanel &parent, wxCoord xx)
static std::shared_ptr< PlayheadHandle > HitTest(const AudacityProject *pProject, AdornedRulerPanel &parent, wxCoord xx)
void Enter(bool, AudacityProject *) override
Result Click(const TrackPanelMouseEvent &event, AudacityProject *) override
Result Release(const TrackPanelMouseEvent &event, AudacityProject *pProject, wxWindow *) override
Result Drag(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
virtual bool Flush() noexcept=0
virtual bool Write(const wxString &key, bool value)=0
virtual bool Read(const wxString &key, bool *value) const =0
void SetLabel(const TranslatableString &label)
void SetFocus(const WindowPlacement &focus)
Set the window that accepts keyboard input.
void CallAfter(Action action)
Schedule an action to be done later, and in the main thread.
bool Begin(const FilePath &dataDir)
void Release(wxWindow *handler)
Namespace containing an enum 'what to do on a refresh?'.
void SetPlayRegionToSelection(AudacityProject &project)
void ActivatePlayRegion(AudacityProject &project)
void InactivatePlayRegion(AudacityProject &project)
void ClearPlayRegion(AudacityProject &project)
void TogglePlayRegion(AudacityProject &project)
double GetPlayHeadFraction(const AudacityProject *pProject, wxCoord xx)
void OnTogglePinnedHead(const CommandContext &context)
const TranslatableString ScrubbingMessage(const Scrubber &scrubber, bool clicked)
const TranslatableString StartScrubbingMessage(const Scrubber &)
wxCoord GetPlayHeadX(const AudacityProject *pProject)
const TranslatableString ContinueScrubbingMessage(const Scrubber &scrubber, bool clicked)
AttachedWindows::RegisteredFactory sKey
const char * end(const char *str) noexcept
MainGroup(const AdornedRulerPanel &ruler)
Subdivision Children(const wxRect &) override
const AdornedRulerPanel & mRuler
const AdornedRulerPanel & mRuler
Subgroup(const AdornedRulerPanel &ruler)
Subdivision Children(const wxRect &) override
enum AudioIOEvent::Type type
Default message type for Publisher.
std::optional< PreferredSystemAppearance > appearance