X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Ftempo_lines.cc;h=6bf7dfbde9081e472f441309545cf9ab95978550;hb=a1f858d3b207739e0719c1fc28003f1d9dd3965d;hp=c234cb4c51f1445ede4ed79597b0f01dc51b5348;hpb=22dc575e4cbc35a5d486d6f448332fb721865d57;p=ardour.git diff --git a/gtk2_ardour/tempo_lines.cc b/gtk2_ardour/tempo_lines.cc index c234cb4c51..6bf7dfbde9 100644 --- a/gtk2_ardour/tempo_lines.cc +++ b/gtk2_ardour/tempo_lines.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2007 Paul Davis + Copyright (C) 2002-2007 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,100 +17,110 @@ */ -#include -#include +#include "canvas/line.h" +#include "canvas/canvas.h" +#include "canvas/debug.h" #include "tempo_lines.h" #include "ardour_ui.h" -ArdourCanvas::SimpleLine * -TempoLines::get_line () +using namespace std; + +TempoLines::TempoLines (ArdourCanvas::Canvas& canvas, ArdourCanvas::Group* group, double screen_height) + : _canvas (canvas) + , _group (group) + , _height (screen_height) { - ArdourCanvas::SimpleLine *line; - - if (_free_lines.empty()) { - line = new ArdourCanvas::SimpleLine (*_group); - _used_lines.push_back (line); - } else { - line = _free_lines.front(); - _free_lines.erase (_free_lines.begin()); - _used_lines.push_back (line); - } +} - return line; +void +TempoLines::tempo_map_changed() +{ + /* remove all lines from the group, put them in the cache (to avoid + * unnecessary object destruction+construction later), and clear _lines + */ + + _group->clear (); + _cache.insert (_cache.end(), _lines.begin(), _lines.end()); + _lines.clear (); } +void +TempoLines::show () +{ + _group->show (); +} void TempoLines::hide () { - for (Lines::iterator i = _used_lines.begin(); i != _used_lines.end(); ++i) { - (*i)->hide(); - _free_lines.push_back (*i); - } - _used_lines.clear (); + _group->hide (); } - void -TempoLines::draw (ARDOUR::TempoMap::BBTPointList& points, double frames_per_unit) +TempoLines::draw (const ARDOUR::TempoMap::BBTPointList::const_iterator& begin, + const ARDOUR::TempoMap::BBTPointList::const_iterator& end, + double samples_per_pixel) { - ARDOUR::TempoMap::BBTPointList::iterator i; - ArdourCanvas::SimpleLine *line; - gdouble xpos; - double who_cares; - double x1, x2, y1, y2, beat_density; + ARDOUR::TempoMap::BBTPointList::const_iterator i; + ArdourCanvas::Rect const visible = _canvas.visible_area (); + double beat_density; uint32_t beats = 0; uint32_t bars = 0; uint32_t color; - _canvas.get_scroll_region (x1, y1, x2, who_cares); - _canvas.root()->get_bounds(who_cares, who_cares, who_cares, y2); - /* get the first bar spacing */ - i = points.end(); + i = end; i--; - bars = (*i).bar - (*points.begin()).bar; - beats = points.size() - bars; + bars = (*i).bar - (*begin).bar; + beats = distance (begin, end) - bars; - beat_density = (beats * 10.0f) / _canvas.get_width (); + beat_density = (beats * 10.0f) / visible.width (); if (beat_density > 4.0f) { - /* if the lines are too close together, they become useless - */ + /* if the lines are too close together, they become useless */ + tempo_map_changed(); return; } - for (i = points.begin(); i != points.end(); ++i) { - - switch ((*i).type) { - case ARDOUR::TempoMap::Bar: - break; + tempo_map_changed (); - case ARDOUR::TempoMap::Beat: - - if ((*i).beat == 1) { - color = ARDOUR_UI::config()->canvasvar_MeasureLineBar.get(); - } else { - color = ARDOUR_UI::config()->canvasvar_MeasureLineBeat.get(); + for (i = begin; i != end; ++i) { - if (beat_density > 2.0) { - /* only draw beat lines if the gaps between beats are large. - */ - break; - } + if ((*i).is_bar()) { + color = ARDOUR_UI::config()->get_canvasvar_MeasureLineBar(); + } else { + if (beat_density > 2.0) { + continue; /* only draw beat lines if the gaps between beats are large. */ } + color = ARDOUR_UI::config()->get_canvasvar_MeasureLineBeat(); + } + + ArdourCanvas::Coord xpos = rint(((framepos_t)(*i).frame) / (double)samples_per_pixel); - xpos = rint(((nframes64_t)(*i).frame) / (double)frames_per_unit); - line = get_line (); - line->property_x1() = xpos; - line->property_x2() = xpos; - line->property_y2() = y2; - line->property_color_rgba() = color; - //line->raise_to_top(); - line->show(); - break; + ArdourCanvas::Line* line; + + if (!_cache.empty()) { + line = _cache.back (); + _cache.pop_back (); + line->reparent (_group); + } else { + line = new ArdourCanvas::Line (_group); + CANVAS_DEBUG_NAME (line, "tempo measure line"); + line->set_ignore_events (true); } + + /* move to 0.5 offset to ensure single pixel lines (see Cairo + * FAQ for info on why we do this). + */ + + line->set_x0 (xpos + 0.5); + line->set_x1 (xpos + 0.5); + line->set_y0 (0.0); + line->set_y1 (_height); + line->set_outline_color (color); + line->show (); } } +