1 /**********************************************************************
2 
3 Audacity: A Digital Audio Editor
4 
5 LabelTrackControls.cpp
6 
7 Paul Licameli split from TrackPanel.cpp
8 
9 **********************************************************************/
10 
11 
12 #include "LabelTrackControls.h"
13 
14 #include "LabelTrackView.h"
15 #include "../../../HitTestResult.h"
16 #include "../../../LabelTrack.h"
17 #include "../../../widgets/PopupMenuTable.h"
18 #include "Prefs.h"
19 #include "../../../RefreshCode.h"
20 #include "../../../ShuttleGui.h"
21 #include "../../../widgets/wxPanelWrapper.h"
22 #include <wx/dialog.h>
23 #include <wx/fontenum.h>
24 #include <wx/listbox.h>
25 #include <wx/spinctrl.h>
26 
~LabelTrackControls()27 LabelTrackControls::~LabelTrackControls()
28 {
29 }
30 
HitTest(const TrackPanelMouseState & state,const AudacityProject * pProject)31 std::vector<UIHandlePtr> LabelTrackControls::HitTest
32 (const TrackPanelMouseState & state,
33  const AudacityProject *pProject)
34 {
35    return CommonTrackControls::HitTest(state, pProject);
36 }
37 
38 class LabelTrackMenuTable : public PopupMenuTable
39 {
LabelTrackMenuTable()40    LabelTrackMenuTable()
41       : PopupMenuTable{ "LabelTrack" }
42    {}
43    DECLARE_POPUP_MENU(LabelTrackMenuTable);
44 
45 public:
46    static LabelTrackMenuTable &Instance();
47 
InitUserData(void * pUserData)48    void InitUserData(void *pUserData) override
49    {
50       mpData = static_cast<CommonTrackControls::InitMenuData*>(pUserData);
51    }
52 
53    CommonTrackControls::InitMenuData *mpData{};
54 
55    void OnSetFont(wxCommandEvent &);
56 };
57 
Instance()58 LabelTrackMenuTable &LabelTrackMenuTable::Instance()
59 {
60    static LabelTrackMenuTable instance;
61    return instance;
62 }
63 
64 enum
65 {
66    OnSetFontID = 30000,
67 };
68 
69 BEGIN_POPUP_MENU(LabelTrackMenuTable)
70    BeginSection( "Basic" );
71       AppendItem( "Font", OnSetFontID, XXO("&Font..."), POPUP_MENU_FN( OnSetFont ) );
72    EndSection();
END_POPUP_MENU()73 END_POPUP_MENU()
74 
75 void LabelTrackMenuTable::OnSetFont(wxCommandEvent &)
76 {
77    // Small helper class to enumerate all fonts in the system
78    // We use this because the default implementation of
79    // wxFontEnumerator::GetFacenames() has changed between wx2.6 and 2.8
80    class FontEnumerator : public wxFontEnumerator
81    {
82    public:
83       explicit FontEnumerator(wxArrayString* fontNames) :
84          mFontNames(fontNames) {}
85 
86       bool OnFacename(const wxString& font) override
87       {
88          mFontNames->push_back(font);
89          return true;
90       }
91 
92    private:
93       wxArrayString* mFontNames;
94    };
95 
96    wxArrayString facenames;
97    FontEnumerator fontEnumerator(&facenames);
98    fontEnumerator.EnumerateFacenames(wxFONTENCODING_SYSTEM, false);
99 
100    wxString facename = gPrefs->Read(wxT("/GUI/LabelFontFacename"), wxT(""));
101 
102    // Correct for empty facename, or bad preference file:
103    // get the name of a really existing font, to highlight by default
104    // in the list box
105    facename = LabelTrackView::GetFont(facename).GetFaceName();
106 
107    long fontsize = gPrefs->Read(wxT("/GUI/LabelFontSize"),
108                                 LabelTrackView::DefaultFontSize);
109 
110    /* i18n-hint: (noun) This is the font for the label track.*/
111    wxDialogWrapper dlg(mpData->pParent, wxID_ANY, XO("Label Track Font"));
112    dlg.SetName();
113    ShuttleGui S(&dlg, eIsCreating);
114    wxListBox *lb;
115    wxSpinCtrl *sc;
116 
117    S.StartVerticalLay(true);
118    {
119       S.StartMultiColumn(2, wxEXPAND);
120       {
121          S.SetStretchyRow(0);
122          S.SetStretchyCol(1);
123 
124          /* i18n-hint: (noun) The name of the typeface*/
125          S.AddPrompt(XXO("Face name"));
126          lb = safenew wxListBox(S.GetParent(), wxID_ANY,
127             wxDefaultPosition,
128             wxDefaultSize,
129             facenames,
130             wxLB_SINGLE);
131 
132          lb->SetSelection( make_iterator_range( facenames ).index( facename ));
133          S
134             .Name(XO("Face name"))
135             .Position(  wxALIGN_LEFT | wxEXPAND | wxALL )
136             .AddWindow(lb);
137 
138          /* i18n-hint: (noun) The size of the typeface*/
139          S.AddPrompt(XXO("Face size"));
140          sc = safenew wxSpinCtrl(S.GetParent(), wxID_ANY,
141             wxString::Format(wxT("%ld"), fontsize),
142             wxDefaultPosition,
143             wxDefaultSize,
144             wxSP_ARROW_KEYS,
145             8, 48, fontsize);
146          S
147             .Name(XO("Face size"))
148             .Position( wxALIGN_LEFT | wxALL )
149             .AddWindow(sc);
150       }
151       S.EndMultiColumn();
152       S.AddStandardButtons();
153    }
154    S.EndVerticalLay();
155 
156    dlg.Layout();
157    dlg.Fit();
158    dlg.CenterOnParent();
159    if (dlg.ShowModal() == wxID_CANCEL)
160       return;
161 
162    gPrefs->Write(wxT("/GUI/LabelFontFacename"), lb->GetStringSelection());
163    gPrefs->Write(wxT("/GUI/LabelFontSize"), sc->GetValue());
164    gPrefs->Flush();
165 
166    LabelTrackView::ResetFont();
167 
168    mpData->result = RefreshCode::RefreshAll;
169 }
170 
GetMenuExtension(Track *)171 PopupMenuTable *LabelTrackControls::GetMenuExtension(Track *)
172 {
173    return &LabelTrackMenuTable::Instance();
174 }
175 
176 using DoGetLabelTrackControls = DoGetControls::Override< LabelTrack >;
DEFINE_ATTACHED_VIRTUAL_OVERRIDE(DoGetLabelTrackControls)177 DEFINE_ATTACHED_VIRTUAL_OVERRIDE(DoGetLabelTrackControls) {
178    return [](LabelTrack &track) {
179       return std::make_shared<LabelTrackControls>( track.SharedPointer() );
180    };
181 }
182 
183 using GetDefaultLabelTrackHeight = GetDefaultTrackHeight::Override< LabelTrack >;
DEFINE_ATTACHED_VIRTUAL_OVERRIDE(GetDefaultLabelTrackHeight)184 DEFINE_ATTACHED_VIRTUAL_OVERRIDE(GetDefaultLabelTrackHeight) {
185    return [](LabelTrack &) {
186       // Label tracks are narrow
187       // Default is to allow two rows so that NEW users get the
188       // idea that labels can 'stack' when they would overlap.
189       return 73;
190    };
191 }
192