... These do not require header files; they are tiny proto-plugins that work
by registration of AttachedVirtualFunction overrides at startup.
Dependency may go from them to TrackView subclasses but not back; so in
principle a reduced Audacity without time-shift could be linked that still uses
the TrackView subclasses.
But other work to make the hit test for the Time Shift tool registrable would
have to precede that.
... Implemented non-invasively just with overrides in LabelTrackShifter
Exceeding the bug description: it's also possible to drag just the subset of
labels that fall partly or wholly in the selected region.
I expect details of the new behavior may be debated.
* Don't need TrackFactory to make LabelTrack
* Don't need TrackFactory to make NoteTrack
* Don't need TrackFactory to make TimeTrack, or ZoomInfo in the factory
* Remove some forward declarations
* Rename TrackFactory as WaveTrackFactory, move it out of Track.cpp
Problem:
labelStruct, a copy of the label is initialized before call to RemoveSelectedText() which acts on the real label. So when the label is updated using labelStruct, the selected text has not been removed.
Fix:
Initialize labelStruct after the call to RemoveSelectedText().
Bug began at 0750f62e88ee96cd4804c19ba54e3ac1d2ff1b73
Track::SetSelected is virtual, after all, but then LabelTrack informs
LabelTrackView of selection changes by events, so that LabelTrack remains
independent of LabelTrackView.
This might make much of the rest of the guily commit unnecessary (the resetting
of selected index to -1 only lazily), but it is harmless.
... use an AttachedVirtualFunction to compute the default view height from
the controls.
This frees LabelTrackControls from cycles.
Also made Track::DoSetHeight non-virtual
... Let the window respond to an undo manager event instead, whenever there
is a push or modify
Maybe this makes a few unnecessary redraws that did not happen before. If
that is important, then we should figure out how to put the logic for eliding
the redraw into ProjectWindow, and the extra information needed for the
decision into the events, but not make intrusions in other code all over the
place.
... It is const, renamed CopyTo, and invokes the create-on-demand factory in
the destination track; this means Track.cpp doesn't need to do that, and so
does not need TrackView.h
... non-intrusively in the Track suclasses, registering functions instead.
For each abstract factory function (of two), build a table of concrete factory
functions, paralleling the hierarchy of Track subclesses. Dispatch using
runt time type information in the Track objects.
... and eliminate some unnecessary calls to SubstitutePendingChangedTrack,
because the track and the substitute store Y and height in their shared
TrackView object.
Also make GetMinimizedHeight() virtual to avoid inclusion of TrackPanel.h in
TrackView.cpp.
... And Track no longer inherits TrackPanelCell, so be careful to rewrite
some dynamic_casts too to check instead for TrackView. Those casts won't fail
to recompile if not rewritten.
... in anticipation of making views to tracks many-to-one, but then the rulers
should be one-to-one with the views. So go through the view to get the ruler.
The ruler is really a left-hand extension for each view.