1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-02 08:59:28 +02:00

Merge branch 'master' into scrubbing2

This commit is contained in:
Paul Licameli 2016-05-06 16:52:45 -04:00
commit cbb8d3c968
7 changed files with 183 additions and 135 deletions

View File

@ -94,6 +94,10 @@ enum CommandFlag : unsigned long long
CanStopAudioStreamFlag = 0x40000000,
AudioStreamNotScrubbingFlag
= 0x80000000ULL, // prl
RulerHasFocus
= 0x100000000ULL, // prl
TrackPanelOrRulerHasFocus
= 0x200000000ULL, // prl
NoFlagsSpecifed = ~0ULL
};

View File

@ -1128,8 +1128,8 @@ void AudacityProject::CreateMenusAndCommands()
c->AddCommand(wxT("SeekLeftLong"), _("Long seek left during playback"), FN(OnSeekLeftLong), wxT("Shift+Left\tallowDup"));
c->AddCommand(wxT("SeekRightLong"), _("Long Seek right during playback"), FN(OnSeekRightLong), wxT("Shift+Right\tallowDup"));
c->SetDefaultFlags(TracksExistFlag | TrackPanelHasFocus,
TracksExistFlag | TrackPanelHasFocus);
c->SetDefaultFlags(TrackPanelOrRulerHasFocus,
TrackPanelOrRulerHasFocus);
c->AddCommand(wxT("PrevTrack"), _("Move Focus to Previous Track"), FN(OnCursorUp), wxT("Up"));
c->AddCommand(wxT("NextTrack"), _("Move Focus to Next Track"), FN(OnCursorDown), wxT("Down"));
@ -1139,6 +1139,11 @@ void AudacityProject::CreateMenusAndCommands()
c->AddCommand(wxT("ShiftUp"), _("Move Focus to Previous and Select"), FN(OnShiftUp), wxT("Shift+Up"));
c->AddCommand(wxT("ShiftDown"), _("Move Focus to Next and Select"), FN(OnShiftDown), wxT("Shift+Down"));
c->SetDefaultFlags(TracksExistFlag | TrackPanelHasFocus,
TracksExistFlag | TrackPanelHasFocus);
c->AddCommand(wxT("Toggle"), _("Toggle Focused Track"), FN(OnToggle), wxT("Return"));
c->AddCommand(wxT("ToggleAlt"), _("Toggle Focused Track"), FN(OnToggle), wxT("NUMPAD_ENTER"));
@ -1619,6 +1624,9 @@ CommandFlag AudacityProject::GetFocusedFrame()
return TopDockHasFocus;
}
if (w == mRuler)
return RulerHasFocus;
if (w == mTrackPanel) {
return TrackPanelHasFocus;
}
@ -1726,6 +1734,8 @@ CommandFlag AudacityProject::GetUpdateFlags()
flags |= TextClipFlag;
flags |= GetFocusedFrame();
if (flags & (TrackPanelHasFocus | RulerHasFocus))
flags |= TrackPanelOrRulerHasFocus;
double start, end;
GetPlayRegion(&start, &end);
@ -2681,9 +2691,13 @@ void AudacityProject::NextFrame()
switch( GetFocusedFrame() )
{
case TopDockHasFocus:
mTrackPanel->SetFocus();
if(mTrackPanel->GetFocusedTrack())
mTrackPanel->SetFocus();
else
mRuler->SetFocus();
break;
case RulerHasFocus:
case TrackPanelHasFocus:
mToolManager->GetBotDock()->SetFocus();
break;
@ -2706,11 +2720,15 @@ void AudacityProject::PrevFrame()
break;
case TrackPanelHasFocus:
case RulerHasFocus:
mToolManager->GetTopDock()->SetFocus();
break;
case BotDockHasFocus:
mTrackPanel->SetFocus();
if(mTrackPanel->GetFocusedTrack())
mTrackPanel->SetFocus();
else
mRuler->SetFocus();
break;
default:

View File

@ -2161,9 +2161,11 @@ void AudacityProject::OnActivate(wxActivateEvent & event)
mLastFocusedWindow->SetFocus();
}
else {
if (mTrackPanel) {
if (mTrackPanel->GetFocusedTrack()) {
mTrackPanel->SetFocus();
}
else
mRuler->SetFocus();
}
// No longer need to remember the last focused window
mLastFocusedWindow = NULL;

View File

@ -7237,46 +7237,49 @@ void TrackPanel::UpdateVRulerSize()
/// TrackPanel::OnNextTrack.
void TrackPanel::OnPrevTrack( bool shift )
{
TrackListIterator iter( mTracks );
Track* t = GetFocusedTrack();
if( t == NULL ) // if there isn't one, focus on last
bool rulerFocus = mRuler->HasFocus();
bool stealFocus = (mCircularTrackNavigation && rulerFocus);
if(stealFocus) // if there isn't one, focus on last
{
t = iter.Last();
if(rulerFocus) {
this->SetFocus();
mRuler->Refresh();
}
TrackListIterator iter( mTracks );
auto t = iter.Last();
SetFocusedTrack( t );
EnsureVisible( t );
MakeParentModifyState(false);
return;
}
else if (rulerFocus) {
// JKC: wxBell() is probably for accessibility, so a blind
// user knows they were at the top track.
wxBell();
return;
}
Track* t = GetFocusedTrack();
Track* p = mTracks->GetPrev( t, true ); // Get previous track
if (!p) {
SetFocusedTrack(nullptr);
mRuler->SetFocus();
Refresh(false);
mRuler->Refresh();
return;
}
Track* p = NULL;
bool tSelected = false;
bool pSelected = false;
if( shift )
{
p = mTracks->GetPrev( t, true ); // Get previous track
if( p == NULL ) // On first track
{
// JKC: wxBell() is probably for accessibility, so a blind
// user knows they were at the top track.
wxBell();
if( mCircularTrackNavigation )
{
TrackListIterator iter( mTracks );
p = iter.Last();
}
else
{
EnsureVisible( t );
return;
}
}
tSelected = t->GetSelected();
if (p)
pSelected = p->GetSelected();
if( tSelected && pSelected )
{
mTracks->Select( t, false );
SetFocusedTrack( p ); // move focus to next track down
SetFocusedTrack( p ); // move focus to next track up
EnsureVisible( p );
MakeParentModifyState(false);
return;
@ -7284,7 +7287,7 @@ void TrackPanel::OnPrevTrack( bool shift )
if( tSelected && !pSelected )
{
mTracks->Select( p, true );
SetFocusedTrack( p ); // move focus to next track down
SetFocusedTrack( p ); // move focus to next track up
EnsureVisible( p );
MakeParentModifyState(false);
return;
@ -7292,7 +7295,7 @@ void TrackPanel::OnPrevTrack( bool shift )
if( !tSelected && pSelected )
{
mTracks->Select( p, false );
SetFocusedTrack( p ); // move focus to next track down
SetFocusedTrack( p ); // move focus to next track up
EnsureVisible( p );
MakeParentModifyState(false);
return;
@ -7300,7 +7303,7 @@ void TrackPanel::OnPrevTrack( bool shift )
if( !tSelected && !pSelected )
{
mTracks->Select( t, true );
SetFocusedTrack( p ); // move focus to next track down
SetFocusedTrack( p ); // move focus to next track up
EnsureVisible( p );
MakeParentModifyState(false);
return;
@ -7308,35 +7311,10 @@ void TrackPanel::OnPrevTrack( bool shift )
}
else
{
p = mTracks->GetPrev( t, true ); // Get next track
if( p == NULL ) // On last track so stay there?
{
wxBell();
if( mCircularTrackNavigation )
{
TrackListIterator iter( mTracks );
for( Track *d = iter.First(); d; d = iter.Next( true ) )
{
p = d;
}
SetFocusedTrack( p ); // Wrap to the first track
EnsureVisible( p );
MakeParentModifyState(false);
return;
}
else
{
EnsureVisible( t );
return;
}
}
else
{
SetFocusedTrack( p ); // move focus to next track down
EnsureVisible( p );
MakeParentModifyState(false);
return;
}
SetFocusedTrack( p ); // move focus to next track up
EnsureVisible( p );
MakeParentModifyState(false);
return;
}
}
@ -7345,37 +7323,46 @@ void TrackPanel::OnPrevTrack( bool shift )
/// block or not.
void TrackPanel::OnNextTrack( bool shift )
{
if(mRuler->HasFocus()) {
TrackListIterator iter(mTracks);
auto first = iter.First();
if(first != nullptr) {
// Steal focus
this->SetFocus();
SetFocusedTrack(first);
EnsureVisible(first);
MakeParentModifyState(false);
mRuler->Refresh();
}
return;
}
Track *t;
Track *n;
TrackListIterator iter( mTracks );
bool tSelected,nSelected;
bool tSelected, nSelected;
t = GetFocusedTrack(); // Get currently focused track
if( t == NULL ) // if there isn't one, focus on first
bool surrenderFocus =
t == nullptr ||
((n = mTracks->GetNext( t, true )) == nullptr &&
mCircularTrackNavigation);
if( surrenderFocus ) // if there is no next, give focus to the ruler
{
t = iter.First();
SetFocusedTrack( t );
EnsureVisible( t );
MakeParentModifyState(false);
SetFocusedTrack(nullptr);
mRuler->SetFocus();
mRuler->Refresh();
Refresh(false);
return;
}
if( shift )
{
n = mTracks->GetNext( t, true ); // Get next track
if( n == NULL ) // On last track so stay there
{
wxBell();
if( mCircularTrackNavigation )
{
TrackListIterator iter( mTracks );
n = iter.First();
}
else
{
EnsureVisible( t );
return;
}
EnsureVisible( t );
return;
}
tSelected = t->GetSelected();
nSelected = n->GetSelected();
@ -7414,24 +7401,11 @@ void TrackPanel::OnNextTrack( bool shift )
}
else
{
n = mTracks->GetNext( t, true ); // Get next track
if( n == NULL ) // On last track so stay there
{
wxBell();
if( mCircularTrackNavigation )
{
TrackListIterator iter( mTracks );
n = iter.First();
SetFocusedTrack( n ); // Wrap to the first track
EnsureVisible( n );
MakeParentModifyState(false);
return;
}
else
{
EnsureVisible( t );
return;
}
EnsureVisible( t );
return;
}
else
{
@ -7445,26 +7419,25 @@ void TrackPanel::OnNextTrack( bool shift )
void TrackPanel::OnFirstTrack()
{
Track *t = GetFocusedTrack();
if (!t)
return;
TrackListIterator iter(mTracks);
Track *f = iter.First();
if (t != f)
{
SetFocusedTrack(f);
MakeParentModifyState(false);
SetFocusedTrack(nullptr);
if (!mRuler->HasFocus()) {
mRuler->SetFocus();
mRuler->Refresh();
}
EnsureVisible(f);
}
void TrackPanel::OnLastTrack()
{
Track *t = GetFocusedTrack();
if (!t)
if (mTracks->empty()) {
OnFirstTrack();
return;
}
else if(mRuler->HasFocus()) {
this->SetFocus();
mRuler->Refresh();
}
Track *t = GetFocusedTrack();
TrackListIterator iter(mTracks);
Track *l = iter.Last();
if (t != l)

View File

@ -46,12 +46,7 @@ TrackPanelAx::~TrackPanelAx()
// Returns currently focused track or first one if none focused
Track *TrackPanelAx::GetFocus()
{
if( !mFocusedTrack )
{
SetFocus( NULL );
}
if( !TrackNum( mFocusedTrack ) )
if( mFocusedTrack && !TrackNum( mFocusedTrack ) )
{
mFocusedTrack = NULL;
}
@ -72,12 +67,6 @@ void TrackPanelAx::SetFocus( Track *track )
}
#endif
if( track == NULL )
{
TrackListIterator iter( mTrackPanel->mTracks );
track = iter.First();
}
mFocusedTrack = track;
#if wxUSE_ACCESSIBILITY
@ -106,13 +95,8 @@ void TrackPanelAx::SetFocus( Track *track )
// Returns TRUE if passed track has the focus
bool TrackPanelAx::IsFocused( Track *track )
{
if( !mFocusedTrack )
{
SetFocus( NULL );
}
if( ( track == mFocusedTrack ) ||
( track == mFocusedTrack->GetLink() ) )
( mFocusedTrack && track == mFocusedTrack->GetLink() ) )
{
return true;
}

View File

@ -1780,6 +1780,12 @@ BEGIN_EVENT_TABLE(AdornedRulerPanel, wxPanel)
// Scrub bar menu commands
EVT_MENU(OnShowHideScrubbingID, AdornedRulerPanel::OnToggleScrubbing)
// Key events, to navigate buttons
EVT_KEY_DOWN(AdornedRulerPanel::OnKeyDown)
EVT_SET_FOCUS(AdornedRulerPanel::OnSetFocus)
EVT_KILL_FOCUS(AdornedRulerPanel::OnKillFocus)
END_EVENT_TABLE()
AdornedRulerPanel::AdornedRulerPanel(AudacityProject* parent,
@ -2075,6 +2081,12 @@ enum : int {
TopMargin = 1,
BottomMargin = 2, // for bottom bevel and bottom line
LeftMargin = 1,
FocusBorder = 2,
FocusBorderLeft = FocusBorder,
FocusBorderTop = FocusBorder,
FocusBorderBottom = FocusBorder + 1, // count 1 for the black stroke
RightMargin = 1,
};
@ -2742,6 +2754,37 @@ void AdornedRulerPanel::OnToggleScrubbing(wxCommandEvent&)
PostSizeEventToParent();
}
void AdornedRulerPanel::OnKeyDown(wxKeyEvent &event)
{
switch (event.GetKeyCode())
{
case WXK_DOWN:
case WXK_NUMPAD_DOWN:
// Always takes our focus away, so redraw.
mProject->GetTrackPanel()->OnNextTrack();
break;
case WXK_UP:
case WXK_NUMPAD_UP:
mProject->GetTrackPanel()->OnPrevTrack();
break;
default:
break;
}
}
void AdornedRulerPanel::OnSetFocus(wxFocusEvent & WXUNUSED(event))
{
mProject->GetTrackPanel()->SetFocusedTrack(nullptr);
Refresh( false );
}
void AdornedRulerPanel::OnKillFocus(wxFocusEvent & WXUNUSED(event))
{
Refresh( false );
}
void AdornedRulerPanel::OnCaptureLost(wxMouseCaptureLostEvent & WXUNUSED(evt))
{
DrawQuickPlayIndicator(NULL);
@ -2957,8 +3000,11 @@ wxRect AdornedRulerPanel::GetButtonAreaRect(bool includeBorder) const
if(includeBorder)
x = 0, y = 0, bottomMargin = 0;
else
x = LeftMargin, y = TopMargin, bottomMargin = BottomMargin;
else {
x = std::max(LeftMargin, FocusBorderLeft);
y = std::max(TopMargin, FocusBorderTop);
bottomMargin = std::max(BottomMargin, FocusBorderBottom);
}
wxRect rect {
x, y,
@ -3262,16 +3308,35 @@ void AdornedRulerPanel::DoDrawBackground(wxDC * dc)
void AdornedRulerPanel::DoDrawEdge(wxDC *dc)
{
wxRect r = mOuter;
r.width -= RightMargin;
r.height -= BottomMargin;
AColor::BevelTrackInfo( *dc, true, r );
if (HasFocus()) {
dc->SetBrush(*wxTRANSPARENT_BRUSH);
wxRect rect{ mOuter };
--rect.height; // Leave room for the black stroke
AColor::TrackFocusPen(dc, 1);
dc->DrawRectangle(rect);
AColor::TrackFocusPen(dc, 0);
rect.Deflate(1, 1);
dc->DrawRectangle(rect);
static_assert(FocusBorder == 2, "Draws the wrong number of rectangles");
}
else {
wxRect r = mOuter;
r.width -= RightMargin;
r.height -= BottomMargin;
AColor::BevelTrackInfo( *dc, true, r );
}
// Black stroke at bottom
dc->SetPen( *wxBLACK_PEN );
dc->DrawLine( mOuter.x,
mOuter.y + mOuter.height - 1,
mOuter.x + mOuter.width,
mOuter.y + mOuter.height - 1 );
mOuter.y + mOuter.height - 1,
mOuter.x + mOuter.width,
mOuter.y + mOuter.height - 1 );
static_assert(FocusBorderBottom == 1 + FocusBorder, "Button area might be wrong");
}
void AdornedRulerPanel::DoDrawMarks(wxDC * dc, bool /*text */ )

View File

@ -291,8 +291,6 @@ public:
~AdornedRulerPanel();
bool AcceptsFocus() const override { return false; };
public:
static int GetRulerHeight();
static int GetRulerHeight(bool showScrubBar);
@ -471,6 +469,10 @@ private:
void OnToggleScrubbing(wxCommandEvent&);
void OnKeyDown(wxKeyEvent &event);
void OnSetFocus(wxFocusEvent &);
void OnKillFocus(wxFocusEvent &);
bool mPlayRegionDragsSelection;
bool mTimelineToolTip;
bool mQuickPlayEnabled;