From 064a5612858e7d596a4cdbbfac0232102111e9f8 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Thu, 4 Aug 2016 07:53:25 -0300 Subject: [PATCH] eeshow/: add AOI to overlays; clicking on sheet name returns to previous sheet --- eeshow/gui-aoi.c | 15 +++++++++++++- eeshow/gui-aoi.h | 3 ++- eeshow/gui-over.c | 52 +++++++++++++++++++++++++++++++++++++++-------- eeshow/gui-over.h | 10 +++++++-- eeshow/gui.c | 19 +++++++++++++++-- 5 files changed, 85 insertions(+), 14 deletions(-) diff --git a/eeshow/gui-aoi.c b/eeshow/gui-aoi.c index 5e0a0dc..f44db30 100644 --- a/eeshow/gui-aoi.c +++ b/eeshow/gui-aoi.c @@ -26,7 +26,7 @@ static const struct aoi *hovering = NULL; -void aoi_add(struct aoi **aois, const struct aoi *aoi) +const struct aoi *aoi_add(struct aoi **aois, const struct aoi *aoi) { struct aoi *new; @@ -34,6 +34,8 @@ void aoi_add(struct aoi **aois, const struct aoi *aoi) *new = *aoi; new->next = *aois; *aois = new; + + return new; } @@ -79,3 +81,14 @@ bool aoi_click(const struct aoi *aois, int x, int y) } return 0; } + + +void aoi_remove(struct aoi **aois, const struct aoi *aoi) +{ + if (hovering == aoi) + aoi->hover(aoi->user, 0); + while (*aois != aoi) + aois = &(*aois)->next; + *aois = aoi->next; + free((void *) aoi); +} diff --git a/eeshow/gui-aoi.h b/eeshow/gui-aoi.h index a5e4d79..040bc99 100644 --- a/eeshow/gui-aoi.h +++ b/eeshow/gui-aoi.h @@ -28,8 +28,9 @@ struct aoi { }; -void aoi_add(struct aoi **aois, const struct aoi *aoi); +const struct aoi *aoi_add(struct aoi **aois, const struct aoi *aoi); bool aoi_hover(const struct aoi *aois, int x, int y); bool aoi_click(const struct aoi *aois, int x, int y); +void aoi_remove(struct aoi **aois, const struct aoi *aoi); #endif /* !GUI_AOI_H */ diff --git a/eeshow/gui-over.c b/eeshow/gui-over.c index deca726..3a0d295 100644 --- a/eeshow/gui-over.c +++ b/eeshow/gui-over.c @@ -25,6 +25,7 @@ #include #include "util.h" +#include "gui-aoi.h" #include "gui-over.h" @@ -38,6 +39,14 @@ struct overlay { const char *s; + + struct aoi **aois; + bool (*hover)(void *user, bool on); + void (*click)(void *user); + void *user; + + const struct aoi *aoi; + struct overlay *next; }; @@ -55,17 +64,18 @@ static void rrect(cairo_t *cr, int x, int y, int w, int h, int r) } -static void overlay_draw(const struct overlay *over, cairo_t *cr, - int *x, int *y) +static void overlay_draw(struct overlay *over, cairo_t *cr, int *x, int *y) { cairo_text_extents_t ext; + int w, h; cairo_set_font_size(cr, OVER_FONT_SIZE); cairo_text_extents(cr, over->s, &ext); - rrect(cr, *x, *y, - ext.width + 2 * OVER_BORDER, ext.height + 2 * OVER_BORDER, - OVER_RADIUS); + w = ext.width + 2 * OVER_BORDER; + h = ext.height + 2 * OVER_BORDER; + + rrect(cr, *x, *y, w, h, OVER_RADIUS); cairo_set_source_rgba(cr, 0.8, 0.9, 1, 0.8); cairo_fill_preserve(cr); @@ -77,13 +87,29 @@ static void overlay_draw(const struct overlay *over, cairo_t *cr, cairo_move_to(cr, *x + OVER_BORDER, *y + OVER_BORDER + ext.height); cairo_show_text(cr, over->s); + if (over->hover || over->click) { + struct aoi aoi = { + .x = *x, + .y = *y, + .w = w, + .h = h, + .hover = over->hover, + .click = over->click, + .user = over->user, + }; + + if (over->aoi) + aoi_remove(over->aois, over->aoi); + over->aoi = aoi_add(over->aois, &aoi); + } + *y += ext.height + OVER_SEP; } -void overlay_draw_all(const struct overlay *overlays, cairo_t *cr) +void overlay_draw_all(struct overlay *overlays, cairo_t *cr) { - const struct overlay *over; + struct overlay *over; int x = OVER_X0; int y = OVER_Y0; @@ -92,7 +118,9 @@ void overlay_draw_all(const struct overlay *overlays, cairo_t *cr) } -struct overlay *overlay_add(struct overlay **overlays, const char *s) +struct overlay *overlay_add(struct overlay **overlays, const char *s, + struct aoi **aois, + bool (*hover)(void *user, bool on), void (*click)(void *user), void *user) { struct overlay *over; struct overlay **anchor; @@ -100,6 +128,12 @@ struct overlay *overlay_add(struct overlay **overlays, const char *s) over = alloc_type(struct overlay); over->s = stralloc(s); + over->aois = aois; + over->hover = hover; + over->click = click; + over->user = user; + over->aoi = NULL; + for (anchor = overlays; *anchor; anchor = &(*anchor)->next); over->next = NULL; *anchor = over; @@ -110,6 +144,8 @@ struct overlay *overlay_add(struct overlay **overlays, const char *s) static void overlay_free(struct overlay *over) { + if (over->aoi) + aoi_remove(over->aois, over->aoi); free((void *) over->s); free(over); } diff --git a/eeshow/gui-over.h b/eeshow/gui-over.h index 8307073..6c8287f 100644 --- a/eeshow/gui-over.h +++ b/eeshow/gui-over.h @@ -13,14 +13,20 @@ #ifndef GUI_OVER_H #define GUI_OVER_H +#include + #include +#include "gui-aoi.h" + struct overlay; -void overlay_draw_all(const struct overlay *overlays, cairo_t *cr); -struct overlay *overlay_add(struct overlay **overlays, const char *s); +void overlay_draw_all(struct overlay *overlays, cairo_t *cr); +struct overlay *overlay_add(struct overlay **overlays, const char *s, + struct aoi **aois, + bool (*hover)(void *user, bool on), void (*click)(void *user), void *user); void overlay_remove(struct overlay **overlays, struct overlay *over); void overlay_remove_all(struct overlay **overlays); diff --git a/eeshow/gui.c b/eeshow/gui.c index 29d4e3b..3a915aa 100644 --- a/eeshow/gui.c +++ b/eeshow/gui.c @@ -44,7 +44,7 @@ struct gui_sheet { int w, h; int xmin, ymin; - struct aoi *aois; /* areas of interest */ + struct aoi *aois; /* areas of interest; in schematics coord */ struct gui_sheet *prev; /* previous in stack */ @@ -64,6 +64,7 @@ struct gui_ctx { int pan_x, pan_y; struct overlay *overlays; + struct aoi *aois; /* areas of interest; in canvas coord */ struct gui_sheet *curr_sheet; /* current sheet */ @@ -248,6 +249,8 @@ static gboolean button_press_event(GtkWidget *widget, GdkEventButton *event, switch (event->button) { case 1: + if (aoi_click(ctx->aois, event->x, event->y)) + break; aoi_click(curr_sheet->aois, x + curr_sheet->xmin, y + curr_sheet->ymin); break; @@ -367,6 +370,16 @@ struct sheet_aoi_ctx { }; +static void close_subsheet(void *user) +{ + struct gui_ctx *ctx = user; + const struct gui_sheet *curr_sheet = ctx->curr_sheet; + + if (curr_sheet->prev) + set_sheet(ctx, curr_sheet->prev); +} + + static void select_subsheet(void *user) { const struct sheet_aoi_ctx *aoi_ctx = user; @@ -378,7 +391,8 @@ static void select_subsheet(void *user) if (sheet->sch == obj->u.sheet.sheet) { sheet->prev = ctx->curr_sheet; set_sheet(ctx, sheet); - overlay_add(&ctx->overlays, obj->u.sheet.name); + overlay_add(&ctx->overlays, obj->u.sheet.name, + &ctx->aois, NULL, close_subsheet, ctx); return; } abort(); @@ -454,6 +468,7 @@ int gui(const struct sheet *sheets) .zoom = 4, /* scale by 1 / 16 */ .panning = 0, .overlays = NULL, + .aois = NULL, }; get_sheets(&ctx, sheets);