r5385 - trunk/eda/fped

werner at docs.openmoko.org werner at docs.openmoko.org
Tue Aug 4 20:03:07 CEST 2009


Author: werner
Date: 2009-08-04 20:03:06 +0200 (Tue, 04 Aug 2009)
New Revision: 5385

Modified:
   trunk/eda/fped/gui.c
   trunk/eda/fped/gui_inst.c
   trunk/eda/fped/gui_inst.h
   trunk/eda/fped/gui_style.c
   trunk/eda/fped/gui_style.h
   trunk/eda/fped/gui_tools.c
   trunk/eda/fped/inst.c
   trunk/eda/fped/inst.h
   trunk/eda/fped/obj.c
Log:
- previous Makefile change was: tentative fix for compatibility with older
  ImageMagick versions (reported by Alvaro Lopes)
- we can now also select the frame's origin as a reference
- added general frame selection logic
- make sure we always use %s when passing names to status_set_name
- we can now drag endpoints (in progress)



Modified: trunk/eda/fped/gui.c
===================================================================
--- trunk/eda/fped/gui.c	2009-08-04 12:06:04 UTC (rev 5384)
+++ trunk/eda/fped/gui.c	2009-08-04 18:03:06 UTC (rev 5385)
@@ -115,7 +115,7 @@
 	inst_select_outside(var, unselect_var);
 	label_in_box_bg(var->widget, COLOR_VAR_EDITING);
 	status_set_type_entry("name =");
-	status_set_name(var->name);
+	status_set_name("%s", var->name);
 	edit_unique(&var->name, validate_var_name, var);
 }
 
@@ -493,7 +493,7 @@
 	inst_select_outside(frame, unselect_frame);
 	label_in_box_bg(frame->label, COLOR_FRAME_EDITING);
 	status_set_type_entry("name =");
-	status_set_name(frame->name);
+	status_set_name("%s", frame->name);
 	edit_unique(&frame->name, validate_frame_name, frame);
 }
 

Modified: trunk/eda/fped/gui_inst.c
===================================================================
--- trunk/eda/fped/gui_inst.c	2009-08-04 12:06:04 UTC (rev 5384)
+++ trunk/eda/fped/gui_inst.c	2009-08-04 18:03:06 UTC (rev 5385)
@@ -393,7 +393,8 @@
 /* ----- frame ------------------------------------------------------------- */
 
 
-unit_type gui_dist_frame(struct inst *self, struct coord pos, unit_type scale)
+unit_type gui_dist_frame_eye(struct inst *self, struct coord pos,
+    unit_type scale)
 {
 	unit_type d;
 
@@ -402,6 +403,40 @@
 }
 
 
+static unit_type dist_from_corner_line(struct inst *self, struct coord pos,
+    struct coord vec, unit_type scale)
+{
+	struct coord ref;
+
+	ref.x = self->bbox.min.x;
+	ref.y = self->bbox.max.y;
+	return dist_line(pos, ref, add_vec(ref, vec))/scale;
+}
+
+
+unit_type gui_dist_frame(struct inst *self, struct coord pos, unit_type scale)
+{
+	unit_type d_min, d;
+	struct coord vec;
+
+	d_min = dist_point(pos, self->base)/scale;
+
+	vec.x = FRAME_SHORT_X*scale;
+	vec.y = 0;
+	d = dist_from_corner_line(self, pos, vec, scale);
+	if (d < d_min)
+		d_min = d;
+
+	vec.x = 0;
+	vec.y = FRAME_SHORT_Y*scale;
+	d = dist_from_corner_line(self, pos, vec, scale);
+	if (d < d_min)
+		d_min = d;
+
+	return d_min > SELECT_R ? -1 : d_min;
+}
+
+
 void gui_hover_frame(struct inst *self, struct draw_ctx *ctx)
 {
 	struct coord center = translate(ctx, self->base);
@@ -418,7 +453,7 @@
 	struct coord corner = { self->bbox.min.x, self->bbox.max.y };
 	GdkGC *gc;
 
-	gc = gc_frame[get_mode(self)];
+	gc = self->u.frame.active ? gc_active_frame : gc_frame[get_mode(self)];
 	draw_eye(ctx, gc, center, FRAME_EYE_R1, FRAME_EYE_R2);
 	if (!self->u.frame.ref->name)
 		return;

Modified: trunk/eda/fped/gui_inst.h
===================================================================
--- trunk/eda/fped/gui_inst.h	2009-08-04 12:06:04 UTC (rev 5384)
+++ trunk/eda/fped/gui_inst.h	2009-08-04 18:03:06 UTC (rev 5385)
@@ -39,6 +39,8 @@
 unit_type gui_dist_arc(struct inst *self, struct coord pos, unit_type scale);
 unit_type gui_dist_meas(struct inst *self, struct coord pos, unit_type scale);
 unit_type gui_dist_frame(struct inst *self, struct coord pos, unit_type scale);
+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);

