From 81fae8d71c15711488699c155128f89373378a58 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Wed, 20 Apr 2016 15:34:49 -0400 Subject: [PATCH] Rework the ESC key to stop playback as an application event handler... ... So it does not depend on the focused window, and can work when selection toolbar has focus. But TrackPanel's escape handling may still take precedence over it. --- src/AudacityApp.cpp | 29 ++++++++++++++++++++++++++++- src/AudacityApp.h | 2 ++ src/TrackPanel.cpp | 37 +++++++++++++++---------------------- src/TrackPanel.h | 2 +- 4 files changed, 46 insertions(+), 24 deletions(-) diff --git a/src/AudacityApp.cpp b/src/AudacityApp.cpp index 541db3b85..3d9499e01 100644 --- a/src/AudacityApp.cpp +++ b/src/AudacityApp.cpp @@ -113,6 +113,8 @@ It handles initialization and termination by subclassing wxApp. #include "effects/ScoreAlignDialog.h" #endif +#include "tracks/ui/Scrubbing.h" + #if 0 #ifdef _DEBUG #ifdef _MSC_VER @@ -766,6 +768,9 @@ BEGIN_EVENT_TABLE(AudacityApp, wxApp) // Handle AppCommandEvents (usually from a script) EVT_APP_COMMAND(wxID_ANY, AudacityApp::OnReceiveCommand) + + // Global ESC key handling + EVT_KEY_DOWN(AudacityApp::OnKeyDown) END_EVENT_TABLE() // backend for OnMRUFile @@ -1519,7 +1524,29 @@ void AudacityApp::OnReceiveCommand(AppCommandEvent &event) mCmdHandler->OnReceiveCommand(event); } -// We now disallow temp directory name that puts it where cleaner apps will +void AudacityApp::OnKeyDown(wxKeyEvent &event) +{ + if(event.GetKeyCode() == WXK_ESCAPE) { + // Stop play, including scrub, but not record + auto project = ::GetActiveProject(); + auto token = project->GetAudioIOToken(); + auto &scrubber = project->GetScrubber(); + if(scrubber.HasStartedScrubbing()) + // ESC out of scrubbing + scrubber.StopScrubbing(); + else if(token > 0 && + gAudioIO->IsAudioTokenActive(token) && + gAudioIO->GetNumCaptureChannels() == 0) + // ESC out of other play (but not record) + project->OnStop(); + else + event.Skip(); + } + else + event.Skip(); +} + +// We now disallow temp directory name that puts it where cleaner apps will // try to clean out the files. bool AudacityApp::IsTempDirectoryNameOK( const wxString & Name ){ #ifndef __WXMSW__ diff --git a/src/AudacityApp.h b/src/AudacityApp.h index 8df9af48b..998a286f9 100644 --- a/src/AudacityApp.h +++ b/src/AudacityApp.h @@ -132,6 +132,8 @@ class AudacityApp final : public wxApp { void OnReceiveCommand(AppCommandEvent &event); + void OnKeyDown(wxKeyEvent &event); + void OnTimer(wxTimerEvent & event); // IPC communication diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 7067162a6..cdb89e0f2 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -1145,7 +1145,7 @@ void TrackPanel::MakeParentRedrawScrollbars() mListener->TP_RedrawScrollbars(); } -void TrackPanel::HandleEscapeKey(bool down) +bool TrackPanel::HandleEscapeKey(bool down) { // Note that this dispatches some keystrokes even when track panel is not focused. // So it works as a place for escaping from playing and scrub as well as other @@ -1153,7 +1153,7 @@ void TrackPanel::HandleEscapeKey(bool down) // same time, the first ESC applies to the drag action only. if (!down) - return; + return false; switch (mMouseCapture) { @@ -1198,23 +1198,8 @@ void TrackPanel::HandleEscapeKey(bool down) break; default: { - // Stop play, but not record, and only if ESC does - // nothing else. See comments at top of function. - - auto project = GetProject(); - auto token = project->GetAudioIOToken(); - auto &scrubber = project->GetScrubber(); - if(scrubber.HasStartedScrubbing()) - // ESC out of scrubbing - scrubber.StopScrubbing(); - else if(token > 0 && - gAudioIO->IsAudioTokenActive(token) && - gAudioIO->GetNumCaptureChannels() == 0) - // ESC out of other play (but not record) - GetProject()->OnStop(); - // Not escaping from a mouse drag - return; + return false; } } @@ -1225,6 +1210,8 @@ void TrackPanel::HandleEscapeKey(bool down) wxMouseEvent dummy; HandleCursor(dummy); Refresh(false); + + return true; } void TrackPanel::HandleAltKey(bool down) @@ -5778,8 +5765,12 @@ void TrackPanel::OnKeyDown(wxKeyEvent & event) switch (event.GetKeyCode()) { case WXK_ESCAPE: - HandleEscapeKey(true); - break; + if(HandleEscapeKey(true)) + // Don't skip the event, eat it so that + // AudacityApp does not also stop any playback. + return; + else + break; case WXK_ALT: HandleAltKey(true); @@ -5878,10 +5869,11 @@ void TrackPanel::OnChar(wxKeyEvent & event) void TrackPanel::OnKeyUp(wxKeyEvent & event) { + bool didSomething = false; switch (event.GetKeyCode()) { case WXK_ESCAPE: - HandleEscapeKey(false); + didSomething = HandleEscapeKey(false); break; case WXK_ALT: HandleAltKey(false); @@ -5896,7 +5888,8 @@ void TrackPanel::OnKeyUp(wxKeyEvent & event) break; } - event.Skip(); + if(!didSomething) + event.Skip(); } /// Should handle the case when the mouse capture is lost. diff --git a/src/TrackPanel.h b/src/TrackPanel.h index f50cec89f..5d7a4c2af 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -195,7 +195,7 @@ class AUDACITY_DLL_API TrackPanel final : public wxPanel { //virtual void SetSelectionFormat(int iformat) //virtual void SetSnapTo(int snapto) - virtual void HandleEscapeKey(bool down); + virtual bool HandleEscapeKey(bool down); virtual void HandleAltKey(bool down); virtual void HandleShiftKey(bool down); virtual void HandleControlKey(bool down);