From a3912b27e3d9f22bf3e2615a1be9966bdc7b7bb9 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Mon, 26 Jun 2023 15:32:54 -0700 Subject: [PATCH] libsysprof-gtk: port mark-chart to use Chart and Series --- .../libsysprof-gtk.gresource.xml | 1 + .../sysprof-mark-chart-item-private.h | 17 +- src/libsysprof-gtk/sysprof-mark-chart-item.c | 148 ++---- src/libsysprof-gtk/sysprof-mark-chart-row.c | 468 +----------------- src/libsysprof-gtk/sysprof-mark-chart-row.ui | 27 + 5 files changed, 92 insertions(+), 569 deletions(-) create mode 100644 src/libsysprof-gtk/sysprof-mark-chart-row.ui diff --git a/src/libsysprof-gtk/libsysprof-gtk.gresource.xml b/src/libsysprof-gtk/libsysprof-gtk.gresource.xml index cda23497..eae0adf8 100644 --- a/src/libsysprof-gtk/libsysprof-gtk.gresource.xml +++ b/src/libsysprof-gtk/libsysprof-gtk.gresource.xml @@ -3,6 +3,7 @@ sysprof-callgraph-view.ui sysprof-mark-chart.ui + sysprof-mark-chart-row.ui sysprof-mark-table.ui sysprof-weighted-callgraph-view.ui style.css diff --git a/src/libsysprof-gtk/sysprof-mark-chart-item-private.h b/src/libsysprof-gtk/sysprof-mark-chart-item-private.h index cca28a65..433657fa 100644 --- a/src/libsysprof-gtk/sysprof-mark-chart-item-private.h +++ b/src/libsysprof-gtk/sysprof-mark-chart-item-private.h @@ -23,6 +23,7 @@ #include #include "sysprof-session.h" +#include "sysprof-time-series.h" G_BEGIN_DECLS @@ -30,16 +31,10 @@ G_BEGIN_DECLS G_DECLARE_FINAL_TYPE (SysprofMarkChartItem, sysprof_mark_chart_item, SYSPROF, MARK_CHART_ITEM, GObject) -SysprofMarkChartItem *sysprof_mark_chart_item_new (SysprofSession *session, - SysprofMarkCatalog *catalog); -SysprofMarkCatalog *sysprof_mark_chart_item_get_catalog (SysprofMarkChartItem *self); -SysprofSession *sysprof_mark_chart_item_get_session (SysprofMarkChartItem *self); -void sysprof_mark_chart_item_load_time_series (SysprofMarkChartItem *self, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -SysprofTimeSeries *sysprof_mark_chart_item_load_time_series_finish (SysprofMarkChartItem *self, - GAsyncResult *result, - GError **error); +SysprofMarkChartItem *sysprof_mark_chart_item_new (SysprofSession *session, + SysprofMarkCatalog *catalog); +SysprofMarkCatalog *sysprof_mark_chart_item_get_catalog (SysprofMarkChartItem *self); +SysprofSession *sysprof_mark_chart_item_get_session (SysprofMarkChartItem *self); +SysprofTimeSeries *sysprof_mark_chart_item_get_series (SysprofMarkChartItem *self); G_END_DECLS diff --git a/src/libsysprof-gtk/sysprof-mark-chart-item.c b/src/libsysprof-gtk/sysprof-mark-chart-item.c index 139292bc..a2c9e813 100644 --- a/src/libsysprof-gtk/sysprof-mark-chart-item.c +++ b/src/libsysprof-gtk/sysprof-mark-chart-item.c @@ -24,37 +24,39 @@ struct _SysprofMarkChartItem { - GObject parent_instance; - SysprofSession *session; + GObject parent_instance; + SysprofSession *session; SysprofMarkCatalog *catalog; + GtkFilterListModel *filtered; + SysprofSeries *series; }; enum { PROP_0, PROP_SESSION, PROP_CATALOG, + PROP_SERIES, N_PROPS }; -enum { - CHANGED, - N_SIGNALS -}; - G_DEFINE_FINAL_TYPE (SysprofMarkChartItem, sysprof_mark_chart_item, G_TYPE_OBJECT) static GParamSpec *properties[N_PROPS]; -static guint signals[N_SIGNALS]; static void -sysprof_mark_chart_item_session_notify_selected_time_cb (SysprofMarkChartItem *self, - GParamSpec *pspec, - SysprofSession *session) +sysprof_mark_chart_item_constructed (GObject *object) { - g_assert (SYSPROF_IS_MARK_CHART_ITEM (self)); - g_assert (SYSPROF_IS_SESSION (session)); + SysprofMarkChartItem *self = (SysprofMarkChartItem *)object; - g_signal_emit (self, signals[CHANGED], 0); + G_OBJECT_CLASS (sysprof_mark_chart_item_parent_class)->constructed (object); + + if (self->catalog == NULL || self->session == NULL) + g_return_if_reached (); + + g_object_set (self->filtered, + "model", G_LIST_MODEL (self->catalog), + "filter", sysprof_session_get_filter (self->session), + NULL); } static void @@ -64,6 +66,8 @@ sysprof_mark_chart_item_dispose (GObject *object) g_clear_object (&self->session); g_clear_object (&self->catalog); + g_clear_object (&self->filtered); + g_clear_object (&self->series); G_OBJECT_CLASS (sysprof_mark_chart_item_parent_class)->dispose (object); } @@ -86,6 +90,10 @@ sysprof_mark_chart_item_get_property (GObject *object, g_value_set_object (value, sysprof_mark_chart_item_get_session (self)); break; + case PROP_SERIES: + g_value_set_object (value, sysprof_mark_chart_item_get_series (self)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -107,11 +115,6 @@ sysprof_mark_chart_item_set_property (GObject *object, case PROP_SESSION: self->session = g_value_dup_object (value); - g_signal_connect_object (self->session, - "notify::selected-time", - G_CALLBACK (sysprof_mark_chart_item_session_notify_selected_time_cb), - self, - G_CONNECT_SWAPPED); break; default: @@ -124,6 +127,7 @@ sysprof_mark_chart_item_class_init (SysprofMarkChartItemClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + object_class->constructed = sysprof_mark_chart_item_constructed; object_class->dispose = sysprof_mark_chart_item_dispose; object_class->get_property = sysprof_mark_chart_item_get_property; object_class->set_property = sysprof_mark_chart_item_set_property; @@ -138,20 +142,24 @@ sysprof_mark_chart_item_class_init (SysprofMarkChartItemClass *klass) SYSPROF_TYPE_SESSION, (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); - g_object_class_install_properties (object_class, N_PROPS, properties); + properties[PROP_SERIES] = + g_param_spec_object ("series", NULL, NULL, + SYSPROF_TYPE_TIME_SERIES, + (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - signals[CHANGED] = g_signal_new ("changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - NULL, - G_TYPE_NONE, 0); + g_object_class_install_properties (object_class, N_PROPS, properties); } static void sysprof_mark_chart_item_init (SysprofMarkChartItem *self) { + self->filtered = gtk_filter_list_model_new (NULL, NULL); + gtk_filter_list_model_set_incremental (self->filtered, TRUE); + + self->series = sysprof_time_series_new (NULL, + g_object_ref (G_LIST_MODEL (self->filtered)), + gtk_property_expression_new (SYSPROF_TYPE_DOCUMENT_MARK, NULL, "time"), + gtk_property_expression_new (SYSPROF_TYPE_DOCUMENT_MARK, NULL, "duration")); } SysprofMarkChartItem * @@ -179,92 +187,10 @@ sysprof_mark_chart_item_get_session (SysprofMarkChartItem *self) return self->session; } -typedef struct _LoadTimeSeries -{ - GListModel *model; - SysprofTimeSpan time_span; -} LoadTimeSeries; - -static void -load_time_series_free (LoadTimeSeries *state) -{ - g_clear_object (&state->model); - g_free (state); -} - -static void -load_time_series_worker (GTask *task, - gpointer source_object, - gpointer task_data, - GCancellable *cancellable) -{ - LoadTimeSeries *state = task_data; - g_autoptr(SysprofTimeSeries) series = NULL; - guint n_items; - - g_assert (G_IS_TASK (task)); - g_assert (!cancellable || G_IS_CANCELLABLE (cancellable)); - - series = sysprof_time_series_new (state->model, state->time_span); - n_items = g_list_model_get_n_items (state->model); - - for (guint i = 0; i < n_items; i++) - { - g_autoptr(SysprofDocumentMark) mark = g_list_model_get_item (state->model, i); - SysprofTimeSpan time_span; - - time_span.begin_nsec = sysprof_document_frame_get_time (SYSPROF_DOCUMENT_FRAME (mark)); - time_span.end_nsec = time_span.begin_nsec + sysprof_document_mark_get_duration (mark); - - sysprof_time_series_add (series, time_span, i); - } - - sysprof_time_series_sort (series); - - g_task_return_pointer (task, - g_steal_pointer (&series), - (GDestroyNotify)sysprof_time_series_unref); -} - -void -sysprof_mark_chart_item_load_time_series (SysprofMarkChartItem *self, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - g_autoptr(GTask) task = NULL; - LoadTimeSeries *state; - - g_return_if_fail (SYSPROF_IS_MARK_CHART_ITEM (self)); - g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable)); - - task = g_task_new (self, cancellable, callback, user_data); - g_task_set_source_tag (task, sysprof_mark_chart_item_load_time_series); - - if (self->catalog == NULL || self->session == NULL) - { - g_task_return_new_error (task, - G_IO_ERROR, - G_IO_ERROR_FAILED, - "No available data to generate"); - return; - } - - state = g_new0 (LoadTimeSeries, 1); - state->model = g_object_ref (G_LIST_MODEL (self->catalog)); - state->time_span = *sysprof_session_get_selected_time (self->session); - - g_task_set_task_data (task, state, (GDestroyNotify)load_time_series_free); - g_task_run_in_thread (task, load_time_series_worker); -} - SysprofTimeSeries * -sysprof_mark_chart_item_load_time_series_finish (SysprofMarkChartItem *self, - GAsyncResult *result, - GError **error) +sysprof_mark_chart_item_get_series (SysprofMarkChartItem *self) { g_return_val_if_fail (SYSPROF_IS_MARK_CHART_ITEM (self), NULL); - g_return_val_if_fail (G_IS_TASK (result), NULL); - return g_task_propagate_pointer (G_TASK (result), error); + return SYSPROF_TIME_SERIES (self->series); } diff --git a/src/libsysprof-gtk/sysprof-mark-chart-row.c b/src/libsysprof-gtk/sysprof-mark-chart-row.c index a08c45cb..5be8c59f 100644 --- a/src/libsysprof-gtk/sysprof-mark-chart-row.c +++ b/src/libsysprof-gtk/sysprof-mark-chart-row.c @@ -23,26 +23,18 @@ #include #include "sysprof-mark-chart-row-private.h" +#include "sysprof-chart.h" +#include "sysprof-time-series-item.h" +#include "sysprof-time-span-layer.h" struct _SysprofMarkChartRow { GtkWidget parent_instance; - GCancellable *cancellable; - SysprofTimeSeries *series; SysprofMarkChartItem *item; - GdkRGBA accent_fg_color; - GdkRGBA accent_bg_color; - GdkRGBA success_bg_color; - - double pointer_x; - double pointer_y; - - guint update_source; - - guint pointer_in_row : 1; - guint in_dispose : 1; + SysprofChart *chart; + SysprofTimeSpanLayer *layer; }; enum { @@ -55,394 +47,18 @@ G_DEFINE_FINAL_TYPE (SysprofMarkChartRow, sysprof_mark_chart_row, GTK_TYPE_WIDGE static GParamSpec *properties [N_PROPS]; -static void -cancel_and_clear (GCancellable **cancellable) -{ - g_cancellable_cancel (*cancellable); - g_clear_object (cancellable); -} - -static void -sysprof_mark_chart_row_set_series (SysprofMarkChartRow *self, - SysprofTimeSeries *series) -{ - g_assert (SYSPROF_IS_MARK_CHART_ROW (self)); - - g_clear_pointer (&self->series, sysprof_time_series_unref); - self->series = series ? sysprof_time_series_ref (series) : NULL; - - if (!self->in_dispose) - gtk_widget_queue_draw (GTK_WIDGET (self)); -} - -static void -sysprof_mark_chart_row_css_changed (GtkWidget *widget, - GtkCssStyleChange *change) -{ - SysprofMarkChartRow *self = (SysprofMarkChartRow *)widget; - - g_assert (SYSPROF_MARK_CHART_ROW (self)); - - GTK_WIDGET_CLASS (sysprof_mark_chart_row_parent_class)->css_changed (widget, change); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - { - GtkStyleContext *style_context; - - style_context = gtk_widget_get_style_context (widget); - gtk_style_context_lookup_color (style_context, "accent_bg_color", &self->accent_bg_color); - gtk_style_context_lookup_color (style_context, "accent_fg_color", &self->accent_fg_color); - gtk_style_context_lookup_color (style_context, "success_bg_color", &self->success_bg_color); - } -G_GNUC_END_IGNORE_DEPRECATIONS -} - -static void -sysprof_mark_chart_row_snapshot (GtkWidget *widget, - GtkSnapshot *snapshot) -{ - SysprofMarkChartRow *self = (SysprofMarkChartRow *)widget; - const SysprofTimeSeriesValue *best_match = NULL; - const SysprofTimeSeriesValue *values; - graphene_point_t pointer; - PangoLayout *layout; - GListModel *model; - guint n_values; - float last_end_x; - int width; - int height; - - g_assert (SYSPROF_IS_MARK_CHART_ROW (self)); - g_assert (GTK_IS_SNAPSHOT (snapshot)); - - if (self->series == NULL) - return; - - model = sysprof_time_series_get_model (self->series); - values = sysprof_time_series_get_values (self->series, &n_values); - if (model == NULL || n_values == 0) - return; - - width = gtk_widget_get_width (widget); - height = gtk_widget_get_height (widget); - - pointer = GRAPHENE_POINT_INIT (self->pointer_x, self->pointer_y); - - layout = gtk_widget_create_pango_layout (widget, NULL); - pango_layout_set_single_paragraph_mode (layout, TRUE); - pango_layout_set_height (layout, height * PANGO_SCALE); - pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); - - last_end_x = 0; - - /* First pass, draw our rectangles for duration which we - * always want in the background compared to "points" which - * are marks w/o a duration. - */ - for (guint i = 0; i < n_values; i++) - { - const SysprofTimeSeriesValue *v = &values[i]; - - if (v->begin != v->end) - { - graphene_rect_t rect; - float end_x; - - rect = GRAPHENE_RECT_INIT (floorf (v->begin * width), - 0, - ceilf ((v->end - v->begin) * width), - height); - - if (graphene_rect_contains_point (&rect, &pointer)) - best_match = v; - - /* Ignore empty sized draws */ - if (rect.size.width == 0) - continue; - - /* Cull draw unless it will extend past last rect */ - end_x = rect.origin.x + rect.size.width; - if (end_x <= last_end_x) - continue; - else - last_end_x = end_x; - - gtk_snapshot_append_color (snapshot, &self->accent_bg_color, &rect); - - /* Only show the message text if the next item does - * not overlap and there are at least 20 pixels - * available to render into. - */ - if ((i + 1 == n_values || values[i+1].begin > v->end) && - rect.size.width > 20) - { - g_autoptr(SysprofDocumentMark) mark = g_list_model_get_item (model, v->index); - const char *message = sysprof_document_mark_get_message (mark); - - if (message && message[0]) - { - pango_layout_set_width (layout, rect.size.width * PANGO_SCALE); - pango_layout_set_text (layout, message, -1); - - gtk_snapshot_save (snapshot); - gtk_snapshot_push_clip (snapshot, - &GRAPHENE_RECT_INIT (v->begin * width, - 0, - v->end * width, - height)); - gtk_snapshot_translate (snapshot, - &GRAPHENE_POINT_INIT (v->begin * width, 0)); - gtk_snapshot_append_layout (snapshot, layout, &self->accent_fg_color); - gtk_snapshot_pop (snapshot); - gtk_snapshot_restore (snapshot); - } - } - } - } - - for (guint i = 0; i < n_values; i++) - { - const SysprofTimeSeriesValue *v = &values[i]; - - if (v->begin == v->end) - { - gtk_snapshot_save (snapshot); - gtk_snapshot_translate (snapshot, - &GRAPHENE_POINT_INIT (v->begin * width, height / 2)); - gtk_snapshot_rotate (snapshot, 45.f); - gtk_snapshot_append_color (snapshot, - &self->success_bg_color, - &GRAPHENE_RECT_INIT (-4, -4, 8, 8)); - gtk_snapshot_restore (snapshot); - } - } - - /* Draw the best hover match fully, drawing over any other items. */ - if (self->pointer_in_row && best_match != NULL) - { - const SysprofTimeSeriesValue *v = best_match; - g_autoptr(SysprofDocumentMark) mark = g_list_model_get_item (model, v->index); - const char *message = sysprof_document_mark_get_message (mark); - graphene_rect_t rect; - - rect = GRAPHENE_RECT_INIT (floorf (v->begin * width), - 0, - ceilf ((v->end - v->begin) * width), - height); - - gtk_snapshot_append_color (snapshot, &self->accent_bg_color, &rect); - - if (message && message[0]) - { - int w, h; - - pango_layout_set_width (layout, -1); - pango_layout_set_text (layout, message, -1); - - pango_layout_get_pixel_size (layout, &w, &h); - - if (w > rect.size.width) - { - GdkRGBA color = self->accent_bg_color; - color.alpha *= .9; - - gtk_snapshot_append_color (snapshot, - &color, - &GRAPHENE_RECT_INIT (rect.origin.x + rect.size.width, - 0, - w - rect.size.width, - rect.origin.y + rect.size.height)); - } - - gtk_snapshot_save (snapshot); - gtk_snapshot_translate (snapshot, - &GRAPHENE_POINT_INIT (v->begin * width, 0)); - gtk_snapshot_append_layout (snapshot, layout, &self->accent_fg_color); - gtk_snapshot_restore (snapshot); - } - } - - g_clear_object (&layout); -} - -static void -sysprof_mark_chart_row_load_time_series_cb (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - SysprofMarkChartItem *item = (SysprofMarkChartItem *)object; - g_autoptr(SysprofMarkChartRow) self = user_data; - g_autoptr(SysprofTimeSeries) series = NULL; - - g_assert (SYSPROF_IS_MARK_CHART_ITEM (item)); - g_assert (G_IS_ASYNC_RESULT (result)); - g_assert (SYSPROF_IS_MARK_CHART_ROW (self)); - - series = sysprof_mark_chart_item_load_time_series_finish (item, result, NULL); - - sysprof_mark_chart_row_set_series (self, series); -} - -static gboolean -sysprof_mark_chart_row_dispatch_update (gpointer user_data) -{ - SysprofMarkChartRow *self = user_data; - - g_assert (SYSPROF_IS_MARK_CHART_ROW (self)); - - g_clear_handle_id (&self->update_source, g_source_remove); - cancel_and_clear (&self->cancellable); - - if (self->item != NULL) - { - self->cancellable = g_cancellable_new (); - sysprof_mark_chart_item_load_time_series (self->item, - self->cancellable, - sysprof_mark_chart_row_load_time_series_cb, - g_object_ref (self)); - } - - return G_SOURCE_REMOVE; -} - -static void -sysprof_mark_chart_row_queue_update (SysprofMarkChartRow *self) -{ - g_assert (SYSPROF_IS_MARK_CHART_ROW (self)); - - cancel_and_clear (&self->cancellable); - g_clear_handle_id (&self->update_source, g_source_remove); - - if (!self->in_dispose) - self->update_source = g_idle_add (sysprof_mark_chart_row_dispatch_update, self); -} - -static void -sysprof_mark_chart_row_item_changed_cb (SysprofMarkChartRow *self, - SysprofMarkChartItem *item) -{ - g_assert (SYSPROF_IS_MARK_CHART_ROW (self)); - g_assert (SYSPROF_IS_MARK_CHART_ITEM (item)); - - sysprof_mark_chart_row_queue_update (self); -} - -static void -sysprof_mark_chart_row_motion_enter_cb (SysprofMarkChartRow *self, - double x, - double y, - GtkEventControllerMotion *motion) -{ - g_assert (SYSPROF_IS_MARK_CHART_ROW (self)); - g_assert (GTK_IS_EVENT_CONTROLLER_MOTION (motion)); - - self->pointer_in_row = TRUE; - self->pointer_x = x; - self->pointer_y = y; - - gtk_widget_queue_draw (GTK_WIDGET (self)); -} - -static void -sysprof_mark_chart_row_motion_motion_cb (SysprofMarkChartRow *self, - double x, - double y, - GtkEventControllerMotion *motion) -{ - g_assert (SYSPROF_IS_MARK_CHART_ROW (self)); - g_assert (GTK_IS_EVENT_CONTROLLER_MOTION (motion)); - - self->pointer_x = x; - self->pointer_y = y; - - gtk_widget_queue_draw (GTK_WIDGET (self)); -} - -static void -sysprof_mark_chart_row_motion_leave_cb (SysprofMarkChartRow *self, - GtkEventControllerMotion *motion) -{ - g_assert (SYSPROF_IS_MARK_CHART_ROW (self)); - g_assert (GTK_IS_EVENT_CONTROLLER_MOTION (motion)); - - self->pointer_in_row = FALSE; - self->pointer_x = 0; - self->pointer_y = 0; - - gtk_widget_queue_draw (GTK_WIDGET (self)); -} - -static void -sysprof_mark_chart_row_click_pressed_cb (SysprofMarkChartRow *self, - guint n_press, - double x, - double y, - GtkGestureClick *click) -{ - const SysprofTimeSeriesValue *best_match = NULL; - const SysprofTimeSeriesValue *values; - g_autoptr(SysprofDocumentMark) mark = NULL; - SysprofSession *session; - GListModel *model; - double normalized_x; - gint64 t; - guint n_values; - int width; - - g_assert (SYSPROF_IS_MARK_CHART_ROW (self)); - g_assert (GTK_IS_GESTURE_CLICK (click)); - - if (n_press != 2 || self->series == NULL || self->item == NULL) - return; - - if (!(session = sysprof_mark_chart_item_get_session (self->item)) || - !(model = sysprof_time_series_get_model (self->series))) - return; - - values = sysprof_time_series_get_values (self->series, &n_values); - if (values == NULL || n_values == 0) - return; - - width = gtk_widget_get_width (GTK_WIDGET (self)); - normalized_x = x / width; - - for (guint i = 0; i < n_values; i++) - { - const SysprofTimeSeriesValue *v = &values[i]; - - if (v->begin > normalized_x) - break; - - if (v->end >= normalized_x) - best_match = v; - } - - if (best_match == NULL) - return; - - mark = g_list_model_get_item (model, best_match->index); - t = sysprof_document_frame_get_time (SYSPROF_DOCUMENT_FRAME (mark)); - - sysprof_session_select_time (session, - &(SysprofTimeSpan) { - t, - t + sysprof_document_mark_get_duration (mark) - }); - -} - static void sysprof_mark_chart_row_dispose (GObject *object) { SysprofMarkChartRow *self = (SysprofMarkChartRow *)object; + GtkWidget *child; - self->in_dispose = TRUE; + self->chart = NULL; - cancel_and_clear (&self->cancellable); - g_clear_handle_id (&self->update_source, g_source_remove); + while ((child = gtk_widget_get_first_child (GTK_WIDGET (self)))) + gtk_widget_unparent (child); - sysprof_mark_chart_row_set_item (self, NULL); - sysprof_mark_chart_row_set_series (self, NULL); + g_clear_object (&self->item); G_OBJECT_CLASS (sysprof_mark_chart_row_parent_class)->dispose (object); } @@ -495,9 +111,6 @@ sysprof_mark_chart_row_class_init (SysprofMarkChartRowClass *klass) object_class->get_property = sysprof_mark_chart_row_get_property; object_class->set_property = sysprof_mark_chart_row_set_property; - widget_class->css_changed = sysprof_mark_chart_row_css_changed; - widget_class->snapshot = sysprof_mark_chart_row_snapshot; - properties [PROP_ITEM] = g_param_spec_object ("item", NULL, NULL, SYSPROF_TYPE_MARK_CHART_ITEM, @@ -506,38 +119,20 @@ sysprof_mark_chart_row_class_init (SysprofMarkChartRowClass *klass) g_object_class_install_properties (object_class, N_PROPS, properties); gtk_widget_class_set_css_name (widget_class, "markchartrow"); + gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT); + gtk_widget_class_set_template_from_resource (widget_class, "/libsysprof-gtk/sysprof-mark-chart-row.ui"); + gtk_widget_class_bind_template_child (widget_class, SysprofMarkChartRow, chart); + gtk_widget_class_bind_template_child (widget_class, SysprofMarkChartRow, layer); + + g_type_ensure (SYSPROF_TYPE_CHART); + g_type_ensure (SYSPROF_TYPE_TIME_SERIES_ITEM); + g_type_ensure (SYSPROF_TYPE_TIME_SPAN_LAYER); } static void sysprof_mark_chart_row_init (SysprofMarkChartRow *self) { - GtkEventController *controller; - - controller = gtk_event_controller_motion_new (); - g_signal_connect_object (controller, - "enter", - G_CALLBACK (sysprof_mark_chart_row_motion_enter_cb), - self, - G_CONNECT_SWAPPED); - g_signal_connect_object (controller, - "leave", - G_CALLBACK (sysprof_mark_chart_row_motion_leave_cb), - self, - G_CONNECT_SWAPPED); - g_signal_connect_object (controller, - "motion", - G_CALLBACK (sysprof_mark_chart_row_motion_motion_cb), - self, - G_CONNECT_SWAPPED); - gtk_widget_add_controller (GTK_WIDGET (self), controller); - - controller = GTK_EVENT_CONTROLLER (gtk_gesture_click_new ()); - g_signal_connect_object (controller, - "pressed", - G_CALLBACK (sysprof_mark_chart_row_click_pressed_cb), - self, - G_CONNECT_SWAPPED); - gtk_widget_add_controller (GTK_WIDGET (self), controller); + gtk_widget_init_template (GTK_WIDGET (self)); } SysprofMarkChartItem * @@ -555,27 +150,6 @@ sysprof_mark_chart_row_set_item (SysprofMarkChartRow *self, g_return_if_fail (SYSPROF_IS_MARK_CHART_ROW (self)); g_return_if_fail (!item || SYSPROF_IS_MARK_CHART_ITEM (item)); - if (self->item == item) - return; - - cancel_and_clear (&self->cancellable); - g_clear_handle_id (&self->update_source, g_source_remove); - - if (self->item) - g_signal_handlers_disconnect_by_func (self->item, - G_CALLBACK (sysprof_mark_chart_row_item_changed_cb), - self); - - g_set_object (&self->item, item); - - if (item) - g_signal_connect_object (self->item, - "changed", - G_CALLBACK (sysprof_mark_chart_row_item_changed_cb), - self, - G_CONNECT_SWAPPED); - - g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ITEM]); - - sysprof_mark_chart_row_queue_update (self); + if (g_set_object (&self->item, item)) + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ITEM]); } diff --git a/src/libsysprof-gtk/sysprof-mark-chart-row.ui b/src/libsysprof-gtk/sysprof-mark-chart-row.ui new file mode 100644 index 00000000..54082bf6 --- /dev/null +++ b/src/libsysprof-gtk/sysprof-mark-chart-row.ui @@ -0,0 +1,27 @@ + + + +