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 "../../ui/CommonTrackInfo.h"
15#include "../../../TrackPanelDrawingContext.h"
16#include "ViewInfo.h"
19
20#include <wx/dc.h>
21
22#include "RealtimeEffectList.h"
23
25
26namespace {
27
28 constexpr auto MuteSoloButtonHeight = 20;
29 constexpr auto MuteSoloButtonExtra = 2;
30 constexpr auto EffectsButtonHeight = 22;
31
32void GetNarrowMuteHorizontalBounds( const wxRect & rect, wxRect &dest )
33{
34 dest.x = rect.x;
35 dest.width = (rect.width - CommonTrackInfo::Margin) / 2;
36}
37
38void GetNarrowSoloHorizontalBounds( const wxRect & rect, wxRect &dest )
39{
40 dest.width = (rect.width - CommonTrackInfo::Margin) / 2;
41 dest.x = rect.x + rect.width - dest.width;
42}
43
44void GetEffectsButtonBounds( const wxRect & rect, wxRect &dest )
45{
46 dest = rect;
47}
48
49void GetWideMuteSoloHorizontalBounds( const wxRect & rect, wxRect &dest )
50{
51 // Larger button, symmetrically placed intended.
52 // On windows this gives 15 pixels each side.
53 dest.width = rect.width - 2 * kTrackInfoBtnSize + 6;
54 dest.x = rect.x + kTrackInfoBtnSize -3;
55}
56
58( wxDC *dc, const wxRect &bev, const Track *pTrack, bool down,
59 bool WXUNUSED(captured),
60 bool solo, bool hit )
61{
62 //bev.Inflate(-1, -1);
63 bool selected = pTrack ? pTrack->GetSelected() : true;
64 auto pt = dynamic_cast<const PlayableTrack *>(pTrack);
65 bool value = pt ? (solo ? pt->GetSolo() : pt->GetMute()) : false;
66
67#if 0
68 AColor::MediumTrackInfo( dc, t->GetSelected());
69 if( solo )
70 {
71 if( pt && pt->GetSolo() )
72 {
73 AColor::Solo(dc, pt->GetSolo(), t->GetSelected());
74 }
75 }
76 else
77 {
78 if( pt && pt->GetMute() )
79 {
80 AColor::Mute(dc, pt->GetMute(), t->GetSelected(), pt->GetSolo());
81 }
82 }
83 //(solo) ? AColor::Solo(dc, t->GetSolo(), t->GetSelected()) :
84 // AColor::Mute(dc, t->GetMute(), t->GetSelected(), t->GetSolo());
85 dc->SetPen( *wxTRANSPARENT_PEN );//No border!
86 dc->DrawRectangle(bev);
87#endif
88
89 wxCoord textWidth, textHeight;
90 wxString str = (solo) ?
91 /* i18n-hint: This is on a button that will silence all the other tracks.*/
92 _("Solo") :
93 /* i18n-hint: This is on a button that will silence this track.*/
94 _("Mute");
95
97 *dc,
98 value == down,
99 bev,
100 selected, hit
101 );
102
104 dc->GetTextExtent(str, &textWidth, &textHeight);
105 dc->DrawText(str, bev.x + (bev.width - textWidth) / 2, bev.y + (bev.height - textHeight) / 2);
106}
107
109( wxDC *dc, const wxRect &bev, const Track *pTrack, bool down,
110 bool sel, bool hit )
111{
112 wxCoord textWidth, textHeight;
113
114 const auto str = _("Effects");
115
116 const auto selected = pTrack ? pTrack->GetSelected() : true;
117
118 AColor::ButtonStretch(*dc, !down, bev, selected, hit);
119
121 dc->GetTextExtent(str, &textWidth, &textHeight);
122 dc->DrawText(str, bev.x + (bev.width - textWidth) / 2, bev.y + (bev.height - textHeight) / 2);
123}
124
126( TrackPanelDrawingContext &context,
127 const wxRect &rect, const Track *pTrack )
128{
129 auto dc = &context.dc;
130 wxRect bev = rect;
132 auto target = dynamic_cast<MuteButtonHandle*>( context.target.get() );
133 bool hit = target && target->GetTrack().get() == pTrack;
134 bool captured = hit && target->IsDragging();
135 bool down = captured && bev.Contains( context.lastState.GetPosition());
136 MuteOrSoloDrawFunction( dc, bev, pTrack, down, captured, false, hit );
137}
138
140( TrackPanelDrawingContext &context,
141 const wxRect &rect, const Track *pTrack )
142{
143 auto dc = &context.dc;
144 wxRect bev = rect;
146 auto target = dynamic_cast<SoloButtonHandle*>( context.target.get() );
147 bool hit = target && target->GetTrack().get() == pTrack;
148 bool captured = hit && target->IsDragging();
149 bool down = captured && bev.Contains( context.lastState.GetPosition());
150 MuteOrSoloDrawFunction( dc, bev, pTrack, down, captured, true, hit );
151}
152
154( TrackPanelDrawingContext &context,
155 const wxRect &rect, const Track *pTrack )
156{
157 auto dc = &context.dc;
158
159 wxRect bev = rect;
160
162 {
163 auto target = dynamic_cast<MuteButtonHandle*>( context.target.get() );
164 bool hit = target && target->GetTrack().get() == pTrack;
165 bool captured = hit && target->IsDragging();
166 bool down = captured && bev.Contains( context.lastState.GetPosition());
167 MuteOrSoloDrawFunction( dc, bev, pTrack, down, captured, false, hit );
168 }
169
171 {
172 auto target = dynamic_cast<SoloButtonHandle*>( context.target.get() );
173 bool hit = target && target->GetTrack().get() == pTrack;
174 bool captured = hit && target->IsDragging();
175 bool down = captured && bev.Contains( context.lastState.GetPosition());
176 MuteOrSoloDrawFunction( dc, bev, pTrack, down, captured, true, hit );
177 }
178}
179
181( TrackPanelDrawingContext &context,
182 const wxRect &rect, const Track *pTrack )
183{
184 auto dc = &context.dc;
185
186 wxRect bev = rect;
187
188 GetEffectsButtonBounds( rect, bev );
189 {
190 auto target = dynamic_cast<EffectsButtonHandle*>( context.target.get() );
191 bool hit = target && target->GetTrack().get() == pTrack;
192 bool captured = hit && target->IsDragging();
193 bool down = captured && bev.Contains( context.lastState.GetPosition());
194 EffectsDrawFunction( dc, bev, pTrack, down, captured, hit );
195 }
196}
197}
198
200(const wxRect & rect_, wxRect & dest, bool solo,
201 const Track *pTrack)
202{
203 const auto rect = wxRect(rect_).Deflate(CommonTrackInfo::Margin);
204
205 auto &trackControl = static_cast<const CommonTrackControls&>(
206 TrackControls::Get( *pTrack ) );
207 const auto [yMute, yHeight] = TrackInfo::CalcItemY( trackControl.GetTCPLines(), TCPLine::kItemMute );
208 const auto [ySolo, sHeight] = TrackInfo::CalcItemY( trackControl.GetTCPLines(), TCPLine::kItemSolo );
209 dest.height = sHeight;
210
211 const auto bSameRow = ( yMute == ySolo );
212
213 if( bSameRow )
214 {
215 if( solo )
216 GetNarrowSoloHorizontalBounds( rect, dest );
217 else
218 GetNarrowMuteHorizontalBounds( rect, dest );
219 }
220 else
222
223 if( bSameRow || !solo )
224 dest.y = rect.y + yMute;
225 else
226 dest.y = rect.y + ySolo;
227}
228
230(const wxRect & rect_, wxRect & dest, const Track *pTrack)
231{
232 const auto rect = wxRect(rect_).Deflate(CommonTrackInfo::Margin);
233
234 auto &trackControl = static_cast<const CommonTrackControls&>(
235 TrackControls::Get( *pTrack ) );
236 const auto resultsE = TrackInfo::CalcItemY( trackControl.GetTCPLines(), TCPLine::kItemEffects );
237 GetEffectsButtonBounds(rect, dest);
238 dest.y = rect.y + resultsE.first;
239 dest.height = resultsE.second;
240}
241
243{
244 static TCPLines playableTrackTCPLines;
245 static std::once_flag flag;
246 std::call_once( flag, []{
247 playableTrackTCPLines = CommonTrackInfo::StaticTCPLines();
248 playableTrackTCPLines.insert( playableTrackTCPLines.end(), {
249 { TCPLine::kItemMute | TCPLine::kItemSolo, MuteSoloButtonHeight, MuteSoloButtonExtra,
250 MuteAndSoloDrawFunction },
251 } );
252 } );
253 return playableTrackTCPLines;
254}
255
257{
258 static TCPLines playableTrackTCPLines;
259 static std::once_flag flag;
260 std::call_once( flag, []{
261 playableTrackTCPLines = CommonTrackInfo::StaticTCPLines();
262 playableTrackTCPLines.insert( playableTrackTCPLines.end(), {
263 { TCPLine::kItemMute | TCPLine::kItemSolo, MuteSoloButtonHeight, MuteSoloButtonExtra,
264 MuteAndSoloDrawFunction },
265 } );
266 playableTrackTCPLines.insert( playableTrackTCPLines.end(), {
267 { TCPLine::kItemEffects, EffectsButtonHeight, 0,
268 EffectsDrawFunction },
269 } );
270 } );
271 return playableTrackTCPLines;
272}
std::vector< TrackInfo::TCPLine > TCPLines
#define str(a)
#define _(s)
Definition: Internat.h:73
Extends Track with notions of mute and solo setting.
TrackInfo::TCPLine TCPLine
@ kTrackInfoBtnSize
Definition: ViewInfo.h:98
static std::once_flag flag
static void Solo(wxDC *dc, bool on, bool selected)
Definition: AColor.cpp:484
static void Bevel2(wxDC &dc, bool up, const wxRect &r, bool bSel=false, bool bHighlight=false)
Definition: AColor.cpp:298
static void Mute(wxDC *dc, bool on, bool selected, bool soloing)
Definition: AColor.cpp:469
static void MediumTrackInfo(wxDC *dc, bool selected)
Definition: AColor.cpp:415
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:289
std::shared_ptr< Track > GetTrack() const
Definition: ButtonHandle.h:30
static void GetMuteSoloRect(const wxRect &rect, wxRect &dest, bool solo, const Track *pTrack)
static const TCPLines & StaticWaveTCPLines()
static const TCPLines & StaticNoteTCPLines()
static void GetEffectsButtonRect(const wxRect &rect, wxRect &dest, const Track *pTrack)
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:110
bool GetSelected() const
Selectedness is always the same for all channels of a group.
Definition: Track.cpp:78
static constexpr auto Margin
AUDACITY_DLL_API const TCPLines & StaticTCPLines()
AUDACITY_DLL_API void SetTrackInfoFont(wxDC *dc)
Definition: TrackInfo.cpp:77
AUDACITY_DLL_API std::pair< int, int > CalcItemY(const TCPLines &lines, unsigned iItem)
Definition: TrackInfo.cpp:61
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)
void GetEffectsButtonBounds(const wxRect &rect, wxRect &dest)