diff --git a/gui_canvas.c b/gui_canvas.c index ed8ee29..be57216 100644 --- a/gui_canvas.c +++ b/gui_canvas.c @@ -111,7 +111,7 @@ void redraw(void) aw = draw_ctx.widget->allocation.width; ah = draw_ctx.widget->allocation.height; gdk_draw_rectangle(draw_ctx.widget->window, - instantiation_ok ? gc_bg : gc_bg_error, TRUE, 0, 0, aw, ah); + instantiation_error ? gc_bg_error : gc_bg, TRUE, 0, 0, aw, ah); inst_draw(); if (highlight) diff --git a/gui_frame.c b/gui_frame.c index 6d9f0ee..78347e9 100644 --- a/gui_frame.c +++ b/gui_frame.c @@ -852,6 +852,8 @@ static void build_loop(GtkWidget *vbox, struct frame *frame, field = label_in_box_new(loop->var.name); gtk_box_pack_start(GTK_BOX(hbox), box_of_label(field), FALSE, FALSE, 0); label_in_box_bg(field, COLOR_VAR_PASSIVE); + if (instantiation_error == loop) + label_in_box_fg(field, COLOR_ITEM_ERROR); g_signal_connect(G_OBJECT(box_of_label(field)), "button_press_event", G_CALLBACK(loop_var_select_event), loop); @@ -1037,6 +1039,9 @@ static GtkWidget *build_items(struct frame *frame) s = print_obj(item->obj, item->vec); item->obj->list_widget = item_label(tab, s, 1, n, item_select_obj, item->obj); + if (item->obj == instantiation_error) + label_in_box_fg(item->obj->list_widget, + COLOR_ITEM_ERROR); } else { s = print_label(item->vec); t = stralloc_printf("%s: ", s); @@ -1046,6 +1051,9 @@ static GtkWidget *build_items(struct frame *frame) s = print_vec(item->vec); item->vec->list_widget = item_label(tab, s, 1, n, item_select_vec, item->vec); + if (item->vec == instantiation_error) + label_in_box_fg(item->vec->list_widget, + COLOR_ITEM_ERROR); } n++; } @@ -1083,6 +1091,8 @@ static GtkWidget *build_meas(struct frame *frame) s = print_meas(obj); obj->list_widget = item_label(tab, s, 0, n, item_select_obj, obj); + if (obj == instantiation_error) + label_in_box_fg(obj->list_widget, COLOR_ITEM_ERROR); n++; } diff --git a/gui_style.h b/gui_style.h index bd7b4e3..87fe575 100644 --- a/gui_style.h +++ b/gui_style.h @@ -83,11 +83,12 @@ #define COLOR_VAR_TABLE_SEP "black" -#define TOOL_UNSELECTED "#dcdad5" -#define TOOL_SELECTED "red" +#define COLOR_TOOL_UNSELECTED "#dcdad5" +#define COLOR_TOOL_SELECTED "red" #define COLOR_ITEM_NORMAL "#dcdad5" #define COLOR_ITEM_SELECTED COLOR_FRAME_SELECTED +#define COLOR_ITEM_ERROR "red" /* ----- canvas drawing styles --------------------------------------------- */ diff --git a/gui_tool.c b/gui_tool.c index 1fa4fce..0b8624c 100644 --- a/gui_tool.c +++ b/gui_tool.c @@ -926,11 +926,11 @@ static void tool_select(GtkWidget *evbox, struct tool_ops *ops) if (active_tool) { if (active_ops && active_ops->tool_deselected) active_ops->tool_deselected(); - col = get_color(TOOL_UNSELECTED); + col = get_color(COLOR_TOOL_UNSELECTED); gtk_widget_modify_bg(active_tool, GTK_STATE_NORMAL, &col); active_tool = NULL; } - col = get_color(TOOL_SELECTED); + col = get_color(COLOR_TOOL_SELECTED); gtk_widget_modify_bg(evbox, GTK_STATE_NORMAL, &col); active_tool = evbox; active_ops = ops; diff --git a/gui_util.c b/gui_util.c index b418bea..a7cdac6 100644 --- a/gui_util.c +++ b/gui_util.c @@ -151,6 +151,14 @@ GtkWidget *box_of_label(GtkWidget *label) } +void label_in_box_fg(GtkWidget *label, const char *color) +{ + GdkColor col = get_color(color); + + gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &col); +} + + void label_in_box_bg(GtkWidget *label, const char *color) { GtkWidget *box; diff --git a/gui_util.h b/gui_util.h index 5bd2090..6b19e73 100644 --- a/gui_util.h +++ b/gui_util.h @@ -54,6 +54,7 @@ void draw_circle(GdkDrawable *da, GdkGC *gc, int fill, GtkWidget *label_in_box_new(const char *s); GtkWidget *box_of_label(GtkWidget *label); +void label_in_box_fg(GtkWidget *box, const char *color); void label_in_box_bg(GtkWidget *box, const char *color); GtkWidget *make_image(GdkDrawable *drawable, char **xpm); diff --git a/meas.c b/meas.c index 51e6282..d2232fa 100644 --- a/meas.c +++ b/meas.c @@ -232,7 +232,7 @@ int instantiate_meas(void) continue; meas = &obj->u.meas; if (!obj->base->samples || !meas->high->samples) - return 1; + continue; lt = lt_op[meas->type]; a0 = meas_find_min(lt, obj->base->samples); @@ -245,8 +245,10 @@ int instantiate_meas(void) offset.n = 0; else { offset = eval_unit(meas->offset, root_frame); - if (is_undef(offset)) + if (is_undef(offset)) { + instantiation_error = obj; return 0; + } } inst_meas(obj, meas->inverted ? b0 : a0, meas->inverted ? a0 : b0, diff --git a/obj.c b/obj.c index 32bd0c1..58ca1e4 100644 --- a/obj.c +++ b/obj.c @@ -32,7 +32,7 @@ char *part_name = NULL; struct frame *frames = NULL; struct frame *root_frame = NULL; struct frame *active_frame = NULL; -int instantiation_ok; +void *instantiation_error = NULL; static int generate_frame(struct frame *frame, struct coord base, @@ -71,19 +71,23 @@ static int generate_vecs(struct frame *frame, struct coord base) for (vec = frame->vecs; vec; vec = vec->next) { x = eval_unit(vec->x, frame); if (is_undef(x)) - return 0; + goto error; y = eval_unit(vec->y, frame); if (is_undef(y)) - return 0; + goto error; vec_base = vec->base ? vec->base->pos : base; vec->pos = vec_base; vec->pos.x += x.n; vec->pos.y += y.n; if (!inst_vec(vec, vec_base)) - return 0; + goto error; meas_post(vec, vec->pos); } return 1; + +error: + instantiation_error = vec; + return 0; } @@ -106,43 +110,43 @@ static int generate_objs(struct frame *frame, struct coord base, int active) width = eval_unit_default(obj->u.line.width, frame, DEFAULT_SILK_WIDTH); if (is_undef(width)) - return 0; + goto error; if (!inst_line(obj, obj->base ? obj->base->pos : base, obj->u.line.other ? obj->u.line.other->pos : base, width.n)) - return 0; + goto error; break; case ot_rect: width = eval_unit_default(obj->u.rect.width, frame, DEFAULT_SILK_WIDTH); if (is_undef(width)) - return 0; + goto error; if (!inst_rect(obj, obj->base ? obj->base->pos : base, obj->u.rect.other ? obj->u.rect.other->pos : base, width.n)) - return 0; + goto error; break; case ot_pad: name = expand(obj->u.pad.name, frame); if (!name) - return 0; + goto error; ok = inst_pad(obj, name, obj->base ? obj->base->pos : base, obj->u.pad.other ? obj->u.pad.other->pos : base); free(name); if (!ok) - return 0; + goto error; break; case ot_arc: width = eval_unit_default(obj->u.arc.width, frame, DEFAULT_SILK_WIDTH); if (is_undef(width)) - return 0; + goto error; if (!inst_arc(obj, obj->base ? obj->base->pos : base, obj->u.arc.start ? obj->u.arc.start->pos : base, obj->u.arc.end ? obj->u.arc.end->pos : base, width.n)) - return 0; + goto error; break; case ot_meas: break; @@ -150,6 +154,10 @@ static int generate_objs(struct frame *frame, struct coord base, int active) abort(); } return 1; + +error: + instantiation_error = obj; + return 0; } @@ -175,22 +183,26 @@ static int run_loops(struct frame *frame, struct loop *loop, from = eval_num(loop->from.expr, frame); if (is_undef(from)) { fail_expr(loop->from.expr); + instantiation_error = loop; return 0; } if (!is_dimensionless(from)) { fail("incompatible type for start value"); fail_expr(loop->from.expr); + instantiation_error = loop; return 0; } to = eval_num(loop->to.expr, frame); if (is_undef(to)) { fail_expr(loop->to.expr); + instantiation_error = loop; return 0; } if (!is_dimensionless(to)) { fail("incompatible type for end value"); fail_expr(loop->to.expr); + instantiation_error = loop; return 0; } @@ -203,6 +215,7 @@ static int run_loops(struct frame *frame, struct loop *loop, if (n >= MAX_ITERATIONS) { fail("%s: too many iterations (%d)", loop->var.name, MAX_ITERATIONS); + instantiation_error = loop; goto fail; } if (!run_loops(frame, loop->next, base, @@ -259,6 +272,7 @@ int instantiate(void) inst_start(); meas_start(); + instantiation_error = NULL; ok = generate_frame(root_frame, zero, NULL, NULL, 1); if (ok) ok = instantiate_meas(); @@ -266,6 +280,5 @@ int instantiate(void) inst_commit(); else inst_revert(); - instantiation_ok = ok; return ok; } diff --git a/obj.h b/obj.h index 2e5b476..37aa4fc 100644 --- a/obj.h +++ b/obj.h @@ -183,7 +183,7 @@ extern char *part_name; extern struct frame *frames; extern struct frame *root_frame; extern struct frame *active_frame; -extern int instantiation_ok; +extern void *instantiation_error; int instantiate(void);