r5354 - developers/werner/fped

werner at docs.openmoko.org werner at docs.openmoko.org
Sat Aug 1 00:11:03 CEST 2009


Author: werner
Date: 2009-08-01 00:11:03 +0200 (Sat, 01 Aug 2009)
New Revision: 5354

Modified:
   developers/werner/fped/README
   developers/werner/fped/TODO
   developers/werner/fped/expr.c
   developers/werner/fped/fpd.y
   developers/werner/fped/gui.c
   developers/werner/fped/gui_status.c
   developers/werner/fped/gui_status.h
   developers/werner/fped/gui_style.h
   developers/werner/fped/inst.c
   developers/werner/fped/inst.h
   developers/werner/fped/obj.c
   developers/werner/fped/obj.h
   developers/werner/fped/util.c
   developers/werner/fped/util.h
Log:
- some more language documentation details and cleanup
- added more details to color scheme for selecting non-canvas items
- moved is_id from expr.c to util.c
- loops now keep their variable name in "struct var", to allow better code 
  sharing with other variable-related functions
- variable names can now be edited
- frame names can now be edited



Modified: developers/werner/fped/README
===================================================================
--- developers/werner/fped/README	2009-07-31 16:57:46 UTC (rev 5353)
+++ developers/werner/fped/README	2009-07-31 22:11:03 UTC (rev 5354)
@@ -10,6 +10,25 @@
 that can be performed through the GUI.
 
 
+Footprint definition file format
+================================
+
+Footprint definitions are stored in text files. The program "fped" reads
+and (soon) writes such files, visualizes their content, and provides a
+graphical editor for them.
+
+The syntax is unique and draws from elements of a variety of languages
+commonly found on unix systems. One specialty is that there are no
+reserved words - the language keywords appear only at the beginning of
+a line and can thus be recognized as such without restricting their use
+for identifiers. This reduces the risk of creating incompatibilities
+with existing designs when introduction future language features.
+
+fped uses the C preprocessor for comments, conditional compilation,
+and - to a limited extent - also macros. Long lines can be split by
+ending them with a backslash.
+
+
 Geometry model
 ==============
 
@@ -186,7 +205,7 @@
 Simple variables
 ----------------
 
-A variable with a single value is defined with the usual C-like
+A variable with a single value is defined with the following
 assignment syntax:
 
 set <identifier> = <expression>

Modified: developers/werner/fped/TODO
===================================================================
--- developers/werner/fped/TODO	2009-07-31 16:57:46 UTC (rev 5353)
+++ developers/werner/fped/TODO	2009-07-31 22:11:03 UTC (rev 5354)
@@ -21,10 +21,13 @@
 - add postscript output
 - add option to include/omit helper vecs and frames (display and postscript)
 - Q: how do we handle stacks of objects ?
-- consider using cairo instead of gdk
+- future: consider using cairo instead of gdk
 - Q: add frame arguments ? (e.g., .frame pad(pin_num_offset) ...)
 - Q: should we make it a requirement to generate objects only once ?
 - advanced: non-standard solder mask
 - advanced: solder paste exceptions (subtractive, additive)
 - advanced: silk line width
 - make column of entry field greedily consume all unallocated space
+- when selecting an arc only consider the part drawn, not the whole circle
+- merge edit_unique with edit_name
+- merge find_var_in_frame with similar mechanisms in expr.c and fpd.y

Modified: developers/werner/fped/expr.c
===================================================================
--- developers/werner/fped/expr.c	2009-07-31 16:57:46 UTC (rev 5353)
+++ developers/werner/fped/expr.c	2009-07-31 22:11:03 UTC (rev 5354)
@@ -123,7 +123,7 @@
 		}
 	}
 	for (loop = frame->loops; loop; loop = loop->next)
-		if (loop->var == name)
+		if (loop->var.name == name)
 			return make_num(loop->curr_value);
 	if (frame->curr_parent)
 		return eval_var(frame->curr_parent, name);
@@ -297,18 +297,6 @@
 /* ----- string expansion -------------------------------------------------- */
 
 
