1
0
mirror of https://github.com/cookiengineer/audacity synced 2026-03-06 22:45:29 +01:00

Add combined slider and text box widget.

This widgets will be used in the new Compresor2 effect but it is
designed for use in other effects as well.

Signed-off-by: Max Maisel <max.maisel@posteo.de>
This commit is contained in:
Max Maisel
2020-02-09 14:55:23 +01:00
parent 6395c8470b
commit 2f58dc7d94
5 changed files with 278 additions and 0 deletions

View File

@@ -956,6 +956,8 @@ list( APPEND SOURCES PRIVATE
widgets/ReadOnlyText.h
widgets/Ruler.cpp
widgets/Ruler.h
widgets/SliderTextCtrl.cpp
widgets/SliderTextCtrl.h
widgets/UnwritableLocationErrorDialog.cpp
widgets/UnwritableLocationErrorDialog.h
widgets/Warning.cpp

View File

@@ -121,6 +121,8 @@ for registering for changes.
#include "widgets/wxTextCtrlWrapper.h"
#include "AllThemeResources.h"
#include "widgets/SliderTextCtrl.h"
#if wxUSE_ACCESSIBILITY
#include "widgets/WindowAccessible.h"
#endif
@@ -613,6 +615,31 @@ wxSlider * ShuttleGuiBase::AddSlider(
return pSlider;
}
SliderTextCtrl* ShuttleGuiBase::AddSliderTextCtrl(
const TranslatableString &Prompt, double pos, double Max, double Min,
int precision, double* value, double scale)
{
HandleOptionality( Prompt );
AddPrompt( Prompt );
UseUpId();
if( mShuttleMode != eIsCreating )
return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), SliderTextCtrl);
SliderTextCtrl * pSlider;
mpWind = pSlider = safenew SliderTextCtrl(GetParent(), miId,
pos, Min, Max, precision, scale, wxDefaultPosition, wxDefaultSize,
GetStyle( SliderTextCtrl::HORIZONTAL ),
value
);
#if wxUSE_ACCESSIBILITY
// so that name can be set on a standard control
mpWind->SetAccessible(safenew WindowAccessible(mpWind));
#endif
mpWind->SetName(wxStripMenuCodes(Prompt.Translation()));
miProp=1;
UpdateSizers();
return pSlider;
}
wxSpinCtrl * ShuttleGuiBase::AddSpinCtrl(
const TranslatableString &Prompt, int Value, int Max, int Min)
{

View File

@@ -28,6 +28,7 @@
class ChoiceSetting;
class wxArrayStringEx;
class SliderTextCtrl;
const int nMaxNestedSizers = 20;
@@ -263,6 +264,10 @@ public:
int Value, int Max, int Min);
wxTreeCtrl * AddTree();
SliderTextCtrl* AddSliderTextCtrl(
const TranslatableString &Prompt, double pos, double Max, double Min = 0,
int precision = 2, double* value = NULL, double scale = 0);
// Pass the same initValue to the sequence of calls to AddRadioButton and
// AddRadioButtonToGroup.
// The radio button is filled if selector == initValue

View File

