1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-06 07:09:39 +02:00

Merge branch 'master' into scrubbing

This commit is contained in:
Paul Licameli 2016-05-14 05:45:47 -04:00
commit 28e1e6303f
7 changed files with 99 additions and 75 deletions

View File

@ -191,7 +191,7 @@ def build(bld):
defines = ['SUIL_SHARED', 'SUIL_INTERNAL'],
install_path = module_dir,
cflags = cflags,
lib = modlib,
lib = modlib + ['X11'],
linkflags = bld.env.NODELETE_FLAGS)
autowaf.use_lib(bld, obj, 'GTK2 GTK2_X11 LV2 LV2_1_4_3')

View File

@ -928,7 +928,7 @@ void AudacityProject::CreateMenusAndCommands()
//////////////////////////////////////////////////////////////////////////
c->AddSeparator();
c->AddCheck(wxT("ScrollLeftOfZero"), _("Scroll left of zero"),
c->AddCheck(wxT("ScrollLeftOfZero"), _("Scroll le&ft of zero"),
FN(OnToggleScrollLeftOfZero),
gPrefs->ReadBool(
TracksPrefs::ScrollingPreferenceKey(),

View File

@ -2161,11 +2161,9 @@ void AudacityProject::OnActivate(wxActivateEvent & event)
mLastFocusedWindow->SetFocus();
}
else {
if (mTrackPanel->GetFocusedTrack()) {
if (mTrackPanel) {
mTrackPanel->SetFocus();
}
else
mRuler->SetFocus();
}
// No longer need to remember the last focused window
mLastFocusedWindow = NULL;
@ -2418,8 +2416,10 @@ void AudacityProject::OnCloseWindow(wxCloseEvent & event)
&mViewInfo);
Destroy();
mRuler = nullptr;
mIsBeingDeleted = true;
}
void AudacityProject::OnOpenAudioFile(wxCommandEvent & event)

View File

@ -13,17 +13,12 @@
#if defined(USE_LV2)
#if defined(__WXMSW__)
#include <float.h>
#define isfinite _finite
#define isnan _isnan
#endif
#include <wx/button.h>
#include <wx/choice.h>
#include <wx/dcbuffer.h>
#include <wx/dialog.h>
#include <wx/dynarray.h>
#include <wx/math.h>
#include <wx/msgdlg.h>
#include <wx/sizer.h>
#include <wx/statbox.h>
@ -562,13 +557,13 @@ bool LV2Effect::SetHost(EffectHostInterface *host)
lilv_scale_points_free(points);
// Collect the value and range info
ctrl.mHasLo = !isnan(minimumVals[i]);
ctrl.mHasHi = !isnan(maximumVals[i]);
ctrl.mHasLo = !wxIsNaN(minimumVals[i]);
ctrl.mHasHi = !wxIsNaN(maximumVals[i]);
ctrl.mMin = ctrl.mHasLo ? minimumVals[i] : 0.0;
ctrl.mMax = ctrl.mHasHi ? maximumVals[i] : 1.0;
ctrl.mLo = ctrl.mMin;
ctrl.mHi = ctrl.mMax;
ctrl.mDef = !isnan(defaultValues[i]) ?
ctrl.mDef = !wxIsNaN(defaultValues[i]) ?
defaultValues[i] :
ctrl.mHasLo ?
ctrl.mLo :

View File

@ -360,7 +360,7 @@ void Scrubber::ContinueScrubbing()
const auto lastTime = gAudioIO->GetLastTimeInScrubQueue();
const auto delta = mLastScrubPosition - position.x;
const double time = viewInfo.OffsetTimeByPixels(lastTime, delta);
result = gAudioIO->EnqueueScrubByPosition(time, mMaxScrubSpeed, false);
result = gAudioIO->EnqueueScrubByPosition(time, mMaxScrubSpeed, true);
mLastScrubPosition = position.x;
}
else {
@ -667,7 +667,7 @@ Scrubber &ScrubbingOverlay::GetScrubber()
bool Scrubber::PollIsSeeking()
{
return !mDragging && (mAlwaysSeeking || ::wxGetMouseState().LeftIsDown());
return mDragging || (mAlwaysSeeking || ::wxGetMouseState().LeftIsDown());
}
void Scrubber::DoScrub(bool scroll, bool seek)

View File

@ -2339,13 +2339,30 @@ void AdornedRulerPanel::OnMouseEvents(wxMouseEvent &evt)
return;
}
const bool overButtons = GetButtonAreaRect(true).Contains(evt.GetPosition());
auto button = FindButton(evt).button;
const auto position = evt.GetPosition();
const bool overButtons = GetButtonAreaRect(true).Contains(position);
StatusChoice button;
{
auto mouseState = FindButton(evt);
button = mouseState.button;
if (IsButton(button)) {
TabState newState{ button, mouseState.state == PointerState::InArrow };
if (mTabState != newState) {
// Change the button highlight
mTabState = newState;
Refresh(false);
}
}
else if(evt.Leaving() && !HasFocus())
// erase the button highlight
Refresh(false);
}
const bool inScrubZone = !overButtons &&
// only if scrubbing is allowed now
mProject->GetScrubber().CanScrub() &&
mShowScrubbing &&
mScrubZone.Contains(evt.GetPosition());
mScrubZone.Contains(position);
const StatusChoice zone =
evt.Leaving()
? StatusChoice::Leaving
@ -2353,7 +2370,7 @@ void AdornedRulerPanel::OnMouseEvents(wxMouseEvent &evt)
? button
: inScrubZone
? StatusChoice::EnteringScrubZone
: mInner.Contains(evt.GetPosition())
: mInner.Contains(position)
? StatusChoice::EnteringQP
: StatusChoice::NoChange;
const bool changeInZone = (zone != mPrevZone);
@ -2457,16 +2474,9 @@ void AdornedRulerPanel::OnMouseEvents(wxMouseEvent &evt)
HandlePushbuttonClick(evt);
// Handle popup menus
else if (!HasCapture() && evt.RightDown() && !(evt.LeftIsDown())) {
if(inScrubZone)
ShowScrubMenu(evt.GetPosition());
else
ShowMenu(evt.GetPosition());
// dismiss and clear Quick-Play indicator
HideQuickPlayIndicator();
if (HasCapture())
ReleaseMouse();
ShowButtonMenu
(inScrubZone ? StatusChoice::ScrubBarButton : StatusChoice::QuickPlayButton,
&position);
return;
}
else if (!HasCapture() && inScrubZone) {
@ -3250,8 +3260,11 @@ void AdornedRulerPanel::ToggleButtonState( StatusChoice button )
UpdateStatusBarAndTooltips(mCaptureState.button);
}
void AdornedRulerPanel::ShowButtonMenu( StatusChoice button, wxPoint *pPosition)
void AdornedRulerPanel::ShowButtonMenu( StatusChoice button, const wxPoint *pPosition)
{
if (!IsButton(button))
return;
wxPoint position;
if(pPosition)
position = *pPosition;
@ -3261,17 +3274,31 @@ void AdornedRulerPanel::ShowButtonMenu( StatusChoice button, wxPoint *pPosition)
position = { rect.GetLeft() + 1, rect.GetBottom() + 1 };
}
switch (button) {
case StatusChoice::QuickPlayButton:
ShowMenu(position); break;
case StatusChoice::ScrubBarButton:
ShowScrubMenu(position); break;
default:
return;
}
// Be sure the arrow button appears pressed
mTabState = { button, true };
mShowingMenu = true;
Refresh();
// dismiss and clear Quick-Play indicator
HideQuickPlayIndicator();
// Do the rest after Refresh() takes effect
CallAfter([=]{
switch (button) {
case StatusChoice::QuickPlayButton:
ShowMenu(position); break;
case StatusChoice::ScrubBarButton:
ShowScrubMenu(position); break;
default:
return;
}
// dismiss and clear Quick-Play indicator
HideQuickPlayIndicator();
if (HasCapture())
ReleaseMouse();
mShowingMenu = false;
Refresh();
});
}
const AdornedRulerPanel::ButtonStrings AdornedRulerPanel::PushbuttonLabels
@ -3310,8 +3337,7 @@ namespace {
}
void AdornedRulerPanel::DoDrawPushbutton
(wxDC *dc, StatusChoice button, PointerState down, PointerState pointerState,
bool inSomeButton) const
(wxDC *dc, StatusChoice button, bool buttonState, bool arrowState) const
{
// Adapted from TrackInfo::DrawMuteSolo()
ADCChanger changer(dc);
@ -3325,21 +3351,20 @@ void AdornedRulerPanel::DoDrawPushbutton
// Draw borders, bevels, and backgrounds of the split sections
const bool tabHighlight =
!inSomeButton &&
mTabState.mButton == button &&
HasFocus();
(HasFocus() || rect.Contains( ScreenToClient(::wxGetMousePosition()) ));
if (tabHighlight)
arrowState = arrowState || mShowingMenu;
if (pointerState == PointerState::InArrow || (tabHighlight && mTabState.mMenu)) {
if (tabHighlight && mTabState.mMenu) {
// Draw highlighted arrow after
DrawButtonBackground(dc, textRect, (down == PointerState::In), false);
DrawButtonBackground(dc, arrowRect, (down == PointerState::InArrow), true);
DrawButtonBackground(dc, textRect, buttonState, false);
DrawButtonBackground(dc, arrowRect, arrowState, true);
}
else {
// Draw maybe highlighted text after
DrawButtonBackground(dc, arrowRect, (down == PointerState::InArrow), false);
DrawButtonBackground(
dc, textRect, (down == PointerState::In),
(pointerState == PointerState::In || (tabHighlight && !mTabState.mMenu)));
DrawButtonBackground(dc, arrowRect, arrowState, false);
DrawButtonBackground(dc, textRect, buttonState, (tabHighlight && !mTabState.mMenu));
}
// Draw the menu triangle
@ -3375,7 +3400,7 @@ void AdornedRulerPanel::DoDrawPushbutton
dc->GetTextExtent(str, &textWidth, &textHeight);
auto xx = textBev.x + (textBev.width - textWidth) / 2;
auto yy = textBev.y + (textBev.height - textHeight) / 2;
if (down == PointerState::In)
if (buttonState)
// Shift the text a bit for "down" appearance
++xx, ++yy;
dc->DrawText(str, xx, yy);
@ -3429,28 +3454,23 @@ void AdornedRulerPanel::DoDrawPushbuttons(wxDC *dc) const
AColor::MediumTrackInfo(dc, false);
dc->DrawRectangle(background);
bool inSomeButton = false;
for (auto button = StatusChoice::FirstButton; !inSomeButton && IsButton(button); ++button) {
inSomeButton = InButtonRect(button, nullptr) != PointerState::Out;
}
for (auto button = StatusChoice::FirstButton; IsButton(button); ++button) {
bool state = GetButtonState(button);
auto in = InButtonRect(button, nullptr);
auto down = PointerState::Out;
if (button == mCaptureState.button && in == mCaptureState.state) {
if (in == PointerState::In) {
// Toggle button's apparent state for mouseover
down = state ? PointerState::Out : in;
}
else if (in == PointerState::InArrow) {
// Menu arrow is not sticky
down = in;
bool buttonState = GetButtonState(button);
bool arrowState = false;
if (button == mCaptureState.button) {
auto in = InButtonRect(button, nullptr);
if (in == mCaptureState.state) {
if (in == PointerState::In) {
// Toggle button's apparent state for mouseover
buttonState = !buttonState;
}
else if (in == PointerState::InArrow) {
// Menu arrow is not sticky
arrowState = true;
}
}
}
else if (state)
down = PointerState::In;
DoDrawPushbutton(dc, button, down, in, inSomeButton);
DoDrawPushbutton(dc, button, buttonState, arrowState);
}
}

View File

@ -410,9 +410,9 @@ private:
CaptureState FindButton( wxMouseEvent &mouseEvent ) const;
bool GetButtonState( StatusChoice button ) const;
void ToggleButtonState( StatusChoice button );
void ShowButtonMenu( StatusChoice button, wxPoint *pPosition);
void DoDrawPushbutton(wxDC *dc, StatusChoice button, PointerState down,
PointerState pointerState, bool inSomeButton) const;
void ShowButtonMenu( StatusChoice button, const wxPoint *pPosition);
void DoDrawPushbutton
(wxDC *dc, StatusChoice button, bool buttonState, bool arrowState) const;
void DoDrawPushbuttons(wxDC *dc) const;
void HandlePushbuttonClick(wxMouseEvent &evt);
void HandlePushbuttonEvent(wxMouseEvent &evt);
@ -505,6 +505,14 @@ private:
StatusChoice mButton { StatusChoice::FirstButton };
bool mMenu { false };
TabState() {}
TabState(StatusChoice button, bool menu)
: mButton{ button }, mMenu{ menu } {}
bool operator == (const TabState &rhs) const
{ return mButton == rhs.mButton && mMenu == rhs.mMenu; }
bool operator != (const TabState &rhs) const { return !(*this == rhs); }
TabState &operator ++ () {
if (!mMenu)
mMenu = true;
@ -535,6 +543,7 @@ private:
mutable wxFont mButtonFont;
bool mDoubleClick {};
bool mShowingMenu {};
DECLARE_EVENT_TABLE()