-static int is_id(char c, int first)
-{
-	if ((c >= 'A' && c <= 'Z') ||
-	    (c >= 'a' && c <= 'z') ||
-	    c == '_')
-		return 1;
-	if (first)
-		return 0;
-	return c >= '0' && c <= '9';
-}
-
-
 char *expand(const char *name, const struct frame *frame)
 {
 	int len = strlen(name);

Modified: developers/werner/fped/fpd.y
===================================================================
--- developers/werner/fped/fpd.y	2009-07-31 16:57:46 UTC (rev 5353)
+++ developers/werner/fped/fpd.y	2009-07-31 22:11:03 UTC (rev 5354)
@@ -21,13 +21,18 @@
 
 
 static struct frame *curr_frame;
+static struct table *curr_table;
+static struct row *curr_row;
+
 static struct frame *last_frame = NULL;
+static struct vec *last_vec = NULL;
+
 static struct table **next_table;
 static struct loop **next_loop;
 static struct vec **next_vec;
 static struct obj **next_obj;
+
 static int n_vars, n_values;
-static struct vec *last_vec = NULL;
 
 
 static struct frame *find_frame(const char *name)
@@ -70,9 +75,11 @@
 	table = zalloc_type(struct table);
 	table->vars = zalloc_type(struct var);
 	table->vars->name = id;
+	table->vars->frame = curr_frame;
 	table->rows = zalloc_type(struct row);
 	table->rows->values = zalloc_type(struct value);
 	table->rows->values->expr = expr;
+	table->rows->values->row = table->rows;
 	*next_table = table;
 	next_table = &table->next;
 }
@@ -83,7 +90,9 @@
 	struct loop *loop;
 
 	loop = alloc_type(struct loop);
-	loop->var = id;
+	loop->var.name = id;
+	loop->var.next = NULL;
+	loop->var.frame = curr_frame;
 	loop->from = from;
 	loop->to = to;
 	loop->next = NULL;
@@ -172,7 +181,6 @@
 			else
 				frames = curr_frame;
 			last_frame = curr_frame;
-
 		}
 	    frame_items '}'
 		{
@@ -213,6 +221,7 @@
 		{
 			$<table>$ = zalloc_type(struct table);
 			*next_table = $<table>$;
+			curr_table = $<table>$;
 			n_vars = 0;
 		}
 	    '{' vars '}' rows
@@ -245,6 +254,7 @@
 		{
 			$$ = alloc_type(struct var);
 			$$->name = $1;
+			$$->frame = curr_frame;
 			$$->next = NULL;
 			n_vars++;
 		}
@@ -257,6 +267,9 @@
 		}
 	| '{'
 		{
+			$<row>$ = alloc_type(struct row);
+			$<row>$->table = curr_table;
+			curr_row = $<row>$;;
 			n_values = 0;
 		}
 	    row '}'
@@ -264,12 +277,11 @@
 			if (n_vars != n_values)
 				yyerrorf("table has %d variables but row has "
 				    "%d values", n_vars, n_values);
-			$<row>$ = alloc_type(struct row);
-			$<row>$->values = $3;
+			$<row>2->values = $3;
 		}
 	    rows
 		{
-			$$ = $<row>5;
+			$$ = $<row>2;
 			$$->next = $6;
 		}
 	;
@@ -294,6 +306,7 @@
 		{
 			$$ = alloc_type(struct value);
 			$$->expr = $1;
+			$$->row = curr_row;
 			$$->next = NULL;
 			n_values++;
 		}

Modified: developers/werner/fped/gui.c
===================================================================
--- developers/werner/fped/gui.c	2009-07-31 16:57:46 UTC (rev 5353)
+++ developers/werner/fped/gui.c	2009-07-31 22:11:03 UTC (rev 5354)
@@ -12,9 +12,11 @@
 
 
 #include <stdlib.h>
+#include <string.h>
 #include <math.h>
 #include <gtk/gtk.h>
 
+#include "util.h"
 #include "inst.h"
 #include "obj.h"
 #include "unparse.h"
@@ -27,6 +29,7 @@
 
 GtkWidget *root;
 
+static GtkWidget *frames_box;
 static GtkWidget *vars_box;
 
 
