diff options
author | David Robillard <d@drobilla.net> | 2008-01-13 17:45:17 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2008-01-13 17:45:17 +0000 |
commit | 2db91c126edc8fcaeda711d35369970576715719 (patch) | |
tree | 5a3a16c77acb7909334c6eb97fd0578c96f276ec /gtk2_ardour/lineset.h | |
parent | f8e3d652e946a169db0c15e3d1a0d9ed15464e0c (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.h | 208 |
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__ */ |