1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-10-25 15:53:52 +02:00

Better tooltip for ASlider

This fixes the problem on GTK where the text was unreadable when
using a "dark" theme.

And fixes the double display of the real tooltip and the tip panel
being displayed at the same time on GTK and OSX.  It seems that
the "disabling/reenabling" of tooltips doesn't take affect right
away anymore...maybe it never did.
This commit is contained in:
Leland Lucius
2015-08-09 06:03:42 -05:00
parent ac6f40dcab
commit 3064f1715f
7 changed files with 201 additions and 123 deletions

View File

@@ -62,6 +62,7 @@ wxPen AColor::labelSurroundPen;
wxPen AColor::trackFocusPens[3]; wxPen AColor::trackFocusPens[3];
wxPen AColor::snapGuidePen; wxPen AColor::snapGuidePen;
wxPen AColor::tooltipPen;
wxBrush AColor::tooltipBrush; wxBrush AColor::tooltipBrush;
// The spare pen and brush possibly help us cut down on the // The spare pen and brush possibly help us cut down on the
@@ -423,6 +424,7 @@ void AColor::Init()
theTheme.SetPenColour( playRegionPen[1], clrRulerPlaybackPen); theTheme.SetPenColour( playRegionPen[1], clrRulerPlaybackPen);
//Determine tooltip color //Determine tooltip color
tooltipPen.SetColour( wxSystemSettingsNative::GetColour(wxSYS_COLOUR_INFOTEXT) );
tooltipBrush.SetColour( wxSystemSettingsNative::GetColour(wxSYS_COLOUR_INFOBK) ); tooltipBrush.SetColour( wxSystemSettingsNative::GetColour(wxSYS_COLOUR_INFOBK) );
// A tiny gradient of yellow surrounding the current focused track // A tiny gradient of yellow surrounding the current focused track

View File

