Audacity 3.2.0
Classes | Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes | List of all members
LabelTrackShifter Class Referencefinal
Inheritance diagram for LabelTrackShifter:
[legend]
Collaboration diagram for LabelTrackShifter:
[legend]

Classes

struct  IntervalData
 

Public Member Functions

 LabelTrackShifter (LabelTrack &track, AudacityProject &project)
 
 ~LabelTrackShifter () override
 
TrackGetTrack () const override
 There is always an associated track. More...
 
HitTestResult HitTest (double time, const ViewInfo &viewInfo, HitTestParams *pParams) override
 Decide how shift behaves, based on the track that is clicked in. More...
 
void SelectInterval (const TrackInterval &interval) override
 Notifies the shifter that a region is selected, so it may update its fixed and moving intervals. More...
 
bool SyncLocks () override
 Whether unfixing of an interval should propagate to all overlapping intervals in the sync lock group. More...
 
bool MayMigrateTo (Track &otherTrack) override
 Whether intervals may migrate to the other track, not yet checking all placement constraints *‍/. More...
 
Intervals Detach () override
 Remove all moving intervals from the track, if possible. More...
 
bool AdjustFit (const Track &, const Intervals &, double &, double) override
 Test whether intervals can fit into another track, maybe adjusting the offset slightly. More...
 
bool Attach (Intervals intervals) override
 Put moving intervals into the track, which may have migrated from another. More...
 
void DoHorizontalOffset (double offset) override
 
- Public Member Functions inherited from TrackShifter
 TrackShifter ()
 
 TrackShifter (const TrackShifter &) PROHIBITED
 
TrackShifteroperator= (const TrackShifter &) PROHIBITED
 
virtual ~TrackShifter ()=0
 
virtual TrackGetTrack () const =0
 There is always an associated track. More...
 
virtual HitTestResult HitTest (double time, const ViewInfo &viewInfo, HitTestParams *pParams=nullptr)=0
 Decide how shift behaves, based on the track that is clicked in. More...
 
const IntervalsFixedIntervals () const
 Return special intervals of the track that will not move. More...
 
const IntervalsMovingIntervals () const
 Return special intervals of the track that may move. More...
 
void UnfixIntervals (std::function< bool(const TrackInterval &) > pred)
 Change intervals satisfying a predicate from fixed to moving. More...
 
void UnfixAll ()
 Change all intervals from fixed to moving. More...
 
virtual void SelectInterval (const TrackInterval &interval)
 Notifies the shifter that a region is selected, so it may update its fixed and moving intervals. More...
 
virtual bool SyncLocks ()=0
 Whether unfixing of an interval should propagate to all overlapping intervals in the sync lock group. More...
 
virtual double HintOffsetLarger (double desiredOffset)
 Given amount to shift by horizontally, maybe adjust it from zero to suggest minimum distance. More...
 
virtual double QuantizeOffset (double desiredOffset)
 Given amount to shift by horizontally, do any preferred rounding, before placement constraint checks. More...
 
virtual double AdjustOffsetSmaller (double desiredOffset)
 Given amount to shift by horizontally, maybe adjust it toward zero to meet placement constraints. More...
 
virtual bool MayMigrateTo (Track &otherTrack)
 Whether intervals may migrate to the other track, not yet checking all placement constraints *‍/. More...
 
virtual Intervals Detach ()
 Remove all moving intervals from the track, if possible. More...
 
virtual bool AdjustFit (const Track &otherTrack, const Intervals &intervals, double &desiredOffset, double tolerance)
 Test whether intervals can fit into another track, maybe adjusting the offset slightly. More...
 
virtual bool Attach (Intervals intervals)
 Put moving intervals into the track, which may have migrated from another. More...
 
virtual bool FinishMigration ()
 When dragging is done, do (once) the final steps of migration (which may be expensive) More...
 
virtual void DoHorizontalOffset (double offset)
 
virtual double AdjustT0 (double t0) const
 

Static Public Member Functions

static size_t & GetIndex (TrackInterval &interval)
 
static size_t GetIndex (const TrackInterval &interval)
 

Private Member Functions

