2008-01-13 12:45:17 -05:00
|
|
|
/*
|
|
|
|
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__
|
|
|
|
|
2009-05-17 20:21:17 -04:00
|
|
|
#include <stdint.h>
|
2008-01-13 12:45:17 -05:00
|
|
|
#include <libgnomecanvasmm/item.h>
|
|
|
|
|
|
|
|
namespace Gnome {
|
|
|
|
namespace Canvas {
|
|
|
|
|
2008-09-24 15:39:01 -04:00
|
|
|
class LineSetClass : public Glib::Class {
|
2008-01-13 12:45:17 -05:00
|
|
|
public:
|
|
|
|
const Glib::Class& init();
|
|
|
|
static void class_init_function(void* g_class, void* class_data);
|
|
|
|
};
|
|
|
|
|
2008-09-24 15:39:01 -04:00
|
|
|
/** A canvas item that displays a set of vertical or horizontal lines,
|
2008-01-13 12:45:17 -05:00
|
|
|
* spanning the entire size of the item.
|
|
|
|
*/
|
2008-09-24 15:39:01 -04:00
|
|
|
class LineSet : public Item {
|
2008-01-13 12:45:17 -05:00
|
|
|
public:
|
|
|
|
enum Orientation {
|
|
|
|
Vertical,
|
|
|
|
Horizontal
|
|
|
|
};
|
|
|
|
|
2008-09-24 15:39:01 -04:00
|
|
|
LineSet(Group& parent, Orientation);
|
|
|
|
virtual ~LineSet();
|
2008-01-13 12:45:17 -05:00
|
|
|
|
|
|
|
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(); }
|
|
|
|
|
2008-09-24 15:39:01 -04:00
|
|
|
/* Note: every line operation takes a coord parameter, as an index to
|
2008-01-13 12:45:17 -05:00
|
|
|
* the line it modifies. The index will identify a line if it is between
|
|
|
|
* line.coord and line.coord + line.width.
|
|
|
|
*/
|
|
|
|
|
2008-09-24 15:39:01 -04:00
|
|
|
/** Move a line to a new position.
|
|
|
|
* For this to work (to move the desired line) it is important that
|
2008-01-13 12:45:17 -05:00
|
|
|
* lines have unique coordinates. This also applies to every line
|
|
|
|
* accessing functions below
|
|
|
|
*/
|
|
|
|
void move_line(double coord, double dest);
|
|
|
|
|
2008-09-24 15:39:01 -04:00
|
|
|
/** Change the width of a line.
|
|
|
|
* Only allow if the new width doesn't overlap the next line (see below)
|
2008-01-13 12:45:17 -05:00
|
|
|
*/
|
|
|
|
void change_line_width(double coord, double width);
|
|
|
|
|
2008-09-24 15:39:01 -04:00
|
|
|
/** Change the color of a line.
|
2008-01-13 12:45:17 -05:00
|
|
|
*/
|
|
|
|
void change_line_color(double coord, uint32_t color);
|
|
|
|
|
2008-09-24 15:39:01 -04:00
|
|
|
/** Add a line to draw.
|
2008-01-13 12:45:17 -05:00
|
|
|
* 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);
|
|
|
|
|
2008-09-24 15:39:01 -04:00
|
|
|
/** Remove the line at coord
|
2008-01-13 12:45:17 -05:00
|
|
|
*/
|
|
|
|
void remove_line(double coord);
|
|
|
|
|
2008-09-24 15:39:01 -04:00
|
|
|
/** Remove all lines in a coordinate range
|
2008-01-13 12:45:17 -05:00
|
|
|
*/
|
|
|
|
void remove_lines(double c1, double c2);
|
|
|
|
|
2008-09-24 15:39:01 -04:00
|
|
|
/** Remove all lines with a coordinate lower than coord
|
2008-01-13 12:45:17 -05:00
|
|
|
*/
|
|
|
|
void remove_until(double coord);
|
|
|
|
|
2008-09-24 15:39:01 -04:00
|
|
|
/** Remove all lines with a coordinate equal to or higher than coord.
|
2008-01-13 12:45:17 -05:00
|
|
|
*/
|
|
|
|
void remove_from(double coord);
|
|
|
|
|
2008-09-24 15:39:01 -04:00
|
|
|
/** Remove all lines.
|
2008-01-13 12:45:17 -05:00
|
|
|
*/
|
|
|
|
void clear();
|
|
|
|
|
2008-09-24 15:39:01 -04:00
|
|
|
/** Add a set of lines in the given range.
|
|
|
|
* For every line visible in the provided coordinate range, call add_line().
|
2008-01-13 12:45:17 -05:00
|
|
|
* This is called when the area between c1 and c2 becomes visible, when
|
2008-09-24 15:39:01 -04:00
|
|
|
* previously outside any possible view.
|
|
|
|
* The number of calls to this function should be kept at a minimum.
|
2008-01-13 12:45:17 -05:00
|
|
|
*/
|
|
|
|
virtual void request_lines(double c1, double c2);
|
|
|
|
|
2008-09-24 15:39:01 -04:00
|
|
|
/** 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.
|
2008-01-13 12:45:17 -05:00
|
|
|
*/
|
2008-09-24 15:39:01 -04:00
|
|
|
sigc::signal<void, LineSet&, double, double> signal_request_lines;
|
2008-01-13 12:45:17 -05:00
|
|
|
|
2008-09-24 15:39:01 -04:00
|
|
|
/* overridden from Gnome::Canvas::Item */
|
2008-01-13 12:45:17 -05:00
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
2008-09-24 15:39:01 -04:00
|
|
|
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);
|
2008-01-13 12:45:17 -05:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2008-09-24 15:39:01 -04:00
|
|
|
/** Stores last accessed line so adjacent lines are found faster */
|
2008-01-13 12:45:17 -05:00
|
|
|
Lines::iterator cached_pos;
|
|
|
|
|
2008-09-24 15:39:01 -04:00
|
|
|
static LineSetClass lineset_class;
|
2008-01-13 12:45:17 -05:00
|
|
|
Orientation orientation;
|
|
|
|
Lines lines;
|
|
|
|
|
|
|
|
/* properties */
|
|
|
|
Glib::Property<double> x1;
|
|
|
|
Glib::Property<double> y1;
|
|
|
|
Glib::Property<double> x2;
|
|
|
|
Glib::Property<double> y2;
|
|
|
|
|
2008-09-24 15:39:01 -04:00
|
|
|
/** Cached bounding box in canvas coordinates */
|
2008-01-13 12:45:17 -05:00
|
|
|
ArtIRect bbox;
|
|
|
|
|
|
|
|
private:
|
2008-09-24 15:39:01 -04:00
|
|
|
LineSet();
|
|
|
|
LineSet(const LineSet&);
|
2008-01-13 12:45:17 -05:00
|
|
|
|
|
|
|
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__ */
|