Modified: trunk/eda/fped/gui_style.c
===================================================================
--- trunk/eda/fped/gui_style.c	2009-08-04 12:06:04 UTC (rev 5384)
+++ trunk/eda/fped/gui_style.c	2009-08-04 18:03:06 UTC (rev 5385)
@@ -24,6 +24,7 @@
 
 GdkGC *gc_bg;
 GdkGC *gc_drag;
+GdkGC *gc_active_frame;
 GdkGC *gc_vec[mode_n];
 GdkGC *gc_obj[mode_n];
 GdkGC *gc_pad[mode_n];
@@ -67,7 +68,8 @@
 	style(gc_pad,	"#400000", INVALID,   "#ff0000", INVALID,   "#ffff80");
 	style(gc_ptext,	"#404040", INVALID,   "#ffffff", INVALID,   "#ffffff");
 	style(gc_meas,	"#280040", INVALID,   "#ff00ff", INVALID,   "#ffff80");
-	style(gc_frame,	"#004000", "#205020", "#00ff00", INVALID,   INVALID);
+	style(gc_frame,	"#004000", "#205020", "#009000", INVALID,   "#ffff80");
+	gc_active_frame = gc("#00ff00", 2);
 
 	gc_frame[mode_hover] = gc_vec[mode_hover] = gc("#c00000", 1);
 }

Modified: trunk/eda/fped/gui_style.h
===================================================================
--- trunk/eda/fped/gui_style.h	2009-08-04 12:06:04 UTC (rev 5384)
+++ trunk/eda/fped/gui_style.h	2009-08-04 18:03:06 UTC (rev 5385)
@@ -84,6 +84,7 @@
 
 extern GdkGC *gc_bg;
 extern GdkGC *gc_drag;
+extern GdkGC *gc_active_frame;
 extern GdkGC *gc_vec[mode_n];
 extern GdkGC *gc_obj[mode_n];
 extern GdkGC *gc_pad[mode_n];

Modified: trunk/eda/fped/gui_tools.c
===================================================================
--- trunk/eda/fped/gui_tools.c	2009-08-04 12:06:04 UTC (rev 5384)
+++ trunk/eda/fped/gui_tools.c	2009-08-04 18:03:06 UTC (rev 5385)
@@ -11,6 +11,8 @@
  */
 
 
+#include <stdlib.h>
+#include <assert.h>
 #include <gtk/gtk.h>
 
 #include "util.h"
