From 6345c44dad55f02a3f5c04b187a5d1b4fe660d42 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Sun, 14 Aug 2016 13:01:35 -0300 Subject: [PATCH] eeshow/: history list can now be dragged --- eeshow/TODO | 4 ++-- eeshow/gui-aoi.c | 46 ++++++++++++++++++++++++++++++++++++++-------- eeshow/gui-aoi.h | 1 + eeshow/gui-over.c | 9 +++++++++ eeshow/gui-over.h | 2 ++ eeshow/gui.c | 18 +++++++++++++++++- 6 files changed, 69 insertions(+), 11 deletions(-) diff --git a/eeshow/TODO b/eeshow/TODO index 7ca755b..174e2ff 100644 --- a/eeshow/TODO +++ b/eeshow/TODO @@ -51,7 +51,7 @@ GUI/history - use Tab to rapidly toggle between old/new sheet - should have quick way to show diff of a single commit - in history, set font to non-bold if showing details -- add scrolling to history +- add scrolling to history, for hot-keys - add manual selection with Up/Down/Enter - highlight subsheets containing differences - "what I am selecting" indication (color of frames of sheets in history) @@ -59,4 +59,4 @@ GUI/history GUI/sheets: - need a way to change new/old sheet association, in case automatic selection - fails (reserved hotkeys: Left/Rigth) + fails (reserved hotkeys: Left/Right) diff --git a/eeshow/gui-aoi.c b/eeshow/gui-aoi.c index f0501fb..3b564b8 100644 --- a/eeshow/gui-aoi.c +++ b/eeshow/gui-aoi.c @@ -30,6 +30,7 @@ static const struct aoi *hovering = NULL; static const struct aoi *clicked = NULL; +static const struct aoi *dragging = NULL; static int clicked_x, clicked_y; @@ -67,10 +68,23 @@ static const struct aoi *find_aoi(const struct aoi *aois, int x, int y) } +static bool aoi_on_list(const struct aoi *aois, const struct aoi *ref) +{ + const struct aoi *aoi; + + for (aoi = aois; aoi; aoi = aoi->next) + if (aoi == ref) + return 1; + return 0; +} + + bool aoi_hover(const struct aoi *aois, int x, int y) { const struct aoi *aoi; + if (dragging) + return 0; if (hovering) { if (x >= hovering->x && x < hovering->x + hovering->w && y >= hovering->y && y < hovering->y + hovering->h) @@ -90,8 +104,15 @@ bool aoi_hover(const struct aoi *aois, int x, int y) bool aoi_move(const struct aoi *aois, int x, int y) { - const struct aoi *aoi; - + if (dragging) { + if (aoi_on_list(aois, dragging)) { + dragging->drag(dragging->user, + x - clicked_x, y - clicked_y); + clicked_x = x; + clicked_y = y; + } + return 1; + } if (!clicked) return 0; @@ -99,14 +120,19 @@ bool aoi_move(const struct aoi *aois, int x, int y) * Ensure we're on the right list and are using the same coordinate * system. */ - for (aoi = aois; aoi; aoi = aoi->next) - if (aoi == clicked) - break; - if (!aoi) + if (!aoi_on_list(aois, clicked)) return 0; - if (hypot(x - clicked_x, y - clicked_y) > DRAG_RADIUS) + if (hypot(x - clicked_x, y - clicked_y) > DRAG_RADIUS) { + if (clicked && clicked->drag) { + dragging = clicked; + dragging->drag(dragging->user, + x - clicked_x, y - clicked_y); + clicked_x = x; + clicked_y = y; + } clicked = NULL; + } return 1; } @@ -140,10 +166,14 @@ bool aoi_up(const struct aoi *aois, int x, int y) * system. */ for (aoi = aois; aoi; aoi = aoi->next) - if (aoi == clicked) + if (aoi == clicked || aoi == dragging) break; if (!aoi) return 0; + if (dragging) { + dragging = NULL; + return 1; + } clicked->click(clicked->user); clicked = NULL; diff --git a/eeshow/gui-aoi.h b/eeshow/gui-aoi.h index 1eb25c7..783ce91 100644 --- a/eeshow/gui-aoi.h +++ b/eeshow/gui-aoi.h @@ -22,6 +22,7 @@ struct aoi { bool (*hover)(void *user, bool on); void (*click)(void *user); + void (*drag)(void *user, int dx, int dy); void *user; struct aoi *next; diff --git a/eeshow/gui-over.c b/eeshow/gui-over.c index cfdd9ef..72e7a75 100644 --- a/eeshow/gui-over.c +++ b/eeshow/gui-over.c @@ -44,6 +44,7 @@ struct overlay { struct aoi **aois; bool (*hover)(void *user, bool on); void (*click)(void *user); + void (*drag)(void *user, int dx, int dy); void *user; struct aoi *aoi; @@ -163,6 +164,7 @@ fprintf(stderr, "%u(%d) %u %.60s\n", ty, ink_rect.y / PANGO_SCALE, ink_h, over-> .h = h, .hover = over->hover, .click = over->click, + .drag = over->drag, .user = over->user, }; @@ -220,6 +222,13 @@ void overlay_style(struct overlay *over, const struct overlay_style *style) } +void overlay_draggable(struct overlay *over, + void (*drag)(void *user, int dx, int dy)) +{ + over->drag = drag; +} + + void overlay_text_raw(struct overlay *over, const char *s) { free((char *) over->s); diff --git a/eeshow/gui-over.h b/eeshow/gui-over.h index d11bcef..bdb8e80 100644 --- a/eeshow/gui-over.h +++ b/eeshow/gui-over.h @@ -48,6 +48,8 @@ struct overlay *overlay_add(struct overlay **overlays, struct aoi **aois, void overlay_text_raw(struct overlay *over, const char *s); void overlay_text(struct overlay *over, const char *fmt, ...); void overlay_style(struct overlay *over, const struct overlay_style *style); +void overlay_draggable(struct overlay *over, + void (*drag)(void *user, int dx, int dy)); 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 c50b8bb..ae9e278 100644 --- a/eeshow/gui.c +++ b/eeshow/gui.c @@ -116,6 +116,8 @@ struct gui_ctx { struct gui_hist *new_hist; struct gui_hist *old_hist; /* NULL if not comparing */ + int hist_y_offset; /* history list y offset */ + /* progress bar */ unsigned hist_size; /* total number of revisions */ unsigned progress; /* progress counter */ @@ -210,7 +212,8 @@ static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, overlay_draw_all(ctx->sheet_overlays, cr, SHEET_OVERLAYS_X, SHEET_OVERLAYS_Y); overlay_draw_all(ctx->hist_overlays, cr, - VCS_OVERLAYS_X, VCS_OVERLAYS_Y); + VCS_OVERLAYS_X, + VCS_OVERLAYS_Y + (ctx->showing_history ? ctx->hist_y_offset : 0)); overlay_draw_all(ctx->pop_overlays, cr, ctx->pop_x, ctx->pop_y); return FALSE; @@ -546,16 +549,28 @@ static void click_history(void *user) } +static void drag_overlay(void *user, int dx, int dy) +{ + const struct gui_hist *h = user; + struct gui_ctx *ctx = h->ctx; + + ctx->hist_y_offset += dy; + redraw(ctx); +} + + static void show_history(struct gui_ctx *ctx, enum selecting sel) { struct gui_hist *h = ctx->hist; ctx->showing_history = 1; + ctx->hist_y_offset = 0; ctx->selecting = sel; overlay_remove_all(&ctx->hist_overlays); for (h = ctx->hist; h; h = h->next) { h->over = overlay_add(&ctx->hist_overlays, &ctx->aois, hover_history, click_history, h); + overlay_draggable(h->over, drag_overlay); hover_history(h, 0); set_history_style(h, 0); } @@ -1404,6 +1419,7 @@ int gui(unsigned n_args, char **args, bool recurse, int limit) .pop_overlays = NULL, .aois = NULL, .old_hist = NULL, + .hist_y_offset = 0, .hist_size = 0, };