add headers to all canvas .cc and .h files
[ardour.git] / libs / canvas / line_set.cc
1 /*
2     Copyright (C) 2011-2013 Paul Davis
3     Author: Carl Hetherington <cth@carlh.net>
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include "canvas/line_set.h"
21 #include "canvas/utils.h"
22
23 using namespace std;
24 using namespace ArdourCanvas;
25
26 /* XXX: hard-wired to horizontal only */
27
28 class LineSorter {
29 public:
30         bool operator() (LineSet::Line& a, LineSet::Line& b) {
31                 return a.y < b.y;
32         }
33 };
34
35 LineSet::LineSet (Group* parent)
36         : Item (parent)
37         , _height (0)
38 {
39
40 }
41
42
43 void
44 LineSet::compute_bounding_box () const
45 {
46         if (_lines.empty ()) {
47                 _bounding_box = boost::optional<Rect> ();
48                 _bounding_box_dirty = false;
49                 return;
50         }
51         
52         _bounding_box = Rect (0, _lines.front().y, COORD_MAX, min (_height, _lines.back().y));
53         _bounding_box_dirty = false;
54 }
55
56 void
57 LineSet::set_height (Distance height)
58 {
59         begin_change ();
60
61         _height = height;
62
63         _bounding_box_dirty = true;
64         end_change ();
65 }
66
67 void
68 LineSet::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
69 {
70         for (list<Line>::const_iterator i = _lines.begin(); i != _lines.end(); ++i) {
71                 if (i->y > area.y1) {
72                         break;
73                 } else if (i->y > area.y0) {
74                         set_source_rgba (context, i->color);
75                         context->set_line_width (i->width);
76                         context->move_to (area.x0, i->y);
77                         context->line_to (area.x1, i->y);
78                         context->stroke ();
79                 }
80         }
81 }
82
83 void
84 LineSet::add (Coord y, Distance width, Color color)
85 {
86         begin_change ();
87         
88         _lines.push_back (Line (y, width, color));
89         _lines.sort (LineSorter ());
90
91         _bounding_box_dirty = true;
92         end_change ();
93 }
94
95 void
96 LineSet::clear ()
97 {
98         begin_change ();
99         _lines.clear ();
100         _bounding_box_dirty = true;
101         end_change ();
102 }