@@ -36,9 +38,10 @@
 
 
 struct tool_ops {
-	struct pix_buf *(*drag)(struct draw_ctx *ctx, struct inst *from,
+	struct pix_buf *(*drag_new)(struct draw_ctx *ctx, struct inst *from,
 	     struct coord to);
-	int (*end)(struct draw_ctx *ctx, struct inst *from, struct inst *to);
+	int (*end_new)(struct draw_ctx *ctx, struct inst *from,
+	    struct inst *to);
 };
 
 
@@ -47,7 +50,16 @@
 static struct tool_ops *active_ops = NULL;
 static struct inst *hover_inst = NULL;
 
-static struct inst *drag;
+static struct drag_state {
+	struct inst *new; /* non-NULL if dragging a new object */
+	int anchors_n; /* number of anchors, 0 if no moving */
+	int anchor_i; /* current anchor */
+	struct vec **anchors[3];
+} drag = {
+	.new = NULL,
+	.anchors_n = 0,
+};
+
 static struct pix_buf *pix_buf;
 
 static struct tool_ops vec_ops;
@@ -104,8 +116,8 @@
 
 
 static struct tool_ops line_ops = {
-	.drag	= drag_new_line,
-	.end	= end_new_line,
+	.drag_new	= drag_new_line,
+	.end_new	= end_new_line,
 };
 
 
@@ -156,8 +168,8 @@
 
 
 static struct tool_ops rect_ops = {
-	.drag	= drag_new_rect,
-	.end	= end_new_rect,
+	.drag_new	= drag_new_rect,
+	.end_new	= end_new_rect,
 };
 
 
@@ -196,14 +208,79 @@
 
 
 static struct tool_ops circ_ops = {
-	.drag	= drag_new_circ,
-	.end	= end_new_circ,
+	.drag_new	= drag_new_circ,
+	.end_new	= end_new_circ,
 };
 
 
-/* ----- mouse actions ----------------------------------------------------- */
+/* ----- moving references ------------------------------------------------- */
 
 
+static int may_move(struct inst *curr)
+{
+	if (!selected_inst)
+		return 0;
+	if (drag.anchors_n)
+		return 0; /* already moving something else */
+	drag.anchors_n = inst_anchors(selected_inst, drag.anchors);
+	for (drag.anchor_i = 0; drag.anchor_i != drag.anchors_n;
+	    drag.anchor_i++)
+		if (*drag.anchors[drag.anchor_i] == inst_get_vec(curr))
+			return 1;
+	drag.anchors_n = 0;
+	return 0;
+}
+
+
+static int would_be_equal(const struct drag_state *state,
+    int a, int b, struct inst *curr)
+{
+	const struct vec *va;
+	const struct vec *vb;
+
+	va = a == state->anchor_i ? inst_get_vec(curr) : *state->anchors[a];
+	vb = b == state->anchor_i ? inst_get_vec(curr) : *state->anchors[b];
+	return va == vb;
+}
+
+
+static int may_move_to(const struct drag_state *state, struct inst *curr)
+{
+	assert(selected_inst);
+	assert(state->anchors_n);
+	switch (state->anchors_n) {
+	case 3:
+		if (would_be_equal(state, 0, 2, curr))
+			return 0;
+		/* fall through */
+	case 2:
+		if (would_be_equal(state, 0, 1, curr))
+			return 0;
+		/* fall through */
+	case 1:
+		return 1;
+	default:
+		abort();
+	}
+}
+
+
+static void do_move_to(struct drag_state *state, struct inst *curr)
+{
+	struct vec *old;
+
+	assert(may_move_to(state, curr));
+	old = *state->anchors[state->anchor_i];
+	if (old)
+		old->n_refs--;
+	*state->anchors[state->anchor_i] = inst_get_ref(curr);
+	state->anchors_n = 0;
+}
+
+
+/* ----- hover ------------------------------------------------------------- */
+
+
 void tool_dehover(struct draw_ctx *ctx)
 {
 	if (hover_inst)
@@ -214,29 +291,46 @@
 
 void tool_hover(struct draw_ctx *ctx, struct coord pos)
 {
-	struct inst *inst;
+	struct inst *curr;
 
-	if (!active_ops)
-		return;
-	inst = inst_find_point(ctx, pos);
-	if (inst != hover_inst)
+	curr = inst_find_point(ctx, pos);
+	if (curr && !active_ops) {
+		if (drag.anchors_n) {
+			if (!may_move_to(&drag, curr))
+				curr = NULL;
+		} else {
+			if (!may_move(curr))
+				curr = NULL;
+			drag.anchors_n = 0;
+		}
+	}
+	if (curr != hover_inst)
 		tool_dehover(ctx);
-	if (inst) {
-		inst_hover(inst, ctx, 1);
-		hover_inst = inst;
+	if (curr) {
+		inst_hover(curr, ctx, 1);
+		hover_inst = curr;
 	}
 }
 
 
+/* ----- mouse actions ----------------------------------------------------- */
+
+
 int tool_consider_drag(struct draw_ctx *ctx, struct coord pos)
 {
-	if (!active_ops)
+	struct inst *curr;
+
+	assert(!drag.new);
+	assert(!drag.anchors_n);
+	curr = inst_find_point(ctx, pos);
+	if (!curr)
 		return 0;
-	drag = inst_find_point(ctx, pos);
-	if (!drag)
-		return 0;
 	pix_buf = NULL;
-	return 1;
+	if (active_ops) {
+		drag.new = curr;
+		return 1;
+	}
+	return may_move(curr);
 }
 
 
@@ -245,7 +339,7 @@
 	if (pix_buf)
 		restore_pix_buf(pix_buf);
 	tool_hover(ctx, to);
-	pix_buf = active_ops->drag(ctx, drag, to);
+	pix_buf = drag.new ? active_ops->drag_new(ctx, drag.new, to) : NULL;
 }
 
 
@@ -255,22 +349,28 @@
 	tool_reset();
 	if (pix_buf)
 		restore_pix_buf(pix_buf);
-	drag = NULL;
+	drag.new = NULL;
 	active_ops = NULL;
+	drag.anchors_n = 0;
 }
 
 
 int tool_end_drag(struct draw_ctx *ctx, struct coord to)
 {
-	struct inst *from = drag;
+	struct drag_state state = drag;
 	struct inst *end;
 	struct tool_ops *ops = active_ops;
 
 	tool_cancel_drag(ctx);
 	end = inst_find_point(ctx, to);
-	if (end)
-		return ops->end(ctx, from, end);
-	return 0;
+	if (!end)
+		return 0;
+	if (state.new)
+		return ops->end_new(ctx, state.new, end);
+	if (!may_move_to(&state, end))
+		return 0;
+	do_move_to(&state, end);
+	return 1;
 }
 
 

Modified: trunk/eda/fped/inst.c
===================================================================
--- trunk/eda/fped/inst.c	2009-08-04 12:06:04 UTC (rev 5384)
+++ trunk/eda/fped/inst.c	2009-08-04 18:03:06 UTC (rev 5385)
@@ -33,6 +33,7 @@
 	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);
 };
 
 enum inst_prio {
@@ -179,9 +180,9 @@
 
 	found = NULL;
 	for (inst = insts[ip_frame]; inst; inst = inst->next) {
-		if (!inst->active || !inst->ops->distance)
+		if (!inst->active)
 			continue;
-		dist = inst->ops->distance(inst, pos, ctx->scale);
+		dist = gui_dist_frame_eye(inst, pos, ctx->scale);
 		if (dist >= 0 && (!found || best_dist > dist)) {
 			found = inst;
 			best_dist = dist;
@@ -225,6 +226,22 @@
 }
 
 
+struct vec *inst_get_vec(const struct inst *inst)
+{
+	if (inst->ops == &vec_ops)
+		return inst->vec;
+	if (inst->ops == &frame_ops)
+		return NULL;
+	abort();
+}
+
+
+int inst_anchors(struct inst *inst, struct vec ***anchors)
+{
+	return inst->ops->anchors ? inst->ops->anchors(inst, anchors) : 0;
+}
+
+
 void inst_deselect(void)
 {
 	if (selected_inst)
@@ -343,7 +360,7 @@
 static void vec_op_select(struct inst *self)
 {
 	status_set_type_entry("ref =");
-	status_set_name(self->vec->name ? self->vec->name : "");
+	status_set_name("%s", self->vec->name ? self->vec->name : "");
 	rect_status(self->base, self->u.rect.end, -1);
 	edit_unique_null(&self->vec->name, validate_vec_name, self->vec);
 	edit_x(&self->vec->x);
@@ -351,12 +368,20 @@
 }
 
 
+static int vec_op_anchors(struct inst *inst, struct vec ***anchors)
+{
+	anchors[0] = &inst->vec->base;
+	return 1;
+}
+
+
 static struct inst_ops vec_ops = {
 	.debug		= vec_op_debug,
 	.draw		= gui_draw_vec,
 	.hover		= gui_hover_vec,
 	.distance	= gui_dist_vec,
 	.select		= vec_op_select,
+	.anchors	= vec_op_anchors,
 };
 
 
@@ -391,11 +416,22 @@
 }
 
 
+static int line_op_anchors(struct inst *inst, struct vec ***anchors)
+{
+	struct obj *obj = inst->obj;
+
+	anchors[0] = &obj->base;
+	anchors[1] = &obj->u.rect.other;
+	return 2;
+}
+
+
 static struct inst_ops line_ops = {
 	.debug		= line_op_debug,
 	.draw		= gui_draw_line,
 	.distance	= gui_dist_line,
 	.select		= line_op_select,
+	.anchors	= line_op_anchors,
 };
 
 
@@ -437,6 +473,7 @@
 	.draw		= gui_draw_rect,
 	.distance	= gui_dist_rect,
 	.select		= rect_op_select,
+	.anchors	= line_op_anchors,
 };
 
 
@@ -481,17 +518,28 @@
 static void pad_op_select(struct inst *self)
 {
 	status_set_type_entry("label =");
-	status_set_name(self->u.name);
+	status_set_name("%s", self->u.name);
 	rect_status(self->bbox.min, self->bbox.max, -1);
 	edit_name(&self->obj->u.pad.name, validate_pad_name, NULL);
 }
 
 
+static int pad_op_anchors(struct inst *inst, struct vec ***anchors)
+{
+	struct obj *obj = inst->obj;
+
+	anchors[0] = &obj->base;
+	anchors[1] = &obj->u.pad.other;
+	return 2;
+}
+
+
 static struct inst_ops pad_ops = {
 	.debug		= pad_op_debug,
 	.draw		= gui_draw_pad,
 	.distance	= gui_dist_pad,
 	.select		= pad_op_select,
+	.anchors	= pad_op_anchors,
 };
 
 
@@ -532,11 +580,23 @@
 }
 
 
