18#include "../../../LabelTrack.h"
21#include "../../../widgets/BasicMenu.h"
23#include "../../../HitTestResult.h"
28#include "../../../ProjectWindow.h"
29#include "../../../ProjectWindows.h"
30#include "../../../RefreshCode.h"
33#include "../../../TrackArt.h"
34#include "../../../TrackArtist.h"
35#include "../../../TrackPanelAx.h"
36#include "../../../TrackPanel.h"
37#include "../../../TrackPanelMouseEvent.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)
129 case LabelTrackEvent::Addition:
130 return OnLabelAdded(e);
131 case LabelTrackEvent::Deletion:
132 return OnLabelDeleted(e);
133 case LabelTrackEvent::Permutation:
134 return OnLabelPermuted(e);
135 case LabelTrackEvent::Selection:
136 return OnSelectionChange(e);
148 if (
const auto pOther =
dynamic_cast< const LabelTrackView*
>( &other ) ) {
169 return std::static_pointer_cast<LabelTrack>(
FindTrack() );
182 std::vector<UIHandlePtr> results;
183 const wxMouseState &state = st.
state;
189 results.push_back(result);
194 results.push_back(result);
242 wxFontEncoding encoding;
243 if (faceName.empty())
244 encoding = wxFONTENCODING_DEFAULT;
246 encoding = wxFONTENCODING_SYSTEM;
248 auto fontInfo =
size == 0 ? wxFontInfo() : wxFontInfo(
size);
253 return wxFont(fontInfo);
259 wxString facename =
gPrefs->Read(
wxT(
"/GUI/LabelFontFacename"),
wxT(
""));
280 const auto &mLabels = pTrack->GetLabels();
282 const auto &labelStruct = mLabels[index];
287 int x = labelStruct.x;
288 int x1 = labelStruct.x1;
289 int width = labelStruct.width;
294 bool bTooWideForScreen = width > (r.width-2*xExtra);
296 bool bSimpleCentering =
false;
314 if( bSimpleCentering )
317 xText = (x+x1-width)/2;
326 int rx0,rx1,xText0,xText1;
331 if( bTooWideForScreen )
336 xText1=x1-(width+xExtra);
341 rx0=x-r.width+width+2*xExtra;
345 rx1=x1-(width+2*xExtra);
347 xText1=x1-(width+xExtra);
362 xText = xText0 + (int)((xText1-xText0)*(((float)(r.x-rx0))/(rx1-rx0)));
373 xText = (x+x1-width)/2;
378 bool bOffLeft = xText < r.x+xExtra;
379 bool bOffRight = xText > r.x+r.width-width-xExtra;
383 if( bOffLeft == bOffRight )
391 else if( bOffLeft != bTooWideForScreen)
403 xText =r.x+r.width-width-xExtra;
413 if( xText > (x1-width-xExtra))
414 xText=(x1-width-xExtra);
415 if( xText < x+xExtra )
418 labelStruct.xText = xText;
439 bool bAvoidName =
false;
440 const int nRows = wxMin((r.height / yRowHeight) + 1,
MAX_NUM_ROWS);
442 bAvoidName =
gPrefs->ReadBool(
wxT(
"/GUI/ShowTrackNameInWaveform"),
false);
448 const int xStart = INT_MIN;
449 for (
auto &x : xUsed)
455 const auto &mLabels = pTrack->GetLabels();
457 {
int i = -1;
for (
const auto &labelStruct : mLabels) { ++i;
468 while( (iRow<nRowsUsed) && (xUsed[iRow] != x ))
473 if( iRow >= nRowsUsed )
476 while( (iRow<nRows) && (xUsed[iRow] > x ))
487 if( (i==0 ) && (iRow==0) && bAvoidName ){
491 xUsed[iRow]=x+labelStruct.width+xExtra;
492 if( xUsed[iRow] < x1 ) xUsed[iRow]=x1;
493 if( xUsed[iRow] < x2 ) xUsed[iRow]=x2;
498 if( iRow >= nRowsUsed )
501 y= r.y + iRow * yRowHeight +(yRowHeight/2)+1;
506 xUsed[iRow]=x+labelStruct.width+xExtra;
507 if( xUsed[iRow] < x1 ) xUsed[iRow]=x1;
518 wxDC & dc,
const LabelStruct &ls,
const wxRect & r)
544 if((x >= r.x) && (x <= (r.x+r.width)))
550 if((x1 >= r.x) && (x1 <= (r.x+r.width)))
569 wxDC & dc,
const LabelStruct &ls,
const wxRect & r,
570 int GlyphLeft,
int GlyphRight)
584 if((x >= r.x) && (x <= (r.x+r.width)))
585 dc.DrawBitmap(
GetGlyph(GlyphLeft), x-xHalfWidth,yStart,
true);
588 if((x1 >= r.x) && (x1 <= (r.x+r.width)) )
589 dc.DrawBitmap(
GetGlyph(GlyphRight), x1-xHalfWidth,yStart,
true);
617 auto &xText = ls.
xText;
618 const int xStart=wxMax(r.x,xText-
mIconWidth/2);
620 const int xWidth = xEnd-xStart;
622 if( (xStart < (r.x+r.width)) && (xEnd > r.x) && (xWidth>0))
626 (yFrameHeight -
mFontHeight) / 2 + dc.GetFontMetrics().ascent;
627 dc.DrawText(ls.
title, xText, pos);
634 wxDC & dc,
const LabelStruct &ls,
const wxRect & r)
646 auto& xText = ls.
xText;
647 const int xStart = wxMax(r.x, xText -
mIconWidth / 2);
648 const int xEnd = wxMin(r.x + r.width, xText + ls.
width +
mIconWidth / 2);
649 const int xWidth = xEnd - xStart;
651 if ((xStart < (r.x + r.width)) && (xEnd > r.x) && (xWidth > 0))
655 xWidth, textFrameHeight);
656 dc.DrawRectangle(frame);
671 const int xStart = wxMax(r.x, x + xBarShorten / 2);
672 const int xEnd = wxMin(r.x + r.width, x1 - xBarShorten / 2);
673 const int xWidth = xEnd - xStart;
675 if ((xStart < (r.x + r.width)) && (xEnd > r.x) && (xWidth > 0))
679 if (x1 > x + xBarShorten)
680 dc.DrawRectangle(bar);
686 int xPos1,
int xPos2,
int charHeight)
690 dc.SetPen(*wxTRANSPARENT_PEN);
691 wxBrush curBrush = dc.GetBrush();
692 curBrush.SetColour(wxString(
wxT(
"BLUE")));
695 dc.DrawRectangle(xPos1-1, top, xPos2-xPos1+1, charHeight);
697 dc.DrawRectangle(xPos2-1, top, xPos1-xPos2+1, charHeight);
708 dc.GetTextExtent(ls.
title.Left(cursorPos), &partWidth, NULL);
724 const auto &mLabels = pTrack->GetLabels();
747 const auto &mLabels = pTrack->GetLabels();
751 getXPos(labelStruct, dc, x1, pos1);
753 getXPos(labelStruct, dc, x2, pos2);
764 auto target = pPanel->
Target();
768 return &*handle->
mpHit;
774#include "../../../TrackPanelDrawingContext.h"
783 auto &dc = context.
dc;
785 const auto &zoomInfo = *artist->pZoomInfo;
787 auto pHit =
findHit( artist->parent );
795 const auto pTrack = std::static_pointer_cast< const LabelTrack >(
796 FindTrack()->SubstitutePendingChangedTrack());
797 const auto &mLabels = pTrack->GetLabels();
803 wxCoord textWidth, textHeight;
808 for (
const auto &labelStruct : mLabels) {
809 dc.GetTextExtent(labelStruct.title, &textWidth, &textHeight);
810 labelStruct.width = textWidth;
819 mTextHeight = dc.GetFontMetrics().ascent + dc.GetFontMetrics().descent;
824 dc.SetBackgroundMode(wxTRANSPARENT);
833 for (
const auto &labelStruct : mLabels)
837 {
int i = -1;
for (
const auto &labelStruct : mLabels) { ++i;
840 if( pHit && i == pHit->mMouseOverLabelLeft )
841 GlyphLeft = (pHit->mEdge & 4) ? 6:9;
842 if( pHit && i == pHit->mMouseOverLabelRight )
843 GlyphRight = (pHit->mEdge & 4) ? 7:4;
844 DrawGlyphs( dc, labelStruct, r, GlyphLeft, GlyphRight );
847 auto &project = *artist->parent->GetProject();
851#ifdef EXPERIMENTAL_TRACK_PANEL_HIGHLIGHTING
852 bool highlightTrack =
false;
854 highlightTrack = target && target->
GetTrack().get() ==
this;
856 int i = -1;
for (
const auto &labelStruct : mLabels) { ++i;
857 bool highlight =
false;
858#ifdef EXPERIMENTAL_TRACK_PANEL_HIGHLIGHTING
859 highlight = highlightTrack && target->GetLabelNum() == i;
886 xpos1, xpos2, dc.GetFontMetrics().ascent + dc.GetFontMetrics().descent);
890 {
int i = -1;
for (
const auto &labelStruct : mLabels) { ++i;
902 int xPos = labelStruct.xText;
912 wxPen currentPen = dc.GetPen();
913 const int CursorWidth=2;
914 currentPen.SetWidth(CursorWidth);
919 currentPen.SetWidth(1);
925 const wxRect &rect,
unsigned iPass )
928 Draw( context, rect );
942 bool finished =
false;
950 const auto &mLabels = pTrack->GetLabels();
951 const auto &labelStruct = mLabels[labelIndex];
952 const auto &
title = labelStruct.title;
953 const int length =
title.length();
954 while (!finished && (charIndex < length + 1))
956 int unichar = (int)
title.at( charIndex-1 );
957 if( (0xDC00 <= unichar) && (unichar <= 0xDFFF)){
961 subString =
title.Left(charIndex);
963 dc.GetTextExtent(subString, &partWidth, NULL);
966 dc.GetTextExtent(subString.Right(1), &oneWidth, NULL);
967 bound = labelStruct.xText + partWidth - oneWidth * 0.5;
972 result = charIndex - 1;
1027 dc.GetTextExtent(
wxT(
"(Test String)|[yp]"), NULL, &
mFontHeight, &charDescent, &charLeading);
1035 const int CursorExtraHeight=2;
1036 mFontHeight += CursorExtraHeight - (charLeading+charDescent);
1046 return index >= 0 && index < static_cast<int>(track->GetLabels().size());
1063 const auto &mLabels = pTrack->GetLabels();
1065 wxString left, right;
1067 auto &text = labelStruct.title;
1079 wxString data = text.Mid(init, cur - init);
1083 left = text.Left(init);
1086 if (cur < (
int)text.length())
1087 right = text.Mid(cur);
1090 text = left + right;
1095 if (wxTheClipboard->Open()) {
1097 wxTheClipboard->SetData(
safenew wxTextDataObject(data));
1098 wxTheClipboard->Close();
1116 const auto &mLabels = pTrack->GetLabels();
1129 wxString data = labelStruct.title.Mid(init, cur-init);
1132 if (wxTheClipboard->Open()) {
1134 wxTheClipboard->SetData(
safenew wxTextDataObject(data));
1135 wxTheClipboard->Close();
1152 wxString text, left, right;
1156 if (wxTheClipboard->Open()) {
1157 wxTextDataObject data;
1158 wxTheClipboard->GetData(data);
1159 wxTheClipboard->Close();
1160 text = data.GetText();
1168 for (
int i = 0; i < (int)text.length(); i++) {
1169 if (wxIscntrl(text[i])) {
1175 const auto &mLabels = pTrack->GetLabels();
1177 auto &
title = labelStruct.title;
1181 left =
title.Left(init);
1182 if (cur < (
int)
title.length())
1183 right =
title.Mid(cur);
1185 title = left + text + right;
1202 const auto& mLabels = pTrack->GetLabels();
1204 auto&
title = labelStruct.title;
1215 return wxTheClipboard->IsSupported(wxDF_UNICODETEXT);
1235 const auto pTrack = &track;
1236 const auto &mLabels = pTrack->
GetLabels();
1237 {
int i = -1;
for (
const auto &labelStruct : mLabels) { ++i;
1252 if( abs(labelStruct.y - (y - (
mTextHeight+3)/2)) < d1 &&
1253 abs(labelStruct.x1 - d2 -x) < d1)
1256 if(abs(labelStruct.x1 - x) < d2 )
1261 if( abs(labelStruct.x1-labelStruct.x) < 5.0 )
1271 else if( abs(labelStruct.y - (y - (
mTextHeight+3)/2)) < d1 &&
1272 abs(labelStruct.x + d2 - x) < d1 )
1275 if(abs(labelStruct.x - x) < d2 )
1279 else if (x >= labelStruct.x && x <= labelStruct.x1 &&
1291 const auto pTrack = &track;
1292 const auto &mLabels = pTrack->
GetLabels();
1293 for (
int nn = (
int)mLabels.size(); nn--;) {
1294 const auto &labelStruct = mLabels[nn];
1317 int keyCode = evt.GetKeyCode();
1318 return (keyCode < WXK_START
1319 && keyCode != WXK_SPACE && keyCode != WXK_DELETE && keyCode != WXK_RETURN) ||
1320 (keyCode >= WXK_NUMPAD0 && keyCode <= WXK_DIVIDE) ||
1321 (keyCode >= WXK_NUMPAD_EQUAL && keyCode <= WXK_NUMPAD_DIVIDE) ||
1322#if defined(__WXMAC__)
1323 (keyCode > WXK_RAW_CONTROL) ||
1325 (keyCode > WXK_WINDOWS_MENU);
1331 int keyCode = evt.GetKeyCode();
1336 return keyCode < WXK_START ||
1337 (keyCode >= WXK_END && keyCode < WXK_UP) ||
1338 (keyCode == WXK_RIGHT) ||
1339 (keyCode >= WXK_NUMPAD0 && keyCode <= WXK_DIVIDE) ||
1340 (keyCode >= WXK_NUMPAD_SPACE && keyCode <= WXK_NUMPAD_ENTER) ||
1341 (keyCode >= WXK_NUMPAD_HOME && keyCode <= WXK_NUMPAD_END) ||
1342 (keyCode >= WXK_NUMPAD_DELETE && keyCode <= WXK_NUMPAD_DIVIDE) ||
1343#if defined(__WXMAC__)
1344 (keyCode > WXK_RAW_CONTROL) ||
1346 (keyCode > WXK_WINDOWS_MENU);
1353 int mods =
event.GetModifiers();
1354 auto code =
event.GetKeyCode();
1356 const auto& mLabels = pTrack->GetLabels();
1360 if (code == WXK_F2 && mods == wxMOD_CONTROL && !mLabels.empty()) {
1365 if (mods != wxMOD_NONE && mods != wxMOD_SHIFT) {
1370 if ((code == WXK_TAB || code == WXK_NUMPAD_TAB) &&
1380 bool typeToCreateLabel;
1381 gPrefs->Read(
wxT(
"/GUI/TypeToCreateLabel"), &typeToCreateLabel,
false);
1393 if (pProj->GetAudioIOToken() > 0 &&
1394 gAudioIO->IsStreamActive(pProj->GetAudioIOToken()))
1397 pProj->GetPlayRegion(&t0, &t1);
1398 if (pProj->mViewInfo.selectedRegion.t0() == t0 &&
1399 pProj->mViewInfo.selectedRegion.t1() == t1) {
1408 selectedRegion.t1()) != wxNOT_FOUND ) {
1427 wxKeyEvent & event,
ViewInfo &viewInfo, wxWindow *WXUNUSED(pParent),
1435 const auto &mLabels = pTrack->GetLabels();
1437 auto &
title = labelStruct.title;
1465 else if (!event.GetSkipped())
1481 const auto &mLabels = pTrack->GetLabels();
1483 auto &
title = labelStruct.title;
1504 else if (!event.GetSkipped())
1515 bool updated =
false;
1518 int keyCode =
event.GetKeyCode();
1519 const int mods =
event.GetModifiers();
1524 if ((keyCode != WXK_F2 && mods != wxMOD_NONE && mods != wxMOD_SHIFT)
1525 || (keyCode == WXK_F2 && mods != wxMOD_CONTROL)) {
1532 const auto &mLabels = pTrack->GetLabels();
1536 auto &
title = labelStruct.title;
1544 int len =
title.length();
1559 if( ((
int)wchar > 0xDFFF) || ((
int)wchar <0xDC00)){
1578 case WXK_NUMPAD_DELETE:
1580 int len =
title.length();
1594 if( ((
int)wchar > 0xDBFF) || ((
int)wchar <0xD800)){
1613 case WXK_NUMPAD_HOME:
1616 if (mods == wxMOD_SHIFT)
1623 case WXK_NUMPAD_END:
1626 if (mods == wxMOD_SHIFT)
1633 case WXK_NUMPAD_LEFT:
1643 more = !(((int)wchar > 0xDFFF) || ((int)wchar < 0xDC00));
1647 if (mods != wxMOD_SHIFT)
1654 case WXK_NUMPAD_RIGHT:
1664 more = !(((int)wchar > 0xDBFF) || ((int)wchar < 0xD800));
1668 if (mods != wxMOD_SHIFT)
1684 case WXK_NUMPAD_ENTER:
1698 case WXK_WINDOWS_MENU:
1718 case WXK_NUMPAD_TAB:
1719 if (!mLabels.empty()) {
1720 int len = (int) mLabels.size();
1727 if (event.ShiftDown()) {
1737 if (event.ShiftDown()) {
1740 if (newSel.
t0() > mLabels[0].getT0()) {
1750 if (newSel.
t0() < mLabels[len - 1].getT0()) {
1764 newSel = labelStruct.selectedRegion;
1773 auto message =
XO(
"%s %d of %d")
1810 const int mods =
event.GetModifiers();
1811 if (mods != wxMOD_NONE && mods != wxMOD_SHIFT) {
1820 wxChar charCode =
event.GetUnicodeKey();
1823 if (charCode == 0 || wxIscntrl(charCode)) {
1832 if (wxIsspace(charCode)) {
1837 gPrefs->Read(
wxT(
"/GUI/DialogForNameNewLabel"), &useDialog,
false);
1842 project, selectedRegion, charCode,
title) ==
1846 pTrack->SetSelected(
true);
1847 pTrack->AddLabel(selectedRegion,
title);
1853 pTrack->SetSelected(
true);
1871 const auto& mLabels = pTrack->GetLabels();
1873 auto&
title = labelStruct.title;
1917 menu.Bind(wxEVT_MENU,
1918 [
this, &project]( wxCommandEvent &event ){
1941 wxClientDC dc(parent);
1951 static_cast<void>(success);
1974 switch (evt.GetId())
1994 project, selectedRegion.t0(), selectedRegion.t1() ))
2026 wxString left, right;
2034 const auto &mLabels = pTrack->GetLabels();
2036 auto &
title = labelStruct.title;
2039 left =
title.Left(init);
2041 if (cur < (
int)
title.length())
2042 right =
title.Mid(cur);
2044 title = left + right;
2063 const double delta = 1.0e-7;
2065 const auto &mLabels = pTrack->GetLabels();
2066 {
int i = -1;
for (
const auto &labelStruct : mLabels) { ++i;
2067 if( fabs( labelStruct.getT0() - t ) > delta )
2069 if( fabs( labelStruct.getT1() - t1 ) > delta )
2082 const wxString &
title,
int restoreFocus)
2086 auto pos = pTrack->AddLabel( selectedRegion,
title );
2137 auto fix = [&](
Index& index) {
2138 if (index == former)
2140 else if (former < index && index <= present)
2142 else if (former > index && index >= present)
2226 const int nSpecRows =
2228 const char *XmpBmp[nSpecRows];
2244 if( iHighlight==1 ) XmpBmp[5]=
"5 c #FFFFFF";
2245 if( iHighlight==2 ) XmpBmp[6]=
"6 c #FFFFFF";
2246 if( iHighlight==3 ) XmpBmp[7]=
"7 c #FFFFFF";
2249 if( iConfig==0) { XmpBmp[3]=
"3 c none"; XmpBmp[5]=
"5 c none"; }
2250 if( iConfig==1) { XmpBmp[4]=
"4 c none"; XmpBmp[7]=
"7 c none"; }
2269#include "../../../LabelDialog.h"
2275 auto format = formats.GetSelectionFormat(),
2276 freqFormat = formats.GetFrequencySelectionFormatName();
2290 if (dlg.ShowModal() == wxID_OK) {
2298 const SelectedRegion& region,
const wxString& initialValue, wxString& value)
2305 trackPanel.FindTrackRect( trackFocus.Get() ).GetBottomLeft();
2312 position = trackPanel.ClientToScreen(position);
2322 wxRect dialogScreenRect = dialog.GetScreenRect();
2323 wxRect projScreenRect = window.GetScreenRect();
2324 wxPoint max = projScreenRect.GetBottomRight() + wxPoint{ -dialogScreenRect.width, -dialogScreenRect.height };
2325 if (dialogScreenRect.x > max.x) {
2327 dialog.Move(position);
2329 if (dialogScreenRect.y > max.y) {
2331 dialog.Move(position);
2334 dialog.SetInsertionPointEnd();
2335 int status = dialog.ShowModal();
2336 if (status != wxID_CANCEL) {
2337 value = dialog.GetValue();
2338 value.Trim(
true).Trim(
false);
2347 return std::make_shared<LabelTrackView>( track.SharedPointer() );
2354 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 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
bool DoCaptureKey(AudacityProject &project, wxKeyEvent &event)
static constexpr int TextFramePadding
void OnLabelAdded(const LabelTrackEvent &)
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]
void OnSelectionChange(const LabelTrackEvent &)
~LabelTrackView() override
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 ComputeTextPosition(const wxRect &r, int index) const
int mInitialCursorPos
current cursor position
void OnLabelDeleted(const LabelTrackEvent &)
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 RestoreFlags(const Flags &flags)
void OnLabelPermuted(const LabelTrackEvent &)
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()
Observer::Subscription mSubscription
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
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
static ProjectHistory & Get(AudacityProject &project)
static ProjectRate & 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)
int64 TimeToPosition(double time, int64 origin=0, bool ignoreFisheye=false) const
STM: Converts a project time to screen x position.
int GetLeftOffset() const
std::unique_ptr< WindowPlacement > FindFocus()
Find the window that is accepting keyboard input, if any.
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
enum LabelTrackEvent::Type type
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)