1
0
mirror of git://projects.qi-hardware.com/fped.git synced 2024-12-22 23:28:38 +02:00

- when dragging the endpoint of an arc, show a helper line to visually connect

the point being dragged
- added pop-up menus for all frame and variable items (on-going)
- clickable items in the frame/var area now only respond to the left button,
  unless they have a pop-up
- removed the frame delete icon - use pop-up instead



git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5396 99fdad57-331a-0410-800a-d7fa5415bdb3
This commit is contained in:
werner 2009-08-06 20:19:00 +00:00
parent dc09f3435d
commit 30664583a1
6 changed files with 544 additions and 79 deletions

View File

@ -225,6 +225,31 @@ static void undelete_obj(struct obj *obj, struct obj *prev)
}
}
/* ----- tables ------------------------------------------------------------ */
void delete_row(struct row *row)
{
}
void delete_column(struct table *table, int n)
{
}
void delete_table(struct table *table)
{
}
/* ----- loops ------------------------------------------------------------- */
void delete_loop(struct loop *loop)
{
}
/* ----- frames ------------------------------------------------------------ */

View File

@ -20,6 +20,10 @@
void delete_vec(struct vec *vec);
void delete_obj(struct obj *obj);
void delete_row(struct row *row);
void delete_column(struct table *table, int n);
void delete_table(struct table *table);
void delete_loop(struct loop *loop);
void delete_frame(struct frame *frame);
int destroy(void);
int undelete(void);

3
fpd.y
View File

@ -78,6 +78,7 @@ static void make_var(const char *id, struct expr *expr)
table->vars = zalloc_type(struct var);
table->vars->name = id;
table->vars->frame = curr_frame;
table->vars->table = table;
table->rows = zalloc_type(struct row);
table->rows->table = table;
table->rows->values = zalloc_type(struct value);
@ -97,6 +98,7 @@ static void make_loop(const char *id, struct expr *from, struct expr *to)
loop->var.name = id;
loop->var.next = NULL;
loop->var.frame = curr_frame;
loop->var.table = NULL;
loop->from.expr = from;
loop->from.row = NULL;
loop->from.next = NULL;
@ -296,6 +298,7 @@ var:
$$ = zalloc_type(struct var);
$$->name = $1;
$$->frame = curr_frame;
$$->table = curr_table;
$$->next = NULL;
n_vars++;
}

571
gui.c
View File

