summaryrefslogtreecommitdiff
path: root/gtk2_ardour/lineset.h
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2008-01-13 17:45:17 +0000
committerDavid Robillard <d@drobilla.net>2008-01-13 17:45:17 +0000
commit2db91c126edc8fcaeda711d35369970576715719 (patch)
tree5a3a16c77acb7909334c6eb97fd0578c96f276ec /gtk2_ardour/lineset.h
parentf8e3d652e946a169db0c15e3d1a0d9ed15464e0c (diff)
Apply MIDI keyboard and "scroomer" patch.
git-svn-id: svn://localhost/ardour2/trunk@2908 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour/lineset.h')
-rw-r--r--gtk2_ardour/lineset.h208
1 files changed, 208 insertions, 0 deletions
diff --git a/gtk2_ardour/lineset.h b/gtk2_ardour/lineset.h
new file mode 100644
index 0000000000..a5d0516139
--- /dev/null
+++ b/gtk2_ardour/lineset.h
@@ -0,0 +1,208 @@
+/*
+ Copyright (C) 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 __gnome_canvas_lineset_h__
+#define __gnome_canvas_lineset_h__
+
+#include <libgnomecanvasmm/item.h>
+
+namespace Gnome {
+namespace Canvas {
+
+class LinesetClass : public Glib::Class {
+public:
+ const Glib::Class& init();
+ static void class_init_function(void* g_class, void* class_data);
+};
+
+/**
+ * A canvas item that displays a list of lines vertically or horizontally,
+ * spanning the entire size of the item.
+ */
+class Lineset : public Item {
+public:
+ enum Orientation {
+ Vertical,
+ Horizontal
+ };
+
+ Lineset(Group& parent, Orientation);
+ virtual ~Lineset();
+
+ Glib::PropertyProxy<double> property_x1() { return x1.get_proxy(); }
+ Glib::PropertyProxy<double> property_y1() { return y1.get_proxy(); }
+ Glib::PropertyProxy<double> property_x2() { return x2.get_proxy(); }
+ Glib::PropertyProxy<double> property_y2() { return y2.get_proxy(); }
+
+ /*
+ * Note: every line operation takes a coord parameter, as an index to
+ * the line it modifies. The index will identify a line if it is between
+ * line.coord and line.coord + line.width.
+ */
+
+ /**
+ * Move a line to a new position
+ * for this to work (to move the desired line) it is important that
+ * lines have unique coordinates. This also applies to every line
+ * accessing functions below
+ */
+ void move_line(double coord, double dest);
+
+ /**
+ * Change the width of a line. Only allow it if the new width doesn't
+ * overlap the next line (see below)
+ */
+ void change_line_width(double coord, double width);
+
+ /**
+ * Change the color of a line
+ */
+ void change_line_color(double coord, uint32_t color);
+
+ /**
+ * this function adds a line to draw.
+ * width is an offset, so that coord + width specifies the end of the line.
+ * lines should not overlap, as no layering information is provided.
+ * however, line_coord[i] + line_width[i] == line_coord[i+1] is
+ * be legal, as the coordinates are real numbers and represents
+ * real world coordinates. Two real world object sharing coordinates for start
+ * and end are not overlapping.
+ */
+ void add_line(double coord, double width, uint32_t color);
+
+ /**
+ * remove the line at coord
+ */
+ void remove_line(double coord);
+
+ /**
+ * remove all lines in a coordinate range
+ */
+ void remove_lines(double c1, double c2);
+
+ /**
+ * remove all lines with a coordinate lower than coord
+ */
+ void remove_until(double coord);
+
+ /**
+ * remove all lines with a coordinate equal to or higher than coord
+ */
+ void remove_from(double coord);
+
+ /**
+ * remove all lines
+ */
+ void clear();
+
+ /**
+ * this is a request of information on lines in a coordinate range.
+ * for every line visible in the provided coordinate range,
+ * call add_line() on it.
+ * This is called when the area between c1 and c2 becomes visible, when
+ * previously outside any possible view. So the number of calls to this
+ * function will be kept at a minimum.
+ */
+ virtual void request_lines(double c1, double c2);
+
+ /**
+ * instead of overriding the update_lines function one can connect to this
+ * and add lines externally instead. If add_lines() is overrided, this
+ * signal will not be emitted.
+ */
+ sigc::signal<void, Lineset&, double, double> signal_request_lines;
+
+ /* overrided from Gnome::Canvas::Item */
+ void update_vfunc(double* affine, ArtSVP* clip_path, int flags);
+ void realize_vfunc();
+ void unrealize_vfunc();
+ void map_vfunc();
+ void unmap_vfunc();
+ void draw_vfunc(const Glib::RefPtr<Gdk::Drawable>& drawable, int x, int y, int width, int height);
+ void render_vfunc(GnomeCanvasBuf* buf);
+ double point_vfunc(double x, double y, int cx, int cy, GnomeCanvasItem** actual_item);
+ void bounds_vfunc(double* x1, double* y1, double* x2, double* y2);
+ bool on_event(GdkEvent* p1);
+
+ /* debug */
+ void print_lines();
+
+protected:
+ struct Line {
+ Line(double c, double w, uint32_t color);
+ Line(double c);
+
+ void set_color(uint32_t color);
+
+ double coord;
+ double width;
+ unsigned char r;
+ unsigned char g;
+ unsigned char b;
+ unsigned char a;
+ };
+
+ static inline void paint_vert(GnomeCanvasBuf* buf, Lineset::Line& line, int x1, int y1, int x2, int y2);
+ static inline void paint_horiz(GnomeCanvasBuf* buf, Lineset::Line& line, int x1, int y1, int x2, int y2);
+
+ static bool line_compare(const Line& a, const Line& b);
+
+ typedef std::list<Line> Lines;
+ void bounds_need_update();
+ void region_needs_update(double coord1, double coord2);
+ bool update_bounds();
+ void update_lines(bool need_redraw);
+ void redraw_request(ArtIRect&);
+ void redraw_request(ArtDRect&);
+
+ Lines::iterator line_at(double coord);
+
+ /* store that last accessed line so adjacent lines are found faster */
+ Lines::iterator cached_pos;
+
+ static LinesetClass lineset_class;
+ Orientation orientation;
+ Lines lines;
+
+ /* properties */
+ Glib::Property<double> x1;
+ Glib::Property<double> y1;
+ Glib::Property<double> x2;
+ Glib::Property<double> y2;
+
+ /* cached bounding box in canvas coordinates*/
+ ArtIRect bbox;
+
+private:
+ Lineset();
+ Lineset(const Lineset&);
+
+ bool in_update;
+
+ /* a range that needs update update1 > update2 ==> no update needed */
+ double update_region1;
+ double update_region2;
+ bool bounds_changed;
+
+ double covered1;
+ double covered2;
+};
+
+} /* namespace Canvas */
+} /* namespace Gnome */
+
+#endif /* __gnome_canvas_lineset_h__ */