mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-16 16:10:06 +02:00
Fix for http://bugzilla.audacityteam.org/show_bug.cgi?id=643 "Residual consistency issues with SHIFT showing Loop Play button icon" by Paul Licameli.
* Loop play-at-speed and cut preview play-at-speed implemented. * Shift or ctrl down now affect all relevant buttons, loop or cut preview, normal or at speed, and append-record.
This commit is contained in:
parent
30500b2e85
commit
7324997db6
@ -62,6 +62,10 @@ from there. Audacity will look for a file called "Pause.png".
|
|||||||
DEFINE_IMAGE( bmpFFwdDisabled, wxImage( 16, 16 ), wxT("FFwdDisabled"));
|
DEFINE_IMAGE( bmpFFwdDisabled, wxImage( 16, 16 ), wxT("FFwdDisabled"));
|
||||||
DEFINE_IMAGE( bmpRecord, wxImage( 16, 16 ), wxT("Record"));
|
DEFINE_IMAGE( bmpRecord, wxImage( 16, 16 ), wxT("Record"));
|
||||||
DEFINE_IMAGE( bmpRecordDisabled, wxImage( 16, 16 ), wxT("RecordDisabled"));
|
DEFINE_IMAGE( bmpRecordDisabled, wxImage( 16, 16 ), wxT("RecordDisabled"));
|
||||||
|
DEFINE_IMAGE( bmpCutPreview, wxImage( 16, 16 ), wxT("CutPreview"));
|
||||||
|
DEFINE_IMAGE( bmpCutPreviewDisabled, wxImage( 16, 16 ), wxT("CutPreviewDisabled"));
|
||||||
|
DEFINE_IMAGE( bmpAppendRecord, wxImage( 16, 16 ), wxT("AppendRecord"));
|
||||||
|
DEFINE_IMAGE( bmpAppendRecordDisabled, wxImage( 16, 16 ), wxT("AppendRecordDisabled"));
|
||||||
|
|
||||||
SET_THEME_FLAGS( resFlagNewLine );
|
SET_THEME_FLAGS( resFlagNewLine );
|
||||||
DEFINE_IMAGE( bmpUpButtonLarge, wxImage( 48, 48 ), wxT("UpButtonLarge"));
|
DEFINE_IMAGE( bmpUpButtonLarge, wxImage( 48, 48 ), wxT("UpButtonLarge"));
|
||||||
|
@ -1281,6 +1281,8 @@ void AudacityProject::CreateMenusAndCommands()
|
|||||||
c->AddCommand(wxT("InputGainDec"), _("Decrease recording volume"), FN(OnInputGainDec));
|
c->AddCommand(wxT("InputGainDec"), _("Decrease recording volume"), FN(OnInputGainDec));
|
||||||
|
|
||||||
c->AddCommand(wxT("PlayAtSpeed"), _("Play at speed"), FN(OnPlayAtSpeed));
|
c->AddCommand(wxT("PlayAtSpeed"), _("Play at speed"), FN(OnPlayAtSpeed));
|
||||||
|
c->AddCommand(wxT("PlayAtSpeedLooped"), _("Loop Play at speed"), FN(OnPlayAtSpeedLooped));
|
||||||
|
c->AddCommand(wxT("PlayAtSpeedCutPreview"), _("Play Cut Preview at speed"), FN(OnPlayAtSpeedCutPreview));
|
||||||
c->AddCommand(wxT("SetPlaySpeed"), _("Adjust playback speed"), FN(OnSetPlaySpeed));
|
c->AddCommand(wxT("SetPlaySpeed"), _("Adjust playback speed"), FN(OnSetPlaySpeed));
|
||||||
c->AddCommand(wxT("PlaySpeedInc"), _("Increase playback speed"), FN(OnPlaySpeedInc));
|
c->AddCommand(wxT("PlaySpeedInc"), _("Increase playback speed"), FN(OnPlaySpeedInc));
|
||||||
c->AddCommand(wxT("PlaySpeedDec"), _("Decrease playback speed"), FN(OnPlaySpeedDec));
|
c->AddCommand(wxT("PlaySpeedDec"), _("Decrease playback speed"), FN(OnPlaySpeedDec));
|
||||||
@ -3004,7 +3006,23 @@ void AudacityProject::OnPlayAtSpeed()
|
|||||||
{
|
{
|
||||||
TranscriptionToolBar *tb = GetTranscriptionToolBar();
|
TranscriptionToolBar *tb = GetTranscriptionToolBar();
|
||||||
if (tb) {
|
if (tb) {
|
||||||
tb->PlayAtSpeed();
|
tb->PlayAtSpeed(false, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudacityProject::OnPlayAtSpeedLooped()
|
||||||
|
{
|
||||||
|
TranscriptionToolBar *tb = GetTranscriptionToolBar();
|
||||||
|
if (tb) {
|
||||||
|
tb->PlayAtSpeed(true, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudacityProject::OnPlayAtSpeedCutPreview()
|
||||||
|
{
|
||||||
|
TranscriptionToolBar *tb = GetTranscriptionToolBar();
|
||||||
|
if (tb) {
|
||||||
|
tb->PlayAtSpeed(false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,6 +127,8 @@ void OnInputGainDec();
|
|||||||
// Transcription control
|
// Transcription control
|
||||||
|
|
||||||
void OnPlayAtSpeed();
|
void OnPlayAtSpeed();
|
||||||
|
void OnPlayAtSpeedLooped();
|
||||||
|
void OnPlayAtSpeedCutPreview();
|
||||||
void OnSetPlaySpeed();
|
void OnSetPlaySpeed();
|
||||||
void OnPlaySpeedInc();
|
void OnPlaySpeedInc();
|
||||||
void OnPlaySpeedDec();
|
void OnPlaySpeedDec();
|
||||||
|
@ -277,6 +277,7 @@ MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
|
|||||||
true); // toggle button
|
true); // toggle button
|
||||||
mToggleButton_Mute->SetName(_("Mute"));
|
mToggleButton_Mute->SetName(_("Mute"));
|
||||||
mToggleButton_Mute->SetAlternateImages(
|
mToggleButton_Mute->SetAlternateImages(
|
||||||
|
1,
|
||||||
*(mMixerBoard->mImageMuteUp), *(mMixerBoard->mImageMuteOver),
|
*(mMixerBoard->mImageMuteUp), *(mMixerBoard->mImageMuteOver),
|
||||||
*(mMixerBoard->mImageMuteDown), *(mMixerBoard->mImageMuteDisabled));
|
*(mMixerBoard->mImageMuteDown), *(mMixerBoard->mImageMuteDisabled));
|
||||||
this->UpdateMute();
|
this->UpdateMute();
|
||||||
@ -465,10 +466,10 @@ void MixerTrackCluster::UpdateName()
|
|||||||
void MixerTrackCluster::UpdateMute()
|
void MixerTrackCluster::UpdateMute()
|
||||||
{
|
{
|
||||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||||
mToggleButton_Mute->SetAlternate(mTrack->GetSolo());
|
mToggleButton_Mute->SetAlternateIdx(mTrack->GetSolo() ? 1 : 0);
|
||||||
if (mTrack->GetMute())
|
if (mTrack->GetMute())
|
||||||
#else
|
#else
|
||||||
mToggleButton_Mute->SetAlternate(mLeftTrack->GetSolo());
|
mToggleButton_Mute->SetAlternateIdx(mLeftTrack->GetSolo() ? 1 : 0);
|
||||||
if (mLeftTrack->GetMute())
|
if (mLeftTrack->GetMute())
|
||||||
#endif
|
#endif
|
||||||
mToggleButton_Mute->PushDown();
|
mToggleButton_Mute->PushDown();
|
||||||
@ -487,7 +488,7 @@ void MixerTrackCluster::UpdateSolo()
|
|||||||
mToggleButton_Solo->PushDown();
|
mToggleButton_Solo->PushDown();
|
||||||
else
|
else
|
||||||
mToggleButton_Solo->PopUp();
|
mToggleButton_Solo->PopUp();
|
||||||
mToggleButton_Mute->SetAlternate(bIsSolo);
|
mToggleButton_Mute->SetAlternateIdx(bIsSolo ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MixerTrackCluster::UpdatePan()
|
void MixerTrackCluster::UpdatePan()
|
||||||
@ -827,10 +828,10 @@ void MixerTrackCluster::OnButton_Mute(wxCommandEvent& WXUNUSED(event))
|
|||||||
{
|
{
|
||||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||||
mProject->HandleTrackMute(mTrack, mToggleButton_Mute->WasShiftDown());
|
mProject->HandleTrackMute(mTrack, mToggleButton_Mute->WasShiftDown());
|
||||||
mToggleButton_Mute->SetAlternate(mTrack->GetSolo());
|
mToggleButton_Mute->SetAlternateIdx(mTrack->GetSolo() ? 1 : 0);
|
||||||
#else
|
#else
|
||||||
mProject->HandleTrackMute(mLeftTrack, mToggleButton_Mute->WasShiftDown());
|
mProject->HandleTrackMute(mLeftTrack, mToggleButton_Mute->WasShiftDown());
|
||||||
mToggleButton_Mute->SetAlternate(mLeftTrack->GetSolo());
|
mToggleButton_Mute->SetAlternateIdx(mLeftTrack->GetSolo() ? 1 : 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Update the TrackPanel correspondingly.
|
// Update the TrackPanel correspondingly.
|
||||||
@ -858,7 +859,7 @@ void MixerTrackCluster::OnButton_Solo(wxCommandEvent& WXUNUSED(event))
|
|||||||
mProject->HandleTrackSolo(mLeftTrack, mToggleButton_Solo->WasShiftDown());
|
mProject->HandleTrackSolo(mLeftTrack, mToggleButton_Solo->WasShiftDown());
|
||||||
bool bIsSolo = mLeftTrack->GetSolo();
|
bool bIsSolo = mLeftTrack->GetSolo();
|
||||||
#endif
|
#endif
|
||||||
mToggleButton_Mute->SetAlternate(bIsSolo);
|
mToggleButton_Mute->SetAlternateIdx(bIsSolo ? 1 : 0);
|
||||||
|
|
||||||
// Update the TrackPanel correspondingly.
|
// Update the TrackPanel correspondingly.
|
||||||
if (mProject->IsSoloSimple())
|
if (mProject->IsSoloSimple())
|
||||||
|
@ -63,7 +63,7 @@ and use it for toolbar and window layouts too.
|
|||||||
|
|
||||||
#include "Project.h"
|
#include "Project.h"
|
||||||
#include "toolbars/ToolBar.h"
|
#include "toolbars/ToolBar.h"
|
||||||
#include "toolbars/ControlToolBar.h"
|
#include "toolbars/ToolManager.h"
|
||||||
#include "ImageManipulation.h"
|
#include "ImageManipulation.h"
|
||||||
#include "Theme.h"
|
#include "Theme.h"
|
||||||
#include "Experimental.h"
|
#include "Experimental.h"
|
||||||
@ -223,9 +223,11 @@ void Theme::EnsureInitialised()
|
|||||||
void Theme::ApplyUpdatedImages()
|
void Theme::ApplyUpdatedImages()
|
||||||
{
|
{
|
||||||
AudacityProject *p = GetActiveProject();
|
AudacityProject *p = GetActiveProject();
|
||||||
if( p->GetControlToolBar() )
|
for( int ii = 0; ii < ToolBarCount; ++ii )
|
||||||
{
|
{
|
||||||
p->GetControlToolBar()->ReCreateButtons();
|
ToolBar *pToolBar = p->mToolManager->GetToolBar(ii);
|
||||||
|
if( pToolBar )
|
||||||
|
pToolBar->ReCreateButtons();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
8190
src/ThemeAsCeeCode.h
8190
src/ThemeAsCeeCode.h
File diff suppressed because it is too large
Load Diff
@ -49,6 +49,7 @@
|
|||||||
#include <wx/tooltip.h>
|
#include <wx/tooltip.h>
|
||||||
|
|
||||||
#include "ControlToolBar.h"
|
#include "ControlToolBar.h"
|
||||||
|
#include "TranscriptionToolBar.h"
|
||||||
#include "MeterToolBar.h"
|
#include "MeterToolBar.h"
|
||||||
|
|
||||||
#include "../AColor.h"
|
#include "../AColor.h"
|
||||||
@ -72,7 +73,6 @@ AudacityProject *ControlToolBar::mBusyProject = NULL;
|
|||||||
|
|
||||||
BEGIN_EVENT_TABLE(ControlToolBar, ToolBar)
|
BEGIN_EVENT_TABLE(ControlToolBar, ToolBar)
|
||||||
EVT_CHAR(ControlToolBar::OnKeyEvent)
|
EVT_CHAR(ControlToolBar::OnKeyEvent)
|
||||||
EVT_TIMER(wxID_ANY, ControlToolBar::OnTimer)
|
|
||||||
EVT_BUTTON(ID_PLAY_BUTTON, ControlToolBar::OnPlay)
|
EVT_BUTTON(ID_PLAY_BUTTON, ControlToolBar::OnPlay)
|
||||||
EVT_BUTTON(ID_STOP_BUTTON, ControlToolBar::OnStop)
|
EVT_BUTTON(ID_STOP_BUTTON, ControlToolBar::OnStop)
|
||||||
EVT_BUTTON(ID_RECORD_BUTTON, ControlToolBar::OnRecord)
|
EVT_BUTTON(ID_RECORD_BUTTON, ControlToolBar::OnRecord)
|
||||||
@ -89,8 +89,6 @@ END_EVENT_TABLE()
|
|||||||
ControlToolBar::ControlToolBar()
|
ControlToolBar::ControlToolBar()
|
||||||
: ToolBar(TransportBarID, _("Transport"), wxT("Control"))
|
: ToolBar(TransportBarID, _("Transport"), wxT("Control"))
|
||||||
{
|
{
|
||||||
mShiftKeyTimer.SetOwner(this);
|
|
||||||
|
|
||||||
mPaused = false;
|
mPaused = false;
|
||||||
|
|
||||||
gPrefs->Read(wxT("/GUI/ErgonomicTransportButtons"), &mErgonomicTransportButtons, true);
|
gPrefs->Read(wxT("/GUI/ErgonomicTransportButtons"), &mErgonomicTransportButtons, true);
|
||||||
@ -102,31 +100,12 @@ ControlToolBar::ControlToolBar()
|
|||||||
|
|
||||||
ControlToolBar::~ControlToolBar()
|
ControlToolBar::~ControlToolBar()
|
||||||
{
|
{
|
||||||
wxTheApp->Disconnect( wxEVT_KEY_DOWN,
|
|
||||||
wxKeyEventHandler( ControlToolBar::OnKeyDown ),
|
|
||||||
NULL,
|
|
||||||
this );
|
|
||||||
|
|
||||||
wxTheApp->Disconnect( wxEVT_KEY_UP,
|
|
||||||
wxKeyEventHandler( ControlToolBar::OnKeyUp ),
|
|
||||||
NULL,
|
|
||||||
this );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ControlToolBar::Create(wxWindow * parent)
|
void ControlToolBar::Create(wxWindow * parent)
|
||||||
{
|
{
|
||||||
ToolBar::Create(parent);
|
ToolBar::Create(parent);
|
||||||
|
|
||||||
wxTheApp->Connect( wxEVT_KEY_DOWN,
|
|
||||||
wxKeyEventHandler( ControlToolBar::OnKeyDown ),
|
|
||||||
NULL,
|
|
||||||
this );
|
|
||||||
|
|
||||||
wxTheApp->Connect( wxEVT_KEY_UP,
|
|
||||||
wxKeyEventHandler( ControlToolBar::OnKeyUp ),
|
|
||||||
NULL,
|
|
||||||
this );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a convenience function that allows for button creation in
|
// This is a convenience function that allows for button creation in
|
||||||
@ -148,27 +127,16 @@ AButton *ControlToolBar::MakeButton(teBmps eEnabledUp, teBmps eEnabledDown, teBm
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControlToolBar::MakeLoopImage()
|
// static
|
||||||
|
void ControlToolBar::MakeAlternateImages(AButton &button, int idx,
|
||||||
|
teBmps eEnabledUp,
|
||||||
|
teBmps eEnabledDown,
|
||||||
|
teBmps eDisabled)
|
||||||
{
|
{
|
||||||
// JKC: See ToolBar::MakeButton() for almost identical code. Condense??
|
ToolBar::MakeAlternateImages(button, idx,
|
||||||
|
bmpRecoloredUpLarge, bmpRecoloredDownLarge, bmpRecoloredHiliteLarge,
|
||||||
wxSize Size1( theTheme.ImageSize( bmpRecoloredUpLarge ));
|
eEnabledUp, eEnabledDown, eDisabled,
|
||||||
wxSize Size2( theTheme.ImageSize( bmpLoop ));
|
theTheme.ImageSize( bmpRecoloredUpLarge ));
|
||||||
|
|
||||||
int xoff = (Size1.GetWidth() - Size2.GetWidth())/2;
|
|
||||||
int yoff = (Size1.GetHeight() - Size2.GetHeight())/2;
|
|
||||||
|
|
||||||
wxImage * up2 = OverlayImage(bmpRecoloredUpLarge, bmpLoop, xoff, yoff);
|
|
||||||
wxImage * hilite2 = OverlayImage(bmpRecoloredHiliteLarge, bmpLoop, xoff, yoff);
|
|
||||||
wxImage * down2 = OverlayImage(bmpRecoloredDownLarge, bmpLoop, xoff + 1, yoff + 1);
|
|
||||||
wxImage * disable2 = OverlayImage(bmpRecoloredUpLarge, bmpLoopDisabled, xoff, yoff);
|
|
||||||
|
|
||||||
mPlay->SetAlternateImages(*up2, *hilite2, *down2, *disable2);
|
|
||||||
|
|
||||||
delete up2;
|
|
||||||
delete hilite2;
|
|
||||||
delete down2;
|
|
||||||
delete disable2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControlToolBar::Populate()
|
void ControlToolBar::Populate()
|
||||||
@ -180,8 +148,10 @@ void ControlToolBar::Populate()
|
|||||||
|
|
||||||
mPlay = MakeButton( bmpPlay, bmpPlay, bmpPlayDisabled,
|
mPlay = MakeButton( bmpPlay, bmpPlay, bmpPlayDisabled,
|
||||||
ID_PLAY_BUTTON, true, _("Play"));
|
ID_PLAY_BUTTON, true, _("Play"));
|
||||||
|
MakeAlternateImages(*mPlay, 1, bmpLoop, bmpLoop, bmpLoopDisabled);
|
||||||
MakeLoopImage();
|
MakeAlternateImages(*mPlay, 2,
|
||||||
|
bmpCutPreview, bmpCutPreview, bmpCutPreviewDisabled);
|
||||||
|
mPlay->FollowModifierKeys();
|
||||||
|
|
||||||
mStop = MakeButton( bmpStop, bmpStop, bmpStopDisabled ,
|
mStop = MakeButton( bmpStop, bmpStop, bmpStopDisabled ,
|
||||||
ID_STOP_BUTTON, false, _("Stop"));
|
ID_STOP_BUTTON, false, _("Stop"));
|
||||||
@ -194,6 +164,9 @@ void ControlToolBar::Populate()
|
|||||||
|
|
||||||
mRecord = MakeButton(bmpRecord, bmpRecord, bmpRecordDisabled,
|
mRecord = MakeButton(bmpRecord, bmpRecord, bmpRecordDisabled,
|
||||||
ID_RECORD_BUTTON, true, _("Record"));
|
ID_RECORD_BUTTON, true, _("Record"));
|
||||||
|
MakeAlternateImages(*mRecord, 1, bmpAppendRecord, bmpAppendRecord,
|
||||||
|
bmpAppendRecordDisabled);
|
||||||
|
mRecord->FollowModifierKeys();
|
||||||
|
|
||||||
#if wxUSE_TOOLTIPS
|
#if wxUSE_TOOLTIPS
|
||||||
RegenerateToolsTooltips();
|
RegenerateToolsTooltips();
|
||||||
@ -397,7 +370,13 @@ void ControlToolBar::EnableDisableButtons()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mPlay->SetEnabled((!recording) || (tracks && !busy));
|
const bool enablePlay = (!recording) || (tracks && !busy);
|
||||||
|
mPlay->SetEnabled(enablePlay);
|
||||||
|
// Enable and disable the other play button
|
||||||
|
TranscriptionToolBar *const pttb = p->GetTranscriptionToolBar();
|
||||||
|
if (pttb)
|
||||||
|
pttb->SetEnabled(enablePlay);
|
||||||
|
|
||||||
mRecord->SetEnabled(!busy && !playing);
|
mRecord->SetEnabled(!busy && !playing);
|
||||||
|
|
||||||
mStop->SetEnabled(busy);
|
mStop->SetEnabled(busy);
|
||||||
@ -406,14 +385,26 @@ void ControlToolBar::EnableDisableButtons()
|
|||||||
mPause->SetEnabled(true);
|
mPause->SetEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControlToolBar::SetPlay(bool down, bool looped)
|
void ControlToolBar::SetPlay(bool down, bool looped, bool cutPreview)
|
||||||
{
|
{
|
||||||
|
AudacityProject *p = GetActiveProject();
|
||||||
|
TranscriptionToolBar *const pttb =
|
||||||
|
p ? p->GetTranscriptionToolBar(): 0;
|
||||||
if (down) {
|
if (down) {
|
||||||
mPlay->SetAlternate(looped);
|
mPlay->SetAlternateIdx(cutPreview ? 2 : looped ? 1 : 0);
|
||||||
mPlay->PushDown();
|
mPlay->PushDown();
|
||||||
} else {
|
if (pttb)
|
||||||
|
// This disables cursor changes for modifier keys
|
||||||
|
// in the other play button too
|
||||||
|
pttb->SetPlaying(true, looped, cutPreview);
|
||||||
|
}
|
||||||
|
else {
|
||||||
mPlay->PopUp();
|
mPlay->PopUp();
|
||||||
mPlay->SetAlternate(false);
|
mPlay->SetAlternateIdx(0);
|
||||||
|
if (pttb)
|
||||||
|
// This reenables cursor changes for modifier keys
|
||||||
|
// in the other play button too
|
||||||
|
pttb->SetPlaying(false, looped, cutPreview);
|
||||||
}
|
}
|
||||||
EnableDisableButtons();
|
EnableDisableButtons();
|
||||||
}
|
}
|
||||||
@ -444,13 +435,12 @@ bool ControlToolBar::IsRecordDown()
|
|||||||
{
|
{
|
||||||
return mRecord->IsDown();
|
return mRecord->IsDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControlToolBar::PlayPlayRegion(double t0, double t1,
|
void ControlToolBar::PlayPlayRegion(double t0, double t1,
|
||||||
bool looped /* = false */,
|
bool looped /* = false */,
|
||||||
bool cutpreview /* = false */,
|
bool cutpreview /* = false */,
|
||||||
TimeTrack *timetrack /* = NULL */)
|
TimeTrack *timetrack /* = NULL */)
|
||||||
{
|
{
|
||||||
SetPlay(true, looped);
|
SetPlay(true, looped, cutpreview);
|
||||||
|
|
||||||
if (gAudioIO->IsBusy()) {
|
if (gAudioIO->IsBusy()) {
|
||||||
SetPlay(false);
|
SetPlay(false);
|
||||||
@ -573,7 +563,7 @@ void ControlToolBar::PlayPlayRegion(double t0, double t1,
|
|||||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||||
NoteTrackArray(),
|
NoteTrackArray(),
|
||||||
#endif
|
#endif
|
||||||
NULL, p->GetRate(), tcp0, tcp1, p, false,
|
timetrack, p->GetRate(), tcp0, tcp1, p, false,
|
||||||
t0, t1-t0);
|
t0, t1-t0);
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
@ -677,48 +667,6 @@ void ControlToolBar::OnKeyEvent(wxKeyEvent & event)
|
|||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControlToolBar::OnKeyDown(wxKeyEvent & event)
|
|
||||||
{
|
|
||||||
event.Skip();
|
|
||||||
|
|
||||||
if (event.GetKeyCode() == WXK_SHIFT)
|
|
||||||
{
|
|
||||||
// Turn the "Play" button into a "Loop" button
|
|
||||||
if (!mPlay->IsDown())
|
|
||||||
mPlay->SetAlternate(true);
|
|
||||||
mShiftKeyTimer.Start(100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ControlToolBar::OnKeyUp(wxKeyEvent & event)
|
|
||||||
{
|
|
||||||
event.Skip();
|
|
||||||
|
|
||||||
if (event.GetKeyCode() == WXK_SHIFT)
|
|
||||||
{
|
|
||||||
// Turn the "Loop" button into a "Play" button
|
|
||||||
if (!mPlay->IsDown())
|
|
||||||
mPlay->SetAlternate(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ControlToolBar::OnTimer(wxTimerEvent & event)
|
|
||||||
{
|
|
||||||
event.Skip();
|
|
||||||
|
|
||||||
// bug 307 fix:
|
|
||||||
// Shift key-up events get swallowed if a command with a Shift in its keyboard
|
|
||||||
// shortcut opens a dialog, and ControlToolBar::OnKeyUp() doesn't get called.
|
|
||||||
if (!wxGetKeyState(WXK_SHIFT))
|
|
||||||
{
|
|
||||||
wxKeyEvent dummyEvent;
|
|
||||||
dummyEvent.m_keyCode = WXK_SHIFT;
|
|
||||||
this->OnKeyUp(dummyEvent);
|
|
||||||
mShiftKeyTimer.Stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ControlToolBar::OnPlay(wxCommandEvent & WXUNUSED(evt))
|
void ControlToolBar::OnPlay(wxCommandEvent & WXUNUSED(evt))
|
||||||
{
|
{
|
||||||
StopPlaying();
|
StopPlaying();
|
||||||
@ -736,12 +684,11 @@ void ControlToolBar::OnStop(wxCommandEvent & WXUNUSED(evt))
|
|||||||
|
|
||||||
void ControlToolBar::PlayDefault()
|
void ControlToolBar::PlayDefault()
|
||||||
{
|
{
|
||||||
if(mPlay->WasControlDown())
|
// Let control have precedence over shift
|
||||||
PlayCurrentRegion(false, true); /* play with cut preview */
|
const bool cutPreview = mPlay->WasControlDown();
|
||||||
else if(mPlay->WasShiftDown())
|
const bool looped = !cutPreview &&
|
||||||
PlayCurrentRegion(true); /* play looped */
|
mPlay->WasShiftDown();
|
||||||
else
|
PlayCurrentRegion(looped, cutPreview);
|
||||||
PlayCurrentRegion(false); /* play normal */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControlToolBar::StopPlaying(bool stopStream /* = true*/)
|
void ControlToolBar::StopPlaying(bool stopStream /* = true*/)
|
||||||
|
@ -14,8 +14,6 @@
|
|||||||
#ifndef __AUDACITY_CONTROL_TOOLBAR__
|
#ifndef __AUDACITY_CONTROL_TOOLBAR__
|
||||||
#define __AUDACITY_CONTROL_TOOLBAR__
|
#define __AUDACITY_CONTROL_TOOLBAR__
|
||||||
|
|
||||||
#include <wx/timer.h>
|
|
||||||
|
|
||||||
#include "ToolBar.h"
|
#include "ToolBar.h"
|
||||||
#include "../Theme.h"
|
#include "../Theme.h"
|
||||||
|
|
||||||
@ -44,10 +42,6 @@ class ControlToolBar:public ToolBar {
|
|||||||
|
|
||||||
void UpdatePrefs();
|
void UpdatePrefs();
|
||||||
virtual void OnKeyEvent(wxKeyEvent & event);
|
virtual void OnKeyEvent(wxKeyEvent & event);
|
||||||
void OnKeyDown(wxKeyEvent & event);
|
|
||||||
void OnKeyUp(wxKeyEvent & event);
|
|
||||||
|
|
||||||
void OnTimer(wxTimerEvent & event);
|
|
||||||
|
|
||||||
// msmeyer: These are public, but it's far better to
|
// msmeyer: These are public, but it's far better to
|
||||||
// call the "real" interface functions like PlayCurrentRegion() and
|
// call the "real" interface functions like PlayCurrentRegion() and
|
||||||
@ -60,7 +54,7 @@ class ControlToolBar:public ToolBar {
|
|||||||
void OnPause(wxCommandEvent & evt);
|
void OnPause(wxCommandEvent & evt);
|
||||||
|
|
||||||
//These allow buttons to be controlled externally:
|
//These allow buttons to be controlled externally:
|
||||||
void SetPlay(bool down, bool looped=false);
|
void SetPlay(bool down, bool looped=false, bool cutPreview = false);
|
||||||
void SetStop(bool down);
|
void SetStop(bool down);
|
||||||
void SetRecord(bool down);
|
void SetRecord(bool down);
|
||||||
|
|
||||||
@ -94,7 +88,13 @@ class ControlToolBar:public ToolBar {
|
|||||||
int id,
|
int id,
|
||||||
bool processdownevents,
|
bool processdownevents,
|
||||||
const wxChar *label);
|
const wxChar *label);
|
||||||
void MakeLoopImage();
|
|
||||||
|
static
|
||||||
|
void MakeAlternateImages(AButton &button, int idx,
|
||||||
|
teBmps eEnabledUp,
|
||||||
|
teBmps eEnabledDown,
|
||||||
|
teBmps eDisabled);
|
||||||
|
|
||||||
void ArrangeButtons();
|
void ArrangeButtons();
|
||||||
void SetupCutPreviewTracks(double playStart, double cutStart,
|
void SetupCutPreviewTracks(double playStart, double cutStart,
|
||||||
double cutEnd, double playEnd);
|
double cutEnd, double playEnd);
|
||||||
@ -118,8 +118,6 @@ class ControlToolBar:public ToolBar {
|
|||||||
AButton *mStop;
|
AButton *mStop;
|
||||||
AButton *mFF;
|
AButton *mFF;
|
||||||
|
|
||||||
wxTimer mShiftKeyTimer;
|
|
||||||
|
|
||||||
static AudacityProject *mBusyProject;
|
static AudacityProject *mBusyProject;
|
||||||
|
|
||||||
// Maybe button state values shouldn't be duplicated in this toolbar?
|
// Maybe button state values shouldn't be duplicated in this toolbar?
|
||||||
|
@ -503,22 +503,40 @@ AButton * ToolBar::MakeButton(teBmps eUp,
|
|||||||
int xoff = (size.GetWidth() - theTheme.Image(eStandardUp).GetWidth())/2;
|
int xoff = (size.GetWidth() - theTheme.Image(eStandardUp).GetWidth())/2;
|
||||||
int yoff = (size.GetHeight() - theTheme.Image(eStandardUp).GetHeight())/2;
|
int yoff = (size.GetHeight() - theTheme.Image(eStandardUp).GetHeight())/2;
|
||||||
|
|
||||||
wxImage * up2 = OverlayImage(eUp, eStandardUp, xoff, yoff);
|
typedef std::auto_ptr<wxImage> wxImagePtr;
|
||||||
wxImage * hilite2 = OverlayImage(eHilite, eStandardUp, xoff, yoff);
|
wxImagePtr up2 (OverlayImage(eUp, eStandardUp, xoff, yoff));
|
||||||
wxImage * down2 = OverlayImage(eDown, eStandardDown, xoff + 1, yoff + 1);
|
wxImagePtr hilite2 (OverlayImage(eHilite, eStandardUp, xoff, yoff));
|
||||||
wxImage * disable2 = OverlayImage(eUp, eDisabled, xoff, yoff);
|
wxImagePtr down2 (OverlayImage(eDown, eStandardDown, xoff + 1, yoff + 1));
|
||||||
|
wxImagePtr disable2 (OverlayImage(eUp, eDisabled, xoff, yoff));
|
||||||
|
|
||||||
AButton * button =
|
AButton * button =
|
||||||
new AButton(this, id, placement, size, *up2, *hilite2, *down2,
|
new AButton(this, id, placement, size, *up2, *hilite2, *down2,
|
||||||
*disable2, processdownevents);
|
*disable2, processdownevents);
|
||||||
|
|
||||||
delete up2;
|
|
||||||
delete down2;
|
|
||||||
delete hilite2;
|
|
||||||
delete disable2;
|
|
||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//static
|
||||||
|
void ToolBar::MakeAlternateImages(AButton &button, int idx,
|
||||||
|
teBmps eUp,
|
||||||
|
teBmps eDown,
|
||||||
|
teBmps eHilite,
|
||||||
|
teBmps eStandardUp,
|
||||||
|
teBmps eStandardDown,
|
||||||
|
teBmps eDisabled,
|
||||||
|
wxSize size)
|
||||||
|
{
|
||||||
|
int xoff = (size.GetWidth() - theTheme.Image(eStandardUp).GetWidth())/2;
|
||||||
|
int yoff = (size.GetHeight() - theTheme.Image(eStandardUp).GetHeight())/2;
|
||||||
|
|
||||||
|
typedef std::auto_ptr<wxImage> wxImagePtr;
|
||||||
|
wxImagePtr up (OverlayImage(eUp, eStandardUp, xoff, yoff));
|
||||||
|
wxImagePtr hilite (OverlayImage(eHilite, eStandardUp, xoff, yoff));
|
||||||
|
wxImagePtr down (OverlayImage(eDown, eStandardDown, xoff + 1, yoff + 1));
|
||||||
|
wxImagePtr disable (OverlayImage(eUp, eDisabled, xoff, yoff));
|
||||||
|
|
||||||
|
button.SetAlternateImages(idx, *up, *hilite, *down, *disable);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// 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)
|
||||||
|
@ -127,6 +127,16 @@ class ToolBar:public wxPanel
|
|||||||
bool processdownevents,
|
bool processdownevents,
|
||||||
wxSize size);
|
wxSize size);
|
||||||
|
|
||||||
|
static
|
||||||
|
void MakeAlternateImages(AButton &button, int idx,
|
||||||
|
teBmps eUp,
|
||||||
|
teBmps eDown,
|
||||||
|
teBmps eHilite,
|
||||||
|
teBmps eStandardUp,
|
||||||
|
teBmps eStandardDown,
|
||||||
|
teBmps eDisabled,
|
||||||
|
wxSize size);
|
||||||
|
|
||||||
void SetButton(bool down, AButton *button);
|
void SetButton(bool down, AButton *button);
|
||||||
|
|
||||||
void MakeMacRecoloredImage(teBmps eBmpOut, teBmps eBmpIn);
|
void MakeMacRecoloredImage(teBmps eBmpOut, teBmps eBmpIn);
|
||||||
|
@ -162,6 +162,16 @@ AButton *TranscriptionToolBar::AddButton(
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TranscriptionToolBar::MakeAlternateImages(
|
||||||
|
teBmps eFore, teBmps eDisabled,
|
||||||
|
int id, unsigned altIdx)
|
||||||
|
{
|
||||||
|
ToolBar::MakeAlternateImages(*mButtons[id], altIdx,
|
||||||
|
bmpRecoloredUpSmall, bmpRecoloredDownSmall, bmpRecoloredHiliteSmall,
|
||||||
|
eFore, eFore, eDisabled,
|
||||||
|
theTheme.ImageSize( bmpRecoloredUpSmall ));
|
||||||
|
}
|
||||||
|
|
||||||
void TranscriptionToolBar::Populate()
|
void TranscriptionToolBar::Populate()
|
||||||
{
|
{
|
||||||
// Very similar to code in ControlToolBar...
|
// Very similar to code in ControlToolBar...
|
||||||
@ -170,6 +180,9 @@ void TranscriptionToolBar::Populate()
|
|||||||
|
|
||||||
AddButton(bmpPlay, bmpPlayDisabled, TTB_PlaySpeed,
|
AddButton(bmpPlay, bmpPlayDisabled, TTB_PlaySpeed,
|
||||||
_("Play at selected speed"));
|
_("Play at selected speed"));
|
||||||
|
MakeAlternateImages(bmpLoop, bmpLoopDisabled, TTB_PlaySpeed, 1);
|
||||||
|
MakeAlternateImages(bmpCutPreview, bmpCutPreviewDisabled, TTB_PlaySpeed, 2);
|
||||||
|
mButtons[TTB_PlaySpeed]->FollowModifierKeys();
|
||||||
|
|
||||||
//Add a slider that controls the speed of playback.
|
//Add a slider that controls the speed of playback.
|
||||||
const int SliderWidth=100;
|
const int SliderWidth=100;
|
||||||
@ -386,7 +399,8 @@ void TranscriptionToolBar::GetSamples(WaveTrack *t, sampleCount *s0, sampleCount
|
|||||||
*slen = ss1 - ss0;
|
*slen = ss1 - ss0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TranscriptionToolBar::OnPlaySpeed(wxCommandEvent & WXUNUSED(event))
|
// Come here from button clicks, or commands
|
||||||
|
void TranscriptionToolBar::PlayAtSpeed(bool looped, bool cutPreview)
|
||||||
{
|
{
|
||||||
// Can't do anything without an active project
|
// Can't do anything without an active project
|
||||||
AudacityProject * p = GetActiveProject();
|
AudacityProject * p = GetActiveProject();
|
||||||
@ -427,12 +441,22 @@ void TranscriptionToolBar::OnPlaySpeed(wxCommandEvent & WXUNUSED(event))
|
|||||||
#endif
|
#endif
|
||||||
p->GetControlToolBar()->PlayPlayRegion(playRegionStart,
|
p->GetControlToolBar()->PlayPlayRegion(playRegionStart,
|
||||||
playRegionEnd,
|
playRegionEnd,
|
||||||
false,
|
looped,
|
||||||
false,
|
cutPreview,
|
||||||
mTimeTrack);
|
mTimeTrack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Come here from button clicks only
|
||||||
|
void TranscriptionToolBar::OnPlaySpeed(wxCommandEvent & WXUNUSED(event))
|
||||||
|
{
|
||||||
|
// Let control have precedence over shift
|
||||||
|
const bool cutPreview = mButtons[TTB_PlaySpeed]->WasControlDown();
|
||||||
|
const bool looped = !cutPreview &&
|
||||||
|
mButtons[TTB_PlaySpeed]->WasShiftDown();
|
||||||
|
PlayAtSpeed(looped, cutPreview);
|
||||||
|
}
|
||||||
|
|
||||||
void TranscriptionToolBar::OnSpeedSlider(wxCommandEvent& WXUNUSED(event))
|
void TranscriptionToolBar::OnSpeedSlider(wxCommandEvent& WXUNUSED(event))
|
||||||
{
|
{
|
||||||
mPlaySpeed = (mPlaySpeedSlider->Get()) * 100;
|
mPlaySpeed = (mPlaySpeedSlider->Get()) * 100;
|
||||||
@ -867,12 +891,6 @@ void TranscriptionToolBar::SetKeyType(wxCommandEvent & WXUNUSED(event))
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TranscriptionToolBar::PlayAtSpeed()
|
|
||||||
{
|
|
||||||
wxCommandEvent e;
|
|
||||||
OnPlaySpeed(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TranscriptionToolBar::ShowPlaySpeedDialog()
|
void TranscriptionToolBar::ShowPlaySpeedDialog()
|
||||||
{
|
{
|
||||||
mPlaySpeedSlider->ShowDialog();
|
mPlaySpeedSlider->ShowDialog();
|
||||||
@ -881,6 +899,24 @@ void TranscriptionToolBar::ShowPlaySpeedDialog()
|
|||||||
OnSpeedSlider(e);
|
OnSpeedSlider(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TranscriptionToolBar::SetEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
mButtons[TTB_PlaySpeed]->SetEnabled(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TranscriptionToolBar::SetPlaying(bool down, bool looped, bool cutPreview)
|
||||||
|
{
|
||||||
|
AButton *const button = mButtons[TTB_PlaySpeed];
|
||||||
|
if (down) {
|
||||||
|
button->SetAlternateIdx(cutPreview ? 2 : looped ? 1 : 0);
|
||||||
|
button->PushDown();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
button->SetAlternateIdx(0);
|
||||||
|
button->PopUp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TranscriptionToolBar::AdjustPlaySpeed(float adj)
|
void TranscriptionToolBar::AdjustPlaySpeed(float adj)
|
||||||
{
|
{
|
||||||
if (adj < 0) {
|
if (adj < 0) {
|
||||||
|
@ -92,10 +92,13 @@ class TranscriptionToolBar:public ToolBar {
|
|||||||
virtual double GetSensitivity();
|
virtual double GetSensitivity();
|
||||||
virtual void SetKeyType(wxCommandEvent & event);
|
virtual void SetKeyType(wxCommandEvent & event);
|
||||||
|
|
||||||
void PlayAtSpeed();
|
void PlayAtSpeed(bool looped, bool cutPreview);
|
||||||
void ShowPlaySpeedDialog();
|
void ShowPlaySpeedDialog();
|
||||||
void AdjustPlaySpeed(float adj);
|
void AdjustPlaySpeed(float adj);
|
||||||
|
|
||||||
|
void SetEnabled(bool enabled);
|
||||||
|
void SetPlaying(bool down, bool looped, bool cutPreview);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void InitializeTranscriptionToolBar();
|
void InitializeTranscriptionToolBar();
|
||||||
@ -103,6 +106,9 @@ class TranscriptionToolBar:public ToolBar {
|
|||||||
teBmps eFore, teBmps eDisabled,
|
teBmps eFore, teBmps eDisabled,
|
||||||
int id,
|
int id,
|
||||||
const wxChar *label);
|
const wxChar *label);
|
||||||
|
void MakeAlternateImages(
|
||||||
|
teBmps eFore, teBmps eDisabled,
|
||||||
|
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();
|
||||||
|
@ -46,6 +46,110 @@ BEGIN_EVENT_TABLE(AButton, wxWindow)
|
|||||||
EVT_ERASE_BACKGROUND(AButton::OnErase)
|
EVT_ERASE_BACKGROUND(AButton::OnErase)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
|
class AButton::Listener
|
||||||
|
: public wxEvtHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Listener (AButton *button);
|
||||||
|
~Listener();
|
||||||
|
|
||||||
|
void OnKeyDown(wxKeyEvent & event);
|
||||||
|
void OnKeyUp(wxKeyEvent & event);
|
||||||
|
void OnTimer(wxTimerEvent & event);
|
||||||
|
|
||||||
|
DECLARE_CLASS(AButton::Listener);
|
||||||
|
DECLARE_EVENT_TABLE();
|
||||||
|
|
||||||
|
private:
|
||||||
|
AButton *mButton;
|
||||||
|
wxTimer mShiftKeyTimer;
|
||||||
|
};
|
||||||
|
|
||||||
|
IMPLEMENT_CLASS(AButton::Listener, wxEvtHandler);
|
||||||
|
|
||||||
|
BEGIN_EVENT_TABLE(AButton::Listener, wxEvtHandler)
|
||||||
|
EVT_TIMER(wxID_ANY, AButton::Listener::OnTimer)
|
||||||
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
|
AButton::Listener::Listener (AButton *button)
|
||||||
|
: mButton(button)
|
||||||
|
{
|
||||||
|
mShiftKeyTimer.SetOwner(this);
|
||||||
|
|
||||||
|
wxTheApp->Connect( wxEVT_KEY_DOWN,
|
||||||
|
wxKeyEventHandler( AButton::Listener::OnKeyDown ),
|
||||||
|
NULL,
|
||||||
|
this );
|
||||||
|
|
||||||
|
wxTheApp->Connect( wxEVT_KEY_UP,
|
||||||
|
wxKeyEventHandler( AButton::Listener::OnKeyUp ),
|
||||||
|
NULL,
|
||||||
|
this );
|
||||||
|
}
|
||||||
|
|
||||||
|
AButton::Listener::~Listener ()
|
||||||
|
{
|
||||||
|
wxTheApp->Disconnect( wxEVT_KEY_DOWN,
|
||||||
|
wxKeyEventHandler( AButton::Listener::OnKeyDown ),
|
||||||
|
NULL,
|
||||||
|
this );
|
||||||
|
|
||||||
|
wxTheApp->Disconnect( wxEVT_KEY_UP,
|
||||||
|
wxKeyEventHandler( AButton::Listener::OnKeyUp ),
|
||||||
|
NULL,
|
||||||
|
this );
|
||||||
|
}
|
||||||
|
|
||||||
|
void AButton::Listener::OnKeyDown(wxKeyEvent & event)
|
||||||
|
{
|
||||||
|
// Really, it's all the same check for changes of key states.
|
||||||
|
OnKeyUp(event);
|
||||||
|
|
||||||
|
// See comments in OnTimer()
|
||||||
|
mShiftKeyTimer.Start(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AButton::Listener::OnKeyUp(wxKeyEvent & event)
|
||||||
|
{
|
||||||
|
event.Skip();
|
||||||
|
|
||||||
|
if (!mButton->IsDown())
|
||||||
|
{
|
||||||
|
int idx = 0;
|
||||||
|
// Ignore the event, consult key states. One modifier key might
|
||||||
|
// have gone up but another remained down.
|
||||||
|
// Note that CMD (or CTRL) takes precedence over Shift if both are down
|
||||||
|
// and alternates are defined for both
|
||||||
|
// see also AButton::OnMouseEvent()
|
||||||
|
if (wxGetKeyState(WXK_CONTROL) && mButton->HasAlternateImages(2))
|
||||||
|
idx = 2;
|
||||||
|
else if (wxGetKeyState(WXK_SHIFT) && mButton->HasAlternateImages(1))
|
||||||
|
idx = 1;
|
||||||
|
|
||||||
|
// Turn e.g. the "Play" button into a "Loop" button
|
||||||
|
// or "Cut Preview" button
|
||||||
|
mButton->SetAlternateIdx(idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AButton::Listener::OnTimer(wxTimerEvent & event)
|
||||||
|
{
|
||||||
|
event.Skip();
|
||||||
|
|
||||||
|
// bug 307 fix:
|
||||||
|
// Shift key-up events get swallowed if a command with a Shift in its keyboard
|
||||||
|
// shortcut opens a dialog, and OnKeyUp() doesn't get called.
|
||||||
|
// With CTRL now causing the button to change appearance, presumably similar
|
||||||
|
// can happen with that key.
|
||||||
|
if (!wxGetKeyState(WXK_SHIFT) ||
|
||||||
|
!wxGetKeyState(WXK_CONTROL))
|
||||||
|
{
|
||||||
|
wxKeyEvent dummy;
|
||||||
|
this->OnKeyUp(dummy);
|
||||||
|
mShiftKeyTimer.Stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AButton::AButton(wxWindow * parent,
|
AButton::AButton(wxWindow * parent,
|
||||||
wxWindowID id,
|
wxWindowID id,
|
||||||
const wxPoint & pos,
|
const wxPoint & pos,
|
||||||
@ -108,18 +212,19 @@ void AButton::Init(wxWindow * parent,
|
|||||||
mToggle = toggle;
|
mToggle = toggle;
|
||||||
mUseDisabledAsDownHiliteImage = false;
|
mUseDisabledAsDownHiliteImage = false;
|
||||||
|
|
||||||
mImage[0] = up;
|
mImages.resize(1);
|
||||||
mImage[1] = over;
|
mImages[0].mArr[0] = up;
|
||||||
mImage[2] = down;
|
mImages[0].mArr[1] = over;
|
||||||
mImage[3] = dis;
|
mImages[0].mArr[2] = down;
|
||||||
|
mImages[0].mArr[3] = dis;
|
||||||
|
|
||||||
mAlternate = false;
|
mAlternateIdx = 0;
|
||||||
|
|
||||||
mButtonIsFocused = false;
|
mButtonIsFocused = false;
|
||||||
mFocusRect = GetRect().Deflate( 3, 3 );
|
mFocusRect = GetRect().Deflate( 3, 3 );
|
||||||
|
|
||||||
SetSizeHints(mImage[0].GetMinSize(),
|
SetSizeHints(mImages[0].mArr[0].GetMinSize(),
|
||||||
mImage[0].GetMaxSize());
|
mImages[0].mArr[0].GetMaxSize());
|
||||||
|
|
||||||
#if wxUSE_ACCESSIBILITY
|
#if wxUSE_ACCESSIBILITY
|
||||||
SetName( wxT("") );
|
SetName( wxT("") );
|
||||||
@ -132,38 +237,50 @@ void AButton::UseDisabledAsDownHiliteImage(bool flag)
|
|||||||
mUseDisabledAsDownHiliteImage = flag;
|
mUseDisabledAsDownHiliteImage = flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AButton::SetAlternateImages(wxImage up,
|
void AButton::SetAlternateImages(unsigned idx,
|
||||||
|
wxImage up,
|
||||||
wxImage over,
|
wxImage over,
|
||||||
wxImage down,
|
wxImage down,
|
||||||
wxImage dis)
|
wxImage dis)
|
||||||
{
|
{
|
||||||
mAltImage[0] = ImageRoll(up);
|
if (1 + idx > mImages.size())
|
||||||
mAltImage[1] = ImageRoll(over);
|
mImages.resize(1 + idx);
|
||||||
mAltImage[2] = ImageRoll(down);
|
mImages[idx].mArr[0] = ImageRoll(up);
|
||||||
mAltImage[3] = ImageRoll(dis);
|
mImages[idx].mArr[1] = ImageRoll(over);
|
||||||
|
mImages[idx].mArr[2] = ImageRoll(down);
|
||||||
|
mImages[idx].mArr[3] = ImageRoll(dis);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AButton::SetAlternateImages(ImageRoll up,
|
void AButton::SetAlternateImages(unsigned idx,
|
||||||
|
ImageRoll up,
|
||||||
ImageRoll over,
|
ImageRoll over,
|
||||||
ImageRoll down,
|
ImageRoll down,
|
||||||
ImageRoll dis)
|
ImageRoll dis)
|
||||||
{
|
{
|
||||||
mAltImage[0] = up;
|
if (1 + idx > mImages.size())
|
||||||
mAltImage[1] = over;
|
mImages.resize(1 + idx);
|
||||||
mAltImage[2] = down;
|
mImages[idx].mArr[0] = up;
|
||||||
mAltImage[3] = dis;
|
mImages[idx].mArr[1] = over;
|
||||||
|
mImages[idx].mArr[2] = down;
|
||||||
|
mImages[idx].mArr[3] = dis;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AButton::SetAlternate(bool useAlternateImages)
|
void AButton::SetAlternateIdx(unsigned idx)
|
||||||
{
|
{
|
||||||
// If alternate-image-state is already correct then
|
// If alternate-image-state is already correct then
|
||||||
// nothing to do (saves repainting button).
|
// nothing to do (saves repainting button).
|
||||||
if( mAlternate == useAlternateImages )
|
if( mAlternateIdx == idx )
|
||||||
return;
|
return;
|
||||||
mAlternate = useAlternateImages;
|
mAlternateIdx = idx;
|
||||||
Refresh(false);
|
Refresh(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AButton::FollowModifierKeys()
|
||||||
|
{
|
||||||
|
if(!mListener.get())
|
||||||
|
mListener.reset(new Listener(this));
|
||||||
|
}
|
||||||
|
|
||||||
void AButton::SetFocusRect(wxRect & r)
|
void AButton::SetFocusRect(wxRect & r)
|
||||||
{
|
{
|
||||||
mFocusRect = r;
|
mFocusRect = r;
|
||||||
@ -218,10 +335,7 @@ void AButton::OnPaint(wxPaintEvent & WXUNUSED(event))
|
|||||||
|
|
||||||
AButtonState buttonState = GetState();
|
AButtonState buttonState = GetState();
|
||||||
|
|
||||||
if (mAlternate)
|
mImages[mAlternateIdx].mArr[buttonState].Draw(dc, GetClientRect());
|
||||||
mAltImage[buttonState].Draw(dc, GetClientRect());
|
|
||||||
else
|
|
||||||
mImage[buttonState].Draw(dc, GetClientRect());
|
|
||||||
|
|
||||||
#if defined(__WXMSW__)
|
#if defined(__WXMSW__)
|
||||||
if( mButtonIsFocused )
|
if( mButtonIsFocused )
|
||||||
@ -242,12 +356,17 @@ void AButton::OnSize(wxSizeEvent & WXUNUSED(event))
|
|||||||
Refresh(false);
|
Refresh(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AButton::HasAlternateImages()
|
bool AButton::HasAlternateImages(unsigned idx)
|
||||||
{
|
{
|
||||||
return (mAltImage[0].Ok() &&
|
if (mImages.size() <= idx)
|
||||||
mAltImage[1].Ok() &&
|
return false;
|
||||||
mAltImage[2].Ok() &&
|
|
||||||
mAltImage[3].Ok());
|
const ImageArr &images = mImages[idx];
|
||||||
|
const ImageRoll (&arr)[4] = images.mArr;
|
||||||
|
return (arr[0].Ok() &&
|
||||||
|
arr[1].Ok() &&
|
||||||
|
arr[2].Ok() &&
|
||||||
|
arr[3].Ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AButton::OnMouseEvent(wxMouseEvent & event)
|
void AButton::OnMouseEvent(wxMouseEvent & event)
|
||||||
@ -264,8 +383,17 @@ void AButton::OnMouseEvent(wxMouseEvent & event)
|
|||||||
(event.m_x >= 0 && event.m_y >= 0 &&
|
(event.m_x >= 0 && event.m_y >= 0 &&
|
||||||
event.m_x < clientSize.x && event.m_y < clientSize.y);
|
event.m_x < clientSize.x && event.m_y < clientSize.y);
|
||||||
|
|
||||||
if (HasAlternateImages() && !mButtonIsDown)
|
if (!mButtonIsDown)
|
||||||
mAlternate = event.ShiftDown();
|
{
|
||||||
|
// Note that CMD (or CTRL) takes precedence over Shift if both are down
|
||||||
|
// see also AButton::Listener::OnKeyUp()
|
||||||
|
if (event.CmdDown() && HasAlternateImages(2))
|
||||||
|
mAlternateIdx = 2;
|
||||||
|
else if (event.ShiftDown() && HasAlternateImages(1))
|
||||||
|
mAlternateIdx = 1;
|
||||||
|
else
|
||||||
|
mAlternateIdx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (mEnabled && event.IsButton()) {
|
if (mEnabled && event.IsButton()) {
|
||||||
if (event.ButtonIsDown(wxMOUSE_BTN_ANY)) {
|
if (event.ButtonIsDown(wxMOUSE_BTN_ANY)) {
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
#ifndef __AUDACITY_BUTTON__
|
#ifndef __AUDACITY_BUTTON__
|
||||||
#define __AUDACITY_BUTTON__
|
#define __AUDACITY_BUTTON__
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#if wxUSE_ACCESSIBILITY
|
#if wxUSE_ACCESSIBILITY
|
||||||
#include <wx/access.h>
|
#include <wx/access.h>
|
||||||
#endif
|
#endif
|
||||||
@ -23,9 +25,12 @@
|
|||||||
|
|
||||||
class AButton: public wxWindow {
|
class AButton: public wxWindow {
|
||||||
friend class AButtonAx;
|
friend class AButtonAx;
|
||||||
|
class Listener;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
// Construct button, specifying images (button up, highlight, button down,
|
||||||
|
// and disabled) for the default state
|
||||||
AButton(wxWindow * parent,
|
AButton(wxWindow * parent,
|
||||||
wxWindowID id,
|
wxWindowID id,
|
||||||
const wxPoint & pos,
|
const wxPoint & pos,
|
||||||
@ -36,6 +41,8 @@ class AButton: public wxWindow {
|
|||||||
ImageRoll dis,
|
ImageRoll dis,
|
||||||
bool toggle);
|
bool toggle);
|
||||||
|
|
||||||
|
// Construct button, specifying images (button up, highlight, button down,
|
||||||
|
// and disabled) for the default state
|
||||||
AButton(wxWindow * parent,
|
AButton(wxWindow * parent,
|
||||||
wxWindowID id,
|
wxWindowID id,
|
||||||
const wxPoint & pos,
|
const wxPoint & pos,
|
||||||
@ -48,17 +55,30 @@ class AButton: public wxWindow {
|
|||||||
|
|
||||||
virtual ~ AButton();
|
virtual ~ AButton();
|
||||||
|
|
||||||
virtual void SetAlternateImages(ImageRoll up,
|
// Associate a set of four images (button up, highlight, button down,
|
||||||
|
// disabled) with one nondefault state of the button
|
||||||
|
virtual void SetAlternateImages(unsigned idx,
|
||||||
|
ImageRoll up,
|
||||||
ImageRoll over,
|
ImageRoll over,
|
||||||
ImageRoll down,
|
ImageRoll down,
|
||||||
ImageRoll dis);
|
ImageRoll dis);
|
||||||
|
|
||||||
virtual void SetAlternateImages(wxImage up,
|
// Associate a set of four images (button up, highlight, button down,
|
||||||
|
// disabled) with one nondefault state of the button
|
||||||
|
virtual void SetAlternateImages(unsigned idx,
|
||||||
|
wxImage up,
|
||||||
wxImage over,
|
wxImage over,
|
||||||
wxImage down,
|
wxImage down,
|
||||||
wxImage dis);
|
wxImage dis);
|
||||||
|
|
||||||
virtual void SetAlternate(bool useAlternateImages);
|
// Choose state of the button
|
||||||
|
virtual void SetAlternateIdx(unsigned idx);
|
||||||
|
|
||||||
|
// Make the button change appearance with the modifier keys, no matter
|
||||||
|
// where the mouse is:
|
||||||
|
// Use state 2 when CTRL is down, else 1 when SHIFT is down, else 0
|
||||||
|
virtual void FollowModifierKeys();
|
||||||
|
|
||||||
virtual void SetFocusRect(wxRect & r);
|
virtual void SetFocusRect(wxRect & r);
|
||||||
|
|
||||||
virtual bool IsEnabled() const { return mEnabled; }
|
virtual bool IsEnabled() const { return mEnabled; }
|
||||||
@ -103,7 +123,7 @@ class AButton: public wxWindow {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool HasAlternateImages();
|
bool HasAlternateImages(unsigned idx);
|
||||||
|
|
||||||
void Init(wxWindow * parent,
|
void Init(wxWindow * parent,
|
||||||
wxWindowID id,
|
wxWindowID id,
|
||||||
@ -115,7 +135,7 @@ class AButton: public wxWindow {
|
|||||||
ImageRoll dis,
|
ImageRoll dis,
|
||||||
bool toggle);
|
bool toggle);
|
||||||
|
|
||||||
bool mAlternate;
|
unsigned mAlternateIdx;
|
||||||
bool mToggle; // This bool, if true, makes the button able to
|
bool mToggle; // This bool, if true, makes the button able to
|
||||||
// process events when it is in the down state, and
|
// process events when it is in the down state, and
|
||||||
// moving to the opposite state when it is clicked.
|
// moving to the opposite state when it is clicked.
|
||||||
@ -133,11 +153,13 @@ class AButton: public wxWindow {
|
|||||||
bool mEnabled;
|
bool mEnabled;
|
||||||
bool mUseDisabledAsDownHiliteImage;
|
bool mUseDisabledAsDownHiliteImage;
|
||||||
|
|
||||||
ImageRoll mImage[4];
|
struct ImageArr { ImageRoll mArr[4]; };
|
||||||
ImageRoll mAltImage[4];
|
std::vector<ImageArr> mImages;
|
||||||
|
|
||||||
wxRect mFocusRect;
|
wxRect mFocusRect;
|
||||||
|
|
||||||
|
std::auto_ptr<Listener> mListener;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user