summaryrefslogtreecommitdiff
path: root/src/callgraph.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/callgraph.c')
-rw-r--r--src/callgraph.c149
1 files changed, 147 insertions, 2 deletions
diff --git a/src/callgraph.c b/src/callgraph.c
index 97d1970..bfa1e02 100644
--- a/src/callgraph.c
+++ b/src/callgraph.c
@@ -547,6 +547,125 @@ cell_renderer_distribution_init (CellRendererDistribution *self)
}
+typedef struct _CellRendererFraction {
+ GtkCellRenderer renderer;
+
+ gdouble fraction;
+} CellRendererFraction;
+typedef struct _CellRendererFractionClass {
+ GtkCellRendererClass parent_class;
+} CellRendererFractionClass;
+
+static GType
+cell_renderer_fraction_get_type (void);
+
+G_DEFINE_TYPE (CellRendererFraction, cell_renderer_fraction, GTK_TYPE_CELL_RENDERER)
+
+static void
+cell_renderer_fraction_get_size (GtkCellRenderer *cell,
+ GtkWidget *widget,
+ GdkRectangle *rectangle,
+ gint *x_offset,
+ gint *y_offset,
+ gint *width,
+ gint *height)
+{
+ if (x_offset)
+ *x_offset = 0;
+ if (y_offset)
+ *y_offset = 0;
+ if (width)
+ *width = 16;
+ if (height)
+ *height = 16;
+}
+
+static void
+cell_renderer_fraction_render (GtkCellRenderer *cell,
+ GdkDrawable *window,
+ GtkWidget *widget,
+ GdkRectangle *background_area,
+ GdkRectangle *cell_area,
+ GdkRectangle *expose_area,
+ GtkCellRendererState flags)
+{
+ CellRendererFraction *self = (CellRendererFraction *) cell;
+ cairo_t *cr = gdk_cairo_create (window);
+
+ cairo_translate (cr, cell_area->x, cell_area->y);
+
+ cairo_new_path (cr);
+ cairo_arc (cr, 8, 8, 6, 0, 2 * G_PI);
+ cairo_set_line_width (cr, 1);
+ cairo_stroke (cr);
+
+ cairo_move_to (cr, 8, 8);
+ cairo_arc (cr, 8, 8, 6, -G_PI/2, self->fraction * 2 * G_PI - G_PI/2);
+ cairo_fill (cr);
+
+ cairo_destroy (cr);
+}
+
+enum {
+ CRF_PROP_0 = 0,
+ CRF_PROP_FRACTION
+};
+
+static void
+cell_renderer_fraction_set_property (GObject *obj, guint id, const GValue *v, GParamSpec *spec)
+{
+ CellRendererFraction *self = (CellRendererFraction *) obj;
+ switch (id) {
+ case CRF_PROP_FRACTION:
+ self->fraction = g_value_get_double (v);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, spec);
+ break;
+ }
+}
+
+static void
+cell_renderer_fraction_class_init (CellRendererFractionClass *klass)
+{
+ GObjectClass *object_class = (GObjectClass *) klass;
+ GtkCellRendererClass *cell_class = (GtkCellRendererClass *) klass;
+
+ cell_class->get_size = cell_renderer_fraction_get_size;
+ cell_class->render = cell_renderer_fraction_render;
+
+ object_class->set_property = cell_renderer_fraction_set_property;
+
+ g_object_class_install_property (object_class,
+ CRF_PROP_FRACTION,
+ g_param_spec_double ("fraction",
+ _("fraction"),
+ _("Fraction"),
+ 0, 1., .5,
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_WRITABLE));
+}
+
+static void
+cell_renderer_fraction_init (CellRendererFraction *self)
+{
+}
+
+
+static void
+render_frame_fraction (GtkCellLayout *layout,
+ GtkCellRenderer *cell,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ CallGraphFrame *frame = iter->user_data;
+ g_object_set (G_OBJECT (cell),
+ "fraction", frame->filter_parent ? frame->allocs / (gdouble) frame->filter_parent->allocs : 1.,
+ NULL);
+}
static void
render_size_distribution (GtkCellLayout *layout,
GtkCellRenderer *cell,
@@ -608,20 +727,43 @@ custom_header (CallGraph *self, GtkTreeViewColumn *column)
return hbox;
}
+
+static void
+autoexpand_children (CallGraph *self, GtkTreeIter *iter, GtkTreePath *path)
+{
+ CallGraphFrame *frame = iter->user_data;
+ if (frame->n_filter == 1) {
+ GtkTreeIter child;
+
+ child.stamp = self->model->stamp;
+ child.user_data = frame->filter[0];
+ path = gtk_tree_model_get_path ((GtkTreeModel *) self->model, &child);
+ gtk_tree_view_expand_to_path (&self->tv, path);
+ gtk_tree_path_free (path);
+ }
+}
+
static void
call_graph_init (CallGraph *self)
{
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
+ column = gtk_tree_view_column_new ();
+ renderer = g_object_new (cell_renderer_fraction_get_type (), NULL);
+ gtk_tree_view_column_pack_start (column, renderer, FALSE);
+ gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (column), renderer,
+ render_frame_fraction, NULL, NULL);
+
renderer = gtk_cell_renderer_text_new ();
g_object_set (G_OBJECT (renderer),
"ellipsize", PANGO_ELLIPSIZE_END,
"ellipsize-set", TRUE,
"width-chars", 50,
NULL);
- column = gtk_tree_view_column_new_with_attributes ("Frame",
- renderer, "text", CG_FRAME, NULL);
+ gtk_tree_view_column_pack_start (column, renderer, TRUE);
+ gtk_tree_view_column_add_attribute (column, renderer, "text", CG_FRAME);
+
gtk_tree_view_column_set_widget (column, custom_header (self, column));
gtk_tree_view_column_set_expand (column, TRUE);
gtk_tree_view_append_column (&self->tv, column);
@@ -663,6 +805,9 @@ call_graph_init (CallGraph *self)
gtk_tree_view_set_enable_tree_lines (&self->tv, TRUE);
gtk_tree_view_set_rules_hint (&self->tv, TRUE);
+ g_signal_connect (&self->tv, "row-expanded",
+ G_CALLBACK (autoexpand_children), NULL);
+
gtk_widget_set_has_tooltip (GTK_WIDGET (self), TRUE);
}