14#include "../../ui/PlayableTrackButtonHandles.h"
20#include "../../../../CellularPanel.h"
22#include "../../../../ProjectAudioIO.h"
24#include "../../../../ProjectWindows.h"
25#include "../../../../RefreshCode.h"
26#include "../../../../ShuttleGui.h"
28#include "../../../../TrackArtist.h"
29#include "../../../../TrackPanel.h"
30#include "../../../../TrackPanelAx.h"
31#include "../../../../TrackPanelMouseEvent.h"
32#include "../../../../WaveTrack.h"
33#include "../../../../effects/RealtimeEffectManager.h"
34#include "../../../../prefs/PrefsDialog.h"
35#include "../../../../prefs/ThemePrefs.h"
36#include "../../../../widgets/AudacityMessageBox.h"
42#include <wx/combobox.h>
56 const wxMouseState &state = st.
state;
57 const wxRect &rect = st.
rect;
58 if (state.ButtonIsDown(wxMOUSE_BTN_LEFT)) {
60 std::vector<UIHandlePtr> results;
86 results.push_back(result);
146template<
typename Table >
150 auto pData =
static_cast<Table&
>( handler ).mpData;
151 const auto pTrack =
static_cast<WaveTrack*
>(pData->pTrack);
152 auto &project = pData->project;
155 menu.Check(
id,
id ==
findValue( *pTrack ) );
156 menu.Enable(
id, !unsafe );
197 return IdOfFormat( track.GetSampleFormat() );
232 int id =
event.GetId();
253 if (newFormat == pTrack->GetSampleFormat())
259 XO(
"Processing... 0%%"),
265 totalSamples += channel->GetSequenceSamplesCount();
271 auto progressUpdate = [&progress, &totalSamples, &processedSamples]
272 (
size_t newlyProcessedCount)->
void
274 processedSamples += newlyProcessedCount;
275 double d_processed = processedSamples.
as_double();
276 double d_total = totalSamples.as_double();
277 int percentage{
static_cast<int>((d_processed / d_total) * 100) };
279 auto progressStatus = progress.Update(d_processed, d_total,
280 XO(
"Processing... %i%%").Format(percentage));
287 channel->ConvertToSampleFormat(
288 newFormat, progressUpdate);
294 XO(
"Format Change"));
338 static const auto fn = initFn< RateMenuTable >(
340 return IdOfRate( (
int)track.
GetRate() );
364static
int gRates[
nRates] = { 8000, 11025, 16000, 22050, 44100, 48000, 88200, 96000,
365176400, 192000, 352800, 384000 };
370 for (
int i = 0; i<
nRates; i++) {
383 channel->SetRate(rate);
386 wxString rateString = wxString::Format(wxT(
"%.3f"), rate);
398 int id =
event.GetId();
424 rate.Printf(wxT(
"%ld"),
lrint(pTrack->GetRate()));
441 S.StartVerticalLay(
true);
444 S.StartHorizontalLay(wxEXPAND,
false);
446 cb =
S.AddCombo(
XXO(
"New sample rate (Hz):"),
449#if defined(__WXMAC__)
455 S.EndHorizontalLay();
456 S.AddStandardButtons();
460 dlg.SetClientSize(dlg.GetSizer()->CalcMin());
463 if (dlg.ShowModal() != wxID_OK)
469 if (cb->GetValue().ToLong(&lrate) && lrate >= 1 && lrate <= 1000000)
471 newRate = (int)lrate;
476 XO(
"The entered value is invalid"),
567 return std::make_unique<Entry>(
573 auto &track = table.FindWaveTrack();
575 menu.Check(
id, view.GetMultiView() );
585 static const auto initFn = [](
bool radio ){
return
591 const auto IdForType =
593 const auto begin = allTypes.begin();
595 (std::find(
begin, allTypes.end(), type ) -
begin);
599 auto &track = table.FindWaveTrack();
603 const auto displays = view.GetDisplays();
604 const auto end = displays.end();
606 std::find_if( displays.begin(),
end,
608 return id == IdForType( type ); } ) );
609 menu.Check(
id, check );
613 if ( !radio && displays.size() == 1 && check )
614 menu.Enable(
id,
false );
618 const auto pTrack = &table.FindWaveTrack();
620 const auto itemType =
621 view.GetMultiView() ? Entry::CheckItem : Entry::RadioItem;
622 return std::make_unique<Entry>( type.name.Internal(), itemType,
623 id, type.name.Msgid(),
625 initFn( !view.GetMultiView() ) );
661 if ( canMakeStereo ) {
666 auto &track = table.FindWaveTrack();
667 auto next = * ++ tracks.
Find(&track);
671 track_cast<WaveTrack*>(next));
673 menu.Enable(
id, canMakeStereo );
684 menu.Enable(
id, isStereo && !
isUnsafe( handler ) );
696 #ifndef EXPERIMENTAL_DA
715 const auto pTrack =
static_cast<WaveTrack*
>(mpData->pTrack);
717 bool multi = !view.GetMultiView();
718 const auto &displays = view.GetDisplays();
719 const auto display = displays.empty()
723 channelView.SetMultiView( multi );
728 channelView.SetDisplay(display, !multi);
735 int idInt =
event.GetId();
743 if ( view.GetMultiView() ) {
756 const auto displays = view.GetDisplays();
757 const bool wrongType =
758 !(displays.size() == 1 && displays[0].id ==
id);
777 int id =
event.GetId();
787 channelmsg =
XO(
"Mono");
791 channelmsg =
XO(
"Left Channel");
795 channelmsg =
XO(
"Right Channel");
818 auto partner =
static_cast< WaveTrack *
>
819 ( *tracks.Find( pTrack ).advance( 1 ) );
821 bool bBothMinimizedp =
825 tracks.MakeMultiChannelTrack( *pTrack, 2,
false );
828 partner->
Merge(*pTrack);
831 partner->SetPan( 0.0f );
837 view.SetMinimized(
false);
838 partnerView.SetMinimized(
false);
839 int AverageHeight = (view.GetHeight() + partnerView.GetHeight()) / 2;
840 view.SetExpandedHeight(AverageHeight);
841 partnerView.SetExpandedHeight(AverageHeight);
842 view.SetMinimized(bBothMinimizedp);
843 partnerView.SetMinimized(bBothMinimizedp);
845 partnerView.RestorePlacements( view.SavePlacements() );
846 partnerView.SetMultiView( view.GetMultiView() );
867 for (
auto channel : channels) {
869 channel->SetName(pTrack->
GetName());
872 channel->SetPanFromChannelType();
875 if (view.GetHeight() < view.GetMinimizedHeight())
876 view.SetExpandedHeight(view.GetMinimizedHeight());
877 totalHeight += view.GetHeight();
882 int averageHeight = totalHeight / nChannels;
884 for (
auto channel : channels)
896 if (channels.size() != 2)
900 Track *
const focused = trackFocus.
Get();
901 const bool hasFocus = channels.contains( focused );
903 auto partner = *channels.rbegin();
908 trackFocus.Set(partner);
913 XO(
"Swap Channels"));
943 XO(
"Split to Mono"));
954 {wxT(
"/SubViews/Extra"), wxT(
"WaveColor,SpectrogramSettings")},
968#include "../../../../widgets/ASlider.h"
969#include "../../../../TrackInfo.h"
970#include "../../../../TrackPanelDrawingContext.h"
977 (
const wxRect &sliderRect,
const WaveTrack *t,
bool captured, wxWindow*),
978 wxDC *dc,
const wxRect &rect,
const Track *pTrack,
980 bool captured,
bool highlight )
982 wxRect sliderRect = rect;
984 auto wt =
static_cast<const WaveTrack*
>( pTrack );
985 Selector( sliderRect, wt, captured, pParent )->OnPaint(*dc, highlight);
990 const wxRect &rect,
const Track *pTrack )
993 auto dc = &context.
dc;
994 bool hit = target && target->GetTrack().get() == pTrack;
995 bool captured = hit && target->IsClicked();
1002 pParent, captured, hit);
1007 const wxRect &rect,
const Track *pTrack )
1010 auto dc = &context.
dc;
1011 bool hit = target && target->GetTrack().get() == pTrack;
1014 bool captured = hit && target->IsClicked();
1021 pParent, captured, hit);
1027 static const int offset = 3;
1028 dc->DrawText(
string.Translation(), rect.x + offset, rect.y);
1033 const wxRect &rect,
const Track *pTrack )
1035 auto dc = &context.
dc;
1036 auto wt =
static_cast<const WaveTrack*
>(pTrack);
1041 auto rate = wt ? wt->
GetRate() : 44100.0;
1046 s =
XO(
"Stereo, %dHz");
1049 s =
XO(
"Mono, %dHz");
1051 s =
XO(
"Left, %dHz");
1053 s =
XO(
"Right, %dHz");
1055 s.
Format( (
int) (rate + 0.5) );
1062 const wxRect &rect,
const Track *pTrack )
1064 auto dc = &context.
dc;
1065 auto wt =
static_cast<const WaveTrack*
>(pTrack);
1086#ifdef EXPERIMENTAL_DA
1102 dest.y = topleft.y + results.first;
1103 dest.height = results.second;
1110 dest.y = topleft.y + results.first;
1125std::unique_ptr<LWSlider>
1136 auto rect = panel.
FindRect( controls );
1139 return GainSlider( sliderRect, &wt,
false, &panel );
1143(
const wxRect &sliderRect,
const WaveTrack *t,
bool captured, wxWindow *pParent)
1145 static std::once_flag
flag;
1149 wxPoint pos = sliderRect.GetPosition();
1150 float gain = t ? t->
GetGain() : 1.0;
1158 slider->SetParent( pParent );
1166 const wxPoint point{ 0, 0 };
1172 gGain = std::make_unique<LWSlider>(
nullptr,
XO(
"Gain"),
1173 wxPoint(sliderRect.x, sliderRect.y),
1174 wxSize(sliderRect.width, sliderRect.height),
1176 gGain->SetDefaultValue(defPos);
1179 wxPoint(sliderRect.x, sliderRect.y),
1180 wxSize(sliderRect.width, sliderRect.height),
1189 auto rect = panel.
FindRect( controls );
1192 return PanSlider( sliderRect, &wt,
false, &panel );
1196(
const wxRect &sliderRect,
const WaveTrack *t,
bool captured, wxWindow *pParent)
1198 static std::once_flag
flag;
1202 wxPoint pos = sliderRect.GetPosition();
1203 float pan = t ? t->
GetPan() : 0.0;
1211 slider->SetParent( pParent );
1219 const wxPoint point{ 0, 0 };
1225 gPan = std::make_unique<LWSlider>(
nullptr,
XO(
"Pan"),
1226 wxPoint(sliderRect.x, sliderRect.y),
1227 wxSize(sliderRect.width, sliderRect.height),
1229 gPan->SetDefaultValue(defPos);
1232 wxPoint(sliderRect.x, sliderRect.y),
1233 wxSize(sliderRect.width, sliderRect.height),
1241 return std::make_shared<WaveTrackControls>( track.
SharedPointer() );
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
std::shared_ptr< UIHandle > UIHandlePtr
wxFrame * FindProjectFrame(AudacityProject *project)
Get a pointer to the window associated with a project, or null if the given pointer is null,...
TrackInfo::TCPLines TCPLines
An AudacityException with no visible message.
DEFINE_ATTACHED_VIRTUAL_OVERRIDE(DoGetWaveTrackControls)
AppendCheckItem("8000", OnRate8ID, XXO("8000 Hz"), POPUP_MENU_FN(OnRateChange), fn)
static std::vector< WaveTrackSubViewType > AllTypes()
TrackInfo::TCPLine TCPLine
static const auto enableSplitStereo
static int gRates[nRates]
Append([](My &table) -> Registry::BaseItemPtr { if(WaveTrackSubViews::slots() > 1) return std::make_unique< Entry >("MultiView", Entry::CheckItem, OnMultiViewID, XXO("&Multi-view"), POPUP_MENU_FN(OnMultiView), table, [](PopupMenuHandler &handler, wxMenu &menu, int id){ auto &table=static_cast< WaveTrackMenuTable & >(handler);auto &track=table.FindWaveTrack();const auto &view=WaveTrackView::Get(track);menu.Check(id, view.GetMultiView());});else return nullptr;})
WaveTrackTCPLines waveTrackTCPLines
AppendRadioItem("16Bit", On16BitID, GetSampleFormatStr(int16Sample), POPUP_MENU_FN(OnFormatChange), fn)
WaveTrackPopupMenuTable & GetWaveTrackMenuTable()
static const auto MenuPathStart
static const auto isUnsafe
AppendItem("MakeStereo", OnMergeStereoID, XXO("Ma&ke Stereo Track"), POPUP_MENU_FN(OnMergeStereo), [](PopupMenuHandler &handler, wxMenu &menu, int id){ bool canMakeStereo=!isUnsafe(handler) &&isMono(handler);if(canMakeStereo) { AudacityProject &project=static_cast< WaveTrackMenuTable & >(handler).mpData->project;auto &tracks=TrackList::Get(project);auto &table=static_cast< WaveTrackMenuTable & >(handler);auto &track=table.FindWaveTrack();auto next= *++tracks.Find(&track);canMakeStereo=(next &&TrackList::Channels(next).size()==1 &&track_cast< WaveTrack * >(next));} menu.Enable(id, canMakeStereo);})
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Formerly part of TrackPanel, this abstract base class has no special knowledge of Track objects and i...
wxRect FindRect(const TrackPanelCell &cell)
static size_t slots()
How many static factories have been registered with this specialization of Site.
Subclass * Find(const RegisteredFactory &key)
Get a (bare) pointer to an attachment, or null, down-cast it to Subclass *; will not create on demand...
Subclass & Get(const RegisteredFactory &key)
Get reference to an attachment, creating on demand if not present, down-cast it to Subclass.
virtual std::vector< UIHandlePtr > HitTest(const TrackPanelMouseState &state, const AudacityProject *) override=0
std::shared_ptr< Track > FindTrack()
static UIHandlePtr HitTest(std::weak_ptr< GainSliderHandle > &holder, const wxMouseState &state, const wxRect &rect, const std::shared_ptr< Track > &pTrack)
Lightweight version of ASlider. In other words it does not have a window permanently associated with ...
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
static UIHandlePtr HitTest(std::weak_ptr< PanSliderHandle > &holder, const wxMouseState &state, const wxRect &rect, const std::shared_ptr< Track > &pTrack)
static const TCPLines & StaticWaveTCPLines()
bool IsAudioActive() const
static ProjectAudioIO & Get(AudacityProject &project)
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
void ModifyState(bool bWantsAutoSave)
static ProjectHistory & Get(AudacityProject &project)
static RealtimeEffectManager & Get(AudacityProject &project)
bool IsActive() const noexcept
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
static TrackArtist * Get(TrackPanelDrawingContext &)
static TrackControls & Get(Track &track)
Abstract base class for an object holding data associated with points on a time axis.
void SetChannel(ChannelType c) noexcept
std::shared_ptr< Subclass > SharedPointer()
static TrackList & Get(AudacityProject &project)
static bool SwapChannels(Track &track)
If the given track is one of a pair of channels, swap them.
void UnlinkChannels(Track &track)
Removes linkage if track belongs to a group.
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
bool GetMinimized() const
void SetExpandedHeight(int height)
static TrackView & Get(Track &)
Holds a msgid for the translation catalog; may also bind format arguments.
TranslatableString & Format(Args &&...args) &
Capture variadic format arguments (by copy) when there is no plural.
Can be thrown when user cancels operations, as with a progress dialog. Delayed handler does nothing.
PopupMenuTable * GetMenuExtension(Track *pTrack) override
std::weak_ptr< MuteButtonHandle > mMuteHandle
static unsigned DefaultWaveTrackHeight()
std::weak_ptr< PanSliderHandle > mPanHandle
static void GetGainRect(const wxPoint &topLeft, wxRect &dest)
static void GetPanRect(const wxPoint &topLeft, wxRect &dest)
std::weak_ptr< EffectsButtonHandle > mEffectsHandle
const TCPLines & GetTCPLines() const override
std::weak_ptr< GainSliderHandle > mGainHandle
static LWSlider * PanSlider(CellularPanel &panel, const WaveTrack &wt)
std::weak_ptr< SoloButtonHandle > mSoloHandle
static void ReCreatePanSlider(struct ThemeChangeMessage)
std::vector< UIHandlePtr > HitTest(const TrackPanelMouseState &state, const AudacityProject *pProject) override
static void ReCreateGainSlider(struct ThemeChangeMessage)
static LWSlider * GainSlider(CellularPanel &panel, const WaveTrack &wt)
A Track that contains audio waveform data.
void SetPan(float newPan) override
double GetRate() const override
void Merge(const Track &orig) override
void SetDisplay(Display display, bool exclusive=true)
static WaveTrackView & Get(WaveTrack &track)
Positions or offsets within audio files need a wide type.
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
void SetName(const TranslatableString &title)
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
auto begin(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Namespace containing an enum 'what to do on a refresh?'.
std::unique_ptr< BaseItem > BaseItemPtr
AUDACITY_DLL_API void GetSliderHorizontalBounds(const wxPoint &topleft, wxRect &dest)
AUDACITY_DLL_API unsigned DefaultTrackHeight(const TCPLines &topLines)
AUDACITY_DLL_API std::pair< int, int > CalcItemY(const TCPLines &lines, unsigned iItem)
static float findValue(const float *spectrum, float bin0, float bin1, unsigned nBins, bool autocorrelation, int gain, int range)
void SliderDrawFunction(LWSlider *(*Selector)(const wxRect &sliderRect, const WaveTrack *t, bool captured, wxWindow *), wxDC *dc, const wxRect &rect, const Track *pTrack, wxWindow *pParent, bool captured, bool highlight)
std::unique_ptr< LWSlider > gPanCaptured
void Status1DrawFunction(TrackPanelDrawingContext &context, const wxRect &rect, const Track *pTrack)
std::function< int(WaveTrack &) > ValueFinder
void GainSliderDrawFunction(TrackPanelDrawingContext &context, const wxRect &rect, const Track *pTrack)
std::unique_ptr< LWSlider > gGain
void Status2DrawFunction(TrackPanelDrawingContext &context, const wxRect &rect, const Track *pTrack)
void PanSliderDrawFunction(TrackPanelDrawingContext &context, const wxRect &rect, const Track *pTrack)
PopupMenuTableEntry::InitFunction initFn(const ValueFinder &findValue)
std::unique_ptr< LWSlider > gGainCaptured
std::unique_ptr< LWSlider > gPan
void StatusDrawFunction(const TranslatableString &string, wxDC *dc, const wxRect &rect)
For defining overrides of the method.
std::optional< PreferredSystemAppearance > appearance
static const std::vector< WaveTrackSubViewType > & All()
Discover all registered types.