diff --git a/eeshow/Makefile b/eeshow/Makefile index b5375bb..8cd3ea4 100644 --- a/eeshow/Makefile +++ b/eeshow/Makefile @@ -12,7 +12,7 @@ NAME = eeshow OBJS = main.o sch-parse.o sch-render.o lib-parse.o lib-render.o \ - gui.o gui-over.o \ + gui.o gui-over.o gui-aoi.o \ file.o git-file.o \ style.o fig.o record.o cro.o diff.o gfx.o dwg.o text.o misc.o diff --git a/eeshow/gui-aoi.c b/eeshow/gui-aoi.c new file mode 100644 index 0000000..5e0a0dc --- /dev/null +++ b/eeshow/gui-aoi.c @@ -0,0 +1,81 @@ +/* + * gui-aoi.c - GUI: areas of interest + * + * Written 2016 by Werner Almesberger + * Copyright 2016 by Werner Almesberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +/* + * Resources: + * + * http://zetcode.com/gfx/cairo/cairobackends/ + * https://developer.gnome.org/gtk3/stable/gtk-migrating-2-to-3.html + */ + +#include + +#include "util.h" +#include "gui-aoi.h" + + +static const struct aoi *hovering = NULL; + + +void aoi_add(struct aoi **aois, const struct aoi *aoi) +{ + struct aoi *new; + + new = alloc_type(struct aoi); + *new = *aoi; + new->next = *aois; + *aois = new; +} + + +bool aoi_hover(const struct aoi *aois, int x, int y) +{ + const struct aoi *aoi; + + if (hovering) { + if (x >= hovering->x && x < hovering->x + hovering->w && + y >= hovering->y && y < hovering->y + hovering->h) + return 1; + hovering->hover(hovering->user, 0); + hovering = NULL; + } + + for (aoi = aois; aoi; aoi = aoi->next) + if (x >= aoi->x && x < aoi->x + aoi->w && + y >= aoi->y && y < aoi->y + aoi->h) + break; + if (aoi && aoi->hover && aoi->hover(aoi->user, 1)) { + hovering = aoi; + return 1; + } + return 0; +} + + +bool aoi_click(const struct aoi *aois, int x, int y) +{ + const struct aoi *aoi; + + if (hovering) { + hovering->hover(hovering->user, 0); + hovering = NULL; + } + for (aoi = aois; aoi; aoi = aoi->next) + if (x >= aoi->x && x < aoi->x + aoi->w && + y >= aoi->y && y < aoi->y + aoi->h) + break; + if (aoi && aoi->click) { + aoi->click(aoi->user); + return 1; + } + return 0; +} diff --git a/eeshow/gui-aoi.h b/eeshow/gui-aoi.h new file mode 100644 index 0000000..a5e4d79 --- /dev/null +++ b/eeshow/gui-aoi.h @@ -0,0 +1,35 @@ +/* + * gui-aoi.h - GUI: areas of interest + * + * Written 2016 by Werner Almesberger + * Copyright 2016 by Werner Almesberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef GUI_AOI_H +#define GUI_AOI_H + +#include + + +struct aoi { + int x, y, w, h; /* activation box, eeschema coordinates */ + /* points to hovered aoi, or NULL */ + + bool (*hover)(void *user, bool on); + void (*click)(void *user); + void *user; + + struct aoi *next; +}; + + +void 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); + +#endif /* !GUI_AOI_H */ diff --git a/eeshow/gui.c b/eeshow/gui.c index c56b820..29d4e3b 100644 --- a/eeshow/gui.c +++ b/eeshow/gui.c @@ -30,22 +30,13 @@ #include "cro.h" #include "gfx.h" #include "sch.h" +#include "gui-aoi.h" #include "gui-over.h" #include "gui.h" struct gui_ctx; -struct aoi { - int x, y, w, h; /* activation box, eeschema coordinates */ - - bool (*hover)(struct gui_ctx *ctx, void *user, bool on); - void (*click)(struct gui_ctx *ctx, void *user); - void *user; - - struct aoi *next; -}; - struct gui_sheet { const const struct sheet *sch; struct cro_ctx *gfx_ctx; @@ -72,8 +63,6 @@ struct gui_ctx { bool panning; int pan_x, pan_y; - const struct aoi *aoi_hovering; /* hovering over this aoi */ - struct overlay *overlays; struct gui_sheet *curr_sheet; @@ -91,63 +80,6 @@ static void redraw(const struct gui_ctx *ctx) } -/* ----- Area of intereest ------------------------------------------------- */ - - -static void aoi_add(struct gui_sheet *sheet, const struct aoi *aoi) -{ - struct aoi *new; - - new = alloc_type(struct aoi); - *new = *aoi; - new->next = sheet->aois; - sheet->aois = new; -} - - -static void aoi_hover(struct gui_ctx *ctx, int x, int y) -{ - const struct gui_sheet *sheet = ctx->curr_sheet; - const struct aoi *aoi = ctx->aoi_hovering; - - if (aoi) { - if (x >= aoi->x && x < aoi->x + aoi->w && - y >= aoi->y && y < aoi->y + aoi->h) - return; - aoi->hover(ctx, aoi->user, 0); - ctx->aoi_hovering = NULL; - } - - for (aoi = sheet->aois; aoi; aoi = aoi->next) - if (x >= aoi->x && x < aoi->x + aoi->w && - y >= aoi->y && y < aoi->y + aoi->h) - break; - if (aoi && aoi->hover && aoi->hover(ctx, aoi->user, 1)) - ctx->aoi_hovering = aoi; -} - - -static void aoi_click(struct gui_ctx *ctx, int x, int y) -{ - const struct gui_sheet *sheet = ctx->curr_sheet; - const struct aoi *aoi = ctx->aoi_hovering; - - x += sheet->xmin; - y += sheet->ymin; - - if (aoi) { - aoi->hover(ctx, aoi->user, 0); - ctx->aoi_hovering = NULL; - } - for (aoi = sheet->aois; aoi; aoi = aoi->next) - if (x >= aoi->x && x < aoi->x + aoi->w && - y >= aoi->y && y < aoi->y + aoi->h) - break; - if (aoi && aoi->click) - aoi->click(ctx, aoi->user); -} - - /* ----- Rendering --------------------------------------------------------- */ @@ -290,6 +222,7 @@ static gboolean motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data) { struct gui_ctx *ctx = data; + const struct gui_sheet *curr_sheet = ctx->curr_sheet; int x, y; ctx->curr_x = event->x; @@ -297,7 +230,7 @@ static gboolean motion_notify_event(GtkWidget *widget, GdkEventMotion *event, canvas_coord(ctx, event->x, event->y, &x, &y); - aoi_hover(ctx, x, y); + aoi_hover(curr_sheet->aois, x + curr_sheet->xmin, y + curr_sheet->ymin); pan_update(ctx, event->x, event->y); return TRUE; @@ -308,13 +241,15 @@ static gboolean button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data) { struct gui_ctx *ctx = data; + const struct gui_sheet *curr_sheet = ctx->curr_sheet; int x, y; canvas_coord(ctx, event->x, event->y, &x, &y); switch (event->button) { case 1: - aoi_click(ctx, x, y); + aoi_click(curr_sheet->aois, + x + curr_sheet->xmin, y + curr_sheet->ymin); break; case 2: pan_begin(ctx, event->x, event->y); @@ -426,10 +361,18 @@ static void size_allocate_event(GtkWidget *widget, GdkRectangle *allocation, /* ----- AoI callbacks ----------------------------------------------------- */ -static void select_subsheet(struct gui_ctx *ctx, void *user) +struct sheet_aoi_ctx { + struct gui_ctx *gui_ctx; + const struct sch_obj *obj; +}; + + +static void select_subsheet(void *user) { - const struct sch_obj *obj = user; - struct gui_sheet *sheet; + const struct sheet_aoi_ctx *aoi_ctx = user; + struct gui_ctx *ctx = aoi_ctx->gui_ctx; + const struct sch_obj *obj = aoi_ctx->obj; + struct gui_sheet *sheet; for (sheet = ctx->sheets; sheet; sheet = sheet->next) if (sheet->sch == obj->u.sheet.sheet) { @@ -445,25 +388,36 @@ static void select_subsheet(struct gui_ctx *ctx, void *user) /* ----- Initialization ---------------------------------------------------- */ -static void mark_aois(struct gui_sheet *sheet) +static void add_sheet_aoi(struct gui_ctx *ctx, struct gui_sheet *parent, + const struct sch_obj *obj) +{ + struct sheet_aoi_ctx *aoi_ctx = alloc_type(struct sheet_aoi_ctx); + + aoi_ctx->gui_ctx = ctx; + aoi_ctx->obj = obj; + + struct aoi aoi = { + .x = obj->x, + .y = obj->y, + .w = obj->u.sheet.w, + .h = obj->u.sheet.h, + .click = select_subsheet, + .user = aoi_ctx, + }; + + aoi_add(&parent->aois, &aoi); +} + + +static void mark_aois(struct gui_ctx *ctx, struct gui_sheet *sheet) { const struct sch_obj *obj; sheet->aois = NULL; for (obj = sheet->sch->objs; obj; obj = obj->next) switch (obj->type) { - case sch_obj_sheet: { - struct aoi aoi = { - .x = obj->x, - .y = obj->y, - .w = obj->u.sheet.w, - .h = obj->u.sheet.h, - .click = select_subsheet, - .user = (void *) obj, - }; - - aoi_add(sheet, &aoi); - } + case sch_obj_sheet: + add_sheet_aoi(ctx, sheet, obj); break; default: break; @@ -483,7 +437,7 @@ static void get_sheets(struct gui_ctx *ctx, const struct sheet *sheets) gui_sheet->prev = NULL; render(ctx, gui_sheet); - mark_aois(gui_sheet); + mark_aois(ctx, gui_sheet); *next = gui_sheet; next = &gui_sheet->next;