From 64a96e6f019da11d110516ecc9664cc8d1457f76 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Wed, 31 Jan 2018 11:31:55 -0500 Subject: [PATCH] Define and use ShuttleGui::ConnectRoot... ... And corrected improper connections in HistoryWindow and ContrastDialog, improper because they got called with the wrong this pointer, to the control instead of the dialog. But that was harmless anyway because the handlers did not use this. --- src/HistoryWindow.cpp | 26 ++++++++++++---------- src/HistoryWindow.h | 1 + src/PluginManager.cpp | 5 ++--- src/ShuttleGui.cpp | 3 +++ src/ShuttleGui.h | 43 ++++++++++++++++++++++++++++++++++++ src/SplashDialog.cpp | 17 +++++++------- src/SplashDialog.h | 1 + src/effects/Contrast.cpp | 20 +++++++++++------ src/effects/Contrast.h | 1 + src/effects/Equalization.cpp | 10 ++++++--- src/effects/Equalization.h | 1 + src/prefs/KeyConfigPrefs.cpp | 37 ++++++++++++++----------------- src/prefs/KeyConfigPrefs.h | 6 ++--- 13 files changed, 115 insertions(+), 56 deletions(-) diff --git a/src/HistoryWindow.cpp b/src/HistoryWindow.cpp index 051007f0e..0f717b273 100644 --- a/src/HistoryWindow.cpp +++ b/src/HistoryWindow.cpp @@ -96,16 +96,14 @@ HistoryWindow::HistoryWindow(AudacityProject *parent, UndoManager *manager): S.StartMultiColumn(3, wxCENTRE); { - mTotal = S.Id(ID_TOTAL).AddTextBox(_("&Total space used"), wxT("0"), 10); - mTotal->Bind(wxEVT_KEY_DOWN, - // ignore it - [](wxEvent&){}); + mTotal = S.Id(ID_TOTAL) + .ConnectRoot(wxEVT_KEY_DOWN, &HistoryWindow::OnChar) + .AddTextBox(_("&Total space used"), wxT("0"), 10); S.AddVariableText( {} )->Hide(); - mAvail = S.Id(ID_AVAIL).AddTextBox(_("&Undo levels available"), wxT("0"), 10); - mAvail->Bind(wxEVT_KEY_DOWN, - // ignore it - [](wxEvent&){}); + mAvail = S.Id(ID_AVAIL) + .ConnectRoot(wxEVT_KEY_DOWN, &HistoryWindow::OnChar) + .AddTextBox(_("&Undo levels available"), wxT("0"), 10); S.AddVariableText( {} )->Hide(); S.AddPrompt(_("&Levels to discard")); @@ -122,10 +120,9 @@ HistoryWindow::HistoryWindow(AudacityProject *parent, UndoManager *manager): /* i18n-hint: (verb)*/ mDiscard = S.Id(ID_DISCARD).AddButton(_("&Discard")); - mClipboard = S.AddTextBox(_("Clipboard space used"), wxT("0"), 10); - mClipboard->Bind(wxEVT_KEY_DOWN, - // ignore it - [](wxEvent&){}); + mClipboard = S + .ConnectRoot(wxEVT_KEY_DOWN, &HistoryWindow::OnChar) + .AddTextBox(_("Clipboard space used"), wxT("0"), 10); S.Id(ID_DISCARD_CLIPBOARD).AddButton(_("Discard")); } S.EndMultiColumn(); @@ -164,6 +161,11 @@ HistoryWindow::HistoryWindow(AudacityProject *parent, UndoManager *manager): parent->Bind(EVT_UNDO_RESET, &HistoryWindow::UpdateDisplay, this); } +void HistoryWindow::OnChar( wxEvent& ) +{ + // ignore it +} + void HistoryWindow::OnAudioIO(wxCommandEvent& evt) { evt.Skip(); diff --git a/src/HistoryWindow.h b/src/HistoryWindow.h index f8b987a4f..f49a06ad2 100644 --- a/src/HistoryWindow.h +++ b/src/HistoryWindow.h @@ -36,6 +36,7 @@ class HistoryWindow final : public wxDialogWrapper { void DoUpdate(); void UpdateLevels(); + void OnChar(wxEvent &event); void OnSize(wxSizeEvent & event); void OnCloseWindow(wxCloseEvent & WXUNUSED(event)); void OnItemSelected(wxListEvent & event); diff --git a/src/PluginManager.cpp b/src/PluginManager.cpp index 17a7eeddb..09e5c62ca 100644 --- a/src/PluginManager.cpp +++ b/src/PluginManager.cpp @@ -578,10 +578,9 @@ void PluginRegistrationDialog::PopulateOrExchange(ShuttleGui &S) mEffects = S.Id(ID_List) .Style(wxSUNKEN_BORDER | wxLC_REPORT | wxLC_HRULES | wxLC_VRULES ) + .ConnectRoot(wxEVT_KEY_DOWN, + &PluginRegistrationDialog::OnListChar) .AddListControlReportMode({ _("Name"), _("State"), _("Path") }); - mEffects->Bind(wxEVT_KEY_DOWN, - &PluginRegistrationDialog::OnListChar, - this); #if wxUSE_ACCESSIBILITY mEffects->SetAccessible(mAx = safenew CheckListAx(mEffects)); #endif diff --git a/src/ShuttleGui.cpp b/src/ShuttleGui.cpp index 835bdab42..d508793d2 100644 --- a/src/ShuttleGui.cpp +++ b/src/ShuttleGui.cpp @@ -2083,6 +2083,9 @@ void ShuttleGuiBase::UpdateSizersCore(bool bPrepend, int Flags, bool prompt) if (mItem.mDisabled) mpWind->Enable( false ); + for (auto &pair : mItem.mRootConnections) + mpWind->Connect( pair.first, pair.second, nullptr, mpDlg ); + // Reset to defaults mItem = {}; } diff --git a/src/ShuttleGui.h b/src/ShuttleGui.h index 9c84c1013..ff0f04e7c 100644 --- a/src/ShuttleGui.h +++ b/src/ShuttleGui.h @@ -180,11 +180,36 @@ struct Item { return std::move( *this ); } + // Dispatch events from the control to the dialog + // The template type deduction ensures consistency between the argument type + // and the event type. It does not (yet) ensure correctness of the type of + // the handler object. + template< typename Tag, typename Argument, typename Handler > + auto ConnectRoot( + wxEventTypeTag eventType, + void (Handler::*func)(Argument&) + ) && + -> typename std::enable_if< + std::is_base_of::value, + Item&& + >::type + { + mRootConnections.push_back({ + eventType, + (void(wxEvtHandler::*)(wxEvent&)) ( + static_cast( func ) + ) + }); + return std::move( *this ); + } + std::function< void(wxWindow*) > mValidatorSetter; TranslatableString mToolTip; TranslatableString mName; TranslatableString mNameSuffix; + std::vector> mRootConnections; + long miStyle{}; bool mFocused { false }; @@ -595,6 +620,24 @@ public: return *this; } + // Dispatch events from the control to the dialog + // The template type deduction ensures consistency between the argument type + // and the event type. It does not (yet) ensure correctness of the type of + // the handler object. + template< typename Tag, typename Argument, typename Handler > + auto ConnectRoot( + wxEventTypeTag eventType, + void (Handler::*func)(Argument&) + ) + -> typename std::enable_if< + std::is_base_of::value, + ShuttleGui& + >::type + { + std::move( mItem ).ConnectRoot( eventType, func ); + return *this; + } + // Prop() sets the proportion value, defined as in wxSizer::Add(). ShuttleGui & Prop( int iProp ){ ShuttleGuiBase::Prop(iProp); return *this;}; // Has to be here too, to return a ShuttleGui and not a ShuttleGuiBase. diff --git a/src/SplashDialog.cpp b/src/SplashDialog.cpp index 50a2a498f..603999b58 100644 --- a/src/SplashDialog.cpp +++ b/src/SplashDialog.cpp @@ -87,6 +87,12 @@ SplashDialog::SplashDialog(wxWindow * parent) Move( x, 60 ); } +void SplashDialog::OnChar(wxMouseEvent &event) +{ + if ( event.ShiftDown() && event.ControlDown() ) + wxLaunchDefaultBrowser("https://www.audacityteam.org"); +} + void SplashDialog::Populate( ShuttleGui & S ) { bool bShow; @@ -118,16 +124,11 @@ void SplashDialog::Populate( ShuttleGui & S ) wxDefaultPosition, wxSize((int)(LOGOWITHNAME_WIDTH*fScale), (int)(LOGOWITHNAME_HEIGHT*fScale))); - S.Prop(0).AddWindow( icon ); - + S.Prop(0) #if (0) - icon->Bind(wxEVT_LEFT_DOWN, - [this]( wxMouseEvent const & event ) ->void { - if ( event.ShiftDown() && event.ControlDown()) - wxLaunchDefaultBrowser("https://www.audacityteam.org"); - } - ); + .ConnectRoot( wxEVT_LEFT_DOWN, &SplashDialog::OnChar) #endif + .AddWindow( icon ); mpHtml = safenew LinkingHtmlWindow(S.GetParent(), -1, wxDefaultPosition, diff --git a/src/SplashDialog.h b/src/SplashDialog.h index 9a9478dde..1a51e07db 100644 --- a/src/SplashDialog.h +++ b/src/SplashDialog.h @@ -33,6 +33,7 @@ public: private: + void OnChar(wxMouseEvent &event); void Populate( ShuttleGui & S ); void OnDontShow( wxCommandEvent & Evt ); diff --git a/src/effects/Contrast.cpp b/src/effects/Contrast.cpp index bb167d760..908b8f7eb 100644 --- a/src/effects/Contrast.cpp +++ b/src/effects/Contrast.cpp @@ -155,7 +155,7 @@ BEGIN_EVENT_TABLE(ContrastDialog,wxDialogWrapper) EVT_BUTTON(wxID_CANCEL, ContrastDialog::OnClose) END_EVENT_TABLE() -static void OnChar(wxKeyEvent & event) +void ContrastDialog::OnChar(wxKeyEvent &event) { // Is this still required? if (event.GetKeyCode() == WXK_TAB) { @@ -252,8 +252,10 @@ ContrastDialog::ContrastDialog(wxWindow * parent, wxWindowID id, .AddWindow(mForegroundEndT); m_pButton_UseCurrentF = S.Id(ID_BUTTON_USECURRENTF).AddButton(_("&Measure selection")); - mForegroundRMSText=S.Id(ID_FOREGROUNDDB_TEXT).AddTextBox( {}, wxT(""), 17); - mForegroundRMSText->Bind(wxEVT_KEY_DOWN, OnChar); + mForegroundRMSText = S.Id(ID_FOREGROUNDDB_TEXT) + .ConnectRoot(wxEVT_KEY_DOWN, + &ContrastDialog::OnChar) + .AddTextBox( {}, wxT(""), 17); //Background S.AddFixedText(_("&Background:")); @@ -284,8 +286,10 @@ ContrastDialog::ContrastDialog(wxWindow * parent, wxWindowID id, .AddWindow(mBackgroundEndT); m_pButton_UseCurrentB = S.Id(ID_BUTTON_USECURRENTB).AddButton(_("Mea&sure selection")); - mBackgroundRMSText = S.Id(ID_BACKGROUNDDB_TEXT).AddTextBox( {}, wxT(""), 17); - mBackgroundRMSText->Bind(wxEVT_KEY_DOWN, OnChar); + mBackgroundRMSText = S.Id(ID_BACKGROUNDDB_TEXT) + .ConnectRoot(wxEVT_KEY_DOWN, + &ContrastDialog::OnChar) + .AddTextBox( {}, wxT(""), 17); } S.EndMultiColumn(); } @@ -300,16 +304,18 @@ ContrastDialog::ContrastDialog(wxWindow * parent, wxWindowID id, S.AddFixedText(label.Translation()); mPassFailText = S.Id(ID_RESULTS_TEXT) .Name(label) + .ConnectRoot(wxEVT_KEY_DOWN, + &ContrastDialog::OnChar) .AddTextBox( {}, wxT(""), 50); - mPassFailText->Bind(wxEVT_KEY_DOWN, OnChar); m_pButton_Reset = S.Id(ID_BUTTON_RESET).AddButton(_("R&eset")); label = XO("&Difference:"); S.AddFixedText(label.Translation()); mDiffText = S.Id(ID_RESULTSDB_TEXT) .Name(label) + .ConnectRoot(wxEVT_KEY_DOWN, + &ContrastDialog::OnChar) .AddTextBox( {}, wxT(""), 50); - mDiffText->Bind(wxEVT_KEY_DOWN, OnChar); m_pButton_Export = S.Id(ID_BUTTON_EXPORT).AddButton(_("E&xport...")); } S.EndMultiColumn(); diff --git a/src/effects/Contrast.h b/src/effects/Contrast.h index 204cbb183..3a4ab4771 100644 --- a/src/effects/Contrast.h +++ b/src/effects/Contrast.h @@ -54,6 +54,7 @@ public: private: // handlers + void OnChar(wxKeyEvent &event); void OnGetURL(wxCommandEvent &event); void OnExport(wxCommandEvent &event); void OnGetForeground(wxCommandEvent & event); diff --git a/src/effects/Equalization.cpp b/src/effects/Equalization.cpp index 746e6e20d..9dea2b622 100644 --- a/src/effects/Equalization.cpp +++ b/src/effects/Equalization.cpp @@ -864,12 +864,10 @@ void EffectEqualization::PopulateOrExchange(ShuttleGui & S) mSliders[i] = safenew wxSliderWrapper(pParent, ID_Slider + i, 0, -20, +20, wxDefaultPosition, wxSize(-1,150), wxSL_VERTICAL | wxSL_INVERSE); - mSliders[i]->Bind(wxEVT_ERASE_BACKGROUND, - // ignore it - [](wxEvent&){}); #if wxUSE_ACCESSIBILITY mSliders[i]->SetAccessible(safenew SliderAx(mSliders[i], _("%d dB"))); #endif + mSlidersOld[i] = 0; mEQVals[i] = 0.; //S.SetSizerProportion(1); @@ -879,6 +877,8 @@ void EffectEqualization::PopulateOrExchange(ShuttleGui & S) ? wxString::Format(_("%d Hz"), (int)kThirdOct[i]) : wxString::Format(_("%g kHz"), kThirdOct[i]/1000.) } ) + .ConnectRoot( + wxEVT_ERASE_BACKGROUND, &EffectEqualization::OnErase) .AddWindow( mSliders[i], wxEXPAND ); } S.AddSpace(15,0); @@ -2757,6 +2757,10 @@ double EffectEqualization::splint(double x[], double y[], size_t n, double y2[], return( a*y[k]+b*y[k+1]+((a*a*a-a)*y2[k]+(b*b*b-b)*y2[k+1])*h*h/6.); } +void EffectEqualization::OnErase( wxEvent& ) +{ +} + void EffectEqualization::OnSize(wxSizeEvent & event) { mUIParent->Layout(); diff --git a/src/effects/Equalization.h b/src/effects/Equalization.h index fe3780fa0..4a38f522d 100644 --- a/src/effects/Equalization.h +++ b/src/effects/Equalization.h @@ -190,6 +190,7 @@ private: void spline(double x[], double y[], size_t n, double y2[]); double splint(double x[], double y[], size_t n, double y2[], double xr); + void OnErase( wxEvent &event ); void OnSize( wxSizeEvent & event ); void OnSlider( wxCommandEvent & event ); void OnInterp( wxCommandEvent & event ); diff --git a/src/prefs/KeyConfigPrefs.cpp b/src/prefs/KeyConfigPrefs.cpp index 4768088db..ecb2df3a1 100644 --- a/src/prefs/KeyConfigPrefs.cpp +++ b/src/prefs/KeyConfigPrefs.cpp @@ -226,14 +226,13 @@ void KeyConfigPrefs::PopulateOrExchange(ShuttleGui & S) #endif wxTE_PROCESS_ENTER); mFilter->SetName(wxStripMenuCodes(mFilterLabel->GetLabel())); - mFilter->Bind(wxEVT_KEY_DOWN, - &KeyConfigPrefs::OnFilterKeyDown, - this); - mFilter->Bind(wxEVT_CHAR, - &KeyConfigPrefs::OnFilterChar, - this); } - S.AddWindow(mFilter, wxALIGN_NOT | wxALIGN_LEFT); + S + .ConnectRoot(wxEVT_KEY_DOWN, + &KeyConfigPrefs::OnFilterKeyDown) + .ConnectRoot(wxEVT_CHAR, + &KeyConfigPrefs::OnFilterChar) + .AddWindow(mFilter, wxALIGN_NOT | wxALIGN_LEFT); } S.EndHorizontalLay(); } @@ -269,17 +268,15 @@ void KeyConfigPrefs::PopulateOrExchange(ShuttleGui & S) mKey->SetAccessible(safenew WindowAccessible(mKey)); #endif mKey->SetName(_("Short cut")); - mKey->Bind(wxEVT_KEY_DOWN, - &KeyConfigPrefs::OnHotkeyKeyDown, - this); - mKey->Bind(wxEVT_CHAR, - &KeyConfigPrefs::OnHotkeyChar, - this); - mKey->Bind(wxEVT_KILL_FOCUS, - &KeyConfigPrefs::OnHotkeyKillFocus, - this); } - S.AddWindow(mKey); + S + .ConnectRoot(wxEVT_KEY_DOWN, + &KeyConfigPrefs::OnHotkeyKeyDown) + .ConnectRoot(wxEVT_CHAR, + &KeyConfigPrefs::OnHotkeyChar) + .ConnectRoot(wxEVT_KILL_FOCUS, + &KeyConfigPrefs::OnHotkeyKillFocus) + .AddWindow(mKey); /* i18n-hint: (verb)*/ mSet = S.Id(SetButtonID).AddButton(_("&Set")); @@ -455,12 +452,12 @@ void KeyConfigPrefs::OnHotkeyKeyDown(wxKeyEvent & e) t->SetValue(KeyEventToKeyString(e).Display()); } -void KeyConfigPrefs::OnHotkeyChar(wxKeyEvent & WXUNUSED(e)) +void KeyConfigPrefs::OnHotkeyChar(wxEvent & WXUNUSED(e)) { // event.Skip() not performed, so event will not be processed further. } -void KeyConfigPrefs::OnHotkeyKillFocus(wxFocusEvent & e) +void KeyConfigPrefs::OnHotkeyKillFocus(wxEvent & e) { if (mKey->GetValue().empty() && mCommandSelected != wxNOT_FOUND) { mKey->AppendText(mView->GetKey(mCommandSelected).Display()); @@ -521,7 +518,7 @@ void KeyConfigPrefs::OnFilterKeyDown(wxKeyEvent & e) } } -void KeyConfigPrefs::OnFilterChar(wxKeyEvent & e) +void KeyConfigPrefs::OnFilterChar(wxEvent & e) { if (mViewType != ViewByKey) { diff --git a/src/prefs/KeyConfigPrefs.h b/src/prefs/KeyConfigPrefs.h index 8c8e236df..28a001f1a 100644 --- a/src/prefs/KeyConfigPrefs.h +++ b/src/prefs/KeyConfigPrefs.h @@ -58,12 +58,12 @@ private: void OnSelected(wxCommandEvent & e); void OnHotkeyKeyDown(wxKeyEvent & e); - void OnHotkeyChar(wxKeyEvent & e); - void OnHotkeyKillFocus(wxFocusEvent & e); + void OnHotkeyChar(wxEvent & e); + void OnHotkeyKillFocus(wxEvent & e); void OnFilterTimer(wxTimerEvent & e); void OnFilterKeyDown(wxKeyEvent & e); - void OnFilterChar(wxKeyEvent & e); + void OnFilterChar(wxEvent & e); KeyView *mView; wxTextCtrl *mKey;