diff --git a/TODO b/TODO index 9269e33..182a4fd 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,5 @@ Missing features: - populate input area (still needed: mm/mil, rezoom) -- add table/var/loop editor (missing: add col/row, add/del var/table/loop) - add default unit (combine with grid unit selection ?) - consider adding auto/mm/mil selection for each dimension - add measurements (partly done. still needed: find out how to define @@ -8,6 +7,10 @@ Missing features: - add KiCad output - add postscript output - add option to include/omit helper vecs and frames (display and postscript) +- reorder frames (can use text editor) +- reorder rows in a table (can use text editor) +- reorder columns in a table +- reorder variables in a frame (can use text editor) Error detection: - eliminate duplicate instances @@ -16,10 +19,12 @@ Style: - make column of entry field greedily consume all unallocated space - status area looks awful - add button with GTK_STOCK_UNDELETE for "undelete" to menu bar +- edit names/values/etc. in place if possible Bugs: - default silk width has no business being hard-coded in obj.c - undelete only works if not much has changed since the deletion +- re-center while dragging confuses the save-under mechanism Code cleanup: - merge edit_unique with edit_name diff --git a/delete.c b/delete.c index 10b9659..f150de6 100644 --- a/delete.c +++ b/delete.c @@ -52,7 +52,7 @@ static struct deletion { struct row *ref; struct row *prev; } row; - struct { + struct column { struct var *var; struct value *values; struct table *table; @@ -187,7 +187,8 @@ static void destroy_obj(struct obj *obj) { switch (obj->type) { case ot_frame: - /* nothing */ + if (obj->u.frame.ref->active_ref == obj) + obj->u.frame.ref->active_ref = NULL; break; case ot_pad: free(obj->u.pad.name); @@ -288,7 +289,62 @@ static void undelete_row(struct row *row, struct row *prev) void delete_column(struct table *table, int n) { + struct deletion *del; + struct column *col; + struct var **var; + struct row *row; + struct value **next, **value; + int i; + groups++; + + del = new_deletion(dt_column); + col = &del->u.col; + col->table = table; + col->n = n; + + var = &table->vars; + for (i = 0; i != n; i++) + var = &(*var)->next; + col->var = *var; + *var = (*var)->next; + + next = &col->values; + for (row = table->rows; row; row = row->next) { + value = &row->values; + for (i = 0; i != n; i++) + value = &(*value)->next; + *next = *value; + *value = (*value)->next; + next = &(*next)->next; + } + *next = NULL; +} + + +static void undelete_column(const struct column *col) +{ + struct var **var; + struct row *row; + struct value **anchor, *value, *next; + int i; + + var = &col->table->vars; + for (i = 0; i != col->n; i++) + var = &(*var)->next; + col->var->next = *var; + *var = col->var; + + value = col->values; + for (row = col->table->rows; row; row = row->next) { + anchor = &row->values; + for (i = 0; i != col->n; i++) + anchor = &(*anchor)->next; + next = value->next; + value->next = *anchor; + *anchor = value; + value = next; + } } @@ -471,6 +527,9 @@ static int undelete_one(void) case dt_row: undelete_row(del->u.row.ref, del->u.row.prev); break; + case dt_column: + undelete_column(&del->u.col); + break; default: abort(); } diff --git a/fpd.y b/fpd.y index 9fbe102..fee92c9 100644 --- a/fpd.y +++ b/fpd.y @@ -162,19 +162,13 @@ static struct obj *new_obj(enum obj_type type) %% all: - START_FPD fpd - | START_EXPR expr - { - expr_result = $2; - } - ; - -fpd: + START_FPD { root_frame = zalloc_type(struct frame); set_frame(root_frame); } - frame_defs part_name frame_items + + fpd { root_frame->prev = last_frame; if (last_frame) @@ -182,6 +176,14 @@ fpd: else frames = root_frame; } + | START_EXPR expr + { + expr_result = $2; + } + ; + +fpd: + | frame_defs part_name frame_items ; part_name: diff --git a/fped.c b/fped.c index d1cd9f7..d07e669 100644 --- a/fped.c +++ b/fped.c @@ -13,6 +13,7 @@ #include "cpp.h" +#include "util.h" #include "error.h" #include "obj.h" #include "inst.h" @@ -46,6 +47,10 @@ int main(int argc, char **argv) argc--; argv++; } + + if (!part_name) + part_name = stralloc("_"); + reporter = report_to_stderr; if (!instantiate()) return 1; diff --git a/gui.c b/gui.c index 8087374..77ba383 100644 --- a/gui.c +++ b/gui.c @@ -329,8 +329,11 @@ static void popup_add_row_by_value(void) static void popup_del_row(void) { struct value *value = popup_data; + struct table *table = value->row->table; delete_row(value->row); + if (table->active_row == value->row) + table->active_row = table->rows; change_world(); } @@ -341,7 +344,8 @@ static void popup_del_column_by_value(void) const struct value *walk; int n = 0; - for (walk = value->row->values; walk != value; walk = walk->next); + for (walk = value->row->values; walk != value; walk = walk->next) + n++; delete_column(value->row->table, n); change_world(); } @@ -530,7 +534,7 @@ static void edit_var(struct var *var) label_in_box_bg(var->widget, COLOR_VAR_EDITING); status_set_type_entry("name ="); status_set_name("%s", var->name); - edit_unique(&var->name, validate_var_name, var); + edit_unique(&var->name, validate_var_name, var, 1); } @@ -551,7 +555,7 @@ static void edit_value(struct value *value) { inst_select_outside(value, unselect_value); label_in_box_bg(value->widget, COLOR_EXPR_EDITING); - edit_expr(&value->expr); + edit_expr(&value->expr, 1); } @@ -954,7 +958,7 @@ static gboolean part_name_edit_event(GtkWidget *widget, GdkEventButton *event, label_in_box_bg(widget, COLOR_PART_NAME_EDITING); status_set_type_entry("part ="); status_set_name("%s", part_name); - edit_name(&part_name, validate_part_name, NULL); + edit_name(&part_name, validate_part_name, NULL, 1); break; } return TRUE; @@ -1015,7 +1019,7 @@ static void edit_frame(struct frame *frame) label_in_box_bg(frame->label, COLOR_FRAME_EDITING); status_set_type_entry("name ="); status_set_name("%s", frame->name); - edit_unique(&frame->name, validate_frame_name, frame); + edit_unique(&frame->name, validate_frame_name, frame, 1); } diff --git a/gui_status.c b/gui_status.c index 28c3985..8cbf874 100644 --- a/gui_status.c +++ b/gui_status.c @@ -110,10 +110,12 @@ static void entry_color(GtkWidget *widget, const char *color) static void setup_edit(GtkWidget *widget, const char *s, - struct edit_ops *ops, void *ctx) + struct edit_ops *ops, void *ctx, int focus) { gtk_entry_set_text(GTK_ENTRY(widget), s); entry_color(widget, COLOR_EDIT_ASIS); + if (focus) + gtk_widget_grab_focus(GTK_WIDGET(widget)); gtk_widget_show(widget); gtk_object_set_data(GTK_OBJECT(widget), "edit-ops", ops); gtk_object_set_data(GTK_OBJECT(widget), "edit-ctx", ctx); @@ -165,14 +167,14 @@ static struct edit_ops edit_ops_unique = { void edit_unique(const char **s, int (*validate)(const char *s, void *ctx), - void *ctx) + void *ctx, int focus) { static struct edit_unique_ctx unique_ctx; unique_ctx.s = s; unique_ctx.validate = validate; unique_ctx.ctx = ctx; - setup_edit(status_entry, *s, &edit_ops_unique, &unique_ctx); + setup_edit(status_entry, *s, &edit_ops_unique, &unique_ctx, focus); } @@ -221,7 +223,7 @@ static struct edit_ops edit_ops_null_unique = { void edit_unique_null(const char **s, - int (*validate)(const char *s, void *ctx), void *ctx) + int (*validate)(const char *s, void *ctx), void *ctx, int focus) { static struct edit_unique_ctx unique_ctx; @@ -229,7 +231,7 @@ void edit_unique_null(const char **s, unique_ctx.validate = validate; unique_ctx.ctx = ctx; setup_edit(status_entry, *s ? *s : "", - &edit_ops_null_unique, &unique_ctx); + &edit_ops_null_unique, &unique_ctx, focus); } @@ -277,14 +279,15 @@ static struct edit_ops edit_ops_name = { }; -void edit_name(char **s, int (*validate)(const char *s, void *ctx), void *ctx) +void edit_name(char **s, int (*validate)(const char *s, void *ctx), void *ctx, + int focus) { static struct edit_name_ctx name_ctx; name_ctx.s = s; name_ctx.validate = validate; name_ctx.ctx = ctx; - setup_edit(status_entry, *s, &edit_ops_name, &name_ctx); + setup_edit(status_entry, *s, &edit_ops_name, &name_ctx, focus); } @@ -335,31 +338,31 @@ static struct edit_ops edit_ops_expr = { }; -static void edit_any_expr(GtkWidget *widget, struct expr **expr) +static void edit_any_expr(GtkWidget *widget, struct expr **expr, int focus) { char *s; s = unparse(*expr); - setup_edit(widget, s, &edit_ops_expr, expr); + setup_edit(widget, s, &edit_ops_expr, expr, focus); free(s); } -void edit_expr(struct expr **expr) +void edit_expr(struct expr **expr, int focus) { - edit_any_expr(status_entry, expr); + edit_any_expr(status_entry, expr, focus); } void edit_x(struct expr **expr) { - edit_any_expr(status_entry_x, expr); + edit_any_expr(status_entry_x, expr, 0); } void edit_y(struct expr **expr) { - edit_any_expr(status_entry_y, expr); + edit_any_expr(status_entry_y, expr, 0); } diff --git a/gui_status.h b/gui_status.h index 0ee3786..3853743 100644 --- a/gui_status.h +++ b/gui_status.h @@ -21,11 +21,12 @@ void edit_unique(const char **s, int (*validate)(const char *s, void *ctx), - void *ctx); + void *ctx, int focus); void edit_unique_null(const char **s, int (*validate)(const char *s, void *ctx), - void *ctx); -void edit_name(char **s, int (*validate)(const char *s, void *ctx), void *ctx); -void edit_expr(struct expr **expr); + void *ctx, int focus); +void edit_name(char **s, int (*validate)(const char *s, void *ctx), void *ctx, + int focus); +void edit_expr(struct expr **expr, int focus); void edit_x(struct expr **expr); void edit_y(struct expr **expr); void edit_nothing(void); diff --git a/gui_tools.c b/gui_tools.c index 0910568..2f1a5ea 100644 --- a/gui_tools.c +++ b/gui_tools.c @@ -168,8 +168,8 @@ static struct coord gridify(struct coord base, struct coord pos) struct coord new; unit_type unit = mm_to_units(0.1); - new.x = pos.x-(pos.x-base.x % unit); - new.y = pos.y-(pos.y-base.y % unit); + new.x = pos.x-((pos.x-base.x) % unit); + new.y = pos.y-((pos.y-base.y) % unit); if (new.x != base.x || new.y != base.y) return new; if (fabs(pos.x-base.x) > fabs(pos.y-base.y)) @@ -494,7 +494,7 @@ static int end_new_meas(struct draw_ctx *ctx, static struct tool_ops meas_ops = { - .drag_new = NULL, + .drag_new = drag_new_line, .end_new = end_new_meas, }; @@ -588,6 +588,8 @@ static int end_new_frame(struct draw_ctx *ctx, obj = new_obj(ot_frame, from); obj->u.frame.ref = locked_frame; obj->u.frame.lineno = 0; + if (!locked_frame->active_ref) + locked_frame->active_ref = obj; locked_frame = NULL; tool_frame_update(); return 1; diff --git a/inst.c b/inst.c index 86fe4bc..ad8ec87 100644 --- a/inst.c +++ b/inst.c @@ -353,7 +353,7 @@ static void vec_op_select(struct inst *self) status_set_type_entry("ref ="); 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_unique_null(&self->vec->name, validate_vec_name, self->vec, 0); edit_x(&self->vec->x); edit_y(&self->vec->y); } @@ -404,7 +404,7 @@ static void line_op_debug(struct inst *self) static void line_op_select(struct inst *self) { rect_status(self->bbox.min, self->bbox.max, self->u.rect.width); - edit_expr(&self->obj->u.line.width); + edit_expr(&self->obj->u.line.width, 0); } @@ -457,7 +457,7 @@ static void rect_op_debug(struct inst *self) static void rect_op_select(struct inst *self) { rect_status(self->bbox.min, self->bbox.max, self->u.rect.width); - edit_expr(&self->obj->u.rect.width); + edit_expr(&self->obj->u.rect.width, 0); } @@ -514,7 +514,7 @@ static void pad_op_select(struct inst *self) status_set_type_entry("label ="); status_set_name("%s", self->u.pad.name); rect_status(self->base, self->u.pad.other, -1); - edit_name(&self->obj->u.pad.name, validate_pad_name, NULL); + edit_name(&self->obj->u.pad.name, validate_pad_name, NULL, 0); } @@ -572,7 +572,7 @@ static void arc_op_select(struct inst *self) status_set_r("r = %5.2f mm", units_to_mm(self->u.arc.r)); status_set_type_entry("width ="); status_set_name("%5.2f mm", units_to_mm(self->u.arc.width)); - edit_expr(&self->obj->u.arc.width); + edit_expr(&self->obj->u.arc.width, 0); } @@ -638,9 +638,9 @@ static void meas_op_debug(struct inst *self) static void meas_op_select(struct inst *self) { rect_status(self->bbox.min, self->bbox.max, -1); - status_set_type_entry("width ="); + status_set_type_entry("offset ="); status_set_name("%5.2f mm", units_to_mm(self->u.meas.offset)); - edit_expr(&self->obj->u.meas.offset); + edit_expr(&self->obj->u.meas.offset, 0); }