Audacity 3.2.0
PlayableTrackControls.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3Audacity: A Digital Audio Editor
4
5PlayableTrackControls.cpp
6
7Paul Licameli split from TrackInfo.cpp
8
9**********************************************************************/
10
12
13
14
16#include "AColor.h"
17#include "Track.h"
18#include "../../../TrackInfo.h"
19#include "../../../TrackPanelDrawingContext.h"
20#include "ViewInfo.h"
21#include "../../../effects/RealtimeEffectManager.h"
22
23#include <wx/dc.h>
24
26
28
29namespace {
30
31void GetNarrowMuteHorizontalBounds( const wxRect & rect, wxRect &dest )
32{
33 dest.x = rect.x;
34 dest.width = rect.width / 2 + 1;
35}
36
37void GetNarrowSoloHorizontalBounds( const wxRect & rect, wxRect &dest )
38{
39 wxRect muteRect;
40 GetNarrowMuteHorizontalBounds( rect, muteRect );
41 dest.x = rect.x + muteRect.width;
42 dest.width = rect.width - muteRect.width + TitleSoloBorderOverlap;
43}
44
45void GetEffectsBounds( const wxRect & rect, wxRect &dest )
46{
47 constexpr int padding = 2;
48 dest.x = rect.x + padding;
49 dest.y = rect.y + padding;
50 dest.width = rect.width - padding * 2;
51 dest.height = rect.height - padding * 2;
52}
53
54void GetWideMuteSoloHorizontalBounds( const wxRect & rect, wxRect &dest )
55{
56 // Larger button, symmetrically placed intended.
57 // On windows this gives 15 pixels each side.
58 dest.width = rect.width - 2 * kTrackInfoBtnSize + 6;
59 dest.x = rect.x + kTrackInfoBtnSize -3;
60}
61
63( wxDC *dc, const wxRect &bev, const Track *pTrack, bool down,
64 bool WXUNUSED(captured),
65 bool solo, bool hit )
66{
67 //bev.Inflate(-1, -1);
68 bool selected = pTrack ? pTrack->GetSelected() : true;
69 auto pt = dynamic_cast<const PlayableTrack *>(pTrack);
70 bool value = pt ? (solo ? pt->GetSolo() : pt->GetMute()) : false;
71
72#if 0
73 AColor::MediumTrackInfo( dc, t->GetSelected());
74 if( solo )
75 {
76 if( pt && pt->GetSolo() )
77 {
78 AColor::Solo(dc, pt->GetSolo(), t->GetSelected());
79 }
80 }
81 else
82 {
83 if( pt && pt->GetMute() )
84 {
85 AColor::Mute(dc, pt->GetMute(), t->GetSelected(), pt->GetSolo());
86 }
87 }
88 //(solo) ? AColor::Solo(dc, t->GetSolo(), t->GetSelected()) :
89 // AColor::Mute(dc, t->GetMute(), t->GetSelected(), t->GetSolo());
90 dc->SetPen( *wxTRANSPARENT_PEN );//No border!
91 dc->DrawRectangle(bev);
92#endif
93
94 wxCoord textWidth, textHeight;
95 wxString str = (solo) ?
96 /* i18n-hint: This is on a button that will silence all the other tracks.*/
97 _("Solo") :
98 /* i18n-hint: This is on a button that will silence this track.*/
99 _("Mute");
100
102 *dc,
103 value == down,
104 bev,
105 selected, hit
106 );
107
109 dc->GetTextExtent(str, &textWidth, &textHeight);
110 dc->DrawText(str, bev.x + (bev.width - textWidth) / 2, bev.y + (bev.height - textHeight) / 2);
111}
112
114( wxDC *dc, const wxRect &bev, const Track *pTrack, bool down,
115 bool sel, bool hit )
116{
117 wxCoord textWidth, textHeight;
118
119 const auto str = _("Effects");
120
121 const auto selected = pTrack ? pTrack->GetSelected() : true;
122
123 AColor::ButtonStretch(*dc, !down, bev, selected, hit);
124
126 dc->GetTextExtent(str, &textWidth, &textHeight);
127 dc->DrawText(str, bev.x + (bev.width - textWidth) / 2, bev.y + (bev.height - textHeight) / 2);
128}
129
131( TrackPanelDrawingContext &context,
132 const wxRect &rect, const Track *pTrack )
133{
134 auto dc = &context.dc;
135 wxRect bev = rect;
137 auto target = dynamic_cast<MuteButtonHandle*>( context.target.get() );
138 bool hit = target && target->GetTrack().get() == pTrack;
139 bool captured = hit && target->IsClicked();
140 bool down = captured && bev.Contains( context.lastState.GetPosition());
141 MuteOrSoloDrawFunction( dc, bev, pTrack, down, captured, false, hit );
142}
143
145( TrackPanelDrawingContext &context,
146 const wxRect &rect, const Track *pTrack )
147{
148 auto dc = &context.dc;
149 wxRect bev = rect;
151 auto target = dynamic_cast<SoloButtonHandle*>( context.target.get() );
152 bool hit = target && target->GetTrack().get() == pTrack;
153 bool captured = hit && target->IsClicked();
154 bool down = captured && bev.Contains( context.lastState.GetPosition());
155 MuteOrSoloDrawFunction( dc, bev, pTrack, down, captured, true, hit );
156}
157
159( TrackPanelDrawingContext &context,
160 const wxRect &rect, const Track *pTrack )
161{
162 auto dc = &context.dc;
163 bool bHasSoloButton = TrackInfo::HasSoloButton();
164
165 wxRect bev = rect;
166 if ( bHasSoloButton )
168 else
170 {
171 auto target = dynamic_cast<MuteButtonHandle*>( context.target.get() );
172 bool hit = target && target->GetTrack().get() == pTrack;
173 bool captured = hit && target->IsClicked();
174 bool down = captured && bev.Contains( context.lastState.GetPosition());
175 MuteOrSoloDrawFunction( dc, bev, pTrack, down, captured, false, hit );
176 }
177
178 if( !bHasSoloButton )
179 return;
180
182 {
183 auto target = dynamic_cast<SoloButtonHandle*>( context.target.get() );
184 bool hit = target && target->GetTrack().get() == pTrack;
185 bool captured = hit && target->IsClicked();
186 bool down = captured && bev.Contains( context.lastState.GetPosition());
187 MuteOrSoloDrawFunction( dc, bev, pTrack, down, captured, true, hit );
188 }
189}
190
192( TrackPanelDrawingContext &context,
193 const wxRect &rect, const Track *pTrack )
194{
195 auto dc = &context.dc;
196
197 wxRect bev = rect;
198
199 GetEffectsBounds( rect, bev );
200 {
201 auto target = dynamic_cast<EffectsButtonHandle*>( context.target.get() );
202 bool hit = target && target->GetTrack().get() == pTrack;
203 bool captured = hit && target->IsClicked();
204 bool down = captured && bev.Contains( context.lastState.GetPosition());
205 EffectsDrawFunction( dc, bev, pTrack, down, captured, hit );
206 }
207}
208}
209
211(const wxRect & rect, wxRect & dest, bool solo, bool bHasSoloButton,
212 const Track *pTrack)
213{
214 auto &trackControl = static_cast<const CommonTrackControls&>(
215 TrackControls::Get( *pTrack ) );
216 auto resultsM = TrackInfo::CalcItemY( trackControl.GetTCPLines(), TCPLine::kItemMute );
217 auto resultsS = TrackInfo::CalcItemY( trackControl.GetTCPLines(), TCPLine::kItemSolo );
218 dest.height = resultsS.second;
219
220 int yMute = resultsM.first;
221 int ySolo = resultsS.first;
222
223 bool bSameRow = ( yMute == ySolo );
224 bool bNarrow = bSameRow && bHasSoloButton;
225
226 if( bNarrow )
227 {
228 if( solo )
229 GetNarrowSoloHorizontalBounds( rect, dest );
230 else
231 GetNarrowMuteHorizontalBounds( rect, dest );
232 }
233 else
235
236 if( bSameRow || !solo )
237 dest.y = rect.y + yMute;
238 else
239 dest.y = rect.y + ySolo;
240
241}
242
244(const wxRect & rect, wxRect & dest, const Track *pTrack)
245{
246 auto &trackControl = static_cast<const CommonTrackControls&>(
247 TrackControls::Get( *pTrack ) );
248 const auto resultsE = TrackInfo::CalcItemY( trackControl.GetTCPLines(), TCPLine::kItemEffects );
249 dest.x = rect.x;
250 dest.y = rect.y + resultsE.first;
251 dest.width = rect.width;
252 dest.height = resultsE.second;
253
254}
255
257{
258 static TCPLines playableTrackTCPLines;
259 static std::once_flag flag;
260 std::call_once( flag, []{
261 playableTrackTCPLines = CommonTrackControls::StaticTCPLines();
262 playableTrackTCPLines.insert( playableTrackTCPLines.end(), {
263 { TCPLine::kItemMute | TCPLine::kItemSolo, kTrackInfoBtnSize + 1, 0,
264 MuteAndSoloDrawFunction },
265 } );
266 } );
267 return playableTrackTCPLines;
268}
269
271{
272 static TCPLines playableTrackTCPLines;
273 static std::once_flag flag;
274 std::call_once( flag, []{
275 playableTrackTCPLines = CommonTrackControls::StaticTCPLines();
276 playableTrackTCPLines.insert( playableTrackTCPLines.end(), {
277 { TCPLine::kItemMute | TCPLine::kItemSolo, kTrackInfoBtnSize + 1, 0,
278 MuteAndSoloDrawFunction },
279 } );
280 playableTrackTCPLines.insert( playableTrackTCPLines.end(), {
281 { TCPLine::kItemEffects, kTrackEffectsBtnHeight + 1, 0,
282 EffectsDrawFunction },
283 } );
284 } );
285 return playableTrackTCPLines;
286}
#define str(a)
#define _(s)
Definition: Internat.h:75
TrackInfo::TCPLine TCPLine
declares abstract base class Track, TrackList, and iterators over TrackList
TrackInfo::TCPLines TCPLines
Definition: TrackInfo.cpp:102
static const int TitleSoloBorderOverlap
Definition: TrackInfo.h:29
@ kTrackInfoBtnSize
Definition: ViewInfo.h:95
static std::once_flag flag
static void Solo(wxDC *dc, bool on, bool selected)
Definition: AColor.cpp:487
static void Bevel2(wxDC &dc, bool up, const wxRect &r, bool bSel=false, bool bHighlight=false)
Definition: AColor.cpp:294
static void Mute(wxDC *dc, bool on, bool selected, bool soloing)
Definition: AColor.cpp:472
static void MediumTrackInfo(wxDC *dc, bool selected)
Definition: AColor.cpp:410
static void ButtonStretch(wxDC &dc, bool up, const wxRect &r, bool selected=false, bool highlight=false)
Draw a button that fills a given rect.
Definition: AColor.cpp:285
std::shared_ptr< Track > GetTrack() const
Definition: ButtonHandle.h:30
static const TCPLines & StaticTCPLines()
Definition: TrackInfo.cpp:123
static void GetEffectsRect(const wxRect &rect, wxRect &dest, const Track *pTrack)
static void GetMuteSoloRect(const wxRect &rect, wxRect &dest, bool solo, bool bHasSoloButton, const Track *pTrack)
static const TCPLines & StaticWaveTCPLines()
static const TCPLines & StaticNoteTCPLines()
AudioTrack subclass that can also be audibly replayed by the program.
Definition: Track.h:916
static TrackControls & Get(Track &track)
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:225
bool GetSelected() const
Definition: Track.h:469
AUDACITY_DLL_API void SetTrackInfoFont(wxDC *dc)
Definition: TrackInfo.cpp:559
AUDACITY_DLL_API bool HasSoloButton()
Definition: TrackInfo.cpp:95
AUDACITY_DLL_API std::pair< int, int > CalcItemY(const TCPLines &lines, unsigned iItem)
Definition: TrackInfo.cpp:146
void GetEffectsBounds(const wxRect &rect, wxRect &dest)
void GetNarrowSoloHorizontalBounds(const wxRect &rect, wxRect &dest)
void WideMuteDrawFunction(TrackPanelDrawingContext &context, const wxRect &rect, const Track *pTrack)
void EffectsDrawFunction(TrackPanelDrawingContext &context, const wxRect &rect, const Track *pTrack)
void MuteAndSoloDrawFunction(TrackPanelDrawingContext &context, const wxRect &rect, const Track *pTrack)
void WideSoloDrawFunction(TrackPanelDrawingContext &context, const wxRect &rect, const Track *pTrack)
void MuteOrSoloDrawFunction(wxDC *dc, const wxRect &bev, const Track *pTrack, bool down, bool WXUNUSED(captured), bool solo, bool hit)
void GetNarrowMuteHorizontalBounds(const wxRect &rect, wxRect &dest)
void GetWideMuteSoloHorizontalBounds(const wxRect &rect, wxRect &dest)