diff --git a/README b/README
index 37922d6..f953c67 100644
--- a/README
+++ b/README
@@ -337,3 +337,15 @@ Expressions
Expressions can contain numeric constants (in non-exponential notation),
variable names, the arithmetic operations +, -, *, /, and unary -.
Parentheses can be used to change precedence.
+
+
+GUI
+---
+
+Keys:
+
+space reset user coordinates
++, = zoom in (like mouse wheel forward)
+- zoom out (like mouse wheel backward)
+. cursor position to screen center (like middle click)
+* zoom and center to extents
diff --git a/TODO b/TODO
index 6f9d8ce..12a53e9 100644
--- a/TODO
+++ b/TODO
@@ -1,5 +1,4 @@
Missing features:
-- add row selection
- populate input area (still needed: mm/mil, rezoom)
- add vec editor (need to be able to edit name, x, and y)
- add obj editor
diff --git a/fpd.l b/fpd.l
index 4bba75b..8f68992 100644
--- a/fpd.l
+++ b/fpd.l
@@ -121,6 +121,8 @@ SP [\t ]*
BEGIN(INITIAL);
lineno++; }
+; BEGIN(INITIAL);
+
"{" { BEGIN(NOKEYWORD);
disable_keywords = is_table;
return '{'; }
diff --git a/fpd.y b/fpd.y
index be43166..f713ac0 100644
--- a/fpd.y
+++ b/fpd.y
@@ -249,7 +249,7 @@ table:
$$ = $
2;
$$->vars = $4;
$$->rows = $6;
- $$->active = 0;
+ $$->active_row = $6;
next_table = &$$->next;
}
;
@@ -272,7 +272,7 @@ vars:
var:
ID
{
- $$ = alloc_type(struct var);
+ $$ = zalloc_type(struct var);
$$->name = $1;
$$->frame = curr_frame;
$$->next = NULL;
diff --git a/gui.c b/gui.c
index e4ba2ac..a29bd65 100644
--- a/gui.c
+++ b/gui.c
@@ -128,8 +128,8 @@ static void unselect_value(void *data)
struct value *value = data;
label_in_box_bg(value->widget,
- value->row && value->row->table && value->row->table->curr_row ==
- value->row ? COLOR_CHOICE_SELECTED : COLOR_EXPR_PASSIVE);
+ value->row && value->row->table->active_row == value->row ?
+ COLOR_CHOICE_SELECTED : COLOR_EXPR_PASSIVE);
}
@@ -141,7 +141,6 @@ static void edit_value(struct value *value)
}
-
/* ----- assignments ------------------------------------------------------- */
@@ -201,6 +200,19 @@ static void build_assignment(GtkWidget *vbox, struct frame *frame,
/* ----- 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)
{
@@ -212,7 +224,14 @@ static gboolean table_var_select_event(GtkWidget *widget,
static gboolean table_value_select_event(GtkWidget *widget,
GdkEventButton *event, gpointer data)
{
- edit_value(data);
+ struct value *value = data;
+
+ if (!value->row || value->row->table->active_row == value->row)
+ edit_value(value);
+ else {
+ select_row(value->row);
+ change_world();
+ }
return TRUE;
}
@@ -272,7 +291,7 @@ static void build_table(GtkWidget *vbox, struct frame *frame,
box_of_label(field),
n_vars, n_vars+1,
n_rows+1, n_rows+2);
- label_in_box_bg(field, table->active == n_rows ?
+ 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",
diff --git a/gui_canvas.c b/gui_canvas.c
index 8d4eff1..5d7c277 100644
--- a/gui_canvas.c
+++ b/gui_canvas.c
@@ -228,6 +228,21 @@ static gboolean key_press_event(GtkWidget *widget, GdkEventKey *event,
user_origin = pos;
update_pos(pos);
break;
+ case '+':
+ case '=':
+ zoom_in(pos);
+ break;
+ case '-':
+ zoom_out(pos);
+ break;
+ case '*':
+ center();
+ auto_scale();
+ redraw();
+ case '.':
+ ctx.center = pos;
+ redraw();
+ break;
}
return TRUE;
}
diff --git a/obj.c b/obj.c
index 1726821..cc7b8d3 100644
--- a/obj.c
+++ b/obj.c
@@ -223,18 +223,13 @@ fail:
static int iterate_tables(struct frame *frame, struct table *table,
struct coord base, int active)
{
- int n;
-
if (!table)
return run_loops(frame, frame->loops, base, active);
- n = 0;
for (table->curr_row = table->rows; table->curr_row;
- table->curr_row = table->curr_row->next) {
+ table->curr_row = table->curr_row->next)
if (!iterate_tables(frame, table->next, base,
- active && table->active == n))
+ active && table->active_row == table->curr_row))
return 0;
- n++;
- }
return 1;
}
diff --git a/obj.h b/obj.h
index 62bdbff..847adaf 100644
--- a/obj.h
+++ b/obj.h
@@ -62,7 +62,7 @@ struct table {
struct row *curr_row;
/* GUI use */
- int active; /* n-th row is active, 0 based */
+ struct row *active_row;
};
struct loop {
diff --git a/tab.fpd b/tab.fpd
new file mode 100644
index 0000000..d4580c1
--- /dev/null
+++ b/tab.fpd
@@ -0,0 +1,14 @@
+/*
+ * row selection example
+ */
+
+table
+ { x, x2 }
+ { 1mm, 1 }
+ { 2mm, 4 }
+ { 3mm, 9 }
+vec @(x, 0mm)
+circ @ .
+c: vec @(x-1mm, -4mm)
+vec c(0.5mm, 0.5mm)
+pad "$x2" c .