summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README1
-rw-r--r--git-hist.c23
-rw-r--r--git-hist.h5
-rw-r--r--gui-over.c6
-rw-r--r--gui-over.h1
-rw-r--r--gui.c95
-rw-r--r--gui.h2
-rw-r--r--main.c2
8 files changed, 125 insertions, 10 deletions
diff --git a/README b/README
index 4bda222..bbd61c2 100644
--- a/README
+++ b/README
@@ -37,4 +37,5 @@ Home go to the top sheet
Delete or Backspace go to the previous sheet
PgUp go to the previous sheet in sequence
PgDn go to the next sheet in sequence
+Up or Down invoke the revision history (WIP)
Q quit the viewer
diff --git a/git-hist.c b/git-hist.c
index bf0129d..21681a0 100644
--- a/git-hist.c
+++ b/git-hist.c
@@ -126,6 +126,17 @@ static void recurse(struct hist *h,
}
+bool vcs_git_try(const char *path)
+{
+ git_repository *repo;
+
+ vcs_git_init();
+
+ return !git_repository_open_ext(&repo, path,
+ GIT_REPOSITORY_OPEN_CROSS_FS, NULL);
+}
+
+
struct hist *vcs_git_hist(const char *path)
{
struct hist *head;
@@ -178,6 +189,18 @@ const char *vcs_git_summary(struct hist *h)
}
+void hist_iterate(struct hist *h,
+ void (*fn)(void *user, struct hist *h), void *user)
+{
+ unsigned i;
+
+ fn(user, h);
+ for (i = 0; i != h->n_older; i++)
+ if (h->older[i]->newer[h->older[i]->n_newer - 1] == h)
+ hist_iterate(h->older[i], fn, user);
+}
+
+
void dump_hist(struct hist *h)
{
git_buf buf = { 0 };
diff --git a/git-hist.h b/git-hist.h
index 838ff3b..2d1b628 100644
--- a/git-hist.h
+++ b/git-hist.h
@@ -13,6 +13,8 @@
#ifndef GIT_HIST_H
#define GIT_HIST_H
+#include <stdbool.h>
+
#include <git2.h>
@@ -29,8 +31,11 @@ struct hist {
};
+bool vcs_git_try(const char *path);
struct hist *vcs_git_hist(const char *path);
const char *vcs_git_summary(struct hist *hist);
+void hist_iterate(struct hist *h,
+ void (*fn)(void *user, struct hist *h), void *user);
void dump_hist(struct hist *h);
#endif /* !GIT_HIST_H */
diff --git a/gui-over.c b/gui-over.c
index baedf98..55d3f13 100644
--- a/gui-over.c
+++ b/gui-over.c
@@ -64,7 +64,7 @@ static void rrect(cairo_t *cr, int x, int y, int w, int h, int r)
}
-static void overlay_draw(struct overlay *over, cairo_t *cr, int *x, int *y)
+struct overlay *overlay_draw(struct overlay *over, cairo_t *cr, int *x, int *y)
{
cairo_text_extents_t ext;
int w, h;
@@ -103,7 +103,9 @@ static void overlay_draw(struct overlay *over, cairo_t *cr, int *x, int *y)
over->aoi = aoi_add(over->aois, &aoi);
}
- *y += ext.height + OVER_SEP;
+ *y += h + OVER_SEP;
+
+ return over->next;
}
diff --git a/gui-over.h b/gui-over.h
index 6c8287f..477c5d9 100644
--- a/gui-over.h
+++ b/gui-over.h
@@ -23,6 +23,7 @@
struct overlay;
+struct overlay *overlay_draw(struct overlay *over, cairo_t *cr, int *x, int *y);
void overlay_draw_all(struct overlay *overlays, cairo_t *cr);
struct overlay *overlay_add(struct overlay **overlays, const char *s,
struct aoi **aois,
diff --git a/gui.c b/gui.c
index f1986b2..ad99597 100644
--- a/gui.c
+++ b/gui.c
@@ -17,6 +17,7 @@
* https://developer.gnome.org/gtk3/stable/gtk-migrating-2-to-3.html
*/
+#define _GNU_SOURCE /* for asprintf */
#include <stddef.h>
#include <stdbool.h>
#include <stdlib.h>
@@ -29,6 +30,7 @@
#include "util.h"
#include "cro.h"
#include "gfx.h"
+#include "git-hist.h"
#include "sch.h"
#include "gui-aoi.h"
#include "gui-over.h"
@@ -49,6 +51,11 @@ struct gui_sheet {
struct gui_sheet *next;
};
+struct gui_hist {
+ struct hist *hist;
+ struct gui_hist *next;
+};
+
struct gui_ctx {
GtkWidget *da;
@@ -61,7 +68,11 @@ struct gui_ctx {
bool panning;
int pan_x, pan_y;
- struct overlay *overlays;
+ struct gui_hist *hist; /* revision history; NULL if none */
+ struct hist *vcs_hist; /* underlying VCS data; NULL if none */
+
+ struct overlay *sheet_overlays;
+ struct overlay *vcs_overlays;
struct aoi *aois; /* areas of interest; in canvas coord */
struct gui_sheet *curr_sheet;
@@ -82,6 +93,17 @@ static void redraw(const struct gui_ctx *ctx)
/* ----- Rendering --------------------------------------------------------- */
+static void draw_vcs_overlays(const struct gui_ctx *ctx, cairo_t *cr)
+{
+ struct overlay *over;
+ int x = 200;
+ int y = 5;
+
+ for (over = ctx->vcs_overlays; over;)
+ over = overlay_draw(over, cr, &x, &y);
+}
+
+
static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr,
gpointer user_data)
{
@@ -97,7 +119,8 @@ static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr,
y = -(sheet->ymin + ctx->y) * f + alloc.height / 2;
cro_canvas_draw(sheet->gfx_ctx, cr, x, y, f);
- overlay_draw_all(ctx->overlays, cr);
+ overlay_draw_all(ctx->sheet_overlays, cr);
+ draw_vcs_overlays(ctx, cr);
return FALSE;
}
@@ -231,9 +254,9 @@ static void close_subsheet(void *user)
static void go_to_sheet(struct gui_ctx *ctx, struct gui_sheet *sheet)
{
ctx->curr_sheet = sheet;
- overlay_remove_all(&ctx->overlays);
+ overlay_remove_all(&ctx->sheet_overlays);
if (sheet->sch->title)
- overlay_add(&ctx->overlays, sheet->sch->title,
+ overlay_add(&ctx->sheet_overlays, sheet->sch->title,
&ctx->aois, NULL, close_subsheet, ctx);
zoom_to_extents(ctx);
}
@@ -277,6 +300,34 @@ static bool go_next_sheet(struct gui_ctx *ctx)
}
+/* ----- Revision history -------------------------------------------------- */
+
+
+static void hide_history(void *user)
+{
+ struct gui_ctx *ctx = user;
+
+ overlay_remove_all(&ctx->vcs_overlays);
+ redraw(ctx);
+}
+
+
+static void show_history(struct gui_ctx *ctx)
+{
+ struct gui_hist *h = ctx->hist;
+ char *s;
+
+ overlay_remove_all(&ctx->vcs_overlays);
+ for (h = ctx->hist; h; h = h->next) {
+ // @@@ \n doesn't work with cairo_show_text :-(
+ if (asprintf(&s, "commit\n%s", vcs_git_summary(h->hist))) {}
+ overlay_add(&ctx->vcs_overlays, s, &ctx->aois,
+ NULL, hide_history, ctx);
+ }
+ redraw(ctx);
+}
+
+
/* ----- Event handlers ---------------------------------------------------- */
@@ -382,6 +433,12 @@ static gboolean key_press_event(GtkWidget *widget, GdkEventKey *event,
case GDK_KEY_KP_Page_Down:
go_next_sheet(ctx);
break;
+ case GDK_KEY_Up:
+ case GDK_KEY_KP_Up:
+ case GDK_KEY_Down:
+ case GDK_KEY_KP_Down:
+ show_history(ctx);
+ break;
case GDK_KEY_q:
gtk_main_quit();
}
@@ -505,17 +562,43 @@ static void get_sheets(struct gui_ctx *ctx, const struct sheet *sheets)
}
-int gui(const struct sheet *sheets)
+
+static void add_hist(void *user, struct hist *h)
+{
+ struct gui_ctx *ctx = user;
+ struct gui_hist **anchor;
+
+ for (anchor = &ctx->hist; *anchor; anchor = &(*anchor)->next);
+ *anchor = alloc_type(struct gui_hist);
+ (*anchor)->hist = h;
+ (*anchor)->next = NULL;
+}
+
+
+static void get_git(struct gui_ctx *ctx, const char *sch_name)
+{
+ if (!vcs_git_try(sch_name))
+ return;
+ ctx->vcs_hist = vcs_git_hist(sch_name);
+ hist_iterate(ctx->vcs_hist, add_hist, ctx);
+}
+
+
+int gui(const struct sheet *sheets, const char *sch_name)
{
GtkWidget *window;
struct gui_ctx ctx = {
.zoom = 4, /* scale by 1 / 16 */
.panning = 0,
- .overlays = NULL,
+ .hist = NULL,
+ .vcs_hist = NULL,
+ .sheet_overlays = NULL,
+ .vcs_overlays = NULL,
.aois = NULL,
};
get_sheets(&ctx, sheets);
+ get_git(&ctx, sch_name);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
diff --git a/gui.h b/gui.h
index 0e1f9ef..4c7c181 100644
--- a/gui.h
+++ b/gui.h
@@ -16,6 +16,6 @@
#include "sch.h"
-int gui(const struct sheet *sheets);
+int gui(const struct sheet *sheets, const char *sch_name);
#endif /* !GUI_H */
diff --git a/main.c b/main.c
index 07e7338..a8e4744 100644
--- a/main.c
+++ b/main.c
@@ -182,7 +182,7 @@ found:
file_close(&sch_file);
if (!have_dashdash)
- return gui(sch_ctx.sheets);
+ return gui(sch_ctx.sheets, argv[dashdash - 1]);
gfx_init(*ops, gfx_argc, gfx_argv);
if (recurse) {