aboutsummaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorMartin Mathieson <martin.r.mathieson@googlemail.com>2012-08-07 19:11:43 +0000
committerMartin Mathieson <martin.r.mathieson@googlemail.com>2012-08-07 19:11:43 +0000
commit41d9e150259df57a46783d0f69ab01ffbc0626d9 (patch)
tree4f5de1c9bacf69b5c8fe5305b5bac63dfe372a36 /ui
parent6c32ba5ff1a5f5ec2426d1d2c4f4f37fd136bab0 (diff)
Redo the cross drawing/erasing.
Draw in black, erase by just redrawing the current pixmap. Will apply to tcp_graph.c if/when this gets through the buildbots. svn path=/trunk/; revision=44308
Diffstat (limited to 'ui')
-rw-r--r--ui/gtk/rlc_lte_graph.c118
1 files changed, 62 insertions, 56 deletions
diff --git a/ui/gtk/rlc_lte_graph.c b/ui/gtk/rlc_lte_graph.c
index 37424fd2fe..f9e709952c 100644
--- a/ui/gtk/rlc_lte_graph.c
+++ b/ui/gtk/rlc_lte_graph.c
@@ -125,11 +125,13 @@ struct element_list {
struct axis {
struct graph *g; /* which graph we belong to */
GtkWidget *drawing_area;
+ /* Double-buffering to avoid flicker */
#if GTK_CHECK_VERSION(2,22,0)
cairo_surface_t *surface[2];
#else
GdkPixmap *pixmap[2];
#endif
+ /* Which of the 2 buffers we are currently showing */
int displayed;
#define AXIS_ORIENTATION 1 << 0
int flags;
@@ -194,6 +196,8 @@ struct graph {
GtkWidget *toplevel; /* keypress handler needs this */
GtkWidget *drawing_area;
PangoFontDescription *font; /* font used for annotations etc. */
+
+ /* Double-buffering */
#if GTK_CHECK_VERSION(2,22,0)
cairo_surface_t *title_surface;
cairo_surface_t *surface[2];
@@ -302,7 +306,6 @@ static void axis_destroy(struct axis * );
static int get_label_dim(struct axis * , int , double );
static void toggle_crosshairs(struct graph *);
-static void cross_xor(struct graph * , int x, int y);
static void cross_draw(struct graph * , int x, int y);
static void cross_erase(struct graph * );
static gboolean motion_notify_event(GtkWidget * , GdkEventMotion * , gpointer );
@@ -1125,14 +1128,13 @@ static void graph_pixmap_draw(struct graph *g)
cairo_rectangle(cr, 0, 0, g->wp.width, g->wp.height);
cairo_fill(cr);
cairo_destroy(cr);
- cr = NULL;
/* Create one cairo_t for use with all of the lines, rather than continually
creating and destroying one for each line */
#if GTK_CHECK_VERSION(2,22,0)
- cr_lines = cairo_create(g->surface[1^g->displayed]);
+ cr_lines = cairo_create(g->surface[not_disp]);
#else
- cr_lines = gdk_cairo_create(g->pixmap[1^g->displayed]);
+ cr_lines = gdk_cairo_create(g->pixmap[not_disp]);
#endif
/* Line width is always 1 pixel */
@@ -1187,10 +1189,10 @@ static void draw_element_line(struct graph *g, struct element *e, cairo_t *cr,
}
/* Map point into graph area, and round to nearest int */
- xx1 = (int )rint(e->p.line.dim.x1 + g->geom.x - g->wp.x);
- xx2 = (int )rint(e->p.line.dim.x2 + g->geom.x - g->wp.x);
- yy1 = (int )rint((g->geom.height-1-e->p.line.dim.y1) + g->geom.y-g->wp.y);
- yy2 = (int )rint((g->geom.height-1-e->p.line.dim.y2) + g->geom.y-g->wp.y);
+ xx1 = (int)rint(e->p.line.dim.x1 + g->geom.x - g->wp.x);
+ xx2 = (int)rint(e->p.line.dim.x2 + g->geom.x - g->wp.x);
+ yy1 = (int)rint((g->geom.height-1-e->p.line.dim.y1) + g->geom.y-g->wp.y);
+ yy2 = (int)rint((g->geom.height-1-e->p.line.dim.y2) + g->geom.y-g->wp.y);
/* If line completely out of the area, we won't show it */
if ((xx1<0 && xx2<0) || (xx1>=g->wp.width && xx2>=g->wp.width) ||
@@ -1682,7 +1684,7 @@ static void graph_select_segment(struct graph *g, int x, int y)
set_busy_cursor(gtk_widget_get_window(g->drawing_area));
- for (list=g->elists; list; list=list->next)
+ for (list=g->elists; list; list=list->next) {
for (e=list->elements; e->type != ELMT_NONE; e++) {
switch (e->type) {
case ELMT_LINE:
@@ -1695,6 +1697,7 @@ static void graph_select_segment(struct graph *g, int x, int y)
break;
}
}
+ }
if (num) {
@@ -1706,27 +1709,33 @@ static int line_detect_collision(struct element *e, int x, int y)
{
int xx1, yy1, xx2, yy2;
+ /* Get sorted x, y co-ordinates for line */
if (e->p.line.dim.x1 < e->p.line.dim.x2) {
- xx1 = (int )rint(e->p.line.dim.x1);
- xx2 = (int )rint(e->p.line.dim.x2);
+ xx1 = (int)rint(e->p.line.dim.x1);
+ xx2 = (int)rint(e->p.line.dim.x2);
} else {
- xx1 = (int )rint(e->p.line.dim.x2);
- xx2 = (int )rint(e->p.line.dim.x1);
+ xx1 = (int)rint(e->p.line.dim.x2);
+ xx2 = (int)rint(e->p.line.dim.x1);
}
if (e->p.line.dim.y1 < e->p.line.dim.y2) {
- yy1 = (int )rint(e->p.line.dim.y1);
- yy2 = (int )rint(e->p.line.dim.y2);
+ yy1 = (int)rint(e->p.line.dim.y1);
+ yy2 = (int)rint(e->p.line.dim.y2);
} else {
- yy1 = (int )rint(e->p.line.dim.y2);
- yy2 = (int )rint(e->p.line.dim.y1);
+ yy1 = (int)rint(e->p.line.dim.y2);
+ yy2 = (int)rint(e->p.line.dim.y1);
}
/*
printf("line: (%d,%d)->(%d,%d), clicked: (%d,%d)\n", xx1, yy1, xx2, yy2, x, y);
*/
- if ((xx1==x && xx2==x && yy1<=y && y<=yy2)||(yy1==y && yy2==y && xx1<=x && x<=xx2))
+
+ /* N.B. won't match with diagonal lines... */
+ if ((xx1==x && xx2==x && yy1<=y && y<=yy2)| /* lies along vertical line */
+ (yy1==y && yy2==y && xx1<=x && x<=xx2)) { /* lies along horizontal line */
return TRUE;
- else
+ }
+ else {
return FALSE;
+ }
}
@@ -2017,7 +2026,7 @@ static gboolean button_press_event(GtkWidget *widget _U_, GdkEventButton *event,
} else if (event->button == MOUSE_BUTTON_MIDDLE) {
do_zoom_mouse(g, event);
} else if (event->button == MOUSE_BUTTON_LEFT) {
- graph_select_segment(g, (int )event->x, (int )event->y);
+ graph_select_segment(g, (int)event->x, (int)event->y);
}
unset_busy_cursor(gtk_widget_get_window(g->drawing_area));
@@ -2036,7 +2045,7 @@ static gboolean button_release_event(GtkWidget *widget _U_, GdkEventButton *even
return TRUE;
}
-static gboolean motion_notify_event (GtkWidget *widget _U_, GdkEventMotion *event, gpointer user_data)
+static gboolean motion_notify_event(GtkWidget *widget _U_, GdkEventMotion *event, gpointer user_data)
{
struct graph *g = user_data;
int x, y;
@@ -2171,38 +2180,6 @@ static void toggle_crosshairs(struct graph *g)
}
}
-static void cross_xor (struct graph *g, int x, int y)
-{
-#if GTK_CHECK_VERSION(2,22,0)
- GdkColor color_gray15 = {0x0, 0xffff, 0xffff, 0xffff};
- cairo_t *cr;
-
- if (x > g->wp.x && x < g->wp.x+g->wp.width &&
- y >= g->wp.y && y < g->wp.y+g->wp.height) {
- /* Draw horizontal line */
- cr = gdk_cairo_create(gtk_widget_get_window(g->drawing_area));
- cairo_set_operator (cr, CAIRO_OPERATOR_XOR);
- gdk_cairo_set_source_color (cr, &color_gray15);
- cairo_set_line_width (cr, 1.0);
- cairo_move_to(cr, g->wp.x+0.5, y+0.5);
- cairo_line_to(cr, g->wp.x + g->wp.width+0.5, y+0.5);
- /* Draw vertical line */
- cairo_move_to(cr, x+0.5, g->wp.y+0.5);
- cairo_line_to(cr, x+0.5, g->wp.y + g->wp.height+0.5);
- cairo_stroke(cr);
- cairo_destroy(cr);
- }
-#else
- if (x > g->wp.x && x < g->wp.x+g->wp.width &&
- y >= g->wp.y && y < g->wp.y+g->wp.height) {
- gdk_draw_line(gtk_widget_get_window(g->drawing_area), xor_gc, g->wp.x,
- y, g->wp.x + g->wp.width, y);
- gdk_draw_line(gtk_widget_get_window(g->drawing_area), xor_gc, x,
- g->wp.y, x, g->wp.y + g->wp.height);
- }
-#endif /* GTK_CHECK_VERSION(2,22,0) */
-}
-
static void cross_draw(struct graph *g, int x, int y)
{
/* Shouldn't draw twice onto the same position if haven't erased in the
@@ -2210,7 +2187,27 @@ static void cross_draw(struct graph *g, int x, int y)
if (g->cross.erase_needed && (g->cross.x == x) && (g->cross.y == y)) {
return;
}
- cross_xor(g, x, y);
+
+ /* Draw the cross */
+ if (x > g->wp.x && x < g->wp.x+g->wp.width &&
+ y >= g->wp.y && y < g->wp.y+g->wp.height) {
+
+ cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(g->drawing_area));
+ gdk_cairo_set_source_color(cr, &g->style.seq_color);
+ cairo_set_line_width(cr, 1.0);
+
+ /* Horizonal line */
+ cairo_move_to(cr, g->wp.x+0.5, y+0.5);
+ cairo_line_to(cr, g->wp.x + g->wp.width+0.5, y+0.5);
+
+ /* Vertical line */
+ cairo_move_to(cr, x+0.5, g->wp.y+0.5);
+ cairo_line_to(cr, x+0.5, g->wp.y + g->wp.height+0.5);
+ cairo_stroke(cr);
+ cairo_destroy(cr);
+ }
+
+ /* Update state */
g->cross.x = x;
g->cross.y = y;
g->cross.erase_needed = TRUE;
@@ -2218,8 +2215,17 @@ static void cross_draw(struct graph *g, int x, int y)
static void cross_erase(struct graph *g)
{
- cross_xor (g, g->cross.x, g->cross.y);
- g->cross.erase_needed = 0;
+ int x = g->cross.x;
+ int y = g->cross.y;
+
+ if (x > g->wp.x && x < g->wp.x+g->wp.width &&
+ y >= g->wp.y && y < g->wp.y+g->wp.height) {
+
+ /* Just redraw what is in the pixmap buffer */
+ graph_pixmap_display(g);
+ }
+
+ g->cross.erase_needed = FALSE;
}