r5405 - trunk/eda/fped

werner at docs.openmoko.org werner at docs.openmoko.org
Sat Aug 8 16:11:27 CEST 2009


Author: werner
Date: 2009-08-08 16:11:26 +0200 (Sat, 08 Aug 2009)
New Revision: 5405

Added:
   trunk/eda/fped/gui_over.c
   trunk/eda/fped/gui_over.h
Modified:
   trunk/eda/fped/Makefile
   trunk/eda/fped/gui_canvas.c
   trunk/eda/fped/gui_canvas.h
   trunk/eda/fped/gui_inst.c
   trunk/eda/fped/gui_inst.h
   trunk/eda/fped/gui_style.c
   trunk/eda/fped/gui_tools.c
   trunk/eda/fped/gui_tools.h
   trunk/eda/fped/gui_util.c
   trunk/eda/fped/gui_util.h
   trunk/eda/fped/inst.c
   trunk/eda/fped/inst.h
Log:
- to simplify communication between the various modules, renamed "ctx" to 
  draw_ctx, moved it to gui_util.c, and made it a global variable
- moved drawing logic for hovering and dragging into dedicated state machine
  in gui_over.c
- hovering now uses a pixmap to restore the background instead of redrawing
- moved hover drawing functions from gui_inst.c to gui_tools.c
- made hover circle thicker



Modified: trunk/eda/fped/Makefile
===================================================================
--- trunk/eda/fped/Makefile	2009-08-07 21:47:51 UTC (rev 5404)
+++ trunk/eda/fped/Makefile	2009-08-08 14:11:26 UTC (rev 5405)
@@ -14,7 +14,7 @@
        unparse.o dump.o meas.o \
        cpp.o lex.yy.o y.tab.o \
        gui.o gui_util.o gui_style.o gui_inst.o gui_status.o gui_canvas.o \
-       gui_tools.o
+       gui_tools.o gui_over.o
 
 XPMS = point.xpm delete.xpm vec.xpm frame.xpm frame_locked.xpm frame_ready.xpm \
        line.xpm rect.xpm pad.xpm circ.xpm meas.xpm meas_x.xpm meas_y.xpm

Modified: trunk/eda/fped/gui_canvas.c
===================================================================
--- trunk/eda/fped/gui_canvas.c	2009-08-07 21:47:51 UTC (rev 5404)
+++ trunk/eda/fped/gui_canvas.c	2009-08-08 14:11:26 UTC (rev 5405)
@@ -18,6 +18,7 @@
 #include "obj.h"
 #include "delete.h"
 #include "inst.h"
+#include "gui_util.h"
 #include "gui_inst.h"
 #include "gui_style.h"
 #include "gui_status.h"
@@ -26,9 +27,8 @@
 #include "gui_canvas.h"
 
 
-void (*highlight)(struct draw_ctx *ctx) = NULL;
+void (*highlight)(void) = NULL;
 
-static struct draw_ctx ctx;
 static struct coord curr_pos;
 static struct coord user_origin = { 0, 0 };
 
@@ -42,7 +42,7 @@
 
 static void update_zoom(void)
 {
-	status_set_zoom("x%d", ctx.scale);
+	status_set_zoom("x%d", draw_ctx.scale);
 }
 
 
@@ -63,8 +63,8 @@
 	struct bbox bbox;
 
 	bbox = this_bbox ? *this_bbox : inst_get_bbox();
-	ctx.center.x = (bbox.min.x+bbox.max.x)/2;
-	ctx.center.y = (bbox.min.y+bbox.max.y)/2;
+	draw_ctx.center.x = (bbox.min.x+bbox.max.x)/2;
+	draw_ctx.center.y = (bbox.min.y+bbox.max.y)/2;
 }
 
 
@@ -76,8 +76,8 @@
 	float aw, ah;
 
 	bbox = this_bbox ? *this_bbox : inst_get_bbox();
-	aw = ctx.widget->allocation.width;
-	ah = ctx.widget->allocation.height;
+	aw = draw_ctx.widget->allocation.width;
+	ah = draw_ctx.widget->allocation.height;
 	h = bbox.max.x-bbox.min.x;
 	w = bbox.max.y-bbox.min.y;
 	aw -= 2*CANVAS_CLEARANCE;
@@ -88,7 +88,7 @@
 		ah = 1;
 	sx = ceil(h/aw);
 	sy = ceil(w/ah);
-	ctx.scale = sx > sy ? sx : sy > 0 ? sy : 1;
+	draw_ctx.scale = sx > sy ? sx : sy > 0 ? sy : 1;
 
 	update_zoom();
 }
@@ -101,15 +101,15 @@
 {
 	float aw, ah;
 
-	aw = ctx.widget->allocation.width;
-	ah = ctx.widget->allocation.height;
-	gdk_draw_rectangle(ctx.widget->window,
+	aw = draw_ctx.widget->allocation.width;
+	ah = draw_ctx.widget->allocation.height;
+	gdk_draw_rectangle(draw_ctx.widget->window,
 	    instantiation_ok ? gc_bg : gc_bg_error, TRUE, 0, 0, aw, ah);
 
-	inst_draw(&ctx);
+	inst_draw();
 	if (highlight)
-		highlight(&ctx);
-	tool_redraw(&ctx);
+		highlight();
+	tool_redraw();
 }
 
 
@@ -121,11 +121,11 @@
 	if (!dragging)
 		return;
 	if (!drag_escaped &&
-	    hypot(pos.x-drag_start.x, pos.y-drag_start.y)/ctx.scale <
+	    hypot(pos.x-drag_start.x, pos.y-drag_start.y)/draw_ctx.scale <
 	    DRAG_MIN_R)
 		return;
 	drag_escaped = 1;
-	tool_drag(&ctx, pos);
+	tool_drag(pos);
 }
 
 
