1
0
mirror of git://projects.qi-hardware.com/fped.git synced 2024-07-01 05:09:50 +03:00

- 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)



git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5385 99fdad57-331a-0410-800a-d7fa5415bdb3
This commit is contained in:
werner 2009-08-04 18:03:06 +00:00
parent 5add8b5229
commit 8377ab0e0d
9 changed files with 281 additions and 44 deletions

4
gui.c
View File

@ -115,7 +115,7 @@ static void edit_var(struct var *var)
inst_select_outside(var, unselect_var); inst_select_outside(var, unselect_var);
label_in_box_bg(var->widget, COLOR_VAR_EDITING); label_in_box_bg(var->widget, COLOR_VAR_EDITING);
status_set_type_entry("name ="); status_set_type_entry("name =");
status_set_name(var->name); status_set_name("%s", var->name);
edit_unique(&var->name, validate_var_name, var); edit_unique(&var->name, validate_var_name, var);
} }
@ -493,7 +493,7 @@ static void edit_frame(struct frame *frame)
inst_select_outside(frame, unselect_frame); inst_select_outside(frame, unselect_frame);
label_in_box_bg(frame->label, COLOR_FRAME_EDITING); label_in_box_bg(frame->label, COLOR_FRAME_EDITING);
status_set_type_entry("name ="); status_set_type_entry("name =");
status_set_name(frame->name); status_set_name("%s", frame->name);
edit_unique(&frame->name, validate_frame_name, frame); edit_unique(&frame->name, validate_frame_name, frame);
} }

View File

