diff --git a/gui.c b/gui.c index 4d3acad..0bd18c0 100644 --- a/gui.c +++ b/gui.c @@ -261,6 +261,16 @@ void change_world(void) } +void change_world_reselect(void) +{ + struct obj *selected_obj; + + selected_obj = selected_inst->obj; + change_world(); + inst_select_obj(selected_obj); +} + + static void make_screen(GtkWidget *window) { GtkWidget *vbox; @@ -309,6 +319,7 @@ int gui_main(void) gui_cleanup_style(); gui_cleanup_tools(); cleanup_tool_bar(); + cleanup_status_area(); return 0; } diff --git a/gui.h b/gui.h index a5d3663..c27dc6b 100644 --- a/gui.h +++ b/gui.h @@ -27,6 +27,9 @@ extern int show_bright; /* update everything after a model change */ void change_world(void); +/* like change_world, but select the object again */ +void change_world_reselect(void); + int gui_init(int *argc, char ***argv); int gui_main(void); diff --git a/gui_status.c b/gui_status.c index 839c3d1..90e17d6 100644 --- a/gui_status.c +++ b/gui_status.c @@ -23,6 +23,7 @@ #include "coord.h" #include "error.h" #include "unparse.h" +#include "obj.h" #include "gui_util.h" #include "gui_style.h" #include "gui_canvas.h" @@ -56,7 +57,7 @@ static GtkWidget *last_edit = NULL; static GtkWidget *status_name, *status_entry; static GtkWidget *status_type_x, *status_type_y, *status_type_entry; -static GtkWidget *status_entry_x, *status_entry_y; +static GtkWidget *status_box_x, *status_entry_y; static GtkWidget *status_x, *status_y; static GtkWidget *status_r, *status_angle; static GtkWidget *status_sys_x, *status_sys_y; @@ -64,6 +65,10 @@ static GtkWidget *status_user_x, *status_user_y; static GtkWidget *status_zoom, *status_grid, *status_unit; static GtkWidget *status_msg; +/* The x entry area serves multiple purposes */ + +static GtkWidget *status_entry_x; + static void set_label(GtkWidget *label, const char *fmt, va_list ap) { @@ -159,7 +164,72 @@ static void entry_color(GtkWidget *widget, const char *color) } -/* ----- helper functions -------------------------------------------------- */ +/* ----- pad type display and change --------------------------------------- */ + + +static enum pad_type *curr_pad_type; +static GtkWidget *pad_type; + + +static void show_pad_type(void) +{ + const char *s; + + switch (*curr_pad_type) { + case pt_normal: + s = "normal"; + break; + case pt_bare: + s = "bare"; + break; + case pt_paste: + s = "paste"; + break; + case pt_mask: + s = "mask"; + break; + default: + abort(); + } + gtk_label_set_text(GTK_LABEL(pad_type), s); +} + + +static gboolean pad_type_button_press_event(GtkWidget *widget, + GdkEventButton *event, gpointer data) +{ + switch (event->button) { + case 1: + *curr_pad_type = (*curr_pad_type+1) % pt_n; + show_pad_type(); + break; + } + /* + * We can't just redraw() here, because changing the pad type may also + * affect the visual stacking. So we change the world and hope we end + * up selecting the same pad afterwards. + */ + change_world_reselect(); + return TRUE; +} + + +void edit_pad_type(enum pad_type *type) +{ + vacate_widget(status_box_x); + curr_pad_type = type; + pad_type = label_in_box_new(NULL); + gtk_container_add(GTK_CONTAINER(status_box_x), box_of_label(pad_type)); + label_in_box_bg(pad_type, COLOR_SELECTOR); + g_signal_connect(G_OBJECT(box_of_label(pad_type)), + "button_press_event", G_CALLBACK(pad_type_button_press_event), + NULL); + show_pad_type(); + gtk_widget_show_all(status_box_x); +} + + +/* ----- edit helper functions --------------------------------------------- */ static void reset_edit(GtkWidget *widget) @@ -532,6 +602,9 @@ void edit_expr(struct expr **expr) void edit_x(struct expr **expr) { + vacate_widget(status_box_x); + gtk_container_add(GTK_CONTAINER(status_box_x), status_entry_x); + gtk_widget_show(status_box_x); edit_any_expr(status_entry_x, expr); } @@ -695,7 +768,7 @@ static gboolean activate(GtkWidget *widget, GdkEventMotion *event, void edit_nothing(void) { gtk_widget_hide(status_entry); - gtk_widget_hide(status_entry_x); + gtk_widget_hide(status_box_x); gtk_widget_hide(status_entry_y); open_edits = NULL; last_edit = NULL; @@ -772,6 +845,17 @@ static gboolean unit_button_press_event(GtkWidget *widget, /* ----- setup ------------------------------------------------------------- */ +static GtkWidget *add_vbox(GtkWidget *tab, int col, int row) +{ + GtkWidget *vbox; + + vbox = gtk_vbox_new(FALSE, 0); + gtk_table_attach_defaults(GTK_TABLE(tab), vbox, + col, col+1, row, row+1); + return vbox; +} + + static GtkWidget *add_label_basic(GtkWidget *tab, int col, int row) { GtkWidget *label; @@ -796,14 +880,12 @@ static GtkWidget *add_label(GtkWidget *tab, int col, int row) } -static GtkWidget *add_entry(GtkWidget *tab, int col, int row) +static GtkWidget *make_entry(void) { GtkWidget *entry; entry = gtk_entry_new(); gtk_entry_set_has_frame(GTK_ENTRY(entry), FALSE); - gtk_table_attach_defaults(GTK_TABLE(tab), entry, - col, col+1, row, row+1); g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(changed), entry); @@ -814,6 +896,17 @@ static GtkWidget *add_entry(GtkWidget *tab, int col, int row) } +static GtkWidget *add_entry(GtkWidget *tab, int col, int row) +{ + GtkWidget *entry; + + entry = make_entry(); + gtk_table_attach_defaults(GTK_TABLE(tab), entry, + col, col+1, row, row+1); + return entry; +} + + void make_status_area(GtkWidget *vbox) { GtkWidget *tab, *sep; @@ -830,10 +923,12 @@ void make_status_area(GtkWidget *vbox) /* x / y */ status_x = add_label(tab, 1, 0); - status_entry_x = add_entry(tab, 2, 0); + status_box_x = add_vbox(tab, 2, 0); status_y = add_label(tab, 1, 1); status_entry_y = add_entry(tab, 2, 1); + status_entry_x = gtk_widget_ref(make_entry()); + /* name and input */ status_name = add_label(tab, 1, 2); @@ -864,7 +959,7 @@ void make_status_area(GtkWidget *vbox) /* unit selection */ - label_in_box_bg(status_unit, COLOR_UNIT_SELECTOR); + label_in_box_bg(status_unit, COLOR_SELECTOR); show_curr_unit(); g_signal_connect(G_OBJECT(box_of_label(status_unit)), "button_press_event", G_CALLBACK(unit_button_press_event), NULL); @@ -877,3 +972,9 @@ void make_status_area(GtkWidget *vbox) context_id = gtk_statusbar_get_context_id(GTK_STATUSBAR(status_msg), "messages"); } + + +void cleanup_status_area(void) +{ + gtk_widget_unref(status_entry_x); +} diff --git a/gui_status.h b/gui_status.h index 195f162..2d86496 100644 --- a/gui_status.h +++ b/gui_status.h @@ -31,6 +31,8 @@ enum curr_unit { extern enum curr_unit curr_unit; +void edit_pad_type(enum pad_type *type); + void edit_unique(const char **s, int (*validate)(const char *s, void *ctx), void *ctx); void edit_unique_null(const char **s, int (*validate)(const char *s, void *ctx), @@ -86,6 +88,7 @@ void status_set_xy(struct coord coord); void status_begin_reporting(void); -void make_status_area(GtkWidget *vbox) ; +void make_status_area(GtkWidget *vbox); +void cleanup_status_area(void); #endif /* !GUI_STATUS_H */ diff --git a/gui_style.h b/gui_style.h index 9f583df..40ca9ff 100644 --- a/gui_style.h +++ b/gui_style.h @@ -96,7 +96,7 @@ #define COLOR_ITEM_SELECTED COLOR_FRAME_SELECTED #define COLOR_ITEM_ERROR "red" -#define COLOR_UNIT_SELECTOR "white" +#define COLOR_SELECTOR "white" /* ----- canvas drawing styles --------------------------------------------- */ diff --git a/gui_util.c b/gui_util.c index a7cdac6..2466f93 100644 --- a/gui_util.c +++ b/gui_util.c @@ -190,9 +190,15 @@ static void remove_child(GtkWidget *widget, gpointer data) } -void set_image(GtkWidget *widget, GtkWidget *image) +void vacate_widget(GtkWidget *widget) { gtk_container_foreach(GTK_CONTAINER(widget), remove_child, widget); +} + + +void set_image(GtkWidget *widget, GtkWidget *image) +{ + vacate_widget(widget); gtk_container_add(GTK_CONTAINER(widget), image); gtk_widget_show_all(widget); } diff --git a/gui_util.h b/gui_util.h index 6b19e73..3ae73d4 100644 --- a/gui_util.h +++ b/gui_util.h @@ -57,6 +57,8 @@ 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); +void vacate_widget(GtkWidget *widget); + GtkWidget *make_image(GdkDrawable *drawable, char **xpm); void set_image(GtkWidget *widget, GtkWidget *image); GtkWidget *tool_button(GtkWidget *bar, GdkDrawable *drawable, char **xpm, diff --git a/inst.c b/inst.c index bee2605..d371105 100644 --- a/inst.c +++ b/inst.c @@ -742,6 +742,7 @@ static int validate_pad_name(const char *s, void *ctx) static void obj_pad_edit(struct obj *obj) { + edit_pad_type(&obj->u.pad.type); edit_name(&obj->u.pad.name, validate_pad_name, NULL); } diff --git a/obj.h b/obj.h index 6ad11c9..4bfddbf 100644 --- a/obj.h +++ b/obj.h @@ -144,6 +144,7 @@ enum pad_type { pt_bare, /* only copper (and finish) */ pt_paste, /* only solder paste */ pt_mask, /* only solder mask */ + pt_n }; struct frame_ref {