@@ -137,14 +137,13 @@
 static gboolean motion_notify_event(GtkWidget *widget, GdkEventMotion *event,
     gpointer data)
 {
-	struct coord pos = canvas_to_coord(&ctx, event->x, event->y);
+	struct coord pos = canvas_to_coord(event->x, event->y);
 
 	curr_pos.x = event->x;
 	curr_pos.y = event->y;
+	tool_hover(pos);
 	if (event->state & GDK_BUTTON1_MASK)
 		drag_left(pos);
-	else
-		tool_hover(&ctx, pos);
 	if (event->state & GDK_BUTTON2_MASK)
 		drag_middle(pos);
 	update_pos(pos);
@@ -158,7 +157,7 @@
 static gboolean button_press_event(GtkWidget *widget, GdkEventButton *event,
     gpointer data)
 {
-	struct coord pos = canvas_to_coord(&ctx, event->x, event->y);
+	struct coord pos = canvas_to_coord(event->x, event->y);
 	const struct inst *prev;
 	int res;
 
@@ -166,10 +165,10 @@
 	case 1:
 		if (dragging) {
 			fprintf(stderr, "HUH ?!?\n");
-			tool_cancel_drag(&ctx);
+			tool_cancel_drag();
 			dragging = 0;
 		}
-		res = tool_consider_drag(&ctx, pos);
+		res = tool_consider_drag(pos);
 		/* tool doesn't do drag */
 		if (res < 0) {
 			change_world();
@@ -186,12 +185,12 @@
 		}
 		prev = selected_inst;
 		inst_deselect();
-		inst_select(&ctx, pos);
+		inst_select(pos);
 		if (prev != selected_inst)
 			redraw();
 		break;
 	case 2:
-		ctx.center = pos;
+		draw_ctx.center = pos;
 		redraw();
 		break;
 	}
@@ -202,18 +201,18 @@
 static gboolean button_release_event(GtkWidget *widget, GdkEventButton *event,
     gpointer data)
 {
-	struct coord pos = canvas_to_coord(&ctx, event->x, event->y);
+	struct coord pos = canvas_to_coord(event->x, event->y);
 
 	switch (event->button) {
 	case 1:
 		if (!dragging)
 			break;
 		dragging = 0;
-		if (hypot(pos.x-drag_start.x, pos.y-drag_start.y)/ctx.scale < 
-		    DRAG_MIN_R)
-			tool_cancel_drag(&ctx);
+		if (hypot(pos.x-drag_start.x,
+		    pos.y-drag_start.y)/draw_ctx.scale < DRAG_MIN_R)
+			tool_cancel_drag();
 		else {
-			if (tool_end_drag(&ctx, pos))
+			if (tool_end_drag(pos))
 				change_world();
 		}
 		break;
@@ -227,11 +226,11 @@
 
 static void zoom_in(struct coord pos)
 {
-	if (ctx.scale < 2)
+	if (draw_ctx.scale < 2)
 		return;
-	ctx.scale /= 2;
-	ctx.center.x = (ctx.center.x+pos.x)/2;
-	ctx.center.y = (ctx.center.y+pos.y)/2;
+	draw_ctx.scale /= 2;
+	draw_ctx.center.x = (draw_ctx.center.x+pos.x)/2;
+	draw_ctx.center.y = (draw_ctx.center.y+pos.y)/2;
 	update_zoom();
 	redraw();
 }
@@ -242,16 +241,16 @@
 	struct bbox bbox;
 
 	bbox = inst_get_bbox();
-	bbox.min = translate(&ctx, bbox.min);
-	bbox.max = translate(&ctx, bbox.max);
+	bbox.min = translate(bbox.min);
+	bbox.max = translate(bbox.max);
 	if (bbox.min.x >= ZOOM_STOP_BORDER &&
 	    bbox.max.y >= ZOOM_STOP_BORDER &&
-	    bbox.max.x < ctx.widget->allocation.width-ZOOM_STOP_BORDER &&
-	    bbox.min.y < ctx.widget->allocation.height-ZOOM_STOP_BORDER)
+	    bbox.max.x < draw_ctx.widget->allocation.width-ZOOM_STOP_BORDER &&
+	    bbox.min.y < draw_ctx.widget->allocation.height-ZOOM_STOP_BORDER)
 		return;
-	ctx.scale *= 2;
-	ctx.center.x = 2*ctx.center.x-pos.x;
-	ctx.center.y = 2*ctx.center.y-pos.y;
+	draw_ctx.scale *= 2;
+	draw_ctx.center.x = 2*draw_ctx.center.x-pos.x;
+	draw_ctx.center.y = 2*draw_ctx.center.y-pos.y;
 	update_zoom();
 	redraw();
 }
@@ -260,7 +259,7 @@
 static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event,
     gpointer data)
 {
-	struct coord pos = canvas_to_coord(&ctx, event->x, event->y);
+	struct coord pos = canvas_to_coord(event->x, event->y);
 
 	switch (event->direction) {
 	case GDK_SCROLL_UP:
@@ -282,7 +281,7 @@
 static gboolean key_press_event(GtkWidget *widget, GdkEventKey *event,
     gpointer data)
 {
-	struct coord pos = canvas_to_coord(&ctx, curr_pos.x, curr_pos.y);
+	struct coord pos = canvas_to_coord(curr_pos.x, curr_pos.y);
 
 	switch (event->keyval) {
 	case ' ':
@@ -307,7 +306,7 @@
 		redraw();
 		break;
 	case '.':
-		ctx.center = pos;
+		draw_ctx.center = pos;
 		redraw();
 		break;
 	case GDK_BackSpace:
@@ -361,8 +360,8 @@
     gpointer data)
 {
 	if (dragging)
-		tool_cancel_drag(&ctx);
-	tool_dehover(&ctx);
+		tool_cancel_drag();
+	tool_dehover();
 	dragging = 0;
 	return TRUE;
 }
@@ -422,7 +421,7 @@
 	    GDK_SCROLL |
 	    GDK_POINTER_MOTION_MASK);
 
-	ctx.widget = canvas;
+	draw_ctx.widget = canvas;
 
 	return canvas;
 }

Modified: trunk/eda/fped/gui_canvas.h
===================================================================
--- trunk/eda/fped/gui_canvas.h	2009-08-07 21:47:51 UTC (rev 5404)
+++ trunk/eda/fped/gui_canvas.h	2009-08-08 14:11:26 UTC (rev 5405)
@@ -22,7 +22,7 @@
  * of objects.
  */
 
-extern void (*highlight)(struct draw_ctx *ctx);
+extern void (*highlight)(void);
 
 
 void redraw(void);

Modified: trunk/eda/fped/gui_inst.c
===================================================================
--- trunk/eda/fped/gui_inst.c	2009-08-07 21:47:51 UTC (rev 5404)
+++ trunk/eda/fped/gui_inst.c	2009-08-08 14:11:26 UTC (rev 5405)
@@ -24,35 +24,31 @@
 #include "gui_inst.h"
 
 
-#define DA	GDK_DRAWABLE(ctx->widget->window)
-
-
 /* ----- coordinate translation -------------------------------------------- */
 
 
-struct coord translate(const struct draw_ctx *ctx, struct coord pos)
+struct coord translate(struct coord pos)
 {
-	pos.x -= ctx->center.x;
-	pos.y -= ctx->center.y;
-	pos.x /= ctx->scale;
-	pos.y /= ctx->scale;
+	pos.x -= draw_ctx.center.x;
+	pos.y -= draw_ctx.center.y;
+	pos.x /= draw_ctx.scale;
+	pos.y /= draw_ctx.scale;
 	pos.y = -pos.y;
-	pos.x += ctx->widget->allocation.width/2;
-	pos.y += ctx->widget->allocation.height/2;
-//fprintf(stderr, "%d %d\n", (int) pos.x, (int) pos.y);
+	pos.x += draw_ctx.widget->allocation.width/2;
+	pos.y += draw_ctx.widget->allocation.height/2;
 	return pos;
 }
 
 
-struct coord canvas_to_coord(const struct draw_ctx *ctx, int x, int y)
+struct coord canvas_to_coord(int x, int y)
 {
 	struct coord pos;
 
-	x -= ctx->widget->allocation.width/2;
-	y -= ctx->widget->allocation.height/2;
+	x -= draw_ctx.widget->allocation.width/2;
+	y -= draw_ctx.widget->allocation.height/2;
 	y = -y;
-	pos.x = x*ctx->scale+ctx->center.x;
-	pos.y = y*ctx->scale+ctx->center.y;
+	pos.x = x*draw_ctx.scale+draw_ctx.center.x;
+	pos.y = y*draw_ctx.scale+draw_ctx.center.y;
 	return pos;
 }
 
@@ -60,8 +56,7 @@
 /* ----- drawing primitives ------------------------------------------------ */
 
 
-static void draw_eye(struct draw_ctx *ctx, GdkGC *gc, struct coord center,
-    int r1, int r2)
+static void draw_eye(GdkGC *gc, struct coord center, int r1, int r2)
 {
 	draw_circle(DA, gc, TRUE, center.x, center.y, r1);
 	draw_circle(DA, gc, FALSE, center.x, center.y, r2);
@@ -71,7 +66,7 @@
 #define MAX_POINTS	10
 
 
-static void draw_poly(struct draw_ctx *ctx, GdkGC *gc, int fill,
+static void draw_poly(GdkGC *gc, int fill,
     const struct coord *points, int n_points)
 {
 	GdkPoint gp[MAX_POINTS];
@@ -92,7 +87,7 @@
 }
 
 
-static void draw_arrow(struct draw_ctx *ctx, GdkGC *gc, int fill,
+static void draw_arrow(GdkGC *gc, int fill,
     struct coord from, struct coord to, int len, double angle)
 {
 	struct coord p[3];
@@ -107,7 +102,7 @@
 	p[0] = add_vec(to, rotate(side, 180-angle));
 	p[1] = to;
 	p[2] = add_vec(to, rotate(side, 180+angle));
-	draw_poly(ctx, gc, fill, p, 3);
+	draw_poly(gc, fill, p, 3);
 }
 
 
@@ -149,32 +144,22 @@
 }
 
 
-void gui_hover_vec(struct inst *self, struct draw_ctx *ctx)
+void gui_highlight_vec(struct inst *self)
 {
-	struct coord center = translate(ctx, self->u.rect.end);
-	GdkGC *gc;
+	struct coord center = translate(self->u.rect.end);
 
-	gc = gc_vec[mode_hover];
-	draw_circle(DA, gc, FALSE, center.x, center.y, VEC_EYE_R);
-}
-
-
-void gui_highlight_vec(struct inst *self, struct draw_ctx *ctx)
-{
-	struct coord center = translate(ctx, self->u.rect.end);
-
 	draw_circle(DA, gc_highlight, FALSE, center.x, center.y, VEC_EYE_R);
 }
 
 
-void gui_draw_vec(struct inst *self, struct draw_ctx *ctx)
+void gui_draw_vec(struct inst *self)
 {
-	struct coord from = translate(ctx, self->base);
-	struct coord to = translate(ctx, self->u.rect.end);
+	struct coord from = translate(self->base);
+	struct coord to = translate(self->u.rect.end);
 	GdkGC *gc;
 
 	gc = gc_vec[get_mode(self)];
-	draw_arrow(ctx, gc, TRUE, from, to, VEC_ARROW_LEN, VEC_ARROW_ANGLE);
+	draw_arrow(gc, TRUE, from, to, VEC_ARROW_LEN, VEC_ARROW_ANGLE);
 	gdk_draw_line(DA, gc, from.x, from.y, to.x, to.y);
 	draw_circle(DA, gc, FALSE, to.x, to.y, VEC_EYE_R);
 }
@@ -195,14 +180,14 @@
 }
 
 
-void gui_draw_line(struct inst *self, struct draw_ctx *ctx)
+void gui_draw_line(struct inst *self)
 {
-	struct coord min = translate(ctx, self->base);
-	struct coord max = translate(ctx, self->u.rect.end);
+	struct coord min = translate(self->base);
+	struct coord max = translate(self->u.rect.end);
 	GdkGC *gc;
 
 	gc = gc_obj[get_mode(self)];
-	set_width(gc, self->u.rect.width/ctx->scale);
+	set_width(gc, self->u.rect.width/draw_ctx.scale);
 	gdk_draw_line(DA, gc, min.x, min.y, max.x, max.y);
 }
 
@@ -222,15 +207,15 @@
 }
 
 
-void gui_draw_rect(struct inst *self, struct draw_ctx *ctx)
+void gui_draw_rect(struct inst *self)
 {
-	struct coord min = translate(ctx, self->base);
-	struct coord max = translate(ctx, self->u.rect.end);
+	struct coord min = translate(self->base);
+	struct coord max = translate(self->u.rect.end);
 	GdkGC *gc;
 
 	sort_coord(&min, &max);
 	gc = gc_obj[get_mode(self)];
-	set_width(gc, self->u.rect.width/ctx->scale);
+	set_width(gc, self->u.rect.width/draw_ctx.scale);
 	gdk_draw_rectangle(DA, gc, FALSE,
 	    min.x, min.y, max.x-min.x, max.y-min.y);
 }
@@ -250,10 +235,10 @@
 }
 
 
