diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2012-01-02 04:04:14 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2012-01-02 04:04:14 +0000 |
commit | 69c7dac1a1ee70c5a4053acdc9dd139c986698a2 (patch) | |
tree | a5a13945a48d27e7ff4adf0ca916ffcab2bb0ef7 /gtk2_ardour/tempo_lines.cc | |
parent | 084fc8b3273d6daeb299773811c7d2bd0e1d5598 (diff) |
new approach to tempo/meter: compute and store the entire map (every bar|beat point), thus enabling us to use the same computation to set the BBT points AND the metric markers (tempo + meter) on the audio timeline. It is known that snapping to the BBT grid doesn't work correctly right now, but this probably caused by the separate code in TempoMap::round_to_type() and i'll dig into that tomorrow. Note that the Bar|beat point list is evaluated "lazily" - we'll never store more than anyone actually needs to display or know, other than 1 minute's worth starting from frame zero
git-svn-id: svn://localhost/ardour2/branches/3.0@11129 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour/tempo_lines.cc')
-rw-r--r-- | gtk2_ardour/tempo_lines.cc | 202 |
1 files changed, 97 insertions, 105 deletions
diff --git a/gtk2_ardour/tempo_lines.cc b/gtk2_ardour/tempo_lines.cc index 8fe877a27c..cab185026f 100644 --- a/gtk2_ardour/tempo_lines.cc +++ b/gtk2_ardour/tempo_lines.cc @@ -131,122 +131,114 @@ TempoLines::draw (ARDOUR::TempoMap::BBTPointList& points, double frames_per_unit for (i = points.begin(); i != points.end(); ++i) { - switch ((*i).type) { - case ARDOUR::TempoMap::Bar: - break; - - case ARDOUR::TempoMap::Beat: - if ((*i).beat == 1) { - color = ARDOUR_UI::config()->canvasvar_MeasureLineBar.get(); - } else { - color = ARDOUR_UI::config()->canvasvar_MeasureLineBeat.get(); - if (beat_density > 2.0) { - break; /* only draw beat lines if the gaps between beats are large. */ - } - } - - xpos = rint(((framepos_t)(*i).frame) / (double)frames_per_unit); - - if (inserted_last_time && !_lines.empty()) { - li = _lines.lower_bound(xpos); // first line >= xpos + if ((*i).type == ARDOUR::TempoMap::Bar) { + color = ARDOUR_UI::config()->canvasvar_MeasureLineBar.get(); + } else { + if (beat_density > 2.0) { + continue; /* only draw beat lines if the gaps between beats are large. */ } + color = ARDOUR_UI::config()->canvasvar_MeasureLineBeat.get(); + } - line = (li != _lines.end()) ? li->second : NULL; - assert(!line || line->property_x1() == li->first); - - Lines::iterator next = li; - if (next != _lines.end()) - ++next; - - exhausted = (next == _lines.end()); - - // Hooray, line is perfect - if (line && line->property_x1() == xpos) { - if (li != _lines.end()) - ++li; - - line->property_color_rgba() = color; - inserted_last_time = false; // don't search next time - + xpos = rint(((framepos_t)(*i).frame) / (double)frames_per_unit); + + if (inserted_last_time && !_lines.empty()) { + li = _lines.lower_bound(xpos); // first line >= xpos + } + + line = (li != _lines.end()) ? li->second : NULL; + assert(!line || line->property_x1() == li->first); + + Lines::iterator next = li; + if (next != _lines.end()) + ++next; + + exhausted = (next == _lines.end()); + + // Hooray, line is perfect + if (line && line->property_x1() == xpos) { + if (li != _lines.end()) + ++li; + + line->property_color_rgba() = color; + inserted_last_time = false; // don't search next time + // Use existing line, moving if necessary - } else if (!exhausted) { - Lines::iterator steal = _lines.end(); - --steal; - - // Steal from the right - if (left->first > needed_left && li != steal && steal->first > needed_right) { - //cout << "*** STEALING FROM RIGHT" << endl; - line = steal->second; - _lines.erase(steal); - line->property_x1() = xpos; - line->property_x2() = xpos; - line->property_color_rgba() = color; - _lines.insert(make_pair(xpos, line)); - inserted_last_time = true; // search next time - invalidated = true; - - // Shift clean range left - _clean_left = min(_clean_left, xpos); - _clean_right = min(_clean_right, steal->first); - - // Move this line to where we need it - } else { - Lines::iterator existing = _lines.find(xpos); - if (existing != _lines.end()) { - //cout << "*** EXISTING LINE" << endl; - li = existing; - li->second->property_color_rgba() = color; - inserted_last_time = false; // don't search next time - } else { - //cout << "*** MOVING LINE" << endl; - const double x1 = line->property_x1(); - const bool was_clean = x1 >= _clean_left && x1 <= _clean_right; - invalidated = invalidated || was_clean; - // Invalidate clean portion (XXX: too harsh?) - _clean_left = needed_left; - _clean_right = needed_right; - _lines.erase(li); - line->property_color_rgba() = color; - line->property_x1() = xpos; - line->property_x2() = xpos; - _lines.insert(make_pair(xpos, line)); - inserted_last_time = true; // search next time - } - } - - // Create a new line - } else if (_lines.size() < needed || _lines.size() < MAX_CACHED_LINES) { - //cout << "*** CREATING LINE" << endl; - assert(_lines.find(xpos) == _lines.end()); - line = new ArdourCanvas::SimpleLine (*_group); - line->property_x1() = xpos; - line->property_x2() = xpos; - line->property_y1() = 0.0; - line->property_y2() = _height; - line->property_color_rgba() = color; - _lines.insert(make_pair(xpos, line)); - inserted_last_time = true; - - // Steal from the left - } else { - //cout << "*** STEALING FROM LEFT" << endl; - assert(_lines.find(xpos) == _lines.end()); - Lines::iterator steal = _lines.begin(); + } else if (!exhausted) { + Lines::iterator steal = _lines.end(); + --steal; + + // Steal from the right + if (left->first > needed_left && li != steal && steal->first > needed_right) { + //cout << "*** STEALING FROM RIGHT" << endl; line = steal->second; _lines.erase(steal); - line->property_color_rgba() = color; line->property_x1() = xpos; line->property_x2() = xpos; + line->property_color_rgba() = color; _lines.insert(make_pair(xpos, line)); inserted_last_time = true; // search next time invalidated = true; - - // Shift clean range right - _clean_left = max(_clean_left, steal->first); - _clean_right = max(_clean_right, xpos); + + // Shift clean range left + _clean_left = min(_clean_left, xpos); + _clean_right = min(_clean_right, steal->first); + + // Move this line to where we need it + } else { + Lines::iterator existing = _lines.find(xpos); + if (existing != _lines.end()) { + //cout << "*** EXISTING LINE" << endl; + li = existing; + li->second->property_color_rgba() = color; + inserted_last_time = false; // don't search next time + } else { + //cout << "*** MOVING LINE" << endl; + const double x1 = line->property_x1(); + const bool was_clean = x1 >= _clean_left && x1 <= _clean_right; + invalidated = invalidated || was_clean; + // Invalidate clean portion (XXX: too harsh?) + _clean_left = needed_left; + _clean_right = needed_right; + _lines.erase(li); + line->property_color_rgba() = color; + line->property_x1() = xpos; + line->property_x2() = xpos; + _lines.insert(make_pair(xpos, line)); + inserted_last_time = true; // search next time + } } - - break; + + // Create a new line + } else if (_lines.size() < needed || _lines.size() < MAX_CACHED_LINES) { + //cout << "*** CREATING LINE" << endl; + assert(_lines.find(xpos) == _lines.end()); + line = new ArdourCanvas::SimpleLine (*_group); + line->property_x1() = xpos; + line->property_x2() = xpos; + line->property_y1() = 0.0; + line->property_y2() = _height; + line->property_color_rgba() = color; + _lines.insert(make_pair(xpos, line)); + inserted_last_time = true; + + // Steal from the left + } else { + //cout << "*** STEALING FROM LEFT" << endl; + assert(_lines.find(xpos) == _lines.end()); + Lines::iterator steal = _lines.begin(); + line = steal->second; + _lines.erase(steal); + line->property_color_rgba() = color; + line->property_x1() = xpos; + line->property_x2() = xpos; + _lines.insert(make_pair(xpos, line)); + inserted_last_time = true; // search next time + invalidated = true; + + // Shift clean range right + _clean_left = max(_clean_left, steal->first); + _clean_right = max(_clean_right, xpos); } } |