r5409 - trunk/eda/fped
werner at docs.openmoko.org
werner at docs.openmoko.org
Sat Aug 8 21:35:16 CEST 2009
Author: werner
Date: 2009-08-08 21:35:16 +0200 (Sat, 08 Aug 2009)
New Revision: 5409
Added:
trunk/eda/fped/gui_frame.c
trunk/eda/fped/gui_frame.h
Modified:
trunk/eda/fped/Makefile
trunk/eda/fped/gui.c
Log:
- moved handling of frame area from gui.c to gui_frame.c and cleaned up their
includes
Modified: trunk/eda/fped/Makefile
===================================================================
--- trunk/eda/fped/Makefile 2009-08-08 19:01:45 UTC (rev 5408)
+++ trunk/eda/fped/Makefile 2009-08-08 19:35:16 UTC (rev 5409)
@@ -14,7 +14,7 @@
unparse.o dump.o meas.o \
cpp.o lex.yy.o y.tab.o \
gui.o gui_util.o gui_style.o gui_inst.o gui_status.o gui_canvas.o \
- gui_tools.o gui_over.o gui_meas.o
+ gui_tools.o gui_over.o gui_meas.o gui_frame.o
XPMS = point.xpm delete.xpm vec.xpm frame.xpm frame_locked.xpm frame_ready.xpm \
line.xpm rect.xpm pad.xpm circ.xpm meas.xpm meas_x.xpm meas_y.xpm
Modified: trunk/eda/fped/gui.c
===================================================================
--- trunk/eda/fped/gui.c 2009-08-08 19:01:45 UTC (rev 5408)
+++ trunk/eda/fped/gui.c 2009-08-08 19:35:16 UTC (rev 5409)
@@ -11,24 +11,17 @@
*/
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-#include "util.h"
-#include "error.h"
#include "inst.h"
#include "obj.h"
-#include "delete.h"
-#include "unparse.h"
#include "dump.h"
#include "gui_util.h"
#include "gui_style.h"
#include "gui_status.h"
#include "gui_canvas.h"
#include "gui_tools.h"
+#include "gui_frame.h"
#include "gui.h"
@@ -37,410 +30,6 @@
static GtkWidget *frames_box;
-/* ----- popup dispatcher -------------------------------------------------- */
-
-
-static void *popup_data;
-
-
-static void pop_up(GtkWidget *menu, GdkEventButton *event, void *data)
-{
- popup_data = data;
- gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
- event->button, event->time);
-}
-
-
-/* ----- popup: frame ------------------------------------------------------ */
-
-
-static GtkItemFactory *factory_frame;
-static GtkWidget *popup_frame_widget;
-
-
-static void select_frame(struct frame *frame);
-
-
-static void popup_add_frame(void)
-{
- struct frame *parent = popup_data;
- struct frame *new;
-
- new = zalloc_type(struct frame);
- new->name = unique("_");
- new->next = parent;
- new->prev = parent->prev;
- if (parent->prev)
- parent->prev->next = new;
- else
- frames = new;
- parent->prev = new;
- change_world();
-}
-
-
-static void popup_del_frame(void)
-{
- struct frame *frame = popup_data;
-
- assert(frame != root_frame);
- delete_frame(frame);
- if (active_frame == frame)
- select_frame(root_frame);
- change_world();
-}
-
-
-/* @@@ merge with fpd.y */
-
-static void popup_add_table(void)
-{
- struct frame *frame = popup_data;
- struct table *table, **walk;
-
- table = zalloc_type(struct table);
- table->vars = zalloc_type(struct var);
- table->vars->name = unique("_");
- table->vars->frame = frame;
- table->vars->table = table;
- table->rows = zalloc_type(struct row);
- table->rows->table = table;
- table->rows->values = zalloc_type(struct value);
- table->rows->values->expr = parse_expr("0");
- table->rows->values->row = table->rows;
- table->active_row = table->rows;
- for (walk = &frame->tables; *walk; walk = &(*walk)->next);
- *walk = table;
- change_world();
-}
-
-
-static void popup_add_loop(void)
-{
- struct frame *frame = popup_data;
- struct loop *loop, **walk;
-
- loop = zalloc_type(struct loop);
- loop->var.name = unique("_");
- loop->var.frame = frame;
- loop->from.expr = parse_expr("0");
- loop->to.expr = parse_expr("0");
- loop->next = NULL;
- for (walk = &frame->loops; *walk; walk = &(*walk)->next);
- *walk = loop;
- change_world();
-}
-
-
-static GtkItemFactoryEntry popup_frame_entries[] = {
- { "/Add frame", NULL, popup_add_frame, 0, "<Item>" },
- { "/sep0", NULL, NULL, 0, "<Separator>" },
- { "/Add variable", NULL, popup_add_table, 0, "<Item>" },
- { "/Add loop", NULL, popup_add_loop, 0, "<Item>" },
- { "/sep1", NULL, NULL, 0, "<Separator>" },
- { "/Delete frame", NULL, popup_del_frame, 0, "<Item>" },
- { "/sep2", NULL, NULL, 0, "<Separator>" },
- { "/Close", NULL, NULL, 0, "<Item>" },
- { NULL }
-};
-
-
-static void pop_up_frame(struct frame *frame, GdkEventButton *event)
-{
- gtk_widget_set_sensitive(
- gtk_item_factory_get_item(factory_frame, "/Delete frame"),
- frame != root_frame);
- pop_up(popup_frame_widget, event, frame);
-}
-
-
-/* ----- popup: single variable -------------------------------------------- */
-
-
-static GtkItemFactory *factory_single_var;
-static GtkWidget *popup_single_var_widget;
-
-
-
-static void add_row_here(struct table *table, struct row **anchor)
-{
- struct row *row;
- const struct value *walk;
- struct value *value;
-
- row = zalloc_type(struct row);
- row->table = table;
- /* @@@ future: adjust type */
- for (walk = table->rows->values; walk; walk = walk->next) {
- value = zalloc_type(struct value);
- value->expr = parse_expr("0");
- value->row = row;
- value->next = row->values;
- row->values = value;
- }
- row->next = *anchor;
- *anchor = row;
- change_world();
-}
-
-
-static void add_column_here(struct table *table, struct var **anchor)
-{
- const struct var *walk;
- struct var *var;
- struct row *row;
- struct value *value;
- struct value **value_anchor;
- int n = 0, i;
-
- for (walk = table->vars; walk != *anchor; walk = walk->next)
- n++;
- var = zalloc_type(struct var);
- var->name = unique("_");
- var->frame = table->vars->frame;
- var->table = table;
- var->next = *anchor;
- *anchor = var;
- for (row = table->rows; row; row = row->next) {
- value_anchor = &row->values;
- for (i = 0; i != n; i++)
- value_anchor = &(*value_anchor)->next;
- value = zalloc_type(struct value);
- value->expr = parse_expr("0");
- value->row = row;
- value->next = *value_anchor;
- *value_anchor = value;
- }
- change_world();
-}
-
-
-static void popup_add_row(void)
-{
- struct var *var = popup_data;
-
- add_row_here(var->table, &var->table->rows);
-}
-
-
-static void popup_add_column(void)
-{
- struct var *var = popup_data;
-
- add_column_here(var->table, &var->next);
-}
-
-
-static void popup_del_table(void)
-{
- struct var *var = popup_data;
-
- delete_table(var->table);
- change_world();
-}
-
-
-static GtkItemFactoryEntry popup_single_var_entries[] = {
- { "/Add row", NULL, popup_add_row, 0, "<Item>" },
- { "/Add column", NULL, popup_add_column, 0, "<Item>" },
- { "/sep1", NULL, NULL, 0, "<Separator>" },
- { "/Delete variable", NULL, popup_del_table, 0, "<Item>" },
- { "/sep2", NULL, NULL, 0, "<Separator>" },
- { "/Close", NULL, NULL, 0, "<Item>" },
- { NULL }
-};
-
-
-static void pop_up_single_var(struct var *var, GdkEventButton *event)
-{
- pop_up(popup_single_var_widget, event, var);
-}
-
-
-/* ----- popup: table variable --------------------------------------------- */
-
-
-static GtkItemFactory *factory_table_var;
-static GtkWidget *popup_table_var_widget;
-
-
-static void popup_del_column(void)
-{
- struct var *var = popup_data;
- const struct var *walk;
- int n = 0;
-
- for (walk = var->table->vars; walk != var; walk = walk->next)
- n++;
- delete_column(var->table, n);
- change_world();
-}
-
-
-static GtkItemFactoryEntry popup_table_var_entries[] = {
- { "/Add row", NULL, popup_add_row, 0, "<Item>" },
- { "/Add column", NULL, popup_add_column, 0, "<Item>" },
- { "/sep1", NULL, NULL, 0, "<Separator>" },
- { "/Delete table", NULL, popup_del_table, 0, "<Item>" },
- { "/Delete column", NULL, popup_del_column, 0, "<Item>" },
- { "/sep2", NULL, NULL, 0, "<Separator>" },
- { "/Close", NULL, NULL, 0, "<Item>" },
- { NULL }
-};
-
-
-static void pop_up_table_var(struct var *var, GdkEventButton *event)
-{
- gtk_widget_set_sensitive(
- gtk_item_factory_get_item(factory_table_var, "/Delete column"),
- var->table->vars->next != NULL);
- pop_up(popup_table_var_widget, event, var);
-}
-
-
-/* ----- popup: table value ------------------------------------------------ */
-
-
-static GtkItemFactory *factory_table_value;
-static GtkWidget *popup_table_value_widget;
-
-
-static void popup_add_column_by_value(void)
-{
- struct value *value = popup_data;
- const struct value *walk;
- struct table *table = value->row->table;
- struct var *var = table->vars;
-
- for (walk = value->row->values; walk != value; walk = walk->next)
- var = var->next;
- add_column_here(table, &var->next);
-}
-
-
-static void popup_add_row_by_value(void)
-{
- struct value *value = popup_data;
-
- add_row_here(value->row->table, &value->row->next);
-}
-
-
-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();
-}
-
-
-static void popup_del_column_by_value(void)
-{
- struct value *value = popup_data;
- const struct value *walk;
- int n = 0;
-
- for (walk = value->row->values; walk != value; walk = walk->next)
- n++;
- delete_column(value->row->table, n);
- change_world();
-}
-
-
-static GtkItemFactoryEntry popup_table_value_entries[] = {
- { "/Add row", NULL, popup_add_row_by_value, 0, "<Item>" },
- { "/Add column", NULL, popup_add_column_by_value,
- 0, "<Item>" },
- { "/sep1", NULL, NULL, 0, "<Separator>" },
- { "/Delete row", NULL, popup_del_row, 0, "<Item>" },
- { "/Delete column", NULL, popup_del_column_by_value,
- 0, "<Item>" },
- { "/sep2", NULL, NULL, 0, "<Separator>" },
- { "/Close", NULL, NULL, 0, "<Item>" },
- { NULL }
-};
-
-
-static void pop_up_table_value(struct value *value, GdkEventButton *event)
-{
- gtk_widget_set_sensitive(
- gtk_item_factory_get_item(factory_table_value, "/Delete row"),
- value->row->table->rows->next != NULL);
- gtk_widget_set_sensitive(
- gtk_item_factory_get_item(factory_table_value, "/Delete column"),
- value->row->table->vars->next != NULL);
- pop_up(popup_table_value_widget, event, value);
-}
-
-
-/* ----- popup: loop ------------------------------------------------------- */
-
-
-static GtkItemFactory *factory_loop_var;
-static GtkWidget *popup_loop_var_widget;
-
-
-static void popup_del_loop(void)
-{
- struct loop *loop = popup_data;
-
- delete_loop(loop);
- change_world();
-}
-
-
-static GtkItemFactoryEntry popup_loop_var_entries[] = {
- { "/Delete loop", NULL, popup_del_loop, 0, "<Item>" },
- { "/sep2", NULL, NULL, 0, "<Separator>" },
- { "/Close", NULL, NULL, 0, "<Item>" },
- { NULL }
-};
-
-
-static void pop_up_loop_var(struct loop *loop, GdkEventButton *event)
-{
- pop_up(popup_loop_var_widget, event, loop);
-}
-
-
-/* ----- make popups ------------------------------------------------------- */
-
-
-static GtkWidget *make_popup(const char *name, GtkItemFactory **factory,
- GtkItemFactoryEntry *entries)
-{
- GtkWidget *popup;
- int n;
-
- n = 0;
- for (n = 0; entries[n].path; n++);
-
- *factory = gtk_item_factory_new(GTK_TYPE_MENU, name, NULL);
- gtk_item_factory_create_items(*factory, n, entries, NULL);
- popup = gtk_item_factory_get_widget(*factory, name);
- return popup;
-}
-
-
-static void make_popups(void)
-{
- popup_frame_widget = make_popup("<FpedFramePopUp>",
- &factory_frame, popup_frame_entries);
- popup_single_var_widget = make_popup("<FpedSingleVarPopUp>",
- &factory_single_var, popup_single_var_entries);
- popup_table_var_widget = make_popup("<FpedTableVarPopUp>",
- &factory_table_var, popup_table_var_entries);
- popup_table_value_widget = make_popup("<FpedTableValusPopUp>",
- &factory_table_value, popup_table_value_entries);
- popup_loop_var_widget = make_popup("<FpedLoopVarPopUp>",
- &factory_loop_var, popup_loop_var_entries);
-}
-
-
/* ----- menu bar ---------------------------------------------------------- */
@@ -476,678 +65,6 @@
}
-/* ----- variable list ----------------------------------------------------- */
-
-
-static void add_sep(GtkWidget *box, int size)
-{
- GtkWidget *sep;
- GdkColor black = { 0, 0, 0, 0 };
-
- sep = gtk_drawing_area_new();
- gtk_box_pack_start(GTK_BOX(box), sep, FALSE, TRUE, size);
- gtk_widget_modify_bg(sep, GTK_STATE_NORMAL, &black);
-}
-
-
-/* ----- variable name editor ---------------------------------------------- */
-
-
-static int find_var_in_frame(const struct frame *frame, const char *name)
-{
- const struct table *table;
- const struct loop *loop;
- const struct var *var;
-
- for (table = frame->tables; table; table = table->next)
- for (var = table->vars; var; var = var->next)
- if (!strcmp(var->name, name))
- return 1;
- for (loop = frame->loops; loop; loop = loop->next)
- if (!strcmp(loop->var.name, name))
- return 1;
- return 0;
-}
-
-
-static int validate_var_name(const char *s, void *ctx)
-{
- struct var *var = ctx;
-
- if (!is_id(s))
- return 0;
- return !find_var_in_frame(var->frame, s);
-}
-
-
-static void unselect_var(void *data)
-{
- struct var *var = data;
-
- label_in_box_bg(var->widget, COLOR_VAR_PASSIVE);
-}
-
-
-static void edit_var(struct var *var)
-{
- inst_select_outside(var, unselect_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);
-}
-
-
-/* ----- value editor ------------------------------------------------------ */
-
-
-static void unselect_value(void *data)
-{
- struct value *value = data;
-
- label_in_box_bg(value->widget,
- value->row && value->row->table->active_row == value->row ?
- COLOR_CHOICE_SELECTED : COLOR_EXPR_PASSIVE);
-}
-
-
-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);
-}
-
-
-/* ----- activator --------------------------------------------------------- */
-
-
-static GtkWidget *add_activator(GtkWidget *hbox, int active,
- gboolean (*cb)(GtkWidget *widget, GdkEventButton *event, gpointer data),
- gpointer user, const char *fmt, ...)
-{
- GtkWidget *label;
- va_list ap;
- char buf[100];
-
- va_start(ap, fmt);
- vsprintf(buf, fmt, ap);
- va_end(ap);
- label = label_in_box_new(buf);
- gtk_misc_set_padding(GTK_MISC(label), 2, 2);
- gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
- label_in_box_bg(label,
- active ? COLOR_CHOICE_SELECTED : COLOR_CHOICE_UNSELECTED);
- gtk_box_pack_start(GTK_BOX(hbox), box_of_label(label),
- FALSE, FALSE, 2);
- g_signal_connect(G_OBJECT(box_of_label(label)),
- "button_press_event", G_CALLBACK(cb), user);
- return label;
-}
-
-
-/* ----- assignments ------------------------------------------------------- */
-
-
-static gboolean assignment_var_select_event(GtkWidget *widget,
- GdkEventButton *event, gpointer data)
-{
- struct var *var = data;
-
- switch (event->button) {
- case 1:
- edit_var(var);
- break;
- case 3:
- pop_up_single_var(var, event);
- break;
- }
- return TRUE;
-}
-
-
-static gboolean assignment_value_select_event(GtkWidget *widget,
- GdkEventButton *event, gpointer data)
-{
- struct value *value = data;
-
- switch (event->button) {
- case 1:
- edit_value(value);
- break;
- }
- return TRUE;
-}
-
-
-static void build_assignment(GtkWidget *vbox, struct frame *frame,
- struct table *table)
-{
- GtkWidget *hbox, *field;
- char *expr;
-
- if (!table->vars || table->vars->next)
- return;
- if (!table->rows || table->rows->next)
- return;
-
- hbox = gtk_hbox_new(FALSE, 0);
- gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
-
- field = label_in_box_new(table->vars->name);
- gtk_box_pack_start(GTK_BOX(hbox), box_of_label(field), FALSE, FALSE, 0);
- label_in_box_bg(field, COLOR_VAR_PASSIVE);
- table->vars->widget = field;
- g_signal_connect(G_OBJECT(box_of_label(field)),
- "button_press_event",
- G_CALLBACK(assignment_var_select_event), table->vars);
-
- gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(" = "),
- FALSE, FALSE, 0);
-
- expr = unparse(table->rows->values->expr);
- field = label_in_box_new(expr);
- free(expr);
- gtk_box_pack_start(GTK_BOX(hbox), box_of_label(field), FALSE, FALSE, 0);
- label_in_box_bg(field, COLOR_EXPR_PASSIVE);
- table->rows->values->widget = field;
- g_signal_connect(G_OBJECT(box_of_label(field)),
- "button_press_event",
- G_CALLBACK(assignment_value_select_event), table->rows->values);
-}
-
-
-/* ----- tables ------------------------------------------------------------ */
-
-
-static void select_row(struct row *row)
-{
- struct table *table = row->table;
- struct value *value;
-
- for (value = table->active_row->values; value; value = value->next)
- label_in_box_bg(value->widget, COLOR_ROW_UNSELECTED);
- table->active_row = row;
- for (value = table->active_row->values; value; value = value->next)
- label_in_box_bg(value->widget, COLOR_ROW_SELECTED);
-}
-
-
-static gboolean table_var_select_event(GtkWidget *widget,
- GdkEventButton *event, gpointer data)
-{
- struct var *var = data;
-
- switch (event->button) {
- case 1:
- edit_var(var);
- break;
- case 3:
- pop_up_table_var(var, event);
- break;
- }
- return TRUE;
-}
-
-
-static gboolean table_value_select_event(GtkWidget *widget,
- GdkEventButton *event, gpointer data)
-{
- struct value *value = data;
-
- switch (event->button) {
- case 1:
- if (!value->row || value->row->table->active_row == value->row)
- edit_value(value);
- else {
- select_row(value->row);
- change_world();
- }
- break;
- case 3:
- pop_up_table_value(value, event);
- break;
- }
- return TRUE;
-}
-
-
-static void build_table(GtkWidget *vbox, struct frame *frame,
- struct table *table)
-{
- GtkWidget *tab, *field;
- GtkWidget *evbox, *align;
- struct var *var;
- struct row *row;
- struct value *value;
- int n_vars = 0, n_rows = 0;
- char *expr;
- GdkColor col;
-
- for (var = table->vars; var; var = var->next)
- n_vars++;
- for (row = table->rows; row; row = row->next)
- n_rows++;
-
- if (n_vars == 1 && n_rows == 1)
- return;
-
- evbox = gtk_event_box_new();
- align = gtk_alignment_new(0, 0, 0, 0);
- gtk_container_add(GTK_CONTAINER(align), evbox);
- gtk_box_pack_start(GTK_BOX(vbox), align, FALSE, FALSE, 0);
-
- tab = gtk_table_new(n_rows+1, n_vars, FALSE);
- gtk_container_add(GTK_CONTAINER(evbox), tab);
- col = get_color(COLOR_VAR_TABLE_SEP);
- gtk_widget_modify_bg(GTK_WIDGET(evbox),
- GTK_STATE_NORMAL, &col);
-
- gtk_table_set_row_spacings(GTK_TABLE(tab), 1);
- gtk_table_set_col_spacings(GTK_TABLE(tab), 1);
-
- n_vars = 0;
- for (var = table->vars; var; var = var->next) {
- field = label_in_box_new(var->name);
- gtk_table_attach_defaults(GTK_TABLE(tab), box_of_label(field),
- n_vars, n_vars+1, 0, 1);
- label_in_box_bg(field, COLOR_VAR_PASSIVE);
- g_signal_connect(G_OBJECT(box_of_label(field)),
- "button_press_event",
- G_CALLBACK(table_var_select_event), var);
- var->widget = field;
- n_vars++;
- }
- n_rows = 0;
- for (row = table->rows; row; row = row->next) {
- n_vars = 0;
- for (value = row->values; value; value = value->next) {
- expr = unparse(value->expr);
- field = label_in_box_new(expr);
- free(expr);
- gtk_table_attach_defaults(GTK_TABLE(tab),
- box_of_label(field),
- n_vars, n_vars+1,
- n_rows+1, n_rows+2);
- label_in_box_bg(field, table->active_row == row ?
- COLOR_ROW_SELECTED : COLOR_ROW_UNSELECTED);
- g_signal_connect(G_OBJECT(box_of_label(field)),
- "button_press_event",
- G_CALLBACK(table_value_select_event), value);
- value->widget = field;
- n_vars++;
- }
- n_rows++;
- }
-}
-
-
-/* ----- loops ------------------------------------------------------------- */
-
-
-static gboolean loop_var_select_event(GtkWidget *widget,
- GdkEventButton *event, gpointer data)
-{
- struct loop *loop = data;
-
- switch (event->button) {
- case 1:
- edit_var(&loop->var);
- break;
- case 3:
- pop_up_loop_var(loop, event);
- break;
- }
- return TRUE;
-}
-
-
-static gboolean loop_from_select_event(GtkWidget *widget,
- GdkEventButton *event, gpointer data)
-{
- struct loop *loop = data;
-
- switch (event->button) {
- case 1:
- edit_value(&loop->from);
- break;
- }
- return TRUE;
-}
-
-
-static gboolean loop_to_select_event(GtkWidget *widget,
- GdkEventButton *event, gpointer data)
-{
- struct loop *loop = data;
-
- switch (event->button) {
- case 1:
- edit_value(&loop->to);
- break;
- }
- return TRUE;
-}
-
-
-static gboolean loop_select_event(GtkWidget *widget, GdkEventButton *event,
- gpointer data)
-{
- struct loop *loop = data;
-
- switch (event->button) {
- case 1:
- loop->active =
- (long) gtk_object_get_data(GTK_OBJECT(widget), "value");
- change_world();
- break;
- }
- return TRUE;
-}
-
-
-static void build_loop(GtkWidget *vbox, struct frame *frame,
- struct loop *loop)
-{
- GtkWidget *hbox, *field, *label;
- char *expr;
- int i;
-
- hbox = gtk_hbox_new(FALSE, 0);
- gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
-
- 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);
- g_signal_connect(G_OBJECT(box_of_label(field)),
- "button_press_event",
- G_CALLBACK(loop_var_select_event), loop);
- loop->var.widget = field;
-
- gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(" = "),
- FALSE, FALSE, 0);
-
- expr = unparse(loop->from.expr);
- field = label_in_box_new(expr);
- free(expr);
- gtk_box_pack_start(GTK_BOX(hbox), box_of_label(field), FALSE, FALSE, 0);
- label_in_box_bg(field, COLOR_EXPR_PASSIVE);
- g_signal_connect(G_OBJECT(box_of_label(field)),
- "button_press_event",
- G_CALLBACK(loop_from_select_event), loop);
- loop->from.widget = field;
-
- gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(" ... "),
- FALSE, FALSE, 0);
-
- expr = unparse(loop->to.expr);
- field = label_in_box_new(expr);
- free(expr);
- gtk_box_pack_start(GTK_BOX(hbox), box_of_label(field), FALSE, FALSE, 0);
- label_in_box_bg(field, COLOR_EXPR_PASSIVE);
- g_signal_connect(G_OBJECT(box_of_label(field)),
- "button_press_event",
- G_CALLBACK(loop_to_select_event), loop);
- loop->to.widget = field;
-
- gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(" ("),
- FALSE, FALSE, 0);
-
- for (i = 0; i != loop->iterations; i++) {
- label = add_activator(hbox, loop->active == i,
- loop_select_event, loop, "%d", i);
- gtk_object_set_data(GTK_OBJECT(box_of_label(label)), "value",
- (gpointer) (long) i);
- }
-
- gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(")"),
- FALSE, FALSE, 0);
-}
-
-
-/* ----- the list of variables, tables, and loops -------------------------- */
-
-
-static GtkWidget *build_vars(struct frame *frame)
-{
- GtkWidget *vbox;
- struct table *table;
- struct loop *loop;
-
- vbox= gtk_vbox_new(FALSE, 0);
- for (table = frame->tables; table; table = table->next) {
- add_sep(vbox, 3);
- build_assignment(vbox, frame, table);
- build_table(vbox, frame, table);
- }
- for (loop = frame->loops; loop; loop = loop->next) {
- add_sep(vbox, 3);
- build_loop(vbox, frame, loop);
- }
- return vbox;
-}
-
-
-/* ----- part name --------------------------------------------------------- */
-
-
-static int validate_part_name(const char *s, void *ctx)
-{
- if (!*s)
- return 0;
- while (*s)
- if (!is_id_char(*s++, 0))
- return 0;
- return 1;
-}
-
-static void unselect_part_name(void *data)
-{
- GtkWidget *widget = data;
-
- label_in_box_bg(widget, COLOR_PART_NAME);
-}
-
-
-static gboolean part_name_edit_event(GtkWidget *widget, GdkEventButton *event,
- gpointer data)
-{
- switch (event->button) {
- case 1:
- inst_select_outside(widget, unselect_part_name);
- 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);
- break;
- }
- return TRUE;
-}
-
-
-static GtkWidget *build_part_name(void)
-{
- GtkWidget *label;
-
- label = label_in_box_new(part_name);
- gtk_misc_set_padding(GTK_MISC(label), 2, 2);
- gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
-
- label_in_box_bg(label, COLOR_PART_NAME);
-
- g_signal_connect(G_OBJECT(box_of_label(label)),
- "button_press_event", G_CALLBACK(part_name_edit_event), NULL);
-
- return box_of_label(label);
-}
-
-
-/* ----- frame labels ------------------------------------------------------ */
-
-
-static int validate_frame_name(const char *s, void *ctx)
-{
- struct frame *f;
-
- if (!is_id(s))
- return 0;
- for (f = frames; f; f = f->next)
- if (f->name && !strcmp(f->name, s))
- return 0;
- return 1;
-}
-
-
-static void unselect_frame(void *data)
-{
- struct frame *frame= data;
-
- /*
- * "unselect" means in this context that the selection has moved
- * elsewhere. However, this does not necessarily change the frame.
- * (And, in fact, since we rebuild the frame list anyway, the color
- * change here doesn't matter if selecting a different frame.)
- * So we revert from "editing" to "selected".
- */
- label_in_box_bg(frame->label, COLOR_FRAME_SELECTED);
-}
-
-
-static void edit_frame(struct frame *frame)
-{
- inst_select_outside(frame, unselect_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);
-}
-
-
-static void select_frame(struct frame *frame)
-{
- if (active_frame)
- label_in_box_bg(active_frame->label, COLOR_FRAME_UNSELECTED);
- active_frame = frame;
- tool_frame_update();
- change_world();
-}
-
-
-static gboolean frame_select_event(GtkWidget *widget, GdkEventButton *event,
- gpointer data)
-{
- struct frame *frame = data;
-
- switch (event->button) {
- case 1:
- if (active_frame != frame)
- select_frame(frame);
- else {
- if (active_frame->name)
- edit_frame(frame);
- }
- break;
- case 3:
- pop_up_frame(frame, event);
- break;
- }
- return TRUE;
-}
-
-
-static GtkWidget *build_frame_label(struct frame *frame)
-{
- GtkWidget *label;
-
- label = label_in_box_new(frame->name ? frame->name : "(root)");
- gtk_misc_set_padding(GTK_MISC(label), 2, 2);
- gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
-
- label_in_box_bg(label, active_frame == frame ?
- COLOR_FRAME_SELECTED : COLOR_FRAME_UNSELECTED);
-
- g_signal_connect(G_OBJECT(box_of_label(label)),
- "button_press_event", G_CALLBACK(frame_select_event), frame);
- frame->label = label;
-
- return box_of_label(label);
-}
-
-
-/* ----- frame references -------------------------------------------------- */
-
-
-static gboolean frame_ref_select_event(GtkWidget *widget, GdkEventButton *event,
- gpointer data)
-{
- struct obj *obj = data;
-
- switch (event->button) {
- case 1:
- obj->u.frame.ref->active_ref = data;
- change_world();
- break;
- }
- return TRUE;
-}
-
-
-static GtkWidget *build_frame_refs(const struct frame *frame)
-{
- GtkWidget *hbox;
- struct obj *obj;
-
- hbox = gtk_hbox_new(FALSE, 0);
- for (obj = frame->objs; obj; obj = obj->next)
- if (obj->type == ot_frame && obj->u.frame.ref == active_frame)
- add_activator(hbox,
- obj == obj->u.frame.ref->active_ref,
- frame_ref_select_event, obj,
- "%d", obj->u.frame.lineno);
- return hbox;
-}
-
-
-/* ----- frames ------------------------------------------------------------ */
-
-
-static void build_frames(GtkWidget *vbox)
-{
- struct frame *frame;
- GtkWidget *tab, *label, *refs, *vars;
- 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);
- 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);
-
- label = build_part_name();
- gtk_table_attach_defaults(GTK_TABLE(tab), label, 0, 1, 0, 1);
-
- n = 0;
- for (frame = root_frame; frame; frame = frame->prev) {
- label = build_frame_label(frame);
- gtk_table_attach_defaults(GTK_TABLE(tab), label,
- 0, 1, n*2+1, n*2+2);
-
- refs = build_frame_refs(frame);
- gtk_table_attach_defaults(GTK_TABLE(tab), refs,
- 1, 2, n*2+1, n*2+2);
-
- vars = build_vars(frame);
- gtk_table_attach_defaults(GTK_TABLE(tab), vars,
- 1, 2, n*2+2, n*2+3);
- n++;
- }
- gtk_widget_show_all(tab);
-}
-
-
/* ----- central screen area ----------------------------------------------- */
Added: trunk/eda/fped/gui_frame.c
===================================================================
--- trunk/eda/fped/gui_frame.c (rev 0)
+++ trunk/eda/fped/gui_frame.c 2009-08-08 19:35:16 UTC (rev 5409)
@@ -0,0 +1,1101 @@
+/*
+ * gui_frame.c - GUI, frame window
+ *
+ * Written 2009 by Werner Almesberger
+ * Copyright 2009 by Werner Almesberger
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+
+#include <string.h>
+#include <gtk/gtk.h>
+
+#include "util.h"
+#include "error.h"
+#include "inst.h"
+#include "obj.h"
+#include "delete.h"
+#include "unparse.h"
+#include "gui_util.h"
+#include "gui_style.h"
+#include "gui_status.h"
+#include "gui_tools.h"
+#include "gui.h"
+#include "gui_frame.h"
+
+
+/* ----- popup dispatcher -------------------------------------------------- */
+
+
+static void *popup_data;
+
+
+static void pop_up(GtkWidget *menu, GdkEventButton *event, void *data)
+{
+ popup_data = data;
+ gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
+ event->button, event->time);
+}
+
+
+/* ----- popup: frame ------------------------------------------------------ */
+
+
+static GtkItemFactory *factory_frame;
+static GtkWidget *popup_frame_widget;
+
+
+static void popup_add_frame(void)
+{
+ struct frame *parent = popup_data;
+ struct frame *new;
+
+ new = zalloc_type(struct frame);
+ new->name = unique("_");
+ new->next = parent;
+ new->prev = parent->prev;
+ if (parent->prev)
+ parent->prev->next = new;
+ else
+ frames = new;
+ parent->prev = new;
+ change_world();
+}
+
+
+static void popup_del_frame(void)
+{
+ struct frame *frame = popup_data;
+
+ assert(frame != root_frame);
+ delete_frame(frame);
+ if (active_frame == frame)
+ select_frame(root_frame);
+ change_world();
+}
+
+
+/* @@@ merge with fpd.y */
+
+static void popup_add_table(void)
+{
+ struct frame *frame = popup_data;
+ struct table *table, **walk;
+
+ table = zalloc_type(struct table);
+ table->vars = zalloc_type(struct var);
+ table->vars->name = unique("_");
+ table->vars->frame = frame;
+ table->vars->table = table;
+ table->rows = zalloc_type(struct row);
+ table->rows->table = table;
+ table->rows->values = zalloc_type(struct value);
+ table->rows->values->expr = parse_expr("0");
+ table->rows->values->row = table->rows;
+ table->active_row = table->rows;
+ for (walk = &frame->tables; *walk; walk = &(*walk)->next);
+ *walk = table;
+ change_world();
+}
+
+
+static void popup_add_loop(void)
+{
+ struct frame *frame = popup_data;
+ struct loop *loop, **walk;
+
+ loop = zalloc_type(struct loop);
+ loop->var.name = unique("_");
+ loop->var.frame = frame;
+ loop->from.expr = parse_expr("0");
+ loop->to.expr = parse_expr("0");
+ loop->next = NULL;
+ for (walk = &frame->loops; *walk; walk = &(*walk)->next);
+ *walk = loop;
+ change_world();
+}
+
+
+static GtkItemFactoryEntry popup_frame_entries[] = {
+ { "/Add frame", NULL, popup_add_frame, 0, "<Item>" },
+ { "/sep0", NULL, NULL, 0, "<Separator>" },
+ { "/Add variable", NULL, popup_add_table, 0, "<Item>" },
+ { "/Add loop", NULL, popup_add_loop, 0, "<Item>" },
+ { "/sep1", NULL, NULL, 0, "<Separator>" },
+ { "/Delete frame", NULL, popup_del_frame, 0, "<Item>" },
+ { "/sep2", NULL, NULL, 0, "<Separator>" },
+ { "/Close", NULL, NULL, 0, "<Item>" },
+ { NULL }
+};
+
+
+static void pop_up_frame(struct frame *frame, GdkEventButton *event)
+{
+ gtk_widget_set_sensitive(
+ gtk_item_factory_get_item(factory_frame, "/Delete frame"),
+ frame != root_frame);
+ pop_up(popup_frame_widget, event, frame);
+}
+
+
+/* ----- popup: single variable -------------------------------------------- */
+
+
+static GtkItemFactory *factory_single_var;
+static GtkWidget *popup_single_var_widget;
+
+
+
+static void add_row_here(struct table *table, struct row **anchor)
+{
+ struct row *row;
+ const struct value *walk;
+ struct value *value;
+
+ row = zalloc_type(struct row);
+ row->table = table;
+ /* @@@ future: adjust type */
+ for (walk = table->rows->values; walk; walk = walk->next) {
+ value = zalloc_type(struct value);
+ value->expr = parse_expr("0");
+ value->row = row;
+ value->next = row->values;
+ row->values = value;
+ }
+ row->next = *anchor;
+ *anchor = row;
+ change_world();
+}
+
+
+static void add_column_here(struct table *table, struct var **anchor)
+{
+ const struct var *walk;
+ struct var *var;
+ struct row *row;
+ struct value *value;
+ struct value **value_anchor;
+ int n = 0, i;
+
+ for (walk = table->vars; walk != *anchor; walk = walk->next)
+ n++;
+ var = zalloc_type(struct var);
+ var->name = unique("_");
+ var->frame = table->vars->frame;
+ var->table = table;
+ var->next = *anchor;
+ *anchor = var;
+ for (row = table->rows; row; row = row->next) {
+ value_anchor = &row->values;
+ for (i = 0; i != n; i++)
+ value_anchor = &(*value_anchor)->next;
+ value = zalloc_type(struct value);
+ value->expr = parse_expr("0");
+ value->row = row;
+ value->next = *value_anchor;
+ *value_anchor = value;
+ }
+ change_world();
+}
+
+
+static void popup_add_row(void)
+{
+ struct var *var = popup_data;
+
+ add_row_here(var->table, &var->table->rows);
+}
+
+
+static void popup_add_column(void)
+{
+ struct var *var = popup_data;
+
+ add_column_here(var->table, &var->next);
+}
+
+
+static void popup_del_table(void)
+{
+ struct var *var = popup_data;
+
+ delete_table(var->table);
+ change_world();
+}
+
+
+static GtkItemFactoryEntry popup_single_var_entries[] = {
+ { "/Add row", NULL, popup_add_row, 0, "<Item>" },
+ { "/Add column", NULL, popup_add_column, 0, "<Item>" },
+ { "/sep1", NULL, NULL, 0, "<Separator>" },
+ { "/Delete variable", NULL, popup_del_table, 0, "<Item>" },
+ { "/sep2", NULL, NULL, 0, "<Separator>" },
+ { "/Close", NULL, NULL, 0, "<Item>" },
+ { NULL }
+};
+
+
+static void pop_up_single_var(struct var *var, GdkEventButton *event)
+{
+ pop_up(popup_single_var_widget, event, var);
+}
+
+
+/* ----- popup: table variable --------------------------------------------- */
+
+
+static GtkItemFactory *factory_table_var;
+static GtkWidget *popup_table_var_widget;
+
+
+static void popup_del_column(void)
+{
+ struct var *var = popup_data;
+ const struct var *walk;
+ int n = 0;
+
+ for (walk = var->table->vars; walk != var; walk = walk->next)
+ n++;
+ delete_column(var->table, n);
+ change_world();
+}
+
+
+static GtkItemFactoryEntry popup_table_var_entries[] = {
+ { "/Add row", NULL, popup_add_row, 0, "<Item>" },
+ { "/Add column", NULL, popup_add_column, 0, "<Item>" },
+ { "/sep1", NULL, NULL, 0, "<Separator>" },
+ { "/Delete table", NULL, popup_del_table, 0, "<Item>" },
+ { "/Delete column", NULL, popup_del_column, 0, "<Item>" },
+ { "/sep2", NULL, NULL, 0, "<Separator>" },
+ { "/Close", NULL, NULL, 0, "<Item>" },
+ { NULL }
+};
+
+
+static void pop_up_table_var(struct var *var, GdkEventButton *event)
+{
+ gtk_widget_set_sensitive(
+ gtk_item_factory_get_item(factory_table_var, "/Delete column"),
+ var->table->vars->next != NULL);
+ pop_up(popup_table_var_widget, event, var);
+}
+
+
+/* ----- popup: table value ------------------------------------------------ */
+
+
+static GtkItemFactory *factory_table_value;
+static GtkWidget *popup_table_value_widget;
+
+
+static void popup_add_column_by_value(void)
+{
+ struct value *value = popup_data;
+ const struct value *walk;
+ struct table *table = value->row->table;
+ struct var *var = table->vars;
+
+ for (walk = value->row->values; walk != value; walk = walk->next)
+ var = var->next;
+ add_column_here(table, &var->next);
+}
+
+
+static void popup_add_row_by_value(void)
+{
+ struct value *value = popup_data;
+
+ add_row_here(value->row->table, &value->row->next);
+}
+
+
+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();
+}
+
+
+static void popup_del_column_by_value(void)
+{
+ struct value *value = popup_data;
+ const struct value *walk;
+ int n = 0;
+
+ for (walk = value->row->values; walk != value; walk = walk->next)
+ n++;
+ delete_column(value->row->table, n);
+ change_world();
+}
+
+
+static GtkItemFactoryEntry popup_table_value_entries[] = {
+ { "/Add row", NULL, popup_add_row_by_value, 0, "<Item>" },
+ { "/Add column", NULL, popup_add_column_by_value,
+ 0, "<Item>" },
+ { "/sep1", NULL, NULL, 0, "<Separator>" },
+ { "/Delete row", NULL, popup_del_row, 0, "<Item>" },
+ { "/Delete column", NULL, popup_del_column_by_value,
+ 0, "<Item>" },
+ { "/sep2", NULL, NULL, 0, "<Separator>" },
+ { "/Close", NULL, NULL, 0, "<Item>" },
+ { NULL }
+};
+
+
+static void pop_up_table_value(struct value *value, GdkEventButton *event)
+{
+ gtk_widget_set_sensitive(
+ gtk_item_factory_get_item(factory_table_value, "/Delete row"),
+ value->row->table->rows->next != NULL);
+ gtk_widget_set_sensitive(
+ gtk_item_factory_get_item(factory_table_value, "/Delete column"),
+ value->row->table->vars->next != NULL);
+ pop_up(popup_table_value_widget, event, value);
+}
+
+
+/* ----- popup: loop ------------------------------------------------------- */
+
+
+static GtkItemFactory *factory_loop_var;
+static GtkWidget *popup_loop_var_widget;
+
+
+static void popup_del_loop(void)
+{
+ struct loop *loop = popup_data;
+
+ delete_loop(loop);
+ change_world();
+}
+
+
+static GtkItemFactoryEntry popup_loop_var_entries[] = {
+ { "/Delete loop", NULL, popup_del_loop, 0, "<Item>" },
+ { "/sep2", NULL, NULL, 0, "<Separator>" },
+ { "/Close", NULL, NULL, 0, "<Item>" },
+ { NULL }
+};
+
+
+static void pop_up_loop_var(struct loop *loop, GdkEventButton *event)
+{
+ pop_up(popup_loop_var_widget, event, loop);
+}
+
+
+/* ----- make popups ------------------------------------------------------- */
+
+
+static GtkWidget *make_popup(const char *name, GtkItemFactory **factory,
+ GtkItemFactoryEntry *entries)
+{
+ GtkWidget *popup;
+ int n;
+
+ n = 0;
+ for (n = 0; entries[n].path; n++);
+
+ *factory = gtk_item_factory_new(GTK_TYPE_MENU, name, NULL);
+ gtk_item_factory_create_items(*factory, n, entries, NULL);
+ popup = gtk_item_factory_get_widget(*factory, name);
+ return popup;
+}
+
+
+void make_popups(void)
+{
+ popup_frame_widget = make_popup("<FpedFramePopUp>",
+ &factory_frame, popup_frame_entries);
+ popup_single_var_widget = make_popup("<FpedSingleVarPopUp>",
+ &factory_single_var, popup_single_var_entries);
+ popup_table_var_widget = make_popup("<FpedTableVarPopUp>",
+ &factory_table_var, popup_table_var_entries);
+ popup_table_value_widget = make_popup("<FpedTableValusPopUp>",
+ &factory_table_value, popup_table_value_entries);
+ popup_loop_var_widget = make_popup("<FpedLoopVarPopUp>",
+ &factory_loop_var, popup_loop_var_entries);
+}
+
+
+/* ----- variable list ----------------------------------------------------- */
+
+
+static void add_sep(GtkWidget *box, int size)
+{
+ GtkWidget *sep;
+ GdkColor black = { 0, 0, 0, 0 };
+
+ sep = gtk_drawing_area_new();
+ gtk_box_pack_start(GTK_BOX(box), sep, FALSE, TRUE, size);
+ gtk_widget_modify_bg(sep, GTK_STATE_NORMAL, &black);
+}
+
+
+/* ----- variable name editor ---------------------------------------------- */
+
+
+static int find_var_in_frame(const struct frame *frame, const char *name)
+{
+ const struct table *table;
+ const struct loop *loop;
+ const struct var *var;
+
+ for (table = frame->tables; table; table = table->next)
+ for (var = table->vars; var; var = var->next)
+ if (!strcmp(var->name, name))
+ return 1;
+ for (loop = frame->loops; loop; loop = loop->next)
+ if (!strcmp(loop->var.name, name))
+ return 1;
+ return 0;
+}
+
+
+static int validate_var_name(const char *s, void *ctx)
+{
+ struct var *var = ctx;
+
+ if (!is_id(s))
+ return 0;
+ return !find_var_in_frame(var->frame, s);
+}
+
+
+static void unselect_var(void *data)
+{
+ struct var *var = data;
+
+ label_in_box_bg(var->widget, COLOR_VAR_PASSIVE);
+}
+
+
+static void edit_var(struct var *var)
+{
+ inst_select_outside(var, unselect_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);
+}
+
+
+/* ----- value editor ------------------------------------------------------ */
+
+
+static void unselect_value(void *data)
+{
+ struct value *value = data;
+
+ label_in_box_bg(value->widget,
+ value->row && value->row->table->active_row == value->row ?
+ COLOR_CHOICE_SELECTED : COLOR_EXPR_PASSIVE);
+}
+
+
+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);
+}
+
+
+/* ----- activator --------------------------------------------------------- */
+
+
+static GtkWidget *add_activator(GtkWidget *hbox, int active,
+ gboolean (*cb)(GtkWidget *widget, GdkEventButton *event, gpointer data),
+ gpointer user, const char *fmt, ...)
+{
+ GtkWidget *label;
+ va_list ap;
+ char buf[100];
+
+ va_start(ap, fmt);
+ vsprintf(buf, fmt, ap);
+ va_end(ap);
+ label = label_in_box_new(buf);
+ gtk_misc_set_padding(GTK_MISC(label), 2, 2);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
+ label_in_box_bg(label,
+ active ? COLOR_CHOICE_SELECTED : COLOR_CHOICE_UNSELECTED);
+ gtk_box_pack_start(GTK_BOX(hbox), box_of_label(label),
+ FALSE, FALSE, 2);
+ g_signal_connect(G_OBJECT(box_of_label(label)),
+ "button_press_event", G_CALLBACK(cb), user);
+ return label;
+}
+
+
+/* ----- assignments ------------------------------------------------------- */
+
+
+static gboolean assignment_var_select_event(GtkWidget *widget,
+ GdkEventButton *event, gpointer data)
+{
+ struct var *var = data;
+
+ switch (event->button) {
+ case 1:
+ edit_var(var);
+ break;
+ case 3:
+ pop_up_single_var(var, event);
+ break;
+ }
+ return TRUE;
+}
+
+
+static gboolean assignment_value_select_event(GtkWidget *widget,
+ GdkEventButton *event, gpointer data)
+{
+ struct value *value = data;
+
+ switch (event->button) {
+ case 1:
+ edit_value(value);
+ break;
+ }
+ return TRUE;
+}
+
+
+static void build_assignment(GtkWidget *vbox, struct frame *frame,
+ struct table *table)
+{
+ GtkWidget *hbox, *field;
+ char *expr;
+
+ if (!table->vars || table->vars->next)
+ return;
+ if (!table->rows || table->rows->next)
+ return;
+
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+
+ field = label_in_box_new(table->vars->name);
+ gtk_box_pack_start(GTK_BOX(hbox), box_of_label(field), FALSE, FALSE, 0);
+ label_in_box_bg(field, COLOR_VAR_PASSIVE);
+ table->vars->widget = field;
+ g_signal_connect(G_OBJECT(box_of_label(field)),
+ "button_press_event",
+ G_CALLBACK(assignment_var_select_event), table->vars);
+
+ gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(" = "),
+ FALSE, FALSE, 0);
+
+ expr = unparse(table->rows->values->expr);
+ field = label_in_box_new(expr);
+ free(expr);
+ gtk_box_pack_start(GTK_BOX(hbox), box_of_label(field), FALSE, FALSE, 0);
+ label_in_box_bg(field, COLOR_EXPR_PASSIVE);
+ table->rows->values->widget = field;
+ g_signal_connect(G_OBJECT(box_of_label(field)),
+ "button_press_event",
+ G_CALLBACK(assignment_value_select_event), table->rows->values);
+}
+
+
+/* ----- tables ------------------------------------------------------------ */
+
+
+static void select_row(struct row *row)
+{
+ struct table *table = row->table;
+ struct value *value;
+
+ for (value = table->active_row->values; value; value = value->next)
+ label_in_box_bg(value->widget, COLOR_ROW_UNSELECTED);
+ table->active_row = row;
+ for (value = table->active_row->values; value; value = value->next)
+ label_in_box_bg(value->widget, COLOR_ROW_SELECTED);
+}
+
+
+static gboolean table_var_select_event(GtkWidget *widget,
+ GdkEventButton *event, gpointer data)
+{
+ struct var *var = data;
+
+ switch (event->button) {
+ case 1:
+ edit_var(var);
+ break;
+ case 3:
+ pop_up_table_var(var, event);
+ break;
+ }
+ return TRUE;
+}
+
+
+static gboolean table_value_select_event(GtkWidget *widget,
+ GdkEventButton *event, gpointer data)
+{
+ struct value *value = data;
+
+ switch (event->button) {
+ case 1:
+ if (!value->row || value->row->table->active_row == value->row)
+ edit_value(value);
+ else {
+ select_row(value->row);
+ change_world();
+ }
+ break;
+ case 3:
+ pop_up_table_value(value, event);
+ break;
+ }
+ return TRUE;
+}
+
+
+static void build_table(GtkWidget *vbox, struct frame *frame,
+ struct table *table)
+{
+ GtkWidget *tab, *field;
+ GtkWidget *evbox, *align;
+ struct var *var;
+ struct row *row;
+ struct value *value;
+ int n_vars = 0, n_rows = 0;
+ char *expr;
+ GdkColor col;
+
+ for (var = table->vars; var; var = var->next)
+ n_vars++;
+ for (row = table->rows; row; row = row->next)
+ n_rows++;
+
+ if (n_vars == 1 && n_rows == 1)
+ return;
+
+ evbox = gtk_event_box_new();
+ align = gtk_alignment_new(0, 0, 0, 0);
+ gtk_container_add(GTK_CONTAINER(align), evbox);
+ gtk_box_pack_start(GTK_BOX(vbox), align, FALSE, FALSE, 0);
+
+ tab = gtk_table_new(n_rows+1, n_vars, FALSE);
+ gtk_container_add(GTK_CONTAINER(evbox), tab);
+ col = get_color(COLOR_VAR_TABLE_SEP);
+ gtk_widget_modify_bg(GTK_WIDGET(evbox),
+ GTK_STATE_NORMAL, &col);
+
+ gtk_table_set_row_spacings(GTK_TABLE(tab), 1);
+ gtk_table_set_col_spacings(GTK_TABLE(tab), 1);
+
+ n_vars = 0;
+ for (var = table->vars; var; var = var->next) {
+ field = label_in_box_new(var->name);
+ gtk_table_attach_defaults(GTK_TABLE(tab), box_of_label(field),
+ n_vars, n_vars+1, 0, 1);
+ label_in_box_bg(field, COLOR_VAR_PASSIVE);
+ g_signal_connect(G_OBJECT(box_of_label(field)),
+ "button_press_event",
+ G_CALLBACK(table_var_select_event), var);
+ var->widget = field;
+ n_vars++;
+ }
+ n_rows = 0;
+ for (row = table->rows; row; row = row->next) {
+ n_vars = 0;
+ for (value = row->values; value; value = value->next) {
+ expr = unparse(value->expr);
+ field = label_in_box_new(expr);
+ free(expr);
+ gtk_table_attach_defaults(GTK_TABLE(tab),
+ box_of_label(field),
+ n_vars, n_vars+1,
+ n_rows+1, n_rows+2);
+ label_in_box_bg(field, table->active_row == row ?
+ COLOR_ROW_SELECTED : COLOR_ROW_UNSELECTED);
+ g_signal_connect(G_OBJECT(box_of_label(field)),
+ "button_press_event",
+ G_CALLBACK(table_value_select_event), value);
+ value->widget = field;
+ n_vars++;
+ }
+ n_rows++;
+ }
+}
+
+
+/* ----- loops ------------------------------------------------------------- */
+
+
+static gboolean loop_var_select_event(GtkWidget *widget,
+ GdkEventButton *event, gpointer data)
+{
+ struct loop *loop = data;
+
+ switch (event->button) {
+ case 1:
+ edit_var(&loop->var);
+ break;
+ case 3:
+ pop_up_loop_var(loop, event);
+ break;
+ }
+ return TRUE;
+}
+
+
+static gboolean loop_from_select_event(GtkWidget *widget,
+ GdkEventButton *event, gpointer data)
+{
+ struct loop *loop = data;
+
+ switch (event->button) {
+ case 1:
+ edit_value(&loop->from);
+ break;
+ }
+ return TRUE;
+}
+
+
+static gboolean loop_to_select_event(GtkWidget *widget,
+ GdkEventButton *event, gpointer data)
+{
+ struct loop *loop = data;
+
+ switch (event->button) {
+ case 1:
+ edit_value(&loop->to);
+ break;
+ }
+ return TRUE;
+}
+
+
+static gboolean loop_select_event(GtkWidget *widget, GdkEventButton *event,
+ gpointer data)
+{
+ struct loop *loop = data;
+
+ switch (event->button) {
+ case 1:
+ loop->active =
+ (long) gtk_object_get_data(GTK_OBJECT(widget), "value");
+ change_world();
+ break;
+ }
+ return TRUE;
+}
+
+
+static void build_loop(GtkWidget *vbox, struct frame *frame,
+ struct loop *loop)
+{
+ GtkWidget *hbox, *field, *label;
+ char *expr;
+ int i;
+
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+
+ 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);
+ g_signal_connect(G_OBJECT(box_of_label(field)),
+ "button_press_event",
+ G_CALLBACK(loop_var_select_event), loop);
+ loop->var.widget = field;
+
+ gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(" = "),
+ FALSE, FALSE, 0);
+
+ expr = unparse(loop->from.expr);
+ field = label_in_box_new(expr);
+ free(expr);
+ gtk_box_pack_start(GTK_BOX(hbox), box_of_label(field), FALSE, FALSE, 0);
+ label_in_box_bg(field, COLOR_EXPR_PASSIVE);
+ g_signal_connect(G_OBJECT(box_of_label(field)),
+ "button_press_event",
+ G_CALLBACK(loop_from_select_event), loop);
+ loop->from.widget = field;
+
+ gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(" ... "),
+ FALSE, FALSE, 0);
+
+ expr = unparse(loop->to.expr);
+ field = label_in_box_new(expr);
+ free(expr);
+ gtk_box_pack_start(GTK_BOX(hbox), box_of_label(field), FALSE, FALSE, 0);
+ label_in_box_bg(field, COLOR_EXPR_PASSIVE);
+ g_signal_connect(G_OBJECT(box_of_label(field)),
+ "button_press_event",
+ G_CALLBACK(loop_to_select_event), loop);
+ loop->to.widget = field;
+
+ gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(" ("),
+ FALSE, FALSE, 0);
+
+ for (i = 0; i != loop->iterations; i++) {
+ label = add_activator(hbox, loop->active == i,
+ loop_select_event, loop, "%d", i);
+ gtk_object_set_data(GTK_OBJECT(box_of_label(label)), "value",
+ (gpointer) (long) i);
+ }
+
+ gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(")"),
+ FALSE, FALSE, 0);
+}
+
+
+/* ----- the list of variables, tables, and loops -------------------------- */
+
+
+static GtkWidget *build_vars(struct frame *frame)
+{
+ GtkWidget *vbox;
+ struct table *table;
+ struct loop *loop;
+
+ vbox= gtk_vbox_new(FALSE, 0);
+ for (table = frame->tables; table; table = table->next) {
+ add_sep(vbox, 3);
+ build_assignment(vbox, frame, table);
+ build_table(vbox, frame, table);
+ }
+ for (loop = frame->loops; loop; loop = loop->next) {
+ add_sep(vbox, 3);
+ build_loop(vbox, frame, loop);
+ }
+ return vbox;
+}
+
+
+/* ----- part name --------------------------------------------------------- */
+
+
+static int validate_part_name(const char *s, void *ctx)
+{
+ if (!*s)
+ return 0;
+ while (*s)
+ if (!is_id_char(*s++, 0))
+ return 0;
+ return 1;
+}
+
+static void unselect_part_name(void *data)
+{
+ GtkWidget *widget = data;
+
+ label_in_box_bg(widget, COLOR_PART_NAME);
+}
+
+
+static gboolean part_name_edit_event(GtkWidget *widget, GdkEventButton *event,
+ gpointer data)
+{
+ switch (event->button) {
+ case 1:
+ inst_select_outside(widget, unselect_part_name);
+ 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);
+ break;
+ }
+ return TRUE;
+}
+
+
+static GtkWidget *build_part_name(void)
+{
+ GtkWidget *label;
+
+ label = label_in_box_new(part_name);
+ gtk_misc_set_padding(GTK_MISC(label), 2, 2);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
+
+ label_in_box_bg(label, COLOR_PART_NAME);
+
+ g_signal_connect(G_OBJECT(box_of_label(label)),
+ "button_press_event", G_CALLBACK(part_name_edit_event), NULL);
+
+ return box_of_label(label);
+}
+
+
+/* ----- frame labels ------------------------------------------------------ */
+
+
+static int validate_frame_name(const char *s, void *ctx)
+{
+ struct frame *f;
+
+ if (!is_id(s))
+ return 0;
+ for (f = frames; f; f = f->next)
+ if (f->name && !strcmp(f->name, s))
+ return 0;
+ return 1;
+}
+
+
+static void unselect_frame(void *data)
+{
+ struct frame *frame= data;
+
+ /*
+ * "unselect" means in this context that the selection has moved
+ * elsewhere. However, this does not necessarily change the frame.
+ * (And, in fact, since we rebuild the frame list anyway, the color
+ * change here doesn't matter if selecting a different frame.)
+ * So we revert from "editing" to "selected".
+ */
+ label_in_box_bg(frame->label, COLOR_FRAME_SELECTED);
+}
+
+
+static void edit_frame(struct frame *frame)
+{
+ inst_select_outside(frame, unselect_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);
+}
+
+
+void select_frame(struct frame *frame)
+{
+ if (active_frame)
+ label_in_box_bg(active_frame->label, COLOR_FRAME_UNSELECTED);
+ active_frame = frame;
+ tool_frame_update();
+ change_world();
+}
+
+
+static gboolean frame_select_event(GtkWidget *widget, GdkEventButton *event,
+ gpointer data)
+{
+ struct frame *frame = data;
+
+ switch (event->button) {
+ case 1:
+ if (active_frame != frame)
+ select_frame(frame);
+ else {
+ if (active_frame->name)
+ edit_frame(frame);
+ }
+ break;
+ case 3:
+ pop_up_frame(frame, event);
+ break;
+ }
+ return TRUE;
+}
+
+
+static GtkWidget *build_frame_label(struct frame *frame)
+{
+ GtkWidget *label;
+
+ label = label_in_box_new(frame->name ? frame->name : "(root)");
+ gtk_misc_set_padding(GTK_MISC(label), 2, 2);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
+
+ label_in_box_bg(label, active_frame == frame ?
+ COLOR_FRAME_SELECTED : COLOR_FRAME_UNSELECTED);
+
+ g_signal_connect(G_OBJECT(box_of_label(label)),
+ "button_press_event", G_CALLBACK(frame_select_event), frame);
+ frame->label = label;
+
+ return box_of_label(label);
+}
+
+
+/* ----- frame references -------------------------------------------------- */
+
+
+static gboolean frame_ref_select_event(GtkWidget *widget, GdkEventButton *event,
+ gpointer data)
+{
+ struct obj *obj = data;
+
+ switch (event->button) {
+ case 1:
+ obj->u.frame.ref->active_ref = data;
+ change_world();
+ break;
+ }
+ return TRUE;
+}
+
+
+static GtkWidget *build_frame_refs(const struct frame *frame)
+{
+ GtkWidget *hbox;
+ struct obj *obj;
+
+ hbox = gtk_hbox_new(FALSE, 0);
+ for (obj = frame->objs; obj; obj = obj->next)
+ if (obj->type == ot_frame && obj->u.frame.ref == active_frame)
+ add_activator(hbox,
+ obj == obj->u.frame.ref->active_ref,
+ frame_ref_select_event, obj,
+ "%d", obj->u.frame.lineno);
+ return hbox;
+}
+
+
+/* ----- frames ------------------------------------------------------------ */
+
+
+void build_frames(GtkWidget *vbox)
+{
+ struct frame *frame;
+ GtkWidget *tab, *label, *refs, *vars;
+ 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);
+ 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);
+
+ label = build_part_name();
+ gtk_table_attach_defaults(GTK_TABLE(tab), label, 0, 1, 0, 1);
+
+ n = 0;
+ for (frame = root_frame; frame; frame = frame->prev) {
+ label = build_frame_label(frame);
+ gtk_table_attach_defaults(GTK_TABLE(tab), label,
+ 0, 1, n*2+1, n*2+2);
+
+ refs = build_frame_refs(frame);
+ gtk_table_attach_defaults(GTK_TABLE(tab), refs,
+ 1, 2, n*2+1, n*2+2);
+
+ vars = build_vars(frame);
+ gtk_table_attach_defaults(GTK_TABLE(tab), vars,
+ 1, 2, n*2+2, n*2+3);
+ n++;
+ }
+ gtk_widget_show_all(tab);
+}
Added: trunk/eda/fped/gui_frame.h
===================================================================
--- trunk/eda/fped/gui_frame.h (rev 0)
+++ trunk/eda/fped/gui_frame.h 2009-08-08 19:35:16 UTC (rev 5409)
@@ -0,0 +1,26 @@
+/*
+ * gui_frame.h - GUI, frame window
+ *
+ * Written 2009 by Werner Almesberger
+ * Copyright 2009 by Werner Almesberger
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+
+#ifndef GUI_FRAME_H
+#define GUI_FRAME_H
+
+#include <gtk/gtk.h>
+
+
+void make_popups(void);
+
+void select_frame(struct frame *frame);
+
+void build_frames(GtkWidget *vbox);
+
+#endif /* !GUI_FRAME_H */
More information about the commitlog
mailing list