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

Adds Track::IsSynchroSelected() and visuals for synchro (group) selection

This commit is contained in:
businessmanprogrammersteve 2010-02-12 16:05:02 +00:00
parent 319903dbf7
commit b646b10df2
10 changed files with 4123 additions and 8105 deletions

View File

@ -217,6 +217,8 @@ from there. Audacity will look for a file called "Pause.png".
DEFINE_IMAGE( bmpAudacityLogo, wxImage( 215, 190 ), wxT("AudacityLogo")); //vvv
DEFINE_IMAGE( bmpAudacityLogo48x48, wxImage( 48, 48 ), wxT("AudacityLogo48x48"));
DEFINE_IMAGE( bmpLinkSelect, wxImage(30, 30), wxT("LinkSelect"));
#ifdef OLD_COLOURS
DEFINE_COLOUR( clrBlank, wxColour(214, 214, 214), wxT("Blank"));
DEFINE_COLOUR( clrUnselected, wxColour(192, 192, 192), wxT("Unselected"));

View File

@ -55,6 +55,7 @@ for drawing different aspects of the label and its text box.
#include "AllThemeResources.h"
#include "AColor.h"
#include "Project.h"
#include "TrackArtist.h"
#include "commands/CommandManager.h"
#include "CaptureEvents.h"
@ -730,6 +731,11 @@ void LabelTrack::Draw(wxDC & dc, const wxRect & r, double h, double pps,
dc.SetPen(AColor::labelSelectedPen);
dc.DrawRectangle(selr);
// If selection is synchro, draw in linked graphics
if (IsSynchroSelected() && !GetSelected() && selr.width > 0) {
TrackArtist::DrawLinkTiles(&dc, selr);
}
wxRect after = r;
after.x += (before.width + selr.width);
after.width -= (before.width + selr.width);

File diff suppressed because it is too large Load Diff

View File

@ -205,6 +205,30 @@ Track *Track::GetLink() const
return NULL;
}
bool Track::IsSynchroSelected()
{
#ifdef EXPERIMENTAL_LINKING
AudacityProject *p = GetActiveProject();
if (!p || !p->IsSticky())
return false;
TrackGroupIterator git(mList);
Track *t = git.First(this);
if (!t) {
// Not in a group.
return GetSelected();
}
for (; t; t = git.Next()) {
if (t->GetSelected())
return true;
}
#endif
return false;
}
// TrackListIterator
TrackListIterator::TrackListIterator(TrackList * val)
{
@ -450,36 +474,35 @@ bool VisibleTrackIterator::Condition(Track *t)
// in which the starting track is a member.
//
TrackGroupIterator::TrackGroupIterator(TrackList * val)
: TrackListIterator(val)
: TrackListIterator(val),
mInLabelSection(false)
{
mEndOfGroup = false;
}
Track *TrackGroupIterator::First(Track * member)
{
Track *t = NULL;
// Scan forward for a label track
while (member && member->GetKind() == Track::Wave) {
member = l->GetNext(member);
// A group consists of any positive number of wave tracks followed by any
// non-negative number of label tracks. Step back through any label tracks,
// and then through the wave tracks above them.
while (member && member->GetKind() == Track::Label) {
member = l->GetPrev(member);
}
// It's not part of a group if one wasn't found
if (!member || member->GetKind() != Track::Label) {
return NULL;
}
// Find first wave track in the group
member = l->GetPrev(member);
while (member && member->GetKind() == Track::Wave) {
t = member;
member = l->GetPrev(member);
}
// Make it current
// Make it current (if t is still NULL there are no wave tracks, so we're
// not in a group).
if (t)
cur = (TrackListNode *) t->GetNode();
mInLabelSection = false;
return t;
}
@ -487,30 +510,59 @@ Track *TrackGroupIterator::Next(bool skiplinked)
{
Track *t = TrackListIterator::Next(skiplinked);
// End of the group has been reached
if (!t || mEndOfGroup) {
//
// Ways to end a group
//
// End of tracks
if (!t)
return NULL;
// In the label section, encounter a non-label track
if (mInLabelSection && t->GetKind() != Track::Label) {
cur = NULL;
return NULL;
}
// Found the end of the group, so signal for next iteration
if (t->GetKind() == Track::Label) {
mEndOfGroup = true;
// Encounter a non-wave non-label track
if (t->GetKind() != Track::Wave && t->GetKind() != Track::Label) {
cur = NULL;
return NULL;
}
// Otherwise, check if we're in the label section
mInLabelSection = (t->GetKind() == Track::Label);
return t;
}
Track *TrackGroupIterator::Prev(bool skiplinked)
{
// AWD: currently grouping as it works here allows only one label track per
// group, but this should change
Track *t = TrackListIterator::Prev(skiplinked);
if (!t || t->GetKind() != Track::Wave) {
//
// Ways to end a group in reverse
//
// Beginning of tracks
if (!t)
return NULL;
// In wave section, encounter a label track
if (!mInLabelSection && t->GetKind() == Track::Label) {
cur = NULL;
return NULL;
}
// Encounter a non-wave non-label track
if (t->GetKind() != Track::Wave && t->GetKind() != Track::Label) {
cur = NULL;
return NULL;
}
// Otherwise, check if we're in the label section
mInLabelSection = (t->GetKind() == Track::Label);
return t;
}
@ -521,7 +573,14 @@ Track *TrackGroupIterator::Last(bool skiplinked)
Track *t = cur->t;
while (!mEndOfGroup) {
while (l->GetNext(t)) {
// Check if this is the last track in the group
int nextKind = l->GetNext(t)->GetKind();
if (mInLabelSection && nextKind != Track::Label)
break;
if (nextKind != Track::Label && nextKind != Track::Wave)
break;
t = Next(skiplinked);
}
@ -543,26 +602,24 @@ Track *TrackAndGroupIterator::NextGroup(bool skiplinked)
return NULL;
Track* t = cur->t;
if (t->GetKind() == Track::Label) {
// the next group when we have a LabelTrack is the next track
return TrackListIterator::Next(skiplinked);
}
TrackGroupIterator git(l);
if (git.First(t) == NULL) {
//not part of a group
return TrackListIterator::Next(skiplinked);
}
//skip the remaining tracks of the current group
for (; t != NULL && t->GetKind() != Track::Label; t = TrackListIterator::Next(skiplinked) );
if (t) {
//Reached final Label track, let's go to the next group
while(t) {
int prevKind = t->GetKind();
t = TrackListIterator::Next(skiplinked);
}
// Check if we've exited a group
// End of tracks
if (!t)
break;
// Non-wave non-label track
if (t->GetKind() != Track::Wave && t->GetKind() != Track::Label)
break;
// From label section to non-label track
if (prevKind == Track::Label && t->GetKind() != Track::Label)
break;
}
return t;
}

View File

@ -179,6 +179,9 @@ class AUDACITY_DLL_API Track: public XMLTagHandler
virtual double GetStartTime() { return 0.0; }
virtual double GetEndTime() { return 0.0; }
// Checks if linking is on and any track in its group is selected
bool IsSynchroSelected();
};
struct TrackListNode
@ -298,7 +301,7 @@ class AUDACITY_DLL_API TrackGroupIterator: public TrackListIterator
Track *Last(bool skiplinked = false);
private:
bool mEndOfGroup;
bool mInLabelSection;
};
//

View File

@ -662,7 +662,7 @@ void TrackArtist::DrawWaveformBackground(wxDC &dc, const wxRect &r, const double
float zoomMin, float zoomMax, bool dB,
const sampleCount where[],
sampleCount ssel0, sampleCount ssel1,
bool drawEnvelope)
bool drawEnvelope, bool synchroSelection)
{
// Visually (one vertical slice of the waveform background, on its side;
// the "*" is the actual waveform background we're drawing
@ -752,6 +752,17 @@ void TrackArtist::DrawWaveformBackground(wxDC &dc, const wxRect &r, const double
dc.DrawRectangle(l, r.y + lmaxtop, w, lminbot - lmaxtop);
}
// If selection is synchro, draw in linked graphics
if (synchroSelection && ssel0 < ssel1) {
// Find the beginning/end of the selection
int begin, end;
for (x = 0; x < r.width && where[x] < ssel0; ++x);
begin = x;
for (; x < r.width && where[x] < ssel1; ++x);
end = x;
DrawLinkTiles(&dc, wxRect(r.x + begin, r.y, end - 1 - begin, r.height));
}
//OK, the display bounds are between min and max, which
//is spread across r.height. Draw the line at the proper place.
@ -1136,7 +1147,7 @@ void TrackArtist::DrawClipWaveform(WaveTrack *track,
double sps = 1./rate; //seconds-per-sample
//If the track isn't selected, make the selection empty
if (!track->GetSelected()) {
if (!track->GetSelected() && !track->IsSynchroSelected()) {
sel0 = sel1 = 0.0;
}
@ -1281,7 +1292,8 @@ void TrackArtist::DrawClipWaveform(WaveTrack *track,
// the envelope and using a colored pen for the selected
// part of the waveform
DrawWaveformBackground(dc, mid, envValues, zoomMin, zoomMax, dB,
where, ssel0, ssel1, drawEnvelope);
where, ssel0, ssel1, drawEnvelope,
!track->GetSelected());
if (!showIndividualSamples) {
DrawMinMaxRMS(dc, mid, envValues, zoomMin, zoomMax, dB,
@ -2522,7 +2534,7 @@ void TrackArtist::DrawLabelTrack(LabelTrack *track,
double sel0 = viewInfo->sel0;
double sel1 = viewInfo->sel1;
if (!track->GetSelected())
if (!track->GetSelected() && !track->IsSynchroSelected())
sel0 = sel1 = 0.0;
track->Draw(dc, r, viewInfo->h, viewInfo->zoom, sel0, sel1);
@ -2623,6 +2635,26 @@ void TrackArtist::SetSpectrumLogMaxFreq(int freq)
mLogMaxFreq = freq;
}
void TrackArtist::DrawLinkTiles(wxDC *dc, wxRect r)
{
wxBitmap sync(theTheme.Image(bmpLinkSelect));
// Draw in full-width copies
int x;
for (x = 0; x + sync.GetWidth() < r.width; x += sync.GetWidth()) {
for (int y = 0; y < r.height; y += sync.GetHeight()) {
dc->DrawBitmap(sync, r.x + x, r.y + y, true);
}
}
// Draw in partial column at end of selection
if (r.width - x > 0) {
sync = sync.GetSubBitmap(wxRect(0, 0, r.width - x, sync.GetHeight()));
for (int y = 0; y < r.height; y += sync.GetHeight()) {
dc->DrawBitmap(sync, r.x + x, r.y + y, true);
}
}
}
// Indentation settings for Vim and Emacs and unique identifier for Arch, a
// version control system. Please do not modify past this point.
//

View File

@ -91,6 +91,9 @@ class AUDACITY_DLL_API TrackArtist {
this->selectedPen = selectedPen;
}
// Helper: draws the "linked" watermark tiled to a rectangle
static void DrawLinkTiles(wxDC *dc, wxRect r);
private:
//
@ -135,7 +138,7 @@ class AUDACITY_DLL_API TrackArtist {
float zoomMin, float zoomMax, bool dB,
const sampleCount where[],
sampleCount ssel0, sampleCount ssel1,
bool drawEnvelope);
bool drawEnvelope, bool synchroSelection);
void DrawMinMaxRMS(wxDC & dc, const wxRect & r, const double env[],
float zoomMin, float zoomMax, bool dB,

View File

@ -3779,7 +3779,7 @@ void TrackPanel::HandleLabelClick(wxMouseEvent & event)
// the selection on this track.
if (event.ShiftDown()) {
mTracks->Select(t, !t->GetSelected());
RefreshTrack(t);
Refresh(false);
#ifdef EXPERIMENTAL_MIXER_BOARD
MixerBoard* pMixerBoard = this->GetMixerBoard();
if (pMixerBoard && (t->GetKind() == Track::Wave))
@ -5132,7 +5132,8 @@ void TrackPanel::DrawOutside(Track * t, wxDC * dc, const wxRect rec,
bool bIsWave = (t->GetKind() == Track::Wave);
mTrackInfo.DrawBackground(dc, r, t->GetSelected(), bIsWave, labelw, vrul);
mTrackInfo.DrawBackground(dc, r, t->GetSelected(), t->IsSynchroSelected(),
bIsWave, labelw, vrul);
DrawBordersAroundTrack(t, dc, r, labelw, vrul);
DrawShadow(t, dc, r);
@ -7235,14 +7236,19 @@ void TrackInfo::DrawBordersWithin(wxDC * dc, const wxRect r, bool bHasMuteSolo )
}
void TrackInfo::DrawBackground(wxDC * dc, const wxRect r, bool bSelected,
bool bHasMuteSolo, const int labelw, const int vrul)
bool bSyncSel, bool bHasMuteSolo, const int labelw, const int vrul)
{
// fill in label
wxRect fill = r;
fill.width = labelw-4;
AColor::MediumTrackInfo(dc, bSelected);
AColor::MediumTrackInfo(dc, bSelected || bSyncSel);
dc->DrawRectangle(fill);
// Draw in linked tiles for synchro selection
if (bSyncSel && !bSelected) {
TrackArtist::DrawLinkTiles(dc, fill);
}
if( bHasMuteSolo )
{
fill=wxRect( r.x+1, r.y+17, vrul-6, 32);
@ -7322,7 +7328,7 @@ void TrackInfo::DrawTitleBar(wxDC * dc, const wxRect r, Track * t,
// characters if they are repeatedly drawn. This
// happens when holding down mouse button and moving
// in and out of the title bar. So clear it first.
AColor::MediumTrackInfo(dc, t->GetSelected());
AColor::MediumTrackInfo(dc, t->GetSelected() || t->IsSynchroSelected());
dc->DrawRectangle(bev);
dc->DrawText(titleStr, r.x + 19, r.y + 2);
@ -7358,19 +7364,21 @@ void TrackInfo::DrawMuteSolo(wxDC * dc, const wxRect r, Track * t,
if (bev.y + bev.height >= r.y + r.height - 19)
return; // don't draw mute and solo buttons, because they don't fit into track label
AColor::MediumTrackInfo( dc, t->GetSelected() );
AColor::MediumTrackInfo( dc, t->GetSelected() || t->IsSynchroSelected());
if( solo )
{
if( t->GetSolo() )
{
AColor::Solo(dc, t->GetSolo(), t->GetSelected());
AColor::Solo(dc, t->GetSolo(),
t->GetSelected() || t->IsSynchroSelected());
}
}
else
{
if( t->GetMute() )
{
AColor::Mute(dc, t->GetMute(), t->GetSelected(), t->GetSolo());
AColor::Mute(dc, t->GetMute(),
t->GetSelected() || t->IsSynchroSelected(), t->GetSolo());
}
}
//(solo) ? AColor::Solo(dc, t->GetSolo(), t->GetSelected()) :
@ -7400,7 +7408,7 @@ void TrackInfo::DrawMinimize(wxDC * dc, const wxRect r, Track * t, bool down, bo
GetMinimizeRect(r, bev, minimized);
// Clear background to get rid of previous arrow
AColor::MediumTrackInfo(dc, t->GetSelected());
AColor::MediumTrackInfo(dc, t->GetSelected() || t->IsSynchroSelected());
dc->DrawRectangle(bev);
#ifdef EXPERIMENTAL_THEMING

View File

@ -94,7 +94,7 @@ private:
void EnsureSufficientSliders(int index);
void SetTrackInfoFont(wxDC *dc);
void DrawBackground(wxDC * dc, const wxRect r, bool bSelected, bool bHasMuteSolo, const int labelw, const int vrul);
void DrawBackground(wxDC * dc, const wxRect r, bool bSelected, bool bSyncSel, bool bHasMuteSolo, const int labelw, const int vrul);
void DrawBordersWithin(wxDC * dc, const wxRect r, bool bHasMuteSolo );
void DrawCloseBox(wxDC * dc, const wxRect r, bool down);
void DrawTitleBar(wxDC * dc, const wxRect r, Track * t, bool down);

View File

@ -247,6 +247,7 @@ void EditToolBar::OnButton(wxCommandEvent &event)
else
mButtons[ETBLinkID]->PopUp();
p->ModifyToolbarMenus();
p->GetTrackPanel()->Refresh(false);
}
return;//avoiding the call to SetButton()
#endif