From ef5859869570cc9324b99bf9d2f1f2f1f5562315 Mon Sep 17 00:00:00 2001 From: werner Date: Sat, 15 Aug 2009 20:52:08 +0000 Subject: [PATCH] - added -std=gnu99 so that we can use "round" and M_PI - added unit status and selection (in lower right corner) - added automatic unit selection - pointer coordinates are now shown with their unit - updated display of X, Y, width, offset, and radius for unit selection git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5454 99fdad57-331a-0410-800a-d7fa5415bdb3 --- Makefile | 2 +- TODO | 2 -- coord.c | 38 ++++++++++++++++++++ coord.h | 8 +++++ gui_canvas.c | 8 ++--- gui_status.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++---- gui_status.h | 4 +++ inst.c | 10 +++--- 8 files changed, 152 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index e87813f..cc0651b 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ LIBS_GTK = `pkg-config --libs gtk+-2.0` CFLAGS_WARN=-Wall -Wshadow -Wmissing-prototypes \ -Wmissing-declarations -CFLAGS=-g $(CFLAGS_GTK) -DCPP='"cpp"' $(CFLAGS_WARN) +CFLAGS=-g -std=gnu99 $(CFLAGS_GTK) -DCPP='"cpp"' $(CFLAGS_WARN) SLOPPY=-Wno-unused -Wno-implicit-function-declaration -Wno-missing-prototypes \ -Wno-missing-declarations LDLIBS = -lm -lfl $(LIBS_GTK) diff --git a/TODO b/TODO index 64fcea6..2863ffa 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,5 @@ Major missing features: - populate input area (still needed: mm/mil, rezoom) -- add default unit (combine with grid unit selection ?) -- consider adding auto/mm/mil selection for each dimension - add postscript output (partially done) - add option to include/omit helper vecs and frames (done for display, still need postscript). Better idea: in PS, print the component 10x, 1x, and then diff --git a/coord.c b/coord.c index c191051..76cfe47 100644 --- a/coord.c +++ b/coord.c @@ -30,6 +30,44 @@ double mil_to_mm(double mil, int exponent) return mil*pow(MIL_IN_MM, exponent); } + +/* ----- convert internal units to best external unit ---------------------- */ + + +double units_to_best(unit_type u, int *mm) +{ + /* + * For finding the best choice, we work with deci-micrometers and + * micro-inches. The conversion to "dum" is actually a no-op, but that + * may change if we ever pick a different internal unit than 0.1 um. + */ + + long dum = round(units_to_mm(u)*10000.0); + long uin = round(units_to_mil(u)*1000.0); + + /* remove trailing zeroes */ + + while (dum && !(dum % 10)) + dum /= 10; + while (uin && !(uin % 10)) + uin /= 10; + + /* ceil(log10(dum)) <= ceil(log10(uin)) ? */ + + while (dum && uin) { + dum /= 10; + uin /= 10; + } + if (!dum) { + *mm = 1; + return units_to_mm(u); + } else { + *mm = 0; + return units_to_mil(u); + } +} + + /* ----- vector operations ------------------------------------------------- */ diff --git a/coord.h b/coord.h index 892da15..9dd0679 100644 --- a/coord.h +++ b/coord.h @@ -54,6 +54,12 @@ static inline double units_to_mm(unit_type u) } +static inline double units_to_mil(unit_type u) +{ + return (double) u/MIL_UNITS; +} + + static inline int units_to_kicad(unit_type u) { return (double) u/KICAD_UNIT; @@ -69,6 +75,8 @@ static inline int coord_eq(struct coord a, struct coord b) double mm_to_mil(double mm, int exponent); double mil_to_mm(double mil, int exponent); +double units_to_best(unit_type u, int *mm); + struct coord normalize(struct coord v, unit_type len); struct coord rotate(struct coord v, double angle); struct coord add_vec(struct coord a, struct coord b); diff --git a/gui_canvas.c b/gui_canvas.c index be57216..8c42d61 100644 --- a/gui_canvas.c +++ b/gui_canvas.c @@ -55,10 +55,10 @@ static void update_zoom(void) static void update_pos(struct coord pos) { - status_set_sys_x("X %5.2lf" , units_to_mm(pos.x)); - status_set_sys_y("Y %5.2lf" , units_to_mm(pos.y)); - status_set_user_x("x %5.2lf", units_to_mm(pos.x-user_origin.x)); - status_set_user_y("y %5.2lf", units_to_mm(pos.y-user_origin.y)); + set_with_units(status_set_sys_x, "X ", pos.x); + set_with_units(status_set_sys_y, "Y ", pos.x); + set_with_units(status_set_user_x, "x ", pos.x-user_origin.x); + set_with_units(status_set_user_y, "y ", pos.y-user_origin.y); } diff --git a/gui_status.c b/gui_status.c index a7a1f9f..9519629 100644 --- a/gui_status.c +++ b/gui_status.c @@ -41,6 +41,15 @@ struct edit_ops { void (*store)(const char *s, void *ctx); }; + +static enum curr_unit { + unit_mm, + unit_mil, + unit_auto, + unit_n +} curr_unit = unit_mm; + + static GtkWidget *open_edits = NULL; static GtkWidget *last_edit = NULL; @@ -55,7 +64,7 @@ static GtkWidget *status_x, *status_y; static GtkWidget *status_r, *status_angle; static GtkWidget *status_sys_x, *status_sys_y; static GtkWidget *status_user_x, *status_user_y; -static GtkWidget *status_zoom, *status_grid; +static GtkWidget *status_zoom, *status_grid, *status_unit; static GtkWidget *status_msg; @@ -93,6 +102,41 @@ SETTER(user_x) SETTER(user_y) SETTER(zoom) SETTER(grid) +SETTER(unit) + + +/* ----- set things with units --------------------------------------------- */ + + +void set_with_units(void (*set)(const char *fmt, ...), const char *prefix, + unit_type u) +{ + double n; + int mm; + + switch (curr_unit) { + case unit_mm: + n = units_to_mm(u); + mm = 1; + break; + case unit_mil: + n = units_to_mil(u); + mm = 0; + break; + case unit_auto: + n = units_to_best(u, &mm); + break; + default: + abort(); + } + if (mm) { + /* -NNN.NNN mm */ + set("%s%8.3f mm", prefix, n); + } else { + /* -NNNN.N mil */ + set("%s%7.1f mil", prefix, n); + } +} /* ----- complex status updates -------------------------------------------- */ @@ -104,8 +148,8 @@ void status_set_xy(struct coord coord) status_set_type_x("X ="); status_set_type_y("Y ="); - status_set_x("%5.2f mm", units_to_mm(coord.x)); - status_set_y("%5.2f mm", units_to_mm(coord.y)); + set_with_units(status_set_x, "", coord.x); + set_with_units(status_set_y, "", coord.y); } @@ -500,12 +544,10 @@ static gboolean activate(GtkWidget *widget, GdkEventMotion *event, return TRUE; for (edit = open_edits; edit; edit = gtk_object_get_data(GTK_OBJECT(edit), "edit-next")) -{ if (get_status(edit) == es_good) { entry_color(edit, COLOR_EDIT_ASIS); set_edit(edit); } -} inst_deselect(); change_world(); return TRUE; @@ -553,10 +595,38 @@ void status_begin_reporting(void) } +/* ----- unit selection ---------------------------------------------------- */ + + +static gboolean unit_button_press_event(GtkWidget *widget, + GdkEventButton *event, gpointer data) +{ + switch (event->button) { + case 1: + curr_unit = (curr_unit+1) % unit_n; + switch (curr_unit) { + case unit_mm: + status_set_unit("mm"); + break; + case unit_mil: + status_set_unit("mil"); + break; + case unit_auto: + status_set_unit("auto"); + break; + default: + abort(); + } + break; + } + return TRUE; +} + + /* ----- setup ------------------------------------------------------------- */ -static GtkWidget *add_label(GtkWidget *tab, int col, int row) +static GtkWidget *add_label_basic(GtkWidget *tab, int col, int row) { GtkWidget *label; @@ -565,7 +635,15 @@ static GtkWidget *add_label(GtkWidget *tab, int col, int row) col, col+1, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 1); /* 0 , 1 - padding */ + return label; +} + +static GtkWidget *add_label(GtkWidget *tab, int col, int row) +{ + GtkWidget *label; + + label = add_label_basic(tab, col, row); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_label_set_selectable(GTK_LABEL(label), TRUE); return label; @@ -632,10 +710,17 @@ void make_status_area(GtkWidget *vbox) status_r = add_label(tab, 4, 2); status_angle = add_label(tab, 5, 2); - /* zoom / grid */ + /* zoom / grid / unit */ status_zoom = add_label(tab, 6, 0); status_grid = add_label(tab, 6, 1); + status_unit = add_label_basic(tab, 6, 2); + + /* unit selection */ + + status_set_unit("mm"); + g_signal_connect(G_OBJECT(box_of_label(status_unit)), + "button_press_event", G_CALLBACK(unit_button_press_event), NULL); /* message bar */ diff --git a/gui_status.h b/gui_status.h index 0ee3786..27f8ab0 100644 --- a/gui_status.h +++ b/gui_status.h @@ -30,6 +30,9 @@ void edit_x(struct expr **expr); void edit_y(struct expr **expr); void edit_nothing(void); +void set_with_units(void (*set)(const char *fmt, ...), const char *prefix, + unit_type u); + void status_set_type_x(const char *fmt, ...); void status_set_type_y(const char *fmt, ...); void status_set_type_entry(const char *fmt, ...); @@ -44,6 +47,7 @@ void status_set_user_x(const char *fmt, ...); void status_set_user_y(const char *fmt, ...); void status_set_zoom(const char *fmt, ...); void status_set_grid(const char *fmt, ...); +void status_set_unit(const char *fmt, ...); void status_set_xy(struct coord coord); diff --git a/inst.c b/inst.c index c8e101e..9e22f52 100644 --- a/inst.c +++ b/inst.c @@ -389,10 +389,10 @@ static void rect_status(struct coord a, struct coord b, unit_type width) angle = theta(a, b); status_set_angle("a = %3.1f deg", angle); } - status_set_r("r = %5.2f mm", hypot(units_to_mm(d.x), units_to_mm(d.y))); + set_with_units(status_set_r, "r = ", hypot(d.x, d.y)); if (width != -1) { status_set_type_entry("width ="); - status_set_name("%5.2f mm", units_to_mm(width)); + set_with_units(status_set_name, "", width); } } @@ -769,9 +769,9 @@ static void arc_op_select(struct inst *self) status_set_angle("a = %3.1f deg", self->u.arc.a1 == self->u.arc.a2 ? 360 : self->u.arc.a2-self->u.arc.a1); - status_set_r("r = %5.2f mm", units_to_mm(self->u.arc.r)); + set_with_units(status_set_r, "r = ", self->u.arc.r); status_set_type_entry("width ="); - status_set_name("%5.2f mm", units_to_mm(self->u.arc.width)); + set_with_units(status_set_name, "", self->u.arc.width); obj_arc_edit(self->obj); } @@ -845,7 +845,7 @@ static void meas_op_select(struct inst *self) { rect_status(self->bbox.min, self->bbox.max, -1); status_set_type_entry("offset ="); - status_set_name("%5.2f mm", units_to_mm(self->u.meas.offset)); + set_with_units(status_set_name, "", self->u.meas.offset); obj_meas_edit(self->obj); }