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:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
167
src/widgets/SliderTextCtrl.cpp
Normal file
167
src/widgets/SliderTextCtrl.cpp
Normal 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()
|
||||
77
src/widgets/SliderTextCtrl.h
Normal file
77
src/widgets/SliderTextCtrl.h
Normal 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
|
||||
Reference in New Issue
Block a user