Audacity 3.2.0
ChannelView.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3Audacity: A Digital Audio Editor
4
5ChannelView.cpp
6
7Paul Licameli split from TrackPanel.cpp
8
9**********************************************************************/
10
11#include "ChannelView.h"
12#include "Track.h"
13
14#include "ClientData.h"
15#include "Project.h"
16#include "XMLTagHandler.h"
17#include "XMLWriter.h"
18
19#include <sstream>
20
21ChannelView::ChannelView(const std::shared_ptr<Track> &pTrack, size_t iChannel)
22 : CommonTrackCell{ pTrack, iChannel }
23 , vrulerSize{ 36, 0 }
24{
26}
27
29{
30}
31
33{
34 const auto GetTrackHeight = [](const Track *pTrack) -> int {
35 return pTrack ? GetFromChannelGroup(*pTrack).GetHeight() : 0;
36 };
37 return pTrack ? TrackList::Channels(pTrack).sum(GetTrackHeight) : 0;
38}
39
41{
42 if (!pChannel)
43 return 0;
44 auto &view = ChannelView::Get(*pChannel);
45 return view.GetCumulativeHeightBefore() + view.GetHeight();
46}
47
49{
50 if (!pTrack)
51 return 0;
52 return GetCumulativeHeight((*pTrack->Channels().rbegin()).get());
53}
54
56{
57 return GetCumulativeHeight(*list.rbegin());
58}
59
60void ChannelView::CopyTo(Track &track) const
61{
62 auto &other = GetFromChannelGroup(track);
63
64 other.mMinimized = mMinimized;
65 other.vrulerSize = vrulerSize;
66
67 // Let mY remain 0 -- TrackPositioner corrects it later
68 other.mY = 0;
69 other.mHeight = mHeight;
70}
71
73
75 [](Track &track){
76 return std::make_shared<ChannelViewAttachments>(track,
77 [](Track &track, size_t iChannel) {
78 assert(iChannel < track.NChannels());
79 return DoGetView::Call(track, iChannel);
80 }
81 );
82 }
83};
84
86 ChannelGroup &group, size_t iChannel)
87{
88 auto &track = static_cast<Track&>(group);
90}
91
93 const ChannelGroup &group, size_t iChannel)
94{
95 return GetFromChannelGroup(const_cast<ChannelGroup &>(group), iChannel);
96}
97
99 ChannelGroup *pGroup, size_t iChannel)
100{
102 keyC, static_cast<Track*>(pGroup), iChannel);
103}
104
105void ChannelView::SetMinimized(bool isMinimized)
106{
107 // Do special changes appropriate to subclass
108 DoSetMinimized(isMinimized);
109
110 // Update positions and heights starting from the first track in the group
111 auto leader = *TrackList::Channels( FindTrack().get() ).begin();
112 if ( leader )
113 leader->AdjustPositions();
114}
115
116namespace {
117// Append a channel number to a base attribute name unless it is 0
118std::string AttributeName(const ChannelView &view, std::string name) {
119 const auto index = view.GetChannelIndex();
120 if (index == 0)
121 return move(name);
122 std::stringstream stream{ name };
123 stream << index;
124 return stream.str();
125}
126std::string HeightAttributeName(const ChannelView &view) {
127 return AttributeName(view, "height");
128}
129std::string MinimizedAttributeName(const ChannelView &view) {
130 return AttributeName(view, "minimized");
131}
132}
133
135{
138}
139
141 const std::string_view& attr, const XMLAttributeValueView& valueView)
142{
143 long nValue;
144
145 if (attr == HeightAttributeName(*this) && valueView.TryGet(nValue)) {
146 // Bug 2803: Extreme values for track height (caused by integer overflow)
147 // will stall Audacity as it tries to create an enormous vertical ruler.
148 // So clamp to reasonable values.
149 nValue = std::max( 40l, std::min( nValue, 1000l ));
150 SetExpandedHeight(nValue);
151 return true;
152 }
153 else if (attr == MinimizedAttributeName(*this) && valueView.TryGet(nValue)) {
154 SetMinimized(nValue != 0);
155 return true;
156 }
157 else
158 return false;
159}
160
161auto ChannelView::GetSubViews(const wxRect &rect) -> Refinement
162{
163 return { { rect.GetTop(), shared_from_this() } };
164}
165
167{
168 return false;
169}
170
171void ChannelView::DoSetMinimized(bool isMinimized)
172{
173 mMinimized = isMinimized;
174}
175
176std::shared_ptr<ChannelVRulerControls> ChannelView::GetVRulerControls()
177{
178 if (!mpVRulerControls)
179 // create on demand
181 return mpVRulerControls;
182}
183
184std::shared_ptr<const ChannelVRulerControls>
186{
187 return const_cast<ChannelView*>(this)->GetVRulerControls();
188}
189
191{
192 mY = y;
193}
194
196{
197 if ( GetMinimized() )
198 return GetMinimizedHeight();
199
200 return mHeight;
201}
202
204{
205 DoSetHeight(h);
206 FindTrack()->AdjustPositions();
207}
208
210{
211 mHeight = h;
212}
213
214std::shared_ptr<CommonTrackCell> ChannelView::GetAffordanceControls()
215{
216 return {};
217}
218
220{
221 return GetFromChannelGroup(channel.GetChannelGroup(),
222 channel.GetChannelIndex());
223}
224
226{
227 return Get(const_cast<Channel&>(channel));
228}
229
231{
232 if (!pChannel)
233 return nullptr;
235 &pChannel->GetChannelGroup(), pChannel->GetChannelIndex());
236}
237
238const ChannelView *ChannelView::Find(const Channel *pChannel)
239{
240 return Find(const_cast<Channel*>(pChannel));
241}
242
243namespace {
244
250{
252
254 : mProject{ project }
255 {
256 mSubscription = TrackList::Get( project )
257 .Subscribe(*this, &TrackPositioner::OnUpdate);
258 }
259 TrackPositioner( const TrackPositioner & ) = delete;
261
262 void OnUpdate(const TrackListEvent & e)
263 {
264 switch (e.mType) {
269 break;
270 default:
271 return;
272 }
273 auto iter =
274 TrackList::Get(mProject).Find(e.mpTrack.lock().get());
275 if (!*iter)
276 return;
277
278 auto prev = iter;
279 auto yy = ChannelView::GetCumulativeHeight(*--prev);
280
281 while (auto pTrack = *iter) {
282 for (auto pChannel : (*iter)->Channels()) {
283 auto &view = ChannelView::Get(*pChannel);
284 view.SetCumulativeHeightBefore(yy);
285 yy += view.GetHeight();
286 }
287 ++iter;
288 }
289 }
290
292};
293
296 return std::make_shared< TrackPositioner >( project );
297 }
298};
299
300}
301
303 return nullptr;
304}
305
307 return nullptr;
308}
static const AttachedTrackObjects::RegisteredFactory keyC
Definition: ChannelView.cpp:74
DEFINE_ATTACHED_VIRTUAL(DoGetView)
Utility ClientData::Site to register hooks into a host class that attach client data.
int min(int a, int b)
const TranslatableString name
Definition: Distortion.cpp:76
const auto project
declares abstract base class Track, TrackList, and iterators over TrackList
Class template generates single-dispatch, open method registry tables.
static Return Call(This &obj, Arguments ...arguments)
Invoke the method – but only after static initialization time.
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
Holds multiple objects of the parameter type as a single attachment to Track.
Definition: Track.h:550
static Attachment * Find(const AttachedTrackObjects::RegisteredFactory &key, Track *pTrack, size_t iChannel)
Definition: Track.h:568
static Attachment & Get(const AttachedTrackObjects::RegisteredFactory &key, Track &track, size_t iChannel)
Definition: Track.h:558
IteratorRange< ChannelIterator< ChannelType > > Channels()
Get range of channels with mutative access.
Definition: Channel.h:408
virtual size_t NChannels() const =0
Report the number of channels.
ChannelGroup & GetChannelGroup()
Channel object's lifetime is assumed to be nested in its Track's.
Definition: Channel.cpp:71
size_t GetChannelIndex() const
Definition: Channel.cpp:77
virtual std::shared_ptr< ChannelVRulerControls > DoGetVRulerControls()=0
static ChannelView * Find(Channel *pChannel)
static int GetTotalHeight(const TrackList &list)
Definition: ChannelView.cpp:55
static ChannelView & Get(Channel &channel)
virtual std::shared_ptr< CommonTrackCell > GetAffordanceControls()
bool mMinimized
Definition: ChannelView.h:162
std::shared_ptr< ChannelVRulerControls > mpVRulerControls
Definition: ChannelView.h:143
virtual int GetMinimizedHeight() const =0
bool GetMinimized() const
Definition: ChannelView.h:68
virtual bool IsSpectral() const
virtual void DoSetMinimized(bool isMinimized)
void WriteXMLAttributes(XMLWriter &) const override
Serialize persistent attributes.
static int GetCumulativeHeight(const Channel *pChannel)
Definition: ChannelView.cpp:40
std::vector< std::pair< wxCoord, std::shared_ptr< ChannelView > > > Refinement
Definition: ChannelView.h:120
void SetMinimized(bool minimized)
int GetExpandedHeight() const
Definition: ChannelView.h:76
void DoSetY(int y)
virtual ~ChannelView()=0
Definition: ChannelView.cpp:28
virtual Refinement GetSubViews(const wxRect &rect)
bool HandleXMLAttribute(const std::string_view &attr, const XMLAttributeValueView &valueView) override
Deserialize an attribute, returning true if recognized.
int GetHeight() const
std::shared_ptr< ChannelVRulerControls > GetVRulerControls()
std::pair< int, int > vrulerSize
Definition: ChannelView.h:128
void DoSetHeight(int h)
void CopyTo(Track &track) const override
Copy state, for undo/redo purposes.
Definition: ChannelView.cpp:60
static ChannelView & GetFromChannelGroup(ChannelGroup &group, size_t iChannel=0)
Definition: ChannelView.cpp:85
static int GetChannelGroupHeight(const Track *pTrack)
Definition: ChannelView.cpp:32
void SetExpandedHeight(int height)
ChannelView(const ChannelView &)=delete
static ChannelView * FindFromChannelGroup(ChannelGroup *pGroup, size_t iChannel=0)
Definition: ChannelView.cpp:98
Client code makes static instance from a factory of attachments; passes it to Get or Find as a retrie...
Definition: ClientData.h:274
size_t GetChannelIndex() const
std::shared_ptr< Track > FindTrack()
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
Definition: Observer.h:199
A move-only handle representing a connection to a Publisher.
Definition: Observer.h:70
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:122
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
Definition: Track.h:975
TrackIter< Track > Find(Track *pTrack)
Definition: Track.cpp:519
reverse_iterator rbegin()
Definition: Track.h:1042
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:347
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1146
A view into an attribute value. The class does not take the ownership of the data.
bool TryGet(bool &value) const noexcept
Try to get a boolean value from the view.
Base class for XMLFileWriter and XMLStringWriter that provides the general functionality for creating...
Definition: XMLWriter.h:25
void WriteAttr(const wxString &name, const Identifier &value)
Definition: XMLWriter.h:36
std::string HeightAttributeName(const ChannelView &view)
static const AudacityProject::AttachedObjects::RegisteredFactory key
std::string MinimizedAttributeName(const ChannelView &view)
std::string AttributeName(const ChannelView &view, std::string name)
A convenient default parameter for class template Site.
Definition: ClientData.h:28
Notification of changes in individual tracks of TrackList, or of TrackList's composition.
Definition: Track.h:928
const std::weak_ptr< Track > mpTrack
Definition: Track.h:963
const Type mType
Definition: Track.h:962
@ RESIZING
Posted when some track changed its height.
Definition: Track.h:941
@ DELETION
Posted when a track has been deleted from a tracklist. Also posted when one track replaces another.
Definition: Track.h:950
@ ADDITION
Posted when a track has been added to a tracklist. Also posted when one track replaces another.
Definition: Track.h:944
@ PERMUTED
Posted when tracks are reordered but otherwise unchanged.
Definition: Track.h:938
TrackPositioner(const TrackPositioner &)=delete
TrackPositioner & operator=(const TrackPositioner &)=delete