Pulled tempo line stuff out into it's own relatively self-contained class.

Draw tempo lines on time canvas and connect them up all pretty-like to the ruler ticks.
Still needs some visual tweaking, but... they draw!  Finally!


git-svn-id: svn://localhost/ardour2/trunk@2247 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
David Robillard 2007-08-05 21:31:02 +00:00
parent 873ab9bbb1
commit 7c950f279b
10 changed files with 204 additions and 99 deletions

View File

@ -193,6 +193,7 @@ ui_config.cc
utils.cc
version.cc
waveview.cc
tempo_lines.cc
""")
fft_analysis_files=Split("""

View File

@ -40,7 +40,7 @@
<Option name="location punch" value="7c3a3aff"/>
<Option name="verbose canvas cursor" value="f4f214bc"/>
<Option name="marker label" value="000000ff"/>
<Option name="marker bar separator" value="30303088"/>
<Option name="marker bar separator" value="aaaaaa77"/>
<Option name="tempo bar" value="72727fff"/>
<Option name="meterbar" value="666672ff"/>
<Option name="markerbar" value="7f7f8cff"/>
@ -60,8 +60,8 @@
<Option name="EnteredMarker" value="dd6363ff"/>
<Option name="MeterMarker" value="f2425bff"/>
<Option name="TempoMarker" value="f2425bff"/>
<Option name="MeasureLineBeat" value="82828276"/>
<Option name="MeasureLineBar" value="9c9ca89c"/>
<Option name="MeasureLineBeat" value="b5b5b576"/>
<Option name="MeasureLineBar" value="d9d9d99c"/>
<Option name="GhostTrackBase" value="44007c7f"/>
<Option name="GhostTrackWave" value="02fd004c"/>
<Option name="GhostTrackWaveClip" value="ff000000"/>

View File

@ -199,6 +199,9 @@ Editor::Editor ()
vertical_adjustment (0.0, 0.0, 10.0, 400.0),
horizontal_adjustment (0.0, 0.0, 20.0, 1200.0),
tempo_lines(0),
marker_tempo_lines(0),
/* tool bar related */
edit_cursor_clock (X_("editcursor"), false, X_("EditCursorClock"), true),

View File

@ -55,6 +55,7 @@
#include "region_selection.h"
#include "canvas.h"
#include "draginfo.h"
#include "tempo_lines.h"
namespace Gtkmm2ext {
class TearOff;
@ -1211,15 +1212,15 @@ class Editor : public PublicEditor
ARDOUR::TempoMap::BBTPointList *current_bbt_points;
typedef vector<ArdourCanvas::SimpleLine*> TimeLineList;
TimeLineList free_measure_lines;
TimeLineList used_measure_lines;
ArdourCanvas::Group* time_line_group;
ArdourCanvas::SimpleLine* get_time_line ();
ArdourCanvas::Group* marker_time_line_group;
TempoLines* tempo_lines;
TempoLines* marker_tempo_lines;
void hide_measures ();
void draw_measures ();
bool lazy_hide_and_draw_measures ();
bool redraw_measures ();
void new_tempo_section ();

View File

@ -143,10 +143,10 @@ Editor::initialize_canvas ()
verbose_cursor_visible = false;
/* a group to hold time (measure) lines */
cursor_group = new ArdourCanvas::Group (*track_canvas.root(), 0.0, 0.0);
time_line_group = new ArdourCanvas::Group (*track_canvas.root(), 0.0, 0.0);
cursor_group = new ArdourCanvas::Group (*track_canvas.root(), 0.0, 0.0);
tempo_lines = new TempoLines(track_canvas, time_line_group);
time_canvas.set_name ("EditorTimeCanvas");
time_canvas.add_events (Gdk::POINTER_MOTION_HINT_MASK);
@ -154,6 +154,9 @@ Editor::initialize_canvas ()
time_canvas.set_center_scroll_region (false);
time_canvas.set_dither (Gdk::RGB_DITHER_NONE);
marker_time_line_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, 0.0);
marker_tempo_lines = new TempoLines(time_canvas, marker_time_line_group);
meter_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, 0.0);
tempo_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, timebar_height);
marker_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, timebar_height * 2.0);

View File

