[sysprof] callgraph: allow going backward with alt+left arrow



commit 172a1b772d099f43fce657c647eaf525964b21a5
Author: Christian Hergert <chergert redhat com>
Date:   Wed Apr 13 06:31:30 2016 -0700

    callgraph: allow going backward with alt+left arrow
    
    Sometimes its really annoying to dive into a descendant and then want to
    go back to where you were. This uses alt+left arrow to go back to the
    previous node. It doesn't, however, re-expand the tree to the previous
    state.

 lib/sp-callgraph-view.c |   42 ++++++++++++++++++++++++++++++++++++++++++
 lib/sp-callgraph-view.h |    4 ++++
 2 files changed, 46 insertions(+), 0 deletions(-)
---
diff --git a/lib/sp-callgraph-view.c b/lib/sp-callgraph-view.c
index 84323b5..c7d57df 100644
--- a/lib/sp-callgraph-view.c
+++ b/lib/sp-callgraph-view.c
@@ -51,6 +51,8 @@ typedef struct
   GtkTreeView         *descendants_view;
   GtkTreeViewColumn   *descendants_name_column;
 
+  GQueue              *history;
+
   guint                profile_size;
 } SpCallgraphViewPrivate;
 
@@ -63,6 +65,11 @@ enum {
 };
 
 enum {
+  GO_PREVIOUS,
+  N_SIGNALS
+};
+
+enum {
   COLUMN_NAME,
   COLUMN_SELF,
   COLUMN_TOTAL,
@@ -74,6 +81,7 @@ static void sp_callgraph_view_update_descendants (SpCallgraphView *self,
                                                   StackNode       *node);
 
 static GParamSpec *properties [N_PROPS];
+static guint signals [N_SIGNALS];
 
 static guint
 sp_callgraph_view_get_profile_size (SpCallgraphView *self)
@@ -201,6 +209,7 @@ sp_callgraph_view_unload (SpCallgraphView *self)
   g_assert (SP_IS_CALLGRAPH_VIEW (self));
   g_assert (SP_IS_CALLGRAPH_PROFILE (priv->profile));
 
+  g_queue_clear (priv->history);
   g_clear_object (&priv->profile);
   priv->profile_size = 0;
 }
@@ -593,11 +602,26 @@ sp_callgraph_view_tag_data_func (GtkTreeViewColumn *column,
 }
 
 static void
+sp_callgraph_view_real_go_previous (SpCallgraphView *self)
+{
+  SpCallgraphViewPrivate *priv = sp_callgraph_view_get_instance_private (self);
+  StackNode *node;
+
+  g_assert (SP_IS_CALLGRAPH_VIEW (self));
+
+  node = g_queue_pop_head (priv->history);
+
+  if (NULL != (node = g_queue_peek_head (priv->history)))
+    sp_callgraph_view_set_node (self, node);
+}
+
+static void
 sp_callgraph_view_finalize (GObject *object)
 {
   SpCallgraphView *self = (SpCallgraphView *)object;
   SpCallgraphViewPrivate *priv = sp_callgraph_view_get_instance_private (self);
 
+  g_clear_pointer (&priv->history, g_queue_free);
   g_clear_object (&priv->profile);
 
   G_OBJECT_CLASS (sp_callgraph_view_parent_class)->finalize (object);
@@ -647,11 +671,14 @@ sp_callgraph_view_class_init (SpCallgraphViewClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+  GtkBindingSet *bindings;
 
   object_class->finalize = sp_callgraph_view_finalize;
   object_class->get_property = sp_callgraph_view_get_property;
   object_class->set_property = sp_callgraph_view_set_property;
 
+  klass->go_previous = sp_callgraph_view_real_go_previous;
+
   properties [PROP_PROFILE] =
     g_param_spec_object ("profile",
                          "Profile",
@@ -661,6 +688,13 @@ sp_callgraph_view_class_init (SpCallgraphViewClass *klass)
 
   g_object_class_install_properties (object_class, N_PROPS, properties);
 
+  signals [GO_PREVIOUS] =
+    g_signal_new ("go-previous",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                  G_STRUCT_OFFSET (SpCallgraphViewClass, go_previous),
+                  NULL, NULL, NULL, G_TYPE_NONE, 0);
+
   gtk_widget_class_set_template_from_resource (widget_class,
                                                "/org/gnome/sysprof/ui/sp-callgraph-view.ui");
 
@@ -668,6 +702,9 @@ sp_callgraph_view_class_init (SpCallgraphViewClass *klass)
   gtk_widget_class_bind_template_child_private (widget_class, SpCallgraphView, functions_view);
   gtk_widget_class_bind_template_child_private (widget_class, SpCallgraphView, descendants_view);
   gtk_widget_class_bind_template_child_private (widget_class, SpCallgraphView, descendants_name_column);
+
+  bindings = gtk_binding_set_by_class (klass);
+  gtk_binding_entry_add_signal (bindings, GDK_KEY_Left, GDK_MOD1_MASK, "go-previous", 0);
 }
 
 static void
@@ -677,6 +714,8 @@ sp_callgraph_view_init (SpCallgraphView *self)
   GtkTreeSelection *selection;
   GtkCellRenderer *cell;
 
+  priv->history = g_queue_new ();
+
   gtk_widget_init_template (GTK_WIDGET (self));
 
   selection = gtk_tree_view_get_selection (priv->functions_view);
@@ -851,6 +890,9 @@ sp_callgraph_view_update_descendants (SpCallgraphView *self,
 
   g_assert (SP_IS_CALLGRAPH_VIEW (self));
 
+  if (g_queue_peek_head (priv->history) != node)
+    g_queue_push_head (priv->history, node);
+
   store = gtk_tree_store_new (4,
                               G_TYPE_STRING,
                               G_TYPE_DOUBLE,
diff --git a/lib/sp-callgraph-view.h b/lib/sp-callgraph-view.h
index 8e9898e..916f7c8 100644
--- a/lib/sp-callgraph-view.h
+++ b/lib/sp-callgraph-view.h
@@ -32,6 +32,10 @@ G_DECLARE_DERIVABLE_TYPE (SpCallgraphView, sp_callgraph_view, SP, CALLGRAPH_VIEW
 struct _SpCallgraphViewClass
 {
   GtkBinClass parent_class;
+
+  void (*go_previous) (SpCallgraphView *self);
+
+  gpointer padding[8];
 };
 
 GtkWidget          *sp_callgraph_view_new         (void);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]