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 6
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 );
1402 wxPoint position( 1, 0 );
1407 pGrabber->SetPosition( position );
1416 bmpRecoloredUpSmall, bmpRecoloredDownSmall,
1417 bmpRecoloredUpHiliteSmall, bmpRecoloredHiliteSmall,
1418 bmpCogwheel, bmpCogwheel, bmpCogwheel,
1422 position.x +=
size.GetWidth();
1437 if(scrubber.Seeks())
1442 return XO(
"Click or drag to begin Seek");
1448 return XO(
"Click or drag to begin Scrub");
1454 return XO(
"Click & move to Scrub. Click & drag to Seek.");
1459 const Scrubber &scrubber,
bool clicked)
1462 if(scrubber.
Seeks())
1467 return XO(
"Move to Seek");
1473 return XO(
"Move to Scrub");
1480 return XO(
"Drag to Seek. Release to stop seeking.");
1483 return XO(
"Drag to Seek. Release and move to Scrub.");
1486 return XO(
"Move to Scrub. Drag to Seek.");
1512 const auto &selectedRegion = viewInfo.selectedRegion;
1513 const auto &playRegion = viewInfo.playRegion;
1518 playRegion.GetLastActiveStart(), playRegion.GetLastActiveEnd() }
1556 const auto &playRegion = viewInfo.playRegion;
1557 const auto playRegionBounds = std::pair{
1558 playRegion.GetLastActiveStart(), playRegion.GetLastActiveEnd() };
1574 rectO = rectP.Intersect(rectS);
1577 const auto top = rectP.GetTop(),
1578 bottom = rectP.GetBottom();
1580 wxPoint{ 0, top }, wxPoint{ this->GetSize().GetWidth() - 1, bottom } };
1582 if (!rectO.IsEmpty()) {
1583 rectR = { wxPoint{ rectO.GetRight() + 1, top }, rectL.GetBottomRight() };
1584 rectL = { rectL.GetTopLeft(), wxPoint{ rectO.GetLeft() - 1, bottom } };
1602 dc.DestroyClippingRegion();
1608 mOuter = GetClientRect();
1659 auto bottom = &inner;
1667 top = &scrubZone, topHeight = scrubHeight;
1669 auto qpHeight = scrubZone.height - scrubHeight;
1670 bottom = &scrubZone, topHeight = qpHeight;
1676 top->height = topHeight;
1677 bottom->height -= topHeight;
1678 bottom->y += topHeight;
1723 int pixelPos =
Time2Pos(markerTime);
1727 return mousePosX >= boundLeft && mousePosX < boundRight;
1730#ifdef QUICK_PLAY_HANDLE
1731auto AdornedRulerPanel::QPHandle::Click(
1734 auto result = CommonRulerHandle::Click(event, pProject);
1736 if (mClicked == Button::Left) {
1741 if(scrubber.HasMark()) {
1749 const auto &playRegion = viewInfo.playRegion;
1750 mParent->mOldPlayRegion = playRegion;
1755 mParent->HandleQPClick( event.event, mX );
1756 mParent->HandleQPDrag( event.event, mX );
1776 if (isWithinStart || isWithinEnd) {
1800auto AdornedRulerPanel::QPHandle::Drag(
1803 auto result = CommonRulerHandle::Drag(event, pProject);
1805 if (mClicked == Button::Left) {
1807 mX =
event.event.m_x;
1808 mParent->UpdateQuickPlayPos( mX );
1809 mParent->HandleQPDrag( event.event, mX );
1818 bool isWithinClick =
1825 auto &playRegion = viewInfo.playRegion;
1831 if (isWithinStart || isWithinEnd) {
1858 if (isWithinStart) {
1878 if (isWithinClick) {
1903 mParent->SetNumGuides(1);
1912#ifdef QUICK_PLAY_HANDLE
1913auto AdornedRulerPanel::QPHandle::Preview(
1917 mParent->SetNumGuides(1);
1921 if (!mParent->mQuickPlayEnabled)
1922 tooltip =
XO(
"Quick-Play disabled");
1924 tooltip =
XO(
"Quick-Play enabled");
1930 const bool scrubbing = scrubber.HasMark();
1938 static wxCursor cursorHand{ wxCURSOR_HAND };
1939 static wxCursor cursorSizeWE{ wxCURSOR_SIZEWE };
1941 bool showArrows =
false;
1944 (mClicked == Button::Left)
1945 || mParent->IsWithinMarker(
1946 state.state.m_x, mParent->mOldPlayRegion.GetStart())
1947 || mParent->IsWithinMarker(
1948 state.state.m_x, mParent->mOldPlayRegion.GetEnd());
1952 showArrows ? &cursorSizeWE : &cursorHand,
1966 auto saveMe = mParent->mQPCell->mHolder.lock();
1970 if (mClicked == Button::Left) {
1972 mParent->HandleQPRelease( event.event );
1975 const auto &playRegion = viewInfo.playRegion;
1976 mParent->mOldPlayRegion = playRegion;
1986 auto &playRegion = viewInfo.playRegion;
1991 const auto &selectedRegion = viewInfo.selectedRegion;
1992 const double sel0 = selectedRegion.t0();
1993 const double sel1 = selectedRegion.t1();
1997 if (evt.ShiftDown() && playRegion.Empty()) {
2001 if (((sel1 < t0) || (sel0 > t1)) &&
2002 ((playRegion.GetStart() < t0) || (playRegion.GetStart() > t1))) {
2007 else if (playRegion.GetStart() >= t1) {
2013 playRegion.GetEnd() - playRegion.GetStart() > 0.0 &&
2014 playRegion.GetEnd() < t0
2023 auto cleanup =
finally( [&] {
2026 SetPlayRegion(mOldPlayRegion.GetStart(), mOldPlayRegion.GetEnd());
2027 SelectUtilities::ActivatePlayRegion(*mProject);
2029 mOldPlayRegion.SetActive( false );
2038 auto result = CommonRulerHandle::Cancel(pProject);
2040 if (mClicked == Button::Left) {
2043 mParent->mMouseEventState = mesNone;
2044 mParent->SetPlayRegion(
2045 mParent->mOldPlayRegion.GetStart(), mParent->mOldPlayRegion.GetEnd());
2046 if (mParent->mOldPlayRegion.Active()) {
2050 mParent->mOldPlayRegion.SetActive(
false );
2060 bool newDefault,
bool cutPreview,
const double *pStartTime)
2065 const auto &playRegion = viewInfo.playRegion;
2066 const auto &selectedRegion = viewInfo.selectedRegion;
2067 const double sel0 = selectedRegion.t0();
2068 const double sel1 = selectedRegion.t1();
2071 bool startPlaying =
true;
2074 bool loopEnabled =
true;
2075 auto oldStart = std::max(0.0, playRegion.GetStart());
2076 double start = oldStart,
end = 0;
2078 if (playRegion.Empty()) {
2080 if (oldStart > sel0 && oldStart < sel1) {
2091 end = std::max(start, playRegion.GetEnd());
2094 loopEnabled = ((
end - start) > 0.001)? true :
false;
2096 newDefault = (loopEnabled && newDefault);
2103 options.pStartTime.emplace(*pStartTime);
2106 options.envelope =
nullptr;
2116 projectAudioManager.Stop();
2133void AdornedRulerPanel::OnToggleScrubRulerFromMenu(wxCommandEvent&)
2136 scrubber.OnToggleScrubRuler(*
mProject);
2143 const auto oldSize = GetSize();
2145 if (
size != oldSize ) {
2148 PostSizeEventToParent();
2157 auto pCellularPanel =
2159 if ( !pCellularPanel ) {
2163 pCellularPanel->DrawOverlays(
false );
2169 auto common = [
this](
2180 timelineOptionsButton->
PopUp();
2183 const auto label =
XO(
"Timeline Options");
2184 common(*timelineOptionsButton,
wxT(
"PinnedHead"),
label);
2207 auto width = viewInfo.GetTracksUsableWidth();
2208 mousePosX = std::max(mousePosX, viewInfo.GetLeftOffset());
2209 mousePosX =
std::min(mousePosX, viewInfo.GetLeftOffset() + width - 1);
2210 const auto time =
Pos2Time(mousePosX);
2224 const auto &playRegion = viewInfo.playRegion;
2229 _(
"Minutes and Seconds"));
2235 _(
"Beats and Measures"));
2239 rulerMenu.AppendSeparator();
2241 auto pDrag = rulerMenu.AppendCheckItem(
OnSyncQuickPlaySelID,
_(
"Setting a loop region also makes an audio selection"));
2243 pDrag->Enable(playRegion.Active());
2248 item->Check(playRegion.Active());
2259 _(
"Set Loop To Selection"));
2262 rulerMenu.AppendSeparator();
2264 rulerMenu.AppendCheckItem(
OnAutoScrollID,
_(
"Scroll view to playhead"))->
2279 PushEventHandler(&scrubber);
2280 auto cleanup =
finally([
this]{ PopEventHandler(); });
2283 scrubber.PopulatePopupMenu(rulerMenu);
2293 const auto &playRegion = viewInfo.playRegion;
2294 auto &selectedRegion = viewInfo.selectedRegion;
2295 selectedRegion.setT0(playRegion.GetStart(),
false);
2296 selectedRegion.setT1(playRegion.GetEnd(),
true);
2310 auto results = snapManager.Snap(
nullptr,
mQuickPlayPos[index],
false);
2317 int id =
event.GetId();
2370 position = *pPosition;
2373 auto rect = GetRect();
2381 position = { rect.GetLeft() + 38, rect.GetHeight()/2 + 1 };
2400 return clrTrackInfo;
2405 return clrTrackPanelText;
2415 return isActive ? clrRulerBackground : clrClipAffordanceInactiveBrush;
2433 dc->DrawRectangle(
mInner );
2440 ScrubRect.Inflate( 1,0 );
2441 dc->DrawRectangle(ScrubRect);
2453 dc->SetPen( *wxBLACK_PEN );
2463 const double hiddenMin =
Pos2Time(0,
true);
2488 const auto &playRegion = viewInfo.playRegion;
2489 const auto t0 = playRegion.GetLastActiveStart(),
2490 t1 = playRegion.GetLastActiveEnd();
2497 const auto &selectedRegion = viewInfo.selectedRegion;
2498 const auto t0 = selectedRegion.t0(), t1 = selectedRegion.t1();
2504 int p0 = -1, p1 = -1;
2513 const int left = p0, top =
mInner.y, right = p1, bottom =
mInner.GetBottom();
2514 return { wxPoint{left, top}, wxPoint{right, bottom} };
2518 wxDC * dc,
const wxRect &rectP,
const wxRect &rectL,
const wxRect &rectR)
2521 const auto& playRegion = viewInfo.playRegion;
2525 if (playRegion.IsLastActiveRegionClear())
2533 dc->DrawRectangle( rectP.Intersect(rectL) );
2534 dc->DrawRectangle( rectP.Intersect(rectR) );
2542 dc->SetPen( { edgeColour } );
2543 dc->SetBrush( { edgeColour } );
2545 constexpr int side = 7;
2546 constexpr int sideLessOne = side - 1;
2549 const auto left = rect.GetLeft(),
2550 right = rect.GetRight(),
2551 bottom = rect.GetBottom(),
2552 top = rect.GetTop();
2555 {left, bottom - sideLessOne},
2556 {left - sideLessOne, bottom},
2560 dc->DrawPolygon( 4, points );
2567 {right + sideLessOne, bottom},
2568 {right, bottom - sideLessOne},
2570 dc->DrawPolygon( 4, points );
2581 dc->SetPen( *wxTRANSPARENT_PEN );
2582 dc->DrawRectangle( rect );
2586 wxDC * dc,
const wxRect &rectS,
const wxRect &rectL,
const wxRect &rectR)
2590 dc->SetPen( *wxTRANSPARENT_PEN );
2591 dc->DrawRectangle( rectS.Intersect(rectL) );
2592 dc->DrawRectangle( rectS.Intersect(rectR) );
2611 wxDC * dc, wxCoord xx,
int width,
bool scrub,
bool seek)
2619 const int TriangleWidth = width * 3 / 8;
2624 : (
mInner.GetBottom() + 1) - 1 - height;
2628 tri[ 1 ].y = yy + height;
2629 tri[ 2 ].x = xx - TriangleWidth;
2630 tri[ 2 ].y = yy + height / 2;
2631 dc->DrawPolygon( 3, tri );
2633 tri[ 0 ].x -= TriangleWidth;
2634 tri[ 1 ].x -= TriangleWidth;
2635 tri[ 2 ].x -= TriangleWidth;
2636 dc->DrawPolygon( 3, tri );
2639 tri[ 2 ].x = xx + TriangleWidth;
2640 dc->DrawPolygon( 3, tri );
2643 tri[ 0 ].x += TriangleWidth;
2644 tri[ 1 ].x += TriangleWidth;
2645 tri[ 2 ].x += TriangleWidth;
2646 dc->DrawPolygon( 3, tri );
2650 const int IndicatorHalfWidth = width / 2;
2655 : (
mInner.GetBottom() + 1) - 1 - height;
2659 tri[ 1 ].y = yy + height;
2660 tri[ 2 ].x = xx - IndicatorHalfWidth;
2661 tri[ 2 ].y = yy + height / 2;
2662 dc->DrawPolygon( 3, tri );
2664 tri[ 2 ].x = xx + IndicatorHalfWidth;
2665 dc->DrawPolygon( 3, tri );
2670 double playRegionStart,
double playRegionEnd)
2679 auto &playRegion = viewInfo.playRegion;
2680 playRegion.SetTimes( playRegionStart, playRegionEnd );
2690 auto &playRegion = viewInfo.playRegion;
2704 s_AcceptsFocus =
true;
2712 for (
size_t ii =
mNumGuides; ii < nn; ++ii) {
2763 return scrubber.ShowsBar();
2770 return std::make_shared< MainGroup >( *
this );
2806 std::make_shared<TrackPanelGuidelineOverlay>(
mProject );
2807 auto pCellularPanel =
2809 if ( !pCellularPanel ) {
2813 pCellularPanel->AddOverlay(
mOverlay );
2829 if (scrubber.HasMark())
2830 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)
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 BevelTrackInfo(wxDC &dc, bool up, const wxRect &r, 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,...
The widget to the left of a ToolBar that allows it to be dragged around to NEW positions.
void SetAsSpacer(bool bIsSpacer)
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