1
0
mirror of git://projects.qi-hardware.com/fped.git synced 2024-12-23 04:59:33 +02:00

- when selecting an item in the canvas, we now check that the underlying object

is still connected. This prevents surprises when making extensive changes
  during instantiation failure.



git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5445 99fdad57-331a-0410-800a-d7fa5415bdb3
This commit is contained in:
werner 2009-08-14 15:53:21 +00:00
parent d39ae30f6e
commit 7af014b516

46
inst.c
View File

@ -40,6 +40,9 @@ static struct inst *prev_insts[ip_n];
static unsigned long active_set = 0;
static struct inst_ops vec_ops;
static struct inst_ops frame_ops;
#define IS_ACTIVE ((active_set & 1))
@ -87,13 +90,44 @@ void inst_select_outside(void *item, void (*deselect)(void *item))
}
/* ----- check connectedness ----------------------------------------------- */
/*
* After an instantiation failure, the instances can get out of sync with the
* object tree, and attempts to select an item on the canvas can cause accesses
* to objects that aren't there anymore. So we need to check if we can still
* reach the corresponding object.
*
* Note: even this isn't bullet-proof. Theoretically, we may get a new object
* in the old place. However, this probably doesn't do any serious damage.
*/
static int inst_connected(const struct inst *inst)
{
const struct frame *frame;
const struct vec *vec;
const struct obj *obj;
for (frame = frames; frame; frame = frame->next) {
if (inst->ops == &vec_ops) {
for (vec = frame->vecs; vec; vec = vec->next)
if (vec == inst->vec)
return 1;
} else {
for (obj = frame->objs; obj; obj = obj->next)
if (obj == inst->obj)
return 1;
}
}
return 0;
}
/* ----- selection --------------------------------------------------------- */
static struct inst_ops vec_ops;
static struct inst_ops frame_ops;
static void set_path(int on)
{
struct inst *inst;
@ -140,6 +174,8 @@ int inst_select(struct coord pos)
for (inst = insts[prio]; inst; inst = inst->next) {
if (!inst->active || !inst->ops->distance)
continue;
if (!inst_connected(inst))
continue;
dist = inst->ops->distance(inst, pos, draw_ctx.scale);
if (dist >= 0 && (!selected_inst || best_dist > dist)) {
selected_inst = inst;
@ -158,6 +194,8 @@ int inst_select(struct coord pos)
for (inst = insts[ip_vec]; inst; inst = inst->next) {
if (!inst->active)
continue;
if (!inst_connected(inst))
continue;
dist = gui_dist_vec_fallback(inst, pos, draw_ctx.scale);
if (dist >= 0 && (!selected_inst || best_dist > dist)) {
selected_inst = inst;