-void gui_draw_pad(struct inst *self, struct draw_ctx *ctx)
+void gui_draw_pad(struct inst *self)
 {
-	struct coord min = translate(ctx, self->base);
-	struct coord max = translate(ctx, self->u.pad.other);
+	struct coord min = translate(self->base);
+	struct coord max = translate(self->u.pad.other);
 	GdkGC *gc;
 	struct coord c;
 	unit_type h, w;
@@ -323,15 +308,15 @@
 }
 
 
-void gui_draw_arc(struct inst *self, struct draw_ctx *ctx)
+void gui_draw_arc(struct inst *self)
 {
-	struct coord center = translate(ctx, self->base);
+	struct coord center = translate(self->base);
 	GdkGC *gc;
 
 	gc = gc_obj[get_mode(self)];
-	set_width(gc, self->u.arc.width/ctx->scale);
+	set_width(gc, self->u.arc.width/draw_ctx.scale);
 	draw_arc(DA, gc, FALSE, center.x, center.y,
-	    self->u.arc.r/ctx->scale, self->u.arc.a1, self->u.arc.a2);
+	    self->u.arc.r/draw_ctx.scale, self->u.arc.a1, self->u.arc.a2);
 }
 
 
@@ -368,7 +353,7 @@
 }
 
 
-void gui_draw_meas(struct inst *self, struct draw_ctx *ctx)
+void gui_draw_meas(struct inst *self)
 {
 	struct coord a0, b0, a1, b1, off, c, d;
 	GdkGC *gc;
@@ -377,8 +362,8 @@
 	    self->u.meas.meas->label ? self->u.meas.meas->label : "" : "";
 	char *s;
 
-	a0 = translate(ctx, self->base);
-	b0 = translate(ctx, self->u.meas.end);
+	a0 = translate(self->base);
+	b0 = translate(self->u.meas.end);
 	a1 = self->base;
 	b1 = self->u.meas.end;
 	switch (self->u.meas.meas ? self->u.meas.meas->type : mt_xy_next) {
@@ -398,14 +383,14 @@
 	}
 	off = offset_vec(a1, b1, self);
 	len = units_to_mm(dist_point(a1, b1));
-	a1 = translate(ctx, add_vec(a1, off));
-	b1 = translate(ctx, add_vec(b1, off));
+	a1 = translate(add_vec(a1, off));
+	b1 = translate(add_vec(b1, off));
 	gc = gc_meas[get_mode(self)];
 	gdk_draw_line(DA, gc, a0.x, a0.y, a1.x, a1.y);
 	gdk_draw_line(DA, gc, b0.x, b0.y, b1.x, b1.y);
 	gdk_draw_line(DA, gc, a1.x, a1.y, b1.x, b1.y);
-	draw_arrow(ctx, gc, FALSE, a1, b1, MEAS_ARROW_LEN, MEAS_ARROW_ANGLE);
-	draw_arrow(ctx, gc, FALSE, b1, a1, MEAS_ARROW_LEN, MEAS_ARROW_ANGLE);
+	draw_arrow(gc, FALSE, a1, b1, MEAS_ARROW_LEN, MEAS_ARROW_ANGLE);
+	draw_arrow(gc, FALSE, b1, a1, MEAS_ARROW_LEN, MEAS_ARROW_ANGLE);
 
 	c = add_vec(a1, b1);
 	d = sub_vec(b1, a1);
@@ -464,27 +449,17 @@
 }
 
 
