mirror of
git://projects.qi-hardware.com/fped.git
synced 2024-11-25 18:15:55 +02:00
- put hbox around frame table so that it doesn't grow when we give it more
space than it needs - dump.c: separated ordering function from actual printing - added list of vectors and object (on the right side of the variables) git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5423 99fdad57-331a-0410-800a-d7fa5415bdb3
This commit is contained in:
parent
9c3cf7e51c
commit
e65d90947c
6
TODO
6
TODO
@ -28,6 +28,9 @@ Bugs:
|
||||
- default silk width has no business being hard-coded in obj.c
|
||||
- undelete only works if not much has changed since the deletion
|
||||
- focus should return to canvas if nobody else wants it
|
||||
- when in uninstantiated mode, objects can be changed and then manipulated
|
||||
through the unchanged instance. Tricky to fix without an alternate means to
|
||||
access the object list. (Getting there.)
|
||||
|
||||
Code cleanup:
|
||||
- merge edit_unique with edit_name
|
||||
@ -67,8 +70,5 @@ Future directions:
|
||||
- advanced: silk line width
|
||||
- future: when encountering an error after a change, we could try to find the
|
||||
same element in the old instance, and select it
|
||||
- idea: run the sort algorithm of dump.c to generate a list of objects per
|
||||
frame, then show the list per frame in the GUI, e.g., as an alternative to
|
||||
the variables. Allow selection.
|
||||
- future: consider editing non-canvas items in place
|
||||
- near future: treat part name as pattern
|
||||
|
476
dump.c
476
dump.c
@ -20,6 +20,186 @@
|
||||
#include "dump.h"
|
||||
|
||||
|
||||
/* ----- order items ------------------------------------------------------- */
|
||||
|
||||
|
||||
static void add_item(struct order **curr, struct vec *vec, struct obj *obj)
|
||||
{
|
||||
(*curr)->vec = vec;
|
||||
(*curr)->obj = obj;
|
||||
(*curr)++;
|
||||
}
|
||||
|
||||
|
||||
static int n_vec_refs(const struct vec *vec)
|
||||
{
|
||||
const struct vec *walk;
|
||||
int n;
|
||||
|
||||
n = 0;
|
||||
for (walk = vec->frame->vecs; walk; walk = walk->next)
|
||||
if (walk->base == vec)
|
||||
n++;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "need" operates in two modes:
|
||||
*
|
||||
* - if "prev" is non-NULL, we're looking for objects that need to be put after
|
||||
* the current vector (in "prev"). Only those objects need to be put there
|
||||
* that have at least one base that isn't the frame's origin or already has a
|
||||
* name.
|
||||
*
|
||||
* - if "prev" is NULL, we're at the end of the frame. We have already used all
|
||||
* the . references we could, so now we have to find out which objects
|
||||
* haven't been dumped yet. "need" still returns the ones that had a need to
|
||||
* be dumped. Again, that's those that have at least one possible "." base.
|
||||
* Since this "." base will have been used by now, the object must have been
|
||||
* dumped.
|
||||
*/
|
||||
|
||||
static int need(const struct vec *base, const struct vec *prev)
|
||||
{
|
||||
if (!base)
|
||||
return 0;
|
||||
if (base->name)
|
||||
return 0;
|
||||
if (prev)
|
||||
return base == prev;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* If we need a vector that's defined later, we have to defer dumping the
|
||||
* object.
|
||||
*/
|
||||
|
||||
static int later(const struct vec *base, const struct vec *prev)
|
||||
{
|
||||
while (prev) {
|
||||
if (base == prev)
|
||||
return 1;
|
||||
prev = prev->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int may_put_obj_now(const struct obj *obj, const struct vec *prev)
|
||||
{
|
||||
int n, l;
|
||||
|
||||
n = need(obj->base, prev);
|
||||
l = later(obj->base, prev);
|
||||
|
||||
switch (obj->type) {
|
||||
case ot_frame:
|
||||
break;
|
||||
case ot_line:
|
||||
n |= need(obj->u.line.other, prev);
|
||||
l |= later(obj->u.line.other, prev);
|
||||
break;
|
||||
case ot_rect:
|
||||
n |= need(obj->u.rect.other, prev);
|
||||
l |= later(obj->u.rect.other, prev);
|
||||
break;
|
||||
case ot_pad:
|
||||
n |= need(obj->u.pad.other, prev);
|
||||
l |= later(obj->u.pad.other, prev);
|
||||
break;
|
||||
case ot_arc:
|
||||
n |= need(obj->u.arc.start, prev);
|
||||
n |= need(obj->u.arc.end, prev);
|
||||
l |= later(obj->u.arc.start, prev);
|
||||
l |= later(obj->u.arc.end, prev);
|
||||
break;
|
||||
case ot_meas:
|
||||
return 0;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
return n && !l;
|
||||
}
|
||||
|
||||
|
||||
static void put_obj(struct order **curr, struct obj *obj,
|
||||
struct vec *prev)
|
||||
{
|
||||
if (obj->dumped)
|
||||
return;
|
||||
obj->dumped = 1;
|
||||
add_item(curr, prev, obj);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tricky logic ahead: when dumping a vector, we search for a vectors that
|
||||
* depends on that vector for ".". If we find one, we dump it immediately after
|
||||
* this vector.
|
||||
*/
|
||||
|
||||
static void recurse_vec(struct order **curr, struct vec *vec)
|
||||
{
|
||||
struct vec *next;
|
||||
struct obj *obj;
|
||||
|
||||
add_item(curr, vec, NULL);
|
||||
for (obj = vec->frame->objs; obj; obj = obj->next)
|
||||
if (may_put_obj_now(obj, vec))
|
||||
put_obj(curr, obj, vec);
|
||||
if (n_vec_refs(vec) == 1) {
|
||||
for (next = vec->next; next->base != vec; next = next->next);
|
||||
recurse_vec(curr, next);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void order_vecs(struct order **curr, struct vec *vecs)
|
||||
{
|
||||
struct vec *vec;
|
||||
|
||||
for (vec = vecs; vec; vec = vec->next)
|
||||
if (!vec->base || n_vec_refs(vec->base) != 1)
|
||||
recurse_vec(curr, vec);
|
||||
}
|
||||
|
||||
|
||||
struct order *order_frame(const struct frame *frame)
|
||||
{
|
||||
struct order *order, *curr;
|
||||
struct vec *vec;
|
||||
struct obj *obj;
|
||||
int n = 0;
|
||||
|
||||
for (vec = frame->vecs; vec; vec = vec->next)
|
||||
n++;
|
||||
for (obj = frame->objs; obj; obj = obj->next)
|
||||
if (obj->type != ot_meas)
|
||||
n++;
|
||||
|
||||
for (obj = frame->objs; obj; obj = obj->next)
|
||||
obj->dumped = 0;
|
||||
|
||||
order = alloc_size(sizeof(*order)*(n+1));
|
||||
curr = order;
|
||||
|
||||
order_vecs(&curr, frame->vecs);
|
||||
|
||||
/* frames based on @ (anything else ?) */
|
||||
for (obj = frame->objs; obj; obj = obj->next)
|
||||
if (obj->type != ot_meas)
|
||||
put_obj(&curr, obj, NULL);
|
||||
|
||||
assert(curr == order+n);
|
||||
add_item(&curr, NULL, NULL);
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
|
||||
/* ----- variables --------------------------------------------------------- */
|
||||
|
||||
|
||||
@ -114,101 +294,61 @@ static char *obj_base_name(const struct vec *base, const struct vec *prev)
|
||||
}
|
||||
|
||||
|
||||
static int n_vec_refs(const struct vec *vec)
|
||||
char *print_obj(const struct obj *obj, const struct vec *prev)
|
||||
{
|
||||
const struct vec *walk;
|
||||
int n;
|
||||
|
||||
n = 0;
|
||||
for (walk = vec->frame->vecs; walk; walk = walk->next)
|
||||
if (walk->base == vec)
|
||||
n++;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "need" operates in two modes:
|
||||
*
|
||||
* - if "prev" is non-NULL, we're looking for objects that need to be put after
|
||||
* the current vector (in "prev"). Only those objects need to be put there
|
||||
* that have at least one base that isn't the frame's origin or already has a
|
||||
* name.
|
||||
*
|
||||
* - if "prev" is NULL, we're at the end of the frame. We have already used all
|
||||
* the . references we could, so now we have to find out which objects
|
||||
* haven't been dumped yet. "need" still returns the ones that had a need to
|
||||
* be dumped. Again, that's those that have at least one possible "." base.
|
||||
* Since this "." base will have been used by now, the object must have been
|
||||
* dumped.
|
||||
*/
|
||||
|
||||
static int need(const struct vec *base, const struct vec *prev)
|
||||
{
|
||||
if (!base)
|
||||
return 0;
|
||||
if (base->name)
|
||||
return 0;
|
||||
if (prev)
|
||||
return base == prev;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* If we need a vector that's defined later, we have to defer dumping the
|
||||
* object.
|
||||
*/
|
||||
|
||||
static int later(const struct vec *base, const struct vec *prev)
|
||||
{
|
||||
while (prev) {
|
||||
if (base == prev)
|
||||
return 1;
|
||||
prev = prev->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int may_dump_obj_now(const struct obj *obj, const struct vec *prev)
|
||||
{
|
||||
int n, l;
|
||||
|
||||
n = need(obj->base, prev);
|
||||
l = later(obj->base, prev);
|
||||
char *base, *s, *s1, *s2, *s3;
|
||||
|
||||
base = obj_base_name(obj->base, prev);
|
||||
switch (obj->type) {
|
||||
case ot_frame:
|
||||
s = stralloc_printf("frame %s %s",
|
||||
obj->u.frame.ref->name, base);
|
||||
break;
|
||||
case ot_line:
|
||||
n |= need(obj->u.line.other, prev);
|
||||
l |= later(obj->u.line.other, prev);
|
||||
s1 = obj_base_name(obj->u.line.other, prev);
|
||||
s2 = unparse(obj->u.line.width);
|
||||
s = stralloc_printf("line %s %s %s", base, s1, s2);
|
||||
free(s1);
|
||||
free(s2);
|
||||
break;
|
||||
case ot_rect:
|
||||
n |= need(obj->u.rect.other, prev);
|
||||
l |= later(obj->u.rect.other, prev);
|
||||
s1 = obj_base_name(obj->u.rect.other, prev);
|
||||
s2 = unparse(obj->u.rect.width);
|
||||
s = stralloc_printf("rect %s %s %s", base, s1, s2);
|
||||
free(s1);
|
||||
free(s2);
|
||||
break;
|
||||
case ot_pad:
|
||||
n |= need(obj->u.pad.other, prev);
|
||||
l |= later(obj->u.pad.other, prev);
|
||||
s1 = obj_base_name(obj->u.pad.other, prev);
|
||||
s = stralloc_printf("pad \"%s\" %s %s",
|
||||
obj->u.pad.name, base, s1);
|
||||
free(s1);
|
||||
break;
|
||||
case ot_arc:
|
||||
n |= need(obj->u.arc.start, prev);
|
||||
n |= need(obj->u.arc.end, prev);
|
||||
l |= later(obj->u.arc.start, prev);
|
||||
l |= later(obj->u.arc.end, prev);
|
||||
s1 = obj_base_name(obj->u.arc.start, prev);
|
||||
s3 = unparse(obj->u.arc.width);
|
||||
if (obj->u.arc.start == obj->u.arc.end) {
|
||||
s = stralloc_printf("circ %s %s %s", base, s1, s3);
|
||||
} else {
|
||||
s2 = obj_base_name(obj->u.arc.end, prev);
|
||||
s = stralloc_printf("arc %s %s %s %s",
|
||||
base, s1, s2, s3);
|
||||
free(s2);
|
||||
}
|
||||
free(s1);
|
||||
free(s3);
|
||||
break;
|
||||
case ot_meas:
|
||||
return 0;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
return n && !l;
|
||||
free(base);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/* ----- print measurement ------------------------------------------------- */
|
||||
|
||||
|
||||
static const char *meas_type_name[mt_n] = {
|
||||
"meas", "measx", "measy",
|
||||
"meas", "measx", "measy",
|
||||
@ -216,132 +356,79 @@ static const char *meas_type_name[mt_n] = {
|
||||
|
||||
|
||||
|
||||
static void print_meas_base(FILE *file, struct vec *base)
|
||||
static char *print_meas_base(struct vec *base)
|
||||
{
|
||||
if (base->frame != root_frame)
|
||||
fprintf(file, "%s.", base->frame->name);
|
||||
fprintf(file, "%s", base->name);
|
||||
if (base->frame == root_frame)
|
||||
return stralloc_printf("%s", base->name);
|
||||
else
|
||||
return stralloc_printf("%s.%s", base->frame->name, base->name);
|
||||
}
|
||||
|
||||
|
||||
static void dump_obj(FILE *file, struct obj *obj, const char *indent,
|
||||
const struct vec *prev)
|
||||
char *print_meas(const struct obj *obj)
|
||||
{
|
||||
char *base, *s1, *s2, *s3;
|
||||
char *s, *t;
|
||||
char *s1, *s2, *s3;
|
||||
|
||||
if (obj->dumped)
|
||||
return;
|
||||
obj->dumped = 1;
|
||||
base = obj_base_name(obj->base, prev);
|
||||
switch (obj->type) {
|
||||
case ot_frame:
|
||||
fprintf(file, "%sframe %s %s\n",
|
||||
indent, obj->u.frame.ref->name, base);
|
||||
break;
|
||||
case ot_line:
|
||||
s1 = obj_base_name(obj->u.line.other, prev);
|
||||
s2 = unparse(obj->u.line.width);
|
||||
fprintf(file, "%sline %s %s %s\n", indent, base, s1, s2);
|
||||
free(s1);
|
||||
free(s2);
|
||||
break;
|
||||
case ot_rect:
|
||||
s1 = obj_base_name(obj->u.rect.other, prev);
|
||||
s2 = unparse(obj->u.rect.width);
|
||||
fprintf(file, "%srect %s %s %s\n", indent, base, s1, s2);
|
||||
free(s1);
|
||||
free(s2);
|
||||
break;
|
||||
case ot_pad:
|
||||
s1 = obj_base_name(obj->u.pad.other, prev);
|
||||
fprintf(file, "%spad \"%s\" %s %s\n", indent,
|
||||
obj->u.pad.name, base, s1);
|
||||
free(s1);
|
||||
break;
|
||||
case ot_arc:
|
||||
s1 = obj_base_name(obj->u.arc.start, prev);
|
||||
s3 = unparse(obj->u.arc.width);
|
||||
if (obj->u.arc.start == obj->u.arc.end) {
|
||||
fprintf(file, "%scirc %s %s %s\n",
|
||||
indent, base, s1, s3);
|
||||
} else {
|
||||
s2 = obj_base_name(obj->u.arc.end, prev);
|
||||
fprintf(file, "%sarc %s %s %s %s\n", indent,
|
||||
base, s1, s2, s3);
|
||||
free(s2);
|
||||
}
|
||||
free(s1);
|
||||
free(s3);
|
||||
break;
|
||||
case ot_meas:
|
||||
fprintf(file, "%s%s ", indent,
|
||||
meas_type_name[obj->u.meas.type]);
|
||||
if (obj->u.meas.label)
|
||||
fprintf(file, "\"%s\" ", obj->u.meas.label);
|
||||
print_meas_base(file, obj->base);
|
||||
fprintf(file, " %s ",
|
||||
assert(obj->type == ot_meas);
|
||||
|
||||
s = stralloc_printf("%s ", meas_type_name[obj->u.meas.type]);
|
||||
if (obj->u.meas.label) {
|
||||
t = stralloc_printf("%s\"%s\" ", s, obj->u.meas.label);
|
||||
free(s);
|
||||
s = t;
|
||||
}
|
||||
s1 = print_meas_base(obj->base);
|
||||
s2 = stralloc_printf(" %s ",
|
||||
obj->u.meas.type < 3 ? obj->u.meas.inverted ? "<-" : "->" :
|
||||
obj->u.meas.inverted ? "<<" : ">>");
|
||||
print_meas_base(file, obj->u.meas.high);
|
||||
if (!obj->u.meas.offset)
|
||||
fprintf(file, "\n");
|
||||
else {
|
||||
s1 = unparse(obj->u.meas.offset);
|
||||
fprintf(file, " %s\n", s1);
|
||||
free(s1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
free(base);
|
||||
s3 = print_meas_base(obj->u.meas.high);
|
||||
t = stralloc_printf("%s%s%s%s", s, s1, s2, s3);
|
||||
free(s);
|
||||
free(s1);
|
||||
free(s2);
|
||||
free(s3);
|
||||
s = t;
|
||||
|
||||
if (!obj->u.meas.offset)
|
||||
return s;
|
||||
|
||||
s1 = unparse(obj->u.meas.offset);
|
||||
t = stralloc_printf("%s %s", s, s1);
|
||||
free(s);
|
||||
free(s1);
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Tricky logic ahead: when dumping a vector, we search for a vectors that
|
||||
* depends on that vector for ".". If we find one, we dump it immediately after
|
||||
* this vector.
|
||||
*/
|
||||
/* ----- print vector ------------------------------------------------------ */
|
||||
|
||||
static void recurse_vec(FILE *file, const struct vec *vec, const char *indent)
|
||||
|
||||
char *print_label(const struct vec *vec)
|
||||
{
|
||||
if (vec->name)
|
||||
return stralloc(vec->name);
|
||||
else
|
||||
return generate_name(vec);
|
||||
}
|
||||
|
||||
|
||||
char *print_vec(const struct vec *vec)
|
||||
{
|
||||
const struct vec *next;
|
||||
struct obj *obj;
|
||||
char *base, *x, *y, *s;
|
||||
|
||||
base = base_name(vec->base, vec);
|
||||
x = unparse(vec->x);
|
||||
y = unparse(vec->y);
|
||||
if (vec->name)
|
||||
fprintf(file, "%s%s: vec %s(%s, %s)\n",
|
||||
indent, vec->name, base, x, y);
|
||||
s = stralloc_printf("vec %s(%s, %s)", base, x, y);
|
||||
else {
|
||||
s = generate_name(vec);
|
||||
fprintf(file, "%s%s: vec %s(%s, %s)\n", indent, s, base, x, y);
|
||||
free(s);
|
||||
s = stralloc_printf("vec %s(%s, %s)", base, x, y);
|
||||
}
|
||||
free(base);
|
||||
free(x);
|
||||
free(y);
|
||||
|
||||
for (obj = vec->frame->objs; obj; obj = obj->next)
|
||||
if (may_dump_obj_now(obj, vec))
|
||||
dump_obj(file, obj, indent, vec);
|
||||
if (n_vec_refs(vec) == 1) {
|
||||
for (next = vec->next; next->base != vec; next = next->next);
|
||||
recurse_vec(file, next, indent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void dump_vecs(FILE *file, const struct vec *vecs, const char *indent)
|
||||
{
|
||||
const struct vec *vec;
|
||||
|
||||
for (vec = vecs; vec; vec = vec->next)
|
||||
if (!vec->base || n_vec_refs(vec->base) != 1)
|
||||
recurse_vec(file, vec, indent);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
@ -354,21 +441,36 @@ static void dump_frame(FILE *file, const struct frame *frame,
|
||||
const struct table *table;
|
||||
const struct loop *loop;
|
||||
struct obj *obj;
|
||||
struct order *order;
|
||||
const struct order *item;
|
||||
char *s, *s1;
|
||||
|
||||
for (table = frame->tables; table; table = table->next)
|
||||
dump_table(file, table, indent);
|
||||
for (loop = frame->loops; loop; loop = loop->next)
|
||||
dump_loop(file, loop, indent);
|
||||
for (obj = frame->objs; obj; obj = obj->next)
|
||||
obj->dumped = 0;
|
||||
dump_vecs(file, frame->vecs, indent);
|
||||
|
||||
/* frames based on @ (anything else ?) */
|
||||
for (obj = frame->objs; obj; obj = obj->next)
|
||||
if (obj->type != ot_meas)
|
||||
dump_obj(file, obj, indent, NULL);
|
||||
for (obj = frame->objs; obj; obj = obj->next)
|
||||
dump_obj(file, obj, indent, NULL);
|
||||
order = order_frame(frame);
|
||||
for (item = order; item->vec || item->obj; item++) {
|
||||
if (item->obj) {
|
||||
s = print_obj(item->obj, item->vec);
|
||||
fprintf(file, "%s%s\n", indent, s);
|
||||
} else {
|
||||
s1 = print_label(item->vec);
|
||||
s = print_vec(item->vec);
|
||||
fprintf(file, "%s%s: %s\n", indent, s1, s);
|
||||
}
|
||||
free(s);
|
||||
}
|
||||
free(order);
|
||||
|
||||
for (obj = frame->objs; obj; obj = obj->next) {
|
||||
if (obj->dumped)
|
||||
continue;
|
||||
s = print_meas(obj);
|
||||
fprintf(file, "%s%s\n", indent, s);
|
||||
free(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
24
dump.h
24
dump.h
@ -16,6 +16,30 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "obj.h"
|
||||
|
||||
|
||||
/*
|
||||
* vec obj
|
||||
* --------------------------------------------------------------
|
||||
* NULL NULL end of list
|
||||
* non-NULL NULL vector
|
||||
* NULL non-NULL object, no previous vector
|
||||
* non-NULL non-NULL object, with previous vector
|
||||
*/
|
||||
|
||||
struct order {
|
||||
struct vec *vec;
|
||||
struct obj *obj;
|
||||
};
|
||||
|
||||
|
||||
char *print_label(const struct vec *vec);
|
||||
char *print_vec(const struct vec *vec);
|
||||
char *print_obj(const struct obj *obj, const struct vec *prev);
|
||||
char *print_meas(const struct obj *obj);
|
||||
|
||||
struct order *order_frame(const struct frame *frame);
|
||||
|
||||
int dump(FILE *file);
|
||||
|
||||
|
145
gui_frame.c
145
gui_frame.c
@ -16,6 +16,7 @@
|
||||
|
||||
#include "util.h"
|
||||
#include "error.h"
|
||||
#include "dump.h"
|
||||
#include "inst.h"
|
||||
#include "obj.h"
|
||||
#include "delete.h"
|
||||
@ -906,7 +907,7 @@ static GtkWidget *build_vars(struct frame *frame)
|
||||
struct table *table;
|
||||
struct loop *loop;
|
||||
|
||||
vbox= gtk_vbox_new(FALSE, 0);
|
||||
vbox = gtk_vbox_new(FALSE, 0);
|
||||
for (table = frame->tables; table; table = table->next) {
|
||||
add_sep(vbox, 3);
|
||||
build_assignment(vbox, frame, table);
|
||||
@ -920,6 +921,122 @@ static GtkWidget *build_vars(struct frame *frame)
|
||||
}
|
||||
|
||||
|
||||
/* ----- items ------------------------------------------------------------- */
|
||||
|
||||
|
||||
static void set_item_color(struct inst *inst, const char *color)
|
||||
{
|
||||
GtkWidget *label;
|
||||
|
||||
if (inst->vec)
|
||||
label = inst->vec->list_widget;
|
||||
else
|
||||
label = inst->obj->list_widget;
|
||||
label_in_box_bg(box_of_label(label), color);
|
||||
}
|
||||
|
||||
|
||||
void gui_frame_select_inst(struct inst *inst)
|
||||
{
|
||||
set_item_color(inst, COLOR_ITEM_SELECTED);
|
||||
}
|
||||
|
||||
|
||||
void gui_frame_deselect_inst(struct inst *inst)
|
||||
{
|
||||
set_item_color(inst, COLOR_ITEM_NORMAL);
|
||||
}
|
||||
|
||||
|
||||
static GtkWidget *item_label(GtkWidget *tab, char *s, int col, int row)
|
||||
{
|
||||
GtkWidget *label;
|
||||
|
||||
label = label_in_box_new(s);
|
||||
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
|
||||
gtk_widget_modify_font(label, item_list_font);
|
||||
gtk_table_attach_defaults(GTK_TABLE(tab), box_of_label(label),
|
||||
col, col+1, row, row+1);
|
||||
label_in_box_bg(box_of_label(label), COLOR_ITEM_NORMAL);
|
||||
free(s);
|
||||
return label;
|
||||
}
|
||||
|
||||
|
||||
static GtkWidget *build_items(struct frame *frame)
|
||||
{
|
||||
GtkWidget *hbox, *tab;
|
||||
struct order *order, *item;
|
||||
struct vec *vec;
|
||||
struct obj *obj;
|
||||
int n;
|
||||
char *s, *t;
|
||||
|
||||
n = 0;
|
||||
for (vec = frame->vecs; vec; vec = vec->next)
|
||||
n++;
|
||||
for (obj = frame->objs; obj; obj = obj->next)
|
||||
if (obj->type != ot_meas)
|
||||
n++;
|
||||
|
||||
hbox = gtk_hbox_new(FALSE, 0);
|
||||
|
||||
tab = gtk_table_new(n, 2, FALSE);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), tab, FALSE, FALSE, 0);
|
||||
|
||||
order = order_frame(frame);
|
||||
n = 0;
|
||||
for (item = order; item->vec || item->obj; item++) {
|
||||
if (item->obj) {
|
||||
s = print_obj(item->obj, item->vec);
|
||||
item->obj->list_widget = item_label(tab, s, 1, n);
|
||||
} else {
|
||||
s = print_label(item->vec);
|
||||
t = stralloc_printf("%s: ", s);
|
||||
free(s);
|
||||
item_label(tab, t, 0, n);
|
||||
|
||||
s = print_vec(item->vec);
|
||||
item->vec->list_widget = item_label(tab, s, 1, n);
|
||||
}
|
||||
n++;
|
||||
}
|
||||
free(order);
|
||||
|
||||
return hbox;
|
||||
}
|
||||
|
||||
|
||||
static GtkWidget *build_meas(struct frame *frame)
|
||||
{
|
||||
GtkWidget *hbox, *tab;
|
||||
struct obj *obj;
|
||||
int n;
|
||||
char *s;
|
||||
|
||||
n = 0;
|
||||
for (obj = frame->objs; obj; obj = obj->next)
|
||||
if (obj->type == ot_meas)
|
||||
n++;
|
||||
|
||||
hbox = gtk_hbox_new(FALSE, 0);
|
||||
|
||||
tab = gtk_table_new(n, 2, FALSE);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), tab, FALSE, FALSE, 0);
|
||||
|
||||
n = 0;
|
||||
for (obj = frame->objs; obj; obj = obj->next) {
|
||||
if (obj->type != ot_meas)
|
||||
continue;
|
||||
s = print_meas(obj);
|
||||
obj->list_widget = item_label(tab, s, 0, n);
|
||||
n++;
|
||||
}
|
||||
|
||||
return hbox;
|
||||
}
|
||||
|
||||
|
||||
/* ----- part name --------------------------------------------------------- */
|
||||
|
||||
|
||||
@ -1110,17 +1227,21 @@ static GtkWidget *build_frame_refs(const struct frame *frame)
|
||||
void build_frames(GtkWidget *vbox)
|
||||
{
|
||||
struct frame *frame;
|
||||
GtkWidget *tab, *label, *refs, *vars;
|
||||
GtkWidget *hbox, *tab, *label, *refs, *vars, *items, *meas;
|
||||
int n = 0;
|
||||
|
||||
destroy_all_children(GTK_CONTAINER(vbox));
|
||||
for (frame = frames; frame; frame = frame->next)
|
||||
n++;
|
||||
|
||||
tab = gtk_table_new(n*2+1, 2, FALSE);
|
||||
hbox = gtk_hbox_new(FALSE, 0);
|
||||
|
||||
tab = gtk_table_new(n*2+3, 3, FALSE);
|
||||
gtk_table_set_row_spacings(GTK_TABLE(tab), 1);
|
||||
gtk_table_set_col_spacings(GTK_TABLE(tab), 1);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), tab, FALSE, FALSE, 0);
|
||||
|
||||
gtk_box_pack_start(GTK_BOX(hbox), tab, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
|
||||
|
||||
label = build_part_name();
|
||||
gtk_table_attach_defaults(GTK_TABLE(tab), label, 0, 1, 0, 1);
|
||||
@ -1138,7 +1259,21 @@ void build_frames(GtkWidget *vbox)
|
||||
vars = build_vars(frame);
|
||||
gtk_table_attach_defaults(GTK_TABLE(tab), vars,
|
||||
1, 2, n*2+2, n*2+3);
|
||||
|
||||
items = build_items(frame);
|
||||
gtk_table_attach_defaults(GTK_TABLE(tab), items,
|
||||
2, 3, n*2+2, n*2+3);
|
||||
|
||||
n++;
|
||||
}
|
||||
gtk_widget_show_all(tab);
|
||||
|
||||
label = label_in_box_new(" ");
|
||||
gtk_table_attach_defaults(GTK_TABLE(tab), box_of_label(label),
|
||||
2, 3, n*2+1, n*2+2);
|
||||
|
||||
meas = build_meas(root_frame);
|
||||
gtk_table_attach_defaults(GTK_TABLE(tab), meas,
|
||||
2, 3, n*2+2, n*2+3);
|
||||
|
||||
gtk_widget_show_all(hbox);
|
||||
}
|
||||
|
@ -21,6 +21,9 @@ void make_popups(void);
|
||||
|
||||
void select_frame(struct frame *frame);
|
||||
|
||||
void gui_frame_select_inst(struct inst *inst);
|
||||
void gui_frame_deselect_inst(struct inst *inst);
|
||||
|
||||
void build_frames(GtkWidget *vbox);
|
||||
|
||||
#endif /* !GUI_FRAME_H */
|
||||
|
@ -32,6 +32,8 @@ GdkGC *gc_ptext[mode_n];
|
||||
GdkGC *gc_meas[mode_n];
|
||||
GdkGC *gc_frame[mode_n];
|
||||
|
||||
PangoFontDescription *item_list_font;
|
||||
|
||||
|
||||
static GdkGC *gc(const char *spec, int width)
|
||||
{
|
||||
@ -75,4 +77,6 @@ void gui_setup_style(GdkDrawable *drawable)
|
||||
// gc_highlight = gc("#ff8020", 2);
|
||||
gc_highlight = gc("#ff90d0", 2);
|
||||
gc_frame[mode_hover] = gc_vec[mode_hover] = gc("#c00000", 2);
|
||||
|
||||
item_list_font = pango_font_description_from_string(ITEM_LIST_FONT);
|
||||
}
|
||||
|
@ -47,6 +47,8 @@
|
||||
#define FRAME_EYE_R1 3
|
||||
#define FRAME_EYE_R2 5
|
||||
|
||||
#define ITEM_LIST_FONT "Sans 8"
|
||||
|
||||
#define SELECT_R 6 /* pixels within which we select */
|
||||
|
||||
#define DRAG_MIN_R 5
|
||||
@ -84,6 +86,9 @@
|
||||
#define TOOL_UNSELECTED "#dcdad5"
|
||||
#define TOOL_SELECTED "red"
|
||||
|
||||
#define COLOR_ITEM_NORMAL "#dcdad5"
|
||||
#define COLOR_ITEM_SELECTED COLOR_FRAME_SELECTED
|
||||
|
||||
|
||||
/* ----- canvas drawing styles --------------------------------------------- */
|
||||
|
||||
@ -99,6 +104,7 @@ extern GdkGC *gc_ptext[mode_n];
|
||||
extern GdkGC *gc_meas[mode_n];
|
||||
extern GdkGC *gc_frame[mode_n];
|
||||
|
||||
extern PangoFontDescription *item_list_font;
|
||||
|
||||
void gui_setup_style(GdkDrawable *drawable);
|
||||
|
||||
|
11
inst.c
11
inst.c
@ -25,6 +25,7 @@
|
||||
#include "gui_tool.h"
|
||||
#include "gui_meas.h"
|
||||
#include "gui_inst.h"
|
||||
#include "gui_frame.h"
|
||||
#include "gui.h"
|
||||
#include "inst.h"
|
||||
|
||||
@ -117,9 +118,11 @@ int inst_select(struct coord pos)
|
||||
|
||||
deselect_outside();
|
||||
edit_nothing();
|
||||
selected_inst = NULL;
|
||||
if (selected_inst)
|
||||
if (selected_inst) {
|
||||
gui_frame_deselect_inst(selected_inst);
|
||||
tool_selected_inst(NULL);
|
||||
}
|
||||
selected_inst = NULL;
|
||||
FOR_INST_PRIOS_DOWN(prio) {
|
||||
if (!show(prio))
|
||||
continue;
|
||||
@ -157,6 +160,7 @@ int inst_select(struct coord pos)
|
||||
selected:
|
||||
set_path(1);
|
||||
tool_selected_inst(selected_inst);
|
||||
gui_frame_select_inst(selected_inst);
|
||||
if (selected_inst->ops->select)
|
||||
selected_inst->ops->select(selected_inst);
|
||||
return 1;
|
||||
@ -269,6 +273,7 @@ void inst_deselect(void)
|
||||
if (selected_inst) {
|
||||
set_path(0);
|
||||
tool_selected_inst(NULL);
|
||||
gui_frame_deselect_inst(selected_inst);
|
||||
}
|
||||
deselect_outside();
|
||||
status_set_type_x("");
|
||||
@ -345,6 +350,8 @@ static struct inst *add_inst(const struct inst_ops *ops, enum inst_prio prio,
|
||||
|
||||
inst = alloc_type(struct inst);
|
||||
inst->ops = ops;
|
||||
inst->vec = NULL;
|
||||
inst->obj = NULL;
|
||||
inst->base = inst->bbox.min = inst->bbox.max = base;
|
||||
inst->outer = curr_frame;
|
||||
inst->active = IS_ACTIVE;
|
||||
|
4
inst.h
4
inst.h
@ -76,8 +76,8 @@ struct inst {
|
||||
struct coord base;
|
||||
// struct inst *base_inst; /* frame or vector leading to this item */
|
||||
struct bbox bbox;
|
||||
struct vec *vec; /* undefined if not vector */
|
||||
struct obj *obj; /* undefined if not object */
|
||||
struct vec *vec; /* NULL if not vector */
|
||||
struct obj *obj; /* NULL if not object */
|
||||
struct inst *outer; /* frame containing this item */
|
||||
int active;
|
||||
int in_path;
|
||||
|
Loading…
Reference in New Issue
Block a user