18#include "../../../LabelTrack.h"
21#include "../../../widgets/BasicMenu.h"
23#include "../../../HitTestResult.h"
27#include "../../../ProjectSettings.h"
28#include "../../../ProjectWindow.h"
29#include "../../../ProjectWindows.h"
30#include "../../../RefreshCode.h"
31#include "../../../SyncLock.h"
33#include "../../../TrackArt.h"
34#include "../../../TrackArtist.h"
35#include "../../../TrackPanelAx.h"
36#include "../../../TrackPanel.h"
37#include "../../../TrackPanelMouseEvent.h"
40#include "../../../widgets/AudacityTextEntryDialog.h"
41#include "../../../widgets/wxWidgetsWindowPlacement.h"
43#include <wx/clipbrd.h>
44#include <wx/dcclient.h>
63 if (index != mIndex) {
84LabelTrackView::Index::operator int()
const
108 BindTo( pLabelTrack.get() );
118 auto newParent = track_cast<LabelTrack*>(parent.get());
119 if (oldParent.get() != newParent) {
155 if (
const auto pOther =
dynamic_cast< const LabelTrackView*
>( &other ) ) {
176 return std::static_pointer_cast<LabelTrack>(
FindTrack() );
189 std::vector<UIHandlePtr> results;
190 const wxMouseState &state = st.
state;
196 results.push_back(result);
201 results.push_back(result);
249 wxFontEncoding encoding;
250 if (faceName.empty())
251 encoding = wxFONTENCODING_DEFAULT;
253 encoding = wxFONTENCODING_SYSTEM;
255 auto fontInfo =
size == 0 ? wxFontInfo() : wxFontInfo(
size);
260 return wxFont(fontInfo);
266 wxString facename =
gPrefs->Read(wxT(
"/GUI/LabelFontFacename"), wxT(
""));
287 const auto &mLabels = pTrack->GetLabels();
289 const auto &labelStruct = mLabels[index];
294 int x = labelStruct.x;
295 int x1 = labelStruct.x1;
296 int width = labelStruct.width;
301 bool bTooWideForScreen = width > (r.width-2*xExtra);
303 bool bSimpleCentering =
false;
321 if( bSimpleCentering )
324 xText = (x+x1-width)/2;
333 int rx0,rx1,xText0,xText1;
338 if( bTooWideForScreen )
343 xText1=x1-(width+xExtra);
348 rx0=x-r.width+width+2*xExtra;
352 rx1=x1-(width+2*xExtra);
354 xText1=x1-(width+xExtra);
369 xText = xText0 + (int)((xText1-xText0)*(((float)(r.x-rx0))/(rx1-rx0)));
380 xText = (x+x1-width)/2;
385 bool bOffLeft = xText < r.x+xExtra;
386 bool bOffRight = xText > r.x+r.width-width-xExtra;
390 if( bOffLeft == bOffRight )
398 else if( bOffLeft != bTooWideForScreen)
410 xText =r.x+r.width-width-xExtra;
420 if( xText > (x1-width-xExtra))
421 xText=(x1-width-xExtra);
422 if( xText < x+xExtra )
425 labelStruct.xText = xText;
446 bool bAvoidName =
false;
447 const int nRows = wxMin((r.height / yRowHeight) + 1,
MAX_NUM_ROWS);
449 bAvoidName =
gPrefs->ReadBool(wxT(
"/GUI/ShowTrackNameInWaveform"),
false);
455 const int xStart = INT_MIN;
456 for (
auto &x : xUsed)
462 const auto &mLabels = pTrack->GetLabels();
464 {
int i = -1;
for (
const auto &labelStruct : mLabels) { ++i;
475 while( (iRow<nRowsUsed) && (xUsed[iRow] != x ))
480 if( iRow >= nRowsUsed )
483 while( (iRow<nRows) && (xUsed[iRow] > x ))
494 if( (i==0 ) && (iRow==0) && bAvoidName ){
498 xUsed[iRow]=x+labelStruct.width+xExtra;
499 if( xUsed[iRow] < x1 ) xUsed[iRow]=x1;
500 if( xUsed[iRow] < x2 ) xUsed[iRow]=x2;
505 if( iRow >= nRowsUsed )
508 y= r.y + iRow * yRowHeight +(yRowHeight/2)+1;
513 xUsed[iRow]=x+labelStruct.width+xExtra;
514 if( xUsed[iRow] < x1 ) xUsed[iRow]=x1;
525 wxDC & dc,
const LabelStruct &ls,
const wxRect & r)
551 if((x >= r.x) && (x <= (r.x+r.width)))
557 if((x1 >= r.x) && (x1 <= (r.x+r.width)))
576 wxDC & dc,
const LabelStruct &ls,
const wxRect & r,
577 int GlyphLeft,
int GlyphRight)
591 if((x >= r.x) && (x <= (r.x+r.width)))
592 dc.DrawBitmap(
GetGlyph(GlyphLeft), x-xHalfWidth,yStart,
true);
595 if((x1 >= r.x) && (x1 <= (r.x+r.width)) )
596 dc.DrawBitmap(
GetGlyph(GlyphRight), x1-xHalfWidth,yStart,
true);
624 auto &xText = ls.
xText;
625 const int xStart=wxMax(r.x,xText-
mIconWidth/2);
627 const int xWidth = xEnd-xStart;
629 if( (xStart < (r.x+r.width)) && (xEnd > r.x) && (xWidth>0))
633 (yFrameHeight -
mFontHeight) / 2 + dc.GetFontMetrics().ascent;
634 dc.DrawText(ls.
title, xText, pos);
641 wxDC & dc,
const LabelStruct &ls,
const wxRect & r)
653 auto& xText = ls.
xText;
654 const int xStart = wxMax(r.x, xText -
mIconWidth / 2);
655 const int xEnd = wxMin(r.x + r.width, xText + ls.
width +
mIconWidth / 2);
656 const int xWidth = xEnd - xStart;
658 if ((xStart < (r.x + r.width)) && (xEnd > r.x) && (xWidth > 0))
662 xWidth, textFrameHeight);
663 dc.DrawRectangle(frame);
678 const int xStart = wxMax(r.x, x + xBarShorten / 2);
679 const int xEnd = wxMin(r.x + r.width, x1 - xBarShorten / 2);
680 const int xWidth = xEnd - xStart;
682 if ((xStart < (r.x + r.width)) && (xEnd > r.x) && (xWidth > 0))
686 if (x1 > x + xBarShorten)
687 dc.DrawRectangle(bar);
693 int xPos1,
int xPos2,
int charHeight)
697 dc.SetPen(*wxTRANSPARENT_PEN);
698 wxBrush curBrush = dc.GetBrush();
699 curBrush.SetColour(wxString(wxT(
"BLUE")));
702 dc.DrawRectangle(xPos1-1, top, xPos2-xPos1+1, charHeight);
704 dc.DrawRectangle(xPos2-1, top, xPos1-xPos2+1, charHeight);
715 dc.GetTextExtent(ls.
title.Left(cursorPos), &partWidth, NULL);
731 const auto &mLabels = pTrack->GetLabels();
754 const auto &mLabels = pTrack->GetLabels();
758 getXPos(labelStruct, dc, x1, pos1);
760 getXPos(labelStruct, dc, x2, pos2);
771 auto target = pPanel->
Target();
775 return &*handle->
mpHit;
781#include "../../../TrackPanelDrawingContext.h"
790 auto &dc = context.
dc;
792 const auto &zoomInfo = *artist->pZoomInfo;
794 auto pHit =
findHit( artist->parent );
802 const auto pTrack = std::static_pointer_cast< const LabelTrack >(
803 FindTrack()->SubstitutePendingChangedTrack());
804 const auto &mLabels = pTrack->GetLabels();
810 wxCoord textWidth, textHeight;
815 for (
const auto &labelStruct : mLabels) {
816 dc.GetTextExtent(labelStruct.title, &textWidth, &textHeight);
817 labelStruct.width = textWidth;
826 mTextHeight = dc.GetFontMetrics().ascent + dc.GetFontMetrics().descent;
831 dc.SetBackgroundMode(wxTRANSPARENT);
840 for (
const auto &labelStruct : mLabels)
844 {
int i = -1;
for (
const auto &labelStruct : mLabels) { ++i;
847 if( pHit && i == pHit->mMouseOverLabelLeft )
848 GlyphLeft = (pHit->mEdge & 4) ? 6:9;
849 if( pHit && i == pHit->mMouseOverLabelRight )
850 GlyphRight = (pHit->mEdge & 4) ? 7:4;
851 DrawGlyphs( dc, labelStruct, r, GlyphLeft, GlyphRight );
854 auto &project = *artist->parent->GetProject();
858#ifdef EXPERIMENTAL_TRACK_PANEL_HIGHLIGHTING
859 bool highlightTrack =
false;
861 highlightTrack = target && target->
GetTrack().get() ==
this;
863 int i = -1;
for (
const auto &labelStruct : mLabels) { ++i;
864 bool highlight =
false;
865#ifdef EXPERIMENTAL_TRACK_PANEL_HIGHLIGHTING
866 highlight = highlightTrack && target->GetLabelNum() == i;
893 xpos1, xpos2, dc.GetFontMetrics().ascent + dc.GetFontMetrics().descent);
897 {
int i = -1;
for (
const auto &labelStruct : mLabels) { ++i;
909 int xPos = labelStruct.xText;
919 wxPen currentPen = dc.GetPen();
920 const int CursorWidth=2;
921 currentPen.SetWidth(CursorWidth);
926 currentPen.SetWidth(1);
932 const wxRect &rect,
unsigned iPass )
935 Draw( context, rect );
949 bool finished =
false;
957 const auto &mLabels = pTrack->GetLabels();
958 const auto &labelStruct = mLabels[labelIndex];
959 const auto &
title = labelStruct.title;
960 const int length =
title.length();
961 while (!finished && (charIndex < length + 1))
963 int unichar = (int)
title.at( charIndex-1 );
964 if( (0xDC00 <= unichar) && (unichar <= 0xDFFF)){
968 subString =
title.Left(charIndex);
970 dc.GetTextExtent(subString, &partWidth, NULL);
973 dc.GetTextExtent(subString.Right(1), &oneWidth, NULL);
974 bound = labelStruct.xText + partWidth - oneWidth * 0.5;
979 result = charIndex - 1;
1034 dc.GetTextExtent(wxT(
"(Test String)|[yp]"), NULL, &
mFontHeight, &charDescent, &charLeading);
1042 const int CursorExtraHeight=2;
1043 mFontHeight += CursorExtraHeight - (charLeading+charDescent);
1053 return index >= 0 && index < static_cast<int>(track->GetLabels().size());
1070 const auto &mLabels = pTrack->GetLabels();
1072 wxString left, right;
1074 auto &text = labelStruct.title;
1086 wxString data = text.Mid(init, cur - init);
1090 left = text.Left(init);
1093 if (cur < (
int)text.length())
1094 right = text.Mid(cur);
1097 text = left + right;
1102 if (wxTheClipboard->Open()) {
1104 wxTheClipboard->SetData(
safenew wxTextDataObject(data));
1105 wxTheClipboard->Close();
1123 const auto &mLabels = pTrack->GetLabels();
1136 wxString data = labelStruct.title.Mid(init, cur-init);
1139 if (wxTheClipboard->Open()) {
1141 wxTheClipboard->SetData(
safenew wxTextDataObject(data));
1142 wxTheClipboard->Close();
1159 wxString text, left, right;
1163 if (wxTheClipboard->Open()) {
1164 wxTextDataObject data;
1165 wxTheClipboard->GetData(data);
1166 wxTheClipboard->Close();
1167 text = data.GetText();
1175 for (
int i = 0; i < (int)text.length(); i++) {
1176 if (wxIscntrl(text[i])) {
1182 const auto &mLabels = pTrack->GetLabels();
1184 auto &
title = labelStruct.title;
1188 left =
title.Left(init);
1189 if (cur < (
int)
title.length())
1190 right =
title.Mid(cur);
1192 title = left + text + right;
1209 const auto& mLabels = pTrack->GetLabels();
1211 auto&
title = labelStruct.title;
1222 return wxTheClipboard->IsSupported(wxDF_UNICODETEXT);
1242 const auto pTrack = &track;
1243 const auto &mLabels = pTrack->
GetLabels();
1244 {
int i = -1;
for (
const auto &labelStruct : mLabels) { ++i;
1259 if( abs(labelStruct.y - (y - (
mTextHeight+3)/2)) < d1 &&
1260 abs(labelStruct.x1 - d2 -x) < d1)
1263 if(abs(labelStruct.x1 - x) < d2 )
1268 if( abs(labelStruct.x1-labelStruct.x) < 5.0 )
1278 else if( abs(labelStruct.y - (y - (
mTextHeight+3)/2)) < d1 &&
1279 abs(labelStruct.x + d2 - x) < d1 )
1282 if(abs(labelStruct.x - x) < d2 )
1286 else if (x >= labelStruct.x && x <= labelStruct.x1 &&
1298 const auto pTrack = &track;
1299 const auto &mLabels = pTrack->
GetLabels();
1300 for (
int nn = (
int)mLabels.size(); nn--;) {
1301 const auto &labelStruct = mLabels[nn];
1324 int keyCode = evt.GetKeyCode();
1325 return (keyCode < WXK_START
1326 && keyCode != WXK_SPACE && keyCode != WXK_DELETE && keyCode != WXK_RETURN) ||
1327 (keyCode >= WXK_NUMPAD0 && keyCode <= WXK_DIVIDE) ||
1328 (keyCode >= WXK_NUMPAD_EQUAL && keyCode <= WXK_NUMPAD_DIVIDE) ||
1329#if defined(__WXMAC__)
1330 (keyCode > WXK_RAW_CONTROL) ||
1332 (keyCode > WXK_WINDOWS_MENU);
1338 int keyCode = evt.GetKeyCode();
1343 return keyCode < WXK_START ||
1344 (keyCode >= WXK_END && keyCode < WXK_UP) ||
1345 (keyCode == WXK_RIGHT) ||
1346 (keyCode >= WXK_NUMPAD0 && keyCode <= WXK_DIVIDE) ||
1347 (keyCode >= WXK_NUMPAD_SPACE && keyCode <= WXK_NUMPAD_ENTER) ||
1348 (keyCode >= WXK_NUMPAD_HOME && keyCode <= WXK_NUMPAD_END) ||
1349 (keyCode >= WXK_NUMPAD_DELETE && keyCode <= WXK_NUMPAD_DIVIDE) ||
1350#if defined(__WXMAC__)
1351 (keyCode > WXK_RAW_CONTROL) ||
1353 (keyCode > WXK_WINDOWS_MENU);
1360 int mods =
event.GetModifiers();
1361 auto code =
event.GetKeyCode();
1363 const auto& mLabels = pTrack->GetLabels();
1367 if (code == WXK_F2 && mods == wxMOD_CONTROL && !mLabels.empty()) {
1372 if (mods != wxMOD_NONE && mods != wxMOD_SHIFT) {
1377 if ((code == WXK_TAB || code == WXK_NUMPAD_TAB) &&
1387 bool typeToCreateLabel;
1388 gPrefs->Read(wxT(
"/GUI/TypeToCreateLabel"), &typeToCreateLabel,
false);
1400 if (pProj->GetAudioIOToken() > 0 &&
1401 gAudioIO->IsStreamActive(pProj->GetAudioIOToken()))
1404 pProj->GetPlayRegion(&t0, &t1);
1405 if (pProj->mViewInfo.selectedRegion.t0() == t0 &&
1406 pProj->mViewInfo.selectedRegion.t1() == t1) {
1415 selectedRegion.t1()) != wxNOT_FOUND ) {
1434 wxKeyEvent & event,
ViewInfo &viewInfo, wxWindow *WXUNUSED(pParent),
1442 const auto &mLabels = pTrack->GetLabels();
1444 auto &
title = labelStruct.title;
1472 else if (!event.GetSkipped())
1488 const auto &mLabels = pTrack->GetLabels();
1490 auto &
title = labelStruct.title;
1511 else if (!event.GetSkipped())
1522 bool updated =
false;
1525 int keyCode =
event.GetKeyCode();
1526 const int mods =
event.GetModifiers();
1531 if ((keyCode != WXK_F2 && mods != wxMOD_NONE && mods != wxMOD_SHIFT)
1532 || (keyCode == WXK_F2 && mods != wxMOD_CONTROL)) {
1539 const auto &mLabels = pTrack->GetLabels();
1543 auto &
title = labelStruct.title;
1551 int len =
title.length();
1566 if( ((
int)wchar > 0xDFFF) || ((
int)wchar <0xDC00)){
1585 case WXK_NUMPAD_DELETE:
1587 int len =
title.length();
1601 if( ((
int)wchar > 0xDBFF) || ((
int)wchar <0xD800)){
1620 case WXK_NUMPAD_HOME:
1623 if (mods == wxMOD_SHIFT)
1630 case WXK_NUMPAD_END:
1633 if (mods == wxMOD_SHIFT)
1640 case WXK_NUMPAD_LEFT:
1650 more = !(((int)wchar > 0xDFFF) || ((int)wchar < 0xDC00));
1654 if (mods != wxMOD_SHIFT)
1661 case WXK_NUMPAD_RIGHT:
1671 more = !(((int)wchar > 0xDBFF) || ((int)wchar < 0xD800));
1675 if (mods != wxMOD_SHIFT)
1691 case WXK_NUMPAD_ENTER:
1705 case WXK_WINDOWS_MENU:
1725 case WXK_NUMPAD_TAB:
1726 if (!mLabels.empty()) {
1727 int len = (int) mLabels.size();
1734 if (event.ShiftDown()) {
1744 if (event.ShiftDown()) {
1747 if (newSel.
t0() > mLabels[0].getT0()) {
1757 if (newSel.
t0() < mLabels[len - 1].getT0()) {
1771 newSel = labelStruct.selectedRegion;
1780 auto message =
XO(
"%s %d of %d")
1817 const int mods =
event.GetModifiers();
1818 if (mods != wxMOD_NONE && mods != wxMOD_SHIFT) {
1827 wxChar charCode =
event.GetUnicodeKey();
1830 if (charCode == 0 || wxIscntrl(charCode)) {
1839 if (wxIsspace(charCode)) {
1844 gPrefs->Read(wxT(
"/GUI/DialogForNameNewLabel"), &useDialog,
false);
1849 project, selectedRegion, charCode,
title) ==
1853 pTrack->SetSelected(
true);
1854 pTrack->AddLabel(selectedRegion,
title);
1860 pTrack->SetSelected(
true);
1878 const auto& mLabels = pTrack->GetLabels();
1880 auto&
title = labelStruct.title;
1915 wxWindow *parent = wxWindow::FindFocus();
1924 menu.Bind(wxEVT_MENU,
1925 [
this, &project]( wxCommandEvent &event ){
1948 wxClientDC dc(parent);
1958 static_cast<void>(success);
1981 switch (evt.GetId())
2001 project, selectedRegion.t0(), selectedRegion.t1() ))
2033 wxString left, right;
2041 const auto &mLabels = pTrack->GetLabels();
2043 auto &
title = labelStruct.title;
2046 left =
title.Left(init);
2048 if (cur < (
int)
title.length())
2049 right =
title.Mid(cur);
2051 title = left + right;
2070 const double delta = 1.0e-7;
2072 const auto &mLabels = pTrack->GetLabels();
2073 {
int i = -1;
for (
const auto &labelStruct : mLabels) { ++i;
2074 if( fabs( labelStruct.getT0() - t ) > delta )
2076 if( fabs( labelStruct.getT1() - t1 ) > delta )
2089 const wxString &
title,
int restoreFocus)
2093 auto pos = pTrack->AddLabel( selectedRegion,
title );
2147 auto fix = [&](
Index& index) {
2148 if (index == former)
2150 else if (former < index && index <= present)
2152 else if (former > index && index >= present)
2237 const int nSpecRows =
2239 const char *XmpBmp[nSpecRows];
2255 if( iHighlight==1 ) XmpBmp[5]=
"5 c #FFFFFF";
2256 if( iHighlight==2 ) XmpBmp[6]=
"6 c #FFFFFF";
2257 if( iHighlight==3 ) XmpBmp[7]=
"7 c #FFFFFF";
2260 if( iConfig==0) { XmpBmp[3]=
"3 c none"; XmpBmp[5]=
"5 c none"; }
2261 if( iConfig==1) { XmpBmp[4]=
"4 c none"; XmpBmp[7]=
"7 c none"; }
2280#include "../../../LabelDialog.h"
2287 freqFormat =
settings.GetFrequencySelectionFormatName();
2301 if (dlg.ShowModal() == wxID_OK) {
2309 const SelectedRegion& region,
const wxString& initialValue, wxString& value)
2316 trackPanel.FindTrackRect( trackFocus.Get() ).GetBottomLeft();
2323 position = trackPanel.ClientToScreen(position);
2333 wxRect dialogScreenRect = dialog.GetScreenRect();
2334 wxRect projScreenRect = window.GetScreenRect();
2335 wxPoint max = projScreenRect.GetBottomRight() + wxPoint{ -dialogScreenRect.width, -dialogScreenRect.height };
2336 if (dialogScreenRect.x > max.x) {
2338 dialog.Move(position);
2340 if (dialogScreenRect.y > max.y) {
2342 dialog.Move(position);
2345 dialog.SetInsertionPointEnd();
2346 int status = dialog.ShowModal();
2347 if (status != wxID_CANCEL) {
2348 value = dialog.GetValue();
2349 value.Trim(
true).Trim(
false);
2358 return std::make_shared<LabelTrackView>( track.SharedPointer() );
2365 std::make_shared<LabelTrackVRulerControls>( shared_from_this() );
std::shared_ptr< UIHandle > UIHandlePtr
static bool IsGoodLabelEditKey(const wxKeyEvent &evt)
This returns true for keys we capture for label editing.
@ OnDeleteSelectedLabelID
DEFINE_ATTACHED_VIRTUAL_OVERRIDE(DoGetLabelTrackView)
static const char *const GlyphXpmRegionSpec[]
static bool IsGoodLabelFirstKey(const wxKeyEvent &evt)
Returns true for keys we capture to start a label.
constexpr int NUM_GLYPH_HIGHLIGHTS
constexpr int MAX_NUM_ROWS
constexpr int NUM_GLYPH_CONFIGS
an object holding per-project preferred sample rate
AUDACITY_DLL_API wxFrame & GetProjectFrame(AudacityProject &project)
Get the top-level window associated with the project (as a wxFrame only, when you do not need to use ...
@ EndSeparator
Delimits the end of a group (of which it is a part)
static Settings & settings()
static wxBrush labelSelectedBrush
static void Line(wxDC &dc, wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
static wxPen labelSurroundPen
static wxBrush labelTextNormalBrush
static wxBrush labelTextEditBrush
static wxBrush labelUnselectedBrush
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Wrap wxTextEntryDialog so that caption IS translatable.
static AudioIOBase * Get()
void Popup(const BasicUI::WindowPlacement &window, const Point &pos={})
Display the menu at pos, invoke at most one action, then hide it.
Subclass & Get(const RegisteredFactory &key)
Get reference to an attachment, creating on demand if not present, down-cast it to Subclass.
void Reparent(const std::shared_ptr< Track > &parent) override
Object may be shared among tracks but hold a special back-pointer to one of them; reassign it.
std::shared_ptr< Track > FindTrack()
Dialog for editing labels.
std::shared_ptr< LabelTrackHit > mpHit
static UIHandlePtr HitTest(std::weak_ptr< LabelGlyphHandle > &holder, const wxMouseState &state, const std::shared_ptr< LabelTrack > &pLT, const wxRect &rect)
A LabelStruct holds information for ONE label in a LabelTrack.
int x1
Pixel position of left hand glyph.
int x
width of the text in pixels.
int width
Text of the label.
int xText
Pixel position of right hand glyph.
int y
Pixel position of left hand side of text box.
static UIHandlePtr HitTest(std::weak_ptr< LabelTextHandle > &holder, const wxMouseState &state, const std::shared_ptr< LabelTrack > &pLT)
std::shared_ptr< LabelTrack > GetTrack() const
A LabelTrack is a Track that holds labels (LabelStruct).
const LabelArray & GetLabels() const
void CalcHighlightXs(int *x1, int *x2) const
std::shared_ptr< LabelTrack > FindLabelTrack()
void ResetTextSelection()
static LabelTrackView & Get(LabelTrack &)
unsigned CaptureKey(wxKeyEvent &event, ViewInfo &viewInfo, wxWindow *pParent, AudacityProject *project) override
void OnSelectionChange(LabelTrackEvent &)
bool DoCaptureKey(AudacityProject &project, wxKeyEvent &event)
static constexpr int TextFramePadding
void RemoveSelectedText()
std::shared_ptr< TrackVRulerControls > DoGetVRulerControls() override
static constexpr int LabelBarHeight
static void DrawLines(wxDC &dc, const LabelStruct &ls, const wxRect &r)
void Reparent(const std::shared_ptr< Track > &parent) override
Object may be shared among tracks but hold a special back-pointer to one of them; reassign it.
static void DrawHighlight(wxDC &dc, const LabelStruct &ls, int xPos1, int xPos2, int charHeight)
Draws text-selected region within the label.
bool CopySelectedText(AudacityProject &project)
static void calculateFontHeight(wxDC &dc)
static wxBitmap mBoundaryGlyphs[NUM_GLYPH_CONFIGS *NUM_GLYPH_HIGHLIGHTS]
~LabelTrackView() override
void OnLabelAdded(LabelTrackEvent &)
static void DrawGlyphs(wxDC &dc, const LabelStruct &ls, const wxRect &r, int GlyphLeft, int GlyphRight)
static int DialogForLabelName(AudacityProject &project, const SelectedRegion ®ion, const wxString &initialValue, wxString &value)
int AddLabel(const SelectedRegion ®ion, const wxString &title={}, int restoreFocus=-1)
bool IsValidIndex(const Index &index, AudacityProject &project) const
void BindTo(LabelTrack *pParent)
static bool mbGlyphsReady
void ComputeLayout(const wxRect &r, const ZoomInfo &zoomInfo) const
int mRestoreFocus
initial cursor position
static void DrawBar(wxDC &dc, const LabelStruct &ls, const wxRect &r)
static wxFont GetFont(const wxString &faceName, int size=DefaultFontSize)
void ShowContextMenu(AudacityProject &project)
bool CalcCursorX(AudacityProject &project, int *x) const
int GetLabelIndex(double t, double t1)
void UnbindFrom(LabelTrack *pParent)
void ComputeTextPosition(const wxRect &r, int index) const
int mInitialCursorPos
current cursor position
void OnContextMenu(AudacityProject &project, wxCommandEvent &evt)
unsigned KeyDown(wxKeyEvent &event, ViewInfo &viewInfo, wxWindow *pParent, AudacityProject *project) override
LabelTrackView(const LabelTrackView &)=delete
Index mTextEditIndex
Index of the current label text being edited.
bool DoChar(AudacityProject &project, NotifyingSelectedRegion &sel, wxKeyEvent &event)
void SetTextSelection(int labelIndex, int start=1, int end=1)
bool PasteSelectedText(AudacityProject &project, double sel0, double sel1)
static void DoEditLabels(AudacityProject &project, LabelTrack *lt=nullptr, int index=-1)
bool SelectAllText(AudacityProject &project)
std::weak_ptr< LabelTextHandle > mTextHandle
void CopyTo(Track &track) const override
Copy state, for undo/redo purposes.
bool DoKeyDown(AudacityProject &project, NotifyingSelectedRegion &sel, wxKeyEvent &event)
KeyEvent is called for every keypress when over the label track.
static void DrawText(wxDC &dc, const LabelStruct &ls, const wxRect &r)
void CreateCustomGlyphs()
static wxBitmap & GetGlyph(int i)
int FindCursorPosition(int labelIndex, wxCoord xPos)
convert pixel coordinate to character position in text box
static int GetTextFrameHeight()
std::weak_ptr< LabelGlyphHandle > mGlyphHandle
void Draw(TrackPanelDrawingContext &context, const wxRect &r) const
void OnLabelDeleted(LabelTrackEvent &)
void OnLabelPermuted(LabelTrackEvent &)
void RestoreFlags(const Flags &flags)
unsigned Char(wxKeyEvent &event, ViewInfo &viewInfo, wxWindow *pParent, AudacityProject *project) override
bool CutSelectedText(AudacityProject &project)
bool IsTextSelected(AudacityProject &project) const
static bool OverTextBox(const LabelStruct *pLabel, int x, int y)
static bool IsTextClipSupported()
int GetTextEditIndex(AudacityProject &project) const
void SetNavigationIndex(int index)
static void OverGlyph(const LabelTrack &track, LabelTrackHit &hit, int x, int y)
static void DrawTextBox(wxDC &dc, const LabelStruct &ls, const wxRect &r)
static int OverATextBox(const LabelTrack &track, int xx, int yy)
std::vector< UIHandlePtr > DetailedHitTest(const TrackPanelMouseState &state, const AudacityProject *pProject, int currentTool, bool bMultiTool) override
static constexpr int TextFrameYOffset
void SetCurrentCursorPosition(int pos)
int GetNavigationIndex(AudacityProject &project) const
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
static ProjectHistory & Get(AudacityProject &project)
static ProjectRate & Get(AudacityProject &project)
static ProjectSettings & Get(AudacityProject &project)
static ProjectWindow & Get(AudacityProject &project)
void ScrollIntoView(double pos)
Defines a selected portion of a project.
static bool IsSelectedOrSyncLockSelected(const Track *pTrack)
wxColour & Colour(int iIndex)
wxBitmap & Bitmap(int iIndex)
static TrackArtist * Get(TrackPanelDrawingContext &)
Abstract base class for an object holding data associated with points on a time axis.
auto Any() -> TrackIterRange< TrackType >
static TrackList & Get(AudacityProject &project)
virtual void Draw(TrackPanelDrawingContext &context, const wxRect &rect, unsigned iPass)
The TrackPanel class coordinates updates and operations on the main part of the screen which contains...
static TrackPanel & Get(AudacityProject &project)
void CopyTo(Track &track) const override
Copy state, for undo/redo purposes.
static TrackView & Get(Track &)
NotifyingSelectedRegion selectedRegion
static ViewInfo & Get(AudacityProject &project)
int GetLeftOffset() const
wxInt64 TimeToPosition(double time, wxInt64 origin=0, bool ignoreFisheye=false) const
STM: Converts a project time to screen x position.
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
AUDACITY_DLL_API void DrawBackgroundWithSelection(TrackPanelDrawingContext &context, const wxRect &rect, const Track *track, const wxBrush &selBrush, const wxBrush &unselBrush, bool useSelection=true)
void getXPos(const LabelStruct &ls, wxDC &dc, int *xPos1, int cursorPos)
LabelTrackHit * findHit(TrackPanel *pPanel)
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
For defining overrides of the method.
const std::weak_ptr< Track > mpTrack
int mMouseOverLabelRight
Keeps track of which left label the mouse is currently over.
int mMouseOverLabelLeft
Keeps track of which (ranged) label the mouse is currently over.
void SetModified(bool modified)
Index & operator=(int index)