Implemented support for --left-right

This commit is contained in:
Jesse van den Kieboom 2009-01-28 16:13:02 +01:00
parent 41df093700
commit 8ae8c69622
6 changed files with 151 additions and 21 deletions

View file

@ -7,6 +7,8 @@
#define GITG_CELL_RENDERER_PATH_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_CELL_RENDERER_PATH, GitgCellRendererPathPrivate))
#define DEFAULT_DOT_WIDTH 10
#define DEFAULT_TRIANGLE_WIDTH 8
#define DEFAULT_LANE_WIDTH (DEFAULT_DOT_WIDTH + 6)
/* Properties */
@ -19,6 +21,7 @@ enum
PROP_NEXT_LANES,
PROP_LANE_WIDTH,
PROP_DOT_WIDTH,
PROP_TRIANGLE_WIDTH,
PROP_LABELS
};
@ -29,6 +32,7 @@ struct _GitgCellRendererPathPrivate
GSList *next_lanes;
GSList *labels;
guint lane_width;
guint triangle_width;
guint dot_width;
};
@ -196,6 +200,65 @@ draw_labels(GitgCellRendererPath *self, GtkWidget *widget, cairo_t *context, Gdk
gitg_label_renderer_draw(widget, font, context, self->priv->labels, area);
}
static void
draw_indicator_triangle(GitgCellRendererPath *self, GitgLane *lane, cairo_t *context, GdkRectangle *area)
{
gdouble offset = self->priv->lane * self->priv->lane_width + (self->priv->lane_width - self->priv->triangle_width) / 2.0;
gdouble radius = self->priv->triangle_width / 2.0;
gdouble xs;
int xd;
if (lane->type & GITG_LANE_SIGN_LEFT)
{
xs = radius;
xd = -1;
}
else
{
xs = -radius;
xd = 1;
}
cairo_set_line_width(context, 2.0);
cairo_move_to(context, area->x + offset + radius + xs, area->y + (area->height - self->priv->triangle_width) / 2);
cairo_rel_line_to(context, 0, self->priv->triangle_width);
cairo_rel_line_to(context, xd * self->priv->triangle_width, -self->priv->triangle_width / 2);
cairo_close_path(context);
cairo_set_source_rgb(context, 0, 0, 0);
cairo_stroke_preserve(context);
gitg_color_set_cairo_source(lane->color, context);
cairo_fill(context);
}
static void
draw_indicator_circle(GitgCellRendererPath *self, GitgLane *lane, cairo_t *context, GdkRectangle *area)
{
gdouble offset = self->priv->lane * self->priv->lane_width + (self->priv->lane_width - self->priv->dot_width) / 2.0;
gdouble radius = self->priv->dot_width / 2.0;
cairo_set_line_width(context, 2.0);
cairo_arc(context, area->x + offset + radius, area->y + area->height / 2.0, radius, 0, 2 * M_PI);
cairo_set_source_rgb(context, 0, 0, 0);
cairo_stroke_preserve(context);
gitg_color_set_cairo_source(lane->color, context);
cairo_fill(context);
}
static void
draw_indicator(GitgCellRendererPath *self, cairo_t *context, GdkRectangle *area)
{
GitgLane *lane = (GitgLane *)g_slist_nth_data(self->priv->lanes, self->priv->lane);
if (lane->type & GITG_LANE_SIGN_LEFT || lane->type & GITG_LANE_SIGN_RIGHT)
draw_indicator_triangle(self, lane, context, area);
else
draw_indicator_circle(self, lane, context, area);
}
static void
renderer_render(GtkCellRenderer *renderer, GdkDrawable *window, GtkWidget *widget, GdkRectangle *area, GdkRectangle *cell_area, GdkRectangle *expose_area, GtkCellRendererState flags)
{
@ -205,19 +268,10 @@ renderer_render(GtkCellRenderer *renderer, GdkDrawable *window, GtkWidget *widge
draw_paths(self, cr, area);
gdouble offset = self->priv->lane * self->priv->lane_width + (self->priv->lane_width - self->priv->dot_width) / 2.0;
gdouble radius = self->priv->dot_width / 2.0;
/* draw indicator */
draw_indicator(self, cr, area);
cairo_set_line_width(cr, 2.0);
cairo_arc(cr, area->x + offset + radius, area->y + area->height / 2.0, radius, 0, 2 * M_PI);
cairo_set_source_rgb(cr, 0, 0, 0);
cairo_stroke_preserve(cr);
gitg_color_set_cairo_source(((GitgLane *)g_slist_nth_data(self->priv->lanes, self->priv->lane))->color, cr);
cairo_fill(cr);
// draw labels
/* draw labels */
draw_labels(self, widget, cr, area);
cairo_destroy(cr);
@ -250,6 +304,9 @@ gitg_cell_renderer_path_get_property(GObject *object, guint prop_id, GValue *val
case PROP_DOT_WIDTH:
g_value_set_uint(value, self->priv->dot_width);
break;
case PROP_TRIANGLE_WIDTH:
g_value_set_uint(value, self->priv->triangle_width);
break;
case PROP_LABELS:
g_value_set_pointer(value, self->priv->labels);
break;
@ -283,6 +340,9 @@ gitg_cell_renderer_path_set_property(GObject *object, guint prop_id, const GValu
case PROP_DOT_WIDTH:
self->priv->dot_width = g_value_get_uint(value);
break;
case PROP_TRIANGLE_WIDTH:
self->priv->triangle_width = g_value_get_uint(value);
break;
case PROP_LABELS:
g_slist_free(self->priv->labels);
self->priv->labels = (GSList *)g_value_get_pointer(value);
@ -347,6 +407,15 @@ gitg_cell_renderer_path_class_init(GitgCellRendererPathClass *klass)
DEFAULT_DOT_WIDTH,
G_PARAM_READWRITE));
g_object_class_install_property(object_class, PROP_TRIANGLE_WIDTH,
g_param_spec_uint("triangle-width",
"TRIANGLE WIDTH",
"The triangle width",
0,
G_MAXUINT,
DEFAULT_TRIANGLE_WIDTH,
G_PARAM_READWRITE));
g_object_class_install_property(object_class, PROP_LABELS,
g_param_spec_pointer("labels",
"LABELS",
@ -363,6 +432,7 @@ gitg_cell_renderer_path_init(GitgCellRendererPath *self)
self->priv->lane_width = DEFAULT_LANE_WIDTH;
self->priv->dot_width = DEFAULT_DOT_WIDTH;
self->priv->triangle_width = DEFAULT_TRIANGLE_WIDTH;
}
GtkCellRenderer *

View file

@ -18,6 +18,7 @@ gitg_lane_dup(GitgLane *lane)
GitgLane *dup = g_new0(GitgLane, 1);
dup->color = gitg_color_copy(lane->color);
dup->from = g_slist_copy(lane->from);
dup->type = lane->type;
return dup;
}

View file

@ -6,8 +6,10 @@
enum {
GITG_LANE_TYPE_NONE,
GITG_LANE_TYPE_START,
GITG_LANE_TYPE_END
GITG_LANE_TYPE_START = 1 << 0,
GITG_LANE_TYPE_END = 1 << 1,
GITG_LANE_SIGN_LEFT = 1 << 2,
GITG_LANE_SIGN_RIGHT = 1 << 3
};
typedef struct _GitgLane

View file

@ -396,18 +396,22 @@ on_loader_update(GitgRunner *object, gchar **buffer, GitgRepository *self)
{
// New line is read
gchar **components = g_strsplit(line, "\01", 0);
guint len = g_strv_length(components);
if (g_strv_length(components) < 5)
if (len < 5)
{
g_strfreev(components);
continue;
}
// components -> [hash, author, subject, parents ([1 2 3]), timestamp]
// components -> [hash, author, subject, parents ([1 2 3]), timestamp[, leftright]]
gint64 timestamp = g_ascii_strtoll(components[4], NULL, 0);
GitgRevision *rv = gitg_revision_new(components[0], components[1], components[2], components[3], timestamp);
GSList *lanes;
if (len > 5 && strlen(components[5]) == 1 && strchr("<>-^", *components[5]) != NULL)
gitg_revision_set_sign(rv, *components[5]);
gint8 mylane = 0;
@ -416,8 +420,7 @@ on_loader_update(GitgRunner *object, gchar **buffer, GitgRepository *self)
lanes = gitg_lanes_next(self->priv->lanes, rv, &mylane);
gitg_revision_set_lanes(rv, lanes);
gitg_revision_set_mylane(rv, mylane);
gitg_revision_set_lanes(rv, lanes, mylane);
gitg_repository_add(self, rv, NULL);
@ -522,6 +525,18 @@ on_refs_update(GitgRunner *runner, gchar **buffer, GitgRepository *self)
}
}
static gboolean
has_left_right(gchar const **av, int argc)
{
int i;
for (i = 0; i < argc; ++i)
if (strcmp(av[i], "--left-right") == 0)
return TRUE;
return FALSE;
}
gboolean
gitg_repository_load(GitgRepository *self, int argc, gchar const **av, GError **error)
{
@ -557,7 +572,11 @@ gitg_repository_load(GitgRepository *self, int argc, gchar const **av, GError **
g_object_unref(refs_runner);
argv[3] = "log";
argv[4] = "--pretty=format:%H\01%an\01%s\01%P\01%at";
if (has_left_right(av, argc))
argv[4] = "--pretty=format:%H%x01%an%x01%s%x01%P%x01%at%x01%m";
else
argv[4] ="--pretty=format:%H%x01%an%x01%s%x01%P%x01%at";
if (argc <= 0)
argv[5] = "HEAD";

View file

@ -10,6 +10,7 @@ struct _GitgRevision
gchar *subject;
Hash *parents;
guint num_parents;
char sign;
GSList *lanes;
gint8 mylane;
@ -149,11 +150,32 @@ gitg_revision_get_lanes(GitgRevision *revision)
return g_slist_copy(revision->lanes);
}
static void
update_lane_type(GitgRevision *revision)
{
GitgLane *lane = (GitgLane *)g_slist_nth_data(revision->lanes, revision->mylane);
if (lane == NULL)
return;
lane->type &= ~(GITG_LANE_SIGN_LEFT | GITG_LANE_SIGN_RIGHT);
if (revision->sign == '<')
lane->type |= GITG_LANE_SIGN_LEFT;
else if (revision->sign == '>')
lane->type |= GITG_LANE_SIGN_RIGHT;
}
void
gitg_revision_set_lanes(GitgRevision *revision, GSList *lanes)
gitg_revision_set_lanes(GitgRevision *revision, GSList *lanes, gint8 mylane)
{
free_lanes(revision);
revision->lanes = lanes;
if (mylane > 0)
revision->mylane = mylane;
update_lane_type(revision);
}
gint8
@ -166,6 +188,19 @@ void
gitg_revision_set_mylane(GitgRevision *revision, gint8 mylane)
{
revision->mylane = mylane;
update_lane_type(revision);
}
void
gitg_revision_set_sign(GitgRevision *revision, char sign)
{
revision->sign = sign;
}
char
gitg_revision_get_sign(GitgRevision *revision)
{
return revision->sign;
}
GType

View file

@ -29,11 +29,14 @@ gchar *gitg_revision_get_sha1(GitgRevision *revision);
gchar **gitg_revision_get_parents(GitgRevision *revision);
GSList *gitg_revision_get_lanes(GitgRevision *revision);
void gitg_revision_set_lanes(GitgRevision *revision, GSList *lanes);
void gitg_revision_set_lanes(GitgRevision *revision, GSList *lanes, gint8 mylane);
gint8 gitg_revision_get_mylane(GitgRevision *revision);
void gitg_revision_set_mylane(GitgRevision *revision, gint8 mylane);
void gitg_revision_set_sign(GitgRevision *revision, char sign);
char gitg_revision_get_sign(GitgRevision *revision);
GitgRevision *gitg_revision_ref(GitgRevision *revision);
void gitg_revision_unref(GitgRevision *revision);