1
0
mirror of git://projects.qi-hardware.com/fped.git synced 2024-06-29 00:17:19 +03:00

GUI can create silk screen objects.

- made xpm name manipulation compatible with older versions of ImageMagick
  (reported by Alvaro Lopes)
- corrected all lines beginning with five or more spaces
- Makefile
- README: fixed loop example (reported by Joerg Reisenweber)
- moved draw_arc and draw_circle from gui_inst.c to gui_util.c
- added dragging and hovering
- added creation of lines, rectangles, and arcs via GUI
- removed arc tool (use circle instead)
- fixed reference counting in vectors



git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5384 99fdad57-331a-0410-800a-d7fa5415bdb3
This commit is contained in:
werner 2009-08-04 12:06:04 +00:00
parent 0015f96f14
commit 5add8b5229
18 changed files with 623 additions and 89 deletions

View File

@ -17,7 +17,7 @@ OBJS = fped.o expr.o coord.o obj.o inst.o util.o error.o \
gui_tools.o gui_tools.o
XPMS = point.xpm vec.xpm frame.xpm \ XPMS = point.xpm vec.xpm frame.xpm \
line.xpm rect.xpm pad.xpm circ.xpm arc.xpm meas.xpm line.xpm rect.xpm pad.xpm circ.xpm meas.xpm
CFLAGS_GTK = `pkg-config --cflags gtk+-2.0` CFLAGS_GTK = `pkg-config --cflags gtk+-2.0`
LIBS_GTK = `pkg-config --libs gtk+-2.0` LIBS_GTK = `pkg-config --libs gtk+-2.0`
@ -76,7 +76,7 @@ endif
.fig.xpm: .fig.xpm:
fig2dev -L xpm -Z 0.32 -S 4 $< | \ fig2dev -L xpm -Z 0.32 -S 4 $< | \
convert -crop 24x24+1+1 - - | \ convert -crop 24x24+1+1 - - | \
sed s/xpm__/xpm_`basename $@ .xpm`/ >$@ sed "s/*.*\[]/*xpm_`basename $@ .xpm`[]/" >$@
all: fped all: fped

4
README
View File

@ -277,9 +277,9 @@ loop n = 1, 3
and and
loop n = 1, 3 loop n = 1, 3.5
both assigns the values 1, 2, and 3 to the variable "n". both assign the values 1, 2, and 3 to the variable "n".
When a loop is executed, the objects contained in the body of the When a loop is executed, the objects contained in the body of the
enclosing frame are generated for each value of the variable. If enclosing frame are generated for each value of the variable. If

View File

@ -27,7 +27,7 @@ double mm_to_mil(double mm, int exponent)
double mil_to_mm(double mil, int exponent) double mil_to_mm(double mil, int exponent)
{ {
return mil*pow(MIL_IN_MM, exponent); return mil*pow(MIL_IN_MM, exponent);
} }
/* ----- vector operations ------------------------------------------------- */ /* ----- vector operations ------------------------------------------------- */
@ -160,5 +160,5 @@ unit_type dist_circle(struct coord p, struct coord c, unit_type r)
unit_type d; unit_type d;
d = hypot(p.x-c.x, p.y-c.y); d = hypot(p.x-c.x, p.y-c.y);
return fabs(d-r); return fabs(d-r);
} }

6
fpd.y
View File

@ -342,8 +342,6 @@ vec:
$$ = alloc_type(struct vec); $$ = alloc_type(struct vec);
$$->name = NULL; $$->name = NULL;
$$->base = $2; $$->base = $2;
if ($2)
$2->n_refs++;
$$->x = $4; $$->x = $4;
$$->y = $6; $$->y = $6;
$$->n_refs = 0; $$->n_refs = 0;
@ -367,6 +365,7 @@ base:
yyerrorf(". without predecessor"); yyerrorf(". without predecessor");
YYABORT; YYABORT;
} }
$$->n_refs++;
} }
| ID | ID
{ {
@ -375,6 +374,7 @@ base:
yyerrorf("unknown vector \"%s\"", $1); yyerrorf("unknown vector \"%s\"", $1);
YYABORT; YYABORT;
} }
$$->n_refs++;
} }
; ;
@ -405,7 +405,7 @@ obj:
$$ = new_obj(ot_arc); $$ = new_obj(ot_arc);
$$->base = $2; $$->base = $2;
$$->u.arc.start = $3; $$->u.arc.start = $3;
$$->u.arc.end = $3; $$->u.arc.end = get_vec($3);
$$->u.arc.width = $4; $$->u.arc.width = $4;
} }
| TOK_ARC base base base opt_expr | TOK_ARC base base base opt_expr

47
gui.c
View File

