mirror of
git://projects.qi-hardware.com/fped.git
synced 2024-11-05 04:35:19 +02: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:
parent
0015f96f14
commit
5add8b5229
4
Makefile
4
Makefile
@ -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
4
README
@ -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
|
||||||
|
6
fpd.y
6
fpd.y
@ -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
|
||||||
|
1
gui.c
1
gui.c
@ -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();
|
||||||
|
38
gui_canvas.c
38
gui_canvas.c
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -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);
|
||||||
@ -140,6 +152,16 @@ static gboolean button_press_event(GtkWidget *widget, GdkEventButton *event,
|
|||||||
|
|
||||||
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);
|
||||||
@ -158,6 +180,18 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,6 +318,10 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
53
gui_inst.c
53
gui_inst.c
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -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);
|
||||||
|
@ -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 */
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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];
|
||||||
|
327
gui_tools.c
327
gui_tools.c
@ -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;
|
||||||
}
|
}
|
||||||
|
11
gui_tools.h
11
gui_tools.h
@ -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);
|
||||||
|
|
||||||
|
69
gui_util.c
69
gui_util.c
@ -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 --------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
16
gui_util.h
16
gui_util.h
@ -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);
|
||||||
|
69
inst.c
69
inst.c
@ -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,6 +29,7 @@ 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
6
inst.h
@ -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
8
obj.h
@ -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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user