+static int arc_op_anchors(struct inst *inst, struct vec ***anchors)
+{
+	struct obj *obj = inst->obj;
+
+	anchors[0] = &obj->base;
+	anchors[1] = &obj->u.arc.start;
+	anchors[2] = &obj->u.arc.end;
+	return 3;
+}
+
+
 static struct inst_ops arc_ops = {
 	.debug		= arc_op_debug,
 	.draw		= gui_draw_arc,
 	.distance	= gui_dist_arc,
 	.select		= arc_op_select,
+	.anchors	= arc_op_anchors,
 };
 
 
@@ -590,11 +650,22 @@
 }
 
 
+static int meas_op_anchors(struct inst *inst, struct vec ***anchors)
+{
+	struct obj *obj = inst->obj;
+
+	anchors[0] = &obj->base;
+	anchors[1] = &obj->u.meas.other;
+	return 2;
+}
+
+
 static struct inst_ops meas_ops = {
 	.debug		= meas_op_debug,
 	.draw		= gui_draw_meas,
 	.distance	= gui_dist_meas,
 	.select		= meas_op_select,
+	.anchors	= meas_op_anchors,
 };
 
 
@@ -640,19 +711,39 @@
 }
 
 
+static void frame_op_select(struct inst *self)
+{
+	rect_status(self->bbox.min, self->bbox.max, -1);
+	status_set_type_entry("name =");
+	status_set_name("%s", self->u.frame.ref->name);
+}
+
+
+static int frame_op_anchors(struct inst *inst, struct vec ***anchors)
+{
+	anchors[0] = &inst->vec->base;
+	return 1;
+}
+
+
 static struct inst_ops frame_ops = {
-	.debug	= frame_op_debug,
-	.draw	= gui_draw_frame,
-	.hover	= gui_hover_frame,
+	.debug		= frame_op_debug,
+	.draw		= gui_draw_frame,
+	.hover		= gui_hover_frame,
+	.distance	= gui_dist_frame,
+	.select		= frame_op_select,
+	.anchors	= frame_op_anchors,
 };
 
 
