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**********************************************************************/
11#include "PlayableTrack.h"
13#include "AColor.h"
14#include "../../../TrackInfo.h"
15#include "../../../TrackPanelDrawingContext.h"
16#include "ViewInfo.h"
18
19#include <wx/dc.h>
20
21#include "RealtimeEffectList.h"
22
24
25namespace {
26
27void GetNarrowMuteHorizontalBounds( const wxRect & rect, wxRect &dest )
28{
29 dest.x = rect.x;
30 dest.width = rect.width / 2 + 1;
31}
32
33void GetNarrowSoloHorizontalBounds( const wxRect & rect, wxRect &dest )
34{
35 wxRect muteRect;
36 GetNarrowMuteHorizontalBounds( rect, muteRect );
37 dest.x = rect.x + muteRect.width;
38 dest.width = rect.width - muteRect.width + TitleSoloBorderOverlap;
39}
40
41void GetEffectsBounds( const wxRect & rect, wxRect &dest )
42{
43 constexpr int padding = 2;
44 dest.x = rect.x + padding;
45 dest.y = rect.y + padding;
46 dest.width = rect.width - padding * 2;
47 dest.height = rect.height - padding * 2;
48}
49
50void GetWideMuteSoloHorizontalBounds( const wxRect & rect, wxRect &dest )
51{
52 // Larger button, symmetrically placed intended.
53 // On windows this gives 15 pixels each side.
54 dest.width = rect.width - 2 * kTrackInfoBtnSize + 6;
55 dest.x = rect.x + kTrackInfoBtnSize -3;
56}
57
59( wxDC *dc, const wxRect &bev, const Track *pTrack, bool down,
60 bool WXUNUSED(captured),
61 bool solo, bool hit )
62{
63 //bev.Inflate(-1, -1);
64 bool selected = pTrack ? pTrack->GetSelected() : true;
65 auto pt = dynamic_cast<const PlayableTrack *>(pTrack);
66 bool value = pt ? (solo ? pt->GetSolo() : pt->GetMute()) : false;
67
68#if 0
69 AColor::MediumTrackInfo( dc, t->GetSelected());
70 if( solo )
71 {
72 if( pt && pt->GetSolo() )
73 {
74 AColor::Solo(dc, pt->GetSolo(), t->GetSelected());
75 }
76 }
77 else
78 {
79 if( pt && pt->GetMute() )
80 {
81 AColor::Mute(dc, pt->GetMute(), t->GetSelected(), pt->GetSolo());
82 }
83 }
84 //(solo) ? AColor::Solo(dc, t->GetSolo(), t->GetSelected()) :
85 // AColor::Mute(dc, t->GetMute(), t->GetSelected(), t->GetSolo());
86 dc->SetPen( *wxTRANSPARENT_PEN );//No border!
87 dc->DrawRectangle(bev);
88#endif
89
90 wxCoord textWidth, textHeight;
91 wxString str = (solo) ?
92 /* i18n-hint: This is on a button that will silence all the other tracks.*/
93 _("Solo") :
94 /* i18n-hint: This is on a button that will silence this track.*/
95 _("Mute");
96
98 *dc,
99 value == down,
100 bev,
101 selected, hit
102 );
103
105 dc->GetTextExtent(str, &textWidth, &textHeight);
106 dc->DrawText(str, bev.x + (bev.width - textWidth) / 2, bev.y + (bev.height - textHeight) / 2);
107}
108
110( wxDC *dc, const wxRect &bev, const Track *pTrack, bool down,
111 bool sel, bool hit )
112{
113 wxCoord textWidth, textHeight;
114
115 const auto str = _("Effects");
116
117 const auto selected = pTrack ? pTrack->GetSelected() : true;
118
119 AColor::ButtonStretch(*dc, !down, bev, selected, hit);
120
122 dc->GetTextExtent(str, &textWidth, &textHeight);
123 dc->DrawText(str, bev.x + (bev.width - textWidth) / 2, bev.y + (bev.height - textHeight) / 2);
124}
125
127( TrackPanelDrawingContext &context,
128 const wxRect &rect, const Track *pTrack )
129{
130 auto dc = &context.dc;
131 wxRect bev = rect;
133 auto target = dynamic_cast<MuteButtonHandle*>( context.target.get() );
134 bool hit = target && target->GetTrack().get() == pTrack;
135 bool captured = hit && target->IsClicked();
136 bool down = captured && bev.Contains( context.lastState.GetPosition());
137 MuteOrSoloDrawFunction( dc, bev, pTrack, down, captured, false, hit );
138}
139
141( TrackPanelDrawingContext &context,
142 const wxRect &rect, const Track *pTrack )
143{
144 auto dc = &context.dc;
145 wxRect bev = rect;
147 auto target = dynamic_cast<SoloButtonHandle*>( context.target.get() );
148 bool hit = target && target->GetTrack().get() == pTrack;
149 bool captured = hit && target->IsClicked();
150 bool down = captured && bev.Contains( context.lastState.GetPosition());
151 MuteOrSoloDrawFunction( dc, bev, pTrack, down, captured, true, hit );
152}
153
155( TrackPanelDrawingContext &context,
156 const wxRect &rect, const Track *pTrack )
157{
158 auto dc = &context.dc;
159 bool bHasSoloButton = TrackInfo::HasSoloButton();
160
161 wxRect bev = rect;
162 if ( bHasSoloButton )
164 else
166 {
167 auto target = dynamic_cast<MuteButtonHandle*>( context.target.get() );
168 bool hit = target && target->GetTrack().get() == pTrack;
169 bool captured = hit && target->IsClicked();
170 bool down = captured && bev.Contains( context.lastState.GetPosition());
171 MuteOrSoloDrawFunction( dc, bev, pTrack, down, captured, false, hit );
172 }
173
174 if( !bHasSoloButton )
175 return;
176
178 {
179 auto target = dynamic_cast<SoloButtonHandle*>( context.target.get() );
180 bool hit = target && target->GetTrack().get() == pTrack;
181 bool captured = hit && target->IsClicked();
182 bool down = captured && bev.Contains( context.lastState.GetPosition());
183 MuteOrSoloDrawFunction( dc, bev, pTrack, down, captured, true, hit );
184 }
185}
186
188( TrackPanelDrawingContext &context,
189 const wxRect &rect, const Track *pTrack )
190{
191 auto dc = &context.dc;
192
193 wxRect bev = rect;
194
195 GetEffectsBounds( rect, bev );
196 {
197 auto target = dynamic_cast<EffectsButtonHandle*>( context.target.get() );
198 bool hit = target && target->GetTrack().get() == pTrack;
199 bool captured = hit && target->IsClicked();
200 bool down = captured && bev.Contains( context.lastState.GetPosition());
201 EffectsDrawFunction( dc, bev, pTrack, down, captured, hit );
202 }
203}
204}
205
207(const wxRect & rect, wxRect & dest, bool solo, bool bHasSoloButton,
208 const Track *pTrack)
209{
210 auto &trackControl = static_cast<const CommonTrackControls&>(
211 TrackControls::Get( *pTrack ) );
212 auto resultsM = TrackInfo::CalcItemY( trackControl.GetTCPLines(), TCPLine::kItemMute );
213 auto resultsS = TrackInfo::CalcItemY( trackControl.GetTCPLines(), TCPLine::kItemSolo );
214 dest.height = resultsS.second;
215
216 int yMute = resultsM.first;
217 int ySolo = resultsS.first;
218
219 bool bSameRow = ( yMute == ySolo );
220 bool bNarrow = bSameRow && bHasSoloButton;
221
222 if( bNarrow )
223 {
224 if( solo )
225 GetNarrowSoloHorizontalBounds( rect, dest );
226 else
227 GetNarrowMuteHorizontalBounds( rect, dest );
228 }
229 else
231
232 if( bSameRow || !solo )
233 dest.y = rect.y + yMute;
234 else
235 dest.y = rect.y + ySolo;
236
237}
238
240(const wxRect & rect, wxRect & dest, const Track *pTrack)
241{
242 auto &trackControl = static_cast<const CommonTrackControls&>(
243 TrackControls::Get( *pTrack ) );
244 const auto resultsE = TrackInfo::CalcItemY( trackControl.GetTCPLines(), TCPLine::kItemEffects );
245 dest.x = rect.x;
246 dest.y = rect.y + resultsE.first;
247 dest.width = rect.width;
248 dest.height = resultsE.second;
249
250}
251
253{
254 static TCPLines playableTrackTCPLines;
255 static std::once_flag flag;
256 std::call_once( flag, []{
257 playableTrackTCPLines = CommonTrackControls::StaticTCPLines();
258 playableTrackTCPLines.insert( playableTrackTCPLines.end(), {
259 { TCPLine::kItemMute | TCPLine::kItemSolo, kTrackInfoBtnSize + 1, 0,
260 MuteAndSoloDrawFunction },
261 } );
262 } );
263 return playableTrackTCPLines;
264}
265
267{
268 static TCPLines playableTrackTCPLines;
269 static std::once_flag flag;
270 std::call_once( flag, []{
271 playableTrackTCPLines = CommonTrackControls::StaticTCPLines();
272 playableTrackTCPLines.insert( playableTrackTCPLines.end(), {
273 { TCPLine::kItemMute | TCPLine::kItemSolo, kTrackInfoBtnSize + 1, 0,
274 MuteAndSoloDrawFunction },
275 } );
276 playableTrackTCPLines.insert( playableTrackTCPLines.end(), {
277 { TCPLine::kItemEffects, kTrackEffectsBtnHeight + 1, 0,
278 EffectsDrawFunction },
279 } );
280 } );
281 return playableTrackTCPLines;
282}
#define str(a)
#define _(s)
Definition: Internat.h:73
Extends Track with notions of mute and solo setting.
TrackInfo::TCPLine TCPLine
TrackInfo::TCPLines TCPLines
Definition: TrackInfo.cpp:98
static const int TitleSoloBorderOverlap
Definition: TrackInfo.h:29
@ kTrackInfoBtnSize
Definition: ViewInfo.h:96
static std::once_flag flag
static void Solo(wxDC *dc, bool on, bool selected)
Definition: AColor.cpp:510
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:495
static void MediumTrackInfo(wxDC *dc, bool selected)
Definition: AColor.cpp:433
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:119
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: PlayableTrack.h:40
static TrackControls & Get(Track &track)
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:162
bool GetSelected() const
Selectedness is always the same for all channels of a group.
Definition: Track.cpp:82
AUDACITY_DLL_API void SetTrackInfoFont(wxDC *dc)
Definition: TrackInfo.cpp:555
AUDACITY_DLL_API bool HasSoloButton()
Definition: TrackInfo.cpp:91
AUDACITY_DLL_API std::pair< int, int > CalcItemY(const TCPLines &lines, unsigned iItem)
Definition: TrackInfo.cpp:142
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)