summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--git-hist.c33
-rw-r--r--git-hist.h1
-rw-r--r--gui-aoi.c17
-rw-r--r--gui-aoi.h3
-rw-r--r--gui-over.c19
-rw-r--r--gui-over.h1
-rw-r--r--gui.c37
7 files changed, 94 insertions, 17 deletions
diff --git a/git-hist.c b/git-hist.c
index 441a15d..1b6d3e1 100644
--- a/git-hist.c
+++ b/git-hist.c
@@ -13,10 +13,12 @@
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
+#include <time.h> /* for vcs_long_for_pango */
#include <alloca.h>
#include "util.h"
#include "main.h"
+#include "fmt-pango.h" /* for vcs_long_for_pango */
#include "git-util.h"
#include "git-file.h"
#include "git-hist.h"
@@ -213,6 +215,37 @@ const char *vcs_git_summary(struct hist *h)
}
+/*
+ * @@@ This one is a bit inconvenient. It depends both on the information the
+ * VCS provides, some of which is fairly generic, but some may not be, and
+ * the very specific constraints imposed by the markup format of Pango.
+ */
+
+char *vcs_git_long_for_pango(struct hist *h)
+{
+ const git_error *e;
+ git_buf buf = { 0 };
+ time_t commit_time;
+ const git_signature *sig;
+ char *s;
+
+ if (git_object_short_id(&buf, (git_object *) h->commit))
+ goto fail;
+ commit_time = git_commit_time(h->commit);
+ sig = git_commit_committer(h->commit);
+ s = fmt_pango("<b>%s</b> %s%s &lt;%s&gt;<small>\n%s</small>",
+ buf.ptr, ctime(&commit_time), sig->name, sig->email,
+ git_commit_summary(h->commit));
+ git_buf_free(&buf);
+ return s;
+
+fail:
+ e = giterr_last();
+ fprintf(stderr, "vcs_git_long_for_pango: %s\n", e->message);
+ exit(1);
+}
+
+
void hist_iterate(struct hist *h,
void (*fn)(void *user, struct hist *h), void *user)
{
diff --git a/git-hist.h b/git-hist.h
index 2f89ec5..8caebfc 100644
--- a/git-hist.h
+++ b/git-hist.h
@@ -35,6 +35,7 @@ bool vcs_git_try(const char *path);
struct hist *vcs_git_hist(const char *path);
char *vcs_git_get_rev(struct hist *h);
const char *vcs_git_summary(struct hist *hist);
+char *vcs_git_long_for_pango(struct hist *hist);
void hist_iterate(struct hist *h,
void (*fn)(void *user, struct hist *h), void *user);
void dump_hist(struct hist *h);
diff --git a/gui-aoi.c b/gui-aoi.c
index f44db30..6d8215a 100644
--- a/gui-aoi.c
+++ b/gui-aoi.c
@@ -26,12 +26,12 @@
static const struct aoi *hovering = NULL;
-const struct aoi *aoi_add(struct aoi **aois, const struct aoi *aoi)
+struct aoi *aoi_add(struct aoi **aois, const struct aoi *cfg)
{
struct aoi *new;
new = alloc_type(struct aoi);
- *new = *aoi;
+ *new = *cfg;
new->next = *aois;
*aois = new;
@@ -39,6 +39,15 @@ const struct aoi *aoi_add(struct aoi **aois, const struct aoi *aoi)
}
+void aoi_update(struct aoi *aoi, const struct aoi *cfg)
+{
+ struct aoi *next = aoi->next;
+
+ *aoi = *cfg;
+ aoi->next = next;
+}
+
+
bool aoi_hover(const struct aoi *aois, int x, int y)
{
const struct aoi *aoi;
@@ -85,8 +94,10 @@ bool aoi_click(const struct aoi *aois, int x, int y)
void aoi_remove(struct aoi **aois, const struct aoi *aoi)
{
- if (hovering == aoi)
+ if (hovering == aoi) {
aoi->hover(aoi->user, 0);
+ hovering = NULL;
+ }
while (*aois != aoi)
aois = &(*aois)->next;
*aois = aoi->next;
diff --git a/gui-aoi.h b/gui-aoi.h
index 83e5719..59a4aa3 100644
--- a/gui-aoi.h
+++ b/gui-aoi.h
@@ -28,7 +28,8 @@ struct aoi {
};
-const struct aoi *aoi_add(struct aoi **aois, const struct aoi *aoi);
+struct aoi *aoi_add(struct aoi **aois, const struct aoi *cfg);
+void aoi_update(struct aoi *aoi, const struct aoi *cfg);
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);
diff --git a/gui-over.c b/gui-over.c
index de664dc..7641af5 100644
--- a/gui-over.c
+++ b/gui-over.c
@@ -50,7 +50,7 @@ struct overlay {
void (*click)(void *user);
void *user;
- const struct aoi *aoi;
+ struct aoi *aoi;
struct overlay *next;
};
@@ -179,7 +179,7 @@ fprintf(stderr, "%u(%d) %u %.60s\n", ty, ink_rect.y / PANGO_SCALE, ink_h, over->
g_object_unref(layout);
if (over->hover || over->click) {
- struct aoi aoi = {
+ struct aoi aoi_cfg = {
.x = *x,
.y = *y,
.w = w,
@@ -190,8 +190,9 @@ fprintf(stderr, "%u(%d) %u %.60s\n", ty, ink_rect.y / PANGO_SCALE, ink_h, over->
};
if (over->aoi)
- aoi_remove(over->aois, over->aoi);
- over->aoi = aoi_add(over->aois, &aoi);
+ aoi_update(over->aoi, &aoi_cfg);
+ else
+ over->aoi = aoi_add(over->aois, &aoi_cfg);
}
*y += h + style->skip;
@@ -241,13 +242,19 @@ void overlay_style(struct overlay *over, const struct overlay_style *style)
}
+void overlay_text_raw(struct overlay *over, const char *s)
+{
+ free((char *) over->s);
+ over->s = stralloc(s);
+}
+
+
void overlay_text(struct overlay *over, const char *fmt, ...)
{
va_list ap;
- free((char *) over->s);
va_start(ap, fmt);
- over->s = vfmt_pango(fmt, ap);
+ overlay_text_raw(over, vfmt_pango(fmt, ap));
va_end(ap);
}
diff --git a/gui-over.h b/gui-over.h
index e9e760d..42534cc 100644
--- a/gui-over.h
+++ b/gui-over.h
@@ -44,6 +44,7 @@ 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, struct aoi **aois,
bool (*hover)(void *user, bool on), void (*click)(void *user), void *user);
+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_remove(struct overlay **overlays, struct overlay *over);
diff --git a/gui.c b/gui.c
index 7a7532b..3d50f23 100644
--- a/gui.c
+++ b/gui.c
@@ -56,6 +56,7 @@ struct gui_sheet {
struct gui_hist {
struct gui_ctx *ctx; /* back link */
struct hist *hist;
+ struct overlay *over; /* current overlay */
struct gui_sheet *sheets; /* NULL if failed */
struct gui_hist *next;
};
@@ -337,7 +338,8 @@ static void show_history(struct gui_ctx *ctx)
static void show_history_cb(void *user)
{
- struct gui_ctx *ctx = user;
+ struct gui_hist *h = user;
+ struct gui_ctx *ctx = h->ctx;
show_history(ctx);
}
@@ -358,6 +360,25 @@ static void close_subsheet(void *user)
}
+static bool show_history_details(void *user, bool on)
+{
+ struct gui_hist *h = user;
+ struct gui_ctx *ctx = h->ctx;
+
+ char *s;
+
+ if (on) {
+ s = vcs_git_long_for_pango(h->hist);
+ overlay_text_raw(h->over, s);
+ free(s);
+ } else {
+ overlay_text(h->over, "%.40s", vcs_git_summary(h->hist));
+ }
+ redraw(ctx);
+ return 1;
+}
+
+
static void go_to_sheet(struct gui_ctx *ctx, struct gui_sheet *sheet)
{
struct overlay *over;
@@ -368,11 +389,11 @@ static void go_to_sheet(struct gui_ctx *ctx, struct gui_sheet *sheet)
}
ctx->curr_sheet = sheet;
overlay_remove_all(&ctx->sheet_overlays);
- if (ctx->hist) {
- over = overlay_add(&ctx->sheet_overlays, &ctx->aois,
- NULL, show_history_cb, ctx);
- overlay_text(over, "%.40s",
- vcs_git_summary(ctx->curr_hist->hist));
+ if (ctx->curr_hist) {
+ ctx->curr_hist->over = overlay_add(&ctx->sheet_overlays,
+ &ctx->aois, show_history_details, show_history_cb,
+ ctx->curr_hist);
+ show_history_details(ctx->curr_hist, 0);
}
if (sheet->sch->title) {
over = overlay_add(&ctx->sheet_overlays, &ctx->aois,
@@ -436,7 +457,9 @@ static gboolean motion_notify_event(GtkWidget *widget, GdkEventMotion *event,
canvas_coord(ctx, event->x, event->y, &x, &y);
- aoi_hover(curr_sheet->aois, x + curr_sheet->xmin, y + curr_sheet->ymin);
+ aoi_hover(ctx->aois, event->x, event->y) ||
+ aoi_hover(curr_sheet->aois,
+ x + curr_sheet->xmin, y + curr_sheet->ymin);
pan_update(ctx, event->x, event->y);
return TRUE;