1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-15 07:40:23 +02:00

Keep a constant set of gain/pan sliders -- this allows Audacity

to open projects with very large numbers of tracks without
crashes (Windows) or major slowdows.
This commit is contained in:
BusinessmanProgrammerSteve 2010-04-21 05:03:24 +00:00
parent 828481a3c8
commit db39f6262b
2 changed files with 147 additions and 23 deletions

View File

@ -157,6 +157,7 @@ is time to refresh some aspect of the screen.
#include "TrackPanel.h"
#include <math.h>
#include <stdlib.h>
//#define DEBUG_DRAW_TIMING 1
@ -1276,6 +1277,9 @@ void TrackPanel::OnPaint(wxPaintEvent & /* event */)
// (See TrackPanel::Refresh())
if( mRefreshBacking || ( box == GetRect() ) )
{
// Update visible sliders
mTrackInfo.UpdateSliderOffset(mViewInfo->track);
// Reset (should a mutex be used???)
mRefreshBacking = false;
@ -3622,9 +3626,9 @@ void TrackPanel::HandleSliders(wxMouseEvent &event, bool pan)
LWSlider *slider;
if (pan)
slider = mTrackInfo.mPans[mCapturedTrack->GetIndex()];
slider = mTrackInfo.PanSlider(mCapturedTrack->GetIndex());
else
slider = mTrackInfo.mGains[mCapturedTrack->GetIndex()];
slider = mTrackInfo.GainSlider(mCapturedTrack->GetIndex());
slider->OnMouseEvent(event);
@ -5988,7 +5992,7 @@ void TrackPanel::OnTrackPan()
return;
}
LWSlider *slider = mTrackInfo.mPans[t->GetIndex()];
LWSlider *slider = mTrackInfo.PanSlider(t->GetIndex());
if (slider->ShowDialog()) {
SetTrackPan(t, slider);
}
@ -6001,7 +6005,7 @@ void TrackPanel::OnTrackPanLeft()
return;
}
LWSlider *slider = mTrackInfo.mPans[t->GetIndex()];
LWSlider *slider = mTrackInfo.PanSlider(t->GetIndex());
slider->Decrease(1);
SetTrackPan(t, slider);
}
@ -6013,7 +6017,7 @@ void TrackPanel::OnTrackPanRight()
return;
}
LWSlider *slider = mTrackInfo.mPans[t->GetIndex()];
LWSlider *slider = mTrackInfo.PanSlider(t->GetIndex());
slider->Increase(1);
SetTrackPan(t, slider);
}
@ -6040,7 +6044,7 @@ void TrackPanel::OnTrackGain()
return;
}
LWSlider *slider = mTrackInfo.mGains[t->GetIndex()];
LWSlider *slider = mTrackInfo.GainSlider(t->GetIndex());
if (slider->ShowDialog()) {
SetTrackGain(t, slider);
}
@ -6053,7 +6057,7 @@ void TrackPanel::OnTrackGainInc()
return;
}
LWSlider *slider = mTrackInfo.mGains[t->GetIndex()];
LWSlider *slider = mTrackInfo.GainSlider(t->GetIndex());
slider->Increase(1);
SetTrackGain(t, slider);
}
@ -6065,7 +6069,7 @@ void TrackPanel::OnTrackGainDec()
return;
}
LWSlider *slider = mTrackInfo.mGains[t->GetIndex()];
LWSlider *slider = mTrackInfo.GainSlider(t->GetIndex());
slider->Decrease(1);
SetTrackGain(t, slider);
}
@ -7139,13 +7143,14 @@ void TrackPanel::OnKillFocus(wxFocusEvent & event)
TrackInfo::TrackInfo(wxWindow * pParentIn)
{
//To prevent flicker, we create an initial set of 16 sliders
//which won't ever be shown.
pParent = pParentIn;
int i;
for (i = 0; i < 16; i++) {
// Populate sliders array
for (unsigned int i = 0; i < kInitialSliders; ++i) {
MakeMoreSliders();
}
mSliderOffset = 0;
int fontSize = 10;
mFont.Create(fontSize, wxSWISS, wxNORMAL, wxNORMAL);
@ -7500,10 +7505,12 @@ void TrackInfo::MakeMoreSliders()
mPans.Add(slider);
}
// This covers the case where kInitialSliders - kSliderPageFlip is not big
// enough
void TrackInfo::EnsureSufficientSliders(int index)
{
while (mGains.Count() < (unsigned int)index+1 ||
mPans.Count() < (unsigned int)index+1)
while (mGains.Count() < (unsigned int)index - mSliderOffset + 1 ||
mPans.Count() < (unsigned int)index - mSliderOffset + 1)
MakeMoreSliders();
}
@ -7519,18 +7526,113 @@ void TrackInfo::DrawSliders(wxDC *dc, WaveTrack *t, wxRect r)
GetPanRect(r, panRect);
if (gainRect.y + gainRect.height < r.y + r.height - 19) {
mGains[index]->Move(wxPoint(gainRect.x, gainRect.y));
mGains[index]->Set(t->GetGain());
mGains[index]->OnPaint(*dc, t->GetSelected());
GainSlider(index)->Move(wxPoint(gainRect.x, gainRect.y));
GainSlider(index)->Set(t->GetGain());
GainSlider(index)->OnPaint(*dc, t->GetSelected());
}
if (panRect.y + panRect.height < r.y + r.height - 19) {
mPans[index]->Move(wxPoint(panRect.x, panRect.y));
mPans[index]->Set(t->GetPan());
mPans[index]->OnPaint(*dc, t->GetSelected());
PanSlider(index)->Move(wxPoint(panRect.x, panRect.y));
PanSlider(index)->Set(t->GetPan());
PanSlider(index)->OnPaint(*dc, t->GetSelected());
}
}
void TrackInfo::UpdateSliderOffset(Track *t)
{
if (!t)
return;
// Ensure that the specified track is: (a) at least the second track in the
// arrays (if it's the second track in a stereo pair the first must be in);
// (b) no farther in than kSliderPageFlip
int newSliderOffset = (int)mSliderOffset;
if ((unsigned int)t->GetIndex() < mSliderOffset + 1 ||
(unsigned int)t->GetIndex() > mSliderOffset + kSliderPageFlip) {
newSliderOffset = t->GetIndex() - (int)kSliderPageFlip / 2;
}
// Slider offset can't be negative
if (newSliderOffset < 0) newSliderOffset = 0;
// Rotate the array values if necessary
int delta = newSliderOffset - (int)mSliderOffset;
// If the rotation is greater than the array size, none of the old values
// are preserved, so don't bother rotating.
if (abs(delta) >= (int)mGains.Count())
delta = 0;
if (delta > 0) {
// Circularly shift values down in the arrays (temp arrays needed to
// avoid reading written-over values)
LWSliderArray tempGains;
LWSliderArray tempPans;
tempGains.SetCount(delta);
tempPans.SetCount(delta);
for (int i = 0; i < (int)mGains.Count(); ++i) {
int src = (i + delta) % (int)mGains.Count();
if (src < 0) src += (int)mGains.Count();
if (i < delta) {
// Save a copy of the first `delta` values
tempGains[i] = mGains[i];
tempPans[i] = mPans[i];
}
if (src >= delta) {
// These values have not been overwritten
mGains[i] = mGains[src];
mPans[i] = mPans[src];
}
else {
// These ones have
mGains[i] = tempGains[src];
mPans[i] = tempPans[src];
}
}
}
else if (delta < 0) {
// Circularly shift values up in the arrays
LWSliderArray tempGains;
LWSliderArray tempPans;
tempGains.SetCount(mGains.Count());
tempPans.SetCount(mPans.Count());
// Iterating backwards to do this
for (int i = mGains.Count() - 1; i >= 0; --i) {
int src = (i + delta) % (int)mGains.Count();
if (src < 0) src += (int)mGains.Count();
if (i >= (int)mGains.Count() + delta) {
// Save a copy of the last `delta` values
tempGains[i] = mGains[i];
tempPans[i] = mPans[i];
}
if (src < (int)mGains.Count() + delta) {
// These values have not been overwritten
mGains[i] = mGains[src];
mPans[i] = mPans[src];
}
else {
// These ones have
mGains[i] = tempGains[src];
mPans[i] = tempPans[src];
}
}
}
mSliderOffset = newSliderOffset;
}
LWSlider * TrackInfo::GainSlider(int trackIndex)
{
return mGains[trackIndex - mSliderOffset];
}
LWSlider * TrackInfo::PanSlider(int trackIndex)
{
return mPans[trackIndex - mSliderOffset];
}
// Indentation settings for Vim and Emacs and unique identifier for Arch, a
// version control system. Please do not modify past this point.