@ -88,7 +88,7 @@ static int find_var_in_frame(const struct frame *frame, const char *name)
for (loop = frame->loops; loop; loop = loop->next) for (loop = frame->loops; loop; loop = loop->next)
if (!strcmp(loop->var.name, name)) if (!strcmp(loop->var.name, name))
return 1; return 1;
return 0; return 0;
} }
@ -106,14 +106,14 @@ static void unselect_var(void *data)
{ {
struct var *var = data; struct var *var = data;
label_in_box_bg(var->widget, COLOR_VAR_PASSIVE); label_in_box_bg(var->widget, COLOR_VAR_PASSIVE);
} }
static void edit_var(struct var *var) static void edit_var(struct var *var)
{ {
inst_select_outside(var, unselect_var); inst_select_outside(var, unselect_var);
label_in_box_bg(var->widget, COLOR_VAR_EDITING); label_in_box_bg(var->widget, COLOR_VAR_EDITING);
status_set_type_entry("name ="); status_set_type_entry("name =");
status_set_name(var->name); status_set_name(var->name);
edit_unique(&var->name, validate_var_name, var); edit_unique(&var->name, validate_var_name, var);
@ -127,7 +127,7 @@ static void unselect_value(void *data)
{ {
struct value *value = data; struct value *value = data;
label_in_box_bg(value->widget, label_in_box_bg(value->widget,
value->row && value->row->table->active_row == value->row ? value->row && value->row->table->active_row == value->row ?
COLOR_CHOICE_SELECTED : COLOR_EXPR_PASSIVE); COLOR_CHOICE_SELECTED : COLOR_EXPR_PASSIVE);
} }
@ -136,7 +136,7 @@ static void unselect_value(void *data)
static void edit_value(struct value *value) static void edit_value(struct value *value)
{ {
inst_select_outside(value, unselect_value); inst_select_outside(value, unselect_value);
label_in_box_bg(value->widget, COLOR_EXPR_EDITING); label_in_box_bg(value->widget, COLOR_EXPR_EDITING);
edit_expr(&value->expr); edit_expr(&value->expr);
} }
@ -172,7 +172,7 @@ static GtkWidget *add_activator(GtkWidget *hbox, int active,
static gboolean assignment_var_select_event(GtkWidget *widget, static gboolean assignment_var_select_event(GtkWidget *widget,
GdkEventButton *event, gpointer data) GdkEventButton *event, gpointer data)
{ {
edit_var(data); edit_var(data);
return TRUE; return TRUE;
@ -180,7 +180,7 @@ static gboolean assignment_var_select_event(GtkWidget *widget,
static gboolean assignment_value_select_event(GtkWidget *widget, static gboolean assignment_value_select_event(GtkWidget *widget,
GdkEventButton *event, gpointer data) GdkEventButton *event, gpointer data)
{ {
edit_value(data); edit_value(data);
return TRUE; return TRUE;
@ -188,7 +188,7 @@ static gboolean assignment_value_select_event(GtkWidget *widget,
static void build_assignment(GtkWidget *vbox, struct frame *frame, static void build_assignment(GtkWidget *vbox, struct frame *frame,
struct table *table) struct table *table)
{ {
GtkWidget *hbox, *field; GtkWidget *hbox, *field;
char *expr; char *expr;
@ -241,7 +241,7 @@ static void select_row(struct row *row)
static gboolean table_var_select_event(GtkWidget *widget, static gboolean table_var_select_event(GtkWidget *widget,
GdkEventButton *event, gpointer data) GdkEventButton *event, gpointer data)
{ {
edit_var(data); edit_var(data);
return TRUE; return TRUE;
@ -249,7 +249,7 @@ static gboolean table_var_select_event(GtkWidget *widget,
static gboolean table_value_select_event(GtkWidget *widget, static gboolean table_value_select_event(GtkWidget *widget,
GdkEventButton *event, gpointer data) GdkEventButton *event, gpointer data)
{ {
struct value *value = data; struct value *value = data;
@ -264,7 +264,7 @@ static gboolean table_value_select_event(GtkWidget *widget,
static void build_table(GtkWidget *vbox, struct frame *frame, static void build_table(GtkWidget *vbox, struct frame *frame,
struct table *table) struct table *table)
{ {
GtkWidget *tab, *field; GtkWidget *tab, *field;
GtkWidget *evbox; GtkWidget *evbox;
@ -290,7 +290,7 @@ static void build_table(GtkWidget *vbox, struct frame *frame,
gtk_container_add(GTK_CONTAINER(evbox), tab); gtk_container_add(GTK_CONTAINER(evbox), tab);
col = get_color(COLOR_VAR_TABLE_SEP); col = get_color(COLOR_VAR_TABLE_SEP);
gtk_widget_modify_bg(GTK_WIDGET(evbox), gtk_widget_modify_bg(GTK_WIDGET(evbox),
GTK_STATE_NORMAL, &col); GTK_STATE_NORMAL, &col);
gtk_table_set_row_spacings(GTK_TABLE(tab), 1); gtk_table_set_row_spacings(GTK_TABLE(tab), 1);
gtk_table_set_col_spacings(GTK_TABLE(tab), 1); gtk_table_set_col_spacings(GTK_TABLE(tab), 1);
@ -335,7 +335,7 @@ static void build_table(GtkWidget *vbox, struct frame *frame,
static gboolean loop_var_select_event(GtkWidget *widget, static gboolean loop_var_select_event(GtkWidget *widget,
GdkEventButton *event, gpointer data) GdkEventButton *event, gpointer data)
{ {
struct loop *loop = data; struct loop *loop = data;
@ -345,7 +345,7 @@ static gboolean loop_var_select_event(GtkWidget *widget,
static gboolean loop_from_select_event(GtkWidget *widget, static gboolean loop_from_select_event(GtkWidget *widget,
GdkEventButton *event, gpointer data) GdkEventButton *event, gpointer data)
{ {
struct loop *loop = data; struct loop *loop = data;
@ -355,7 +355,7 @@ static gboolean loop_from_select_event(GtkWidget *widget,
static gboolean loop_to_select_event(GtkWidget *widget, static gboolean loop_to_select_event(GtkWidget *widget,
GdkEventButton *event, gpointer data) GdkEventButton *event, gpointer data)
{ {
struct loop *loop = data; struct loop *loop = data;
@ -365,7 +365,7 @@ static gboolean loop_to_select_event(GtkWidget *widget,
static gboolean loop_select_event(GtkWidget *widget, GdkEventButton *event, static gboolean loop_select_event(GtkWidget *widget, GdkEventButton *event,
gpointer data) gpointer data)
{ {
struct loop *loop = data; struct loop *loop = data;
@ -376,7 +376,7 @@ static gboolean loop_select_event(GtkWidget *widget, GdkEventButton *event,
static void build_loop(GtkWidget *vbox, struct frame *frame, static void build_loop(GtkWidget *vbox, struct frame *frame,
struct loop *loop) struct loop *loop)
{ {
GtkWidget *hbox, *field, *label; GtkWidget *hbox, *field, *label;
char *expr; char *expr;
@ -484,7 +484,7 @@ static void unselect_frame(void *data)
* change here doesn't matter if selecting a different frame.) * change here doesn't matter if selecting a different frame.)
* So we revert from "editing" to "selected". * So we revert from "editing" to "selected".
*/ */
label_in_box_bg(frame->label, COLOR_FRAME_SELECTED); label_in_box_bg(frame->label, COLOR_FRAME_SELECTED);
} }
@ -508,7 +508,7 @@ static void select_frame(struct frame *frame)
static gboolean frame_select_event(GtkWidget *widget, GdkEventButton *event, static gboolean frame_select_event(GtkWidget *widget, GdkEventButton *event,
gpointer data) gpointer data)
{ {
if (active_frame != data) if (active_frame != data)
select_frame(data); select_frame(data);
@ -543,7 +543,7 @@ static GtkWidget *build_frame_label(struct frame *frame)
static gboolean frame_ref_select_event(GtkWidget *widget, GdkEventButton *event, static gboolean frame_ref_select_event(GtkWidget *widget, GdkEventButton *event,
gpointer data) gpointer data)
{ {
struct obj *obj = data; struct obj *obj = data;
@ -591,13 +591,13 @@ static void build_frames(GtkWidget *vbox)
for (frame = root_frame; frame; frame = frame->prev) { for (frame = root_frame; frame; frame = frame->prev) {
label = build_frame_label(frame); label = build_frame_label(frame);
gtk_table_attach_defaults(GTK_TABLE(tab), label, gtk_table_attach_defaults(GTK_TABLE(tab), label,
0, 1, n*2, n*2+1); 0, 1, n*2, n*2+1);
refs = build_frame_refs(frame); refs = build_frame_refs(frame);
gtk_table_attach_defaults(GTK_TABLE(tab), refs, gtk_table_attach_defaults(GTK_TABLE(tab), refs,
1, 2, n*2, n*2+1); 1, 2, n*2, n*2+1);
vars = build_vars(frame); vars = build_vars(frame);
gtk_table_attach_defaults(GTK_TABLE(tab), vars, gtk_table_attach_defaults(GTK_TABLE(tab), vars,
1, 2, n*2+1, n*2+2); 1, 2, n*2+1, n*2+2);
n++; n++;
} }
gtk_widget_show_all(tab); gtk_widget_show_all(tab);
@ -648,6 +648,7 @@ static void make_center_area(GtkWidget *vbox)
void change_world(void) void change_world(void)
{ {
tool_reset();
inst_deselect(); inst_deselect();
status_begin_reporting(); status_begin_reporting();
instantiate(); instantiate();

View File

@ -19,6 +19,7 @@
#include "gui_inst.h" #include "gui_inst.h"
#include "gui_style.h" #include "gui_style.h"
#include "gui_status.h" #include "gui_status.h"
#include "gui_tools.h"
#include "gui.h" #include "gui.h"
#include "gui_canvas.h" #include "gui_canvas.h"
@ -27,6 +28,9 @@ static struct draw_ctx ctx;
static struct coord curr_pos; static struct coord curr_pos;
static struct coord user_origin = { 0, 0 }; static struct coord user_origin = { 0, 0 };
static int dragging = 0;
static struct coord drag_start;
/* ----- status display ---------------------------------------------------- */ /* ----- status display ---------------------------------------------------- */
@ -105,6 +109,12 @@ void redraw(void)
static void drag_left(struct coord pos) static void drag_left(struct coord pos)
{ {
if (!dragging)
return;
if (hypot(pos.x-drag_start.x, pos.y-drag_start.y)/ctx.scale <
DRAG_MIN_R)
return;
tool_drag(&ctx, pos);
} }
@ -114,7 +124,7 @@ static void drag_middle(struct coord pos)
static gboolean motion_notify_event(GtkWidget *widget, GdkEventMotion *event, static gboolean motion_notify_event(GtkWidget *widget, GdkEventMotion *event,
gpointer data) gpointer data)
{ {
struct coord pos = canvas_to_coord(&ctx, event->x, event->y); struct coord pos = canvas_to_coord(&ctx, event->x, event->y);
@ -122,6 +132,8 @@ static gboolean motion_notify_event(GtkWidget *widget, GdkEventMotion *event,
curr_pos.y = event->y; curr_pos.y = event->y;
if (event->state & GDK_BUTTON1_MASK) if (event->state & GDK_BUTTON1_MASK)
drag_left(pos); drag_left(pos);
else
tool_hover(&ctx, pos);
if (event->state & GDK_BUTTON2_MASK) if (event->state & GDK_BUTTON2_MASK)
drag_middle(pos); drag_middle(pos);
update_pos(pos); update_pos(pos);
@ -133,13 +145,23 @@ static gboolean motion_notify_event(GtkWidget *widget, GdkEventMotion *event,
static gboolean button_press_event(GtkWidget *widget, GdkEventButton *event, static gboolean button_press_event(GtkWidget *widget, GdkEventButton *event,
gpointer data) gpointer data)
{ {
struct coord pos = canvas_to_coord(&ctx, event->x, event->y); struct coord pos = canvas_to_coord(&ctx, event->x, event->y);
const struct inst *prev; const struct inst *prev;
switch (event->button) { switch (event->button) {
case 1: case 1:
if (dragging) {
fprintf(stderr, "HUH ?!?\n");
tool_cancel_drag(&ctx);
dragging = 0;
}
if (tool_consider_drag(&ctx, pos)) {
dragging = 1;
drag_start = pos;
break;
}
prev = selected_inst; prev = selected_inst;
inst_deselect(); inst_deselect();
inst_select(&ctx, pos); inst_select(&ctx, pos);
@ -156,8 +178,20 @@ static gboolean button_press_event(GtkWidget *widget, GdkEventButton *event,
static gboolean button_release_event(GtkWidget *widget, GdkEventButton *event, static gboolean button_release_event(GtkWidget *widget, GdkEventButton *event,
gpointer data) gpointer data)
{ {
struct coord pos = canvas_to_coord(&ctx, event->x, event->y);
if (dragging) {
dragging = 0;
if (hypot(pos.x-drag_start.x, pos.y-drag_start.y)/ctx.scale <
DRAG_MIN_R)
tool_cancel_drag(&ctx);
else {
if (tool_end_drag(&ctx, pos))
change_world();
}
}
return TRUE; return TRUE;
} }
@ -197,7 +231,7 @@ static void zoom_out(struct coord pos)
static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event, static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event,
gpointer data) gpointer data)
{ {
struct coord pos = canvas_to_coord(&ctx, event->x, event->y); struct coord pos = canvas_to_coord(&ctx, event->x, event->y);
@ -219,7 +253,7 @@ static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event,
static gboolean key_press_event(GtkWidget *widget, GdkEventKey *event, static gboolean key_press_event(GtkWidget *widget, GdkEventKey *event,
gpointer data) gpointer data)
{ {
struct coord pos = canvas_to_coord(&ctx, curr_pos.x, curr_pos.y); struct coord pos = canvas_to_coord(&ctx, curr_pos.x, curr_pos.y);
@ -258,7 +292,7 @@ static gboolean key_press_event(GtkWidget *widget, GdkEventKey *event,
static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event,
gpointer data) gpointer data)
{ {
static int first = 1; static int first = 1;
if (first) { if (first) {
@ -274,7 +308,7 @@ static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event,
static gboolean enter_notify_event(GtkWidget *widget, GdkEventCrossing *event, static gboolean enter_notify_event(GtkWidget *widget, GdkEventCrossing *event,
gpointer data) gpointer data)
{ {
gtk_widget_grab_focus(widget); gtk_widget_grab_focus(widget);
return TRUE; return TRUE;
@ -282,8 +316,12 @@ static gboolean enter_notify_event(GtkWidget *widget, GdkEventCrossing *event,
static gboolean leave_notify_event(GtkWidget *widget, GdkEventCrossing *event, static gboolean leave_notify_event(GtkWidget *widget, GdkEventCrossing *event,
gpointer data) gpointer data)
{ {
if (dragging)
tool_cancel_drag(&ctx);
tool_dehover(&ctx);
dragging = 0;
return TRUE; return TRUE;
} }

View File

@ -49,9 +49,9 @@ struct coord canvas_to_coord(const struct draw_ctx *ctx, int x, int y)
x -= ctx->widget->allocation.width/2; x -= ctx->widget->allocation.width/2;
y -= ctx->widget->allocation.height/2; y -= ctx->widget->allocation.height/2;
y = -y; y = -y;
pos.x = x*ctx->scale+ctx->center.x; pos.x = x*ctx->scale+ctx->center.x;
pos.y = y*ctx->scale+ctx->center.y; pos.y = y*ctx->scale+ctx->center.y;
return pos; return pos;
} }
@ -59,27 +59,11 @@ struct coord canvas_to_coord(const struct draw_ctx *ctx, int x, int y)
/* ----- drawing primitives ------------------------------------------------ */ /* ----- drawing primitives ------------------------------------------------ */
static void draw_arc(struct draw_ctx *ctx, GdkGC *gc, int fill,
int x, int y, int r, double a1, double a2)
{
if (a1 == a2)
a2 = a1+360;
gdk_draw_arc(DA, gc, fill, x-r, y-r, 2*r, 2*r, a1*64, (a2-a1)*64);
}
static void draw_circle(struct draw_ctx *ctx, GdkGC *gc, int fill,
int x, int y, int r)
{
draw_arc(ctx, gc, fill, x, y, r, 0, 360);
}
static void draw_eye(struct draw_ctx *ctx, GdkGC *gc, struct coord center, static void draw_eye(struct draw_ctx *ctx, GdkGC *gc, struct coord center,
int r1, int r2) int r1, int r2)
{ {
draw_circle(ctx, gc, TRUE, center.x, center.y, r1); draw_circle(DA, gc, TRUE, center.x, center.y, r1);
draw_circle(ctx, gc, FALSE, center.x, center.y, r2); draw_circle(DA, gc, FALSE, center.x, center.y, r2);
} }
@ -159,6 +143,16 @@ unit_type gui_dist_vec_fallback(struct inst *self, struct coord pos,
} }
void gui_hover_vec(struct inst *self, struct draw_ctx *ctx)
{
struct coord center = translate(ctx, self->u.rect.end);
GdkGC *gc;
gc = gc_vec[mode_hover];
draw_circle(DA, gc, FALSE, center.x, center.y, VEC_EYE_R);
}
void gui_draw_vec(struct inst *self, struct draw_ctx *ctx) void gui_draw_vec(struct inst *self, struct draw_ctx *ctx)
{ {
struct coord from = translate(ctx, self->base); struct coord from = translate(ctx, self->base);
@ -168,7 +162,7 @@ void gui_draw_vec(struct inst *self, struct draw_ctx *ctx)
gc = gc_vec[get_mode(self)]; gc = gc_vec[get_mode(self)];
draw_arrow(ctx, gc, TRUE, from, to, VEC_ARROW_LEN, VEC_ARROW_ANGLE); draw_arrow(ctx, gc, TRUE, from, to, VEC_ARROW_LEN, VEC_ARROW_ANGLE);
gdk_draw_line(DA, gc, from.x, from.y, to.x, to.y); gdk_draw_line(DA, gc, from.x, from.y, to.x, to.y);
draw_circle(ctx, gc, FALSE, to.x, to.y, VEC_EYE_R); draw_circle(DA, gc, FALSE, to.x, to.y, VEC_EYE_R);
} }
@ -295,8 +289,8 @@ unit_type gui_dist_arc(struct inst *self, struct coord pos, unit_type scale)
p = rotate_r(c, self->u.arc.r, self->u.arc.a2); p = rotate_r(c, self->u.arc.r, self->u.arc.a2);
d = hypot(pos.x-p.x, pos.y-p.y); d = hypot(pos.x-p.x, pos.y-p.y);
if (d < d_min) if (d < d_min)
d_min = d; d_min = d;
if (d_min/scale <= r) if (d_min/scale <= r)
return d; return d;
@ -328,7 +322,7 @@ void gui_draw_arc(struct inst *self, struct draw_ctx *ctx)
gc = gc_obj[get_mode(self)]; gc = gc_obj[get_mode(self)];
set_width(gc, self->u.arc.width/ctx->scale); set_width(gc, self->u.arc.width/ctx->scale);
draw_arc(ctx, gc, FALSE, center.x, center.y, draw_arc(DA, gc, FALSE, center.x, center.y,
self->u.arc.r/ctx->scale, self->u.arc.a1, self->u.arc.a2); self->u.arc.r/ctx->scale, self->u.arc.a1, self->u.arc.a2);
} }
@ -399,6 +393,25 @@ void gui_draw_meas(struct inst *self, struct draw_ctx *ctx)
/* ----- frame ------------------------------------------------------------- */ /* ----- frame ------------------------------------------------------------- */
unit_type gui_dist_frame(struct inst *self, struct coord pos, unit_type scale)
{
unit_type d;
d = dist_point(pos, self->base)/scale;
return d > FRAME_EYE_R2 ? -1 : d;
}
void gui_hover_frame(struct inst *self, struct draw_ctx *ctx)
{
struct coord center = translate(ctx, self->base);
GdkGC *gc;
gc = gc_frame[mode_hover];
draw_circle(DA, gc, FALSE, center.x, center.y, FRAME_EYE_R2);
}
void gui_draw_frame(struct inst *self, struct draw_ctx *ctx) void gui_draw_frame(struct inst *self, struct draw_ctx *ctx)
{ {
struct coord center = translate(ctx, self->base); struct coord center = translate(ctx, self->base);

View File

@ -38,6 +38,7 @@ unit_type gui_dist_rect(struct inst *self, struct coord pos, unit_type scale);
unit_type gui_dist_pad(struct inst *self, struct coord pos, unit_type scale); unit_type gui_dist_pad(struct inst *self, struct coord pos, unit_type scale);
unit_type gui_dist_arc(struct inst *self, struct coord pos, unit_type scale); unit_type gui_dist_arc(struct inst *self, struct coord pos, unit_type scale);
unit_type gui_dist_meas(struct inst *self, struct coord pos, unit_type scale); unit_type gui_dist_meas(struct inst *self, struct coord pos, unit_type scale);
unit_type gui_dist_frame(struct inst *self, struct coord pos, unit_type scale);
void gui_draw_vec(struct inst *self, struct draw_ctx *ctx); void gui_draw_vec(struct inst *self, struct draw_ctx *ctx);
void gui_draw_line(struct inst *self, struct draw_ctx *ctx); void gui_draw_line(struct inst *self, struct draw_ctx *ctx);
@ -47,4 +48,7 @@ void gui_draw_arc(struct inst *self, struct draw_ctx *ctx);
void gui_draw_meas(struct inst *self, struct draw_ctx *ctx); void gui_draw_meas(struct inst *self, struct draw_ctx *ctx);
void gui_draw_frame(struct inst *self, struct draw_ctx *ctx); void gui_draw_frame(struct inst *self, struct draw_ctx *ctx);
void gui_hover_vec(struct inst *self, struct draw_ctx *ctx);
void gui_hover_frame(struct inst *self, struct draw_ctx *ctx);
#endif /* !GUI_INST_H */ #endif /* !GUI_INST_H */

View File

@ -367,7 +367,7 @@ void edit_y(struct expr **expr)
static gboolean changed(GtkWidget *widget, GdkEventMotion *event, static gboolean changed(GtkWidget *widget, GdkEventMotion *event,
gpointer data) gpointer data)
{ {
struct edit_ops *ops = struct edit_ops *ops =
gtk_object_get_data(GTK_OBJECT(widget), "edit-ops"); gtk_object_get_data(GTK_OBJECT(widget), "edit-ops");
@ -381,7 +381,7 @@ static gboolean changed(GtkWidget *widget, GdkEventMotion *event,
static gboolean activate(GtkWidget *widget, GdkEventMotion *event, static gboolean activate(GtkWidget *widget, GdkEventMotion *event,
gpointer data) gpointer data)
{ {
struct edit_ops *ops = struct edit_ops *ops =
gtk_object_get_data(GTK_OBJECT(widget), "edit-ops"); gtk_object_get_data(GTK_OBJECT(widget), "edit-ops");
@ -462,9 +462,9 @@ static GtkWidget *add_entry(GtkWidget *tab, int col, int row)
col, col+1, row, row+1); col, col+1, row, row+1);
g_signal_connect(G_OBJECT(entry), "changed", g_signal_connect(G_OBJECT(entry), "changed",
G_CALLBACK(changed), entry); G_CALLBACK(changed), entry);
g_signal_connect(G_OBJECT(entry), "activate", g_signal_connect(G_OBJECT(entry), "activate",
G_CALLBACK(activate), entry); G_CALLBACK(activate), entry);
return entry; return entry;
} }

View File

@ -23,6 +23,7 @@
GdkGC *gc_bg; GdkGC *gc_bg;
GdkGC *gc_drag;
GdkGC *gc_vec[mode_n]; GdkGC *gc_vec[mode_n];
GdkGC *gc_obj[mode_n]; GdkGC *gc_obj[mode_n];
GdkGC *gc_pad[mode_n]; GdkGC *gc_pad[mode_n];
@ -59,6 +60,7 @@ static void style(GdkGC *gcs[mode_n],
void gui_setup_style(GdkDrawable *drawable) void gui_setup_style(GdkDrawable *drawable)
{ {
gc_bg = gc("#000000", 0); gc_bg = gc("#000000", 0);
gc_drag = gc("#ffffff", 2);
/* inactive in+path active act+path selected */ /* inactive in+path active act+path selected */
style(gc_vec, "#202000", "#404020", "#909040", "#c0c080", "#ffff80"); style(gc_vec, "#202000", "#404020", "#909040", "#c0c080", "#ffff80");
style(gc_obj, "#006060", INVALID, "#00ffff", INVALID, "#ffff80"); style(gc_obj, "#006060", INVALID, "#00ffff", INVALID, "#ffff80");
@ -66,4 +68,6 @@ void gui_setup_style(GdkDrawable *drawable)
style(gc_ptext, "#404040", INVALID, "#ffffff", INVALID, "#ffffff"); style(gc_ptext, "#404040", INVALID, "#ffffff", INVALID, "#ffffff");
style(gc_meas, "#280040", INVALID, "#ff00ff", INVALID, "#ffff80"); style(gc_meas, "#280040", INVALID, "#ff00ff", INVALID, "#ffff80");
style(gc_frame, "#004000", "#205020", "#00ff00", INVALID, INVALID); style(gc_frame, "#004000", "#205020", "#00ff00", INVALID, INVALID);
gc_frame[mode_hover] = gc_vec[mode_hover] = gc("#c00000", 1);
} }

View File

@ -46,6 +46,8 @@
#define SELECT_R 6 /* pixels within which we select */ #define SELECT_R 6 /* pixels within which we select */
#define DRAG_MIN_R 5
#define MIN_FONT_SCALE 0.20 /* don't scale fonts below this */ #define MIN_FONT_SCALE 0.20 /* don't scale fonts below this */
@ -73,11 +75,15 @@
#define COLOR_VAR_TABLE_SEP "black" #define COLOR_VAR_TABLE_SEP "black"
#define TOOL_UNSELECTED "#dcdad5"
#define TOOL_SELECTED "red"
/* ----- canvas drawing styles --------------------------------------------- */ /* ----- canvas drawing styles --------------------------------------------- */
extern GdkGC *gc_bg; extern GdkGC *gc_bg;
extern GdkGC *gc_drag;
extern GdkGC *gc_vec[mode_n]; extern GdkGC *gc_vec[mode_n];
extern GdkGC *gc_obj[mode_n]; extern GdkGC *gc_obj[mode_n];
extern GdkGC *gc_pad[mode_n]; extern GdkGC *gc_pad[mode_n];

View File

@ -13,11 +13,15 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "util.h"
#include "inst.h"
#include "obj.h"
#include "gui_util.h" #include "gui_util.h"
#include "gui_style.h"
#include "gui_inst.h"
#include "gui_tools.h" #include "gui_tools.h"
#include "icons/arc.xpm"
#include "icons/circ.xpm" #include "icons/circ.xpm"
#include "icons/frame.xpm" #include "icons/frame.xpm"
#include "icons/line.xpm" #include "icons/line.xpm"
@ -28,13 +32,292 @@
#include "icons/vec.xpm" #include "icons/vec.xpm"
static GtkToolItem *tool_button(GtkWidget *bar, GdkDrawable *drawable, #define DA GDK_DRAWABLE(ctx->widget->window)
char **xpm, GtkToolItem *last)
struct tool_ops {
struct pix_buf *(*drag)(struct draw_ctx *ctx, struct inst *from,
struct coord to);
int (*end)(struct draw_ctx *ctx, struct inst *from, struct inst *to);
};
static GtkWidget *ev_point;
static GtkWidget *active_tool;
static struct tool_ops *active_ops = NULL;
static struct inst *hover_inst = NULL;
static struct inst *drag;
static struct pix_buf *pix_buf;
static struct tool_ops vec_ops;
static struct tool_ops frame_ops;
static struct tool_ops pad_ops;
static struct tool_ops circ_ops;
static struct tool_ops meas_ops;
static struct obj *new_obj(enum obj_type type, struct inst *base)
{
struct obj *obj, **walk;
obj = alloc_type(struct obj);
obj->type = type;
obj->base = inst_get_ref(base);
obj->next = NULL;
obj->lineno = 0;
for (walk = &active_frame->objs; *walk; walk = &(*walk)->next);
*walk = obj;
return obj;
}
/* ----- line -------------------------------------------------------------- */
static struct pix_buf *drag_new_line(struct draw_ctx *ctx,
struct inst *from, struct coord to)
{
struct coord pos;
struct pix_buf *buf;
pos = translate(ctx, inst_get_point(from));
to = translate(ctx, to);
buf = save_pix_buf(DA, pos.x, pos.y, to.x, to.y, 1);
gdk_draw_line(DA, gc_drag, pos.x, pos.y, to.x, to.y);
return buf;
}
static int end_new_line(struct draw_ctx *ctx,
struct inst *from, struct inst *to)
{
struct obj *obj;
if (from == to)
return 0;
obj = new_obj(ot_line, from);
obj->u.line.other = inst_get_ref(to);
obj->u.line.width = NULL;
return 1;
}
static struct tool_ops line_ops = {
.drag = drag_new_line,
.end = end_new_line,
};
/* ----- rect -------------------------------------------------------------- */
static void swap_coord(unit_type *a, unit_type *b)
{
unit_type tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
static struct pix_buf *drag_new_rect(struct draw_ctx *ctx,
struct inst *from, struct coord to)
{
struct coord pos;
struct pix_buf *buf;
pos = translate(ctx, inst_get_point(from));
to = translate(ctx, to);
if (pos.x > to.x)
swap_coord(&pos.x, &to.x);
if (pos.y > to.y)
swap_coord(&pos.y, &to.y);
buf = save_pix_buf(DA, pos.x, pos.y, to.x, to.y, 1);
gdk_draw_rectangle(DA, gc_drag, FALSE,
pos.x, pos.y, to.x-pos.x, to.y-pos.y);
return buf;
}
static int end_new_rect(struct draw_ctx *ctx,
struct inst *from, struct inst *to)
{
struct obj *obj;
if (from == to)
return 0;
obj = new_obj(ot_rect, from);
obj->u.rect.other = inst_get_ref(to);
obj->u.rect.width = NULL;
return 1;
}
static struct tool_ops rect_ops = {
.drag = drag_new_rect,
.end = end_new_rect,
};
/* ----- circ -------------------------------------------------------------- */
static struct pix_buf *drag_new_circ(struct draw_ctx *ctx,
struct inst *from, struct coord to)
{
struct coord pos;
struct pix_buf *buf;
double r;
pos = translate(ctx, inst_get_point(from));
to = translate(ctx, to);
r = hypot(to.x-pos.x, to.y-pos.y);
buf = save_pix_buf(DA, pos.x-r, pos.y-r, pos.x+r, pos.y+r, 1);
draw_circle(DA, gc_drag, FALSE, pos.x, pos.y, r);
return buf;
}
static int end_new_circ(struct draw_ctx *ctx,
struct inst *from, struct inst *to)
{
struct obj *obj;
if (from == to)
return 0;
obj = new_obj(ot_arc, from);
obj->u.arc.start = inst_get_ref(to);
obj->u.arc.end = inst_get_ref(to);
obj->u.arc.width = NULL;
return 1;
}
static struct tool_ops circ_ops = {
.drag = drag_new_circ,
.end = end_new_circ,
};
/* ----- mouse actions ----------------------------------------------------- */
void tool_dehover(struct draw_ctx *ctx)
{
if (hover_inst)
inst_hover(hover_inst, ctx, 0);
hover_inst = NULL;
}
void tool_hover(struct draw_ctx *ctx, struct coord pos)
{
struct inst *inst;
if (!active_ops)
return;
inst = inst_find_point(ctx, pos);
if (inst != hover_inst)
tool_dehover(ctx);
if (inst) {
inst_hover(inst, ctx, 1);
hover_inst = inst;
}
}
int tool_consider_drag(struct draw_ctx *ctx, struct coord pos)
{
if (!active_ops)
return 0;
drag = inst_find_point(ctx, pos);
if (!drag)
return 0;
pix_buf = NULL;
return 1;
}
void tool_drag(struct draw_ctx *ctx, struct coord to)
{
if (pix_buf)
restore_pix_buf(pix_buf);
tool_hover(ctx, to);
pix_buf = active_ops->drag(ctx, drag, to);
}
void tool_cancel_drag(struct draw_ctx *ctx)
{
tool_dehover(ctx);
tool_reset();
if (pix_buf)
restore_pix_buf(pix_buf);
drag = NULL;
active_ops = NULL;
}
int tool_end_drag(struct draw_ctx *ctx, struct coord to)
{
struct inst *from = drag;
struct inst *end;
struct tool_ops *ops = active_ops;
tool_cancel_drag(ctx);
end = inst_find_point(ctx, to);
if (end)
return ops->end(ctx, from, end);
return 0;
}
/* ----- tool bar creation ------------------------------------------------- */
static void tool_select(GtkWidget *evbox, struct tool_ops *ops)
{
GdkColor col;
if (active_tool) {
col = get_color(TOOL_UNSELECTED);
gtk_widget_modify_bg(active_tool, GTK_STATE_NORMAL, &col);
active_tool = NULL;
}
col = get_color(TOOL_SELECTED);
gtk_widget_modify_bg(evbox, GTK_STATE_NORMAL, &col);
active_tool = evbox;
active_ops = ops;
}
void tool_reset(void)
{
tool_select(ev_point, NULL);
}
static gboolean tool_button_press_event(GtkWidget *widget,
GdkEventButton *event, gpointer data)
{
tool_select(widget, data);
return TRUE;
}
static GtkWidget *tool_button(GtkWidget *bar, GdkDrawable *drawable,
char **xpm, GtkWidget *last_evbox, struct tool_ops *ops)
{ {
GdkPixmap *pixmap; GdkPixmap *pixmap;
GtkWidget *image; GtkWidget *image, *evbox;
GtkToolItem *item; GtkToolItem *item;
GtkToolItem *last = NULL;
if (last_evbox)
last = GTK_TOOL_ITEM(gtk_widget_get_ancestor(last_evbox,
GTK_TYPE_TOOL_ITEM));
pixmap = gdk_pixmap_create_from_xpm_d(drawable, NULL, NULL, xpm); pixmap = gdk_pixmap_create_from_xpm_d(drawable, NULL, NULL, xpm);
image = gtk_image_new_from_pixmap(pixmap, NULL); image = gtk_image_new_from_pixmap(pixmap, NULL);
@ -50,38 +333,44 @@ static GtkToolItem *tool_button(GtkWidget *bar, GdkDrawable *drawable,
item = gtk_radio_tool_button_new(NULL); item = gtk_radio_tool_button_new(NULL);
gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(item), image); gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(item), image);
#else #else
item = gtk_tool_item_new(); evbox = gtk_event_box_new();
gtk_container_add(GTK_CONTAINER(item), image); gtk_misc_set_padding(GTK_MISC(image), 1, 1);
gtk_container_add(GTK_CONTAINER(evbox), image);
g_signal_connect(G_OBJECT(evbox), "button_press_event",
G_CALLBACK(tool_button_press_event), ops);
gtk_container_set_border_width(GTK_CONTAINER(item), 1); item = gtk_tool_item_new();
gtk_container_add(GTK_CONTAINER(item), evbox);
gtk_container_set_border_width(GTK_CONTAINER(item), 0);
#endif #endif
gtk_toolbar_insert(GTK_TOOLBAR(bar), item, -1); gtk_toolbar_insert(GTK_TOOLBAR(bar), item, -1);
return item; return evbox;
} }
GtkWidget *gui_setup_tools(GdkDrawable *drawable) GtkWidget *gui_setup_tools(GdkDrawable *drawable)
{ {
GtkWidget *bar; GtkWidget *bar;
GtkToolItem *last; GtkWidget *last;
bar = gtk_toolbar_new(); bar = gtk_toolbar_new();
gtk_toolbar_set_style(GTK_TOOLBAR(bar), GTK_TOOLBAR_ICONS); gtk_toolbar_set_style(GTK_TOOLBAR(bar), GTK_TOOLBAR_ICONS);
gtk_toolbar_set_orientation(GTK_TOOLBAR(bar), gtk_toolbar_set_orientation(GTK_TOOLBAR(bar),
GTK_ORIENTATION_VERTICAL); GTK_ORIENTATION_VERTICAL);
//gtk_container_set_border_width(GTK_CONTAINER(bar), 5);
last = tool_button(bar, drawable, xpm_point, NULL); ev_point = tool_button(bar, drawable, xpm_point, NULL, NULL);
last = tool_button(bar, drawable, xpm_vec, last); last = tool_button(bar, drawable, xpm_vec, ev_point, &vec_ops);
last = tool_button(bar, drawable, xpm_frame, last); last = tool_button(bar, drawable, xpm_frame, last, &frame_ops);
last = tool_button(bar, drawable, xpm_pad, last); last = tool_button(bar, drawable, xpm_pad, last, &pad_ops);
last = tool_button(bar, drawable, xpm_line, last); last = tool_button(bar, drawable, xpm_line, last, &line_ops);
last = tool_button(bar, drawable, xpm_rect, last); last = tool_button(bar, drawable, xpm_rect, last, &rect_ops);
last = tool_button(bar, drawable, xpm_circ, last); last = tool_button(bar, drawable, xpm_circ, last, &circ_ops);
last = tool_button(bar, drawable, xpm_arc, last); last = tool_button(bar, drawable, xpm_meas, last, &meas_ops);
last = tool_button(bar, drawable, xpm_meas, last);
tool_reset();
return bar; return bar;
} }

View File

@ -16,6 +16,17 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "inst.h"
void tool_dehover(struct draw_ctx *ctx);
void tool_hover(struct draw_ctx *ctx, struct coord pos);
int tool_consider_drag(struct draw_ctx *ctx, struct coord pos);
void tool_drag(struct draw_ctx *ctx, struct coord to);
void tool_cancel_drag(struct draw_ctx *ctx);
int tool_end_drag(struct draw_ctx *ctx, struct coord to);
void tool_reset(void);
GtkWidget *gui_setup_tools(GdkDrawable *drawable); GtkWidget *gui_setup_tools(GdkDrawable *drawable);

View File

@ -15,6 +15,7 @@
#include <math.h> #include <math.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "util.h"
#include "gui_style.h" #include "gui_style.h"
#include "gui.h" #include "gui.h"
#include "gui_util.h" #include "gui_util.h"
@ -47,6 +48,74 @@ void set_width(GdkGC *gc, int width)
} }
/* ----- backing store ----------------------------------------------------- */
struct pix_buf *save_pix_buf(GdkDrawable *da, int xa, int ya, int xb, int yb,
int border)
{
struct pix_buf *buf;
int tmp;
int w, h;
if (xa > xb) {
tmp = xa;
xa = xb;
xb = tmp;
}
if (ya > yb) {
tmp = ya;
ya = yb;
yb = tmp;
}
buf = alloc_type(struct pix_buf);
buf->da = da;
buf->x = xa-border;
buf->y = ya-border;
w = xb-xa+1+2*border;
h = yb-ya+1+2*border;
if (buf->x < 0) {
w += buf->x;
buf->x = 0;
}
if (buf->y < 0) {
w += buf->y;
buf->y = 0;
}
buf->buf = gdk_pixbuf_get_from_drawable(NULL, da, NULL,
buf->x, buf->y, 0, 0, w, h);
return buf;
}
void restore_pix_buf(struct pix_buf *buf)
{
gdk_draw_pixbuf(buf->da, NULL, buf->buf, 0, 0, buf->x, buf->y, -1, -1,
GDK_RGB_DITHER_NORMAL, 0, 0);
g_object_unref(G_OBJECT(buf->buf));
free(buf);
}
/* ----- arcs and circles -------------------------------------------------- */
void draw_arc(GdkDrawable *da, GdkGC *gc, int fill,
int x, int y, int r, double a1, double a2)
{
if (a1 == a2)
a2 = a1+360;
gdk_draw_arc(da, gc, fill, x-r, y-r, 2*r, 2*r, a1*64, (a2-a1)*64);
}
void draw_circle(GdkDrawable *da, GdkGC *gc, int fill,
int x, int y, int r)
{
draw_arc(da, gc, fill, x, y, r, 0, 360);
}
/* ----- labels in a box --------------------------------------------------- */ /* ----- labels in a box --------------------------------------------------- */

View File

@ -17,10 +17,26 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
struct pix_buf {
GdkDrawable *da;
int x, y;
GdkPixbuf *buf;
};
GdkColor get_color(const char *spec); GdkColor get_color(const char *spec);
void set_width(GdkGC *gc, int width); void set_width(GdkGC *gc, int width);
struct pix_buf *save_pix_buf(GdkDrawable *da, int xa, int ya, int xb, int yb,
int border);
void restore_pix_buf(struct pix_buf *buf);
void draw_arc(GdkDrawable *da, GdkGC *gc, int fill,
int x, int y, int r, double a1, double a2);
void draw_circle(GdkDrawable *da, GdkGC *gc, int fill,
int x, int y, int r);
GtkWidget *label_in_box_new(const char *s); GtkWidget *label_in_box_new(const char *s);
GtkWidget *box_of_label(GtkWidget *label); GtkWidget *box_of_label(GtkWidget *label);
void label_in_box_bg(GtkWidget *box, const char *color); void label_in_box_bg(GtkWidget *box, const char *color);

71
inst.c
View File

@ -20,6 +20,7 @@
#include "expr.h" #include "expr.h"
#include "obj.h" #include "obj.h"
#include "gui_status.h" #include "gui_status.h"
#include "gui_status.h"
#include "gui_inst.h" #include "gui_inst.h"
#include "inst.h" #include "inst.h"
@ -28,8 +29,9 @@ struct inst_ops {
void (*debug)(struct inst *self); void (*debug)(struct inst *self);
void (*save)(FILE *file, struct inst *self); void (*save)(FILE *file, struct inst *self);
void (*draw)(struct inst *self, struct draw_ctx *ctx); void (*draw)(struct inst *self, struct draw_ctx *ctx);
void (*hover)(struct inst *self, struct draw_ctx *ctx);
unit_type (*distance)(struct inst *self, struct coord pos, unit_type (*distance)(struct inst *self, struct coord pos,
unit_type scale); unit_type scale);
void (*select)(struct inst *self); void (*select)(struct inst *self);
}; };
@ -169,6 +171,60 @@ selected:
} }
struct inst *inst_find_point(const struct draw_ctx *ctx, struct coord pos)
{
struct inst *inst, *found;
int best_dist = 0; /* keep gcc happy */
int dist;
found = NULL;
for (inst = insts[ip_frame]; inst; inst = inst->next) {
if (!inst->active || !inst->ops->distance)
continue;
dist = inst->ops->distance(inst, pos, ctx->scale);
if (dist >= 0 && (!found || best_dist > dist)) {
found = inst;
best_dist = dist;
}
}
if (found)
return found;
for (inst = insts[ip_vec]; inst; inst = inst->next) {
if (!inst->active || !inst->ops->distance)
continue;
dist = inst->ops->distance(inst, pos, ctx->scale);
if (dist >= 0 && (!found || best_dist > dist)) {
found = inst;
best_dist = dist;
}
}
return found;
}
struct coord inst_get_point(const struct inst *inst)
{
if (inst->ops == &vec_ops)
return inst->u.rect.end;
if (inst->ops == &frame_ops)
return inst->base;
abort();
}
struct vec *inst_get_ref(const struct inst *inst)
{
if (inst->ops == &vec_ops) {
inst->vec->n_refs++;
return inst->vec;
}
if (inst->ops == &frame_ops)
return NULL;
abort();
}
void inst_deselect(void) void inst_deselect(void)
{ {
if (selected_inst) if (selected_inst)
@ -298,6 +354,7 @@ static void vec_op_select(struct inst *self)
static struct inst_ops vec_ops = { static struct inst_ops vec_ops = {
.debug = vec_op_debug, .debug = vec_op_debug,
.draw = gui_draw_vec, .draw = gui_draw_vec,
.hover = gui_hover_vec,
.distance = gui_dist_vec, .distance = gui_dist_vec,
.select = vec_op_select, .select = vec_op_select,
}; };
@ -586,6 +643,7 @@ static void frame_op_debug(struct inst *self)
static struct inst_ops frame_ops = { static struct inst_ops frame_ops = {
.debug = frame_op_debug, .debug = frame_op_debug,
.draw = gui_draw_frame, .draw = gui_draw_frame,
.hover = gui_hover_frame,
}; };
@ -685,6 +743,17 @@ void inst_draw(struct draw_ctx *ctx)
} }
void inst_hover(struct inst *inst, struct draw_ctx *ctx, int on)
{
if (!inst->ops->hover)
return;
if (on)
inst->ops->hover(inst, ctx);
else
inst->ops->draw(inst, ctx);
}
void inst_debug(void) void inst_debug(void)
{ {
enum inst_prio prio; enum inst_prio prio;

6
inst.h
View File

@ -26,6 +26,7 @@ enum mode {
mode_active, /* on active frame */ mode_active, /* on active frame */
mode_active_in_path, /* active and is in path to selected */ mode_active_in_path, /* active and is in path to selected */
mode_selected, /* item is selected */ mode_selected, /* item is selected */
mode_hover, /* hovering over item's contact area */
mode_n /* number of modes */ mode_n /* number of modes */
}; };
@ -78,6 +79,10 @@ void inst_select_outside(void *item, void (*deselect)(void *item));
int inst_select(const struct draw_ctx *ctx, struct coord pos); int inst_select(const struct draw_ctx *ctx, struct coord pos);
void inst_deselect(void); void inst_deselect(void);
struct inst *inst_find_point(const struct draw_ctx *ctx, struct coord pos);
struct coord inst_get_point(const struct inst *inst);
struct vec *inst_get_ref(const struct inst *inst);
int inst_vec(struct vec *vec, struct coord base); int inst_vec(struct vec *vec, struct coord base);
int inst_line(struct obj *obj, struct coord a, struct coord b, unit_type width); int inst_line(struct obj *obj, struct coord a, struct coord b, unit_type width);
int inst_rect(struct obj *obj, struct coord a, struct coord b, unit_type width); int inst_rect(struct obj *obj, struct coord a, struct coord b, unit_type width);
@ -100,6 +105,7 @@ void inst_commit(void);
void inst_revert(void); void inst_revert(void);
void inst_draw(struct draw_ctx *ctx); void inst_draw(struct draw_ctx *ctx);
void inst_hover(struct inst *inst, struct draw_ctx *ctx, int on);
void inst_debug(void); void inst_debug(void);
#endif /* !INST_H */ #endif /* !INST_H */

8
obj.h
View File

@ -172,6 +172,14 @@ extern struct frame *root_frame;
extern struct frame *active_frame; extern struct frame *active_frame;
static inline struct vec *get_vec(struct vec *vec)
{
if (vec)
vec->n_refs++;
return vec;
}
int instantiate(void); int instantiate(void);
#endif /* !OBJ_H */ #endif /* !OBJ_H */