@ -393,7 +393,8 @@ void gui_draw_meas(struct inst *self, struct draw_ctx *ctx)
/* ----- frame ------------------------------------------------------------- */ /* ----- 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; unit_type d;
@ -402,6 +403,40 @@ unit_type gui_dist_frame(struct inst *self, struct coord pos, unit_type scale)
} }
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) void gui_hover_frame(struct inst *self, struct draw_ctx *ctx)
{ {
struct coord center = translate(ctx, self->base); struct coord center = translate(ctx, self->base);
@ -418,7 +453,7 @@ void gui_draw_frame(struct inst *self, struct draw_ctx *ctx)
struct coord corner = { self->bbox.min.x, self->bbox.max.y }; struct coord corner = { self->bbox.min.x, self->bbox.max.y };
GdkGC *gc; 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); draw_eye(ctx, gc, center, FRAME_EYE_R1, FRAME_EYE_R2);
if (!self->u.frame.ref->name) if (!self->u.frame.ref->name)
return; return;

View File

@ -39,6 +39,8 @@ unit_type gui_dist_pad(struct inst *self, struct coord pos, unit_type scale);
unit_type gui_dist_arc(struct inst *self, struct coord pos, unit_type scale); 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_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(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_vec(struct inst *self, struct draw_ctx *ctx);
void gui_draw_line(struct inst *self, struct draw_ctx *ctx); void gui_draw_line(struct inst *self, struct draw_ctx *ctx);

View File

@ -24,6 +24,7 @@
GdkGC *gc_bg; GdkGC *gc_bg;
GdkGC *gc_drag; GdkGC *gc_drag;
GdkGC *gc_active_frame;
GdkGC *gc_vec[mode_n]; GdkGC *gc_vec[mode_n];
GdkGC *gc_obj[mode_n]; GdkGC *gc_obj[mode_n];
GdkGC *gc_pad[mode_n]; GdkGC *gc_pad[mode_n];
@ -67,7 +68,8 @@ void gui_setup_style(GdkDrawable *drawable)
style(gc_pad, "#400000", INVALID, "#ff0000", INVALID, "#ffff80"); style(gc_pad, "#400000", INVALID, "#ff0000", INVALID, "#ffff80");
style(gc_ptext, "#404040", INVALID, "#ffffff", INVALID, "#ffffff"); style(gc_ptext, "#404040", INVALID, "#ffffff", INVALID, "#ffffff");
style(gc_meas, "#280040", INVALID, "#ff00ff", INVALID, "#ffff80"); 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); gc_frame[mode_hover] = gc_vec[mode_hover] = gc("#c00000", 1);
} }

View File

@ -84,6 +84,7 @@
extern GdkGC *gc_bg; extern GdkGC *gc_bg;
extern GdkGC *gc_drag; extern GdkGC *gc_drag;
extern GdkGC *gc_active_frame;
extern GdkGC *gc_vec[mode_n]; extern GdkGC *gc_vec[mode_n];
extern GdkGC *gc_obj[mode_n]; extern GdkGC *gc_obj[mode_n];
extern GdkGC *gc_pad[mode_n]; extern GdkGC *gc_pad[mode_n];

View File

@ -11,6 +11,8 @@
*/ */
#include <stdlib.h>
#include <assert.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "util.h" #include "util.h"
@ -36,9 +38,10 @@
struct tool_ops { 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); 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 GtkWidget *active_tool;
static struct tool_ops *active_ops = NULL; static struct tool_ops *active_ops = NULL;
static struct inst *hover_inst = 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 pix_buf *pix_buf;
static struct tool_ops vec_ops; static struct tool_ops vec_ops;
@ -104,8 +116,8 @@ static int end_new_line(struct draw_ctx *ctx,
static struct tool_ops line_ops = { static struct tool_ops line_ops = {
.drag = drag_new_line, .drag_new = drag_new_line,
.end = end_new_line, .end_new = end_new_line,
}; };
@ -156,8 +168,8 @@ static int end_new_rect(struct draw_ctx *ctx,
static struct tool_ops rect_ops = { static struct tool_ops rect_ops = {
.drag = drag_new_rect, .drag_new = drag_new_rect,
.end = end_new_rect, .end_new = end_new_rect,
}; };
@ -196,12 +208,77 @@ static int end_new_circ(struct draw_ctx *ctx,
static struct tool_ops circ_ops = { static struct tool_ops circ_ops = {
.drag = drag_new_circ, .drag_new = drag_new_circ,
.end = end_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) void tool_dehover(struct draw_ctx *ctx)
@ -214,29 +291,46 @@ void tool_dehover(struct draw_ctx *ctx)
void tool_hover(struct draw_ctx *ctx, struct coord pos) void tool_hover(struct draw_ctx *ctx, struct coord pos)
{ {
struct inst *inst; struct inst *curr;
if (!active_ops) curr = inst_find_point(ctx, pos);
return; if (curr && !active_ops) {
inst = inst_find_point(ctx, pos); if (drag.anchors_n) {
if (inst != hover_inst) 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); tool_dehover(ctx);
if (inst) { if (curr) {
inst_hover(inst, ctx, 1); inst_hover(curr, ctx, 1);
hover_inst = inst; hover_inst = curr;
} }
} }
/* ----- mouse actions ----------------------------------------------------- */
int tool_consider_drag(struct draw_ctx *ctx, struct coord pos) int tool_consider_drag(struct draw_ctx *ctx, struct coord pos)
{ {
if (!active_ops) struct inst *curr;
return 0;
drag = inst_find_point(ctx, pos); assert(!drag.new);
if (!drag) assert(!drag.anchors_n);
curr = inst_find_point(ctx, pos);
if (!curr)
return 0; return 0;
pix_buf = NULL; pix_buf = NULL;
return 1; if (active_ops) {
drag.new = curr;
return 1;
}
return may_move(curr);
} }
@ -245,7 +339,7 @@ void tool_drag(struct draw_ctx *ctx, struct coord to)
if (pix_buf) if (pix_buf)
restore_pix_buf(pix_buf); restore_pix_buf(pix_buf);
tool_hover(ctx, to); 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 @@ void tool_cancel_drag(struct draw_ctx *ctx)
tool_reset(); tool_reset();
if (pix_buf) if (pix_buf)
restore_pix_buf(pix_buf); restore_pix_buf(pix_buf);
drag = NULL; drag.new = NULL;
active_ops = NULL; active_ops = NULL;
drag.anchors_n = 0;
} }
int tool_end_drag(struct draw_ctx *ctx, struct coord to) int tool_end_drag(struct draw_ctx *ctx, struct coord to)
{ {
struct inst *from = drag; struct drag_state state = drag;
struct inst *end; struct inst *end;
struct tool_ops *ops = active_ops; struct tool_ops *ops = active_ops;
tool_cancel_drag(ctx); tool_cancel_drag(ctx);
end = inst_find_point(ctx, to); end = inst_find_point(ctx, to);
if (end) if (!end)
return ops->end(ctx, from, end); return 0;
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;
} }

107
inst.c
View File

@ -33,6 +33,7 @@ struct inst_ops {
unit_type (*distance)(struct inst *self, struct coord pos, unit_type (*distance)(struct inst *self, struct coord pos,
unit_type scale); unit_type scale);
void (*select)(struct inst *self); void (*select)(struct inst *self);
int (*anchors)(struct inst *self, struct vec ***anchors);
}; };
enum inst_prio { enum inst_prio {
@ -179,9 +180,9 @@ struct inst *inst_find_point(const struct draw_ctx *ctx, struct coord pos)
found = NULL; found = NULL;
for (inst = insts[ip_frame]; inst; inst = inst->next) { for (inst = insts[ip_frame]; inst; inst = inst->next) {
if (!inst->active || !inst->ops->distance) if (!inst->active)
continue; 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)) { if (dist >= 0 && (!found || best_dist > dist)) {
found = inst; found = inst;
best_dist = dist; best_dist = dist;
@ -225,6 +226,22 @@ struct vec *inst_get_ref(const struct inst *inst)
} }
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) void inst_deselect(void)
{ {
if (selected_inst) if (selected_inst)
@ -343,7 +360,7 @@ static int validate_vec_name(const char *s, void *ctx)
static void vec_op_select(struct inst *self) static void vec_op_select(struct inst *self)
{ {
status_set_type_entry("ref ="); 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); rect_status(self->base, self->u.rect.end, -1);
edit_unique_null(&self->vec->name, validate_vec_name, self->vec); edit_unique_null(&self->vec->name, validate_vec_name, self->vec);
edit_x(&self->vec->x); edit_x(&self->vec->x);
@ -351,12 +368,20 @@ static void vec_op_select(struct inst *self)
} }
static int vec_op_anchors(struct inst *inst, struct vec ***anchors)
{
anchors[0] = &inst->vec->base;
return 1;
}
static struct inst_ops vec_ops = { static struct inst_ops vec_ops = {
.debug = vec_op_debug, .debug = vec_op_debug,
.draw = gui_draw_vec, .draw = gui_draw_vec,
.hover = gui_hover_vec, .hover = gui_hover_vec,
.distance = gui_dist_vec, .distance = gui_dist_vec,
.select = vec_op_select, .select = vec_op_select,
.anchors = vec_op_anchors,
}; };
@ -391,11 +416,22 @@ static void line_op_select(struct inst *self)
} }
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 = { static struct inst_ops line_ops = {
.debug = line_op_debug, .debug = line_op_debug,
.draw = gui_draw_line, .draw = gui_draw_line,
.distance = gui_dist_line, .distance = gui_dist_line,
.select = line_op_select, .select = line_op_select,
.anchors = line_op_anchors,
}; };
@ -437,6 +473,7 @@ static struct inst_ops rect_ops = {
.draw = gui_draw_rect, .draw = gui_draw_rect,
.distance = gui_dist_rect, .distance = gui_dist_rect,
.select = rect_op_select, .select = rect_op_select,
.anchors = line_op_anchors,
}; };
@ -481,17 +518,28 @@ static int validate_pad_name(const char *s, void *ctx)
static void pad_op_select(struct inst *self) static void pad_op_select(struct inst *self)
{ {
status_set_type_entry("label ="); 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); rect_status(self->bbox.min, self->bbox.max, -1);
edit_name(&self->obj->u.pad.name, validate_pad_name, NULL); 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 = { static struct inst_ops pad_ops = {
.debug = pad_op_debug, .debug = pad_op_debug,
.draw = gui_draw_pad, .draw = gui_draw_pad,
.distance = gui_dist_pad, .distance = gui_dist_pad,
.select = pad_op_select, .select = pad_op_select,
.anchors = pad_op_anchors,
}; };
@ -532,11 +580,23 @@ static void arc_op_select(struct inst *self)
} }
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 = { static struct inst_ops arc_ops = {
.debug = arc_op_debug, .debug = arc_op_debug,
.draw = gui_draw_arc, .draw = gui_draw_arc,
.distance = gui_dist_arc, .distance = gui_dist_arc,
.select = arc_op_select, .select = arc_op_select,
.anchors = arc_op_anchors,
}; };
@ -590,11 +650,22 @@ static void meas_op_select(struct inst *self)
} }
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 = { static struct inst_ops meas_ops = {
.debug = meas_op_debug, .debug = meas_op_debug,
.draw = gui_draw_meas, .draw = gui_draw_meas,
.distance = gui_dist_meas, .distance = gui_dist_meas,
.select = meas_op_select, .select = meas_op_select,
.anchors = meas_op_anchors,
}; };
@ -640,19 +711,39 @@ static void frame_op_debug(struct inst *self)
} }
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 = { static struct inst_ops frame_ops = {
.debug = frame_op_debug, .debug = frame_op_debug,
.draw = gui_draw_frame, .draw = gui_draw_frame,
.hover = gui_hover_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; struct inst *inst;
inst = add_inst(&frame_ops, ip_frame, base); inst = add_inst(&frame_ops, ip_frame, base);
inst->u.frame.ref = frame; inst->u.frame.ref = frame;
inst->u.frame.active = is_active_frame;
inst->active = active; inst->active = active;
curr_frame = inst; curr_frame = inst;
} }