void OnLabelPermuted (const LabelTrackEvent &e)
 
void OnLabelAdded (const LabelTrackEvent &e)
 
void OnLabelDeleted (const LabelTrackEvent e)
 

Private Attributes

Observer::Subscription mSubscription
 
std::shared_ptr< LabelTrackmpTrack
 
AudacityProjectmProject
 

Additional Inherited Members

- Public Types inherited from TrackShifter
enum class  HitTestResult { Miss , Selection , Intervals , Track }
 Possibilities for HitTest on the clicked track. More...
 
using Intervals = std::vector< TrackInterval >
 
- Protected Member Functions inherited from TrackShifter
void CommonSelectInterval (const TrackInterval &interval)
 
bool CommonMayMigrateTo (Track &otherTrack)
 
void InitIntervals ()
 Derived class constructor can initialize all intervals reported by the track as fixed, none moving. More...
 
bool AllFixed () const
 
- Protected Attributes inherited from TrackShifter
Intervals mFixed
 
Intervals mMoving
 

Detailed Description

Definition at line 11 of file LabelTrackShifter.cpp.

Constructor & Destructor Documentation

◆ LabelTrackShifter()

LabelTrackShifter::LabelTrackShifter ( LabelTrack track,
AudacityProject project 
)
inline

Definition at line 13 of file LabelTrackShifter.cpp.

14 : mpTrack{ track.SharedPointer<LabelTrack>() }
15 , mProject{ project }
16 {
18 mSubscription = mpTrack->Subscribe([this](const LabelTrackEvent &e){
19 switch (e.type) {
20 case LabelTrackEvent::Permutation:
21 return OnLabelPermuted(e);
22 case LabelTrackEvent::Addition:
23 return OnLabelAdded(e);
24 case LabelTrackEvent::Deletion:
25 return OnLabelDeleted(e);
26 default:
27 return;
28 }
29 });
30 }
A LabelTrack is a Track that holds labels (LabelStruct).
Definition: LabelTrack.h:87
AudacityProject & mProject
std::shared_ptr< LabelTrack > mpTrack
Observer::Subscription mSubscription
std::shared_ptr< Subclass > SharedPointer()
Definition: Track.h:298
void InitIntervals()
Derived class constructor can initialize all intervals reported by the track as fixed,...
enum LabelTrackEvent::Type type

References TrackShifter::InitIntervals(), mpTrack, mSubscription, and LabelTrackEvent::type.

Here is the call graph for this function:

◆ ~LabelTrackShifter()

LabelTrackShifter::~LabelTrackShifter ( )
inlineoverride

Definition at line 31 of file LabelTrackShifter.cpp.

32 {
33 }

Member Function Documentation

◆ AdjustFit()

bool LabelTrackShifter::AdjustFit ( const Track otherTrack,
const Intervals intervals,
double &  desiredOffset,
double  tolerance 
)
inlineoverridevirtual

Test whether intervals can fit into another track, maybe adjusting the offset slightly.

Default implementation does nothing and returns false

Parameters
intervalsAssume these came from Detach() and only after MayMigrateTo returned true for otherTrack
[in,out]desiredOffset
toleranceNonnegative ceiling for allowed changes in fabs(desiredOffset)

Reimplemented from TrackShifter.

Definition at line 130 of file LabelTrackShifter.cpp.

132 {
133 // Labels have no overlapping constraints, so just...
134 return true;
135 }

◆ Attach()

bool LabelTrackShifter::Attach ( Intervals  intervals)
inlineoverridevirtual

Put moving intervals into the track, which may have migrated from another.

Returns
success

In case of failure, track states are unspecified

Default implementation does nothing and returns true

Reimplemented from TrackShifter.

Definition at line 137 of file LabelTrackShifter.cpp.

138 {
139 auto pTrack = mpTrack.get();
140 std::for_each( intervals.rbegin(), intervals.rend(),
141 [this, pTrack](auto &interval){
142 auto pData = static_cast<IntervalData*>( interval.Extra() );
143 auto index = pTrack->AddLabel(pData->region, pData->title);
144 // Recreate the simpler TrackInterval as would be reported by LabelTrack
145 mMoving.emplace_back( pTrack->MakeInterval(index) );
146 } );
147 return true;
148 }

