diff --git a/gtk/inspector/Makefile.am b/gtk/inspector/Makefile.am index bc16e6a708..4371d4cc99 100644 --- a/gtk/inspector/Makefile.am +++ b/gtk/inspector/Makefile.am @@ -54,6 +54,8 @@ libgtkinspector_la_SOURCES = \ signals-list.c \ size-groups.h \ size-groups.c \ + statistics.h \ + statistics.c \ visual.h \ visual.c \ window.h \ @@ -100,6 +102,7 @@ templates = \ prop-list.ui \ resource-list.ui \ signals-list.ui \ + statistics.ui \ style-prop-list.ui \ visual.ui \ window.ui diff --git a/gtk/inspector/init.c b/gtk/inspector/init.c index 6ba9ca2402..ce26a199fe 100644 --- a/gtk/inspector/init.c +++ b/gtk/inspector/init.c @@ -39,6 +39,7 @@ #include "resources.h" #include "signals-list.h" #include "size-groups.h" +#include "statistics.h" #include "style-prop-list.h" #include "visual.h" #include "window.h" @@ -61,8 +62,9 @@ gtk_inspector_init (void) g_type_ensure (GTK_TYPE_INSPECTOR_PROP_LIST); g_type_ensure (GTK_TYPE_INSPECTOR_RESOURCE_LIST); g_type_ensure (GTK_TYPE_INSPECTOR_SIGNALS_LIST); - g_type_ensure (GTK_TYPE_INSPECTOR_STYLE_PROP_LIST); g_type_ensure (GTK_TYPE_INSPECTOR_SIZE_GROUPS); + g_type_ensure (GTK_TYPE_INSPECTOR_STATISTICS); + g_type_ensure (GTK_TYPE_INSPECTOR_STYLE_PROP_LIST); g_type_ensure (GTK_TYPE_INSPECTOR_VISUAL); g_type_ensure (GTK_TYPE_INSPECTOR_WINDOW); } diff --git a/gtk/inspector/inspector.gresource.xml b/gtk/inspector/inspector.gresource.xml index 592b9706b6..0b9f552c00 100644 --- a/gtk/inspector/inspector.gresource.xml +++ b/gtk/inspector/inspector.gresource.xml @@ -11,9 +11,10 @@ object-hierarchy.ui object-tree.ui prop-list.ui + signals-list.ui + statistics.ui style-prop-list.ui resource-list.ui - signals-list.ui visual.ui window.ui logo.png diff --git a/gtk/inspector/statistics.c b/gtk/inspector/statistics.c new file mode 100644 index 0000000000..0427c5d41d --- /dev/null +++ b/gtk/inspector/statistics.c @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2014 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include "config.h" +#include + +#include "statistics.h" + +#include "gtkstack.h" +#include "gtktreeview.h" +#include "gtkcellrenderertext.h" +#include "gtkcelllayout.h" + +struct _GtkInspectorStatisticsPrivate +{ + GtkWidget *stack; + GtkTreeModel *model; + GtkTreeView *view; + GtkTreeViewColumn *column_self; + GtkCellRenderer *renderer_self; + GtkTreeViewColumn *column_cumulative; + GtkCellRenderer *renderer_cumulative; + GtkWidget *button; +}; + +enum +{ + COLUMN_TYPE, + COLUMN_SELF, + COLUMN_CUMULATIVE +}; + +G_DEFINE_TYPE_WITH_PRIVATE (GtkInspectorStatistics, gtk_inspector_statistics, GTK_TYPE_BOX) + +static void +cell_data_func (GtkCellLayout *layout, + GtkCellRenderer *cell, + GtkTreeModel *model, + GtkTreeIter *iter, + gpointer data) +{ + gint column; + gint count; + gchar *text; + + column = GPOINTER_TO_INT (data); + + gtk_tree_model_get (model, iter, column, &count, -1); + + text = g_strdup_printf ("%d", count); + g_object_set (cell, "text", text, NULL); + g_free (text); +} + +static gint +add_type_count (GtkInspectorStatistics *sl, GType type) +{ + gint cumulative; + gint self; + GType *children; + guint n_children; + GtkTreeIter iter; + gint i; + + cumulative = 0; + + children = g_type_children (type, &n_children); + for (i = 0; i < n_children; i++) + cumulative += add_type_count (sl, children[i]); + + self = g_type_get_instance_count (type); + cumulative += self; + gtk_list_store_append (GTK_LIST_STORE (sl->priv->model), &iter); + gtk_list_store_set (GTK_LIST_STORE (sl->priv->model), &iter, + COLUMN_TYPE, g_type_name (type), + COLUMN_SELF, self, + COLUMN_CUMULATIVE, cumulative, + -1); + + return cumulative; +} + +static void +refresh_clicked (GtkWidget *button, GtkInspectorStatistics *sl) +{ + GType type; + gpointer class; + + gtk_list_store_clear (GTK_LIST_STORE (sl->priv->model)); + + for (type = G_TYPE_INTERFACE; type <= G_TYPE_FUNDAMENTAL_MAX; type += G_TYPE_FUNDAMENTAL_SHIFT) + { + class = g_type_class_peek (type); + if (class == NULL) + continue; + + if (!G_TYPE_IS_INSTANTIATABLE (type)) + continue; + + add_type_count (sl, type); + } +} + +static gboolean +has_instance_counts (void) +{ + const gchar *string; + guint flags = 0; + + string = g_getenv ("GOBJECT_DEBUG"); + if (string != NULL) + { + GDebugKey debug_keys[] = { + { "objects", 1 }, + { "instance-count", 2 }, + { "signals", 4 } + }; + + flags = g_parse_debug_string (string, debug_keys, G_N_ELEMENTS (debug_keys)); + } + + return (flags & 2) != 0; +} + +static void +gtk_inspector_statistics_init (GtkInspectorStatistics *sl) +{ + sl->priv = gtk_inspector_statistics_get_instance_private (sl); + gtk_widget_init_template (GTK_WIDGET (sl)); + gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (sl->priv->column_self), + sl->priv->renderer_self, + cell_data_func, + GINT_TO_POINTER (COLUMN_SELF), NULL); + gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (sl->priv->column_cumulative), + sl->priv->renderer_cumulative, + cell_data_func, + GINT_TO_POINTER (COLUMN_CUMULATIVE), NULL); + if (has_instance_counts ()) + add_type_count (sl, G_TYPE_OBJECT); + else + gtk_stack_set_visible_child_name (GTK_STACK (sl->priv->stack), "excuse"); +} + +static void +gtk_inspector_statistics_class_init (GtkInspectorStatisticsClass *klass) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/inspector/statistics.ui"); + gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorStatistics, view); + gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorStatistics, stack); + gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorStatistics, model); + gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorStatistics, column_self); + gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorStatistics, renderer_self); + gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorStatistics, column_cumulative); + gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorStatistics, renderer_cumulative); + gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorStatistics, button); + gtk_widget_class_bind_template_callback (widget_class, refresh_clicked); +} + +// vim: set et sw=2 ts=2: diff --git a/gtk/inspector/statistics.h b/gtk/inspector/statistics.h new file mode 100644 index 0000000000..1df3264905 --- /dev/null +++ b/gtk/inspector/statistics.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2014 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#ifndef _GTK_INSPECTOR_STATISTICS_H_ +#define _GTK_INSPECTOR_STATISTICS_H_ + +#include + +#define GTK_TYPE_INSPECTOR_STATISTICS (gtk_inspector_statistics_get_type()) +#define GTK_INSPECTOR_STATISTICS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_INSPECTOR_STATISTICS, GtkInspectorStatistics)) +#define GTK_INSPECTOR_STATISTICS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_INSPECTOR_STATISTICS, GtkInspectorStatisticsClass)) +#define GTK_INSPECTOR_IS_STATISTICS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_INSPECTOR_STATISTICS)) +#define GTK_INSPECTOR_IS_STATISTICS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_INSPECTOR_STATISTICS)) +#define GTK_INSPECTOR_STATISTICS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_INSPECTOR_STATISTICS, GtkInspectorStatisticsClass)) + + +typedef struct _GtkInspectorStatisticsPrivate GtkInspectorStatisticsPrivate; + +typedef struct _GtkInspectorStatistics +{ + GtkBox parent; + GtkInspectorStatisticsPrivate *priv; +} GtkInspectorStatistics; + +typedef struct _GtkInspectorStatisticsClass +{ + GtkBoxClass parent; +} GtkInspectorStatisticsClass; + +G_BEGIN_DECLS + +GType gtk_inspector_statistics_get_type (void); + +G_END_DECLS + +#endif // _GTK_INSPECTOR_STATISTICS_H_ + +// vim: set et sw=2 ts=2: diff --git a/gtk/inspector/statistics.ui b/gtk/inspector/statistics.ui new file mode 100644 index 0000000000..0c79d05c1e --- /dev/null +++ b/gtk/inspector/statistics.ui @@ -0,0 +1,107 @@ + + + + + + + + + + + diff --git a/gtk/inspector/statistics.ui.h b/gtk/inspector/statistics.ui.h new file mode 100644 index 0000000000..ad38e80871 --- /dev/null +++ b/gtk/inspector/statistics.ui.h @@ -0,0 +1,5 @@ +N_("Refresh"); +N_("Type"); +N_("Self"); +N_("Cumulative"); +N_("Enable statistics with GOBJECT_DEBUG=instance-count"); diff --git a/gtk/inspector/window.ui b/gtk/inspector/window.ui index fb3e597e93..582c03a3cc 100644 --- a/gtk/inspector/window.ui +++ b/gtk/inspector/window.ui @@ -245,6 +245,15 @@ Objects + + + True + + + statistics + Statistics + + True diff --git a/gtk/inspector/window.ui.h b/gtk/inspector/window.ui.h index 98870a84b3..be9b3cce44 100644 --- a/gtk/inspector/window.ui.h +++ b/gtk/inspector/window.ui.h @@ -15,6 +15,7 @@ N_("Actions"); N_("Menu"); N_("Gestures"); N_("Objects"); +N_("Statistics"); N_("Resources"); N_("Custom CSS"); N_("Visual");