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