References mpTrack.

◆ Detach()

Intervals LabelTrackShifter::Detach ( )
inlineoverridevirtual

Remove all moving intervals from the track, if possible.

Default implementation does nothing

Reimplemented from TrackShifter.

Definition at line 108 of file LabelTrackShifter.cpp.

109 {
110 auto pTrack = mpTrack.get();
111 auto moveLabel = [pTrack](TrackInterval &interval) -> TrackInterval {
112 auto &rindex = GetIndex(interval);
113 auto index = rindex;
114 rindex = -1;
115 auto result = TrackInterval{
116 interval.Start(), interval.End(),
117 std::make_unique<IntervalData>( *pTrack->GetLabel(index) ) };
118 pTrack->DeleteLabel(index);
119 return result;
120 };
121 Intervals result;
122 std::transform(
123 // Reverse traversal may lessen the shifting-left in the label array
124 mMoving.rbegin(), mMoving.rend(), std::back_inserter(result),
125 moveLabel );
126 mMoving = Intervals{};
127 return result;
128 }
double Start() const
Definition: Track.h:193
static size_t & GetIndex(TrackInterval &interval)
A start and an end time, and mutative access to optional extra information.
Definition: Track.h:206
std::vector< TrackInterval > Intervals
Intervals mMoving

References GetIndex(), TrackShifter::mMoving, mpTrack, and ConstTrackInterval::Start().

Here is the call graph for this function:

◆ DoHorizontalOffset()

void LabelTrackShifter::DoHorizontalOffset ( double  offset)
inlineoverridevirtual

Shift all moving intervals horizontally Default moves the whole track, provided !AllFixed(); else does nothing

Reimplemented from TrackShifter.

Definition at line 150 of file LabelTrackShifter.cpp.

151 {
152 auto &labels = mpTrack->GetLabels();
153 for ( auto &interval : MovingIntervals() ) {
154 auto index = GetIndex( interval );
155 auto labelStruct = labels[index];
156 labelStruct.selectedRegion.move(offset);
157 mpTrack->SetLabel( index, labelStruct );
158 }
159
160 mpTrack->SortLabels(); // causes callback to OnLabelPermuted
161 }
const Intervals & MovingIntervals() const
Return special intervals of the track that may move.

References GetIndex(), TrackShifter::MovingIntervals(), and mpTrack.

Here is the call graph for this function:

◆ GetIndex() [1/2]

static size_t LabelTrackShifter::GetIndex ( const TrackInterval interval)
inlinestatic

Definition at line 43 of file LabelTrackShifter.cpp.

44 {
45 return GetIndex( const_cast<TrackInterval&>(interval) );
46 }

References GetIndex().

Here is the call graph for this function:

◆ GetIndex() [2/2]

static size_t & LabelTrackShifter::GetIndex ( TrackInterval interval)
inlinestatic

Definition at line 36 of file LabelTrackShifter.cpp.

37 {
38 auto pExtra =
39 static_cast<LabelTrack::IntervalData*>( interval.Extra() );
40 return pExtra->index;
41 }
TrackIntervalData * Extra() const
Definition: Track.h:213

References TrackInterval::Extra(), and LabelTrack::IntervalData::index.

Referenced by Detach(), DoHorizontalOffset(), GetIndex(), HitTest(), and OnLabelPermuted().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetTrack()

Track & LabelTrackShifter::GetTrack ( ) const
inlineoverridevirtual

There is always an associated track.

Implements TrackShifter.

Definition at line 34 of file LabelTrackShifter.cpp.

34{ return *mpTrack; }

References mpTrack.

◆ HitTest()

HitTestResult LabelTrackShifter::HitTest ( double  time,
const ViewInfo viewInfo,
HitTestParams pParams 
)
inlineoverridevirtual

Decide how shift behaves, based on the track that is clicked in.

If the return value is Intervals or Selection, then some intervals may be marked moving as a side effect

