From 72a8276fafbe293d7cb3da498856508118e8bf63 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Thu, 6 Oct 2016 21:03:01 -0700 Subject: [PATCH] visualizer-view: fix time range for ticks This uses the graph_width to get the proper time range of the visualizer row. Mostly, this is just complicated because we the ticks to be an overlay rather than inline with the list rows. --- lib/resources/ui/sp-visualizer-view.ui | 7 +- lib/sp-visualizer-view.c | 141 ++++++++++++++++++++++++- 2 files changed, 137 insertions(+), 11 deletions(-) diff --git a/lib/resources/ui/sp-visualizer-view.ui b/lib/resources/ui/sp-visualizer-view.ui index 45ec5226..742f9a1a 100644 --- a/lib/resources/ui/sp-visualizer-view.ui +++ b/lib/resources/ui/sp-visualizer-view.ui @@ -12,7 +12,7 @@ - + true false true @@ -26,9 +26,4 @@ - - 0.0 - 0.0 - 0.0 - diff --git a/lib/sp-visualizer-view.c b/lib/sp-visualizer-view.c index 5890ed5e..e4bd557b 100644 --- a/lib/sp-visualizer-view.c +++ b/lib/sp-visualizer-view.c @@ -21,10 +21,13 @@ #include #include "sp-visualizer-list.h" +#include "sp-visualizer-row.h" +#include "sp-visualizer-row-private.h" #include "sp-visualizer-ticks.h" #include "sp-visualizer-view.h" #define NSEC_PER_SEC G_GINT64_CONSTANT(1000000000) +#define DEFAULT_PIXELS_PER_SECOND 20 typedef struct { @@ -32,7 +35,7 @@ typedef struct SpZoomManager *zoom_manager; SpVisualizerList *list; - GtkAdjustment *scroll_adjustment; + GtkScrolledWindow *scroller; SpVisualizerTicks *ticks; } SpVisualizerViewPrivate; @@ -85,6 +88,80 @@ sp_visualizer_view_row_removed (SpVisualizerView *self, g_signal_emit (self, signals [VISUALIZER_REMOVED], 0, widget); } +static void +find_row1 (GtkWidget *widget, + gpointer data) +{ + GtkWidget **row1 = data; + + if (*row1 == NULL && SP_IS_VISUALIZER_ROW (widget)) + *row1 = widget; +} + +static void +sp_visualizer_view_update_ticks (SpVisualizerView *self) +{ + SpVisualizerViewPrivate *priv = sp_visualizer_view_get_instance_private (self); + SpVisualizerRow *row1 = NULL; + GtkAdjustment *hadjustment; + GtkAllocation alloc; + gdouble nsec_per_pixel; + gdouble value; + gint64 begin_time; + gint64 end_time; + gint graph_width; + + g_assert (SP_IS_VISUALIZER_VIEW (self)); + + if (priv->reader == NULL) + return; + + begin_time = sp_capture_reader_get_start_time (priv->reader); + end_time = sp_capture_reader_get_end_time (priv->reader); + + gtk_container_foreach (GTK_CONTAINER (priv->list), find_row1, &row1); + + if (!SP_IS_VISUALIZER_ROW (row1)) + return; + + hadjustment = gtk_scrolled_window_get_hadjustment (priv->scroller); + value = gtk_adjustment_get_value (hadjustment); + + gtk_widget_get_allocation (GTK_WIDGET (priv->ticks), &alloc); + + /* In practice, the adjustment is 1.0 per pixel. */ + graph_width = _sp_visualizer_row_get_graph_width (row1); + nsec_per_pixel = (end_time - begin_time) / (gdouble)graph_width; + begin_time += value * nsec_per_pixel; + end_time = begin_time + (alloc.width * nsec_per_pixel); + + sp_visualizer_ticks_set_time_range (priv->ticks, begin_time, end_time); +} + +static void +sp_visualizer_view_hadjustment_value_changed (SpVisualizerView *self, + GtkAdjustment *adjustment) +{ + g_assert (SP_IS_VISUALIZER_VIEW (self)); + g_assert (GTK_IS_ADJUSTMENT (adjustment)); + + sp_visualizer_view_update_ticks (self); +} + +static void +sp_visualizer_view_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + SpVisualizerView *self = (SpVisualizerView *)widget; + + g_assert (SP_IS_VISUALIZER_VIEW (self)); + g_assert (allocation != NULL); + + GTK_WIDGET_CLASS (sp_visualizer_view_parent_class)->size_allocate (widget, allocation); + + sp_visualizer_view_update_ticks (self); +} + static void sp_visualizer_view_finalize (GObject *object) { @@ -153,6 +230,8 @@ sp_visualizer_view_class_init (SpVisualizerViewClass *klass) object_class->get_property = sp_visualizer_view_get_property; object_class->set_property = sp_visualizer_view_set_property; + widget_class->size_allocate = sp_visualizer_view_size_allocate; + properties [PROP_READER] = g_param_spec_boxed ("reader", "Reader", @@ -187,7 +266,7 @@ sp_visualizer_view_class_init (SpVisualizerViewClass *klass) gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/sysprof/ui/sp-visualizer-view.ui"); gtk_widget_class_bind_template_child_private (widget_class, SpVisualizerView, list); - gtk_widget_class_bind_template_child_private (widget_class, SpVisualizerView, scroll_adjustment); + gtk_widget_class_bind_template_child_private (widget_class, SpVisualizerView, scroller); gtk_widget_class_bind_template_child_private (widget_class, SpVisualizerView, ticks); gtk_widget_class_set_css_name (widget_class, "visualizers"); @@ -197,6 +276,7 @@ static void sp_visualizer_view_init (SpVisualizerView *self) { SpVisualizerViewPrivate *priv = sp_visualizer_view_get_instance_private (self); + GtkAdjustment *hadjustment; gtk_widget_init_template (GTK_WIDGET (self)); @@ -211,6 +291,14 @@ sp_visualizer_view_init (SpVisualizerView *self) G_CALLBACK (sp_visualizer_view_row_removed), self, G_CONNECT_SWAPPED); + + hadjustment = gtk_scrolled_window_get_hadjustment (priv->scroller); + + g_signal_connect_object (hadjustment, + "value-changed", + G_CALLBACK (sp_visualizer_view_hadjustment_value_changed), + self, + G_CONNECT_SWAPPED); } /** @@ -239,9 +327,22 @@ sp_visualizer_view_set_reader (SpVisualizerView *self, if (priv->reader != reader) { g_clear_pointer (&priv->reader, sp_capture_reader_unref); + if (reader != NULL) - priv->reader = sp_capture_reader_ref (reader); + { + gint64 begin_time; + + priv->reader = sp_capture_reader_ref (reader); + + begin_time = sp_capture_reader_get_start_time (priv->reader); + + sp_visualizer_ticks_set_epoch (priv->ticks, begin_time); + sp_visualizer_ticks_set_time_range (priv->ticks, begin_time, begin_time); + } + sp_visualizer_list_set_reader (priv->list, reader); + sp_visualizer_view_update_ticks (self); + g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_READER]); } } @@ -275,6 +376,17 @@ buildable_iface_init (GtkBuildableIface *iface) iface->add_child = sp_visualizer_view_add_child; } +static void +sp_visualizer_view_zoom_manager_notify_zoom (SpVisualizerView *self, + GParamSpec *pspec, + SpZoomManager *zoom_manager) +{ + g_assert (SP_IS_VISUALIZER_VIEW (self)); + g_assert (SP_IS_ZOOM_MANAGER (zoom_manager)); + + sp_visualizer_view_update_ticks (self); +} + /** * sp_visualizer_view_get_zoom_manager: * @@ -299,10 +411,29 @@ sp_visualizer_view_set_zoom_manager (SpVisualizerView *self, g_return_if_fail (SP_IS_VISUALIZER_VIEW (self)); g_return_if_fail (!zoom_manager || SP_IS_ZOOM_MANAGER (zoom_manager)); - if (g_set_object (&priv->zoom_manager, zoom_manager)) + if (priv->zoom_manager != zoom_manager) { + if (priv->zoom_manager != NULL) + { + g_signal_handlers_disconnect_by_func (priv->zoom_manager, + G_CALLBACK (sp_visualizer_view_zoom_manager_notify_zoom), + self); + g_clear_object (&priv->zoom_manager); + } + + if (zoom_manager != NULL) + { + priv->zoom_manager = g_object_ref (zoom_manager); + g_signal_connect_object (priv->zoom_manager, + "notify::zoom", + G_CALLBACK (sp_visualizer_view_zoom_manager_notify_zoom), + self, + G_CONNECT_SWAPPED); + } + sp_visualizer_list_set_zoom_manager (priv->list, zoom_manager); - g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_ZOOM_MANAGER]); gtk_widget_queue_resize (GTK_WIDGET (self)); + + g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_ZOOM_MANAGER]); } }