16#ifdef EXPERIMENTAL_BRUSH_TOOL
23#include <wx/checkbox.h>
27#include <wx/imaglist.h>
29#include <wx/listctrl.h>
30#include <wx/settings.h>
31#include <wx/spinctrl.h>
32#include <wx/statline.h>
33#include <wx/stattext.h>
34#include <wx/textctrl.h>
37#include "../images/Arrow.xpm"
38#include "../images/Empty9x16.xpm"
70 ID_BRUSH_BUTTON = 10000,
74 ID_CHECKBOX_OVERTONES,
102 void DoUpdateDisplay();
103 void UpdateControls(
bool active );
105 bool Show(
bool show =
true )
override;
114 void OnApply(wxCommandEvent &event);
115 void OnBrushButton(wxCommandEvent &event);
116 void OnBrushSizeSlider(wxCommandEvent &event);
117 void OnCheckSmartSelection(wxCommandEvent &event);
118 void OnCheckOvertones(wxCommandEvent &event);
125 , mClipboardSubscription
128 wxToggleButton *mBrushButton =
nullptr;
129 bool mAudioIOBusy {
false };
132 void DoToolChanged();
134 DECLARE_EVENT_TABLE()
137class AUDACITY_DLL_API SpectralDataDialogWorker final
141 ~SpectralDataDialogWorker();
143 void OnToolChanged(wxCommandEvent &evt);
144 void OnIdle(wxIdleEvent &evt);
147 unsigned mPrevNViews = 0;
151 EVT_TOGGLEBUTTON(ID_BRUSH_BUTTON, SpectralDataDialog::OnBrushButton)
152 #ifdef SMART_CHECKBOX
153 EVT_CHECKBOX(ID_CHECKBOX_SMART, SpectralDataDialog::OnCheckSmartSelection)
155 EVT_CHECKBOX(ID_CHECKBOX_OVERTONES, SpectralDataDialog::OnCheckOvertones)
157 EVT_SLIDER(ID_SLIDER_BRUSH_SIZE, SpectralDataDialog::OnBrushSizeSlider)
160#define Title XO("Spectral Data Control Panel")
165 wxDefaultPosition, wxDefaultSize,
166 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER )
177 ->
Subscribe(*
this, &SpectralDataDialog::OnAudioIO);
180 .
Subscribe(*
this, &::SpectralDataDialog::UpdateDisplayForClipboard);
183 .
Subscribe(*
this, &SpectralDataDialog::UpdateDisplay);
188static const AttachedWindows::RegisteredFactory
key{
194static wxToggleButton *MakeButton(wxWindow *pParent)
196 auto button =
safenew wxBitmapToggleButton{
199 button->SetName(
XO(
"Brush Tool").Translation());
205 mBrushButton = MakeButton(
this);
207 S.StartVerticalLay(
true);
210 S.AddVariableText(
XO(
"Spectral Brush"));
211 S.AddWindow(mBrushButton, wxALIGN_LEFT);
213 S.AddVariableText(
XO(
"Brush radius"));
214 S.Id(ID_SLIDER_BRUSH_SIZE)
215 .Style(wxSL_HORIZONTAL)
216 .Name(
XO(
"Custom brush size"))
217 .AddSlider( {}, 5, 10, 1);
219 S.AddWindow(
safenew wxStaticLine{
S.GetParent() });
221 S.Id(ID_CHECKBOX_OVERTONES)
223 XXO(
"Auto-select overtones (beta)"),
227 S.Id(ID_CHECKBOX_SMART)
228 .AddCheckBox(
XXO(
"Enable smart selection"),
false);
232 XO(
"Select the fundamental frequency\n"
233 "and release the mouse"));
240 SetMinSize(GetSize());
246 mAudioIOBusy = ev.
on;
256 switch (message.
type) {
269void SpectralDataDialog::DoUpdateDisplay()
275void SpectralDataDialog::UpdateControls(
bool active )
278 mBrushButton->SetValue(active);
286bool SpectralDataDialog::Show(
bool show )
288 if ( show && !IsShown())
290 if ( IsShown() && !show && IsBrushToolActive(mProject) )
292 auto result = wxDialogWrapper::Show( show );
297void SpectralDataDialog::DoUpdate()
309 bool shown = IsShown();
327void SpectralDataDialog::OnBrushButton(wxCommandEvent &event) {
328 if (mBrushButton->GetValue())
332 mBrushButton->SetValue(
true);
337 return std::make_shared< SpectralDataDialogWorker >( project );
341AttachedWindows::RegisteredFactory sSpectralDataDialogKey{
367SpectralDataDialogWorker::SpectralDataDialogWorker(
AudacityProject &project)
368 : mProject{ project }
370 project.Bind(EVT_PROJECT_SETTINGS_CHANGE, &SpectralDataDialogWorker::OnToolChanged,
this);
371 wxTheApp->Bind(wxEVT_IDLE, &SpectralDataDialogWorker::OnIdle,
this);
374SpectralDataDialogWorker::~SpectralDataDialogWorker()
376 wxTheApp->Unbind(wxEVT_IDLE, &SpectralDataDialogWorker::OnIdle,
this);
379void SpectralDataDialogWorker::OnToolChanged(wxCommandEvent &evt)
385 pDialog && pDialog->IsShown())
386 pDialog->DoToolChanged();
389 using Type = std::underlying_type_t<
decltype(ToolCodes::brushTool)>;
390 constexpr auto value =
static_cast<Type>(ToolCodes::brushTool);
393 if (projectSettings.GetTool() == value) {
394 auto oldValue =
static_cast<Type>( evt.GetExtraLong() );
395 if (oldValue + 1 == value)
397 wxTheApp->CallAfter([&]{ projectSettings.SetTool(
402 wxTheApp->CallAfter([&]{ projectSettings.SetTool(
406 wxTheApp->CallAfter([&]{ projectSettings.SetTool(oldValue); });
412static bool HasVisibleSpectralView(
WaveTrack *wt)
415 if (
auto waveTrackViewPtr =
dynamic_cast<WaveTrackView*
>(&trackView) ) {
416 const auto range = waveTrackViewPtr->GetSubViews();
417 return std::any_of( range.begin(), range.end(),
418 [](
const auto &pair){
419 return dynamic_cast<SpectrumView*>(pair.second.get()); } );
427 return std::count_if( range.begin(), range.end(), HasVisibleSpectralView );
430void SpectralDataDialogWorker::OnIdle(wxIdleEvent &evt)
433 auto nViews = CountVisibleSpectralViews(mProject);
434 if (nViews > mPrevNViews) {
441 else if (nViews == 0 && mPrevNViews > 0) {
447 mPrevNViews = nViews;
450void SpectralDataDialog::DoToolChanged()
452 UpdateControls( IsBrushToolActive(mProject) );
455void SpectralDataDialog::OnBrushSizeSlider(wxCommandEvent &event) {
457 projectSettings.SetBrushRadius(event.GetInt());
460void SpectralDataDialog::OnCheckSmartSelection(wxCommandEvent &event){
461 int isSelected =
event.GetInt();
462 wxASSERT(isSelected == 0 || isSelected == 1);
464 projectSettings.SetSmartSelection(isSelected);
467void SpectralDataDialog::OnCheckOvertones(wxCommandEvent &event){
468 int isSelected =
event.GetInt();
469 wxASSERT(isSelected == 0 || isSelected == 1);
471 projectSettings.SetOvertones(isSelected);
472#ifndef SMART_CHECKBOX
474 OnCheckSmartSelection(event);
481 auto &project = context.
project;
483 dialog.Show( !dialog.IsShown() );
488 wxT(
"View/Other/Toolbars/Toolbars/Other"),
490 XXO(
"Spectra&l Selection Panel"),
491 OnSpectralEditingPanel,
497 return pDialog && pDialog->IsShown();
Utility ClientData::Site to register hooks into a host class that attach client data.
constexpr CommandFlag AlwaysEnabledFlag
static const AudacityProject::AttachedObjects::RegisteredFactory key
XXO("&Cut/Copy/Paste Toolbar")
wxFrame * FindProjectFrame(AudacityProject *project)
Get a pointer to the window associated with a project, or null if the given pointer is null,...
AUDACITY_DLL_API AttachedWindows & GetAttachedWindows(AudacityProject &project)
accessors for certain important windows associated with each project
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Client code makes static instance from a factory of attachments; passes it to Get or Find as a retrie...
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.
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
AudacityProject & project
void UpdateCheckmarks(AudacityProject &project)
static CommandManager & Get(AudacityProject &project)
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
A move-only handle representing a connection to a Publisher.
A listener notified of changes in preferences.
static ProjectSettings & Get(AudacityProject &project)
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Provides UI for spectral editing and parameters adjustments.
wxBitmap & Bitmap(int iIndex)
auto Any() -> TrackIterRange< TrackType >
static TrackList & Get(AudacityProject &project)
static TrackView & Get(Track &)
Maintain a non-persistent list of states of the project, to support undo and redo commands.
static UndoManager & Get(AudacityProject &project)
A Track that contains audio waveform data.
wxString Find(const FilePath &path)
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
AUDACITY_DLL_API void UpdatePrefs(wxWindow *pParent)
void OnCloseWindow(wxCloseEvent &e)
enum AudioIOEvent::Type type
A convenient default parameter for class template Site.
Message is sent during idle time by the global clipboard.
Options && CheckTest(const CheckFn &fn) &&
Type of message published by UndoManager.
@ Purge
Undo or redo states eliminated.
enum UndoRedoMessage::Type type