1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-05-04 09:39:42 +02:00

Context menu for scrubbing in the ruler

This commit is contained in:
Paul Licameli 2016-04-26 11:09:34 -04:00
parent c12993a53b
commit 3d222bcd87
6 changed files with 107 additions and 46 deletions

View File

@ -689,8 +689,6 @@ struct Final_action {
Final_action(F f) : clean{ f } {}
~Final_action() { clean(); }
F clean;
Final_action(const Final_action&) PROHIBITED;
Final_action& operator= (const Final_action&) PROHIBITED;
};
// Function template with type deduction lets you construct Final_action

View File

@ -10,6 +10,7 @@
#define __AUDACITY_COMMAND_FUNCTORS__
#include <wx/string.h>
#include <wx/event.h>
#include "../MemoryX.h"
class wxEvent;
@ -61,6 +62,24 @@ private:
const audCommandKeyFunction<OBJ> mCommandKeyFunction;
};
// This allows functions to be used either by command manager or by a wxMenu popup,
// but the functions MUST ignore the argument!
template<typename OBJ>
using audCommandPopupFunction = void (OBJ::*)(wxCommandEvent&);
template<typename OBJ>
class PopupFunctor final : public CommandFunctor
{
public:
explicit PopupFunctor(OBJ *This, audCommandPopupFunction<OBJ> pfn)
: mThis{ This }, mCommandPopupFunction{ pfn } {}
void operator () (int, const wxEvent *) override
{ wxCommandEvent dummy; (mThis->*mCommandPopupFunction) (dummy); }
private:
OBJ *const mThis;
const audCommandPopupFunction<OBJ> mCommandPopupFunction;
};
template<typename OBJ>
using audCommandListFunction = void (OBJ::*)(int);
@ -108,6 +127,11 @@ inline CommandFunctorPointer MakeFunctor(OBJ *This,
audCommandKeyFunction<OBJ> pfn)
{ return CommandFunctorPointer{ safenew KeyFunctor<OBJ>{ This, pfn } }; }
template<typename OBJ>
inline CommandFunctorPointer MakeFunctor(OBJ *This,
audCommandPopupFunction<OBJ> pfn)
{ return CommandFunctorPointer{ safenew PopupFunctor<OBJ>{ This, pfn } }; }
template<typename OBJ>
inline CommandFunctorPointer MakeFunctor(OBJ *This,
audCommandListFunction<OBJ> pfn)

View File

@ -141,7 +141,7 @@ namespace {
wxString name;
wxString label;
wxString status;
void (Scrubber::*memFn)();
void (Scrubber::*memFn)(wxCommandEvent&);
bool scroll;
bool seek;
@ -634,26 +634,37 @@ void Scrubber::DoScrub(bool scroll, bool seek)
}
}
void Scrubber::OnScrub()
void Scrubber::OnScrub(wxCommandEvent&)
{
DoScrub(false, false);
}
void Scrubber::OnScrollScrub()
void Scrubber::OnScrollScrub(wxCommandEvent&)
{
DoScrub(true, false);
}
void Scrubber::OnSeek()
void Scrubber::OnSeek(wxCommandEvent&)
{
DoScrub(false, true);
}
void Scrubber::OnScrollSeek()
void Scrubber::OnScrollSeek(wxCommandEvent&)
{
DoScrub(true, true);
}
enum { CMD_ID = 8000 };
BEGIN_EVENT_TABLE(Scrubber, wxEvtHandler)
EVT_MENU(CMD_ID, Scrubber::OnScrub)
EVT_MENU(CMD_ID + 1, Scrubber::OnScrollScrub)
EVT_MENU(CMD_ID + 2, Scrubber::OnSeek)
EVT_MENU(CMD_ID + 3, Scrubber::OnScrollSeek)
END_EVENT_TABLE()
static_assert(nMenuItems == 4, "wrong number of items");
const wxString &Scrubber::GetUntranslatedStateString() const
{
static wxString empty;
@ -697,6 +708,17 @@ void Scrubber::AddMenuItems()
CheckMenuItem();
}
void Scrubber::PopulateMenu(wxMenu &menu)
{
int id = CMD_ID;
auto cm = mProject->GetCommandManager();
for (const auto &item : menuItems) {
if (cm->GetEnabled(item.name))
menu.Append(id, item.label);
++id;
}
}
void Scrubber::UncheckAllMenuItems()
{
auto cm = mProject->GetCommandManager();

View File

@ -66,12 +66,16 @@ public:
// This returns the same as the enabled state of the menu items:
bool CanScrub() const;
void AddMenuItems();
void OnScrub();
void OnScrollScrub();
void OnSeek();
void OnScrollSeek();
// For the toolbar
void AddMenuItems();
// For popup
void PopulateMenu(wxMenu &menu);
void OnScrub(wxCommandEvent&);
void OnScrollScrub(wxCommandEvent&);
void OnSeek(wxCommandEvent&);
void OnScrollSeek(wxCommandEvent&);
// A string to put in the leftmost part of the status bar.
const wxString &GetUntranslatedStateString() const;
@ -101,6 +105,8 @@ private:
#endif
AudacityProject *mProject;
DECLARE_EVENT_TABLE()
};
// Specialist in drawing the scrub speed, and listening for certain events

