34 constexpr int FrameThickness{ 1 };
47 int height,
bool dB,
bool outer,
55 float sign = (value >= 0 ? 1 : -1);
59 value = (db + dBr) / dBr;
89 value = (max - value) / (max -
min);
90 return (
int) (value * (height - 1) + 0.5);
93float FromDB(
float value,
double dBRange)
98 double sign = (value >= 0 ? 1 : -1);
99 return DB_TO_LINEAR((fabs(value) * dBRange) - dBRange) * sign;
103 bool dB,
double dBRange,
float zoomMin,
float zoomMax)
105 wxASSERT(height > 0);
108 height == 1 ? (zoomMin + zoomMax) / 2 :
109 zoomMax - (yy / (
float)(height - 1)) * (zoomMax - zoomMin);
126 auto &dc = context.
dc;
132 dc.SetPen(*wxBLACK_PEN);
134 rect.x + 2, rect.y + 6,
135 rect.x + 8, rect.y + 6);
137 rect.x + 2, rect.y + 6,
138 rect.x + 6, rect.y + 2);
140 rect.x + 2, rect.y + 6,
141 rect.x + 6, rect.y + 10);
143 rect.x + 2, rect.y + rect.height - 8,
144 rect.x + 8, rect.y + rect.height - 8);
146 rect.x + 2, rect.y + rect.height - 8,
147 rect.x + 6, rect.y + rect.height - 4);
149 rect.x + 2, rect.y + rect.height - 8,
150 rect.x + 6, rect.y + rect.height - 12);
155 static const wxString ellipsis =
"\u2026";
157 if (dc.GetTextExtent(text).GetWidth() <= maxWidth)
162 auto right =
static_cast<int>(text.Length() - 2);
164 while (left <= right)
166 auto middle = (left + right) / 2;
167 auto str = text.SubString(0, middle).Trim() + ellipsis;
168 auto strWidth = dc.GetTextExtent(
str).GetWidth();
169 if (strWidth < maxWidth)
174 else if (strWidth > maxWidth)
183 return text.SubString(0, right).Trim() + ellipsis;
185 return wxEmptyString;
194 bool hasClipRect = dc.GetClippingBox(clipRect);
201 auto drawingRect = rect;
205 drawingRect.SetLeft(std::max(rect.GetLeft(), clipRect.GetLeft() - clipFrameRadius - 1));
206 drawingRect.SetRight(
std::min(rect.GetRight(), clipRect.GetRight() + clipFrameRadius + 1));
215 drawingRect.height + clipFrameRadius };
216 dc.SetBrush(*wxTRANSPARENT_BRUSH);
218 dc.DrawRoundedRectangle(strokeRect, clipFrameRadius);
221 AColor::UseThemeColour(&dc, highlight ? clrClipAffordanceActiveBrush : clrClipAffordanceInactiveBrush, clrClipAffordanceOutlinePen);
222 dc.DrawRoundedRectangle(
227 drawingRect.height + clipFrameRadius
231 auto titleRect = hasClipRect ?
241 if(titleRect.IsEmpty())
247 if (!truncatedTitle.empty())
249 auto hAlign = wxTheApp->GetLayoutDirection() == wxLayout_RightToLeft ? wxALIGN_RIGHT : wxALIGN_LEFT;
250 dc.DrawLabel(truncatedTitle, titleRect, hAlign | wxALIGN_CENTER_VERTICAL);
258 dc.SetBrush(*wxTRANSPARENT_BRUSH);
262 clipRect.GetLeft(), clipRect.GetTop(),
263 clipRect.GetLeft(), clipRect.GetBottom());
265 clipRect.GetRight(), clipRect.GetTop(),
266 clipRect.GetRight(), clipRect.GetBottom());
283 dc.DrawRectangle(wxRect(
286 dc.DrawRectangle(wxRect(
287 clipRect.GetRight() + 1, clipRect.GetTop(),
296 dc.DrawRectangle(rect);
315 const auto dc = &context.
dc;
320 int gridW = syncLockBitmap.GetWidth() - 6;
321 int gridH = syncLockBitmap.GetHeight() - 8;
324 int blockX = (rect.x / gridW) % 5;
327 int xOffset = rect.x % gridW;
328 if (xOffset < 0) xOffset += gridW;
332 bool extraCol =
false;
333 if (syncLockBitmap.GetWidth() - gridW > xOffset) {
336 blockX = (blockX - 1) % 5;
339 if (blockX < 0) blockX += 5;
342 while (xx < rect.width) {
343 int width = syncLockBitmap.GetWidth() - xOffset;
344 if (xx + width > rect.width)
345 width = rect.width - xx;
352 int blockY = (rect.y / gridH) % 5;
355 int yOffset = rect.y % gridH;
356 if (yOffset < 0) yOffset += gridH;
360 bool extraRow =
false;
361 if (syncLockBitmap.GetHeight() - gridH > yOffset) {
364 blockY = (blockY - 1) % 5;
367 if (blockY < 0) blockY += 5;
370 while (yy < rect.height)
372 int height = syncLockBitmap.GetHeight() - yOffset;
373 if (yy + height > rect.height)
374 height = rect.height - yy;
377 if ((blockX == 0 && blockY == 0) || (blockX == 2 && blockY == 1) ||
378 (blockX == 4 && blockY == 2) || (blockX == 1 && blockY == 3) ||
379 (blockX == 3 && blockY == 4))
383 if (width != syncLockBitmap.GetWidth() || height != syncLockBitmap.GetHeight()) {
384 wxBitmap subSyncLockBitmap =
385 syncLockBitmap.GetSubBitmap(wxRect(xOffset, yOffset, width, height));
386 dc->DrawBitmap(subSyncLockBitmap, rect.x + xx, rect.y + yy,
true);
389 dc->DrawBitmap(syncLockBitmap, rect.x + xx, rect.y + yy,
true);
401 yy += gridH - yOffset;
404 blockY = (blockY + 1) % 5;
415 xx += gridW - xOffset;
418 blockX = (blockX + 1) % 5;
424 const Track *track,
const wxBrush &selBrush,
const wxBrush &unselBrush,
427 const auto dc = &context.
dc;
429 const auto &selectedRegion = *artist->pSelectedRegion;
430 const auto &zoomInfo = *artist->pZoomInfo;
433 const double sel0 = useSelection ? selectedRegion.t0() : 0.0;
434 const double sel1 = useSelection ? selectedRegion.t1() : 0.0;
436 dc->SetPen(*wxTRANSPARENT_PEN);
440 wxRect before = rect;
444 before.width = (int)(zoomInfo.TimeToPosition(sel0) );
445 if (before.GetRight() > rect.GetRight()) {
446 before.width = rect.width;
449 if (before.width > 0) {
450 dc->SetBrush(unselBrush);
451 dc->DrawRectangle(before);
453 within.x = 1 + before.GetRight();
455 within.width = rect.x + (int)(zoomInfo.TimeToPosition(sel1) ) -
within.x -1;
457 if (
within.GetRight() > rect.GetRight()) {
470 dc->SetBrush(selBrush);
471 dc->DrawRectangle(
within);
475 dc->SetBrush(unselBrush);
476 dc->DrawRectangle(
within);
480 after.x = 1 +
within.GetRight();
487 after.width = 1 + rect.GetRight() - after.x;
488 if (after.width > 0) {
489 dc->SetBrush(unselBrush);
490 dc->DrawRectangle(after);
496 dc->SetBrush(unselBrush);
497 dc->DrawRectangle(rect);
502 const wxRect& rect,
const Track* track)
504 const auto dc = &context.
dc;
506 const auto& selectedRegion = *artist->pSelectedRegion;
508 if (selectedRegion.isPoint())
510 const auto& zoomInfo = *artist->pZoomInfo;
511 auto x =
static_cast<int>(zoomInfo.TimeToPosition(selectedRegion.t0(), rect.x));
512 if (x >= rect.GetLeft() && x <= rect.GetRight())
515 AColor::Line(*dc, x, rect.GetTop(), x, rect.GetBottom());
static const wxPoint2DDouble outer[]
declares abstract base class Track, TrackList, and iterators over TrackList
int GetWaveYPos(float value, float min, float max, int height, bool dB, bool outer, float dBr, bool clip)
float FromDB(float value, double dBRange)
float ValueOfPixel(int yy, int height, bool offset, bool dB, double dBRange, float zoomMin, float zoomMax)
static constexpr int ClipSelectionStrokeSize
bool within(A a, B b, DIST d)
static void Line(wxDC &dc, wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
static void CursorColor(wxDC *dc)
static void UseThemeColour(wxDC *dc, int iBrush, int iPen=-1, int alpha=255)
static bool IsSelectedOrSyncLockSelected(const Track *pTrack)
wxImage & Image(int iIndex)
static TrackArtist * Get(TrackPanelDrawingContext &)
Abstract base class for an object holding data associated with points on a time axis.
AUDACITY_DLL_API void DrawSyncLockTiles(TrackPanelDrawingContext &context, const wxRect &rect)
AUDACITY_DLL_API wxString TruncateText(wxDC &dc, const wxString &text, const int maxWidth)
AUDACITY_DLL_API void DrawClipFolded(wxDC &dc, const wxRect &rect)
AUDACITY_DLL_API void DrawClipEdges(wxDC &dc, const wxRect &clipRect, bool selected=false)
AUDACITY_DLL_API wxRect DrawClipAffordance(wxDC &dc, const wxRect &affordanceRect, bool highlight=false, bool selected=false)
AUDACITY_DLL_API void DrawBackgroundWithSelection(TrackPanelDrawingContext &context, const wxRect &rect, const Track *track, const wxBrush &selBrush, const wxBrush &unselBrush, bool useSelection=true)
AUDACITY_DLL_API void DrawCursor(TrackPanelDrawingContext &context, const wxRect &rect, const Track *track)
AUDACITY_DLL_API void DrawNegativeOffsetTrackArrows(TrackPanelDrawingContext &context, const wxRect &rect)
static constexpr int ClipFrameRadius
AUDACITY_DLL_API bool DrawClipTitle(wxDC &dc, const wxRect &titleRect, const wxString &title)
wxRect GetAffordanceTitleRect(const wxRect &rect)