summaryrefslogtreecommitdiff
path: root/libs/canvas/line_set.cc
blob: c77ab7cf2b451563c1d89bcd5421578963f0c702 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include "pbd/xml++.h"
#include "canvas/line_set.h"
#include "canvas/utils.h"

using namespace std;
using namespace ArdourCanvas;

/* XXX: hard-wired to horizontal only */

class LineSorter {
public:
	bool operator() (LineSet::Line& a, LineSet::Line& b) {
		return a.y < b.y;
	}
};

LineSet::LineSet (Group* parent)
	: Item (parent)
	, _height (0)
{

}

XMLNode *
LineSet::get_state () const
{
	/* XXX */
	return new XMLNode ("LineSet");
}

void
LineSet::compute_bounding_box () const
{
	if (_lines.empty ()) {
		_bounding_box = boost::optional<Rect> ();
		_bounding_box_dirty = false;
		return;
	}
	
	_bounding_box = Rect (0, _lines.front().y, COORD_MAX, min (_height, _lines.back().y));
	_bounding_box_dirty = false;
}

void
LineSet::set_height (Distance height)
{
	begin_change ();

	_height = height;

	_bounding_box_dirty = true;
	end_change ();
}

void
LineSet::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
{
	for (list<Line>::const_iterator i = _lines.begin(); i != _lines.end(); ++i) {
		if (i->y > area.y1) {
			break;
		} else if (i->y > area.y0) {
			set_source_rgba (context, i->color);
			context->set_line_width (i->width);
			context->move_to (area.x0, i->y);
			context->line_to (area.x1, i->y);
			context->stroke ();
		}
	}
}

void
LineSet::add (Coord y, Distance width, Color color)
{
	begin_change ();
	
	_lines.push_back (Line (y, width, color));
	_lines.sort (LineSorter ());

	_bounding_box_dirty = true;
	end_change ();
}

void
LineSet::clear ()
{
	begin_change ();
	_lines.clear ();
	_bounding_box_dirty = true;
	end_change ();
}