-void gui_hover_frame(struct inst *self, struct draw_ctx *ctx)
+void gui_draw_frame(struct inst *self)
 {
-	struct coord center = translate(ctx, self->base);
-	GdkGC *gc;
-
-	gc = gc_frame[mode_hover];
-	draw_circle(DA, gc, FALSE, center.x, center.y, FRAME_EYE_R2);
-}
-
-
-void gui_draw_frame(struct inst *self, struct draw_ctx *ctx)
-{
-	struct coord center = translate(ctx, self->base);
+	struct coord center = translate(self->base);
 	struct coord corner = { self->bbox.min.x, self->bbox.max.y };
 	GdkGC *gc;
 
 	gc = self->u.frame.active ? gc_active_frame : gc_frame[get_mode(self)];
-	draw_eye(ctx, gc, center, FRAME_EYE_R1, FRAME_EYE_R2);
+	draw_eye(gc, center, FRAME_EYE_R1, FRAME_EYE_R2);
 	if (!self->u.frame.ref->name)
 		return;
-	corner = translate(ctx, corner);
+	corner = translate(corner);
 	corner.x -= FRAME_CLEARANCE;
 	corner.y -= FRAME_CLEARANCE;
 	gdk_draw_line(DA, gc, corner.x, corner.y,

Modified: trunk/eda/fped/gui_inst.h
===================================================================
--- trunk/eda/fped/gui_inst.h	2009-08-07 21:47:51 UTC (rev 5404)
+++ trunk/eda/fped/gui_inst.h	2009-08-08 14:11:26 UTC (rev 5405)
@@ -20,16 +20,9 @@
 #include "inst.h"
 
 
-struct draw_ctx {
-	GtkWidget *widget;
-	int scale;
-	struct coord center;
-};
+struct coord translate(struct coord pos);
+struct coord canvas_to_coord(int x, int y);
 
-
-struct coord translate(const struct draw_ctx *ctx, struct coord pos);
-struct coord canvas_to_coord(const struct draw_ctx *ctx, int x, int y);
-
 unit_type gui_dist_vec(struct inst *self, struct coord pos, unit_type scale);
 unit_type gui_dist_vec_fallback(struct inst *self, struct coord pos,
     unit_type scale);
@@ -42,16 +35,14 @@
 unit_type gui_dist_frame_eye(struct inst *self, struct coord pos,
     unit_type scale);
 
-void gui_draw_vec(struct inst *self, struct draw_ctx *ctx);
-void gui_draw_line(struct inst *self, struct draw_ctx *ctx);
-void gui_draw_rect(struct inst *self, struct draw_ctx *ctx);
-void gui_draw_pad(struct inst *self, struct draw_ctx *ctx);
-void gui_draw_arc(struct inst *self, struct draw_ctx *ctx);
-void gui_draw_meas(struct inst *self, struct draw_ctx *ctx);
-void gui_draw_frame(struct inst *self, struct draw_ctx *ctx);
+void gui_draw_vec(struct inst *self);
+void gui_draw_line(struct inst *self);
+void gui_draw_rect(struct inst *self);
+void gui_draw_pad(struct inst *self);
+void gui_draw_arc(struct inst *self);
+void gui_draw_meas(struct inst *self);
+void gui_draw_frame(struct inst *self);
 
-void gui_highlight_vec(struct inst *self, struct draw_ctx *ctx);
-void gui_hover_vec(struct inst *self, struct draw_ctx *ctx);
-void gui_hover_frame(struct inst *self, struct draw_ctx *ctx);
+void gui_highlight_vec(struct inst *self);
 
 #endif /* !GUI_INST_H */

Added: trunk/eda/fped/gui_over.c
===================================================================
--- trunk/eda/fped/gui_over.c	                        (rev 0)
+++ trunk/eda/fped/gui_over.c	2009-08-08 14:11:26 UTC (rev 5405)
@@ -0,0 +1,211 @@
+/*
+ * gui_over.c - GUI, canvas overlays
+ *
+ * Written 2009 by Werner Almesberger
+ * Copyright 2009 by Werner Almesberger
+ *
+ * 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 file is for the overlay state machine only. Given the heavy use of
+ * global variables, adding other functionality would quickly render it
+ * illegible.
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "coord.h"
+#include "gui_util.h"
+#include "gui_over.h"
+
+
+#if 0
+#define DPRINTF(fmt, ...)	fprintf(stderr, fmt "\n", ##__VA_ARGS__)
+#else
+#define	DPRINTF(fmt, ...)
+#endif
+
+
+static enum states {
+	NOTHING,
+	HOVER,
+	DRAG,
+	BOTH,
+} state = NOTHING;
+
+
+/*
+ * We cache some externally provided state so that we can redraw without the
+ * outside telling us what to redraw, etc.
+ */
+
+static struct pix_buf *buf_D, *buf_H;
+static struct pix_buf *(*over_D_save_and_draw)(void *user, struct coord to);
+static void *over_D_user;
+static struct pix_buf *(*over_H_save_and_draw)(void *user);
+static void *over_H_user;
+static struct coord over_pos;
+
+
+/* ----- actions ----------------------------------------------------------- */
+
+
+static void draw_D(void)
+{
+	buf_D = over_D_save_and_draw(over_D_user, over_pos);
+}
+
+
+static void draw_H(void)
+{
+	buf_H = over_H_save_and_draw(over_H_user);
+}
+
+
+#define STATE(s)	DPRINTF("%s", #s); state = s; break;
+#define	restore(x)	DPRINTF("  restore(%s)", #x); restore_pix_buf(buf_##x)
+#define	drop(x)		DPRINTF("  drop(%s)", #x); free_pix_buf(buf_##x)
+#define	save(x)		DPRINTF("  save(%s)", #x)
+#define	draw(x)		DPRINTF("  draw(%s)", #x); draw_##x()
+#define	update()	DPRINTF("  update"); over_pos = pos
+
+
+/* ----- state machine ----------------------------------------------------- */
+
+
+void over_enter(struct pix_buf *(*save_and_draw)(void *user), void *user)
+{
+	over_H_save_and_draw = save_and_draw;
+	over_H_user = user;
+
+	DPRINTF("enter");
+	switch (state) {
+	case NOTHING:
+		save(H);
+		draw(H);
+		STATE(HOVER);
+	case DRAG:
+		restore(D);
+		save(H);
+		draw(H);
+		save(D);
+		draw(D);
+		STATE(BOTH);
+	default:
+		abort();
+	}
+}
+
+
+void over_leave(void)
+{
+	DPRINTF("leave");
+	switch (state) {
+	case HOVER:
+		restore(H);
+		STATE(NOTHING);
+	case BOTH:
+		restore(D);
+		restore(H);
+		save(D);
+		draw(D);
+		STATE(DRAG);
+	default:
+		abort();
+	}
+}
+
+
+void over_begin(struct pix_buf *(*save_and_draw)(void *user, struct coord to),
+    void *user, struct coord pos)
+{
+	over_pos = pos;
+	over_D_save_and_draw = save_and_draw;
+	over_D_user = user;
+
+	DPRINTF("begin");
+	switch (state) {
+	case NOTHING:
+		save(D);
+		draw(D);
+		STATE(DRAG);
+	case HOVER:
+		save(D);
+		draw(D);
+		STATE(BOTH);
+	default:
+		abort();
+	}
+}
+
+
+void over_move(struct coord pos)
+{
+	over_pos = pos;
+
+	DPRINTF("move");
+	switch (state) {
+	case NOTHING:
+		break;
+	case HOVER:
+		break;
+	case DRAG:
+		restore(D);
+		update();
+		save(D);
+		draw(D);
+		STATE(DRAG);
+	case BOTH:
+		restore(D);
+		update();
+		save(D);
+		draw(D);
+		STATE(BOTH);
+	default:
+		abort();
+	}
+}
+
+
+void over_end(void)
+{
+	DPRINTF("end");
+	switch (state) {
+	case DRAG:
+		restore(D);
+		STATE(NOTHING);
+	case BOTH:
+		restore(D);
+		STATE(HOVER);
+	default:
+		abort();
+	}
+}
+
+
+void over_reset(void)
+{
+	DPRINTF("reset");
+	switch (state) {
+	case NOTHING:
+		break;
+	case HOVER:
+		drop(H);
+		STATE(NOTHING);
+	case DRAG:
+		drop(D);
+		STATE(NOTHING);
+	case BOTH:
+		drop(D);
+		drop(H);
+		STATE(NOTHING);
+	default:
+		abort();
+	}
+}

Added: trunk/eda/fped/gui_over.h
===================================================================
--- trunk/eda/fped/gui_over.h	                        (rev 0)
+++ trunk/eda/fped/gui_over.h	2009-08-08 14:11:26 UTC (rev 5405)
@@ -0,0 +1,79 @@
+/*
+ * gui_over.h - GUI, canvas overlays
+ *
+ * Written 2009 by Werner Almesberger
+ * Copyright 2009 by Werner Almesberger
+ *
+ * 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.
+ */
+
+
+#ifndef GUI_OVER_H
+#define	GUI_OVER_H
+
+/*
+ * Dynamic changes around the pointer are affected by the following events:
+ *
+ * - enter: enter a circle where we're hovering
+ * - leave: leave a circle where we've been hovering
+ * - begin: begin dragging
+ * - move: move with or without dragging
+ * - end: end dragging
+ * - reset: we got a redraw, just drop everything
+ *
+ * We have the following states:
+ *
+ * - NOTHING: neither hovering nor dragging
+ * - HOVER: we're hovering but not dragging
+ * - DRAG: we're dragging but not hovering, e.g., when searching for a place to
+ *   end the drag
+ * - BOTH: we're dragging and hovering
+ *
+ * Both drag and hover save the area being changed and restore it after a
+ * change. We have to make sure the save/draw/restore operations are properly
+ * sequenced. We call the hover area H, the drag area D. This is the state
+ * machine that does the sequencing:
+ *
+ * NOTHING (saved: -)
+ *	enter -> save H, draw H, HOVER
+ *	begin -> save D, draw D, DRAG
+ *	move -> NOTHING
+ *	reset -> NOTHING
+ *
+ * HOVER: (saved: H)
+ *	leave -> restore H, NOTHING
+ *	begin -> save D, draw D, BOTH
+ *	move -> HOVER
+ *	reset -> drop H, NOTHING
+ *
+ * DRAG: (saved: D)
+ *	end -> restore D, NOTHING
+ *	enter -> restore D, save H, draw H, save D, draw D, BOTH
+ *	move -> restore D, update, save D, draw D, DRAG
+ *	reset -> drop D, NOTHING
+ *
+ * BOTH: (saved: D on top of H)
+ *	end -> restore D, HOVER
+ *	leave -> restore D, restore H, save D, draw D, DRAG
+ *	move -> restore D, update, save D, draw D, BOTH
+ *	reset -> drop D, drop H, NOTHING
+ */
+
+#include "coord.h"
+#include "inst.h"
+
+
+void over_enter(struct pix_buf *(*save_and_draw)(void *user), void *user);
+void over_leave(void);
+
+void over_begin(struct pix_buf *(*save_and_draw)(void *user, struct coord pos),
+    void *user, struct coord pos);
+void over_move(struct coord pos);
+void over_end(void);
+
+void over_reset(void);
+
+#endif /* !GUI_OVER_H */

Modified: trunk/eda/fped/gui_style.c
===================================================================
--- trunk/eda/fped/gui_style.c	2009-08-07 21:47:51 UTC (rev 5404)
+++ trunk/eda/fped/gui_style.c	2009-08-08 14:11:26 UTC (rev 5405)
@@ -74,5 +74,5 @@
 	gc_active_frame = gc("#00ff00", 2);
 //	gc_highlight = gc("#ff8020", 2);
 	gc_highlight = gc("#ff90d0", 2);
-	gc_frame[mode_hover] = gc_vec[mode_hover] = gc("#c00000", 1);
+	gc_frame[mode_hover] = gc_vec[mode_hover] = gc("#c00000", 2);
 }

Modified: trunk/eda/fped/gui_tools.c
===================================================================
--- trunk/eda/fped/gui_tools.c	2009-08-07 21:47:51 UTC (rev 5404)
+++ trunk/eda/fped/gui_tools.c	2009-08-08 14:11:26 UTC (rev 5405)
@@ -22,6 +22,7 @@
 #include "gui_util.h"
 #include "gui_style.h"
 #include "gui_inst.h"
+#include "gui_over.h"
 #include "gui_canvas.h"
 #include "gui_status.h"
 #include "gui.h"
@@ -43,19 +44,13 @@
 #include "icons/vec.xpm"
 
 
-#define DA	GDK_DRAWABLE(ctx->widget->window)
-
-
 struct tool_ops {
 	void (*tool_selected)(void);
 	void (*tool_deselected)(void);
-	void (*click)(struct draw_ctx *ctx, struct coord pos);
-	struct pix_buf *(*drag_new)(struct draw_ctx *ctx, struct inst *from,
-	     struct coord to);
-	int (*end_new_raw)(struct draw_ctx *ctx, struct inst *from,
-	    struct coord to);
-	int (*end_new)(struct draw_ctx *ctx, struct inst *from,
-	    struct inst *to);
+	void (*click)(struct coord pos);
+	struct pix_buf *(*drag_new)(struct inst *from, struct coord to);
+	int (*end_new_raw)(struct inst *from, struct coord to);
+	int (*end_new)(struct inst *from, struct inst *to);
 };
 
 
@@ -76,7 +71,6 @@
 	.anchors_n = 0,
 };
 
