1#include "../AdornedRulerPanel.h"
3#include "../CommonCommandFlags.h"
7#include "../ProjectAudioManager.h"
11#include "../ProjectSelectionManager.h"
12#include "../ProjectSettings.h"
13#include "../ProjectWindow.h"
14#include "../ProjectWindows.h"
15#include "../SelectUtilities.h"
17#include "../TrackPanel.h"
19#include "../LabelTrack.h"
20#include "../commands/CommandContext.h"
21#include "../commands/CommandManager.h"
22#include "../toolbars/ControlToolBar.h"
23#include "../tracks/ui/SelectHandle.h"
24#include "../tracks/labeltrack/ui/LabelTrackView.h"
25#include "../tracks/playabletrack/wavetrack/ui/WaveTrackView.h"
37 auto windowSize = size_t(std::max(1.0, rate / 100));
38 Floats dist{ windowSize,
true };
41 for (
auto one : tracks.Selected<
const WaveTrack >()) {
42 auto oneWindowSize = size_t(std::max(1.0, one->GetRate() / 100));
43 Floats oneDist{ oneWindowSize };
44 auto s = one->TimeToLongSamples(t0);
47 one->GetFloats(oneDist.get(),
48 s - (
int)oneWindowSize/2, oneWindowSize,
fillTwo);
53 for(
size_t i=0; i<oneWindowSize; i++){
54 float fDist = fabs( oneDist[i]);
55 if( prev * oneDist[i] > 0 )
66 for(
size_t i = 0; i < windowSize; i++) {
68 if (windowSize != oneWindowSize)
69 j = i * (oneWindowSize-1) / (windowSize-1);
73 dist[i] += oneDist[j];
77 0.1 * (abs(
int(i) -
int(windowSize/2))) /
float(windowSize/2);
85 for(
size_t i=0; i<windowSize; i++) {
93 if(( nTracks == 1 ) && (
min > (0.2*nTracks) ))
96 if(( nTracks > 1 ) && (
min > (0.6*nTracks) ))
99 return t0 + (argmin - (int)windowSize/2) / rate;
107 auto &project = context.
project;
108 auto evt = context.
pEvt;
109 bool bKeyUp = (evt) && evt->GetEventType() == wxEVT_KEY_UP;
138 wxLongLong mLastSelectionAdjustment { ::wxGetUTCTimeMillis() };
139 double mSeekShort{ 0.0 };
140 double mSeekLong{ 0.0 };
146#ifdef EXPERIMENTAL_IMPROVED_SEEKING
147 if (gAudioIO->GetLastPlaybackTime() < lastSelectionAdjustment) {
154 lastSelectionAdjustment = ::wxGetUTCTimeMillis();
156 gAudioIO->SeekStream(seekStep);
170 auto result = projectSnap.SingleStep(t, minPix >= 0).time;
173 std::abs(viewInfo.TimeToPosition(result) - viewInfo.TimeToPosition(t)) >=
178 result = viewInfo.OffsetTimeByPixels(t, minPix);
179 return projectSnap.SnapTime(result).time;
192 return viewInfo.OffsetTimeByPixels(t, (
int)offset);
194 return GridMove(project, t, (
int)offset);
209 auto snapMode =
settings.GetSnapMode();
210 const double t0 = viewInfo.selectedRegion.t0();
211 const double end = std::max(
213 viewInfo.GetScreenEndTime());
217 if( viewInfo.selectedRegion.isPoint() )
220 t0, seekStep, timeUnit, snapMode);
222 newT = std::max(0.0, newT);
225 viewInfo.selectedRegion.setT0(
228 viewInfo.selectedRegion.collapseToT0();
231 trackPanel.DrawOverlays(
false);
232 ruler.DrawOverlays(
false);
238 viewInfo.selectedRegion.collapseToT0();
240 viewInfo.selectedRegion.collapseToT1();
241 trackPanel.Refresh(
false);
245 window.ScrollIntoView(viewInfo.selectedRegion.t1());
264 auto snapMode =
settings.GetSnapMode();
265 const double t0 = viewInfo.selectedRegion.t0();
266 const double t1 = viewInfo.selectedRegion.t1();
267 const double end = std::max(
269 viewInfo.GetScreenEndTime());
276 bMoveT0 ? t0 : t1, seekStep, timeUnit, snapMode);
278 newT = std::max( 0.0, newT );
282 newT = bMoveT0 ?
std::min( t1, newT ) : std::max( t0, newT );
286 viewInfo.selectedRegion.setT0( newT );
288 viewInfo.selectedRegion.setT1( newT );
291 window.ScrollIntoView(newT);
318 const wxLongLong curtime = ::wxGetUTCTimeMillis();
319 enum { MIN_INTERVAL = 50 };
326 enum { LARGER_MULTIPLIER = 4 };
327 const double seekStep = (fast ? LARGER_MULTIPLIER : 1.0) * direction;
335 wxLongLong &lastSelectionAdjustment)
342 lastSelectionAdjustment = ::wxGetUTCTimeMillis();
360 wxLongLong curtime = ::wxGetUTCTimeMillis();
370 bool bMoveT0 = (step < 0 );
375 double indicator = gAudioIO->GetStreamTime();
377 viewInfo.selectedRegion.setT0(indicator,
false);
379 viewInfo.selectedRegion.setT1(indicator);
385 const double t0 = viewInfo.selectedRegion.t0();
386 const double t1 = viewInfo.selectedRegion.t1();
387 const double end = std::max(
389 viewInfo.GetScreenEndTime());
391 double newT = viewInfo.OffsetTimeByPixels( bMoveT0 ? t0 : t1, pixels);
393 newT = std::max( 0.0, newT );
401 viewInfo.selectedRegion.setT0( newT );
403 viewInfo.selectedRegion.setT1( newT );
406 window.ScrollIntoView(newT);
429 for (
auto lt : tracks.Selected<
LabelTrack >()) {
431 if (view.SelectAllText(context.
project)) {
432 trackPanel.Refresh(
false);
439 for (
auto wt : tracks.Any<
WaveTrack>()) {
441 if (view.SelectAllText(context.
project)) {
442 trackPanel.Refresh(
false);
452 auto &project = context.
project;
462 auto &project = context.
project;
468 auto &project = context.
project;
471 bool selected =
false;
474 t->SetSelected(
true);
485 true,
true,
XO(
"Set Left Selection Boundary"));
491 false,
true,
XO(
"Set Right Selection Boundary"));
496 auto &project = context.
project;
500 double kWayOverToRight = std::numeric_limits<double>::max();
502 auto range = tracks.Selected();
509 (kWayOverToRight * (1 - std::numeric_limits<double>::epsilon()) ))
512 selectedRegion.setT0(minOffset);
519 auto &project = context.
project;
523 double kWayOverToLeft = std::numeric_limits<double>::lowest();
525 auto range = tracks.Selected();
532 (kWayOverToLeft * (1 - std::numeric_limits<double>::epsilon()) ))
535 selectedRegion.setT1(maxEndOffset);
542 auto &project = context.
project;
546 auto range = tracks.Selected();
550 if( maxEndOffset < minOffset)
553 viewInfo.selectedRegion.setTimes( minOffset, maxEndOffset );
562 auto &project = context.
project;
570 auto &project = context.
project;
579 window.ScrollIntoView(selectedRegion.t0());
590 auto &project = context.
project;
596 double cursorPositionCurrent = isAudioActive
597 ? gAudioIO->GetStreamTime()
598 : selectedRegion.t0();
599 selectedRegion.setTimes(
609 auto &project = context.
project;
615 isAudioActive ? gAudioIO->GetStreamTime() : selectedRegion.t0();
621 auto &project = context.
project;
625 if (selectedRegion.isPoint())
626 selectedRegion.setTimes(t0, t0);
631 selectedRegion.setTimes(t0, t1);
639 auto &project = context.
project;
645 auto &project = context.
project;
651 auto &project = context.
project;
657 auto &project = context.
project;
665 auto &project = context.
project;
667 window.SkipEnd(
true);
714 auto &project = context.
project;
718 selectedRegion.collapseToT0();
720 window.ScrollIntoView(selectedRegion.t0());
725 auto &project = context.
project;
729 selectedRegion.collapseToT1();
731 window.ScrollIntoView(selectedRegion.t1());
736 auto &project = context.
project;
741 double kWayOverToRight = std::numeric_limits<double>::max();
744 if (trackRange.empty())
752 (kWayOverToRight * (1 - std::numeric_limits<double>::epsilon()) ))
755 selectedRegion.setTimes(minOffset, minOffset);
757 window.ScrollIntoView(selectedRegion.t0());
762 auto &project = context.
project;
767 double kWayOverToLeft = std::numeric_limits<double>::lowest();
770 if (trackRange.empty())
778 (kWayOverToLeft * (1 - std::numeric_limits<double>::epsilon()) ))
781 selectedRegion.setTimes(maxEndOffset, maxEndOffset);
783 window.ScrollIntoView(selectedRegion.t1());
788 auto &project = context.
project;
792 controlToolBar.OnRewind(evt);
798 auto &project = context.
project;
802 controlToolBar.OnFF(evt);
846 auto &project = context.
project;
852 auto &project = context.
project;
858 auto &project = context.
project;
864 auto &project = context.
project;
872 auto &project = context.
project;
897 return std::make_unique< SelectActions::Handler >(); } };
905#define FN(X) (& SelectActions::Handler :: X)
928 FN(OnSelectAllTracks),
930 wxT(
"Ctrl+Shift+K") ),
931 Command(
wxT(
"SelSyncLockTracks"),
XXO(
"In All &Sync-Locked Tracks"),
932 FN(OnSelectSyncLockSel),
934 Options{
wxT(
"Ctrl+Shift+Y"),
XO(
"Select Sync-Locked") } )
941 Command(
wxT(
"SetLeftSelection"),
XXO(
"&Left at Playback Position"),
943 Options{
wxT(
"["),
XO(
"Set Selection Left at Play Position") } ),
944 Command(
wxT(
"SetRightSelection"),
XXO(
"&Right at Playback Position"),
946 Options{
wxT(
"]"),
XO(
"Set Selection Right at Play Position") } ),
947 Command(
wxT(
"SelTrackStartToCursor"),
XXO(
"Track &Start to Cursor"),
949 Options{
wxT(
"Shift+J"),
XO(
"Select Track Start to Cursor") } ),
950 Command(
wxT(
"SelCursorToTrackEnd"),
XXO(
"Cursor to Track &End"),
952 Options{
wxT(
"Shift+K"),
XO(
"Select Cursor to Track End") } ),
953 Command(
wxT(
"SelTrackStartToEnd"),
XXO(
"Track Start to En&d"),
978 XXO(
"Cursor to Stored &Cursor Position"),
982 Command(
wxT(
"StoreCursorPosition"),
XXO(
"Store Cursor Pos&ition"),
983 FN(OnCursorPositionStore),
1013 Command(
wxT(
"SnapToPrior"),
XXO(
"Snap-To &Prior"),
FN(OnSnapToPrior),
1015 Command(
wxT(
"SelStart"),
XXO(
"Selection to &Start"),
FN(OnSelToStart),
1020 FN(OnSelExtendLeft),
1022 Options{
wxT(
"Shift+Left") }.WantKeyUp().AllowDup() ),
1023 Command(
wxT(
"SelExtRight"),
XXO(
"Selection Extend &Right"),
1024 FN(OnSelExtendRight),
1026 Options{
wxT(
"Shift+Right") }.WantKeyUp().AllowDup() ),
1027 Command(
wxT(
"SelSetExtLeft"),
XXO(
"Set (or Extend) Le&ft Selection"),
1028 FN(OnSelSetExtendLeft),
1030 Command(
wxT(
"SelSetExtRight"),
XXO(
"Set (or Extend) Rig&ht Selection"),
1031 FN(OnSelSetExtendRight),
1033 Command(
wxT(
"SelCntrLeft"),
XXO(
"Selection Contract L&eft"),
1034 FN(OnSelContractLeft),
1036 Options{
wxT(
"Ctrl+Shift+Right") }.WantKeyUp() ),
1037 Command(
wxT(
"SelCntrRight"),
XXO(
"Selection Contract R&ight"),
1038 FN(OnSelContractRight),
1040 Options{
wxT(
"Ctrl+Shift+Left") }.WantKeyUp() )
1046 wxT(
"Optional/Extra/Part1"),
1066 FN(OnCursorSelStart),
1075 FN(OnCursorTrackStart),
1079 FN(OnCursorTrackEnd),
1086 Options{
wxT(
"Home"),
XO(
"Cursor to Project Start") } ),
1095 wxT(
"Transport/Basic"),
1107 Options{
wxT(
"Left") }.WantKeyUp().AllowDup() ),
1110 Options{
wxT(
"Right") }.WantKeyUp().AllowDup() ),
1111 Command(
wxT(
"CursorShortJumpLeft"),
XXO(
"Cursor Sh&ort Jump Left"),
1112 FN(OnCursorShortJumpLeft),
1114 Command(
wxT(
"CursorShortJumpRight"),
XXO(
"Cursor Shor&t Jump Right"),
1115 FN(OnCursorShortJumpRight),
1117 Command(
wxT(
"CursorLongJumpLeft"),
XXO(
"Cursor Long J&ump Left"),
1118 FN(OnCursorLongJumpLeft),
1120 Command(
wxT(
"CursorLongJumpRight"),
XXO(
"Cursor Long Ju&mp Right"),
1121 FN(OnCursorLongJumpRight),
1128 wxT(
"Optional/Extra/Part2"),
1138 Command(
wxT(
"SeekLeftShort"),
XXO(
"Short Seek &Left During Playback"),
1142 XXO(
"Short Seek &Right During Playback"),
FN(OnSeekRightShort),
1145 Command(
wxT(
"SeekLeftLong"),
XXO(
"Long Seek Le&ft During Playback"),
1148 Command(
wxT(
"SeekRightLong"),
XXO(
"Long Seek Rig&ht During Playback"),
1156 wxT(
"Optional/Extra/Part1"),
AttachedItem sAttachment1
AttachedItem sAttachment2
constexpr CommandFlag AlwaysEnabledFlag
wxEvtHandler CommandHandlerObject
const ReservedCommandFlag & AudioIOBusyFlag()
const ReservedCommandFlag & AudioIONotBusyFlag()
const ReservedCommandFlag & IsSyncLockedFlag()
const ReservedCommandFlag & TimeSelectedFlag()
const ReservedCommandFlag & EditableTracksSelectedFlag()
const ReservedCommandFlag & TracksExistFlag()
const ReservedCommandFlag & WaveTracksExistFlag()
const ReservedCommandFlag & WaveTracksSelectedFlag()
const ReservedCommandFlag & TrackPanelHasFocus()
XXO("&Cut/Copy/Paste Toolbar")
const ReservedCommandFlag & CanStopAudioStreamFlag()
an object holding per-project preferred sample rate
static Settings & settings()
static AdornedRulerPanel & Get(AudacityProject &project)
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Client code makes static instance from a factory of attachments; passes it to Get or Find as a retrie...
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
AudacityProject & project
A LabelTrack is a Track that holds labels (LabelStruct).
static LabelTrackView & Get(LabelTrack &)
A listener notified of changes in preferences.
bool IsAudioActive() const
static ProjectAudioIO & Get(AudacityProject &project)
void ModifyState(bool bWantsAutoSave)
static ProjectHistory & Get(AudacityProject &project)
static ProjectRate & Get(AudacityProject &project)
void SetSnapMode(SnapMode mode)
static ProjectSnap & Get(AudacityProject &project)
static ProjectWindow & Get(AudacityProject &project)
Defines a selected portion of a project.
static bool IsSyncLockSelected(const Track *pTrack)
virtual bool SupportsBasicEditing() const
Whether this track type implements cut-copy-paste; by default, true.
virtual double GetStartTime() const =0
virtual double GetOffset() const =0
virtual double GetEndTime() const =0
static TrackList & Get(AudacityProject &project)
static TrackPanel & Get(AudacityProject &project)
NotifyingSelectedRegion selectedRegion
static ViewInfo & Get(AudacityProject &project)
A Track that contains audio waveform data.
static WaveTrackView & Get(WaveTrack &track)
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
std::unique_ptr< IndirectItem > Indirect(const BaseItemSharedPtr &ptr)
A convenience function.
std::shared_ptr< BaseItem > BaseItemSharedPtr
void SelectNone(AudacityProject &project)
void DoSelectAll(AudacityProject &project)
void OnSetRegion(AudacityProject &project, bool left, bool selection, const TranslatableString &dialogTitle)
Adjust left or right of selection or play region.
void DoSelectTimeAndTracks(AudacityProject &project, bool bAllTime, bool bAllTracks)
CommandManager::Options Options
double GetRate(const Track &track)
A convenient default parameter for class template Site.
Options && LongName(const TranslatableString &value) &&
void OnSetLeftSelection(const CommandContext &context)
double mCursorPositionStored
void OnCursorLeft(const CommandContext &context)
void OnSnapToOff(const CommandContext &context)
void OnCursorRight(const CommandContext &context)
Handler & operator=(const Handler &) PROHIBITED
void OnSelExtendRight(const CommandContext &context)
void OnSelectionSave(const CommandContext &context)
void OnSkipEnd(const CommandContext &context)
void OnSelContractRight(const CommandContext &context)
void OnSelContractLeft(const CommandContext &context)
void OnSelectAll(const CommandContext &context)
SelectedRegion mRegionSave
void OnCursorLongJumpRight(const CommandContext &context)
void UpdatePrefs() override
void OnSeekRightShort(const CommandContext &context)
void OnSnapToNearest(const CommandContext &context)
void OnSelToStart(const CommandContext &context)
void OnCursorLongJumpLeft(const CommandContext &context)
void OnSeekLeftShort(const CommandContext &context)
void OnSelectAllTime(const CommandContext &context)
void OnSnapToPrior(const CommandContext &context)
void OnSelectTrackStartToEnd(const CommandContext &context)
void OnCursorTrackEnd(const CommandContext &context)
void OnZeroCrossing(const CommandContext &context)
void OnCursorShortJumpRight(const CommandContext &context)
void OnCursorShortJumpLeft(const CommandContext &context)
void OnCursorTrackStart(const CommandContext &context)
void OnSelectNone(const CommandContext &context)
void OnSelSetExtendLeft(const CommandContext &context)
void OnSelectCursorEnd(const CommandContext &context)
void OnSelectSyncLockSel(const CommandContext &context)
Handler(const Handler &) PROHIBITED
void OnSelectCursorStoredCursor(const CommandContext &context)
void OnSelToEnd(const CommandContext &context)
void OnSelSetExtendRight(const CommandContext &context)
void OnCursorSelStart(const CommandContext &context)
void OnSkipStart(const CommandContext &context)
void OnSelectStartCursor(const CommandContext &context)
void OnSelectionRestore(const CommandContext &context)
void OnSeekRightLong(const CommandContext &context)
void OnSelExtendLeft(const CommandContext &context)
void OnSelectAllTracks(const CommandContext &context)
void OnSetRightSelection(const CommandContext &context)
void OnSeekLeftLong(const CommandContext &context)
void OnCursorPositionStore(const CommandContext &context)
bool mCursorPositionHasBeenStored
void OnCursorSelEnd(const CommandContext &context)