diff --git a/src/libsysprof-gtk/meson.build b/src/libsysprof-gtk/meson.build index bb6b2dc3..19bb812b 100644 --- a/src/libsysprof-gtk/meson.build +++ b/src/libsysprof-gtk/meson.build @@ -63,6 +63,7 @@ libsysprof_gtk_public_headers = [ ] libsysprof_gtk_private_sources = [ + 'sysprof-counter-track.c', 'sysprof-css.c', 'sysprof-mark-chart-item.c', 'sysprof-mark-chart-row.c', diff --git a/src/libsysprof-gtk/sysprof-counter-track-private.h b/src/libsysprof-gtk/sysprof-counter-track-private.h new file mode 100644 index 00000000..8f45686b --- /dev/null +++ b/src/libsysprof-gtk/sysprof-counter-track-private.h @@ -0,0 +1,35 @@ +/* sysprof-counter-track-private.h + * + * Copyright 2023 Christian Hergert + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include "sysprof-track.h" + +G_BEGIN_DECLS + +#define SYSPROF_TYPE_COUNTER_TRACK (sysprof_counter_track_get_type()) + +G_DECLARE_FINAL_TYPE (SysprofCounterTrack, sysprof_counter_track, SYSPROF, COUNTER_TRACK, SysprofTrack) + +SysprofTrack *sysprof_counter_track_new (SysprofSession *session, + const char *title, + SysprofDocumentCounter *counter); + +G_END_DECLS diff --git a/src/libsysprof-gtk/sysprof-counter-track.c b/src/libsysprof-gtk/sysprof-counter-track.c new file mode 100644 index 00000000..2bb9d031 --- /dev/null +++ b/src/libsysprof-gtk/sysprof-counter-track.c @@ -0,0 +1,119 @@ +/* sysprof-counter-track.c + * + * Copyright 2023 Christian Hergert + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include "config.h" + +#include "sysprof-counter-track-private.h" +#include "sysprof-chart.h" +#include "sysprof-line-layer.h" +#include "sysprof-value-axis.h" +#include "sysprof-xy-series.h" + +struct _SysprofCounterTrack +{ + SysprofTrack parent_instance; + SysprofDocumentCounter *counter; +}; + +G_DEFINE_FINAL_TYPE (SysprofCounterTrack, sysprof_counter_track, SYSPROF_TYPE_TRACK) + +static GtkWidget * +sysprof_counter_track_create_chart (SysprofTrack *track) +{ + SysprofCounterTrack *self = (SysprofCounterTrack *)track; + SysprofSession *session = NULL; + g_autoptr(SysprofSeries) xy_series = NULL; + g_autoptr(SysprofAxis) x_axis = NULL; + g_autoptr(SysprofAxis) y_axis = NULL; + SysprofChartLayer *layer; + SysprofChart *chart; + + g_assert (SYSPROF_IS_COUNTER_TRACK (self)); + + if (!(session = sysprof_track_get_session (track))) + return NULL; + + x_axis = sysprof_session_get_visible_time_axis (session); + y_axis = sysprof_value_axis_new (sysprof_document_counter_get_min_value (self->counter), + sysprof_document_counter_get_max_value (self->counter)); + xy_series = sysprof_xy_series_new (sysprof_track_get_title (track), + G_LIST_MODEL (self->counter), + gtk_property_expression_new (SYSPROF_TYPE_DOCUMENT_COUNTER_VALUE, NULL, "time"), + gtk_property_expression_new (SYSPROF_TYPE_DOCUMENT_COUNTER_VALUE, NULL, "value-double")); + + chart = g_object_new (SYSPROF_TYPE_CHART, NULL); + layer = g_object_new (SYSPROF_TYPE_LINE_LAYER, + "spline", TRUE, + "series", xy_series, + "x-axis", x_axis, + "y-axis", y_axis, + NULL); + sysprof_chart_add_layer (chart, layer); + + return GTK_WIDGET (chart); +} + +static void +sysprof_counter_track_dispose (GObject *object) +{ + SysprofCounterTrack *self = (SysprofCounterTrack *)object; + + g_clear_object (&self->counter); + + G_OBJECT_CLASS (sysprof_counter_track_parent_class)->dispose (object); +} + +static void +sysprof_counter_track_class_init (SysprofCounterTrackClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + SysprofTrackClass *track_class = SYSPROF_TRACK_CLASS (klass); + + object_class->dispose = sysprof_counter_track_dispose; + + track_class->create_chart = sysprof_counter_track_create_chart; +} + +static void +sysprof_counter_track_init (SysprofCounterTrack *self) +{ +} + +SysprofTrack * +sysprof_counter_track_new (SysprofSession *session, + const char *title, + SysprofDocumentCounter *counter) +{ + SysprofCounterTrack *self; + + g_return_val_if_fail (SYSPROF_IS_DOCUMENT_COUNTER (counter), NULL); + + if (title == NULL) + title = sysprof_document_counter_get_name (counter); + + self = g_object_new (SYSPROF_TYPE_COUNTER_TRACK, + "session", session, + "title", title, + NULL); + + self->counter = g_object_ref (counter); + + return SYSPROF_TRACK (self); +} diff --git a/src/libsysprof-gtk/sysprof-session-discover.c b/src/libsysprof-gtk/sysprof-session-discover.c index b3fca200..45e756c1 100644 --- a/src/libsysprof-gtk/sysprof-session-discover.c +++ b/src/libsysprof-gtk/sysprof-session-discover.c @@ -22,6 +22,7 @@ #include +#include "sysprof-counter-track-private.h" #include "sysprof-session-private.h" #include "sysprof-track.h" @@ -94,9 +95,9 @@ _sysprof_session_discover_tracks (SysprofSession *self, g_autoptr(SysprofTrack) track = NULL; g_autoptr(GListModel) subcounters = NULL; - track = g_object_new (SYSPROF_TYPE_TRACK, - "title", g_dgettext (GETTEXT_PACKAGE, info->track_name), - NULL); + track = sysprof_counter_track_new (self, + g_dgettext (GETTEXT_PACKAGE, info->track_name), + counter); if ((subcounters = filter_counters (counters, info->category, info->subtracks_name_glob))) { diff --git a/src/libsysprof-gtk/sysprof-track-private.h b/src/libsysprof-gtk/sysprof-track-private.h index 1467451c..cae00540 100644 --- a/src/libsysprof-gtk/sysprof-track-private.h +++ b/src/libsysprof-gtk/sysprof-track-private.h @@ -24,7 +24,8 @@ G_BEGIN_DECLS -void _sysprof_track_add_subtrack (SysprofTrack *self, - SysprofTrack *subtrack); +GtkWidget *_sysprof_track_create_chart (SysprofTrack *track); +void _sysprof_track_add_subtrack (SysprofTrack *self, + SysprofTrack *subtrack); G_END_DECLS diff --git a/src/libsysprof-gtk/sysprof-track-view.c b/src/libsysprof-gtk/sysprof-track-view.c index e60ea849..af9e2eb9 100644 --- a/src/libsysprof-gtk/sysprof-track-view.c +++ b/src/libsysprof-gtk/sysprof-track-view.c @@ -20,6 +20,7 @@ #include "config.h" +#include "sysprof-track-private.h" #include "sysprof-track-view.h" struct _SysprofTrackView @@ -149,5 +150,15 @@ sysprof_track_view_set_track (SysprofTrackView *self, g_return_if_fail (!track || SYSPROF_IS_TRACK (track)); if (g_set_object (&self->track, track)) - g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TRACK]); + { + GtkWidget *child; + + while ((child = gtk_widget_get_first_child (GTK_WIDGET (self)))) + gtk_widget_unparent (child); + + if ((child = _sysprof_track_create_chart (track))) + gtk_widget_set_parent (child, GTK_WIDGET (self)); + + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TRACK]); + } } diff --git a/src/libsysprof-gtk/sysprof-track-view.ui b/src/libsysprof-gtk/sysprof-track-view.ui index 7b2bfa3f..23f4e1cd 100644 --- a/src/libsysprof-gtk/sysprof-track-view.ui +++ b/src/libsysprof-gtk/sysprof-track-view.ui @@ -1,21 +1,5 @@ diff --git a/src/libsysprof-gtk/sysprof-track.c b/src/libsysprof-gtk/sysprof-track.c index ffaf5dbe..25fd857d 100644 --- a/src/libsysprof-gtk/sysprof-track.c +++ b/src/libsysprof-gtk/sysprof-track.c @@ -24,12 +24,16 @@ typedef struct _SysprofTrackPrivate { - GListStore *subtracks; - char *title; + SysprofSession *session; + char *title; + GListStore *subtracks; + GMenuModel *menu_model; } SysprofTrackPrivate; enum { PROP_0, + PROP_MENU_MODEL, + PROP_SESSION, PROP_SUBTRACKS, PROP_TITLE, N_PROPS @@ -45,8 +49,10 @@ sysprof_track_dispose (GObject *object) SysprofTrack *self = (SysprofTrack *)object; SysprofTrackPrivate *priv = sysprof_track_get_instance_private (self); + g_clear_object (&priv->menu_model); g_clear_object (&priv->subtracks); g_clear_pointer (&priv->title, g_free); + g_clear_weak_pointer (&priv->session); G_OBJECT_CLASS (sysprof_track_parent_class)->dispose (object); } @@ -61,6 +67,14 @@ sysprof_track_get_property (GObject *object, switch (prop_id) { + case PROP_MENU_MODEL: + g_value_set_object (value, sysprof_track_get_menu_model (self)); + break; + + case PROP_SESSION: + g_value_set_object (value, sysprof_track_get_session (self)); + break; + case PROP_SUBTRACKS: g_value_take_object (value, sysprof_track_list_subtracks (self)); break; @@ -85,6 +99,14 @@ sysprof_track_set_property (GObject *object, switch (prop_id) { + case PROP_MENU_MODEL: + priv->menu_model = g_value_dup_object (value); + break; + + case PROP_SESSION: + g_set_weak_pointer (&priv->session, g_value_get_object (value)); + break; + case PROP_TITLE: priv->title = g_value_dup_string (value); break; @@ -103,6 +125,16 @@ sysprof_track_class_init (SysprofTrackClass *klass) object_class->get_property = sysprof_track_get_property; object_class->set_property = sysprof_track_set_property; + properties [PROP_MENU_MODEL] = + g_param_spec_object ("menu-model", NULL, NULL, + G_TYPE_MENU_MODEL, + (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + + properties [PROP_SESSION] = + g_param_spec_object ("session", NULL, NULL, + SYSPROF_TYPE_SESSION, + (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + properties[PROP_SUBTRACKS] = g_param_spec_object ("subtracks", NULL, NULL, G_TYPE_LIST_MODEL, @@ -162,3 +194,45 @@ sysprof_track_list_subtracks (SysprofTrack *self) return g_object_ref (G_LIST_MODEL (priv->subtracks)); } + +/** + * sysprof_track_get_session: + * @self: a #SysprofTrack + * + * Returns: (transfer none) (nullable): a #SysprofSession or %NULL + */ +SysprofSession * +sysprof_track_get_session (SysprofTrack *self) +{ + SysprofTrackPrivate *priv = sysprof_track_get_instance_private (self); + + g_return_val_if_fail (SYSPROF_IS_TRACK (self), NULL); + + return priv->session; +} + +/** + * sysprof_track_get_menu_model: + * @self: a #SysprofTrack + * + * Gets the optional menu model for a track. + * + * Returns: (transfer none) (nullable): a #GMenuModel or %NULL + */ +GMenuModel * +sysprof_track_get_menu_model (SysprofTrack *self) +{ + SysprofTrackPrivate *priv = sysprof_track_get_instance_private (self); + + g_return_val_if_fail (SYSPROF_IS_TRACK (self), NULL); + + return priv->menu_model; +} + +GtkWidget * +_sysprof_track_create_chart (SysprofTrack *self) +{ + g_return_val_if_fail (SYSPROF_IS_TRACK (self), NULL); + + return SYSPROF_TRACK_GET_CLASS (self)->create_chart (self); +} diff --git a/src/libsysprof-gtk/sysprof-track.h b/src/libsysprof-gtk/sysprof-track.h index b91b37e6..9c83ca20 100644 --- a/src/libsysprof-gtk/sysprof-track.h +++ b/src/libsysprof-gtk/sysprof-track.h @@ -24,6 +24,8 @@ #include +#include "sysprof-session.h" + G_BEGIN_DECLS #define SYSPROF_TYPE_TRACK (sysprof_track_get_type()) @@ -42,12 +44,12 @@ struct _SysprofTrackClass }; SYSPROF_AVAILABLE_IN_ALL -const char *sysprof_track_get_title (SysprofTrack *self); +SysprofSession *sysprof_track_get_session (SysprofTrack *self); SYSPROF_AVAILABLE_IN_ALL -GListModel *sysprof_track_list_subtracks (SysprofTrack *self); +const char *sysprof_track_get_title (SysprofTrack *self); SYSPROF_AVAILABLE_IN_ALL -GMenuModel *sysprof_track_get_menu_model (SysprofTrack *self); +GListModel *sysprof_track_list_subtracks (SysprofTrack *self); SYSPROF_AVAILABLE_IN_ALL -GtkWidget *sysprof_track_create_chart (SysprofTrack *self); +GMenuModel *sysprof_track_get_menu_model (SysprofTrack *self); G_END_DECLS diff --git a/src/libsysprof-gtk/sysprof-tracks-view.ui b/src/libsysprof-gtk/sysprof-tracks-view.ui index d0c3e3e3..eab29df0 100644 --- a/src/libsysprof-gtk/sysprof-tracks-view.ui +++ b/src/libsysprof-gtk/sysprof-tracks-view.ui @@ -35,12 +35,78 @@