Audacity 3.2.0
CommonTrackInfo.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3Audacity: A Digital Audio Editor
4
5CommonTrackInfo.cpp
6
7Paul Licameli split from TrackInfo.cpp
8
9********************************************************************/
27#include "CommonTrackInfo.h"
28
29#include <wx/dc.h>
30#include "AColor.h"
31#include "AllThemeResources.h"
32#include "SyncLock.h"
33#include "Theme.h"
34#include "Track.h"
35#include "TrackControls.h"
37#include "UIHandle.h"
38#include "ViewInfo.h"
40
41#define RANGE(array) std::begin(array), std::end(array)
44
46{
47 static const TCPLines theLines{
50 };
51 return theLines;
52}
53
55{
56 return commonTrackTCPLines();
57}
58
59namespace {
60
61int totalTCPLines( const TCPLines &lines, bool omitLastExtra )
62{
63 int total = 0;
64 int lastExtra = 0;
65 for ( const auto line : lines ) {
66 lastExtra = line.extraSpace;
67 total += line.height + lastExtra;
68 }
69 if (omitLastExtra)
70 total -= lastExtra;
71 return total;
72}
73}
74
75namespace {
76
77// Items for the bottom of the panel, listed bottom-upwards
78// As also with the top items, the extra space is below the item
80 // The '0' avoids impinging on bottom line of TCP
81 // Use -1 if you do want to do so.
84};
86
87// return y value and height
88std::pair< int, int > CalcBottomItemY
89 ( const TCPLines &lines, unsigned iItem, int height )
90{
91 int y = height;
92 auto pLines = lines.begin();
93 while ( pLines != lines.end() &&
94 0 == (pLines->items & iItem) ) {
95 y -= pLines->height + pLines->extraSpace;
96 ++pLines;
97 }
98 if (pLines != lines.end())
99 y -= (pLines->height + pLines->extraSpace );
100 return { y, pLines->height };
101}
102
103}
104
106{
107 unsigned height = 0;
108 if (!commonTrackTCPLines().empty())
109 height += commonTrackTCPLines().front().height;
110 if (!commonTrackTCPBottomLines.empty())
111 height += commonTrackTCPBottomLines.front().height;
112 // + 1 prevents the top item from disappearing for want of enough space,
113 // according to the rules in HideTopItem.
114 return height + kVerticalPadding + 1;
115}
116
117bool CommonTrackInfo::HideTopItem( const wxRect &rect, const wxRect &subRect,
118 int allowance ) {
119 auto limit = CalcBottomItemY
121 // Return true if the rectangle is even touching the limit
122 // without an overlap. That was the behavior as of 2.1.3.
123 return subRect.y + subRect.height - allowance >= rect.y + limit;
124}
125
127( TrackPanelDrawingContext &context,
128 const wxRect &rect, const Track &track )
129{
130 auto &trackControl = TrackControls::Get(track);
131 const auto &topLines = trackControl.GetTCPLines();
132 const auto &bottomLines = commonTrackTCPBottomLines;
134 ( context, rect, &track, topLines, bottomLines );
135}
136
138( TrackPanelDrawingContext &context,
139 const wxRect &rect, const Track *pTrack,
140 const std::vector<TCPLine> &topLines, const std::vector<TCPLine> &bottomLines )
141{
142 auto dc = &context.dc;
144 dc->SetTextForeground(theTheme.Colour(clrTrackPanelText));
145
146 {
147 int yy = 0;
148 for ( const auto &line : topLines ) {
149 wxRect itemRect{
150 rect.x, rect.y + yy,
151 rect.width, line.height
152 };
153 if ( !CommonTrackInfo::HideTopItem( rect, itemRect ) &&
154 line.drawFunction )
155 line.drawFunction( context, itemRect, pTrack );
156 yy += line.height + line.extraSpace;
157 }
158 }
159 {
160 int yy = rect.height;
161 for ( const auto &line : bottomLines ) {
162 yy -= line.height + line.extraSpace;
163 if ( line.drawFunction ) {
164 wxRect itemRect{
165 rect.x, rect.y + yy,
166 rect.width, line.height
167 };
168 line.drawFunction( context, itemRect, pTrack );
169 }
170 }
171 }
172}
173
175 TrackPanelDrawingContext &context, const wxRect &bev,
176 const Channel *pChannel, UIHandle *target)
177{
178 auto dc = &context.dc;
179 auto pTrack = pChannel
180 ? dynamic_cast<const Track*>(&pChannel->GetChannelGroup())
181 : nullptr;
182 bool selected = pTrack ? pTrack->GetSelected() : true;
183 bool hit = target && target->FindTrack().get() == pTrack;
184 bool captured = hit && target->IsDragging();
185 bool down = captured && bev.Contains( context.lastState.GetPosition());
186 AColor::Bevel2(*dc, !down, bev, selected, hit );
187
188 wxPen pen( theTheme.Colour( clrTrackPanelText ));
189 dc->SetPen( pen );
190 bev.Inflate( -1, -1 );
191 // Draw the "X"
192 const int s = 6;
193
194 int ls = bev.x + ((bev.width - s) / 2);
195 int ts = bev.y + ((bev.height - s) / 2);
196 int rs = ls + s;
197 int bs = ts + s;
198
199 AColor::Line(*dc, ls, ts, rs, bs);
200 AColor::Line(*dc, ls + 1, ts, rs + 1, bs);
201 AColor::Line(*dc, rs, ts, ls, bs);
202 AColor::Line(*dc, rs + 1, ts, ls + 1, bs);
203 // bev.Inflate(-1, -1);
204}
205
207( TrackPanelDrawingContext &context,
208 const wxRect &rect, const Track *pTrack )
209{
210 auto dc = &context.dc;
211 bool selected = pTrack ? pTrack->GetSelected() : true;
212 {
213 wxRect bev = rect;
214 GetCloseBoxHorizontalBounds( rect, bev );
215 auto target = context.target.get();
216 DrawCloseButton(context, bev,
217 (*pTrack->Channels().begin()).get(), target);
218 }
219
220 {
221 wxRect bev = rect;
222 GetTitleBarHorizontalBounds( rect, bev );
223 auto target = context.target.get();
224 bool hit = target &&
225 target->FindTrack().get() == pTrack;
226 bool captured = hit && target->IsDragging();
227 bool down = captured && bev.Contains( context.lastState.GetPosition());
228 wxString titleStr =
229 pTrack ? pTrack->GetName() : _("Name");
230
231 //bev.Inflate(-1, -1);
232 AColor::Bevel2(*dc, !down, bev, selected, hit);
233
234 // Draw title text
236
237 // Bug 1660 The 'k' of 'Audio Track' was being truncated.
238 // Constant of 32 found by counting pixels on a windows machine.
239 // I believe it's the size of the X close button + the size of the
240 // drop down arrow.
241 int allowableWidth = rect.width - 32;
242
243 wxCoord textWidth, textHeight;
244 dc->GetTextExtent(titleStr, &textWidth, &textHeight);
245 while (textWidth > allowableWidth) {
246 titleStr = titleStr.Left(titleStr.length() - 1);
247 dc->GetTextExtent(titleStr, &textWidth, &textHeight);
248 }
249
250 // Pop-up triangle
251 wxColour c = theTheme.Colour( clrTrackPanelText );
252
253 // wxGTK leaves little scraps (antialiasing?) of the
254 // characters if they are repeatedly drawn. This
255 // happens when holding down mouse button and moving
256 // in and out of the title bar. So clear it first.
257 // AColor::MediumTrackInfo(dc, t->GetSelected());
258 // dc->DrawRectangle(bev);
259
260 dc->SetTextForeground( c );
261 dc->SetTextBackground( wxTRANSPARENT );
262 dc->DrawText(titleStr, bev.x + 2, bev.y + (bev.height - textHeight) / 2);
263
264
265
266 dc->SetPen(c);
267 dc->SetBrush(c);
268
269 int s = 10; // Width of dropdown arrow...height is half of width
270 AColor::Arrow(*dc,
271 bev.GetRight() - s - 3, // 3 to offset from right border
272 bev.y + ((bev.height - (s / 2)) / 2),
273 s);
274
275 }
276}
277
279( TrackPanelDrawingContext &context,
280 const wxRect &rect, const Track *pTrack )
281{
282 auto dc = &context.dc;
283 bool selected = pTrack ? pTrack->GetSelected() : true;
284 bool syncLockSelected =
285 pTrack ? SyncLock::IsSyncLockSelected(*pTrack) : true;
286 bool minimized =
287 pTrack ? ChannelView::Get(*pTrack->GetChannel(0)).GetMinimized() : false;
288 {
289 wxRect bev = rect;
291 auto target = context.target.get();
292 bool hit = target && target->FindTrack().get() == pTrack;
293 bool captured = hit && target->IsDragging();
294 bool down = captured && bev.Contains( context.lastState.GetPosition());
295
296 // Clear background to get rid of previous arrow
297 //AColor::MediumTrackInfo(dc, t->GetSelected());
298 //dc->DrawRectangle(bev);
299
300 AColor::Bevel2(*dc, !down, bev, selected, hit);
301
302 wxColour c = theTheme.Colour(clrTrackPanelText);
303 dc->SetBrush(c);
304 dc->SetPen(c);
305
306 AColor::Arrow(*dc,
307 bev.x - 5 + bev.width / 2,
308 bev.y - 2 + bev.height / 2,
309 10,
310 minimized);
311 }
312
313
314 // Draw the sync-lock indicator if this track is in a sync-lock selected group.
315 if (syncLockSelected)
316 {
317 wxRect syncLockIconRect = rect;
318
319 GetSyncLockHorizontalBounds( rect, syncLockIconRect );
320 wxBitmap syncLockBitmap(theTheme.Image(bmpSyncLockIcon));
321 // Icon is 12x12 and syncLockIconRect is 16x16.
322 dc->DrawBitmap(syncLockBitmap,
323 syncLockIconRect.x + 3,
324 syncLockIconRect.y + 2,
325 true);
326 }
327}
328
329void CommonTrackInfo::GetCloseBoxHorizontalBounds( const wxRect & rect, wxRect &dest )
330{
331 dest.x = rect.x;
332 dest.width = kTrackInfoBtnSize;
333}
334
335void CommonTrackInfo::GetCloseBoxRect(const wxRect & rect, wxRect & dest)
336{
337 GetCloseBoxHorizontalBounds( rect, dest );
339 dest.y = rect.y + results.first;
340 dest.height = results.second;
341}
342
343void CommonTrackInfo::GetTitleBarHorizontalBounds( const wxRect & rect, wxRect &dest )
344{
345 // to right of CloseBoxRect, plus a little more
346 wxRect closeRect;
347 GetCloseBoxHorizontalBounds( rect, closeRect );
348 dest.x = rect.x + closeRect.width + 1;
349 dest.width = rect.x + rect.width - dest.x + TitleSoloBorderOverlap;
350}
351
352void CommonTrackInfo::GetTitleBarRect(const wxRect & rect, wxRect & dest)
353{
354 GetTitleBarHorizontalBounds( rect, dest );
356 dest.y = rect.y + results.first;
357 dest.height = results.second;
358}
359
360void CommonTrackInfo::GetSliderHorizontalBounds( const wxPoint &topleft, wxRect &dest )
361{
362 dest.x = topleft.x + 6;
363 dest.width = kTrackInfoSliderWidth;
364}
365
366void CommonTrackInfo::GetMinimizeHorizontalBounds( const wxRect &rect, wxRect &dest )
367{
368 const int space = 0;// was 3.
369 dest.x = rect.x + space;
370
371 wxRect syncLockRect;
372 GetSyncLockHorizontalBounds( rect, syncLockRect );
373
374 // Width is rect.width less space on left for track select
375 // and on right for sync-lock icon.
376 dest.width = kTrackInfoBtnSize;
377// rect.width - (space + syncLockRect.width);
378}
379
380void CommonTrackInfo::GetMinimizeRect(const wxRect & rect, wxRect &dest)
381{
382 GetMinimizeHorizontalBounds( rect, dest );
383 auto results = CalcBottomItemY
385 dest.y = rect.y + results.first;
386 dest.height = results.second;
387}
388
389void CommonTrackInfo::GetSyncLockHorizontalBounds( const wxRect &rect, wxRect &dest )
390{
391 dest.width = kTrackInfoBtnSize;
392 dest.x = rect.x + rect.width - dest.width;
393}
394
395void CommonTrackInfo::GetSyncLockIconRect(const wxRect & rect, wxRect &dest)
396{
397 GetSyncLockHorizontalBounds( rect, dest );
398 auto results = CalcBottomItemY
400 dest.y = rect.y + results.first;
401 dest.height = results.second;
402}
403
405{
406 int needed =
408 totalTCPLines( topLines, true ) +
410 return (unsigned) std::max(needed, (int) ChannelView::DefaultHeight);
411}
std::vector< TrackInfo::TCPLine > TCPLines
TrackInfo::TCPLine TCPLine
static const TCPLines & commonTrackTCPLines()
#define RANGE(array)
static const int TitleSoloBorderOverlap
#define _(s)
Definition: Internat.h:73
THEME_API Theme theTheme
Definition: Theme.cpp:82
declares abstract base class Track, TrackList, and iterators over TrackList
@ kTrackInfoSliderWidth
Definition: ViewInfo.h:99
@ kTrackInfoBtnSize
Definition: ViewInfo.h:96
@ kVerticalPadding
Definition: ViewInfo.h:92
static void Arrow(wxDC &dc, wxCoord x, wxCoord y, int width, bool down=true)
Definition: AColor.cpp:158
static void Bevel2(wxDC &dc, bool up, const wxRect &r, bool bSel=false, bool bHighlight=false)
Definition: AColor.cpp:292
static void Line(wxDC &dc, wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
Definition: AColor.cpp:185
IteratorRange< ChannelIterator< ChannelType > > Channels()
Get range of channels with mutative access.
Definition: Channel.h:381
std::shared_ptr< ChannelType > GetChannel(size_t iChannel)
Retrieve a channel, cast to the given type.
Definition: Channel.h:320
ChannelGroup & GetChannelGroup()
Channel object's lifetime is assumed to be nested in its Track's.
Definition: Channel.cpp:43
static ChannelView & Get(Channel &channel)
bool GetMinimized() const
Definition: ChannelView.h:69
static bool IsSyncLockSelected(const Track &track)
Definition: SyncLock.cpp:80
wxColour & Colour(int iIndex)
wxImage & Image(int iIndex)
static TrackControls & Get(Track &track)
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:110
bool GetSelected() const
Selectedness is always the same for all channels of a group.
Definition: Track.cpp:78
const wxString & GetName() const
Name is always the same for all channels of a group.
Definition: Track.cpp:64
Short-lived drawing and event-handling object associated with a TrackPanelCell.
Definition: UIHandle.h:37
virtual std::shared_ptr< const Track > FindTrack() const =0
virtual bool IsDragging() const
Definition: UIHandle.cpp:57
AUDACITY_DLL_API void GetSyncLockIconRect(const wxRect &rect, wxRect &dest)
AUDACITY_DLL_API void GetCloseBoxHorizontalBounds(const wxRect &rect, wxRect &dest)
AUDACITY_DLL_API void CloseTitleDrawFunction(TrackPanelDrawingContext &context, const wxRect &rect, const Track *pTrack)
AUDACITY_DLL_API void GetTitleBarHorizontalBounds(const wxRect &rect, wxRect &dest)
AUDACITY_DLL_API void GetSyncLockHorizontalBounds(const wxRect &rect, wxRect &dest)
AUDACITY_DLL_API void DrawItems(TrackPanelDrawingContext &context, const wxRect &rect, const Track &track)
AUDACITY_DLL_API void GetCloseBoxRect(const wxRect &rect, wxRect &dest)
TrackInfo::TCPLines TCPLines
AUDACITY_DLL_API unsigned DefaultTrackHeight(const TCPLines &topLines)
AUDACITY_DLL_API void DrawCloseButton(TrackPanelDrawingContext &context, const wxRect &bev, const Channel *pChannel, UIHandle *target)
AUDACITY_DLL_API void GetMinimizeRect(const wxRect &rect, wxRect &dest)
AUDACITY_DLL_API void MinimizeSyncLockDrawFunction(TrackPanelDrawingContext &context, const wxRect &rect, const Track *pTrack)
AUDACITY_DLL_API void GetMinimizeHorizontalBounds(const wxRect &rect, wxRect &dest)
AUDACITY_DLL_API void GetTitleBarRect(const wxRect &rect, wxRect &dest)
AUDACITY_DLL_API void GetSliderHorizontalBounds(const wxPoint &topleft, wxRect &dest)
AUDACITY_DLL_API const TCPLines & StaticTCPLines()
AUDACITY_DLL_API unsigned MinimumTrackHeight()
AUDACITY_DLL_API bool HideTopItem(const wxRect &rect, const wxRect &subRect, int allowance=0)
AUDACITY_DLL_API void SetTrackInfoFont(wxDC *dc)
Definition: TrackInfo.cpp:73
std::vector< TCPLine > TCPLines
Definition: TrackInfo.h:59
AUDACITY_DLL_API std::pair< int, int > CalcItemY(const TCPLines &lines, unsigned iItem)
Definition: TrackInfo.cpp:57
const TrackInfo::TCPLine defaultCommonTrackTCPBottomLines[]
std::pair< int, int > CalcBottomItemY(const TCPLines &lines, unsigned iItem, int height)
int totalTCPLines(const TCPLines &lines, bool omitLastExtra)