mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-30 15:18:42 +02:00
Refactor note track rendering/position height code into own class
This will make later refactoring easier, and also fixes some const-correctness issues
This commit is contained in:
parent
3b312f9d1b
commit
8e8d838a08
@ -214,9 +214,11 @@ double NoteTrack::GetEndTime() const
|
|||||||
void NoteTrack::DoSetHeight(int h)
|
void NoteTrack::DoSetHeight(int h)
|
||||||
{
|
{
|
||||||
auto oldHeight = GetHeight();
|
auto oldHeight = GetHeight();
|
||||||
auto oldMargin = GetNoteMargin(oldHeight);
|
NoteTrackDisplayData oldData = NoteTrackDisplayData(this, wxRect(0, 0, 1, oldHeight));
|
||||||
|
auto oldMargin = oldData.GetNoteMargin();
|
||||||
PlayableTrack::DoSetHeight(h);
|
PlayableTrack::DoSetHeight(h);
|
||||||
auto margin = GetNoteMargin(h);
|
NoteTrackDisplayData newData = NoteTrackDisplayData(this, wxRect(0, 0, 1, h));
|
||||||
|
auto margin = newData.GetNoteMargin();
|
||||||
Zoom(
|
Zoom(
|
||||||
wxRect{ 0, 0, 1, h }, // only height matters
|
wxRect{ 0, 0, 1, h }, // only height matters
|
||||||
h - margin - 1, // preserve bottom note
|
h - margin - 1, // preserve bottom note
|
||||||
@ -979,17 +981,17 @@ void NoteTrack::Zoom(const wxRect &rect, int y, float multiplier, bool center)
|
|||||||
// Construct track rectangle to map pitch to screen coordinates
|
// Construct track rectangle to map pitch to screen coordinates
|
||||||
// Only y and height are needed:
|
// Only y and height are needed:
|
||||||
wxRect trackRect(0, rect.GetY(), 1, rect.GetHeight());
|
wxRect trackRect(0, rect.GetY(), 1, rect.GetHeight());
|
||||||
PrepareIPitchToY(trackRect);
|
NoteTrackDisplayData data = NoteTrackDisplayData(this, trackRect);
|
||||||
int clickedPitch = YToIPitch(y);
|
int clickedPitch = data.YToIPitch(y);
|
||||||
// zoom by changing the pitch height
|
// zoom by changing the pitch height
|
||||||
SetPitchHeight(rect.height, mPitchHeight * multiplier);
|
SetPitchHeight(rect.height, mPitchHeight * multiplier);
|
||||||
PrepareIPitchToY(trackRect); // update because mPitchHeight changed
|
NoteTrackDisplayData newData = NoteTrackDisplayData(this, trackRect); // update because mPitchHeight changed
|
||||||
if (center) {
|
if (center) {
|
||||||
int newCenterPitch = YToIPitch(rect.GetY() + rect.GetHeight() / 2);
|
int newCenterPitch = newData.YToIPitch(rect.GetY() + rect.GetHeight() / 2);
|
||||||
// center the pitch that the user clicked on
|
// center the pitch that the user clicked on
|
||||||
SetBottomNote(mBottomNote + (clickedPitch - newCenterPitch));
|
SetBottomNote(mBottomNote + (clickedPitch - newCenterPitch));
|
||||||
} else {
|
} else {
|
||||||
int newClickedPitch = YToIPitch(y);
|
int newClickedPitch = newData.YToIPitch(y);
|
||||||
// align to keep the pitch that the user clicked on in the same place
|
// align to keep the pitch that the user clicked on in the same place
|
||||||
SetBottomNote(mBottomNote + (clickedPitch - newClickedPitch));
|
SetBottomNote(mBottomNote + (clickedPitch - newClickedPitch));
|
||||||
}
|
}
|
||||||
@ -999,9 +1001,9 @@ void NoteTrack::Zoom(const wxRect &rect, int y, float multiplier, bool center)
|
|||||||
void NoteTrack::ZoomTo(const wxRect &rect, int start, int end)
|
void NoteTrack::ZoomTo(const wxRect &rect, int start, int end)
|
||||||
{
|
{
|
||||||
wxRect trackRect(0, rect.GetY(), 1, rect.GetHeight());
|
wxRect trackRect(0, rect.GetY(), 1, rect.GetHeight());
|
||||||
PrepareIPitchToY(trackRect);
|
NoteTrackDisplayData data = NoteTrackDisplayData(this, trackRect);
|
||||||
int topPitch = YToIPitch(start);
|
int topPitch = data.YToIPitch(start);
|
||||||
int botPitch = YToIPitch(end);
|
int botPitch = data.YToIPitch(end);
|
||||||
if (topPitch < botPitch) { // swap
|
if (topPitch < botPitch) { // swap
|
||||||
int temp = topPitch; topPitch = botPitch; botPitch = temp;
|
int temp = topPitch; topPitch = botPitch; botPitch = temp;
|
||||||
}
|
}
|
||||||
@ -1013,7 +1015,20 @@ void NoteTrack::ZoomTo(const wxRect &rect, int start, int end)
|
|||||||
Zoom(rect, (start + end) / 2, trialPitchHeight / mPitchHeight, true);
|
Zoom(rect, (start + end) / 2, trialPitchHeight / mPitchHeight, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
int NoteTrack::YToIPitch(int y)
|
NoteTrackDisplayData::NoteTrackDisplayData(const NoteTrack* track, const wxRect &r)
|
||||||
|
{
|
||||||
|
mPitchHeight = track->mPitchHeight;
|
||||||
|
mMargin = std::min(r.height / 4, (GetPitchHeight(1) + 1) / 2);
|
||||||
|
|
||||||
|
mBottom = r.y + r.height - GetNoteMargin() - 1 - GetPitchHeight(1) +
|
||||||
|
(track->GetBottomNote() / 12) * GetOctaveHeight() +
|
||||||
|
GetNotePos(track->GetBottomNote() % 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
int NoteTrackDisplayData::IPitchToY(int p) const
|
||||||
|
{ return mBottom - (p / 12) * GetOctaveHeight() - GetNotePos(p % 12); }
|
||||||
|
|
||||||
|
int NoteTrackDisplayData::YToIPitch(int y) const
|
||||||
{
|
{
|
||||||
y = mBottom - y; // pixels above pitch 0
|
y = mBottom - y; // pixels above pitch 0
|
||||||
int octave = (y / GetOctaveHeight());
|
int octave = (y / GetOctaveHeight());
|
||||||
|
@ -64,9 +64,12 @@ using QuantizedTimeAndBeat = std::pair< double, double >;
|
|||||||
|
|
||||||
class StretchHandle;
|
class StretchHandle;
|
||||||
|
|
||||||
|
class NoteTrackDisplayData;
|
||||||
|
|
||||||
class AUDACITY_DLL_API NoteTrack final
|
class AUDACITY_DLL_API NoteTrack final
|
||||||
: public NoteTrackBase
|
: public NoteTrackBase
|
||||||
{
|
{
|
||||||
|
friend class NoteTrackDisplayData;
|
||||||
public:
|
public:
|
||||||
NoteTrack(const std::shared_ptr<DirManager> &projDirManager);
|
NoteTrack(const std::shared_ptr<DirManager> &projDirManager);
|
||||||
virtual ~NoteTrack();
|
virtual ~NoteTrack();
|
||||||
@ -145,44 +148,6 @@ class AUDACITY_DLL_API NoteTrack final
|
|||||||
/// If center is true, the result will be centered at y.
|
/// If center is true, the result will be centered at y.
|
||||||
void Zoom(const wxRect &rect, int y, float multiplier, bool center);
|
void Zoom(const wxRect &rect, int y, float multiplier, bool center);
|
||||||
void ZoomTo(const wxRect &rect, int start, int end);
|
void ZoomTo(const wxRect &rect, int start, int end);
|
||||||
int GetNoteMargin(int height) const
|
|
||||||
{ return std::min(height / 4, (GetPitchHeight(1) + 1) / 2); }
|
|
||||||
int GetOctaveHeight() const { return GetPitchHeight(12) + 2; }
|
|
||||||
// call this once before a series of calls to IPitchToY(). It
|
|
||||||
// sets mBottom to offset of octave 0 so that mBottomNote
|
|
||||||
// is located at r.y + r.height - (GetNoteMargin() + 1 + GetPitchHeight())
|
|
||||||
void PrepareIPitchToY(const wxRect &r) const {
|
|
||||||
mBottom =
|
|
||||||
r.y + r.height - GetNoteMargin(r.height) - 1 - GetPitchHeight(1) +
|
|
||||||
(mBottomNote / 12) * GetOctaveHeight() +
|
|
||||||
GetNotePos(mBottomNote % 12);
|
|
||||||
}
|
|
||||||
// IPitchToY returns Y coordinate of top of pitch p
|
|
||||||
int IPitchToY(int p) const {
|
|
||||||
return mBottom - (p / 12) * GetOctaveHeight() - GetNotePos(p % 12);
|
|
||||||
}
|
|
||||||
// compute the window coordinate of the bottom of an octave: This is
|
|
||||||
// the bottom of the line separating B and C.
|
|
||||||
int GetOctaveBottom(int oct) const {
|
|
||||||
return IPitchToY(oct * 12) + GetPitchHeight(1) + 1;
|
|
||||||
}
|
|
||||||
// Y coordinate for given floating point pitch (rounded to int)
|
|
||||||
int PitchToY(double p) const {
|
|
||||||
return IPitchToY((int) (p + 0.5));
|
|
||||||
}
|
|
||||||
// Integer pitch corresponding to a Y coordinate
|
|
||||||
int YToIPitch(int y);
|
|
||||||
// map pitch class number (0-11) to pixel offset from bottom of octave
|
|
||||||
// (the bottom of the black line between B and C) to the top of the
|
|
||||||
// note. Note extra pixel separates B(11)/C(0) and E(4)/F(5).
|
|
||||||
int GetNotePos(int p) const
|
|
||||||
{ return 1 + GetPitchHeight(p + 1) + (p > 4); }
|
|
||||||
// get pixel offset to top of ith black key note
|
|
||||||
int GetBlackPos(int i) const { return GetNotePos(i * 2 + 1 + (i > 1)); }
|
|
||||||
// GetWhitePos tells where to draw lines between keys as an offset from
|
|
||||||
// GetOctaveBottom. GetWhitePos(0) returns 1, which matches the location
|
|
||||||
// of the line separating B and C
|
|
||||||
int GetWhitePos(int i) const { return 1 + (i * GetOctaveHeight()) / 7; }
|
|
||||||
void SetBottomNote(int note)
|
void SetBottomNote(int note)
|
||||||
{
|
{
|
||||||
if (note < 0)
|
if (note < 0)
|
||||||
@ -254,10 +219,11 @@ class AUDACITY_DLL_API NoteTrack final
|
|||||||
float mVelocity; // velocity offset
|
float mVelocity; // velocity offset
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// mBottom is the Y offset of pitch 0 (normally off screen)
|
|
||||||
mutable int mBottom;
|
|
||||||
int mBottomNote;
|
int mBottomNote;
|
||||||
|
#if 0
|
||||||
|
// Also unused from vertical scrolling
|
||||||
int mStartBottomNote;
|
int mStartBottomNote;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Remember continuous variation for zooming,
|
// Remember continuous variation for zooming,
|
||||||
// but it is rounded off whenever drawing:
|
// but it is rounded off whenever drawing:
|
||||||
@ -275,6 +241,47 @@ protected:
|
|||||||
std::shared_ptr<TrackVRulerControls> DoGetVRulerControls() override;
|
std::shared_ptr<TrackVRulerControls> DoGetVRulerControls() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class NoteTrackDisplayData {
|
||||||
|
private:
|
||||||
|
float mPitchHeight;
|
||||||
|
// mBottom is the Y offset of pitch 0 (normally off screen)
|
||||||
|
// Used so that mBottomNote is located at
|
||||||
|
// mY + mHeight - (GetNoteMargin() + 1 + GetPitchHeight())
|
||||||
|
int mBottom;
|
||||||
|
int mMargin;
|
||||||
|
public:
|
||||||
|
NoteTrackDisplayData(const NoteTrack* track, const wxRect &r);
|
||||||
|
|
||||||
|
int GetPitchHeight(int factor) const
|
||||||
|
{ return std::max(1, (int)(factor * mPitchHeight)); }
|
||||||
|
int GetNoteMargin() const { return mMargin; };
|
||||||
|
int GetOctaveHeight() const { return GetPitchHeight(12) + 2; }
|
||||||
|
// IPitchToY returns Y coordinate of top of pitch p
|
||||||
|
int IPitchToY(int p) const;
|
||||||
|
// compute the window coordinate of the bottom of an octave: This is
|
||||||
|
// the bottom of the line separating B and C.
|
||||||
|
int GetOctaveBottom(int oct) const {
|
||||||
|
return IPitchToY(oct * 12) + GetPitchHeight(1) + 1;
|
||||||
|
}
|
||||||
|
// Y coordinate for given floating point pitch (rounded to int)
|
||||||
|
int PitchToY(double p) const {
|
||||||
|
return IPitchToY((int) (p + 0.5));
|
||||||
|
}
|
||||||
|
// Integer pitch corresponding to a Y coordinate
|
||||||
|
int YToIPitch(int y) const;
|
||||||
|
// map pitch class number (0-11) to pixel offset from bottom of octave
|
||||||
|
// (the bottom of the black line between B and C) to the top of the
|
||||||
|
// note. Note extra pixel separates B(11)/C(0) and E(4)/F(5).
|
||||||
|
int GetNotePos(int p) const
|
||||||
|
{ return 1 + GetPitchHeight(p + 1) + (p > 4); }
|
||||||
|
// get pixel offset to top of ith black key note
|
||||||
|
int GetBlackPos(int i) const { return GetNotePos(i * 2 + 1 + (i > 1)); }
|
||||||
|
// GetWhitePos tells where to draw lines between keys as an offset from
|
||||||
|
// GetOctaveBottom. GetWhitePos(0) returns 1, which matches the location
|
||||||
|
// of the line separating B and C
|
||||||
|
int GetWhitePos(int i) const { return 1 + (i * GetOctaveHeight()) / 7; }
|
||||||
|
};
|
||||||
|
|
||||||
#endif // USE_MIDI
|
#endif // USE_MIDI
|
||||||
|
|
||||||
#ifndef SONIFY
|
#ifndef SONIFY
|
||||||
|
@ -138,36 +138,6 @@ namespace {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_MIDI
|
|
||||||
/*
|
|
||||||
const int octaveHeight = 62;
|
|
||||||
const int blackPos[5] = { 6, 16, 32, 42, 52 };
|
|
||||||
const int whitePos[7] = { 0, 9, 17, 26, 35, 44, 53 };
|
|
||||||
const int notePos[12] = { 1, 6, 11, 16, 21, 27,
|
|
||||||
32, 37, 42, 47, 52, 57 };
|
|
||||||
|
|
||||||
// map pitch number to window coordinate of the *top* of the note
|
|
||||||
// Note the "free" variable bottom, which is assumed to be a local
|
|
||||||
// variable set to the offset of pitch 0 relative to the window
|
|
||||||
#define IPITCH_TO_Y(t, p) (bottom - ((p) / 12) * octaveHeight - \
|
|
||||||
notePos[(p) % 12] - (t)->GetPitchHeight())
|
|
||||||
|
|
||||||
// GetBottom is called from a couple of places to compute the hypothetical
|
|
||||||
// coordinate of the bottom of pitch 0 in window coordinates. See
|
|
||||||
// IPITCH_TO_Y above, which computes coordinates relative to GetBottom()
|
|
||||||
// Note the -NOTE_MARGIN, which leaves a little margin to draw notes that
|
|
||||||
// are out of bounds. I'm not sure why the -2 is necessary.
|
|
||||||
int TrackArt::GetBottom(NoteTrack *t, const wxRect &rect)
|
|
||||||
{
|
|
||||||
int bottomNote = t->GetBottomNote();
|
|
||||||
int bottom = rect.y + rect.height - 2 - t->GetNoteMargin() +
|
|
||||||
((bottomNote / 12) * octaveHeight + notePos[bottomNote % 12]);
|
|
||||||
return bottom;
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
#endif // USE_MIDI
|
|
||||||
|
|
||||||
TrackArtist::TrackArtist( TrackPanel *parent_ )
|
TrackArtist::TrackArtist( TrackPanel *parent_ )
|
||||||
: parent( parent_ )
|
: parent( parent_ )
|
||||||
{
|
{
|
||||||
@ -549,8 +519,7 @@ void TrackArt::DrawVRuler
|
|||||||
rect.y += 1;
|
rect.y += 1;
|
||||||
rect.height -= 1;
|
rect.height -= 1;
|
||||||
|
|
||||||
//int bottom = GetBottom(track, rect);
|
NoteTrackDisplayData data = NoteTrackDisplayData(track, rect);
|
||||||
track->PrepareIPitchToY(rect);
|
|
||||||
|
|
||||||
wxPen hilitePen;
|
wxPen hilitePen;
|
||||||
hilitePen.SetColour(120, 120, 120);
|
hilitePen.SetColour(120, 120, 120);
|
||||||
@ -568,13 +537,13 @@ void TrackArt::DrawVRuler
|
|||||||
dc->SetFont(labelFont);
|
dc->SetFont(labelFont);
|
||||||
|
|
||||||
int octave = 0;
|
int octave = 0;
|
||||||
int obottom = track->GetOctaveBottom(octave);
|
int obottom = data.GetOctaveBottom(octave);
|
||||||
int marg = track->GetNoteMargin(rect.height);
|
int marg = data.GetNoteMargin();
|
||||||
//IPITCH_TO_Y(octave * 12) + PITCH_HEIGHT + 1;
|
|
||||||
while (obottom >= rect.y) {
|
while (obottom >= rect.y) {
|
||||||
dc->SetPen(*wxBLACK_PEN);
|
dc->SetPen(*wxBLACK_PEN);
|
||||||
for (int white = 0; white < 7; white++) {
|
for (int white = 0; white < 7; white++) {
|
||||||
int pos = track->GetWhitePos(white);
|
int pos = data.GetWhitePos(white);
|
||||||
if (obottom - pos > rect.y + marg + 1 &&
|
if (obottom - pos > rect.y + marg + 1 &&
|
||||||
// don't draw too close to margin line -- it's annoying
|
// don't draw too close to margin line -- it's annoying
|
||||||
obottom - pos < rect.y + rect.height - marg - 3)
|
obottom - pos < rect.y + rect.height - marg - 3)
|
||||||
@ -582,11 +551,11 @@ void TrackArt::DrawVRuler
|
|||||||
rect.x + rect.width, obottom - pos);
|
rect.x + rect.width, obottom - pos);
|
||||||
}
|
}
|
||||||
wxRect br = rect;
|
wxRect br = rect;
|
||||||
br.height = track->GetPitchHeight(1);
|
br.height = data.GetPitchHeight(1);
|
||||||
br.x++;
|
br.x++;
|
||||||
br.width = 17;
|
br.width = 17;
|
||||||
for (int black = 0; black < 5; black++) {
|
for (int black = 0; black < 5; black++) {
|
||||||
br.y = obottom - track->GetBlackPos(black);
|
br.y = obottom - data.GetBlackPos(black);
|
||||||
if (br.y > rect.y + marg - 2 && br.y + br.height < rect.y + rect.height - marg) {
|
if (br.y > rect.y + marg - 2 && br.y + br.height < rect.y + rect.height - marg) {
|
||||||
dc->SetPen(hilitePen);
|
dc->SetPen(hilitePen);
|
||||||
dc->DrawRectangle(br);
|
dc->DrawRectangle(br);
|
||||||
@ -614,7 +583,7 @@ void TrackArt::DrawVRuler
|
|||||||
obottom - height + 2);
|
obottom - height + 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
obottom = track->GetOctaveBottom(++octave);
|
obottom = data.GetOctaveBottom(++octave);
|
||||||
}
|
}
|
||||||
// draw lines delineating the out-of-bounds margins
|
// draw lines delineating the out-of-bounds margins
|
||||||
dc->SetPen(*wxBLACK_PEN);
|
dc->SetPen(*wxBLACK_PEN);
|
||||||
@ -2844,16 +2813,17 @@ void TrackArt::DrawNoteBackground(TrackPanelDrawingContext &context,
|
|||||||
// need overlap between MIDI data and the background region
|
// need overlap between MIDI data and the background region
|
||||||
if (left >= right) return;
|
if (left >= right) return;
|
||||||
|
|
||||||
|
NoteTrackDisplayData data = NoteTrackDisplayData(track, rect);
|
||||||
dc.SetBrush(bb);
|
dc.SetBrush(bb);
|
||||||
int octave = 0;
|
int octave = 0;
|
||||||
// obottom is the window coordinate of octave divider line
|
// obottom is the window coordinate of octave divider line
|
||||||
int obottom = track->GetOctaveBottom(octave);
|
int obottom = data.GetOctaveBottom(octave);
|
||||||
// eOffset is for the line between E and F; there's another line
|
// eOffset is for the line between E and F; there's another line
|
||||||
// between B and C, hence the offset of 2 for two line thicknesses
|
// between B and C, hence the offset of 2 for two line thicknesses
|
||||||
int eOffset = track->GetPitchHeight(5) + 2;
|
int eOffset = data.GetPitchHeight(5) + 2;
|
||||||
while (obottom > rect.y + track->GetNoteMargin(rect.height) + 3) {
|
while (obottom > rect.y + data.GetNoteMargin() + 3) {
|
||||||
// draw a black line separating octaves if this octave botton is visible
|
// draw a black line separating octaves if this octave botton is visible
|
||||||
if (obottom < rect.y + rect.height - track->GetNoteMargin(rect.height)) {
|
if (obottom < rect.y + rect.height - data.GetNoteMargin()) {
|
||||||
dc.SetPen(*wxBLACK_PEN);
|
dc.SetPen(*wxBLACK_PEN);
|
||||||
// obottom - 1 because obottom is at the bottom of the line
|
// obottom - 1 because obottom is at the bottom of the line
|
||||||
AColor::Line(dc, left, obottom - 1, right, obottom - 1);
|
AColor::Line(dc, left, obottom - 1, right, obottom - 1);
|
||||||
@ -2869,14 +2839,14 @@ void TrackArt::DrawNoteBackground(TrackPanelDrawingContext &context,
|
|||||||
wxRect br;
|
wxRect br;
|
||||||
br.x = left;
|
br.x = left;
|
||||||
br.width = right - left;
|
br.width = right - left;
|
||||||
br.height = track->GetPitchHeight(1);
|
br.height = data.GetPitchHeight(1);
|
||||||
for (int black = 0; black < 5; black++) {
|
for (int black = 0; black < 5; black++) {
|
||||||
br.y = obottom - track->GetBlackPos(black);
|
br.y = obottom - data.GetBlackPos(black);
|
||||||
if (br.y > rect.y && br.y + br.height < rect.y + rect.height) {
|
if (br.y > rect.y && br.y + br.height < rect.y + rect.height) {
|
||||||
dc.DrawRectangle(br); // draw each black key background stripe
|
dc.DrawRectangle(br); // draw each black key background stripe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
obottom = track->GetOctaveBottom(++octave);
|
obottom = data.GetOctaveBottom(++octave);
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw bar lines
|
// draw bar lines
|
||||||
@ -2940,17 +2910,13 @@ void TrackArt::DrawNoteTrack(TrackPanelDrawingContext &context,
|
|||||||
if (!track->GetSelected())
|
if (!track->GetSelected())
|
||||||
sel0 = sel1 = 0.0;
|
sel0 = sel1 = 0.0;
|
||||||
|
|
||||||
|
NoteTrackDisplayData data = NoteTrackDisplayData(track, rect);
|
||||||
|
|
||||||
// reserve 1/2 note height at top and bottom of track for
|
// reserve 1/2 note height at top and bottom of track for
|
||||||
// out-of-bounds notes
|
// out-of-bounds notes
|
||||||
int numPitches = (rect.height) / track->GetPitchHeight(1);
|
int numPitches = (rect.height) / data.GetPitchHeight(1);
|
||||||
if (numPitches < 0) numPitches = 0; // cannot be negative
|
if (numPitches < 0) numPitches = 0; // cannot be negative
|
||||||
|
|
||||||
// bottom is the hypothetical location of the bottom of pitch 0 relative to
|
|
||||||
// the top of the clipping region rect: rect.height - PITCH_HEIGHT/2 is where the
|
|
||||||
// bottomNote is displayed, and to that
|
|
||||||
// we add the height of bottomNote from the position of pitch 0
|
|
||||||
track->PrepareIPitchToY(rect);
|
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_NOTETRACK_OVERLAY
|
#ifdef EXPERIMENTAL_NOTETRACK_OVERLAY
|
||||||
DrawBackgroundWithSelection(context, rect, track,
|
DrawBackgroundWithSelection(context, rect, track,
|
||||||
AColor::labelSelectedBrush, AColor::labelUnselectedBrush);
|
AColor::labelSelectedBrush, AColor::labelUnselectedBrush);
|
||||||
@ -3005,7 +2971,7 @@ void TrackArt::DrawNoteTrack(TrackPanelDrawingContext &context,
|
|||||||
selectedBarLinePen);
|
selectedBarLinePen);
|
||||||
SonifyEndNoteBackground();
|
SonifyEndNoteBackground();
|
||||||
SonifyBeginNoteForeground();
|
SonifyBeginNoteForeground();
|
||||||
int marg = track->GetNoteMargin(rect.height);
|
int marg = data.GetNoteMargin();
|
||||||
|
|
||||||
// NOTE: it would be better to put this in some global initialization
|
// NOTE: it would be better to put this in some global initialization
|
||||||
// function rather than do lookups every time.
|
// function rather than do lookups every time.
|
||||||
@ -3051,8 +3017,8 @@ void TrackArt::DrawNoteTrack(TrackPanelDrawingContext &context,
|
|||||||
const char *shape = NULL;
|
const char *shape = NULL;
|
||||||
if (note->loud > 0.0 || 0 == (shape = IsShape(note))) {
|
if (note->loud > 0.0 || 0 == (shape = IsShape(note))) {
|
||||||
wxRect nr; // "note rectangle"
|
wxRect nr; // "note rectangle"
|
||||||
nr.y = track->PitchToY(note->pitch);
|
nr.y = data.PitchToY(note->pitch);
|
||||||
nr.height = track->GetPitchHeight(1);
|
nr.height = data.GetPitchHeight(1);
|
||||||
|
|
||||||
nr.x = TIME_TO_X(xx);
|
nr.x = TIME_TO_X(xx);
|
||||||
nr.width = TIME_TO_X(x1) - nr.x;
|
nr.width = TIME_TO_X(x1) - nr.x;
|
||||||
@ -3093,7 +3059,7 @@ void TrackArt::DrawNoteTrack(TrackPanelDrawingContext &context,
|
|||||||
else
|
else
|
||||||
AColor::MIDIChannel(&dc, note->chan + 1);
|
AColor::MIDIChannel(&dc, note->chan + 1);
|
||||||
dc.DrawRectangle(nr);
|
dc.DrawRectangle(nr);
|
||||||
if (track->GetPitchHeight(1) > 2) {
|
if (data.GetPitchHeight(1) > 2) {
|
||||||
AColor::LightMIDIChannel(&dc, note->chan + 1);
|
AColor::LightMIDIChannel(&dc, note->chan + 1);
|
||||||
AColor::Line(dc, nr.x, nr.y, nr.x + nr.width-2, nr.y);
|
AColor::Line(dc, nr.x, nr.y, nr.x + nr.width-2, nr.y);
|
||||||
AColor::Line(dc, nr.x, nr.y, nr.x, nr.y + nr.height-2);
|
AColor::Line(dc, nr.x, nr.y, nr.x, nr.y + nr.height-2);
|
||||||
@ -3111,7 +3077,7 @@ void TrackArt::DrawNoteTrack(TrackPanelDrawingContext &context,
|
|||||||
// add 0.5 to pitch because pitches are plotted with
|
// add 0.5 to pitch because pitches are plotted with
|
||||||
// height = PITCH_HEIGHT; thus, the center is raised
|
// height = PITCH_HEIGHT; thus, the center is raised
|
||||||
// by PITCH_HEIGHT * 0.5
|
// by PITCH_HEIGHT * 0.5
|
||||||
int yy = track->PitchToY(note->pitch);
|
int yy = data.PitchToY(note->pitch);
|
||||||
long linecolor = LookupIntAttribute(note, linecolori, -1);
|
long linecolor = LookupIntAttribute(note, linecolori, -1);
|
||||||
long linethick = LookupIntAttribute(note, linethicki, 1);
|
long linethick = LookupIntAttribute(note, linethicki, 1);
|
||||||
long fillcolor = -1;
|
long fillcolor = -1;
|
||||||
@ -3137,7 +3103,7 @@ void TrackArt::DrawNoteTrack(TrackPanelDrawingContext &context,
|
|||||||
wxBRUSHSTYLE_SOLID));
|
wxBRUSHSTYLE_SOLID));
|
||||||
if (!fillflag) dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
if (!fillflag) dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
||||||
}
|
}
|
||||||
int y1 = track->PitchToY(LookupRealAttribute(note, y1r, note->pitch));
|
int y1 = data.PitchToY(LookupRealAttribute(note, y1r, note->pitch));
|
||||||
if (shape == line) {
|
if (shape == line) {
|
||||||
// extreme zooms caues problems under windows, so we have to do some
|
// extreme zooms caues problems under windows, so we have to do some
|
||||||
// clipping before calling display routine
|
// clipping before calling display routine
|
||||||
@ -3168,7 +3134,7 @@ void TrackArt::DrawNoteTrack(TrackPanelDrawingContext &context,
|
|||||||
points[1].y = y1;
|
points[1].y = y1;
|
||||||
points[2].x = TIME_TO_X(LookupRealAttribute(note, x2r, xx));
|
points[2].x = TIME_TO_X(LookupRealAttribute(note, x2r, xx));
|
||||||
CLIP(points[2].x);
|
CLIP(points[2].x);
|
||||||
points[2].y = track->PitchToY(LookupRealAttribute(note, y2r, note->pitch));
|
points[2].y = data.PitchToY(LookupRealAttribute(note, y2r, note->pitch));
|
||||||
dc.DrawPolygon(3, points);
|
dc.DrawPolygon(3, points);
|
||||||
} else if (shape == polygon) {
|
} else if (shape == polygon) {
|
||||||
wxPoint points[20]; // upper bound of 20 sides
|
wxPoint points[20]; // upper bound of 20 sides
|
||||||
@ -3180,7 +3146,7 @@ void TrackArt::DrawNoteTrack(TrackPanelDrawingContext &context,
|
|||||||
points[1].y = y1;
|
points[1].y = y1;
|
||||||
points[2].x = TIME_TO_X(LookupRealAttribute(note, x2r, xx));
|
points[2].x = TIME_TO_X(LookupRealAttribute(note, x2r, xx));
|
||||||
CLIP(points[2].x);
|
CLIP(points[2].x);
|
||||||
points[2].y = track->PitchToY(LookupRealAttribute(note, y2r, note->pitch));
|
points[2].y = data.PitchToY(LookupRealAttribute(note, y2r, note->pitch));
|
||||||
int n = 3;
|
int n = 3;
|
||||||
while (n < 20) {
|
while (n < 20) {
|
||||||
char name[8];
|
char name[8];
|
||||||
@ -3194,7 +3160,7 @@ void TrackArt::DrawNoteTrack(TrackPanelDrawingContext &context,
|
|||||||
attr = symbol_table.insert_string(name);
|
attr = symbol_table.insert_string(name);
|
||||||
double yn = LookupRealAttribute(note, attr, -1000000.0);
|
double yn = LookupRealAttribute(note, attr, -1000000.0);
|
||||||
if (yn == -1000000.0) break;
|
if (yn == -1000000.0) break;
|
||||||
points[n].y = track->PitchToY(yn);
|
points[n].y = data.PitchToY(yn);
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
dc.DrawPolygon(n, points);
|
dc.DrawPolygon(n, points);
|
||||||
|
@ -92,7 +92,6 @@ namespace TrackArt {
|
|||||||
const WaveTrack *track,
|
const WaveTrack *track,
|
||||||
const wxRect & rect);
|
const wxRect & rect);
|
||||||
#ifdef USE_MIDI
|
#ifdef USE_MIDI
|
||||||
int GetBottom(NoteTrack *t, const wxRect &rect);
|
|
||||||
void DrawNoteBackground(TrackPanelDrawingContext &context,
|
void DrawNoteBackground(TrackPanelDrawingContext &context,
|
||||||
const NoteTrack *track,
|
const NoteTrack *track,
|
||||||
const wxRect &rect, const wxRect &sel,
|
const wxRect &rect, const wxRect &sel,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user