18#include "../../../LabelTrack.h"
21#include "../../../widgets/BasicMenu.h"
23#include "../../../HitTestResult.h"
29#include "../../../ProjectWindows.h"
30#include "../../../RefreshCode.h"
33#include "../../../TrackArt.h"
34#include "../../../TrackArtist.h"
36#include "../../../TrackPanel.h"
37#include "../../../TrackPanelMouseEvent.h"
44#include <wx/clipbrd.h>
45#include <wx/dcclient.h>
64 if (index != mIndex) {
85LabelTrackView::Index::operator int()
const
109 BindTo( pLabelTrack.get() );
117 const std::shared_ptr<Track> &parent,
size_t iChannel)
121 auto newParent = track_cast<LabelTrack*>(parent.get());
122 if (oldParent.get() != newParent)
132 case LabelTrackEvent::Addition:
133 return OnLabelAdded(e);
134 case LabelTrackEvent::Deletion:
135 return OnLabelDeleted(e);
136 case LabelTrackEvent::Permutation:
137 return OnLabelPermuted(e);
138 case LabelTrackEvent::Selection:
139 return OnSelectionChange(e);
151 if (
const auto pOther =
dynamic_cast<const LabelTrackView*
>(&other)) {
172 return FindChannel<LabelTrack>();
185 std::vector<UIHandlePtr> results;
186 const wxMouseState &state = st.
state;
192 results.push_back(result);
197 results.push_back(result);
245 wxFontEncoding encoding;
246 if (faceName.empty())
247 encoding = wxFONTENCODING_DEFAULT;
249 encoding = wxFONTENCODING_SYSTEM;
251 auto fontInfo =
size == 0 ? wxFontInfo() : wxFontInfo(
size);
256 return wxFont(fontInfo);
283 const auto &mLabels = pTrack->GetLabels();
285 const auto &labelStruct = mLabels[index];
290 int x = labelStruct.x;
291 int x1 = labelStruct.x1;
292 int width = labelStruct.width;
297 bool bTooWideForScreen = width > (r.width-2*xExtra);
299 bool bSimpleCentering =
false;
317 if( bSimpleCentering )
320 xText = (x+x1-width)/2;
329 int rx0,rx1,xText0,xText1;
334 if( bTooWideForScreen )
339 xText1=x1-(width+xExtra);
344 rx0=x-r.width+width+2*xExtra;
348 rx1=x1-(width+2*xExtra);
350 xText1=x1-(width+xExtra);
365 xText = xText0 + (int)((xText1-xText0)*(((float)(r.x-rx0))/(rx1-rx0)));
376 xText = (x+x1-width)/2;
381 bool bOffLeft = xText < r.x+xExtra;
382 bool bOffRight = xText > r.x+r.width-width-xExtra;
386 if( bOffLeft == bOffRight )
394 else if( bOffLeft != bTooWideForScreen)
406 xText =r.x+r.width-width-xExtra;
416 if( xText > (x1-width-xExtra))
417 xText=(x1-width-xExtra);
418 if( xText < x+xExtra )
421 labelStruct.xText = xText;
442 bool bAvoidName =
false;
443 const int nRows = wxMin((r.height / yRowHeight) + 1,
MAX_NUM_ROWS);
451 const int xStart = INT_MIN;
452 for (
auto &x : xUsed)
458 const auto &mLabels = pTrack->GetLabels();
460 {
int i = -1;
for (
const auto &labelStruct : mLabels) { ++i;
471 while( (iRow<nRowsUsed) && (xUsed[iRow] != x ))
476 if( iRow >= nRowsUsed )
479 while( (iRow<nRows) && (xUsed[iRow] > x ))
490 if( (i==0 ) && (iRow==0) && bAvoidName ){
494 xUsed[iRow]=x+labelStruct.width+xExtra;
495 if( xUsed[iRow] < x1 ) xUsed[iRow]=x1;
496 if( xUsed[iRow] < x2 ) xUsed[iRow]=x2;
501 if( iRow >= nRowsUsed )
504 y= r.y + iRow * yRowHeight +(yRowHeight/2)+1;
509 xUsed[iRow]=x+labelStruct.width+xExtra;
510 if( xUsed[iRow] < x1 ) xUsed[iRow]=x1;
521 wxDC & dc,
const LabelStruct &ls,
const wxRect & r)
547 if((x >= r.x) && (x <= (r.x+r.width)))
553 if((x1 >= r.x) && (x1 <= (r.x+r.width)))
572 wxDC & dc,
const LabelStruct &ls,
const wxRect & r,
573 int GlyphLeft,
int GlyphRight)
587 if((x >= r.x) && (x <= (r.x+r.width)))
588 dc.DrawBitmap(
GetGlyph(GlyphLeft), x-xHalfWidth,yStart,
true);
591 if((x1 >= r.x) && (x1 <= (r.x+r.width)) )
592 dc.DrawBitmap(
GetGlyph(GlyphRight), x1-xHalfWidth,yStart,
true);
620 auto &xText = ls.
xText;
621 const int xStart=wxMax(r.x,xText-
mIconWidth/2);
623 const int xWidth = xEnd-xStart;
625 if( (xStart < (r.x+r.width)) && (xEnd > r.x) && (xWidth>0))
629 (yFrameHeight -
mFontHeight) / 2 + dc.GetFontMetrics().ascent;
630 dc.DrawText(ls.
title, xText, pos);
637 wxDC & dc,
const LabelStruct &ls,
const wxRect & r)
649 auto& xText = ls.
xText;
650 const int xStart = wxMax(r.x, xText -
mIconWidth / 2);
651 const int xEnd = wxMin(r.x + r.width, xText + ls.
width +
mIconWidth / 2);
652 const int xWidth = xEnd - xStart;
654 if ((xStart < (r.x + r.width)) && (xEnd > r.x) && (xWidth > 0))
658 xWidth, textFrameHeight);
659 dc.DrawRectangle(frame);
674 const int xStart = wxMax(r.x, x + xBarShorten / 2);
675 const int xEnd = wxMin(r.x + r.width, x1 - xBarShorten / 2);
676 const int xWidth = xEnd - xStart;
678 if ((xStart < (r.x + r.width)) && (xEnd > r.x) && (xWidth > 0))
682 if (x1 > x + xBarShorten)
683 dc.DrawRectangle(bar);
689 int xPos1,
int xPos2,
int charHeight)
693 dc.SetPen(*wxTRANSPARENT_PEN);
694 wxBrush curBrush = dc.GetBrush();
695 curBrush.SetColour(wxString(
wxT(
"BLUE")));
698 dc.DrawRectangle(xPos1-1, top, xPos2-xPos1+1, charHeight);
700 dc.DrawRectangle(xPos2-1, top, xPos1-xPos2+1, charHeight);
711 dc.GetTextExtent(ls.
title.Left(cursorPos), &partWidth, NULL);
727 const auto &mLabels = pTrack->GetLabels();
750 const auto &mLabels = pTrack->GetLabels();
754 getXPos(labelStruct, dc, x1, pos1);
756 getXPos(labelStruct, dc, x2, pos2);
767 auto target = pPanel->
Target();
771 return &*handle->
mpHit;
777#include "../../../TrackPanelDrawingContext.h"
786 auto &dc = context.
dc;
788 const auto &zoomInfo = *artist->pZoomInfo;
789 const auto &pendingTracks = *artist->pPendingTracks;
791 auto pHit =
findHit( artist->parent );
801 const auto &track =
static_cast<const LabelTrack&
>(
802 pendingTracks.SubstitutePendingChangedChannel(*
FindChannel()));
809 wxCoord textWidth, textHeight;
814 for (
const auto &labelStruct : mLabels) {
815 dc.GetTextExtent(labelStruct.title, &textWidth, &textHeight);
816 labelStruct.width = textWidth;
825 mTextHeight = dc.GetFontMetrics().ascent + dc.GetFontMetrics().descent;
830 dc.SetBackgroundMode(wxTRANSPARENT);
839 for (
const auto &labelStruct : mLabels)
843 {
int i = -1;
for (
const auto &labelStruct : mLabels) { ++i;
846 if( pHit && i == pHit->mMouseOverLabelLeft )
847 GlyphLeft = (pHit->mEdge & 4) ? 6:9;
848 if( pHit && i == pHit->mMouseOverLabelRight )
849 GlyphRight = (pHit->mEdge & 4) ? 7:4;
850 DrawGlyphs( dc, labelStruct, r, GlyphLeft, GlyphRight );
853 auto &
project = *artist->parent->GetProject();
857#ifdef EXPERIMENTAL_TRACK_PANEL_HIGHLIGHTING
858 bool highlightTrack =
false;
860 highlightTrack = target &&
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);
1853 pTrack->SetSelected(
true);
1854 pTrack->AddLabel(selectedRegion,
title);
1860 pTrack->SetSelected(
true);
1878 const auto& mLabels = pTrack->GetLabels();
1880 auto&
title = labelStruct.title;
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 )
2090 const wxString &
title,
int restoreFocus)
2094 auto pos = pTrack->AddLabel( selectedRegion,
title );
2145 auto fix = [&](
Index& index) {
2146 if (index == former)
2148 else if (former < index && index <= present)
2150 else if (former > index && index >= present)
2234 const int nSpecRows =
2236 const char *XmpBmp[nSpecRows];
2252 if( iHighlight==1 ) XmpBmp[5]=
"5 c #FFFFFF";
2253 if( iHighlight==2 ) XmpBmp[6]=
"6 c #FFFFFF";
2254 if( iHighlight==3 ) XmpBmp[7]=
"7 c #FFFFFF";
2257 if( iConfig==0) { XmpBmp[3]=
"3 c none"; XmpBmp[5]=
"5 c none"; }
2258 if( iConfig==1) { XmpBmp[4]=
"4 c none"; XmpBmp[7]=
"7 c none"; }
2277#include "../../../LabelDialog.h"
2283 auto format = formats.GetSelectionFormat(),
2284 freqFormat = formats.GetFrequencySelectionFormatName();
2297 if (dlg.ShowModal() == wxID_OK) {
2305 const SelectedRegion& region,
const wxString& initialValue, wxString& value)
2312 trackPanel.FindTrackRect( trackFocus.Get() ).GetBottomLeft();
2319 position = trackPanel.ClientToScreen(position);
2329 wxRect dialogScreenRect = dialog.GetScreenRect();
2330 wxRect projScreenRect = window.GetScreenRect();
2331 wxPoint max = projScreenRect.GetBottomRight() + wxPoint{ -dialogScreenRect.width, -dialogScreenRect.height };
2332 if (dialogScreenRect.x > max.x) {
2334 dialog.Move(position);
2336 if (dialogScreenRect.y > max.y) {
2338 dialog.Move(position);
2341 dialog.SetInsertionPointEnd();
2342 int status = dialog.ShowModal();
2343 if (status != wxID_CANCEL) {
2344 value = dialog.GetValue();
2345 value.Trim(
true).Trim(
false);
2354 return std::make_shared<LabelTrackView>(
2362 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.
DEFINE_ATTACHED_VIRTUAL_OVERRIDE(DoGetLabelTrackView)
@ OnDeleteSelectedLabelID
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
audacity::BasicSettings * gPrefs
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.
std::shared_ptr< ChannelType > GetChannel(size_t iChannel)
Retrieve a channel, cast to the given type.
void Reparent(const std::shared_ptr< Track > &parent, size_t iChannel) override
Object may be shared among tracks but hold a special back-pointer to one of them; reassign it.
static ChannelView & Get(Channel &channel)
void CopyTo(Track &track, size_t iChannel) const override
Copy state, for undo/redo purposes.
Subclass & Get(const RegisteredFactory &key)
Get reference to an attachment, creating on demand if not present, down-cast it to Subclass.
auto FindChannel() -> std::shared_ptr< Subtype >
May return null.
Implements some hit-testing shared by many ChannelView subtypes.
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< const Track > FindTrack() const override
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 &)
void Reparent(const std::shared_ptr< Track > &parent, size_t iChannel) override
Object may be shared among tracks but hold a special back-pointer to one of them; reassign it.
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()
static constexpr int LabelBarHeight
static void DrawLines(wxDC &dc, const LabelStruct &ls, const wxRect &r)
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
void CopyTo(Track &track, size_t iChannel) const override
Copy state, for undo/redo purposes.
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
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
std::shared_ptr< ChannelVRulerControls > DoGetVRulerControls() override
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)
Defines a selected portion of a project.
static bool IsSelectedOrSyncLockSelected(const Track &track)
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.
std::shared_ptr< Subclass > SharedPointer()
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)
NotifyingSelectedRegion selectedRegion
static ViewInfo & Get(AudacityProject &project)
static Viewport & Get(AudacityProject &project)
void ScrollIntoView(double pos)
Center view horizontally at the given time, if it was not in bounds.
int64 TimeToPosition(double time, int64 origin=0, bool ignoreFisheye=false) const
STM: Converts a project time to screen x position.
int GetLeftOffset() const
bool ReadBool(const wxString &key, bool defaultValue) const
virtual bool Read(const wxString &key, bool *value) const =0
std::unique_ptr< WindowPlacement > FindFocus()
Find the window that is accepting keyboard input, if any.
AUDACITY_DLL_API void DrawBackgroundWithSelection(TrackPanelDrawingContext &context, const wxRect &rect, const Channel &channel, 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)
const char * end(const char *str) noexcept
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)