6
inst.h
View File

@ -51,6 +51,7 @@ struct inst {
union { union {
struct { struct {
const struct frame *ref; const struct frame *ref;
int active;
} frame; } frame;
const char *name; const char *name;
struct { struct {
@ -81,7 +82,9 @@ void inst_deselect(void);
struct inst *inst_find_point(const struct draw_ctx *ctx, struct coord pos); struct inst *inst_find_point(const struct draw_ctx *ctx, struct coord pos);
struct coord inst_get_point(const struct inst *inst); 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_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_vec(struct vec *vec, struct coord base);
int inst_line(struct obj *obj, struct coord a, struct coord b, unit_type width); int inst_line(struct obj *obj, struct coord a, struct coord b, unit_type width);
@ -95,7 +98,8 @@ int inst_meas(struct obj *obj, struct coord from, struct coord to,
void inst_begin_active(int active); void inst_begin_active(int active);
void inst_end_active(void); 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); void inst_end_frame(const struct frame *frame);
struct bbox inst_get_bbox(void); struct bbox inst_get_bbox(void);

4
obj.c
View File

@ -244,7 +244,9 @@ static int generate_frame(struct frame *frame, struct coord base,
/* /*
* We ensure during construction that frames can never recurse. * 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; frame->curr_parent = parent;
ok = iterate_tables(frame, frame->tables, base, active); ok = iterate_tables(frame, frame->tables, base, active);
inst_end_frame(frame); inst_end_frame(frame);