1
0
mirror of git://projects.qi-hardware.com/fped.git synced 2024-11-22 14:08:28 +02: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);
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 @@ static void edit_frame(struct frame *frame)
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);
}

View File

@ -393,7 +393,8 @@ void gui_draw_meas(struct inst *self, struct draw_ctx *ctx)
/* ----- 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 @@ 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)
{
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 };
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;

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

View File

@ -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 @@ void gui_setup_style(GdkDrawable *drawable)
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);
}

View File

@ -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];

View File

@ -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 GtkWidget *active_tool;
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 int end_new_line(struct draw_ctx *ctx,
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 int end_new_rect(struct draw_ctx *ctx,
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,12 +208,77 @@ static int end_new_circ(struct draw_ctx *ctx,
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)
@ -214,29 +291,46 @@ void tool_dehover(struct draw_ctx *ctx)
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)
return 0;
drag = inst_find_point(ctx, pos);
if (!drag)
struct inst *curr;
assert(!drag.new);
assert(!drag.anchors_n);
curr = inst_find_point(ctx, pos);
if (!curr)
return 0;
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)
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 @@ void tool_cancel_drag(struct draw_ctx *ctx)
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;
}

107
inst.c
View File

@ -33,6 +33,7 @@ struct inst_ops {
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 @@ struct inst *inst_find_point(const struct draw_ctx *ctx, struct coord pos)
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_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)
{
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)
{
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 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 = {
.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 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 = {
.debug = line_op_debug,
.draw = gui_draw_line,
.distance = gui_dist_line,
.select = line_op_select,
.anchors = line_op_anchors,
};
@ -437,6 +473,7 @@ static struct inst_ops rect_ops = {
.draw = gui_draw_rect,
.distance = gui_dist_rect,
.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)
{
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 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 = {
.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 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 = {
.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_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 = {
.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;
}

6
inst.h
View File

@ -51,6 +51,7 @@ struct inst {
union {
struct {
const struct frame *ref;
int active;
} frame;
const char *name;
struct {
@ -81,7 +82,9 @@ void inst_deselect(void);
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 @@ int inst_meas(struct obj *obj, struct coord from, struct coord to,
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);

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.
*/
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);