-static struct pix_buf *pix_buf;
 static struct coord last_canvas_pos;
 
 
@@ -116,14 +110,14 @@
 
 
 static struct pix_buf *draw_move_line_common(struct inst *inst,
-    struct coord end, struct draw_ctx *ctx, struct coord pos, int i)
+    struct coord end, struct coord pos, int i)
 {
 	struct coord from, to;
 	struct pix_buf *buf;
 
-	from = translate(ctx, inst->base);
-	to = translate(ctx, end);
-	pos = translate(ctx, pos);
+	from = translate(inst->base);
+	to = translate(end);
+	pos = translate(pos);
 	switch (i) {
 	case 0:
 		from = pos;
@@ -141,14 +135,14 @@
 
 
 static struct pix_buf *draw_move_rect_common(struct inst *inst,
-    struct coord other, struct draw_ctx *ctx, struct coord pos, int i)
+    struct coord other, struct coord pos, int i)
 {
 	struct coord min, max;
 	struct pix_buf *buf;
 
-	min = translate(ctx, inst->base);
-	max = translate(ctx, other);
-	pos = translate(ctx, pos);
+	min = translate(inst->base);
+	max = translate(other);
+	pos = translate(pos);
 	switch (i) {
 	case 0:
 		min = pos;
@@ -167,15 +161,27 @@
 }
 
 
+static struct pix_buf *hover_common(GdkGC *gc, struct coord center, unit_type r)
+{
+	struct pix_buf *buf;
+
+	center = translate(center);
+	buf = save_pix_buf(DA,
+	    center.x-r, center.y-r, center.x+r, center.y+r, 2);
+	draw_circle(DA, gc, FALSE, center.x, center.y, VEC_EYE_R);
+	return buf;
+}
+
+
 /* ----- delete ------------------------------------------------------------ */
 
 
-static void click_delete(struct draw_ctx *ctx, struct coord pos)
+static void click_delete(struct coord pos)
 {
 	inst_deselect();
-	inst_select(ctx, pos);
+	inst_select(pos);
 	if (selected_inst) {
-		tool_dehover(ctx);
+		tool_dehover();
 		inst_delete(selected_inst);
 	}
 	change_world();
@@ -208,8 +214,7 @@
 }
 
 
-static struct pix_buf *drag_new_vec(struct draw_ctx *ctx,
-    struct inst *from, struct coord to)
+static struct pix_buf *drag_new_vec(struct inst *from, struct coord to)
 {
 	struct coord pos;
 	struct pix_buf *buf;
@@ -220,25 +225,30 @@
 	status_set_type_y("dX =");
 	status_set_x("%lg mm", units_to_mm(to.x-pos.x));
 	status_set_y("%lg mm", units_to_mm(to.y-pos.y));
-	pos = translate(ctx, pos);
-	to = translate(ctx, to);
+	pos = translate(pos);
+	to = translate(to);
 	buf = save_pix_buf(DA, pos.x, pos.y, to.x, to.y, 1);
 	gdk_draw_line(DA, gc_drag, pos.x, pos.y, to.x, to.y);
 	return buf;
 }
 
 
-struct pix_buf *draw_move_vec(struct inst *inst, struct draw_ctx *ctx,
-    struct coord pos, int i)
+struct pix_buf *draw_move_vec(struct inst *inst, struct coord pos, int i)
 {
 	return draw_move_line_common(inst,
-	    add_vec(sub_vec(inst->u.rect.end, inst->base), pos), ctx, pos, i);
+	    add_vec(sub_vec(inst->u.rect.end, inst->base), pos), pos, i);
 }
 
 
-static int end_new_raw_vec(struct draw_ctx *ctx,
-    struct inst *from, struct coord to)
+struct pix_buf *gui_hover_vec(struct inst *self)
 {
+	return hover_common(gc_vec[mode_hover],
+	    self->u.rect.end, VEC_EYE_R);
+}
+
+
+static int end_new_raw_vec(struct inst *from, struct coord to)
+{
 	struct vec *vec;
 	struct coord pos;
 
@@ -260,29 +270,26 @@
 /* ----- line -------------------------------------------------------------- */
 
 
-static struct pix_buf *drag_new_line(struct draw_ctx *ctx,
-    struct inst *from, struct coord to)
+static struct pix_buf *drag_new_line(struct inst *from, struct coord to)
 {
 	struct coord pos;
 	struct pix_buf *buf;
 
-	pos = translate(ctx, inst_get_point(from));
-	to = translate(ctx, to);
+	pos = translate(inst_get_point(from));
+	to = translate(to);
 	buf = save_pix_buf(DA, pos.x, pos.y, to.x, to.y, 1);
 	gdk_draw_line(DA, gc_drag, pos.x, pos.y, to.x, to.y);
 	return buf;
 }
 
 
-struct pix_buf *draw_move_line(struct inst *inst, struct draw_ctx *ctx,
-    struct coord pos, int i)
+struct pix_buf *draw_move_line(struct inst *inst, struct coord pos, int i)
 {
-	return draw_move_line_common(inst, inst->u.rect.end, ctx, pos, i);
+	return draw_move_line_common(inst, inst->u.rect.end, pos, i);
 }
 
 
-static int end_new_line(struct draw_ctx *ctx,
-    struct inst *from, struct inst *to)
+static int end_new_line(struct inst *from, struct inst *to)
 {
 	struct obj *obj;
 
@@ -304,14 +311,13 @@
 /* ----- rect -------------------------------------------------------------- */
 
 
-static struct pix_buf *drag_new_rect(struct draw_ctx *ctx,
-    struct inst *from, struct coord to)
+static struct pix_buf *drag_new_rect(struct inst *from, struct coord to)
 {
 	struct coord pos;
 	struct pix_buf *buf;
 
-	pos = translate(ctx, inst_get_point(from));
-	to = translate(ctx, to);
+	pos = translate(inst_get_point(from));
+	to = translate(to);
 	sort_coord(&pos, &to);
 	buf = save_pix_buf(DA, pos.x, pos.y, to.x, to.y, 1);
 	gdk_draw_rectangle(DA, gc_drag, FALSE,
@@ -320,15 +326,13 @@
 }
 
 
-struct pix_buf *draw_move_rect(struct inst *inst, struct draw_ctx *ctx,
-    struct coord pos, int i)
+struct pix_buf *draw_move_rect(struct inst *inst, struct coord pos, int i)
 {
-	return draw_move_rect_common(inst, inst->u.rect.end, ctx, pos, i);
+	return draw_move_rect_common(inst, inst->u.rect.end, pos, i);
 }
 
 
-static int end_new_rect(struct draw_ctx *ctx,
-    struct inst *from, struct inst *to)
+static int end_new_rect(struct inst *from, struct inst *to)
 {
 	struct obj *obj;
 
@@ -350,8 +354,7 @@
 /* ----- pad --------------------------------------------------------------- */
 
 
-static int end_new_pad(struct draw_ctx *ctx,
-    struct inst *from, struct inst *to)
+static int end_new_pad(struct inst *from, struct inst *to)
 {
 	struct obj *obj;
 
@@ -364,10 +367,9 @@
 }
 
 
-struct pix_buf *draw_move_pad(struct inst *inst, struct draw_ctx *ctx,
-    struct coord pos, int i)
+struct pix_buf *draw_move_pad(struct inst *inst, struct coord pos, int i)
 {
-	return draw_move_rect_common(inst, inst->u.pad.other, ctx, pos, i);
+	return draw_move_rect_common(inst, inst->u.pad.other, pos, i);
 }
 
 
@@ -380,15 +382,14 @@
 /* ----- circ -------------------------------------------------------------- */
 
 
-static struct pix_buf *drag_new_circ(struct draw_ctx *ctx,
-    struct inst *from, struct coord to)
+static struct pix_buf *drag_new_circ(struct inst *from, struct coord to)
 {
 	struct coord pos;
 	struct pix_buf *buf;
 	double r;
 
-	pos = translate(ctx, inst_get_point(from));
-	to = translate(ctx, to);
+	pos = translate(inst_get_point(from));
+	to = translate(to);
 	r = hypot(to.x-pos.x, to.y-pos.y);
 	buf = save_pix_buf(DA, pos.x-r, pos.y-r, pos.x+r, pos.y+r, 1);
 	draw_circle(DA, gc_drag, FALSE, pos.x, pos.y, r);
@@ -396,8 +397,7 @@
 }
 
 
-static int end_new_circ(struct draw_ctx *ctx,
-    struct inst *from, struct inst *to)
+static int end_new_circ(struct inst *from, struct inst *to)
 {
 	struct obj *obj;
 
@@ -411,19 +411,18 @@
 }
 
 
-struct pix_buf *draw_move_arc(struct inst *inst, struct draw_ctx *ctx,
-    struct coord pos, int i)
+struct pix_buf *draw_move_arc(struct inst *inst, struct coord pos, int i)
 {
 	struct coord c, from, to, end;
 	double r, r_save, a1, a2;
 	struct pix_buf *buf;
 
-	c = translate(ctx, inst->base);
+	c = translate(inst->base);
 	from =
-	    translate(ctx, rotate_r(inst->base, inst->u.arc.r, inst->u.arc.a1));
+	    translate(rotate_r(inst->base, inst->u.arc.r, inst->u.arc.a1));
 	to =
-	    translate(ctx, rotate_r(inst->base, inst->u.arc.r, inst->u.arc.a2));
-	pos = translate(ctx, pos);
+	    translate(rotate_r(inst->base, inst->u.arc.r, inst->u.arc.a2));
+	pos = translate(pos);
 	switch (i) {
 	case 0:
 		c = pos;
@@ -500,15 +499,13 @@
 /* ----- meas -------------------------------------------------------------- */
 
 
-struct pix_buf *draw_move_meas(struct inst *inst, struct draw_ctx *ctx,
-    struct coord pos, int i)
+struct pix_buf *draw_move_meas(struct inst *inst, struct coord pos, int i)
 {
-	return draw_move_line_common(inst, inst->u.meas.end, ctx, pos, i);
+	return draw_move_line_common(inst, inst->u.meas.end, pos, i);
 }
 
 
-static int end_new_meas(struct draw_ctx *ctx,
-    struct inst *from, struct inst *to)
+static int end_new_meas(struct inst *from, struct inst *to)
 {
 	struct obj *obj;
 
@@ -533,9 +530,9 @@
 }
 
 
-static void highlight_vecs(struct draw_ctx *ctx)
+static void highlight_vecs(void)
 {
-	inst_highlight_vecs(ctx, meas_x_pick_vec, NULL);
+	inst_highlight_vecs(meas_x_pick_vec, NULL);
 }
 
 
@@ -645,22 +642,27 @@
 /* ----- frame ------------------------------------------------------------- */
 
 
-struct pix_buf *draw_move_frame(struct inst *inst, struct draw_ctx *ctx,
-    struct coord pos, int i)
+struct pix_buf *draw_move_frame(struct inst *inst, struct coord pos, int i)
 {
 	struct pix_buf *buf;
 	int r = FRAME_EYE_R2;
 
-	pos = translate(ctx, pos);
+	pos = translate(pos);
 	buf = save_pix_buf(DA, pos.x-r, pos.y-r, pos.x+r, pos.y+r, 1);
 	draw_arc(DA, gc_drag, FALSE, pos.x, pos.y, r, 0, 360);
 	return buf;
 }
 
 
-static int end_new_frame(struct draw_ctx *ctx,
-    struct inst *from, struct inst *to)
+struct pix_buf *gui_hover_frame(struct inst *self)
 {
+	return hover_common(gc_frame[mode_hover],
+	    self->base, FRAME_EYE_R2);
+}
+
+
+static int end_new_frame(struct inst *from, struct inst *to)
+{
 	struct obj *obj;
 
 	if (!locked_frame || is_parent_of(locked_frame, active_frame))
@@ -745,19 +747,28 @@
 /* ----- hover ------------------------------------------------------------- */
 
 
-void tool_dehover(struct draw_ctx *ctx)
+static struct pix_buf *hover_save_and_draw(void *user)
 {
-	if (hover_inst)
-		inst_hover(hover_inst, ctx, 0);
+	return inst_hover(hover_inst);
+}
+
+
+void tool_dehover(void)
+{
+	if (!hover_inst)
+		return;
+	over_leave();
 	hover_inst = NULL;
 }
 
 
-void tool_hover(struct draw_ctx *ctx, struct coord pos)
+void tool_hover(struct coord pos)
 {
 	struct inst *curr;
 
-	curr = inst_find_point(ctx, pos);
+	curr = inst_find_point(pos);
+	if ((drag.new && curr == drag.new) || (drag.inst && curr == drag.inst))
+		return;
 	if (curr && !active_ops) {
 		if (drag.anchors_n) {
 			if (!may_move_to(&drag, curr))
@@ -768,42 +779,58 @@
 			drag.anchors_n = 0;
 		}
 	}
-	if (curr != hover_inst)
-		tool_dehover(ctx);
-	if (curr) {
-		inst_hover(curr, ctx, 1);
-		hover_inst = curr;
+	if (curr == hover_inst)
+		return;
+	if (hover_inst) {
+		over_leave();
+		hover_inst = NULL;
 	}
+	if (!curr)
+		return;
+	hover_inst = curr;
+	over_enter(hover_save_and_draw, NULL);
 }
 
 
 /* ----- mouse actions ----------------------------------------------------- */
 
 
-int tool_consider_drag(struct draw_ctx *ctx, struct coord pos)
+static struct pix_buf *drag_save_and_draw(void *user, struct coord to)
 {
+	if (drag.new) {
+		assert(active_ops);
+		return active_ops->drag_new(drag.new, to);
+	} else {
+		return inst_draw_move(drag.inst, to, drag.anchor_i);
+	}
+}
+
+
+int tool_consider_drag(struct coord pos)
+{
 	struct inst *curr;
 
 	assert(!drag.new);
 	assert(!drag.anchors_n);
-	last_canvas_pos = translate(ctx, pos);
+	last_canvas_pos = translate(pos);
 	if (active_ops && active_ops->click) {
-		active_ops->click(ctx, pos);
+		active_ops->click(pos);
 		return 0;
 	}
-	curr = inst_find_point(ctx, pos);
+	curr = inst_find_point(pos);
 	if (!curr)
 		return 0;
-	pix_buf = NULL;
+	tool_dehover();
 	if (active_ops) {
 		if (active_ops->drag_new) {
 			drag.inst = NULL;
 			drag.new = curr;
+			over_begin(drag_save_and_draw, NULL, pos);
 			return 1;
 		} else {
 			/* object is created without dragging */
-			if (active_ops->end_new(ctx, curr, NULL)) {
-				tool_cancel_drag(ctx);
+			if (active_ops->end_new(curr, NULL)) {
+				tool_cancel_drag();
 				return -1;
 			}
 			return 0;
@@ -813,49 +840,43 @@
 		return 0;
 	drag.inst = selected_inst;
 	drag.new = NULL;
+	over_begin(drag_save_and_draw, NULL, pos);
 	return 1;
 }
 
 
-void tool_drag(struct draw_ctx *ctx, struct coord to)
+void tool_drag(struct coord to)
 {
-	if (pix_buf)
-		restore_pix_buf(pix_buf);
-	last_canvas_pos = translate(ctx, to);
-	tool_hover(ctx, to);
-	pix_buf = drag.new ? active_ops->drag_new(ctx, drag.new, to) :
-	    inst_draw_move(drag.inst, ctx, to, drag.anchor_i);
+	last_canvas_pos = translate(to);
+	over_move(to);
 }
 
 
-void tool_cancel_drag(struct draw_ctx *ctx)
+void tool_cancel_drag(void)
 {
-	tool_dehover(ctx);
+	over_end();
+	tool_dehover();
 	tool_reset();
-	if (pix_buf) {
-		restore_pix_buf(pix_buf);
-		pix_buf = NULL;
-	}
 	drag.new = NULL;
 	active_ops = NULL;
 	drag.anchors_n = 0;
 }
 
 
-int tool_end_drag(struct draw_ctx *ctx, struct coord to)
+int tool_end_drag(struct coord to)
 {
 	struct drag_state state = drag;
 	struct inst *end;
 	struct tool_ops *ops = active_ops;
 
-	tool_cancel_drag(ctx);
+	tool_cancel_drag();
 	if (state.new && ops->end_new_raw)
-		return ops->end_new_raw(ctx, state.new, to);
-	end = inst_find_point(ctx, to);
+		return ops->end_new_raw(state.new, to);
+	end = inst_find_point(to);
 	if (!end)
 		return 0;
 	if (state.new)
-		return ops->end_new(ctx, state.new, end);
+		return ops->end_new(state.new, end);
 	if (!may_move_to(&state, end))
 		return 0;
 	if (!inst_do_move_to(drag.inst, inst_get_vec(end), state.anchor_i))
@@ -864,15 +885,14 @@
 }
 
 
-void tool_redraw(struct draw_ctx *ctx)
+void tool_redraw(void)
 {
+	over_reset();
 	if (!drag.new && !drag.anchors_n)
 		return;
-	if (pix_buf)
-		free_pix_buf(pix_buf);
-	pix_buf = NULL;
-	tool_drag(ctx, canvas_to_coord(ctx,
-	    last_canvas_pos.x, last_canvas_pos.y));
+	tool_hover(last_canvas_pos);
+	over_begin(drag_save_and_draw, NULL,
+	    canvas_to_coord(last_canvas_pos.x, last_canvas_pos.y));
 }
 
 
@@ -901,6 +921,7 @@
 
 void tool_reset(void)
 {
+	over_reset();
 	tool_select(ev_point, NULL);
 }
 

Modified: trunk/eda/fped/gui_tools.h
===================================================================
--- trunk/eda/fped/gui_tools.h	2009-08-07 21:47:51 UTC (rev 5404)
+++ trunk/eda/fped/gui_tools.h	2009-08-08 14:11:26 UTC (rev 5405)
@@ -19,31 +19,29 @@
 #include "inst.h"
 
 
-struct pix_buf *draw_move_vec(struct inst *inst, struct draw_ctx *ctx,
-    struct coord pos, int i);
-struct pix_buf *draw_move_line(struct inst *inst, struct draw_ctx *ctx,
-    struct coord pos, int i);
-struct pix_buf *draw_move_rect(struct inst *inst, struct draw_ctx *ctx,
-    struct coord pos, int i);
-struct pix_buf *draw_move_pad(struct inst *inst, struct draw_ctx *ctx,
-    struct coord pos, int i);
-struct pix_buf *draw_move_arc(struct inst *inst, struct draw_ctx *ctx,
-    struct coord pos, int i);
-struct pix_buf *draw_move_meas(struct inst *inst, struct draw_ctx *ctx,
-    struct coord pos, int i);
-struct pix_buf *draw_move_frame(struct inst *inst, struct draw_ctx *ctx,
-    struct coord pos, int i);
+struct pix_buf *draw_move_vec(struct inst *inst, struct coord pos, int i);
+struct pix_buf *draw_move_line(struct inst *inst, struct coord pos, int i);
+struct pix_buf *draw_move_rect(struct inst *inst, struct coord pos, int i);
+struct pix_buf *draw_move_pad(struct inst *inst, struct coord pos, int i);
+struct pix_buf *draw_move_arc(struct inst *inst, struct coord pos, int i);
+struct pix_buf *draw_move_meas(struct inst *inst, struct coord pos, int i);
+struct pix_buf *draw_move_frame(struct inst *inst, struct coord pos, int i);
 
+struct pix_buf *gui_hover_vec(struct inst *self);
+struct pix_buf *gui_hover_frame(struct inst *self);
+
 void do_move_to_arc(struct inst *inst, struct vec *vec, int i);
 
-void tool_dehover(struct draw_ctx *ctx);
-void tool_hover(struct draw_ctx *ctx, struct coord pos);
-int tool_consider_drag(struct draw_ctx *ctx, struct coord pos);
-void tool_drag(struct draw_ctx *ctx, struct coord to);
-void tool_cancel_drag(struct draw_ctx *ctx);
-int tool_end_drag(struct draw_ctx *ctx, struct coord to);
-void tool_redraw(struct draw_ctx *ctx);
+void tool_dehover(void);
+void tool_hover(struct coord pos);
+int tool_consider_drag(struct coord pos);
+void tool_drag(struct coord to);
+void tool_cancel_drag(void);
+int tool_end_drag(struct coord to);
+void tool_redraw(void);
 
+struct pix_buf *tool_drag_new(struct inst *inst, struct coord pos);
+
 /*
  * Cache the frame and track it.
  */

Modified: trunk/eda/fped/gui_util.c
===================================================================
--- trunk/eda/fped/gui_util.c	2009-08-07 21:47:51 UTC (rev 5404)
+++ trunk/eda/fped/gui_util.c	2009-08-08 14:11:26 UTC (rev 5405)
@@ -21,6 +21,9 @@
 #include "gui_util.h"
 
 
+struct draw_ctx draw_ctx;
+
+
 /* ----- look up a color --------------------------------------------------- */
 
 

Modified: trunk/eda/fped/gui_util.h
===================================================================
--- trunk/eda/fped/gui_util.h	2009-08-07 21:47:51 UTC (rev 5404)
+++ trunk/eda/fped/gui_util.h	2009-08-08 14:11:26 UTC (rev 5405)
@@ -16,7 +16,15 @@
 
 #include <gtk/gtk.h>
 
+#include "coord.h"
 
+
+struct draw_ctx {
+	GtkWidget *widget;
+	int scale;
+	struct coord center;
+};
+
 struct pix_buf {
 	GdkDrawable *da;
 	int x, y;
@@ -24,6 +32,12 @@
 };
 
 
+extern struct draw_ctx draw_ctx;
+
+
+#define DA      GDK_DRAWABLE(draw_ctx.widget->window)
+
+
 GdkColor get_color(const char *spec);
 
 void set_width(GdkGC *gc, int width);

Modified: trunk/eda/fped/inst.c
===================================================================
--- trunk/eda/fped/inst.c	2009-08-07 21:47:51 UTC (rev 5404)
+++ trunk/eda/fped/inst.c	2009-08-08 14:11:26 UTC (rev 5405)
@@ -20,6 +20,7 @@
 #include "expr.h"
 #include "obj.h"
 #include "delete.h"
+#include "gui_util.h"
 #include "gui_status.h"
 #include "gui_tools.h"
 #include "gui_inst.h"
@@ -29,13 +30,13 @@
 struct inst_ops {
 	void (*debug)(struct inst *self);
 	void (*save)(FILE *file, struct inst *self);
-	void (*draw)(struct inst *self, struct draw_ctx *ctx);
-	void (*hover)(struct inst *self, struct draw_ctx *ctx);
+	void (*draw)(struct inst *self);
+	struct pix_buf *(*hover)(struct inst *self);
 	unit_type (*distance)(struct inst *self, struct coord pos, 
 	    unit_type scale);
 	void (*select)(struct inst *self);
 	int (*anchors)(struct inst *self, struct vec ***anchors);
-	struct pix_buf *(*draw_move)(struct inst *inst, struct draw_ctx *ctx,
+	struct pix_buf *(*draw_move)(struct inst *inst,
 	    struct coord pos, int i);
 	/* arcs need this special override */
 	void (*do_move_to)(struct inst *inst, struct vec *vec, int i);
@@ -130,7 +131,7 @@
 }
 
 
-int inst_select(const struct draw_ctx *ctx, struct coord pos)
+int inst_select(struct coord pos)
 {
 	enum inst_prio prio;
 	struct inst *inst;
@@ -144,7 +145,7 @@
 		for (inst = insts[prio]; inst; inst = inst->next) {
 			if (!inst->active || !inst->ops->distance)
 				continue;
-			dist = inst->ops->distance(inst, pos, ctx->scale);
+			dist = inst->ops->distance(inst, pos, draw_ctx.scale);
 			if (dist >= 0 && (!selected_inst || best_dist > dist)) {
 				selected_inst = inst;
 				best_dist = dist;
@@ -159,7 +160,7 @@
 	for (inst = insts[ip_vec]; inst; inst = inst->next) {
 		if (!inst->active)
 			continue;
-		dist = gui_dist_vec_fallback(inst, pos, ctx->scale);
+		dist = gui_dist_vec_fallback(inst, pos, draw_ctx.scale);
 		if (dist >= 0 && (!selected_inst || best_dist > dist)) {
 			selected_inst = inst;
 			best_dist = dist;
@@ -177,7 +178,7 @@
 }
 
 
-struct inst *inst_find_point(const struct draw_ctx *ctx, struct coord pos)
+struct inst *inst_find_point(struct coord pos)
 {
 	struct inst *inst, *found;
 	int best_dist = 0; /* keep gcc happy */
@@ -187,7 +188,7 @@
 	for (inst = insts[ip_frame]; inst; inst = inst->next) {
 		if (!inst->u.frame.active)
 			continue;
-		dist = gui_dist_frame_eye(inst, pos, ctx->scale);
+		dist = gui_dist_frame_eye(inst, pos, draw_ctx.scale);
 		if (dist >= 0 && (!found || best_dist > dist)) {
 			found = inst;
 			best_dist = dist;
@@ -199,7 +200,7 @@
 	for (inst = insts[ip_vec]; inst; inst = inst->next) {
 		if (!inst->active || !inst->ops->distance)
 			continue;
-		dist = inst->ops->distance(inst, pos, ctx->scale);
+		dist = inst->ops->distance(inst, pos, draw_ctx.scale);
 		if (dist >= 0 && (!found || best_dist > dist)) {
 			found = inst;
 			best_dist = dist;
@@ -821,41 +822,39 @@
 }
 
 
-void inst_draw(struct draw_ctx *ctx)
+void inst_draw(void)
 {
 	enum inst_prio prio;
 	struct inst *inst;
 
 	FOR_INSTS_UP(prio, inst)
 		if (!inst->active && inst->ops->draw)
-			inst->ops->draw(inst, ctx);
+			inst->ops->draw(inst);
 	FOR_INSTS_UP(prio, inst)
 		if (prio != ip_frame && inst->active &&
 		    inst != selected_inst && inst->ops->draw)
-			inst->ops->draw(inst, ctx);
+			inst->ops->draw(inst);
 	for (inst = insts[ip_frame]; inst; inst = inst->next)
 		if (inst->active && inst != selected_inst && inst->ops->draw)
-			inst->ops->draw(inst, ctx);
+			inst->ops->draw(inst);
 	if (selected_inst && selected_inst->ops->draw)
-		selected_inst->ops->draw(selected_inst, ctx);
+		selected_inst->ops->draw(selected_inst);
 }
 
 
-void inst_highlight_vecs(struct draw_ctx *ctx,
-    int (*pick)(struct inst *inst, void *user), void *user)
+void inst_highlight_vecs(int (*pick)(struct inst *inst, void *user), void *user)
 {
 	struct inst *inst;
 
 	for (inst = insts[ip_vec]; inst; inst = inst->next)
 		if (pick(inst, user))
-			gui_highlight_vec(inst, ctx);
+			gui_highlight_vec(inst);
 }
 
 
-struct pix_buf *inst_draw_move(struct inst *inst, struct draw_ctx *ctx,
-    struct coord pos, int i)
+struct pix_buf *inst_draw_move(struct inst *inst, struct coord pos, int i)
 {
-	return inst->ops->draw_move(inst, ctx, pos, i);
+	return inst->ops->draw_move(inst, pos, i);
 }
 
 
@@ -868,14 +867,11 @@
 }
 
 
-void inst_hover(struct inst *inst, struct draw_ctx *ctx, int on)
+struct pix_buf *inst_hover(struct inst *inst)
 {
 	if (!inst->ops->hover)
-		return;
-	if (on)
-		inst->ops->hover(inst, ctx);
-	else
-		inst->ops->draw(inst, ctx);
+		return NULL;
+	return inst->ops->hover(inst);
 }
 
 

Modified: trunk/eda/fped/inst.h
===================================================================
--- trunk/eda/fped/inst.h	2009-08-07 21:47:51 UTC (rev 5404)
+++ trunk/eda/fped/inst.h	2009-08-08 14:11:26 UTC (rev 5405)
@@ -37,7 +37,6 @@
 };
 
 struct inst_ops;
-struct draw_ctx;
 
 struct inst {
 	const struct inst_ops *ops;
@@ -83,10 +82,10 @@
 
 
 void inst_select_outside(void *item, void (*deselect)(void *item));
-int inst_select(const struct draw_ctx *ctx, struct coord pos);
+int inst_select(struct coord pos);
 void inst_deselect(void);
 
-struct inst *inst_find_point(const struct draw_ctx *ctx, struct coord pos);
+struct inst *inst_find_point(struct coord pos);
 struct coord inst_get_point(const struct inst *inst);
 int inst_anchors(struct inst *inst, struct vec ***anchors);
 struct vec *inst_get_vec(const struct inst *inst);
@@ -113,13 +112,12 @@
 void inst_commit(void);
 void inst_revert(void);
 
-void inst_draw(struct draw_ctx *ctx);
-void inst_highlight_vecs(struct draw_ctx *ctx, 
-    int (*pick)(struct inst *inst, void *user), void *user);
-struct pix_buf *inst_draw_move(struct inst *inst, struct draw_ctx *ctx,
-    struct coord pos, int i);
+void inst_draw(void);
+void inst_highlight_vecs(int (*pick)(struct inst *inst, void *user),
+     void *user);
+struct pix_buf *inst_draw_move(struct inst *inst, struct coord pos, int i);
 int inst_do_move_to(struct inst *inst, struct vec *vec, int i);
-void inst_hover(struct inst *inst, struct draw_ctx *ctx, int on);
+struct pix_buf *inst_hover(struct inst *inst);
 void inst_delete(struct inst *inst);
 void inst_debug(void);
 




More information about the commitlog mailing list