@@ -69,13 +72,88 @@
 }
 
 
-/* ----- GUI construction -------------------------------------------------- */
+/* ----- 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_id(const char *s)
+{
+	const char *p;
+
+	if (!*s)
+		return 0;
+	for (p = s; *p; p++)
+		if (!is_id(*p, s == p))
+			return 0;
+	return 1;
+}
+
+
+static int validate_var_name(const char *s, void *ctx)
+{
+	struct var *var = ctx;
+
+	if (!validate_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_name(var->name);
+	edit_unique(&var->name, validate_var_name, var);
+}
+
+
+/* ----- assignments ------------------------------------------------------- */
+
+
+static gboolean assignment_var_select_event(GtkWidget *widget,
+     GdkEventButton *event, gpointer data)
+{
+	edit_var(data);
+	return TRUE;
+}
+
+
+static gboolean assignment_value_select_event(GtkWidget *widget,
+     GdkEventButton *event, gpointer data)
+{
+	return TRUE;
+}
+
+
 static void build_assignment(GtkWidget *vbox, struct frame *frame,
      struct table *table)
 {
-	GtkWidget *hbox;
+	GtkWidget *hbox, *field;
 	char *expr;
 
 	if (!table->vars || table->vars->next)
@@ -85,17 +163,48 @@
 
 	hbox = gtk_hbox_new(FALSE, 0);
 	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
-	gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(table->vars->name),
-	    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);
-	gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(expr),
-	    FALSE, FALSE, 0);
+	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 gboolean table_var_select_event(GtkWidget *widget,
+     GdkEventButton *event, gpointer data)
+{
+	edit_var(data);
+	return TRUE;
+}
+
+
+static gboolean table_value_select_event(GtkWidget *widget,
+     GdkEventButton *event, gpointer data)
+{
+	return TRUE;
+}
+
+
 static void build_table(GtkWidget *vbox, struct frame *frame,
      struct table *table)
 {
@@ -123,9 +232,13 @@
 	n_vars = 0;
 	for (var = table->vars; var; var = var->next) {
 		field = label_in_box_new(var->name);
-		label_in_box_bg(field, "pink");
 		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;
@@ -139,6 +252,12 @@
 			    box_of_label(field),
 			    n_vars, n_vars+1,
 			    n_rows+1, n_rows+2);
+			label_in_box_bg(field, table->active == n_rows ?
+			    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++;
@@ -146,31 +265,77 @@
 }
 
 
+/* ----- loops ------------------------------------------------------------- */
+
+
+static gboolean loop_var_select_event(GtkWidget *widget,
+     GdkEventButton *event, gpointer data)
+{
+	edit_var(data);
+	return TRUE;
+}
+
+
+static gboolean loop_from_select_event(GtkWidget *widget,
+     GdkEventButton *event, gpointer data)
+{
+	return TRUE;
+}
+
+
+static gboolean loop_to_select_event(GtkWidget *widget,
+     GdkEventButton *event, gpointer data)
+{
+	return TRUE;
+}
+
+
 static void build_loop(GtkWidget *vbox, struct frame *frame,
      struct loop *loop)
 {
-	GtkWidget *hbox;
+	GtkWidget *hbox, *field;
 	char *expr;
 
 	hbox = gtk_hbox_new(FALSE, 0);
 	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
-	gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(loop->var),
-	    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);
-	gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(expr),
-	    FALSE, FALSE, 0);
+	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);
+
 	gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(" ... "),
 	    FALSE, FALSE, 0);
+
 	expr = unparse(loop->to);
-	gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(expr),
-	    FALSE, FALSE, 0);
+	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);
 }
 
 