-void inst_begin_frame(const struct frame *frame, struct coord base, int active)
+void inst_begin_frame(const struct frame *frame, struct coord base,
+    int active, int is_active_frame)
 {
 	struct inst *inst;
 
 	inst = add_inst(&frame_ops, ip_frame, base);
 	inst->u.frame.ref = frame;
+	inst->u.frame.active = is_active_frame;
 	inst->active = active;
 	curr_frame = inst;
 }

Modified: trunk/eda/fped/inst.h
===================================================================
--- trunk/eda/fped/inst.h	2009-08-04 12:06:04 UTC (rev 5384)
+++ trunk/eda/fped/inst.h	2009-08-04 18:03:06 UTC (rev 5385)
@@ -51,6 +51,7 @@
 	union {
 		struct {
 			const struct frame *ref;
+			int active;
 		} frame;
 		const char *name;
 		struct {
@@ -81,7 +82,9 @@
 
 struct inst *inst_find_point(const struct draw_ctx *ctx, 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_ref(const struct inst *inst);
+struct vec *inst_get_vec(const struct inst *inst);
 
 int inst_vec(struct vec *vec, struct coord base);
 int inst_line(struct obj *obj, struct coord a, struct coord b, unit_type width);
@@ -95,7 +98,8 @@
 void inst_begin_active(int active);
 void inst_end_active(void);
 
-void inst_begin_frame(const struct frame *frame, struct coord base, int active);
+void inst_begin_frame(const struct frame *frame, struct coord base,
+    int active, int is_active_frame);
 void inst_end_frame(const struct frame *frame);
 
 struct bbox inst_get_bbox(void);

Modified: trunk/eda/fped/obj.c
===================================================================
--- trunk/eda/fped/obj.c	2009-08-04 12:06:04 UTC (rev 5384)
+++ trunk/eda/fped/obj.c	2009-08-04 18:03:06 UTC (rev 5385)
@@ -244,7 +244,9 @@
 	/*
 	 * We ensure during construction that frames can never recurse.
 	 */
-	inst_begin_frame(frame, base, active && frame == active_frame);
+	inst_begin_frame(frame, base,
+	    active && parent == active_frame,
+	    active && frame == active_frame);
 	frame->curr_parent = parent;
 	ok = iterate_tables(frame, frame->tables, base, active);
 	inst_end_frame(frame);




More information about the commitlog mailing list