Precondition
!pParams || (time == pParams->viewInfo.PositionToTime(pParams->xx, pParams->rect.x))
Parameters
timeA time value to test
pParamsOptional extra information

Implements TrackShifter.

Definition at line 48 of file LabelTrackShifter.cpp.

50 {
52 auto t0 = viewInfo.selectedRegion.t0();
53 auto t1 = viewInfo.selectedRegion.t1();
54 if ( mpTrack->IsSelected() && time >= t0 && time < t1 )
56
57 // Prefer the box that the mouse hovers over, else the selected one
58 int iLabel = -1;
59 if ( pParams )
60 iLabel =
61 LabelTrackView::OverATextBox(*mpTrack, pParams->xx, pParams->yy);
62 if (iLabel == -1)
64 if (iLabel != -1) {
65 UnfixIntervals([&](const auto &myInterval){
66 return GetIndex( myInterval ) == iLabel;
67 });
68 return result;
69 }
70 else {
71 // If the pick is within the selection, which overlaps some intervals,
72 // then move those intervals only
73 // Else move all labels (preserving the older beahvior of time shift)
74 if ( result == HitTestResult::Selection )
75 SelectInterval({ t0, t1 });
76 if (mMoving.empty())
78 else
79 return result;
80 }
81 }
void SelectInterval(const TrackInterval &interval) override
Notifies the shifter that a region is selected, so it may update its fixed and moving intervals.
static LabelTrackView & Get(LabelTrack &)
static int OverATextBox(const LabelTrack &track, int xx, int yy)
int GetNavigationIndex(AudacityProject &project) const
double t1() const
Definition: ViewInfo.h:36
double t0() const
Definition: ViewInfo.h:35
void UnfixIntervals(std::function< bool(const TrackInterval &) > pred)
Change intervals satisfying a predicate from fixed to moving.
HitTestResult
Possibilities for HitTest on the clicked track.
@ Selection
Shift chosen intervals of this track; may shift other tracks' intervals.
@ Intervals
Shift intervals only of selected track and sister channels.
@ Track
Shift selected track and sister channels only, as a whole.
NotifyingSelectedRegion selectedRegion
Definition: ViewInfo.h:219

References LabelTrackView::Get(), GetIndex(), LabelTrackView::GetNavigationIndex(), TrackShifter::Intervals, TrackShifter::mMoving, mProject, mpTrack, LabelTrackView::OverATextBox(), ViewInfo::selectedRegion, SelectInterval(), TrackShifter::Selection, NotifyingSelectedRegion::t0(), NotifyingSelectedRegion::t1(), TrackShifter::Track, TrackShifter::UnfixIntervals(), TrackShifter::HitTestParams::xx, and TrackShifter::HitTestParams::yy.

Here is the call graph for this function:

◆ MayMigrateTo()

bool LabelTrackShifter::MayMigrateTo ( Track otherTrack)
inlineoverridevirtual

Whether intervals may migrate to the other track, not yet checking all placement constraints *‍/.

Default implementation returns false

Reimplemented from TrackShifter.

Definition at line 90 of file LabelTrackShifter.cpp.

91 {
92 return CommonMayMigrateTo(otherTrack);
93 }
bool CommonMayMigrateTo(Track &otherTrack)

References TrackShifter::CommonMayMigrateTo().

Here is the call graph for this function:

◆ OnLabelAdded()

void LabelTrackShifter::OnLabelAdded ( const LabelTrackEvent e)
inlineprivate

Definition at line 192 of file LabelTrackShifter.cpp.

193 {
194 if ( e.mpTrack.lock() != mpTrack )
195 return;
196
197 auto present = e.mPresentPosition;
198
199 // Avoid signed-unsigned comparison below!
200 if (present < 0) {
201 wxASSERT(false);
202 return;
203 }
204
205 auto update = [=]( TrackInterval &interval ){
206 auto pExtra = static_cast<LabelTrack::IntervalData*>(interval.Extra());
207 auto &index = pExtra->index;
208 if ( index >= present )
209 ++ index;
210 };
211
212 std::for_each(mFixed.begin(), mFixed.end(), update);
213 std::for_each(mMoving.begin(), mMoving.end(), update);
214 }
Intervals mFixed
const std::weak_ptr< Track > mpTrack
Definition: LabelTrack.h:211

