mirror of
https://github.com/cookiengineer/audacity
synced 2025-12-13 16:16:33 +01:00
Add option of Start/Center to SelectionBar
We now have Start/Center and End/Length, per Robert and Martyn's suggestion I've also tidied up the code here that was repetitive/messy.
This commit is contained in:
@@ -66,6 +66,8 @@ enum {
|
|||||||
SelectionBarFirstID = 2700,
|
SelectionBarFirstID = 2700,
|
||||||
OnRateID,
|
OnRateID,
|
||||||
OnSnapToID,
|
OnSnapToID,
|
||||||
|
OnStartRadioID,
|
||||||
|
OnCenterRadioID,
|
||||||
OnLengthRadioID,
|
OnLengthRadioID,
|
||||||
OnEndRadioID,
|
OnEndRadioID,
|
||||||
OnLeftTimeID,
|
OnLeftTimeID,
|
||||||
@@ -76,6 +78,8 @@ BEGIN_EVENT_TABLE(SelectionBar, ToolBar)
|
|||||||
EVT_SIZE(SelectionBar::OnSize)
|
EVT_SIZE(SelectionBar::OnSize)
|
||||||
EVT_TEXT(OnLeftTimeID, SelectionBar::OnLeftTime)
|
EVT_TEXT(OnLeftTimeID, SelectionBar::OnLeftTime)
|
||||||
EVT_TEXT(OnRightTimeID, SelectionBar::OnRightTime)
|
EVT_TEXT(OnRightTimeID, SelectionBar::OnRightTime)
|
||||||
|
EVT_RADIOBUTTON(OnStartRadioID, SelectionBar::OnStartRadio)
|
||||||
|
EVT_RADIOBUTTON(OnCenterRadioID, SelectionBar::OnCenterRadio)
|
||||||
EVT_RADIOBUTTON(OnLengthRadioID, SelectionBar::OnLengthRadio)
|
EVT_RADIOBUTTON(OnLengthRadioID, SelectionBar::OnLengthRadio)
|
||||||
EVT_RADIOBUTTON(OnEndRadioID, SelectionBar::OnEndRadio)
|
EVT_RADIOBUTTON(OnEndRadioID, SelectionBar::OnEndRadio)
|
||||||
EVT_CHOICE(OnSnapToID, SelectionBar::OnSnapTo)
|
EVT_CHOICE(OnSnapToID, SelectionBar::OnSnapTo)
|
||||||
@@ -109,6 +113,39 @@ void SelectionBar::Create(wxWindow * parent)
|
|||||||
ToolBar::Create(parent);
|
ToolBar::Create(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Can't set textcolour of radio buttons.
|
||||||
|
// so instead if we want to them, we make the text empty and add in a wxStaticText
|
||||||
|
// and we can set the colour of that.
|
||||||
|
// Slight regression relative ot Audacity, in that this text is not
|
||||||
|
// clickable/active. You have to click on the actual button.
|
||||||
|
// And you can't tab between and hear the labels with voice over.
|
||||||
|
// So VI users should use blend themes (which is the default).
|
||||||
|
// Should not be a hardship for them, as themes make little difference
|
||||||
|
// for them, except Hi-Contrast, which should be used with blend thems
|
||||||
|
// and a windows theme that is close enough to actually blend.
|
||||||
|
|
||||||
|
wxRadioButton * SelectionBar::AddRadioButton( const wxString & Name,
|
||||||
|
int id, std::unique_ptr<wxBoxSizer>& pSizer, long style )
|
||||||
|
{
|
||||||
|
bool bUseNativeRadioButton = theTheme.IsUsingSyestemTextColour();
|
||||||
|
wxRadioButton * pBtn;
|
||||||
|
// Safenew because the button is being create dinto this window.
|
||||||
|
pBtn = safenew wxRadioButton(this, id,bUseNativeRadioButton ? Name : wxT(""),
|
||||||
|
wxDefaultPosition, wxDefaultSize, style);
|
||||||
|
pBtn->SetName(Name);
|
||||||
|
pBtn->SetForegroundColour( theTheme.Colour( clrTrackPanelText ));
|
||||||
|
|
||||||
|
pSizer->Add(pBtn, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
|
||||||
|
if( !bUseNativeRadioButton )
|
||||||
|
{
|
||||||
|
wxStaticText * pText = safenew wxStaticText(this, -1, Name);
|
||||||
|
pText->SetForegroundColour( theTheme.Colour( clrTrackPanelText ) );
|
||||||
|
pSizer->Add(pText, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
|
||||||
|
}
|
||||||
|
return pBtn;
|
||||||
|
}
|
||||||
|
|
||||||
void SelectionBar::Populate()
|
void SelectionBar::Populate()
|
||||||
{
|
{
|
||||||
SetBackgroundColour( theTheme.Colour( clrMedium ) );
|
SetBackgroundColour( theTheme.Colour( clrMedium ) );
|
||||||
@@ -138,7 +175,7 @@ void SelectionBar::Populate()
|
|||||||
// Top row (mostly labels)
|
// Top row (mostly labels)
|
||||||
//
|
//
|
||||||
|
|
||||||
wxColour clrText = theTheme.Colour( clrTrackPanelText );
|
wxColour clrText = theTheme.Colour( clrTrackPanelText );
|
||||||
wxColour clrText2 = *wxBLUE;
|
wxColour clrText2 = *wxBLUE;
|
||||||
wxStaticText * pProjRate = safenew wxStaticText(this, -1, _("Project Rate (Hz):"),
|
wxStaticText * pProjRate = safenew wxStaticText(this, -1, _("Project Rate (Hz):"),
|
||||||
// LLL: On my Ubuntu 7.04 install, the label wraps to two lines
|
// LLL: On my Ubuntu 7.04 install, the label wraps to two lines
|
||||||
@@ -156,56 +193,31 @@ void SelectionBar::Populate()
|
|||||||
pSnapTo->SetForegroundColour( clrText );
|
pSnapTo->SetForegroundColour( clrText );
|
||||||
mainSizer->Add( pSnapTo, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
|
mainSizer->Add( pSnapTo, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
|
||||||
|
|
||||||
wxStaticText * pSelStart = safenew wxStaticText(this, -1, _("Selection Start:"));
|
|
||||||
pSelStart->SetForegroundColour( clrText );
|
|
||||||
mainSizer->Add( pSelStart,0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
|
|
||||||
|
|
||||||
|
bool showSelectionStart = false;
|
||||||
bool showSelectionLength = false;
|
bool showSelectionLength = false;
|
||||||
|
gPrefs->Read(wxT("/ShowSelectionStart"), &showSelectionStart);
|
||||||
gPrefs->Read(wxT("/ShowSelectionLength"), &showSelectionLength);
|
gPrefs->Read(wxT("/ShowSelectionLength"), &showSelectionLength);
|
||||||
|
|
||||||
{
|
{
|
||||||
bool bSysTextColour = theTheme.IsUsingSyestemTextColour();
|
|
||||||
// Can't set textcolour of radio buttons.
|
|
||||||
// so instead we make the text empty and add in two wxStaticTexts
|
|
||||||
// and we can set the colour of those.
|
|
||||||
// Slight regression relative ot Audacity, in that this text is not
|
|
||||||
// clickable/active. You have to click on the actual button.
|
|
||||||
// And can't tab between and hear the labels with voice over.
|
|
||||||
// So VI users should use blend themes (which is the default).
|
|
||||||
// Should not be a hardship for them, as themes make little difference
|
|
||||||
// for them, except Hi-Contrast, which should be used with recolouring.
|
|
||||||
auto hSizer = std::make_unique<wxBoxSizer>(wxHORIZONTAL);
|
auto hSizer = std::make_unique<wxBoxSizer>(wxHORIZONTAL);
|
||||||
mRightEndButton = safenew wxRadioButton(this, OnEndRadioID, bSysTextColour ? _("End") : wxT("") ,
|
|
||||||
wxDefaultPosition, wxDefaultSize,
|
|
||||||
wxRB_GROUP);
|
|
||||||
mRightEndButton->SetName(_("End"));
|
|
||||||
mRightEndButton->SetForegroundColour( clrText );
|
|
||||||
mRightEndButton->SetValue(!showSelectionLength);
|
|
||||||
hSizer->Add(mRightEndButton,
|
|
||||||
0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
|
|
||||||
if( !bSysTextColour )
|
|
||||||
{
|
|
||||||
wxStaticText * pEndText = safenew wxStaticText(this, -1, _("End"));
|
|
||||||
pEndText->SetForegroundColour( clrText );
|
|
||||||
hSizer->Add(pEndText,
|
|
||||||
0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
mRightLengthButton = safenew wxRadioButton(this, OnLengthRadioID,bSysTextColour ? _("Length") : wxT("") );
|
wxStaticText * pSelStart = safenew wxStaticText(this, -1, _("Selection:"));
|
||||||
mRightLengthButton->SetName(_("Length"));
|
pSelStart->SetForegroundColour( clrText );
|
||||||
mRightLengthButton->SetForegroundColour( clrText );
|
hSizer->Add( pSelStart,0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
|
||||||
mRightLengthButton->SetValue(showSelectionLength);
|
|
||||||
hSizer->Add(mRightLengthButton,
|
|
||||||
0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
|
|
||||||
if( !bSysTextColour )
|
|
||||||
{
|
|
||||||
wxStaticText * pLengthText = safenew wxStaticText(this, -1, _("Length"));
|
|
||||||
pLengthText->SetForegroundColour( clrText );
|
|
||||||
hSizer->Add(pLengthText,
|
|
||||||
0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(__WXMSW__)
|
mSelStartButton = AddRadioButton( _("Start"), OnStartRadioID, hSizer, wxRB_GROUP);
|
||||||
|
mSelStartButton->SetValue(showSelectionStart);
|
||||||
|
AddRadioButton( _("Center"), OnCenterRadioID, hSizer, 0)->SetValue(!showSelectionStart);
|
||||||
|
mainSizer->Add(hSizer.release(), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 0);
|
||||||
|
|
||||||
|
hSizer = std::make_unique<wxBoxSizer>(wxHORIZONTAL);
|
||||||
|
mSelEndButton = AddRadioButton( _("End"), OnEndRadioID, hSizer, wxRB_GROUP);
|
||||||
|
mSelEndButton->SetValue(!showSelectionLength);
|
||||||
|
AddRadioButton( _("Length"), OnLengthRadioID, hSizer, 0)->SetValue(showSelectionLength);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// was #if defined(__WXMSW__)
|
||||||
// Refer to Microsoft KB article 261192 for an explanation as
|
// Refer to Microsoft KB article 261192 for an explanation as
|
||||||
// to why this is needed. We've only experienced it under Win2k
|
// to why this is needed. We've only experienced it under Win2k
|
||||||
// so it's probably been fixed. But, it doesn't hurt to have this
|
// so it's probably been fixed. But, it doesn't hurt to have this
|
||||||
@@ -373,18 +385,44 @@ void SelectionBar::OnSize(wxSizeEvent &evt)
|
|||||||
|
|
||||||
void SelectionBar::ModifySelection(bool done)
|
void SelectionBar::ModifySelection(bool done)
|
||||||
{
|
{
|
||||||
mStart = mLeftTime->GetValue();
|
double left = mLeftTime->GetValue();
|
||||||
double right = mRightTime->GetValue();
|
double right = mRightTime->GetValue();
|
||||||
|
|
||||||
if (mRightEndButton->GetValue()) {
|
// Four combinations:
|
||||||
if(mStart > right)
|
|
||||||
mEnd = mStart;
|
|
||||||
else
|
|
||||||
mEnd = right;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
mEnd = mStart + right;
|
|
||||||
|
|
||||||
|
const int kStart = 0;
|
||||||
|
const int kCenter = 1;
|
||||||
|
const int kEnd = 0;
|
||||||
|
const int kLength = 2;
|
||||||
|
|
||||||
|
int option = (mSelStartButton->GetValue()? kStart:kCenter) + (mSelEndButton->GetValue()? kEnd:kLength);
|
||||||
|
|
||||||
|
switch( option ){
|
||||||
|
case kStart+kEnd:
|
||||||
|
if( right < left )
|
||||||
|
right = left;
|
||||||
|
mStart = wxMin( left, right );
|
||||||
|
mEnd = wxMax( left, right);
|
||||||
|
break;
|
||||||
|
case kCenter+kEnd:
|
||||||
|
if( right < left )
|
||||||
|
right = left;
|
||||||
|
mStart = left - fabs( right-left );
|
||||||
|
mEnd = left + fabs( right-left);
|
||||||
|
break;
|
||||||
|
case kStart+kLength:
|
||||||
|
if( right < 0 )
|
||||||
|
right = 0;
|
||||||
|
mStart = wxMin( left, left+right );
|
||||||
|
mEnd = wxMax( left, left+right);
|
||||||
|
break;
|
||||||
|
case kCenter+kLength:
|
||||||
|
if( right < 0 )
|
||||||
|
right = 0;
|
||||||
|
mStart = left - fabs( right)/2.0;
|
||||||
|
mEnd = left + fabs( right)/2.0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
mListener->AS_ModifySelection(mStart, mEnd, done);
|
mListener->AS_ModifySelection(mStart, mEnd, done);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,6 +436,24 @@ void SelectionBar::OnRightTime(wxCommandEvent & event)
|
|||||||
ModifySelection(event.GetInt() != 0);
|
ModifySelection(event.GetInt() != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SelectionBar::OnStartRadio(wxCommandEvent & WXUNUSED(event))
|
||||||
|
{
|
||||||
|
gPrefs->Write(wxT("/ShowSelectionStart"), true);
|
||||||
|
gPrefs->Flush();
|
||||||
|
mLeftTime->SetName(wxString(_("Selection Start")));
|
||||||
|
|
||||||
|
ValuesToControls();
|
||||||
|
}
|
||||||
|
void SelectionBar::OnCenterRadio(wxCommandEvent & WXUNUSED(event))
|
||||||
|
{
|
||||||
|
gPrefs->Write(wxT("/ShowSelectionStart"), true);
|
||||||
|
gPrefs->Flush();
|
||||||
|
mLeftTime->SetName(wxString(_("Selection Center")));
|
||||||
|
|
||||||
|
ValuesToControls();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SelectionBar::OnLengthRadio(wxCommandEvent & WXUNUSED(event))
|
void SelectionBar::OnLengthRadio(wxCommandEvent & WXUNUSED(event))
|
||||||
{
|
{
|
||||||
gPrefs->Write(wxT("/ShowSelectionLength"), true);
|
gPrefs->Write(wxT("/ShowSelectionLength"), true);
|
||||||
@@ -410,6 +466,7 @@ void SelectionBar::OnLengthRadio(wxCommandEvent & WXUNUSED(event))
|
|||||||
void SelectionBar::OnEndRadio(wxCommandEvent & WXUNUSED(event))
|
void SelectionBar::OnEndRadio(wxCommandEvent & WXUNUSED(event))
|
||||||
{
|
{
|
||||||
gPrefs->Write(wxT("/ShowSelectionLength"), false);
|
gPrefs->Write(wxT("/ShowSelectionLength"), false);
|
||||||
|
gPrefs->Flush();
|
||||||
mRightTime->SetName(wxString(_("Selection End")));
|
mRightTime->SetName(wxString(_("Selection End")));
|
||||||
|
|
||||||
ValuesToControls();
|
ValuesToControls();
|
||||||
@@ -439,8 +496,8 @@ void SelectionBar::OnUpdate(wxCommandEvent &evt)
|
|||||||
mRightTime =
|
mRightTime =
|
||||||
mAudioTime = NULL;
|
mAudioTime = NULL;
|
||||||
|
|
||||||
mRightEndButton =
|
mSelStartButton = NULL;
|
||||||
mRightLengthButton = NULL;
|
mSelEndButton = NULL;
|
||||||
|
|
||||||
mRateBox = NULL;
|
mRateBox = NULL;
|
||||||
mRateText = NULL;
|
mRateText = NULL;
|
||||||
@@ -469,20 +526,44 @@ void SelectionBar::OnUpdate(wxCommandEvent &evt)
|
|||||||
|
|
||||||
void SelectionBar::ValuesToControls()
|
void SelectionBar::ValuesToControls()
|
||||||
{
|
{
|
||||||
mLeftTime->SetValue(mStart);
|
double left;
|
||||||
|
double right;
|
||||||
|
|
||||||
if (mRightEndButton->GetValue())
|
// Start or center?
|
||||||
mRightTime->SetValue(mEnd);
|
if (mSelStartButton->GetValue())
|
||||||
|
left = mStart;
|
||||||
else
|
else
|
||||||
{ // mRightTime is the length.
|
{
|
||||||
// Be sure to take into account the sub-sample offset.
|
// TODO: Doing rounding calcs here, as in the length case, but
|
||||||
|
// not sure that is needed.
|
||||||
|
//left = (mStart+mEnd)/2.0;
|
||||||
|
auto samples = (sampleCount)floor(mEnd * mRate + 0.5);
|
||||||
|
samples += (sampleCount)floor(mStart * mRate + 0.5);
|
||||||
|
auto t = samples.as_double() / mRate;
|
||||||
|
// An odd thing here is that we could allow the center to be at half a sample.
|
||||||
|
// in which case length must be odd, or at a sample, in which case length
|
||||||
|
// must be even. Same fo rany selection granularity.
|
||||||
|
// For now, don't care. User gets benefit from having center, even if
|
||||||
|
// it is slightly peculiar when used close up to the granularity.
|
||||||
|
left = t/2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// End or length?
|
||||||
|
if (mSelEndButton->GetValue())
|
||||||
|
right = mEnd;
|
||||||
|
else
|
||||||
|
{ // Be sure to take into account the sub-sample offset.
|
||||||
// See TimeToLongSamples and LongSamplesToTime but here at the project rate.
|
// See TimeToLongSamples and LongSamplesToTime but here at the project rate.
|
||||||
auto samples = (sampleCount)floor(mEnd * mRate + 0.5);
|
auto samples = (sampleCount)floor(mEnd * mRate + 0.5);
|
||||||
samples -= (sampleCount)floor(mStart * mRate + 0.5);
|
samples -= (sampleCount)floor(mStart * mRate + 0.5);
|
||||||
auto t = samples.as_double() / mRate;
|
auto t = samples.as_double() / mRate;
|
||||||
mRightTime->SetValue(t);
|
right = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mLeftTime->SetValue(left);
|
||||||
|
mRightTime->SetValue(right);
|
||||||
|
|
||||||
|
|
||||||
mAudioTime->SetValue(mAudio);
|
mAudioTime->SetValue(mAudio);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -502,7 +583,7 @@ double SelectionBar::GetLeftTime()
|
|||||||
|
|
||||||
double SelectionBar::GetRightTime()
|
double SelectionBar::GetRightTime()
|
||||||
{
|
{
|
||||||
if (mRightEndButton->GetValue())
|
if (mSelEndButton->GetValue())
|
||||||
return mRightTime->GetValue();
|
return mRightTime->GetValue();
|
||||||
else {
|
else {
|
||||||
// What would be shown if we were showing the end time
|
// What would be shown if we were showing the end time
|
||||||
|
|||||||
@@ -52,12 +52,16 @@ class SelectionBar final : public ToolBar {
|
|||||||
void RegenerateTooltips() override;
|
void RegenerateTooltips() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
wxRadioButton * AddRadioButton( const wxString & Name, int id,
|
||||||
|
std::unique_ptr<wxBoxSizer>& pSizer, long style);
|
||||||
|
|
||||||
void ValuesToControls();
|
void ValuesToControls();
|
||||||
void OnUpdate(wxCommandEvent &evt);
|
void OnUpdate(wxCommandEvent &evt);
|
||||||
void OnLeftTime(wxCommandEvent &evt);
|
void OnLeftTime(wxCommandEvent &evt);
|
||||||
void OnRightTime(wxCommandEvent &evt);
|
void OnRightTime(wxCommandEvent &evt);
|
||||||
|
|
||||||
|
void OnStartRadio(wxCommandEvent &evt);
|
||||||
|
void OnCenterRadio(wxCommandEvent &evt);
|
||||||
void OnEndRadio(wxCommandEvent &evt);
|
void OnEndRadio(wxCommandEvent &evt);
|
||||||
void OnLengthRadio(wxCommandEvent &evt);
|
void OnLengthRadio(wxCommandEvent &evt);
|
||||||
|
|
||||||
@@ -79,10 +83,12 @@ class SelectionBar final : public ToolBar {
|
|||||||
double mStart, mEnd, mAudio;
|
double mStart, mEnd, mAudio;
|
||||||
wxString mField[10];
|
wxString mField[10];
|
||||||
|
|
||||||
|
bool mbUseNativeRadioButton;
|
||||||
|
|
||||||
NumericTextCtrl *mLeftTime;
|
NumericTextCtrl *mLeftTime;
|
||||||
NumericTextCtrl *mRightTime;
|
NumericTextCtrl *mRightTime;
|
||||||
wxRadioButton *mRightEndButton;
|
wxRadioButton *mSelStartButton; // for start/center
|
||||||
wxRadioButton *mRightLengthButton;
|
wxRadioButton *mSelEndButton; // for end/length
|
||||||
NumericTextCtrl *mAudioTime;
|
NumericTextCtrl *mAudioTime;
|
||||||
|
|
||||||
wxComboBox *mRateBox;
|
wxComboBox *mRateBox;
|
||||||
|
|||||||
Reference in New Issue
Block a user