diff options
author | David Zeuthen <davidz@redhat.com> | 2009-04-02 11:28:41 -0400 |
---|---|---|
committer | David Zeuthen <davidz@redhat.com> | 2009-04-02 11:28:41 -0400 |
commit | c10bf147c408f111977fe985c19bad2da5320efa (patch) | |
tree | a93b1b236508f98bba39c366ccdcb1bc1b418e75 | |
parent | e2dabdb585a18624f893757fcfaa9d8bd3d0d1ad (diff) | |
download | gnome-disk-utility-c10bf147c408f111977fe985c19bad2da5320efa.tar.gz gnome-disk-utility-c10bf147c408f111977fe985c19bad2da5320efa.tar.xz gnome-disk-utility-c10bf147c408f111977fe985c19bad2da5320efa.zip |
grid: add a spinner
-rw-r--r-- | src/playground/grid/gdu-grid-element.c | 167 | ||||
-rw-r--r-- | src/playground/grid/grid.c | 2 |
2 files changed, 162 insertions, 7 deletions
diff --git a/src/playground/grid/gdu-grid-element.c b/src/playground/grid/gdu-grid-element.c index 3878025..862dc2b 100644 --- a/src/playground/grid/gdu-grid-element.c +++ b/src/playground/grid/gdu-grid-element.c @@ -15,9 +15,13 @@ struct GduGridElementPrivate { GduGridView *view; GduPresentable *presentable; + GduDevice *device; guint minimum_size; gdouble percent_size; GduGridElementFlags flags; + + guint job_spinner_timeout_id; + gdouble job_spinner_animation_step; }; enum @@ -30,6 +34,11 @@ enum PROP_FLAGS, }; +static void gdu_grid_element_presentable_changed (GduPresentable *presentable, + gpointer user_data); +static void gdu_grid_element_presentable_job_changed (GduPresentable *presentable, + gpointer user_data); + G_DEFINE_TYPE (GduGridElement, gdu_grid_element, GTK_TYPE_DRAWING_AREA) static void @@ -37,8 +46,19 @@ gdu_grid_element_finalize (GObject *object) { GduGridElement *element = GDU_GRID_ELEMENT (object); - if (element->priv->presentable != NULL) + if (element->priv->job_spinner_timeout_id > 0) { + g_source_remove (element->priv->job_spinner_timeout_id); + } + + if (element->priv->presentable != NULL) { + g_signal_handlers_disconnect_by_func (element->priv->presentable, + gdu_grid_element_presentable_changed, + element); + g_signal_handlers_disconnect_by_func (element->priv->presentable, + gdu_grid_element_presentable_job_changed, + element); g_object_unref (element->priv->presentable); + } if (G_OBJECT_CLASS (gdu_grid_element_parent_class)->finalize != NULL) G_OBJECT_CLASS (gdu_grid_element_parent_class)->finalize (object); @@ -195,6 +215,48 @@ render_pixbuf (cairo_t *cr, cairo_fill (cr); } +static void +render_spinner (cairo_t *cr, + gdouble x, + gdouble y, + gdouble radius, + gdouble anim_step) +{ + guint n; + gdouble angle; + gdouble inner_radius; + guint num_circles; + + num_circles = 8; + inner_radius = radius / 4.0; + + for (n = 0, angle = 0; n < num_circles; n++, angle += 2 * M_PI / num_circles) { + gdouble color; + gdouble this_anim_step; + + this_anim_step = anim_step + ((gdouble) n) / num_circles; + if (this_anim_step > 1.0) + this_anim_step -= 1.0; + if (this_anim_step < 0.5) + this_anim_step = 2.0 * (0.5 - this_anim_step); + else + this_anim_step = 2.0 * (this_anim_step - 0.5); + color = 0.7 + this_anim_step * 0.3; + + cairo_set_source_rgba (cr, 0, 0, 0, 1 - color); + + cairo_set_dash (cr, NULL, 0, 0.0); + cairo_set_line_width (cr, 1.0); + cairo_arc (cr, + x + (radius - inner_radius) * cos (angle), + y + (radius - inner_radius) * sin (angle), + inner_radius, + 0, + 2 * M_PI); + cairo_fill (cr); + } +} + static gboolean gdu_grid_element_expose_event (GtkWidget *widget, GdkEventExpose *event) @@ -231,9 +293,12 @@ gdu_grid_element_expose_event (GtkWidget *widget, gdouble text_selected_green; gdouble text_selected_blue; gdouble border_width; + GduDevice *d; f = element->priv->flags; + d = gdu_presentable_get_device (element->priv->presentable); + width = widget->allocation.width; height = widget->allocation.height; @@ -336,6 +401,18 @@ gdu_grid_element_expose_event (GtkWidget *widget, cairo_set_line_width (cr, 1); cairo_stroke (cr); + /* draw a spinner if one or more jobs are pending on the device */ + if (element->priv->job_spinner_timeout_id > 0) { + render_spinner (cr, + ceil (rect_x + rect_width - 6 - 4), + ceil (rect_y + rect_height - 6 - 4), + 6, + element->priv->job_spinner_animation_step); + element->priv->job_spinner_animation_step += 0.1; + if (element->priv->job_spinner_animation_step > 1.0) + element->priv->job_spinner_animation_step -= 1.0; + } + /* draw focus indicator */ if (has_focus) { gdouble dashes[] = {2.0}; @@ -405,9 +482,6 @@ gdu_grid_element_expose_event (GtkWidget *widget, line_height = te.height + 4; y += line_height; - - GduDevice *d; - d = gdu_presentable_get_device (element->priv->presentable); if (d != NULL) { s = g_strdup (gdu_device_get_device_file (d)); } else { @@ -432,9 +506,6 @@ gdu_grid_element_expose_event (GtkWidget *widget, //g_free (s); //y += line_height; - if (d != NULL) - g_object_unref (d); - } else { gchar *s; gchar *s1; @@ -508,6 +579,8 @@ gdu_grid_element_expose_event (GtkWidget *widget, g_object_unref (d); } + if (d != NULL) + g_object_unref (d); cairo_destroy (cr); @@ -678,6 +751,85 @@ gdu_grid_element_unrealize (GtkWidget *widget) } #endif +static gboolean +job_spinner_timeout_cb (gpointer user_data) +{ + GduGridElement *element = GDU_GRID_ELEMENT (user_data); + gtk_widget_queue_draw (GTK_WIDGET (element)); + return TRUE; +} + +static void +update_job_spinner (GduGridElement *element) +{ + GduDevice *d; + + d = NULL; + if (element->priv->presentable == NULL) + goto out; + d = gdu_presentable_get_device (element->priv->presentable); + if (d == NULL) + goto out; + + if (gdu_device_job_in_progress (d)) { + if (element->priv->job_spinner_timeout_id == 0) { + element->priv->job_spinner_timeout_id = g_timeout_add (100, job_spinner_timeout_cb, element); + element->priv->job_spinner_animation_step = 0.0; + gtk_widget_queue_draw (GTK_WIDGET (element)); + } + } else { + if (element->priv->job_spinner_timeout_id > 0) { + g_source_remove (element->priv->job_spinner_timeout_id); + element->priv->job_spinner_timeout_id = 0; + gtk_widget_queue_draw (GTK_WIDGET (element)); + } + } + + out: + if (d != NULL) + g_object_unref (d); +} + +static void +gdu_grid_element_presentable_changed (GduPresentable *presentable, + gpointer user_data) +{ + GduGridElement *element = GDU_GRID_ELEMENT (user_data); + g_debug ("changed for %s", gdu_presentable_get_name (presentable)); + update_job_spinner (element); +} + +static void +gdu_grid_element_presentable_job_changed (GduPresentable *presentable, + gpointer user_data) +{ + GduGridElement *element = GDU_GRID_ELEMENT (user_data); + g_debug ("job changed for %s", gdu_presentable_get_name (presentable)); + update_job_spinner (element); +} + +static void +gdu_grid_element_constructed (GObject *object) +{ + GduGridElement *element = GDU_GRID_ELEMENT (object); + + if (element->priv->presentable != NULL) { + g_signal_connect (element->priv->presentable, + "changed", + G_CALLBACK (gdu_grid_element_presentable_changed), + element); + g_signal_connect (element->priv->presentable, + "job-changed", + G_CALLBACK (gdu_grid_element_presentable_job_changed), + element); + } + + update_job_spinner (element); + + if (G_OBJECT_CLASS (gdu_grid_element_parent_class)->constructed != NULL) + G_OBJECT_CLASS (gdu_grid_element_parent_class)->constructed (object); +} + static void gdu_grid_element_class_init (GduGridElementClass *klass) { @@ -688,6 +840,7 @@ gdu_grid_element_class_init (GduGridElementClass *klass) object_class->get_property = gdu_grid_element_get_property; object_class->set_property = gdu_grid_element_set_property; + object_class->constructed = gdu_grid_element_constructed; object_class->finalize = gdu_grid_element_finalize; widget_class->realize = gdu_grid_element_realize; diff --git a/src/playground/grid/grid.c b/src/playground/grid/grid.c index 8358fe6..853c48e 100644 --- a/src/playground/grid/grid.c +++ b/src/playground/grid/grid.c @@ -37,12 +37,14 @@ main (int argc, char *argv[]) TRUE, 0); +#if 0 details = gdu_grid_details_new (GDU_GRID_VIEW (view)); gtk_box_pack_start (GTK_BOX (vbox), details, TRUE, TRUE, 0); +#endif gtk_window_set_default_size (GTK_WINDOW (window), 600, 400); gtk_widget_show_all (window); |