View File

@ -2162,7 +2162,14 @@ void AdornedRulerPanel::OnMouseEvents(wxMouseEvent &evt)
}
if (evt.RightDown() && !(evt.LeftIsDown())) {
ShowMenu(evt.GetPosition());
if(inScrubZone)
ShowScrubMenu(evt.GetPosition());
else
ShowMenu(evt.GetPosition());
// dismiss and clear Quick-Play indicator
HideQuickPlayIndicator();
if (HasCapture())
ReleaseMouse();
return;
@ -2471,52 +2478,55 @@ void AdornedRulerPanel::OnCaptureLost(wxMouseCaptureLostEvent & WXUNUSED(evt))
OnMouseEvents(e);
}
// Pop-up menu
// Pop-up menus
void AdornedRulerPanel::ShowMenu(const wxPoint & pos)
{
{
wxMenu rulerMenu;
wxMenu rulerMenu;
if (mQuickPlayEnabled)
rulerMenu.Append(OnToggleQuickPlayID, _("Disable Quick-Play"));
else
rulerMenu.Append(OnToggleQuickPlayID, _("Enable Quick-Play"));
if (mQuickPlayEnabled)
rulerMenu.Append(OnToggleQuickPlayID, _("Disable Quick-Play"));
else
rulerMenu.Append(OnToggleQuickPlayID, _("Enable Quick-Play"));
wxMenuItem *dragitem;
if (mPlayRegionDragsSelection && !mProject->IsPlayRegionLocked())
dragitem = rulerMenu.Append(OnSyncQuickPlaySelID, _("Disable dragging selection"));
else
dragitem = rulerMenu.Append(OnSyncQuickPlaySelID, _("Enable dragging selection"));
dragitem->Enable(mQuickPlayEnabled && !mProject->IsPlayRegionLocked());
wxMenuItem *dragitem;
if (mPlayRegionDragsSelection && !mProject->IsPlayRegionLocked())
dragitem = rulerMenu.Append(OnSyncQuickPlaySelID, _("Disable dragging selection"));
else
dragitem = rulerMenu.Append(OnSyncQuickPlaySelID, _("Enable dragging selection"));
dragitem->Enable(mQuickPlayEnabled && !mProject->IsPlayRegionLocked());
#if wxUSE_TOOLTIPS
if (mTimelineToolTip)
rulerMenu.Append(OnTimelineToolTipID, _("Disable Timeline Tooltips"));
else
rulerMenu.Append(OnTimelineToolTipID, _("Enable Timeline Tooltips"));
if (mTimelineToolTip)
rulerMenu.Append(OnTimelineToolTipID, _("Disable Timeline Tooltips"));
else
rulerMenu.Append(OnTimelineToolTipID, _("Enable Timeline Tooltips"));
#endif
if (mViewInfo->bUpdateTrackIndicator)
rulerMenu.Append(OnAutoScrollID, _("Do not scroll while playing"));
else
rulerMenu.Append(OnAutoScrollID, _("Update display while playing"));
if (mViewInfo->bUpdateTrackIndicator)
rulerMenu.Append(OnAutoScrollID, _("Do not scroll while playing"));
else
rulerMenu.Append(OnAutoScrollID, _("Update display while playing"));
wxMenuItem *prlitem;
if (!mProject->IsPlayRegionLocked())
prlitem = rulerMenu.Append(OnLockPlayRegionID, _("Lock Play Region"));
else
prlitem = rulerMenu.Append(OnLockPlayRegionID, _("Unlock Play Region"));
prlitem->Enable(mProject->IsPlayRegionLocked() || (mPlayRegionStart != mPlayRegionEnd));
wxMenuItem *prlitem;
if (!mProject->IsPlayRegionLocked())
prlitem = rulerMenu.Append(OnLockPlayRegionID, _("Lock Play Region"));
else
prlitem = rulerMenu.Append(OnLockPlayRegionID, _("Unlock Play Region"));
prlitem->Enable(mProject->IsPlayRegionLocked() || (mPlayRegionStart != mPlayRegionEnd));
PopupMenu(&rulerMenu, pos);
}
PopupMenu(&rulerMenu, pos);
}
// dismiss and clear Quick-Play indicator
mQuickPlayInd = false;
DrawQuickPlayIndicator(NULL);
void AdornedRulerPanel::ShowScrubMenu(const wxPoint & pos)
{
auto &scrubber = mProject->GetScrubber();
PushEventHandler(&scrubber);
auto cleanup = finally([this]{ PopEventHandler(); });
Refresh();
wxMenu rulerMenu;
mProject->GetScrubber().PopulateMenu(rulerMenu);
PopupMenu(&rulerMenu, pos);
}
void AdornedRulerPanel::OnToggleQuickPlay(wxCommandEvent&)

View File

@ -390,6 +390,7 @@ private:
// Pop-up menu
//
void ShowMenu(const wxPoint & pos);
void ShowScrubMenu(const wxPoint & pos);
void DragSelection();
void HandleSnapping();
void OnToggleQuickPlay(wxCommandEvent &evt);