Patch from agorka to add some includes required for building with the GCC shipped...
[ardour.git] / gtk2_ardour / lineset.h
1 /*
2     Copyright (C) 2007 Paul Davis
3     This program is free software; you can redistribute it and/or modify
4     it under the terms of the GNU General Public License as published by
5     the Free Software Foundation; either version 2 of the License, or
6     (at your option) any later version.
7
8     This program is distributed in the hope that it will be useful,
9     but WITHOUT ANY WARRANTY; without even the implied warranty of
10     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11     GNU General Public License for more details.
12
13     You should have received a copy of the GNU General Public License
14     along with this program; if not, write to the Free Software
15     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16 */
17
18 #ifndef __gnome_canvas_lineset_h__
19 #define __gnome_canvas_lineset_h__
20
21 #include <stdint.h>
22 #include <libgnomecanvasmm/item.h>
23
24 namespace Gnome {
25 namespace Canvas {
26
27 class LineSetClass : public Glib::Class {
28 public:
29         const Glib::Class& init();
30         static void class_init_function(void* g_class, void* class_data);
31 };
32
33 /** A canvas item that displays a set of vertical or horizontal lines,
34  * spanning the entire size of the item.
35  */
36 class LineSet : public Item {
37 public:
38         enum Orientation {
39                 Vertical,
40                 Horizontal
41         };
42
43         LineSet(Group& parent, Orientation);
44         virtual ~LineSet();
45
46         Glib::PropertyProxy<double> property_x1() { return x1.get_proxy(); }
47         Glib::PropertyProxy<double> property_y1() { return y1.get_proxy(); }
48         Glib::PropertyProxy<double> property_x2() { return x2.get_proxy(); }
49         Glib::PropertyProxy<double> property_y2() { return y2.get_proxy(); }
50
51         /* Note: every line operation takes a coord parameter, as an index to
52          * the line it modifies. The index will identify a line if it is between
53          * line.coord and line.coord + line.width.
54          */
55
56         /** Move a line to a new position.
57          * For this to work (to move the desired line) it is important that
58          * lines have unique coordinates. This also applies to every line
59          * accessing functions below
60          */
61         void move_line(double coord, double dest);
62
63         /** Change the width of a line.
64          * Only allow if the new width doesn't overlap the next line (see below)
65          */
66         void change_line_width(double coord, double width);
67
68         /** Change the color of a line.
69          */
70         void change_line_color(double coord, uint32_t color);
71
72         /** Add a line to draw.
73          * width is an offset, so that coord + width specifies the end of the line.
74          * lines should not overlap, as no layering information is provided.
75          * however, line_coord[i] + line_width[i] == line_coord[i+1] is
76          * be legal, as the coordinates are real numbers and represents
77          * real world coordinates. Two real world object sharing coordinates for start
78          * and end are not overlapping.
79          */
80         void add_line(double coord, double width, uint32_t color);
81
82         /** Remove the line at coord
83          */
84         void remove_line(double coord);
85         
86         /** Remove all lines in a coordinate range
87          */
88         void remove_lines(double c1, double c2);
89
90         /** Remove all lines with a coordinate lower than coord
91          */
92         void remove_until(double coord);
93         
94         /** Remove all lines with a coordinate equal to or higher than coord.
95          */
96         void remove_from(double coord);
97
98         /** Remove all lines.
99          */
100         void clear();
101
102         /** Add a set of lines in the given range.
103          * For every line visible in the provided coordinate range, call add_line().
104          * This is called when the area between c1 and c2 becomes visible, when
105          * previously outside any possible view.
106          * The number of calls to this function should be kept at a minimum.
107          */
108         virtual void request_lines(double c1, double c2);
109
110         /** Instead of overriding the update_lines function one can connect to this
111          * and add lines externally instead.
112          * If add_lines() is overrided, this signal will not be emitted.
113          */
114         sigc::signal<void, LineSet&, double, double> signal_request_lines;
115
116         /* overridden from Gnome::Canvas::Item */
117         void update_vfunc(double* affine, ArtSVP* clip_path, int flags);
118         void realize_vfunc();
119         void unrealize_vfunc();
120         void map_vfunc();
121         void unmap_vfunc();
122         void draw_vfunc(const Glib::RefPtr<Gdk::Drawable>& drawable, int x, int y, int width, int height);
123         void render_vfunc(GnomeCanvasBuf* buf);
124         double point_vfunc(double x, double y, int cx, int cy, GnomeCanvasItem** actual_item);
125         void bounds_vfunc(double* x1, double* y1, double* x2, double* y2);
126         bool on_event(GdkEvent* p1);
127
128         /* debug */
129         void print_lines();
130         
131 protected:
132         struct Line {
133                 Line(double c, double w, uint32_t color);
134                 Line(double c);
135
136                 void set_color(uint32_t color);
137
138                 double coord;
139                 double width;
140                 unsigned char r;
141                 unsigned char g;
142                 unsigned char b;
143                 unsigned char a;
144         };
145
146         static inline void paint_vert(GnomeCanvasBuf* buf, LineSet::Line& line, int x1, int y1, int x2, int y2);
147         static inline void paint_horiz(GnomeCanvasBuf* buf, LineSet::Line& line, int x1, int y1, int x2, int y2);
148
149         static bool line_compare(const Line& a, const Line& b);
150
151         typedef std::list<Line> Lines;
152         void bounds_need_update();
153         void region_needs_update(double coord1, double coord2);
154         bool update_bounds();
155         void update_lines(bool need_redraw);
156         void redraw_request(ArtIRect&);
157         void redraw_request(ArtDRect&);
158
159         Lines::iterator line_at(double coord);
160
161         /** Stores last accessed line so adjacent lines are found faster */
162         Lines::iterator cached_pos;
163
164         static LineSetClass lineset_class;
165         Orientation orientation;
166         Lines lines;
167
168         /* properties */
169         Glib::Property<double> x1;
170         Glib::Property<double> y1;
171         Glib::Property<double> x2;
172         Glib::Property<double> y2;
173
174         /** Cached bounding box in canvas coordinates */
175         ArtIRect bbox;
176
177 private:
178         LineSet();
179         LineSet(const LineSet&);
180
181         bool in_update;
182
183         /* a range that needs update update1 > update2 ==> no update needed */
184         double update_region1;
185         double update_region2;
186         bool bounds_changed;
187
188         double covered1;
189         double covered2;
190 };
191
192 } /* namespace Canvas */
193 } /* namespace Gnome */
194
195 #endif /* __gnome_canvas_lineset_h__ */