r5351 - developers/werner/fped
werner at docs.openmoko.org
werner at docs.openmoko.org
Fri Jul 31 17:52:32 CEST 2009
Author: werner
Date: 2009-07-31 17:52:32 +0200 (Fri, 31 Jul 2009)
New Revision: 5351
Modified:
developers/werner/fped/expr.c
developers/werner/fped/expr.h
developers/werner/fped/gui.c
developers/werner/fped/gui.h
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/obj.c
developers/werner/fped/obj.h
Log:
- added infrastructure for editing values
- added editing of pad names
- moved "expand" from obj.c to expr.c and added syntax-check mode
- "expand": reject $ not followed by identifier character or {
Modified: developers/werner/fped/expr.c
===================================================================
--- developers/werner/fped/expr.c 2009-07-31 09:00:51 UTC (rev 5350)
+++ developers/werner/fped/expr.c 2009-07-31 15:52:32 UTC (rev 5351)
@@ -257,6 +257,9 @@
}
+/* ----- expression construction ------------------------------------------- */
+
+
struct expr *new_op(op_type op)
{
struct expr *expr;
@@ -289,3 +292,121 @@
{
return expr->op(expr, frame);
}
+
+
+/* ----- 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);
+ char *buf = alloc_size(len+1);
+ char num_buf[100]; /* enough :-) */
+ const char *s, *s0;
+ char *var;
+ const char *var_unique;
+ struct num value;
+ int i, value_len;
+
+ i = 0;
+ for (s = name; *s; s++) {
+ if (*s != '$') {
+ buf[i++] = *s;
+ continue;
+ }
+ s0 = ++s;
+ if (*s != '{') {
+ while (is_id(*s, s == s0))
+ s++;
+ if (s == s0)
+ goto invalid;
+ var = strnalloc(s0, s-s0);
+ len -= s-s0+1;
+ s--;
+ } else {
+ s++;
+ while (*s != '}') {
+ if (!*s) {
+ fail("unfinished \"${...}\"");
+ goto fail;
+ }
+ if (!is_id(*s, s == s0+1))
+ goto invalid;
+ s++;
+ }
+ var = strnalloc(s0+1, s-s0-1);
+ len -= s-s0+2;
+ }
+ if (!frame)
+ continue;
+ var_unique = unique(var);
+ free(var);
+ value = eval_var(frame, var_unique);
+ if (is_undef(value)) {
+ fail("undefined variable \"%s\"", var_unique);
+ goto fail;
+ }
+ value_len = snprintf(num_buf, sizeof(num_buf), "%lg%s",
+ value.n, str_unit(value));
+ len += value_len;
+ buf = realloc(buf, len);
+ if (!buf)
+ abort();
+ strcpy(buf+i, num_buf);
+ i += value_len;
+ }
+ buf[i] = 0;
+ return buf;
+
+invalid:
+ fail("invalid character in variable name");
+fail:
+ free(buf);
+ return NULL;
+}
+
+
+/* ----- expression-only parser -------------------------------------------- */
+
+
+struct expr *parse_expr(const char *s)
+{
+ return NULL;
+}
+
+
+static void vacate_op(struct expr *expr)
+{
+ if (expr->op == &op_num || expr->op == &op_var)
+ return;
+ if (expr->op == &op_minus) {
+ free_expr(expr->u.op.a);
+ return;
+ }
+ if (expr->op == &op_add || expr->op == &op_sub ||
+ expr->op == &op_mult || expr->op == &op_div) {
+ free_expr(expr->u.op.a);
+ free_expr(expr->u.op.b);
+ return;
+ }
+ abort();
+}
+
+
+void free_expr(struct expr *expr)
+{
+ vacate_op(expr);
+ free(expr);
+}
Modified: developers/werner/fped/expr.h
===================================================================
--- developers/werner/fped/expr.h 2009-07-31 09:00:51 UTC (rev 5350)
+++ developers/werner/fped/expr.h 2009-07-31 15:52:32 UTC (rev 5351)
@@ -98,4 +98,10 @@
char *eval_str(const struct frame *frame, const struct expr *expr);
struct num eval_num(const struct expr *expr, const struct frame *frame);
+/* if frame == NULL, we only check the syntax without expanding */
+char *expand(const char *name, const struct frame *frame);
+
+struct expr *parse_expr(const char *s);
+void free_expr(struct expr *expr);
+
#endif /* !EXPR_H */
Modified: developers/werner/fped/gui.c
===================================================================
--- developers/werner/fped/gui.c 2009-07-31 09:00:51 UTC (rev 5350)
+++ developers/werner/fped/gui.c 2009-07-31 15:52:32 UTC (rev 5351)
@@ -193,6 +193,15 @@
/* ----- frame list -------------------------------------------------------- */
+void change_world(void)
+{
+ instantiate();
+ label_in_box_bg(active_frame->label, "pink");
+ build_vars(vars_box, active_frame);
+ redraw();
+}
+
+
static void select_frame(struct frame *frame)
{
if (active_frame) {
@@ -200,10 +209,7 @@
inst_deselect();
}
active_frame = frame;
- instantiate();
- label_in_box_bg(active_frame->label, "pink");
- build_vars(vars_box, active_frame);
- redraw();
+ change_world();
}
@@ -327,6 +333,7 @@
gui_setup_style(root->window);
init_canvas();
+ edit_nothing();
select_frame(root_frame);
gtk_main();
Modified: developers/werner/fped/gui.h
===================================================================
--- developers/werner/fped/gui.h 2009-07-31 09:00:51 UTC (rev 5350)
+++ developers/werner/fped/gui.h 2009-07-31 15:52:32 UTC (rev 5351)
@@ -19,6 +19,10 @@
extern GtkWidget *root;
+
+/* update everything after a model change */
+void change_world(void);
+
int gui_init(int *argc, char ***argv);
int gui_main(int argc, char **argv);
Modified: developers/werner/fped/gui_status.c
===================================================================
--- developers/werner/fped/gui_status.c 2009-07-31 09:00:51 UTC (rev 5350)
+++ developers/werner/fped/gui_status.c 2009-07-31 15:52:32 UTC (rev 5351)
@@ -12,14 +12,32 @@
#include <stdarg.h>
+#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
#include <gtk/gtk.h>
+#include "util.h"
#include "coord.h"
+#include "unparse.h"
#include "gui_util.h"
+#include "gui_style.h"
+#include "gui.h"
#include "gui_status.h"
+struct edit_ops {
+ int (*changed)(GtkWidget *widget, const char *s, void *ctx);
+ int (*activate)(GtkWidget *widget, const char *s, void *ctx);
+};
+
+static struct edit_ops *edit_ops = NULL;
+static void *edit_ctx;
+
+
+/* ----- setter functions -------------------------------------------------- */
+
+
static GtkWidget *status_name, *status_entry;
static GtkWidget *status_x, *status_y;
static GtkWidget *status_r, *status_angle;
@@ -68,6 +86,160 @@
}
+static void entry_color(const char *color)
+{
+ GdkColor col;
+
+ col = get_color(color);
+ gtk_widget_modify_base(GTK_WIDGET(status_entry), GTK_STATE_NORMAL, &col);
+}
+
+
+/* ----- string fields ----------------------------------------------------- */
+
+
+struct edit_name_ctx {
+ char **s;
+ int (*validate)(const char *s, void *ctx);
+ void *ctx;
+};
+
+
+static int name_changed(GtkWidget *widget, const char *s, void *ctx)
+{
+ const struct edit_name_ctx *name_ctx = ctx;
+ int ok;
+
+ if (!strcmp(s, *name_ctx->s)) {
+ entry_color(COLOR_EDIT_ASIS);
+ return 1;
+ }
+ ok = !name_ctx->validate || name_ctx->validate(s, name_ctx->ctx);
+ entry_color(ok ? COLOR_EDIT_GOOD : COLOR_EDIT_BAD);
+ return ok;
+}
+
+
+static int name_activate(GtkWidget *widget, const char *s, void *ctx)
+{
+ const struct edit_name_ctx *name_ctx = ctx;
+
+ if (name_ctx->validate && !name_ctx->validate(s, name_ctx->ctx))
+ return 0;
+ free(*name_ctx->s);
+ *name_ctx->s = stralloc(s);
+ entry_color(COLOR_EDIT_ASIS);
+ return 1;
+}
+
+
+static struct edit_ops edit_ops_name = {
+ .changed = name_changed,
+ .activate = name_activate,
+};
+
+
+void edit_name(char **s, int (*validate)(const char *s, void *ctx), void *ctx)
+{
+ static struct edit_name_ctx name_ctx;
+
+ name_ctx.s = s;
+ name_ctx.validate = validate;
+ name_ctx.ctx = ctx;
+ edit_ops = &edit_ops_name;
+ edit_ctx = &name_ctx;
+ gtk_entry_set_text(GTK_ENTRY(status_entry), *s);
+ entry_color(COLOR_EDIT_ASIS);
+ gtk_widget_show(status_entry);
+}
+
+
+/* ----- expression fields ------------------------------------------------- */
+
+
+static int expr_changed(GtkWidget *widget, const char *s, void *ctx)
+{
+ struct expr *expr;
+
+ expr = parse_expr(s);
+ if (!expr) {
+ entry_color(COLOR_EDIT_BAD);
+ return 0;
+ }
+ entry_color(COLOR_EDIT_BAD);
+ free_expr(expr);
+ return 1;
+}
+
+
+static int expr_activate(GtkWidget *widget, const char *s, void *ctx)
+{
+ struct expr **anchor = ctx;
+ struct expr *expr;
+
+ expr = parse_expr(s);
+ if (!expr)
+ return 0;
+ free_expr(*anchor);
+ *anchor = expr;
+ entry_color(COLOR_EDIT_ASIS);
+ return 1;
+}
+
+
+static struct edit_ops edit_ops_expr = {
+ .changed = expr_changed,
+ .activate = expr_activate,
+};
+
+
+void edit_expression(struct expr **expr)
+{
+ char *s;
+
+ edit_ops = &edit_ops_expr;
+ edit_ctx = expr;
+ s = unparse(*expr);
+ gtk_entry_set_text(GTK_ENTRY(status_entry), s);
+ free(s);
+ entry_color(COLOR_EDIT_ASIS);
+ gtk_widget_show(status_entry);
+}
+
+
+/* ----- text entry -------------------------------------------------------- */
+
+
+static gboolean changed(GtkWidget *widget, GdkEventMotion *event,
+ gpointer data)
+{
+ if (edit_ops && edit_ops->changed)
+ edit_ops->changed(widget,
+ gtk_entry_get_text(GTK_ENTRY(widget)), edit_ctx);
+ return TRUE;
+}
+
+
+static gboolean activate(GtkWidget *widget, GdkEventMotion *event,
+ gpointer data)
+{
+ if (edit_ops && edit_ops->activate)
+ if (edit_ops->activate(widget,
+ gtk_entry_get_text(GTK_ENTRY(widget)), edit_ctx)) {
+ inst_deselect();
+ change_world();
+ }
+ return TRUE;
+}
+
+
+void edit_nothing(void)
+{
+ edit_ops = NULL;
+ gtk_widget_hide(status_entry);
+}
+
+
/* ----- setup ------------------------------------------------------------- */
@@ -106,6 +278,13 @@
status_entry = gtk_entry_new();
gtk_box_pack_start(GTK_BOX(hbox), status_entry, TRUE, TRUE, 0);
+ gtk_entry_set_has_frame(GTK_ENTRY(status_entry), FALSE);
+
+ g_signal_connect(G_OBJECT(status_entry), "changed",
+ G_CALLBACK(changed), status_entry);
+ g_signal_connect(G_OBJECT(status_entry), "activate",
+ G_CALLBACK(activate), status_entry);
+
/* x / y */
status_x = add_label(tab, 1, 0);
Modified: developers/werner/fped/gui_status.h
===================================================================
--- developers/werner/fped/gui_status.h 2009-07-31 09:00:51 UTC (rev 5350)
+++ developers/werner/fped/gui_status.h 2009-07-31 15:52:32 UTC (rev 5351)
@@ -14,10 +14,15 @@
#ifndef GUI_STATUS_H
#define GUI_STATUS_H
+#include <gtk/gtk.h>
+
#include "coord.h"
+#include "expr.h"
-#include <gtk/gtk.h>
+void edit_name(char **s, int (*validate)(const char *s, void *ctx), void *ctx);
+void edit_expression(struct expr **expr);
+void edit_nothing(void);
void status_set_name(const char *fmt, ...);
void status_set_x(const char *fmt, ...);
Modified: developers/werner/fped/gui_style.h
===================================================================
--- developers/werner/fped/gui_style.h 2009-07-31 09:00:51 UTC (rev 5350)
+++ developers/werner/fped/gui_style.h 2009-07-31 15:52:32 UTC (rev 5351)
@@ -19,6 +19,9 @@
#include "inst.h"
+/* ----- screen distances -------------------------------------------------- */
+
+
#define CANVAS_CLEARANCE 10
#define VEC_ARROW_LEN 10
@@ -32,6 +35,17 @@
#define SELECT_R 6 /* pixels within which we select */
+/* ----- assorted colors --------------------------------------------------- */
+
+
+#define COLOR_EDIT_ASIS "#ffffff"
+#define COLOR_EDIT_GOOD "#a0ffa0"
+#define COLOR_EDIT_BAD "#ffa0a0"
+
+
+/* ----- canvas drawing styles --------------------------------------------- */
+
+
GdkGC *gc_bg;
GdkGC *gc_vec[mode_n];
GdkGC *gc_obj[mode_n];
Modified: developers/werner/fped/inst.c
===================================================================
--- developers/werner/fped/inst.c 2009-07-31 09:00:51 UTC (rev 5350)
+++ developers/werner/fped/inst.c 2009-07-31 15:52:32 UTC (rev 5351)
@@ -17,6 +17,7 @@
#include "util.h"
#include "coord.h"
+#include "expr.h"
#include "obj.h"
#include "gui_status.h"
#include "gui_inst.h"
@@ -63,6 +64,7 @@
int best_dist, dist;
selected_inst = NULL;
+ edit_nothing();
for (inst = insts; inst; inst = inst->next) {
if (!inst->active || !inst->ops->distance)
continue;
@@ -91,6 +93,7 @@
status_set_r("");
status_set_angle("");
selected_inst = NULL;
+ edit_nothing();
}
@@ -277,10 +280,23 @@
}
+static int validate_pad_name(const char *s, void *ctx)
+{
+ char *tmp;
+
+ tmp = expand(s, NULL);
+ if (!tmp)
+ return 0;
+ free(tmp);
+ return 1;
+}
+
+
static void pad_op_select(struct inst *self)
{
status_set_name(self->u.name);
rect_status(self->bbox.min, self->bbox.max);
+ edit_name(&self->obj->u.pad.name, validate_pad_name, NULL);
}
Modified: developers/werner/fped/obj.c
===================================================================
--- developers/werner/fped/obj.c 2009-07-31 09:00:51 UTC (rev 5350)
+++ developers/werner/fped/obj.c 2009-07-31 15:52:32 UTC (rev 5351)
@@ -33,79 +33,6 @@
const struct frame *parent, int active);
-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';
-}
-
-
-static char *expand(const char *name, const struct frame *frame)
-{
- int len = strlen(name);
- char *buf = alloc_size(len+1);
- char num_buf[100]; /* enough :-) */
- const char *s, *s0;
- char *var;
- const char *var_unique;
- struct num value;
- int i, value_len;
-
- i = 0;
- for (s = name; *s; s++) {
- if (*s != '$') {
- buf[i++] = *s;
- continue;
- }
- s0 = ++s;
- if (*s != '{') {
- while (is_id(*s, s == s0))
- s++;
- var = strnalloc(s0, s-s0);
- len -= s-s0+1;
- s--;
- } else {
- s++;
- while (*s != '}') {
- if (!is_id(*s, s == s0+1))
- goto invalid;
- s++;
- }
- var = strnalloc(s0+1, s-s0-1);
- len -= s-s0+2;
- }
- var_unique = unique(var);
- free(var);
- value = eval_var(frame, var_unique);
- if (is_undef(value)) {
- fail("undefined variable \"%s\"", var_unique);
- goto fail;
- }
- value_len = snprintf(num_buf, sizeof(num_buf), "%lg%s",
- value.n, str_unit(value));
- len += value_len;
- buf = realloc(buf, len);
- if (!buf)
- abort();
- strcpy(buf+i, num_buf);
- i += value_len;
- }
- buf[i] = 0;
- return buf;
-
-invalid:
- fail("invalid character in variable name");
-fail:
- free(buf);
- return NULL;
-}
-
-
static int generate_vecs(struct frame *frame, struct coord base)
{
struct coord vec_base;
Modified: developers/werner/fped/obj.h
===================================================================
--- developers/werner/fped/obj.h 2009-07-31 09:00:51 UTC (rev 5350)
+++ developers/werner/fped/obj.h 2009-07-31 15:52:32 UTC (rev 5351)
@@ -101,7 +101,7 @@
};
struct pad {
- const char *name;
+ char *name;
struct vec *other; /* NULL if frame origin */
};
More information about the commitlog
mailing list