@ -160,7 +160,7 @@ Editor::redisplay_tempo (bool immediate_redraw)
} else {
if (session && current_bbt_points) {
Glib::signal_idle().connect (mem_fun (*this, &Editor::lazy_hide_and_draw_measures));
Glib::signal_idle().connect (mem_fun (*this, &Editor::redraw_measures));
} else {
hide_measures ();
}
@ -170,32 +170,12 @@ Editor::redisplay_tempo (bool immediate_redraw)
void
Editor::hide_measures ()
{
for (TimeLineList::iterator i = used_measure_lines.begin(); i != used_measure_lines.end(); ++i) {
(*i)->hide();
free_measure_lines.push_back (*i);
}
used_measure_lines.clear ();
}
ArdourCanvas::SimpleLine *
Editor::get_time_line ()
{
ArdourCanvas::SimpleLine *line;
if (free_measure_lines.empty()) {
line = new ArdourCanvas::SimpleLine (*time_line_group);
used_measure_lines.push_back (line);
} else {
line = free_measure_lines.front();
free_measure_lines.erase (free_measure_lines.begin());
used_measure_lines.push_back (line);
}
return line;
tempo_lines->hide();
marker_tempo_lines->hide();
}
bool
Editor::lazy_hide_and_draw_measures ()
Editor::redraw_measures ()
{
hide_measures ();
draw_measures ();
@ -205,77 +185,21 @@ Editor::lazy_hide_and_draw_measures ()
void
Editor::draw_measures ()
{
if (session == 0 || _show_measures == false) {
if (session == 0 || _show_measures == false
|| !current_bbt_points || current_bbt_points->empty()) {
return;
}
TempoMap::BBTPointList::iterator i;
ArdourCanvas::SimpleLine *line;
gdouble xpos;
double x1, x2, y1, y2, beat_density;
uint32_t beats = 0;
uint32_t bars = 0;
uint32_t color;
if (current_bbt_points == 0 || current_bbt_points->empty()) {
return;
}
track_canvas.get_scroll_region (x1, y1, x2, y2);
y2 = TimeAxisView::hLargest*5000; // five thousand largest tracks should be enough.. :)
/* get the first bar spacing */
i = current_bbt_points->end();
i--;
bars = (*i).bar - (*current_bbt_points->begin()).bar;
beats = current_bbt_points->size() - bars;
beat_density = (beats * 10.0f) / track_canvas.get_width ();
if (beat_density > 4.0f) {
/* if the lines are too close together, they become useless
*/
return;
}
for (i = current_bbt_points->begin(); i != current_bbt_points->end(); ++i) {
switch ((*i).type) {
case TempoMap::Bar:
break;
case 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) {
/* only draw beat lines if the gaps between beats are large.
*/
break;
}
}
xpos = frame_to_unit ((*i).frame);
line = get_time_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;
}
}
tempo_lines->draw(*current_bbt_points, frames_per_unit);
marker_tempo_lines->draw(*current_bbt_points, frames_per_unit);
/* the cursors are always on top of everything */
time_line_group->raise_to_top();
marker_time_line_group->raise_to_top();
cursor_group->raise_to_top();
time_line_group->lower_to_bottom();
return;
}

View File

@ -181,6 +181,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
virtual void play_selection () = 0;
virtual void set_show_measures (bool yn) = 0;
virtual bool show_measures () const = 0;
virtual bool redraw_measures () = 0;
/** Open an export dialogue for the whole session */
virtual void export_session () = 0;

122
gtk2_ardour/tempo_lines.cc Normal file
View File

@ -0,0 +1,122 @@
/*
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <libgnomecanvasmm/canvas.h>
#include <libgnomecanvasmm/group.h>
#include "tempo_lines.h"
#include "ardour_ui.h"
ArdourCanvas::SimpleLine *
TempoLines::get_line ()
{
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::hide ()
{
for (Lines::iterator i = _used_lines.begin(); i != _used_lines.end(); ++i) {
(*i)->hide();
_free_lines.push_back (*i);
}
_used_lines.clear ();
}
void
TempoLines::draw (ARDOUR::TempoMap::BBTPointList& points, double frames_per_unit)
{
ARDOUR::TempoMap::BBTPointList::iterator i;
ArdourCanvas::SimpleLine *line;
gdouble xpos;
double who_cares;
double x1, x2, y1, y2, 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);
// FIXME use canvas height
//y2 = TimeAxisView::hLargest*5000; // five thousand largest tracks should be enough.. :)
//y2 = 500000; // five thousand largest tracks should be enough.. :)
/* get the first bar spacing */
i = points.end();
i--;
bars = (*i).bar - (*points.begin()).bar;
beats = points.size() - bars;
beat_density = (beats * 10.0f) / _canvas.get_width ();
if (beat_density > 4.0f) {
/* if the lines are too close together, they become useless
*/
return;
}
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) {
/* only draw beat lines if the gaps between beats are large.
*/
break;
}
}
xpos = rint((*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;
}
}
}

48
gtk2_ardour/tempo_lines.h Normal file
View File

@ -0,0 +1,48 @@
/*
Copyright (C) 2000-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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_tempo_lines_h__
#define __ardour_tempo_lines_h__
#include <vector>
#include <ardour/tempo.h>
#include "canvas.h"
#include "simpleline.h"
class TempoLines {
public:
TempoLines(ArdourCanvas::Canvas& canvas, ArdourCanvas::Group* group)
: _canvas(canvas)
, _group(group)
{}
ArdourCanvas::SimpleLine* get_line();
void draw(ARDOUR::TempoMap::BBTPointList& points, double frames_per_unit);
void hide();
private:
typedef std::vector<ArdourCanvas::SimpleLine*> Lines;
Lines _free_lines;
Lines _used_lines;
ArdourCanvas::Canvas& _canvas;
ArdourCanvas::Group* _group;
};
#endif /* __ardour_tempo_lines_h__ */

View File

@ -369,6 +369,8 @@ TimeAxisView::set_height_pixels (uint32_t h)
/* resize the selection rect */
show_selection (editor.get_selection().time);
}
editor.redraw_measures();
}
bool