@ -37,6 +37,406 @@ GtkWidget *root;
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;
delete_row(value->row);
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);
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 ---------------------------------------------------------- */
@ -188,7 +588,16 @@ static GtkWidget *add_activator(GtkWidget *hbox, int active,
static gboolean assignment_var_select_event(GtkWidget *widget,
GdkEventButton *event, gpointer data)
{
edit_var(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;
}
@ -196,7 +605,13 @@ static gboolean assignment_var_select_event(GtkWidget *widget,
static gboolean assignment_value_select_event(GtkWidget *widget,
GdkEventButton *event, gpointer data)
{
edit_value(data);
struct value *value = data;
switch (event->button) {
case 1:
edit_value(value);
break;
}
return TRUE;
}
@ -257,7 +672,16 @@ static void select_row(struct row *row)
static gboolean table_var_select_event(GtkWidget *widget,
GdkEventButton *event, gpointer data)
{
edit_var(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;
}
@ -267,11 +691,18 @@ static gboolean table_value_select_event(GtkWidget *widget,
{
struct value *value = data;
if (!value->row || value->row->table->active_row == value->row)
edit_value(value);
else {
select_row(value->row);
change_world();
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;
}
@ -353,7 +784,14 @@ static gboolean loop_var_select_event(GtkWidget *widget,
{
struct loop *loop = data;
edit_var(&loop->var);
switch (event->button) {
case 1:
edit_var(&loop->var);
break;
case 3:
pop_up_loop_var(loop, event);
break;
}
return TRUE;
}
@ -363,7 +801,11 @@ static gboolean loop_from_select_event(GtkWidget *widget,
{
struct loop *loop = data;
edit_value(&loop->from);
switch (event->button) {
case 1:
edit_value(&loop->from);
break;
}
return TRUE;
}
@ -373,7 +815,11 @@ static gboolean loop_to_select_event(GtkWidget *widget,
{
struct loop *loop = data;
edit_value(&loop->to);
switch (event->button) {
case 1:
edit_value(&loop->to);
break;
}
return TRUE;
}
@ -383,8 +829,13 @@ static gboolean loop_select_event(GtkWidget *widget, GdkEventButton *event,
{
struct loop *loop = data;
loop->active = (long) gtk_object_get_data(GTK_OBJECT(widget), "value");
change_world();
switch (event->button) {
case 1:
loop->active =
(long) gtk_object_get_data(GTK_OBJECT(widget), "value");
change_world();
break;
}
return TRUE;
}
@ -495,11 +946,15 @@ static void unselect_part_name(void *data)
static gboolean part_name_edit_event(GtkWidget *widget, GdkEventButton *event,
gpointer data)
{
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);
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;
}
@ -575,11 +1030,20 @@ static void select_frame(struct frame *frame)
static gboolean frame_select_event(GtkWidget *widget, GdkEventButton *event,
gpointer data)
{
if (active_frame != data)
select_frame(data);
else {
if (active_frame->name)
edit_frame(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;
}
@ -604,52 +1068,6 @@ static GtkWidget *build_frame_label(struct frame *frame)
}
/* ----- frame delete ------------------------------------------------------ */
static gboolean frame_delete_event(GtkWidget *widget, GdkEventButton *event,
gpointer data)
{
struct frame *frame = data;
switch (event->button) {
case 1:
if (frame == root_frame) {
fail("you cannot delete the root frame");
break;
}
delete_frame(frame);
if (active_frame == frame)
select_frame(root_frame);
change_world();
break;
}
return TRUE;
}
static GtkWidget *build_frame_delete(struct frame *frame)
{
GtkWidget *evbox, *image;
GtkWidget *align;
evbox = gtk_event_box_new();
image =
gtk_image_new_from_stock(GTK_STOCK_CANCEL,
GTK_ICON_SIZE_SMALL_TOOLBAR);
gtk_container_add(GTK_CONTAINER(evbox), image);
align = gtk_alignment_new(0.3, 0, 0, 0);
gtk_container_add(GTK_CONTAINER(align), evbox);
gtk_alignment_set_padding(GTK_ALIGNMENT(align), 2, 0, 0, 0);
g_signal_connect(G_OBJECT(evbox),
"button_press_event", G_CALLBACK(frame_delete_event), frame);
return align;
}
/* ----- frame references -------------------------------------------------- */
@ -658,8 +1076,12 @@ static gboolean frame_ref_select_event(GtkWidget *widget, GdkEventButton *event,
{
struct obj *obj = data;
obj->u.frame.ref->active_ref = data;
change_world();
switch (event->button) {
case 1:
obj->u.frame.ref->active_ref = data;
change_world();
break;
}
return TRUE;
}
@ -686,7 +1108,7 @@ static GtkWidget *build_frame_refs(const struct frame *frame)
static void build_frames(GtkWidget *vbox)
{
struct frame *frame;
GtkWidget *tab, *label, *delete, *refs, *vars;
GtkWidget *tab, *label, *refs, *vars;
int n = 0;
destroy_all_children(GTK_CONTAINER(vbox));
@ -707,10 +1129,6 @@ static void build_frames(GtkWidget *vbox)
gtk_table_attach_defaults(GTK_TABLE(tab), label,
0, 1, n*2+1, n*2+2);
delete = build_frame_delete(frame);
gtk_table_attach_defaults(GTK_TABLE(tab), delete,
0, 1, n*2+2, n*2+3);
refs = build_frame_refs(frame);
gtk_table_attach_defaults(GTK_TABLE(tab), refs,
1, 2, n*2+1, n*2+2);
@ -818,6 +1236,7 @@ int gui_main(void)
init_canvas();
edit_nothing();
select_frame(root_frame);
make_popups();
gtk_main();

View File

@ -386,8 +386,8 @@ static int end_new_circ(struct draw_ctx *ctx,
struct pix_buf *draw_move_arc(struct inst *inst, struct draw_ctx *ctx,
struct coord pos, int i)
{
struct coord c, from, to;
double r, a1, a2;
struct coord c, from, to, end;
double r, r_save, a1, a2;
struct pix_buf *buf;
c = translate(ctx, inst->base);
@ -420,8 +420,21 @@ struct pix_buf *draw_move_arc(struct inst *inst, struct draw_ctx *ctx,
a2 = -theta(c, to);
if (a2 < a1)
a2 += 360.0;
buf = save_pix_buf(DA, c.x-r, c.y-r, c.x+r, c.y+r, 1);
if (i != 2)
r_save = r;
else {
r_save = hypot(to.x-c.x, to.y-c.y);
if (r > r_save)
r_save = r;
}
buf = save_pix_buf(DA,
c.x-r_save, c.y-r_save, c.x+r_save, c.y+r_save, 1);
draw_arc(DA, gc_drag, FALSE, c.x, c.y, r, a1, a2);
if (i == 2) {
end = rotate_r(c, r_save, -a2);
gdk_draw_line(DA, gc_drag, c.x, c.y, end.x, end.y);
}
return buf;
}

1
obj.h
View File

@ -27,6 +27,7 @@ struct var {
/* back reference */
struct frame *frame;
struct table *table; /* NULL if loop */
/* for the GUI */
GtkWidget *widget;