From 2300a906764ad9d40c7f8dcb453c65db80a438da Mon Sep 17 00:00:00 2001 From: ellson Date: Sat, 30 Apr 2005 22:41:36 +0000 Subject: [PATCH] add a CLOSEENOUGH factor for mouse in objects add an OVERLAP macro --- lib/common/macros.h | 4 ++- lib/common/renderprocs.h | 2 ++ lib/common/utils.c | 21 ++++++---------- lib/gvc/gvevent.c | 54 +++++++++++++++++++++++++--------------- 4 files changed, 47 insertions(+), 34 deletions(-) diff --git a/lib/common/macros.h b/lib/common/macros.h index 078d32664..3e0869354 100644 --- a/lib/common/macros.h +++ b/lib/common/macros.h @@ -83,7 +83,9 @@ #undef BETWEEN #endif #define BETWEEN(a,b,c) (((a) <= (b)) && ((b) <= (c))) -#define INSIDE(p,b) (BETWEEN(b.LL.x,p.x,b.UR.x) && BETWEEN(b.LL.y,p.y,b.UR.y)) +#define INSIDE(p,b) (BETWEEN((b).LL.x,(p).x,(b).UR.x) && BETWEEN((b).LL.y,(p).y,(b).UR.y)) +#define OVERLAP(b0,b1) (((b0).UR.x >= (b1).LL.x) && ((b1).UR.x >= (b0).LL.x) && ((b0).UR.y >= (b1).LL.y) && ((b1).UR.y >= (b0).LL.y)) +#define CONTAINS(b0,b1) (((b0).UR.x >= (b1).UR.x) && ((b0).UR.y >= (b1).UR.y) && ((b0).LL.x <= (b1).LL.x) && ((b0).LL.y <= (b1).LL.y)) #define ROUND(f) ((f>=0)?(int)(f + .5):(int)(f - .5)) #define RADIANS(deg) ((deg)/180.0 * PI) diff --git a/lib/common/renderprocs.h b/lib/common/renderprocs.h index 1d4e18bea..571f2e7c4 100644 --- a/lib/common/renderprocs.h +++ b/lib/common/renderprocs.h @@ -48,6 +48,8 @@ extern "C" { extern boxf boxf_intersect(boxf, boxf); extern boolean box_overlap(box, box); extern boolean boxf_overlap(boxf, boxf); + extern boolean box_contains(box, box); + extern boolean boxf_contains(boxf, boxf); extern void cat_libfile(FILE *, char **, char **); extern void clip_and_install(edge_t *, edge_t *, point *, int, splineInfo *); diff --git a/lib/common/utils.c b/lib/common/utils.c index 6dd4812ad..a37262193 100644 --- a/lib/common/utils.c +++ b/lib/common/utils.c @@ -654,26 +654,21 @@ boxf boxf_intersect(boxf b0, boxf b1) boolean box_overlap(box b0, box b1) { - if ((b0.UR.x < b1.LL.x) || (b1.UR.x < b0.LL.x) - || (b0.UR.y < b1.LL.y) || (b1.UR.y < b0.LL.y)) - return FALSE; - return TRUE; + return OVERLAP(b0, b1); } boolean boxf_overlap(boxf b0, boxf b1) { - if ((b0.UR.x < b1.LL.x) || (b1.UR.x < b0.LL.x) - || (b0.UR.y < b1.LL.y) || (b1.UR.y < b0.LL.y)) - return FALSE; - return TRUE; + return OVERLAP(b0, b1); } -boolean boxf_contains_p(boxf b0, boxf b1) +boolean box_contains(box b0, box b1) { - if ((b0.UR.x >= b1.UR.x) && (b0.UR.y >= b1.UR.y) - && (b0.LL.x <= b1.LL.x) && (b0.LL.y <= b1.LL.y)) - return TRUE; - return FALSE; + return CONTAINS(b0, b1); +} +boolean boxf_contains(boxf b0, boxf b1) +{ + return CONTAINS(b0, b1); } int maptoken(char *p, char **name, int *val) diff --git a/lib/gvc/gvevent.c b/lib/gvc/gvevent.c index 8c0174980..54c5e3568 100644 --- a/lib/gvc/gvevent.c +++ b/lib/gvc/gvevent.c @@ -37,11 +37,13 @@ void gvevent_refresh(GVJ_t * job) emit_graph(job, job->g); } -static boolean inside_node(node_t *n, pointf p) +static boolean inside_node(node_t *n, boxf b) { + boxf bb; // inside_t ictxt; - if (! INSIDE(p, ND_bb(n))) + bb = ND_bb(n); + if (! OVERLAP(b, bb)) return FALSE; // ictxt.s.n = n; @@ -51,7 +53,7 @@ static boolean inside_node(node_t *n, pointf p) return TRUE; } -static boolean inside_label(edge_t *e, pointf p) +static boolean inside_label(edge_t *e, boxf b) { textlabel_t *lp; double sx, sy; @@ -66,10 +68,10 @@ static boolean inside_label(edge_t *e, pointf p) bb.UR.x = lp->p.x + sx; bb.LL.y = lp->p.y - sy; bb.UR.y = lp->p.y + sy; - return INSIDE(p, bb); + return OVERLAP(b, bb); } -static boolean inside_spline(edge_t *e, pointf p) +static boolean inside_spline(edge_t *e, boxf b) { int i, j, k; bezier bz; @@ -80,8 +82,9 @@ static boolean inside_spline(edge_t *e, pointf p) spl = ED_spl(e); if (spl == NULL) return FALSE; - - if (! INSIDE(p, spl->bb)) + + bbf = spl->bb; + if (! OVERLAP(b, bbf)) return FALSE; for (i = 0; i < spl->size; i++) { @@ -95,8 +98,8 @@ static boolean inside_spline(edge_t *e, pointf p) bb.UR.x = MAX(bb.UR.x,bz.list[k].x); bb.UR.y = MAX(bb.UR.y,bz.list[k].y); } - B2BF(bb,bbf); - if (INSIDE(p,bbf)) { + B2BF(bb, bbf); + if (OVERLAP(b, bbf)) { /* FIXME - check if really close enough to actual curve */ return TRUE; } @@ -105,36 +108,36 @@ static boolean inside_spline(edge_t *e, pointf p) return FALSE; } -static boolean inside_edge(edge_t *e, pointf p) +static boolean inside_edge(edge_t *e, boxf b) { - if (inside_spline(e, p)) + if (inside_spline(e, b)) return TRUE; // FIXME // if (inside_arrow(e)) // return TRUE; - return inside_label(e, p); + return inside_label(e, b); } /* recursively find innermost cluster containing the point */ -static graph_t *gvevent_find_cluster(graph_t *g, pointf p) +static graph_t *gvevent_find_cluster(graph_t *g, boxf b) { int i; graph_t *sg; boxf bb; for (i = 1; i <= GD_n_cluster(g); i++) { - sg = gvevent_find_cluster(GD_clust(g)[i], p); + sg = gvevent_find_cluster(GD_clust(g)[i], b); if (sg) return(sg); } B2BF(GD_bb(g), bb); - if (INSIDE(p, bb)) + if (OVERLAP(b, bb)) return g; return NULL; } -static void * gvevent_find_obj(graph_t *g, pointf p) +static void * gvevent_find_obj(graph_t *g, boxf b) { graph_t *sg; node_t *n; @@ -143,14 +146,14 @@ static void * gvevent_find_obj(graph_t *g, pointf p) /* edges might overlap nodes, so search them first */ for (n = agfstnode(g); n; n = agnxtnode(g, n)) for (e = agfstout(g, n); e; e = agnxtout(g, e)) - if (inside_edge(e, p)) + if (inside_edge(e, b)) return (void *)e; /* search graph backwards to get topmost node, in case of overlap */ for (n = aglstnode(g); n; n = agprvnode(g, n)) - if (inside_node(n, p)) + if (inside_node(n, b)) return (void *)n; /* search for innermost cluster */ - sg = gvevent_find_cluster(g, p); + sg = gvevent_find_cluster(g, b); if (sg) return (void *)sg; @@ -158,10 +161,15 @@ static void * gvevent_find_obj(graph_t *g, pointf p) return (void *)g; } +/* CLOSEENOUGH is in window units - probably should be a feature... */ +#define CLOSEENOUGH 1 + static void gvevent_find_current_obj(GVJ_t * job, double x, double y) { void *obj; pointf p; + boxf b; + double closeenough; /* convert window point to graph coordinates */ if (job->rotation) { @@ -172,8 +180,14 @@ static void gvevent_find_current_obj(GVJ_t * job, double x, double y) p.x = job->focus.x + (x - job->width / 2.) / job->compscale.x; p.y = job->focus.y + (y - job->height / 2.) / job->compscale.y; } + closeenough = CLOSEENOUGH / job->compscale.x; + + b.UR.x = p.x + closeenough; + b.UR.y = p.y + closeenough; + b.LL.x = p.x - closeenough; + b.LL.y = p.y - closeenough; - obj = gvevent_find_obj(job->g, p); + obj = gvevent_find_obj(job->g, b); if (obj != job->current_obj) { job->current_obj = obj; fprintf(stderr,"obj=%x kind=%d\n",obj,agobjkind(obj)); -- 2.40.0