References LabelTrack::IntervalData::index, TrackShifter::mFixed, TrackShifter::mMoving, LabelTrackEvent::mPresentPosition, LabelTrackEvent::mpTrack, and mpTrack.

◆ OnLabelDeleted()

void LabelTrackShifter::OnLabelDeleted ( const LabelTrackEvent  e)
inlineprivate

Definition at line 216 of file LabelTrackShifter.cpp.

217 {
218 if ( e.mpTrack.lock() != mpTrack )
219 return;
220
221 auto former = e.mFormerPosition;
222
223 // Avoid signed-unsigned comparison below!
224 if (former < 0) {
225 wxASSERT(false);
226 return;
227 }
228
229 auto update = [=]( TrackInterval &interval ){
230 auto pExtra = static_cast<LabelTrack::IntervalData*>(interval.Extra());
231 auto &index = pExtra->index;
232 if ( index > former )
233 -- index;
234 else if ( index == former )
235 // It should have been deleted first!
236 wxASSERT( false );
237 };
238
239 std::for_each(mFixed.begin(), mFixed.end(), update);
240 std::for_each(mMoving.begin(), mMoving.end(), update);
241 }

References LabelTrack::IntervalData::index, TrackShifter::mFixed, LabelTrackEvent::mFormerPosition, TrackShifter::mMoving, LabelTrackEvent::mpTrack, and mpTrack.

◆ OnLabelPermuted()

void LabelTrackShifter::OnLabelPermuted ( const LabelTrackEvent e)
inlineprivate

Definition at line 164 of file LabelTrackShifter.cpp.

165 {
166 if ( e.mpTrack.lock() != mpTrack )
167 return;
168
169 auto former = e.mFormerPosition;
170 auto present = e.mPresentPosition;
171
172 // Avoid signed-unsigned comparison below!
173 if (former < 0 || present < 0) {
174 wxASSERT(false);
175 return;
176 }
177
178 auto update = [=]( TrackInterval &interval ){
179 auto &index = GetIndex( interval );
180 if ( index == former )
181 index = present;
182 else if ( former < index && index <= present )
183 -- index;
184 else if ( former > index && index >= present )
185 ++ index;
186 };
187
188 std::for_each(mFixed.begin(), mFixed.end(), update);
189 std::for_each(mMoving.begin(), mMoving.end(), update);
190 }

References GetIndex(), TrackShifter::mFixed, LabelTrackEvent::mFormerPosition, TrackShifter::mMoving, LabelTrackEvent::mPresentPosition, LabelTrackEvent::mpTrack, and mpTrack.

Here is the call graph for this function:

◆ SelectInterval()

void LabelTrackShifter::SelectInterval ( const TrackInterval interval)
inlineoverridevirtual

Notifies the shifter that a region is selected, so it may update its fixed and moving intervals.

Default behavior: if any part of the track is selected, unfix all parts of it.

Reimplemented from TrackShifter.

Definition at line 83 of file LabelTrackShifter.cpp.

84 {
85 CommonSelectInterval(interval);
86 }
void CommonSelectInterval(const TrackInterval &interval)

References TrackShifter::CommonSelectInterval().

Referenced by HitTest().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SyncLocks()

bool LabelTrackShifter::SyncLocks ( )
inlineoverridevirtual

Whether unfixing of an interval should propagate to all overlapping intervals in the sync lock group.

Implements TrackShifter.

Definition at line 88 of file LabelTrackShifter.cpp.

88{ return false; }

Member Data Documentation

◆ mProject

AudacityProject& LabelTrackShifter::mProject
private

Definition at line 245 of file LabelTrackShifter.cpp.

Referenced by HitTest().

◆ mpTrack

std::shared_ptr<LabelTrack> LabelTrackShifter::mpTrack
private

◆ mSubscription

Observer::Subscription LabelTrackShifter::mSubscription
private

Definition at line 243 of file LabelTrackShifter.cpp.

Referenced by LabelTrackShifter().


The documentation for this class was generated from the following file: