1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-23 15:50:05 +02:00

Tool tips, status messages for most buttons mention shortcut keys...

... Also for the pin/unpin button on the ruler.

Exceptions:  scrubbing toolbar; transcription play does not mention shift
and ctrl modified versions.

Note too that on Mac, the special characters are used to indicate modifiers.
This commit is contained in:
Paul Licameli 2016-06-12 00:02:49 -04:00
commit c1ee03d48f
30 changed files with 260 additions and 110 deletions

View File

@ -229,3 +229,12 @@ wxString Internat::StripAccelerators(const wxString &s)
} }
return result; return result;
} }
wxString Internat::Parenthesize(const wxString &str)
{
/* i18n-hint: An opening parenthesis, in some languages a right parenthesis */
auto open = _("(");
/* i18n-hint: A closing parenthesis, in some languages a left parenthesis */
auto close = _(")");
return open + str + close;
}

View File

@ -73,6 +73,8 @@ public:
* when they aren't, saving translators effort. */ * when they aren't, saving translators effort. */
static wxString StripAccelerators(const wxString& str); static wxString StripAccelerators(const wxString& str);
static wxString Parenthesize(const wxString &str);
private: private:
static wxChar mDecimalSeparator; static wxChar mDecimalSeparator;

View File

@ -545,7 +545,7 @@ AudacityProject *CreateNewAudacityProject()
// Okay, GetActiveProject() is ready. Now we can get its CommandManager, // Okay, GetActiveProject() is ready. Now we can get its CommandManager,
// and add the shortcut keys to the tooltips. // and add the shortcut keys to the tooltips.
p->GetControlToolBar()->RegenerateToolsTooltips(); p->GetToolManager()->RegenerateTooltips();
ModuleManager::Get().Dispatch(ProjectInitialized); ModuleManager::Get().Dispatch(ProjectInitialized);

View File

@ -491,6 +491,9 @@ TrackPanel::TrackPanel(wxWindow * parent, wxWindowID id,
mAdjustLeftSelectionCursor = std::make_unique<wxCursor>(wxCURSOR_POINT_LEFT); mAdjustLeftSelectionCursor = std::make_unique<wxCursor>(wxCURSOR_POINT_LEFT);
mAdjustRightSelectionCursor = std::make_unique<wxCursor>(wxCURSOR_POINT_RIGHT); mAdjustRightSelectionCursor = std::make_unique<wxCursor>(wxCURSOR_POINT_RIGHT);
// Menu pointers are set to NULL here. Delay building of menus until after
// the command managter is finished, so that we can look up shortcut
// key strings that need to appear in some of the popup menus.
mWaveTrackMenu = NULL; mWaveTrackMenu = NULL;
mChannelItemsInsertionPoint = 0; mChannelItemsInsertionPoint = 0;
@ -500,8 +503,6 @@ TrackPanel::TrackPanel(wxWindow * parent, wxWindowID id,
mRulerWaveformMenu = mRulerSpectrumMenu = NULL; mRulerWaveformMenu = mRulerSpectrumMenu = NULL;
BuildMenus();
mTrackArtist = new TrackArtist(); mTrackArtist = new TrackArtist();
mTrackArtist->SetInset(1, kTopMargin, kRightMargin, kBottomMargin); mTrackArtist->SetInset(1, kTopMargin, kRightMargin, kBottomMargin);
@ -586,6 +587,12 @@ TrackPanel::~TrackPanel()
delete mInitialTrackSelection; delete mInitialTrackSelection;
} }
void TrackPanel::BuildMenusIfNeeded(void)
{
if (!mRateMenu)
BuildMenus();
}
void TrackPanel::BuildMenus(void) void TrackPanel::BuildMenus(void)
{ {
// Get rid of existing menus // Get rid of existing menus
@ -676,6 +683,8 @@ void TrackPanel::BuildCommonDropMenuItems(wxMenu * menu)
{ {
menu->Append(OnSetNameID, _("&Name...")); menu->Append(OnSetNameID, _("&Name..."));
menu->AppendSeparator(); menu->AppendSeparator();
// It is not correct to use KeyStringDisplay here -- wxWidgets will apply
// its equivalent to the key names passed to menu functions.
menu->Append(OnMoveUpID, _("Move Track &Up") + wxT("\t") + menu->Append(OnMoveUpID, _("Move Track &Up") + wxT("\t") +
(GetProject()->GetCommandManager()->GetKeyFromName(wxT("TrackMoveUp")))); (GetProject()->GetCommandManager()->GetKeyFromName(wxT("TrackMoveUp"))));
menu->Append(OnMoveDownID, _("Move Track &Down") + wxT("\t") + menu->Append(OnMoveDownID, _("Move Track &Down") + wxT("\t") +
@ -708,6 +717,8 @@ void TrackPanel::DeleteMenus(void)
{ {
// Note that the submenus (mRateMenu, ...) // Note that the submenus (mRateMenu, ...)
// are deleted by their parent // are deleted by their parent
mRateMenu = mFormatMenu = nullptr;
if (mWaveTrackMenu) { if (mWaveTrackMenu) {
delete mWaveTrackMenu; delete mWaveTrackMenu;
mWaveTrackMenu = NULL; mWaveTrackMenu = NULL;
@ -7480,6 +7491,8 @@ void TrackPanel::ScrollIntoView(int x)
void TrackPanel::OnTrackMenu(Track *t) void TrackPanel::OnTrackMenu(Track *t)
{ {
BuildMenusIfNeeded();
if(!t) { if(!t) {
t = GetFocusedTrack(); t = GetFocusedTrack();
if(!t) return; if(!t) return;
@ -8083,6 +8096,8 @@ void TrackPanel::SetRate(Track * pTrack, double rate)
/// track menu. /// track menu.
void TrackPanel::OnFormatChange(wxCommandEvent & event) void TrackPanel::OnFormatChange(wxCommandEvent & event)
{ {
BuildMenusIfNeeded();
int id = event.GetId(); int id = event.GetId();
wxASSERT(id >= On16BitID && id <= OnFloatID); wxASSERT(id >= On16BitID && id <= OnFloatID);
wxASSERT(mPopupMenuTarget wxASSERT(mPopupMenuTarget
@ -8174,6 +8189,8 @@ static int gRates[nRates] = { 8000, 11025, 16000, 22050, 44100, 48000, 88200, 96
/// submenu of the track menu, except for "Other" (/see OnRateOther). /// submenu of the track menu, except for "Other" (/see OnRateOther).
void TrackPanel::OnRateChange(wxCommandEvent & event) void TrackPanel::OnRateChange(wxCommandEvent & event)
{ {
BuildMenusIfNeeded();
int id = event.GetId(); int id = event.GetId();
wxASSERT(id >= OnRate8ID && id <= OnRate384ID); wxASSERT(id >= OnRate8ID && id <= OnRate384ID);
wxASSERT(mPopupMenuTarget wxASSERT(mPopupMenuTarget
@ -8199,6 +8216,8 @@ int TrackPanel::IdOfRate( int rate )
void TrackPanel::OnRateOther(wxCommandEvent &event) void TrackPanel::OnRateOther(wxCommandEvent &event)
{ {
BuildMenusIfNeeded();
wxASSERT(mPopupMenuTarget wxASSERT(mPopupMenuTarget
&& mPopupMenuTarget->GetKind() == Track::Wave); && mPopupMenuTarget->GetKind() == Track::Wave);

View File

@ -147,6 +147,7 @@ class AUDACITY_DLL_API TrackPanel final : public OverlayPanel {
virtual ~ TrackPanel(); virtual ~ TrackPanel();
virtual void BuildMenusIfNeeded(void);
virtual void BuildMenus(void); virtual void BuildMenus(void);
virtual void DeleteMenus(void); virtual void DeleteMenus(void);

View File

@ -43,13 +43,25 @@ wxString KeyStringNormalize(const wxString & key)
#endif #endif
} }
wxString KeyStringDisplay(const wxString & key) wxString KeyStringDisplay(const wxString & key, bool useSspecialChars)
{ {
wxString newkey = KeyStringNormalize(key); wxString newkey = KeyStringNormalize(key);
#if defined(__WXMAC__) #if defined(__WXMAC__)
if (!useSspecialChars) {
// Compose user-visible keystroke names, all ASCII
newkey.Replace(wxT("XCtrl+"), wxT("Control+")); newkey.Replace(wxT("XCtrl+"), wxT("Control+"));
newkey.Replace(wxT("Alt+"), wxT("Option+")); newkey.Replace(wxT("Alt+"), wxT("Option+"));
newkey.Replace(wxT("Ctrl+"), wxT("Command+")); newkey.Replace(wxT("Ctrl+"), wxT("Command+"));
}
else {
// Compuse user-visible keystroke names, with special characters
newkey.Replace(wxT("Shift+"), wxT("\u21e7"));
newkey.Replace(wxT("XCtrl+"), wxT("Control+"));
newkey.Replace(wxT("Alt+"), wxT("\u2325"));
newkey.Replace(wxT("Ctrl+"), wxT("\u2318"));
}
#endif #endif
return newkey; return newkey;

View File

@ -14,5 +14,5 @@
#include <wx/string.h> #include <wx/string.h>
wxString KeyStringNormalize(const wxString & key); wxString KeyStringNormalize(const wxString & key);
wxString KeyStringDisplay(const wxString & key); wxString KeyStringDisplay(const wxString & key, bool useSpecialChars = false);
wxString KeyEventToKeyString(const wxKeyEvent & keyEvent); wxString KeyEventToKeyString(const wxKeyEvent & keyEvent);

View File

@ -188,7 +188,7 @@ void ControlToolBar::Populate()
mRecord->FollowModifierKeys(); mRecord->FollowModifierKeys();
#if wxUSE_TOOLTIPS #if wxUSE_TOOLTIPS
RegenerateToolsTooltips(); RegenerateTooltips();
wxToolTip::Enable(true); wxToolTip::Enable(true);
wxToolTip::SetDelay(1000); wxToolTip::SetDelay(1000);
#endif #endif
@ -197,47 +197,41 @@ void ControlToolBar::Populate()
ArrangeButtons(); ArrangeButtons();
} }
void ControlToolBar::RegenerateToolsTooltips() void ControlToolBar::RegenerateTooltips()
{ {
#if wxUSE_TOOLTIPS #if wxUSE_TOOLTIPS
std::vector<wxString> commands;
for (long iWinID = ID_PLAY_BUTTON; iWinID < BUTTON_COUNT; iWinID++) for (long iWinID = ID_PLAY_BUTTON; iWinID < BUTTON_COUNT; iWinID++)
{ {
wxWindow* pCtrl = this->FindWindow(iWinID); commands.clear();
wxString strToolTip = pCtrl->GetLabel(); auto pCtrl = static_cast<AButton*>(this->FindWindow(iWinID));
AudacityProject* pProj = GetActiveProject(); commands.push_back(pCtrl->GetLabel());
CommandManager* pCmdMgr = (pProj) ? pProj->GetCommandManager() : NULL;
if (pCmdMgr)
{
wxString strKey(wxT(" ("));
switch (iWinID) switch (iWinID)
{ {
case ID_PLAY_BUTTON: case ID_PLAY_BUTTON:
strKey += pCmdMgr->GetKeyFromName(wxT("Play")); commands.push_back(wxT("Play"));
strKey += _(") / Loop Play ("); commands.push_back(_("Loop Play"));
strKey += pCmdMgr->GetKeyFromName(wxT("PlayLooped")); commands.push_back(wxT("PlayLooped"));
break; break;
case ID_RECORD_BUTTON: case ID_RECORD_BUTTON:
strKey += pCmdMgr->GetKeyFromName(wxT("Record")); commands.push_back(wxT("Record"));
strKey += _(") / Append Record ("); commands.push_back(_("Append Record"));
strKey += pCmdMgr->GetKeyFromName(wxT("RecordAppend")); commands.push_back(wxT("RecordAppend"));
break; break;
case ID_PAUSE_BUTTON: case ID_PAUSE_BUTTON:
strKey += pCmdMgr->GetKeyFromName(wxT("Pause")); commands.push_back(wxT("Pause"));
break; break;
case ID_STOP_BUTTON: case ID_STOP_BUTTON:
strKey += pCmdMgr->GetKeyFromName(wxT("Stop")); commands.push_back(wxT("Stop"));
break; break;
case ID_FF_BUTTON: case ID_FF_BUTTON:
strKey += pCmdMgr->GetKeyFromName(wxT("SkipEnd")); commands.push_back(wxT("SkipEnd"));
break; break;
case ID_REW_BUTTON: case ID_REW_BUTTON:
strKey += pCmdMgr->GetKeyFromName(wxT("SkipStart")); commands.push_back(wxT("SkipStart"));
break; break;
} }
strKey += wxT(")"); ToolBar::SetButtonToolTip(*pCtrl, commands);
strToolTip += strKey;
}
pCtrl->SetToolTip(strToolTip);
} }
#endif #endif
} }
@ -262,14 +256,14 @@ void ControlToolBar::UpdatePrefs()
if( updated ) if( updated )
{ {
ReCreateButtons(); // side effect: calls RegenerateToolsTooltips() ReCreateButtons(); // side effect: calls RegenerateTooltips()
Updated(); Updated();
} }
else else
// The other reason to regenerate tooltips is if keyboard shortcuts for // The other reason to regenerate tooltips is if keyboard shortcuts for
// transport buttons changed, but that's too much work to check for, so just // transport buttons changed, but that's too much work to check for, so just
// always do it. (Much cheaper than calling ReCreateButtons() in all cases. // always do it. (Much cheaper than calling ReCreateButtons() in all cases.
RegenerateToolsTooltips(); RegenerateTooltips();
// Set label to pull in language change // Set label to pull in language change
@ -383,7 +377,7 @@ void ControlToolBar::ReCreateButtons()
EnableDisableButtons(); EnableDisableButtons();
RegenerateToolsTooltips(); RegenerateTooltips();
} }
void ControlToolBar::Repaint( wxDC *dc ) void ControlToolBar::Repaint( wxDC *dc )

View File

@ -101,7 +101,7 @@ class ControlToolBar final : public ToolBar {
void EnableDisableButtons() override; void EnableDisableButtons() override;
void ReCreateButtons() override; void ReCreateButtons() override;
void RegenerateToolsTooltips(); void RegenerateTooltips() override;
int WidthForStatusBar(wxStatusBar* const); int WidthForStatusBar(wxStatusBar* const);
void UpdateStatusBar(AudacityProject *pProject); void UpdateStatusBar(AudacityProject *pProject);

View File

@ -63,7 +63,7 @@ class DeviceToolBar final : public ToolBar {
void SetDevices(const DeviceSourceMap *in, const DeviceSourceMap *out); void SetDevices(const DeviceSourceMap *in, const DeviceSourceMap *out);
void RepositionCombos(); void RepositionCombos();
void SetNames(); void SetNames();
void RegenerateTooltips(); void RegenerateTooltips() override;
void ShowComboDialog(wxChoice *combo, const wxString &title); void ShowComboDialog(wxChoice *combo, const wxString &title);

View File

@ -198,24 +198,40 @@ void EditToolBar::UpdatePrefs()
void EditToolBar::RegenerateTooltips() void EditToolBar::RegenerateTooltips()
{ {
#if wxUSE_TOOLTIPS #if wxUSE_TOOLTIPS
mButtons[ETBCutID]->SetToolTip(_("Cut")); static const struct Entry {
mButtons[ETBCopyID]->SetToolTip(_("Copy")); int tool;
mButtons[ETBPasteID]->SetToolTip(_("Paste")); wxString commandName;
mButtons[ETBTrimID]->SetToolTip(_("Trim Audio")); wxString untranslatedLabel;
mButtons[ETBSilenceID]->SetToolTip(_("Silence Audio")); } table[] = {
mButtons[ETBUndoID]->SetToolTip(_("Undo")); { ETBCutID, wxT("Cut"), XO("Cut") },
mButtons[ETBRedoID]->SetToolTip(_("Redo")); { ETBCopyID, wxT("Copy"), XO("Copy") },
{ ETBPasteID, wxT("Paste"), XO("Paste") },
{ ETBTrimID, wxT("Trim"), XO("Trim Audio") },
{ ETBSilenceID, wxT("Silence"), XO("Silence Audio") },
{ ETBUndoID, wxT("Undo"), XO("Undo") },
{ ETBRedoID, wxT("Redo"), XO("Redo") },
#ifdef EXPERIMENTAL_SYNC_LOCK #ifdef EXPERIMENTAL_SYNC_LOCK
mButtons[ETBSyncLockID]->SetToolTip(_("Sync-Lock Tracks")); { ETBSyncLockID, wxT("SyncLock"), XO("Sync-Lock Tracks") },
#endif #endif
mButtons[ETBZoomInID]->SetToolTip(_("Zoom In"));
mButtons[ETBZoomOutID]->SetToolTip(_("Zoom Out")); { ETBZoomInID, wxT("ZoomIn"), XO("Zoom In") },
mButtons[ETBZoomSelID]->SetToolTip(_("Fit Selection")); { ETBZoomOutID, wxT("ZoomOut"), XO("Zoom Out") },
mButtons[ETBZoomFitID]->SetToolTip(_("Fit Project")); { ETBZoomSelID, wxT("ZoomSel"), XO("Fit Selection") },
{ ETBZoomFitID, wxT("FitInWindow"), XO("Fit Project") },
#if defined(EXPERIMENTAL_EFFECTS_RACK) #if defined(EXPERIMENTAL_EFFECTS_RACK)
mButtons[ETBEffectsID]->SetToolTip(_("Open Effects Rack")); { ETBEffectsID, wxT(""), XO("Open Effects Rack") },
#endif #endif
};
std::vector<wxString> commands;
for (const auto &entry : table) {
commands.clear();
commands.push_back(wxGetTranslation(entry.untranslatedLabel));
commands.push_back(entry.commandName);
ToolBar::SetButtonToolTip(*mButtons[entry.tool], commands);
}
#endif #endif
} }

View File

@ -83,7 +83,7 @@ class EditToolBar final : public ToolBar {
void MakeButtons(); void MakeButtons();
void RegenerateTooltips(); void RegenerateTooltips() override;
AButton *mButtons[ETBNumButtons]; AButton *mButtons[ETBNumButtons];
@ -136,7 +136,7 @@ public:
void EnableDisableButtons(); void EnableDisableButtons();
void UpdatePrefs(); void UpdatePrefs();
void RegenerateTooltips(); void RegenerateTooltips() override;
private: private:

View File

@ -53,7 +53,7 @@ class MeterToolBar final : public ToolBar {
wxSize GetDockedSize(); wxSize GetDockedSize();
private: private:
void RegenerateTooltips(); void RegenerateTooltips() override;
AudacityProject *mProject; AudacityProject *mProject;
int mWhichMeters; int mWhichMeters;

View File

@ -196,6 +196,8 @@ void MixerToolBar::UpdatePrefs()
// Set label to pull in language change // Set label to pull in language change
SetLabel(_("Mixer")); SetLabel(_("Mixer"));
RegenerateTooltips();
// Give base class a chance // Give base class a chance
ToolBar::UpdatePrefs(); ToolBar::UpdatePrefs();
} }

View File

@ -49,6 +49,8 @@ class MixerToolBar final : public ToolBar {
void AdjustOutputGain(int adj); void AdjustOutputGain(int adj);
void AdjustInputGain(int adj); void AdjustInputGain(int adj);
void RegenerateTooltips() override {};
protected: protected:
float mInputSliderVolume; float mInputSliderVolume;
float mOutputSliderVolume; float mOutputSliderVolume;

View File

@ -296,6 +296,8 @@ void SelectionBar::UpdatePrefs()
// Set label to pull in language change // Set label to pull in language change
SetLabel(_("Selection")); SetLabel(_("Selection"));
RegenerateTooltips();
// Give base class a chance // Give base class a chance
ToolBar::UpdatePrefs(); ToolBar::UpdatePrefs();
} }

View File

@ -49,6 +49,7 @@ class SelectionBar final : public ToolBar {
void SetSelectionFormat(const wxString & format); void SetSelectionFormat(const wxString & format);
void SetRate(double rate); void SetRate(double rate);
void SetListener(SelectionBarListener *l); void SetListener(SelectionBarListener *l);
void RegenerateTooltips() override {};
private: private:

View File

@ -209,6 +209,8 @@ void SpectralSelectionBar::UpdatePrefs()
// Set label to pull in language change // Set label to pull in language change
SetLabel(_("Spectral Selection")); SetLabel(_("Spectral Selection"));
RegenerateTooltips();
// Give base class a chance // Give base class a chance
ToolBar::UpdatePrefs(); ToolBar::UpdatePrefs();
} }

View File

@ -46,6 +46,8 @@ public:
void SetBandwidthSelectionFormatName(const wxString & formatName); void SetBandwidthSelectionFormatName(const wxString & formatName);
void SetListener(SpectralSelectionBarListener *l); void SetListener(SpectralSelectionBarListener *l);
void RegenerateTooltips() override {};
private: private:
void ValuesToControls(); void ValuesToControls();

View File

@ -48,6 +48,7 @@ in which buttons can be placed.
#include "../ImageManipulation.h" #include "../ImageManipulation.h"
#include "../Project.h" #include "../Project.h"
#include "../Theme.h" #include "../Theme.h"
#include "../commands/Keyboard.h"
#include "../widgets/AButton.h" #include "../widgets/AButton.h"
#include "../widgets/Grabber.h" #include "../widgets/Grabber.h"
@ -761,6 +762,33 @@ void ToolBar::MakeAlternateImages(AButton &button, int idx,
button.SetAlternateImages(idx, *up, *hilite, *down, *disable); button.SetAlternateImages(idx, *up, *hilite, *down, *disable);
} }
void ToolBar::SetButtonToolTip
(AButton &button, const std::vector<wxString> &commands, const wxString &separator)
{
const auto project = GetActiveProject();
const auto commandManager = project ? project->GetCommandManager() : nullptr;
wxString result;
auto iter = commands.begin(), end = commands.end();
while (iter != end) {
result += *iter++;
if (iter != end) {
if (!iter->empty()) {
if (commandManager) {
auto keyStr = commandManager->GetKeyFromName(*iter);
if (keyStr.empty())
keyStr = _("no key");
result += wxT(" ");
result += Internat::Parenthesize(KeyStringDisplay(keyStr, true));
}
}
++iter;
}
if (iter != end)
result += separator;
}
button.SetToolTip(result);
}
// //
// This changes the state a button (from up to down or vice versa) // This changes the state a button (from up to down or vice versa)
// //

View File

@ -15,6 +15,7 @@
#include "../Experimental.h" #include "../Experimental.h"
#include <vector>
#include <wx/defs.h> #include <wx/defs.h>
#include <wx/panel.h> #include <wx/panel.h>
#include <wx/sizer.h> #include <wx/sizer.h>
@ -98,6 +99,7 @@ class ToolBar /* not final */ : public wxPanel
virtual void EnableDisableButtons() = 0; virtual void EnableDisableButtons() = 0;
virtual void ReCreateButtons(); virtual void ReCreateButtons();
virtual void UpdatePrefs(); virtual void UpdatePrefs();
virtual void RegenerateTooltips() = 0;
int GetType(); int GetType();
wxString GetTitle(); wxString GetTitle();
@ -150,6 +152,17 @@ class ToolBar /* not final */ : public wxPanel
teBmps eDisabled, teBmps eDisabled,
wxSize size); wxSize size);
static
void SetButtonToolTip
(AButton &button,
// An array, alternating user-visible strings, and
// non-user-visible command names. If a shortcut key is defined
// for the command, then it is appended, parenthesized, after the
// user-visible string.
const std::vector<wxString> &commands,
// If more than one pair of strings is given, then use this separator.
const wxString &separator = wxT(" / "));
protected: protected:
void SetButton(bool down, AButton *button); void SetButton(bool down, AButton *button);

View File

@ -598,6 +598,14 @@ void ToolManager::Reset()
Updated(); Updated();
} }
void ToolManager::RegenerateTooltips()
{
for (auto bar : mBars) {
if (bar)
bar->RegenerateTooltips();
}
}
// //
// Read the toolbar states // Read the toolbar states
// //

View File

@ -65,6 +65,7 @@ class ToolManager final : public wxEvtHandler
ToolDock *GetBotDock(); ToolDock *GetBotDock();
void Reset(); void Reset();
void RegenerateTooltips();
private: private:

View File

@ -111,7 +111,7 @@ ToolsToolBar::~ToolsToolBar()
{ {
} }
void ToolsToolBar::RegenerateToolsTooltips() void ToolsToolBar::RegenerateTooltips()
{ {
// JKC: // JKC:
@ -136,12 +136,28 @@ void ToolsToolBar::RegenerateToolsTooltips()
// wxSafeYield(); //Deal with some queued up messages... // wxSafeYield(); //Deal with some queued up messages...
#if wxUSE_TOOLTIPS #if wxUSE_TOOLTIPS
mTool[selectTool]->SetToolTip(_("Selection Tool"));
mTool[envelopeTool]->SetToolTip(_("Envelope Tool")); static const struct Entry {
mTool[slideTool]->SetToolTip(_("Time Shift Tool")); int tool;
mTool[zoomTool]->SetToolTip(_("Zoom Tool")); wxString commandName;
mTool[drawTool]->SetToolTip(_("Draw Tool")); wxString untranslatedLabel;
mTool[multiTool]->SetToolTip(_("Multi-Tool Mode")); } table[] = {
{ selectTool, wxT("SelectTool"), XO("Selection Tool") },
{ envelopeTool, wxT("EnvelopeTool"), XO("Envelope Tool") },
{ slideTool, wxT("TimeShiftTool"), XO("Time Shift Tool") },
{ zoomTool, wxT("ZoomTool"), XO("Zoom Tool") },
{ drawTool, wxT("DrawTool"), XO("Draw Tool") },
{ multiTool, wxT("MultiTool"), XO("Multi Tool") },
};
std::vector<wxString> commands;
for (const auto &entry : table) {
commands.clear();
commands.push_back(wxGetTranslation(entry.untranslatedLabel));
commands.push_back(entry.commandName);
ToolBar::SetButtonToolTip(*mTool[entry.tool], commands);
}
#endif #endif
// wxSafeYield(); // wxSafeYield();
@ -150,7 +166,7 @@ void ToolsToolBar::RegenerateToolsTooltips()
void ToolsToolBar::UpdatePrefs() void ToolsToolBar::UpdatePrefs()
{ {
RegenerateToolsTooltips(); RegenerateTooltips();
} }
AButton * ToolsToolBar::MakeTool( teBmps eTool, AButton * ToolsToolBar::MakeTool( teBmps eTool,
@ -183,7 +199,7 @@ void ToolsToolBar::Populate()
mTool[mCurrentTool]->PushDown(); mTool[mCurrentTool]->PushDown();
RegenerateToolsTooltips(); RegenerateTooltips();
} }
/// Gets the currently active tool /// Gets the currently active tool

View File

@ -70,7 +70,7 @@ class ToolsToolBar final : public ToolBar {
private: private:
void RegenerateToolsTooltips(); void RegenerateTooltips() override;
wxImage *MakeToolImage(wxImage *tool, wxImage *mask, int style); wxImage *MakeToolImage(wxImage *tool, wxImage *mask, int style);
AButton *MakeTool(teBmps eTool, int id, const wxChar *label); AButton *MakeTool(teBmps eTool, int id, const wxChar *label);

View File

@ -298,7 +298,25 @@ void TranscriptionToolBar::UpdatePrefs()
void TranscriptionToolBar::RegenerateTooltips() void TranscriptionToolBar::RegenerateTooltips()
{ {
mButtons[TTB_PlaySpeed]->SetToolTip(_("Play-at-speed")); // We could also mention the shift- and ctrl-modified versions in the
// tool tip... but it would get long
static const struct Entry {
int tool;
wxString commandName;
wxString untranslatedLabel;
} table[] = {
{ TTB_PlaySpeed, wxT("PlayAtSpeed"), XO("Play-at-speed") },
};
std::vector<wxString> commands;
for (const auto &entry : table) {
commands.clear();
commands.push_back(wxGetTranslation(entry.untranslatedLabel));
commands.push_back(entry.commandName);
ToolBar::SetButtonToolTip(*mButtons[entry.tool], commands);
}
#ifdef EXPERIMENTAL_VOICE_DETECTION #ifdef EXPERIMENTAL_VOICE_DETECTION
mButtons[TTB_StartOn]->SetToolTip(TRANSLATABLE("Left-to-On")); mButtons[TTB_StartOn]->SetToolTip(TRANSLATABLE("Left-to-On"));

View File

@ -131,7 +131,7 @@ class TranscriptionToolBar final : public ToolBar {
int id, unsigned altIdx); int id, unsigned altIdx);
void GetSamples(WaveTrack *t, sampleCount *s0, sampleCount *slen); void GetSamples(WaveTrack *t, sampleCount *s0, sampleCount *slen);
void SetButton(bool newstate, AButton *button); void SetButton(bool newstate, AButton *button);
void RegenerateTooltips(); void RegenerateTooltips() override;
AButton *mButtons[TTBNumButtons]; AButton *mButtons[TTBNumButtons];
wxImage *upImage; wxImage *upImage;

View File

@ -426,6 +426,18 @@ void AButton::OnMouseEvent(wxMouseEvent & event)
if (newState != prevState) { if (newState != prevState) {
Refresh(false); Refresh(false);
if (mCursorIsInWindow)
UpdateStatus();
else {
GetActiveProject()->TP_DisplayStatusMessage(wxT(""));
}
}
else
event.Skip();
}
void AButton::UpdateStatus()
{
if (mCursorIsInWindow) { if (mCursorIsInWindow) {
#if wxUSE_TOOLTIPS // Not available in wxX11 #if wxUSE_TOOLTIPS // Not available in wxX11
// Display the tooltip in the status bar // Display the tooltip in the status bar
@ -438,12 +450,6 @@ void AButton::OnMouseEvent(wxMouseEvent & event)
} }
#endif #endif
} }
else {
GetActiveProject()->TP_DisplayStatusMessage(wxT(""));
}
}
else
event.Skip();
} }
void AButton::OnCaptureLost(wxMouseCaptureLostEvent & WXUNUSED(event)) void AButton::OnCaptureLost(wxMouseCaptureLostEvent & WXUNUSED(event))

View File

@ -99,6 +99,11 @@ class AButton final : public wxWindow {
void OnPaint(wxPaintEvent & event); void OnPaint(wxPaintEvent & event);
void OnSize(wxSizeEvent & event); void OnSize(wxSizeEvent & event);
void OnMouseEvent(wxMouseEvent & event); void OnMouseEvent(wxMouseEvent & event);
// Update the status bar message if the pointer is in the button.
// Else do nothing.
void UpdateStatus();
void OnCaptureLost(wxMouseCaptureLostEvent & event); void OnCaptureLost(wxMouseCaptureLostEvent & event);
void OnKeyDown(wxKeyEvent & event); void OnKeyDown(wxKeyEvent & event);
void OnSetFocus(wxFocusEvent & event); void OnSetFocus(wxFocusEvent & event);

View File

@ -2060,19 +2060,6 @@ void AdornedRulerPanel::UpdatePrefs()
RegenerateTooltips(mPrevZone); RegenerateTooltips(mPrevZone);
} }
namespace
{
wxString ComposeButtonLabel
(AudacityProject &project, const wxString &commandName, const wxString &label)
{
auto pCmdMgr = project.GetCommandManager();
const auto &keyString = pCmdMgr->GetKeyFromName(commandName);
return keyString.empty()
? label
: label + wxT(" (") + keyString + wxT(")");
}
}
void AdornedRulerPanel::ReCreateButtons() void AdornedRulerPanel::ReCreateButtons()
{ {
for (auto & button : mButtons) { for (auto & button : mButtons) {
@ -2797,10 +2784,14 @@ void AdornedRulerPanel::OnContextMenu(wxContextMenuEvent & WXUNUSED(event))
void AdornedRulerPanel::UpdateButtonStates() void AdornedRulerPanel::UpdateButtonStates()
{ {
auto common = [this] auto common = [this]
(wxWindow *button, const wxString &commandName, const wxString &label){ (AButton &button, const wxString &commandName, const wxString &label) {
const auto &fullLabel = ComposeButtonLabel(*mProject, commandName, label); std::vector<wxString> commands;
button->SetLabel(fullLabel); commands.push_back(label);
button->SetToolTip(fullLabel); commands.push_back(commandName);
ToolBar::SetButtonToolTip(button, commands);
button.SetLabel(button.GetToolTipText());
button.UpdateStatus();
}; };
{ {
@ -2813,7 +2804,7 @@ void AdornedRulerPanel::UpdateButtonStates()
// (which is, to toggle the state) // (which is, to toggle the state)
? _("Pinned play/record Head") ? _("Pinned play/record Head")
: _("Unpinned play/record Head"); : _("Unpinned play/record Head");
common(pinButton, wxT("PinnedHead"), label); common(*pinButton, wxT("PinnedHead"), label);
} }
auto &scrubber = mProject->GetScrubber(); auto &scrubber = mProject->GetScrubber();