@@ -0,0 +1,167 @@
/**********************************************************************
Audacity: A Digital Audio Editor
SliderTextCtrl.cpp
Max Maisel
*******************************************************************//**
\class SliderTextCtrl
\brief A slider with connected text box.
*//*******************************************************************/
#include "../Audacity.h"
#include "audacity/Types.h"
#include "SliderTextCtrl.h"
#include <wx/defs.h>
#include <wx/panel.h>
#include <wx/sizer.h>
#include <wx/slider.h>
#include <wx/textctrl.h>
#include <wx/valnum.h>
wxDEFINE_EVENT(cEVT_SLIDERTEXT, wxCommandEvent);
SliderTextCtrl::SliderTextCtrl(wxWindow *parent, wxWindowID winid,
double value, double min, double max, int precision, double scale,
const wxPoint& pos, const wxSize& size, long style, double* varValue)
: wxPanelWrapper(parent, winid, pos, size, wxWS_EX_VALIDATE_RECURSIVELY)
{
m_log = style & LOG;
m_int = style & INT;
m_value = value;
m_min = min;
m_max = max;
m_zero = -std::numeric_limits<double>::infinity();
if(m_int)
{
precision = 0;
m_format = "%d";
}
else
m_format = wxString::Format("%%.%df", precision);
if(scale == 0)
m_scale = pow(10, precision);
else
m_scale = scale;
wxFloatingPointValidator<double> validator(precision, varValue);
if(m_log)
{
if(min <= 0.0)
{
m_zero = -double(precision) - 1.0 / m_scale;
min = m_zero;
}
else
min = log10(min);
if(value <= 0.0)
value = m_zero;
else
value = log10(value);
max = log10(max);
}
m_sizer = safenew wxBoxSizer(
style & HORIZONTAL ? wxHORIZONTAL : wxVERTICAL);
m_slider = safenew wxSlider(this, ID_SLIDER,
round(value * m_scale), floor(min * m_scale), ceil(max * m_scale),
wxDefaultPosition, wxDefaultSize,
style & HORIZONTAL ? wxSL_HORIZONTAL : wxSL_VERTICAL);
m_textbox = safenew wxTextCtrl(this, ID_TEXTBOX, wxEmptyString,
wxDefaultPosition, wxDefaultSize, 0, validator);
m_textbox->ChangeValue(FormatValue());
m_textbox->Bind(wxEVT_KILL_FOCUS, &SliderTextCtrl::OnKillFocus, this);
m_sizer->Add(m_slider, 1, wxEXPAND);
m_sizer->Add(m_textbox, 0, wxEXPAND);
SetSizer(m_sizer);
}
void SliderTextCtrl::SetMinTextboxWidth(int width)
{
wxSize size = GetMinSize();
size.SetWidth(width);
m_textbox->SetMinSize(size);
}
double SliderTextCtrl::GetValue() const
{
return m_value;
}
void SliderTextCtrl::SetValue(double value)
{
m_value = value;
m_textbox->ChangeValue(FormatValue());
}
void SliderTextCtrl::OnTextChange(wxCommandEvent& event)
{
double value;
m_textbox->GetValue().ToDouble(&value);
m_value = std::min(value, m_max);
m_value = std::max(m_value, m_min);
if(m_log)
{
if(m_value == 0.0)
value = m_zero;
else
value = log10(m_value);
}
m_slider->SetValue(round(value * m_scale));
event.SetEventType(cEVT_SLIDERTEXT);
event.Skip();
}
void SliderTextCtrl::OnSlider(wxCommandEvent& event)
{
m_value = m_slider->GetValue() / m_scale;
if(m_log)
{
if(m_value <= m_zero)
m_value = 0.0;
else
{
m_value = pow(10.0, m_value);
m_value = std::max(m_min, m_value);
m_value = std::min(m_max, m_value);
}
}
m_textbox->ChangeValue(FormatValue());
m_textbox->SetSelection(-1, -1);
event.SetEventType(cEVT_SLIDERTEXT);
event.Skip();
}
void SliderTextCtrl::OnKillFocus(wxFocusEvent& _)
{
m_textbox->ChangeValue(FormatValue());
wxCommandEvent event(cEVT_SLIDERTEXT, GetId());
wxPostEvent(GetParent(), event);
}
wxString SliderTextCtrl::FormatValue() const
{
int v = m_value;
if(m_int)
return wxString::Format(m_format, v);
else
return wxString::Format(m_format, m_value);
}
BEGIN_EVENT_TABLE(SliderTextCtrl, wxControl)
EVT_TEXT(ID_TEXTBOX, SliderTextCtrl::OnTextChange)
EVT_SLIDER(ID_SLIDER, SliderTextCtrl::OnSlider)
END_EVENT_TABLE()

View File

@@ -0,0 +1,77 @@
/**********************************************************************
Audacity: A Digital Audio Editor
SliderTextCtrl.h
Max Maisel
This class is a custom slider.
**********************************************************************/
#ifndef __AUDACITY_SLIDERTEXTCTRL__
#define __AUDACITY_SLIDERTEXTCTRL__
#include "wxPanelWrapper.h" // to inherit
class wxSizer;
class wxSlider;
class wxTextCtrl;
wxDECLARE_EVENT(cEVT_SLIDERTEXT, wxCommandEvent);
#define EVT_SLIDERTEXT(winid, func) wx__DECLARE_EVT1( \
cEVT_SLIDERTEXT, winid, wxCommandEventHandler(func))
class SliderTextCtrl : public wxPanelWrapper
{
public:
enum Styles
{
HORIZONTAL = 1,
VERTICAL = 2,
LOG = 4,
INT = 8,
};
SliderTextCtrl(wxWindow *parent, wxWindowID winid,
double value, double min, double max, int precision = 2,
double scale = 0, const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, long style = HORIZONTAL,
double* varValue = NULL);
void SetMinTextboxWidth(int width);
double GetValue() const;
void SetValue(double value);
private:
void OnTextChange(wxCommandEvent& event);
void OnSlider(wxCommandEvent& event);
void OnKillFocus(wxFocusEvent& event);
wxString FormatValue() const;
enum
{
ID_SLIDER = 1,
ID_TEXTBOX
};
wxSizer* m_sizer;
wxSlider* m_slider;
wxTextCtrl* m_textbox;
bool m_log;
bool m_int;
double m_value;
double m_scale;
double m_min;
double m_max;
double m_zero;
wxString m_format;
DECLARE_EVENT_TABLE()
};
#endif