View File

@ -11,11 +11,11 @@
#ifndef __AUDACITY_TRACK_PANEL__
#define __AUDACITY_TRACK_PANEL__
#include <wx/dcmemory.h>
#include <wx/dynarray.h>
#include <wx/panel.h>
#include <wx/timer.h>
#include <wx/window.h>
#include <wx/panel.h>
#include <wx/dcmemory.h>
//Stm: The following included because of the sampleCount struct.
#include "Sequence.h"
@ -80,6 +80,16 @@ class AUDACITY_DLL_API TrackPanelListener {
virtual void TP_HandleResize() = 0;
};
//
// TrackInfo sliders: we keep a constant number of sliders, and attach them to
// tracks as they come on screen (this helps deal with very large numbers of
// tracks, esp. on MSW).
//
const unsigned int kInitialSliders = 100;
// kInitialSliders-kSliderPageFlipshould be around the most tracks you could
// ever fit vertically on the screen (but if more fit on that's OK too)
const unsigned int kSliderPageFlip = 80;
class TrackInfo
{
@ -89,6 +99,8 @@ public:
int GetTitleWidth() const;
void UpdateSliderOffset(Track *t);
private:
void MakeMoreSliders();
void EnsureSufficientSliders(int index);
@ -111,9 +123,19 @@ private:
void GetPanRect(const wxRect r, wxRect &dest) const;
void GetMinimizeRect(const wxRect r, wxRect &dest, bool minimized) const;
public:
// These arrays are always kept the same size.
LWSliderArray mGains;
LWSliderArray mPans;
// index of track whose pan/gain sliders are at index 0 in the above arrays
unsigned int mSliderOffset;
public:
// Slider access by track index
LWSlider * GainSlider(int trackIndex);
LWSlider * PanSlider(int trackIndex);
wxWindow * pParent;
wxFont mFont;