+/* ----- the list of variables, tables, and loops -------------------------- */
+
+
 static void build_vars(GtkWidget *vbox, struct frame *frame)
 {
 	struct table *table;
@@ -193,19 +358,32 @@
 /* ----- frame list -------------------------------------------------------- */
 
 
-void change_world(void)
+static int validate_frame_name(const char *s, void *ctx)
 {
-	instantiate();
-	label_in_box_bg(active_frame->label, "pink");
-	build_vars(vars_box, active_frame);
-	redraw();
+	struct frame *f;
+
+	if (!validate_id(s))
+		return 0;
+	for (f = frames; f; f = f->next)
+		if (f->name && !strcmp(f->name, s))
+			return 0;
+	return 1;
 }
 
 
+static void edit_frame(struct frame *frame)
+{
+	inst_select_outside(frame, NULL);
+	label_in_box_bg(frame->label, COLOR_FRAME_EDITING);
+	status_set_name(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, "grey");
+		label_in_box_bg(active_frame->label, COLOR_FRAME_UNSELECTED);
 		inst_deselect();
 	}
 	active_frame = frame;
@@ -216,16 +394,22 @@
 static gboolean frame_select_event(GtkWidget *widget, GdkEventButton *event,
      gpointer data)
 {
-	select_frame(data);
+	if (active_frame != data)
+		select_frame(data);
+	else {
+		if (active_frame->name)
+			edit_frame(data);
+	}
 	return TRUE;
 }
 
 
-static void show_frames(GtkWidget *vbox)
+static void build_frames(GtkWidget *vbox)
 {
 	struct frame *f;
 	GtkWidget *label;
 
+	destroy_all_children(GTK_CONTAINER(vbox));
 	for (f = root_frame; f; f = f->prev) {
 		label = label_in_box_new(f->name ? f->name : "(root)");
 		gtk_box_pack_start(GTK_BOX(vbox), box_of_label(label),
@@ -233,12 +417,14 @@
 		gtk_misc_set_padding(GTK_MISC(label), 2, 2);
 		gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
 
-		label_in_box_bg(label, "grey");
+		label_in_box_bg(label, active_frame == f ?
+		    COLOR_FRAME_SELECTED : COLOR_FRAME_UNSELECTED);
 
 		g_signal_connect(G_OBJECT(box_of_label(label)),
 		    "button_press_event", G_CALLBACK(frame_select_event), f);
 		f->label = label;
 	}
+	gtk_widget_show_all(vbox);
 }
 
 
@@ -249,7 +435,6 @@
 {
 	GtkWidget *hbox, *vars, *paned;
 	GtkWidget *frame_list;
-	GtkWidget *v2box;
 
 	hbox = gtk_hbox_new(FALSE, 0);
 	gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
@@ -261,11 +446,11 @@
 	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(frame_list),
 	    GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
 
-	v2box = gtk_vbox_new(FALSE, 0);
+	frames_box = gtk_vbox_new(FALSE, 0);
 	gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(frame_list),
-	    v2box);
+	    frames_box);
 
-	show_frames(v2box);
+	build_frames(frames_box);
 
 	add_sep(hbox, 2);
 
@@ -293,6 +478,16 @@
 /* ----- GUI construction -------------------------------------------------- */
 
 
+void change_world(void)
+{
+	instantiate();
+	label_in_box_bg(active_frame->label, COLOR_FRAME_SELECTED);
+	build_frames(frames_box);
+	build_vars(vars_box, active_frame);
+	redraw();
+}
+
+
 static void make_screen(GtkWidget *window)
 {
 	GtkWidget *vbox;

Modified: developers/werner/fped/gui_status.c
===================================================================
--- developers/werner/fped/gui_status.c	2009-07-31 16:57:46 UTC (rev 5353)
+++ developers/werner/fped/gui_status.c	2009-07-31 22:11:03 UTC (rev 5354)
@@ -95,6 +95,65 @@
 }
 
 
+/* ----- identifier fields ------------------------------------------------- */
+
+
+struct edit_unique_ctx {
+	const char **s;
+	int (*validate)(const char *s, void *ctx);
+	void *ctx;
+};
+
+
+static int unique_changed(GtkWidget *widget, const char *s, void *ctx)
+{
+	const struct edit_unique_ctx *unique_ctx = ctx;
+	int ok;
+
+	if (!strcmp(s, *unique_ctx->s)) {
+		entry_color(COLOR_EDIT_ASIS);
+		return 1;
+	}
+	ok = !unique_ctx->validate || unique_ctx->validate(s, unique_ctx->ctx);
+	entry_color(ok ? COLOR_EDIT_GOOD : COLOR_EDIT_BAD);
+	return ok;
+}
+
+
+static int unique_activate(GtkWidget *widget, const char *s, void *ctx)
+{
+	const struct edit_unique_ctx *unique_ctx = ctx;
+
+	if (unique_ctx->validate && !unique_ctx->validate(s, unique_ctx->ctx))
+		return 0;
+	*unique_ctx->s = unique(s);
+	entry_color(COLOR_EDIT_ASIS);
+	return 1;
+}
+
+
+static struct edit_ops edit_ops_unique = {
+	.changed	= unique_changed,
+	.activate	= unique_activate,
+};
+
+
+void edit_unique(const char **s, int (*validate)(const char *s, void *ctx), 
+    void *ctx)
+{
+	static struct edit_unique_ctx unique_ctx;
+
+	unique_ctx.s = s;
+	unique_ctx.validate = validate;
+	unique_ctx.ctx = ctx;
+	edit_ops = &edit_ops_unique;
+	edit_ctx = &unique_ctx;
+	gtk_entry_set_text(GTK_ENTRY(status_entry), *s);
+	entry_color(COLOR_EDIT_ASIS);
+	gtk_widget_show(status_entry);
+}
+
+
 /* ----- string fields ----------------------------------------------------- */
 
 

Modified: developers/werner/fped/gui_status.h
===================================================================
--- developers/werner/fped/gui_status.h	2009-07-31 16:57:46 UTC (rev 5353)
+++ developers/werner/fped/gui_status.h	2009-07-31 22:11:03 UTC (rev 5354)
@@ -20,6 +20,8 @@
 #include "expr.h"
 
 
+void edit_unique(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_expression(struct expr **expr);
 void edit_nothing(void);

Modified: developers/werner/fped/gui_style.h
===================================================================
--- developers/werner/fped/gui_style.h	2009-07-31 16:57:46 UTC (rev 5353)
+++ developers/werner/fped/gui_style.h	2009-07-31 22:11:03 UTC (rev 5354)
@@ -42,7 +42,22 @@
 #define COLOR_EDIT_GOOD	"#a0ffa0"
 #define COLOR_EDIT_BAD	"#ffa0a0"
 
+#define	COLOR_EDITING	"#ff00ff"
 
+#define	COLOR_FRAME_UNSELECTED	"#c0c0c0"
+#define COLOR_FRAME_SELECTED	"#fff0a0"
+#define COLOR_FRAME_EDITING	COLOR_EDITING
+
+#define	COLOR_VAR_PASSIVE	COLOR_FRAME_UNSELECTED
+#define	COLOR_VAR_EDITING	COLOR_EDITING
+#define	COLOR_EXPR_PASSIVE	"#f0f0ff"
+#define	COLOR_EXPR_EDITING	COLOR_EDITING
+#define	COLOR_CHOICE_UNSELECTED	COLOR_EXPR_PASSIVE
+#define	COLOR_CHOICE_SELECTED	"#9090ff"
+#define	COLOR_ROW_UNSELECTED	COLOR_CHOICE_UNSELECTED
+#define	COLOR_ROW_SELECTED	COLOR_CHOICE_SELECTED
+
+
 /* ----- canvas drawing styles --------------------------------------------- */
 
 

Modified: developers/werner/fped/inst.c
===================================================================
--- developers/werner/fped/inst.c	2009-07-31 16:57:46 UTC (rev 5353)
+++ developers/werner/fped/inst.c	2009-07-31 22:11:03 UTC (rev 5354)
@@ -36,6 +36,32 @@
 #define	IS_ACTIVE	((active_set & 1))
 
 
+/* ----- selection of items not on the canvas ------------------------------ */
+
+
+static void *selected_outside = NULL;
+static void (*outside_deselect)(void *item);
+
+
+static void deselect_outside(void)
+{
+	if (selected_outside && outside_deselect)
+		outside_deselect(selected_outside);
+	selected_outside = NULL;
+}
+
+
+void inst_select_outside(void *item, void (*deselect)(void *item))
+{
+	if (item == selected_outside)
+		return;
+	deselect_outside();
+	inst_deselect();
+	selected_outside = item;
+	outside_deselect = deselect;
+}
+
+
 /* ----- selection --------------------------------------------------------- */
 
 
@@ -63,6 +89,7 @@
 	struct inst *inst;
 	int best_dist, dist;
 
+	deselect_outside();
 	selected_inst = NULL;
 	edit_nothing();
 	for (inst = insts; inst; inst = inst->next) {
@@ -87,6 +114,7 @@
 {
 	if (selected_inst)
 		set_path(0);
+	deselect_outside();
 	status_set_name("");
 	status_set_x("");
 	status_set_y("");

Modified: developers/werner/fped/inst.h
===================================================================
--- developers/werner/fped/inst.h	2009-07-31 16:57:46 UTC (rev 5353)
+++ developers/werner/fped/inst.h	2009-07-31 22:11:03 UTC (rev 5354)
@@ -74,6 +74,7 @@
 extern struct inst *selected_inst;
 
 
+void inst_select_outside(void *item, void (*deselect)(void *item));
 int inst_select(const struct draw_ctx *ctx, struct coord pos);
 void inst_deselect(void);
 

Modified: developers/werner/fped/obj.c
===================================================================
--- developers/werner/fped/obj.c	2009-07-31 16:57:46 UTC (rev 5353)
+++ developers/werner/fped/obj.c	2009-07-31 22:11:03 UTC (rev 5354)
@@ -151,7 +151,7 @@
 	for (loop->curr_value = from.n; loop->curr_value <= to.n;
 	    loop->curr_value += 1) {
 		if (n >= MAX_ITERATIONS) {
-			fail("%s: too many iterations (%d)", loop->var,
+			fail("%s: too many iterations (%d)", loop->var.name,
 			    MAX_ITERATIONS);
 			return 0;
 		}

Modified: developers/werner/fped/obj.h
===================================================================
--- developers/werner/fped/obj.h	2009-07-31 16:57:46 UTC (rev 5353)
+++ developers/werner/fped/obj.h	2009-07-31 22:11:03 UTC (rev 5354)
@@ -23,16 +23,31 @@
 struct var {
 	const char *name;
 	struct var *next;
+
+	/* back reference */
+	struct frame *frame;
+
+	/* for the GUI */
+	GtkWidget *widget;
 };
 
 struct value {
 	struct expr *expr;
 	struct value *next;
+
+	/* back reference */
+	struct row *row;
+
+	/* for the GUI */
+	GtkWidget *widget;
 };
 
 struct row {
 	struct value *values;
 	struct row *next;
+
+	/* back reference */
+	struct table *table;
 };
 
 struct table {
@@ -48,7 +63,7 @@
 };
 
 struct loop {
-	const char *var;
+	struct var var;
 	struct expr *from;
 	struct expr *to;
 	struct loop *next;

Modified: developers/werner/fped/util.c
===================================================================
--- developers/werner/fped/util.c	2009-07-31 16:57:46 UTC (rev 5353)
+++ developers/werner/fped/util.c	2009-07-31 22:11:03 UTC (rev 5354)
@@ -16,6 +16,20 @@
 #include "util.h"
 
 
+
+int is_id(char c, int first) 
+{
+	if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_')
+		return 1;
+	if (first)
+		return 0;
+	return c >= '0' && c <= '9';
+}
+
+
+/* ----- unique identifiers ------------------------------------------------ */
+
+
 static struct unique {
 	const char *s;
 	struct unique *next;

Modified: developers/werner/fped/util.h
===================================================================
--- developers/werner/fped/util.h	2009-07-31 16:57:46 UTC (rev 5353)
+++ developers/werner/fped/util.h	2009-07-31 22:11:03 UTC (rev 5354)
@@ -45,6 +45,9 @@
 	strnalloc_tmp[n] = 0;				\
 	strnalloc_tmp; })
 
+
+int is_id(char c, int first);
+
 const char *unique(const char *s);
 
 #endif /* !UTIL_H */




More information about the commitlog mailing list