@@ -103,6 +103,7 @@ class AColor {
static wxPen trackFocusPens[3]; static wxPen trackFocusPens[3];
static wxPen snapGuidePen; static wxPen snapGuidePen;
static wxPen tooltipPen;
static wxBrush tooltipBrush; static wxBrush tooltipBrush;
static bool gradient_inited; static bool gradient_inited;

View File

@@ -51,10 +51,10 @@ public:
, windowSize(-1) , windowSize(-1)
, zeroPaddingFactor(-1) , zeroPaddingFactor(-1)
, frequencyGain(-1) , frequencyGain(-1)
#if 0
, freq(NULL) , freq(NULL)
, where(NULL) , where(NULL)
#endif
, dirty(-1) , dirty(-1)
{ {
} }

View File

@@ -286,24 +286,18 @@ void MixerToolBar::AdjustInputGain(int adj)
void MixerToolBar::SetToolTips() void MixerToolBar::SetToolTips()
{ {
#if wxUSE_TOOLTIPS
if (mInputSlider->IsEnabled()) { if (mInputSlider->IsEnabled()) {
mInputSlider->SetToolTip(wxString::Format( mInputSlider->SetToolTipTemplate(_("Recording Volume: %.2f"));
_("Recording Volume: %.2f"), mInputSliderVolume));
} }
else { else {
mInputSlider->SetToolTip( mInputSlider->SetToolTipTemplate(_("Recording Volume (Unavailable; use system mixer.)"));
_("Recording Volume (Unavailable; use system mixer.)"));
} }
if (mOutputSlider->IsEnabled()) { if (mOutputSlider->IsEnabled()) {
mOutputSlider->SetToolTip(wxString::Format( mOutputSlider->SetToolTipTemplate(wxString::Format(
_("Playback Volume: %.2f%s"), mOutputSliderVolume, gAudioIO->OutputMixerEmulated() ? _(" (emulated)") : wxT(""))); _("Playback Volume: %%.2f%s"), gAudioIO->OutputMixerEmulated() ? _(" (emulated)") : wxT("")));
} }
else { else {
mOutputSlider->SetToolTip( mOutputSlider->SetToolTipTemplate(_("Playback Volume (Unavailable; use system mixer.)"));
_("Playback Volume (Unavailable; use system mixer.)"));
} }
#endif
} }

View File

@@ -303,13 +303,8 @@ void TranscriptionToolBar::UpdatePrefs()
void TranscriptionToolBar::RegenerateTooltips() void TranscriptionToolBar::RegenerateTooltips()
{ {
#if wxUSE_TOOLTIPS
mButtons[TTB_PlaySpeed]->SetToolTip(_("Play-at-speed")); mButtons[TTB_PlaySpeed]->SetToolTip(_("Play-at-speed"));
wxString tip;
tip.Printf(_("Playback Speed") + wxT(": %.2fx"), mPlaySpeedSlider->Get());
mPlaySpeedSlider->SetToolTip(tip);
#ifdef EXPERIMENTAL_VOICE_DETECTION #ifdef EXPERIMENTAL_VOICE_DETECTION
mButtons[TTB_StartOn]->SetToolTip(TRANSLATABLE("Left-to-On")); mButtons[TTB_StartOn]->SetToolTip(TRANSLATABLE("Left-to-On"));
mButtons[TTB_EndOn]->SetToolTip( TRANSLATABLE("Right-to-Off")); mButtons[TTB_EndOn]->SetToolTip( TRANSLATABLE("Right-to-Off"));
@@ -324,7 +319,6 @@ void TranscriptionToolBar::RegenerateTooltips()
mSensitivitySlider->SetToolTip(TRANSLATABLE("Sensitivity")); mSensitivitySlider->SetToolTip(TRANSLATABLE("Sensitivity"));
mKeyTypeChoice->SetToolTip(TRANSLATABLE("Key type")); mKeyTypeChoice->SetToolTip(TRANSLATABLE("Key type"));
#endif #endif
#endif
} }
void TranscriptionToolBar::OnFocus(wxFocusEvent &event) void TranscriptionToolBar::OnFocus(wxFocusEvent &event)

View File

@@ -40,8 +40,10 @@ or ASlider.
#include <math.h> #include <math.h>
#include <wx/defs.h> #include <wx/defs.h>
#include <wx/dcbuffer.h>
#include <wx/dcclient.h> #include <wx/dcclient.h>
#include <wx/dcmemory.h> #include <wx/dcmemory.h>
#include <wx/graphics.h>
#include <wx/image.h> #include <wx/image.h>
#include <wx/msgdlg.h> #include <wx/msgdlg.h>
#include <wx/panel.h> #include <wx/panel.h>
@@ -99,6 +101,9 @@ class TipPanel : public wxPopupWindow
private: private:
void OnPaint(wxPaintEvent & event); void OnPaint(wxPaintEvent & event);
#if defined(__WXGTK__)
void OnCreate(wxWindowCreateEvent & event);
#endif
private: private:
wxString mMaxLabel; wxString mMaxLabel;
@@ -111,19 +116,28 @@ private:
BEGIN_EVENT_TABLE(TipPanel, wxPopupWindow) BEGIN_EVENT_TABLE(TipPanel, wxPopupWindow)
EVT_PAINT(TipPanel::OnPaint) EVT_PAINT(TipPanel::OnPaint)
#if defined(__WXGTK__)
EVT_WINDOW_CREATE(TipPanel::OnCreate)
#endif
END_EVENT_TABLE() END_EVENT_TABLE()
TipPanel::TipPanel(wxWindow *parent, const wxString & maxLabel) TipPanel::TipPanel(wxWindow *parent, const wxString & maxLabel)
: wxPopupWindow(parent) : wxPopupWindow(parent, wxFRAME_SHAPED)
{ {
SetBackgroundStyle(wxBG_STYLE_PAINT);
mMaxLabel = maxLabel; mMaxLabel = maxLabel;
wxFont labelFont(sliderFontSize, wxSWISS, wxNORMAL, wxNORMAL); wxFont labelFont(sliderFontSize, wxSWISS, wxNORMAL, wxNORMAL);
GetTextExtent(mMaxLabel, &mWidth, &mHeight, NULL, NULL, &labelFont); GetTextExtent(mMaxLabel, &mWidth, &mHeight, NULL, NULL, &labelFont);
mWidth += 8; mWidth += 8;
mHeight += 8; mHeight += 8;
#if defined(__WXMSW__) || defined(__WXMAC__)
wxGraphicsPath path = wxGraphicsRenderer::GetDefaultRenderer()->CreatePath();
path.AddRoundedRectangle(0, 0, mWidth, mHeight, 5);
SetShape(path);
#endif
} }
void TipPanel::SetPos(const wxPoint & pos) void TipPanel::SetPos(const wxPoint & pos)
@@ -136,21 +150,32 @@ void TipPanel::SetLabel(const wxString & label)
mLabel = label; mLabel = label;
} }
void TipPanel::OnPaint(wxPaintEvent& WXUNUSED(event)) void TipPanel::OnPaint(wxPaintEvent & WXUNUSED(event))
{ {
wxPaintDC dc(this); wxAutoBufferedPaintDC dc(this);
DisableAntialiasing(dc);
dc.SetFont(wxFont(sliderFontSize, wxSWISS, wxNORMAL, wxNORMAL));
dc.SetPen(*wxBLACK_PEN); dc.SetPen(*wxBLACK_PEN);
dc.SetBrush(AColor::tooltipBrush); dc.SetBrush(AColor::tooltipBrush);
dc.DrawRectangle(0, 0, mWidth, mHeight); dc.DrawRoundedRectangle(0, 0, mWidth, mHeight, 5);
dc.SetFont(wxFont(sliderFontSize, wxSWISS, wxNORMAL, wxNORMAL));
dc.SetTextForeground(AColor::tooltipPen.GetColour());
int textWidth, textHeight; int textWidth, textHeight;
dc.GetTextExtent(mLabel, &textWidth, &textHeight); dc.GetTextExtent(mLabel, &textWidth, &textHeight);
dc.DrawText(mLabel, (mWidth - textWidth) / 2, (mHeight - textHeight) / 2); DrawText(dc, mLabel, (mWidth - textWidth) / 2, (mHeight - textHeight) / 2);
} }
#if defined(__WXGTK__)
void TipPanel::OnCreate(wxWindowCreateEvent & WXUNUSED(event))
{
wxGraphicsPath path = wxGraphicsRenderer::GetDefaultRenderer()->CreatePath();
path.AddRoundedRectangle(0, 0, mWidth, mHeight, 5);
SetShape(path);
}
#endif
// //
// SliderDialog // SliderDialog
// //
@@ -463,39 +488,6 @@ void LWSlider::SetScroll(float line, float page)
mScrollPage = page; mScrollPage = page;
} }
void LWSlider::CreatePopWin()
{
if (mTipPanel)
{
delete mTipPanel;
mTipPanel = NULL;
}
wxString maxTipLabel = mName + wxT(": 000000");
if (mStyle == PAN_SLIDER || mStyle == DB_SLIDER || mStyle == SPEED_SLIDER
#ifdef EXPERIMENTAL_MIDI_OUT
|| mStyle == VEL_SLIDER
#endif
)
maxTipLabel += wxT("000");
mTipPanel = new TipPanel(mParent, maxTipLabel);
}
void LWSlider::SetPopWinPosition()
{
wxPoint pt;
if (mOrientation == wxHORIZONTAL)
pt = wxPoint(mWidth/2 + mLeft, mHeight + mTop + 1);
else
pt = wxPoint(mWidth + mLeft + 1, mHeight/2 + mTop);
pt = mParent->ClientToScreen(pt);
if (mTipPanel)
mTipPanel->SetPos(pt);
}
void LWSlider::Move(const wxPoint &newpos) void LWSlider::Move(const wxPoint &newpos)
{ {
mLeft = newpos.x; mLeft = newpos.x;
@@ -533,7 +525,7 @@ void LWSlider::OnPaint(wxDC &dc, bool WXUNUSED(selected))
dc.DrawBitmap(*mThumbBitmap, mLeft+thumbOrtho, mTop+thumbPos, true); dc.DrawBitmap(*mThumbBitmap, mLeft+thumbOrtho, mTop+thumbPos, true);
if (mTipPanel) if (mTipPanel)
mTipPanel->Refresh(); mTipPanel->Update();
} }
void LWSlider::OnSize( wxSizeEvent & event ) void LWSlider::OnSize( wxSizeEvent & event )
@@ -806,57 +798,132 @@ void LWSlider::Draw()
mBitmap->SetMask( new wxMask( *mBitmap, TransparentColour ) ); mBitmap->SetMask( new wxMask( *mBitmap, TransparentColour ) );
} }
void LWSlider::SetToolTipTemplate(const wxString & tip)
{
mTipTemplate = tip;
}
void LWSlider::ShowTip(bool show)
{
if (show)
{
if (mTipPanel)
{
delete mTipPanel;
mTipPanel = NULL;
}
CreatePopWin();
FormatPopWin();
SetPopWinPosition();
mTipPanel->Show();
}
else
{
if (mTipPanel)
{
mTipPanel->Hide();
delete mTipPanel;
mTipPanel = NULL;
}
}
}
void LWSlider::CreatePopWin()
{
if (mTipPanel)
{
delete mTipPanel;
mTipPanel = NULL;
}
wxString mintip = GetTip(mMinValue);
wxString maxtip = GetTip(mMaxValue);
mTipPanel = new TipPanel(mParent, mintip.Length() > maxtip.Length() ? mintip : maxtip);
}
void LWSlider::SetPopWinPosition()
{
wxPoint pt;
if (mOrientation == wxHORIZONTAL)
{
pt = wxPoint(mWidth/2 + mLeft, mHeight + mTop + 1);
}
else
{
pt = wxPoint(mWidth + mLeft + 1, mHeight/2 + mTop);
}
if (mTipPanel)
{
mTipPanel->SetPos(mParent->ClientToScreen(pt));
}
}
void LWSlider::FormatPopWin() void LWSlider::FormatPopWin()
{ {
if (!mTipPanel) { if (!mTipPanel)
{
return; return;
} }
mTipPanel->SetLabel(GetTip(mCurrentValue));
mTipPanel->Refresh();
}
wxString LWSlider::GetTip(float value) const
{
wxString label; wxString label;
wxString valstr;
switch(mStyle) { if (mTipTemplate.IsEmpty())
case FRAC_SLIDER: {
label.Printf(wxT("%s: %.2f"), mName.c_str(), mCurrentValue); wxString val;
break;
case DB_SLIDER: switch(mStyle)
valstr.Printf(wxT("%.1f"), mCurrentValue); {
if (valstr.Right(1) == wxT("0")) case FRAC_SLIDER:
valstr = valstr.Left(valstr.Length() - 2); val.Printf(wxT("%.2f"), value);
if (mCurrentValue > 0) break;
valstr = wxT("+") + valstr;
case DB_SLIDER:
val.Printf(wxT("%.3g dB"), value);
break;
label.Printf(wxT("%s: %s dB"), mName.c_str(), valstr.c_str()); case PAN_SLIDER:
break; if (value == 0.0)
case PAN_SLIDER: {
if (mCurrentValue == 0.0) val = _("Center");
label.Printf(wxT("%s: %s"), mName.c_str(), }
_("Center")); else
else { {
if (mCurrentValue < 0.0) val.Printf(wxT("%.0f%% %s"),
label.Printf(wxT("%s: %.0f%% %s"), mName.c_str(), value * (value < 0.0 ? -100.0f : 100.0f),
-mCurrentValue * 100.0f, _("Left")); value < 0.0 ? _("Left") : _("Right"));
else /* if (val > 0.0) */ }
label.Printf(wxT("%s: %.0f%% %s"), mName.c_str(), break;
mCurrentValue * 100.0f, _("Right"));
case SPEED_SLIDER:
val.Printf(wxT("%.2fx"), value);
break;
#ifdef EXPERIMENTAL_MIDI_OUT
case VEL_SLIDER:
val.Printf(wxT("%s%d"),
(value > 0.0f ? _("+") : wxT("")),
(int) value);
break;
#endif
} }
break; label.Printf(wxT("%s: %s"), mName.c_str(), val.c_str());
case SPEED_SLIDER: }
label.Printf(wxT("%s: %.2fx"), mName.c_str(), mCurrentValue); else
break; {
#ifdef EXPERIMENTAL_MIDI_OUT label.Printf(mTipTemplate, value);
case VEL_SLIDER:
label.Printf(wxT("%s: %s%d"), mName.c_str(),
(mCurrentValue > 0.0f ? _("+") : wxT("")),
(int) mCurrentValue);
#endif
} }
mTipPanel->SetLabel(label); return label;
mTipPanel->Refresh();
} }
bool LWSlider::ShowDialog() bool LWSlider::ShowDialog()
@@ -902,19 +969,19 @@ bool LWSlider::DoShowDialog(wxPoint pos)
void LWSlider::OnMouseEvent(wxMouseEvent & event) void LWSlider::OnMouseEvent(wxMouseEvent & event)
{ {
if (event.Entering()) { if (event.Entering())
#if wxUSE_TOOLTIPS // Not available in wxX11 {
// Display the tooltip in the status bar // Display the tooltip in the status bar
if (mParent->GetToolTip()) wxString tip = GetTip(mCurrentValue);
{ GetActiveProject()->TP_DisplayStatusMessage(tip);
wxString tip = mParent->GetToolTip()->GetTip(); Refresh();
GetActiveProject()->TP_DisplayStatusMessage(tip);
Refresh();
}
#endif
} }
else if (event.Leaving()) else if (event.Leaving())
{ {
if (!mIsDragging)
{
ShowTip(false);
}
GetActiveProject()->TP_DisplayStatusMessage(wxT("")); GetActiveProject()->TP_DisplayStatusMessage(wxT(""));
Refresh(); Refresh();
} }
@@ -994,13 +1061,7 @@ void LWSlider::OnMouseEvent(wxMouseEvent & event)
mParent->CaptureMouse(); mParent->CaptureMouse();
} }
CreatePopWin(); ShowTip(true);
FormatPopWin();
SetPopWinPosition();
mTipPanel->Show();
//hide mouseover tooltip
wxToolTip::Enable(false);
} }
else if( event.ButtonUp() ) else if( event.ButtonUp() )
{ {
@@ -1008,14 +1069,7 @@ void LWSlider::OnMouseEvent(wxMouseEvent & event)
if (mParent->HasCapture()) if (mParent->HasCapture())
mParent->ReleaseMouse(); mParent->ReleaseMouse();
if (mTipPanel) ShowTip(false);
{
delete mTipPanel;
mTipPanel = NULL;
}
//restore normal tooltip behavor for mouseovers
wxToolTip::Enable(true);
} }
else if (event.Dragging() && mIsDragging) else if (event.Dragging() && mIsDragging)
{ {
@@ -1345,6 +1399,7 @@ BEGIN_EVENT_TABLE(ASlider, wxWindow)
EVT_SLIDER(wxID_ANY, ASlider::OnSlider) EVT_SLIDER(wxID_ANY, ASlider::OnSlider)
EVT_SET_FOCUS(ASlider::OnSetFocus) EVT_SET_FOCUS(ASlider::OnSetFocus)
EVT_KILL_FOCUS(ASlider::OnKillFocus) EVT_KILL_FOCUS(ASlider::OnKillFocus)
EVT_TIMER(wxID_ANY, ASlider::OnTimer)
END_EVENT_TABLE() END_EVENT_TABLE()
ASlider::ASlider( wxWindow * parent, ASlider::ASlider( wxWindow * parent,
@@ -1375,6 +1430,8 @@ ASlider::ASlider( wxWindow * parent,
mStyle = style; mStyle = style;
mTimer.SetOwner(this);
#if wxUSE_ACCESSIBILITY #if wxUSE_ACCESSIBILITY
SetAccessible( new ASliderAx( this ) ); SetAccessible( new ASliderAx( this ) );
#endif #endif
@@ -1435,6 +1492,15 @@ void ASlider::OnPaint(wxPaintEvent & WXUNUSED(event))
void ASlider::OnMouseEvent(wxMouseEvent &event) void ASlider::OnMouseEvent(wxMouseEvent &event)
{ {
if (event.Entering())
{
mTimer.StartOnce(1000);
}
else if (event.Leaving())
{
mTimer.Stop();
}
mLWSlider->OnMouseEvent(event); mLWSlider->OnMouseEvent(event);
} }
@@ -1461,6 +1527,11 @@ void ASlider::OnKillFocus(wxFocusEvent & WXUNUSED(event))
Refresh(); Refresh();
} }
void ASlider::OnTimer(wxTimerEvent & WXUNUSED(event))
{
mLWSlider->ShowTip(true);
}
void ASlider::GetScroll(float & line, float & page) void ASlider::GetScroll(float & line, float & page)
{ {
mLWSlider->GetScroll(line, page); mLWSlider->GetScroll(line, page);
@@ -1471,6 +1542,11 @@ void ASlider::SetScroll(float line, float page)
mLWSlider->SetScroll(line, page); mLWSlider->SetScroll(line, page);
} }
void ASlider::SetToolTipTemplate(const wxString & tip)
{
mLWSlider->SetToolTipTemplate(tip);
}
float ASlider::Get( bool convert ) float ASlider::Get( bool convert )
{ {
return mLWSlider->Get( convert ); return mLWSlider->Get( convert );

View File

@@ -17,6 +17,7 @@
#include <wx/window.h> #include <wx/window.h>
#include <wx/dialog.h> #include <wx/dialog.h>
#include <wx/panel.h> #include <wx/panel.h>
#include <wx/timer.h>
#if wxUSE_ACCESSIBILITY #if wxUSE_ACCESSIBILITY
#include <wx/access.h> #include <wx/access.h>
@@ -122,6 +123,9 @@ class LWSlider
void GetScroll(float & line, float & page); void GetScroll(float & line, float & page);
void SetScroll(float line, float page); void SetScroll(float line, float page);
void ShowTip(bool show);
void SetToolTipTemplate(const wxString & tip);
float Get(bool convert = true); float Get(bool convert = true);
void Set(float value); void Set(float value);
#ifdef EXPERIMENTAL_MIDI_OUT #ifdef EXPERIMENTAL_MIDI_OUT
@@ -152,6 +156,7 @@ class LWSlider
private: private:
wxString GetTip(float value) const;
void FormatPopWin(); void FormatPopWin();
void SetPopWinPosition(); void SetPopWinPosition();
void CreatePopWin(); void CreatePopWin();
@@ -218,6 +223,8 @@ class LWSlider
wxWindowID mID; wxWindowID mID;
TipPanel *mTipPanel; TipPanel *mTipPanel;
wxString mTipTemplate;
wxTimer mTimer;
Ruler* mpRuler; Ruler* mpRuler;
@@ -256,6 +263,8 @@ class ASlider :public wxPanel
void GetScroll(float & line, float & page); void GetScroll(float & line, float & page);
void SetScroll(float line, float page); void SetScroll(float line, float page);
void SetToolTipTemplate(const wxString & tip);
float Get( bool convert = true ); float Get( bool convert = true );
void Set(float value); void Set(float value);
#ifdef EXPERIMENTAL_MIDI_OUT #ifdef EXPERIMENTAL_MIDI_OUT
@@ -277,6 +286,7 @@ class ASlider :public wxPanel
void OnSlider(wxCommandEvent &event); void OnSlider(wxCommandEvent &event);
void OnSetFocus(wxFocusEvent & event); void OnSetFocus(wxFocusEvent & event);
void OnKillFocus(wxFocusEvent & event); void OnKillFocus(wxFocusEvent & event);
void OnTimer(wxTimerEvent & event);
// Overrides of the wxWindow functions with the same semantics // Overrides of the wxWindow functions with the same semantics
bool Enable(bool enable = true); bool Enable(bool enable = true);
@@ -285,6 +295,7 @@ class ASlider :public wxPanel
private: private:
LWSlider *mLWSlider; LWSlider *mLWSlider;
bool mSliderIsFocused; bool mSliderIsFocused;
wxTimer mTimer;
protected: protected:
int mStyle; int mStyle;