/* * DiaClock * * This is LGPL'ed code. */ #include "dia-clock.h" #include #include #include #include #include static void dia_clock_class_init (DiaClockClass *klass); static void dia_clock_init (DiaClock *item); static void dia_clock_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void dia_clock_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void dia_clock_dispose (GObject *object); static void dia_clock_update (DiaCanvasItem *item, gdouble affine[6]); static gboolean dia_clock_get_shape_iter (DiaCanvasItem *item, DiaCanvasIter *iter); static gboolean dia_clock_shape_next (DiaCanvasItem *item, DiaCanvasIter *iter); static DiaShape* dia_clock_shape_value (DiaCanvasItem *item, DiaCanvasIter *iter); static gdouble dia_clock_glue (DiaCanvasItem *item, DiaHandle *handle, gdouble *x, gdouble *y); static gboolean dia_clock_connect (DiaCanvasItem *item, DiaHandle *handle); static DiaCanvasElementClass *parent_class = NULL; gboolean clock_update (gpointer data) { DiaClock *clock = data; time_t t; struct tm *lt; glong sec; time (&t); lt = localtime (&t); sec = ((lt->tm_hour * 60) + lt->tm_min) * 60 + lt->tm_sec; if (sec != clock->sec) { clock->sec = sec; dia_canvas_item_request_update (DIA_CANVAS_ITEM (clock)); } return TRUE; /* keep the timeout function. */ } GType dia_clock_get_type (void) { static GType object_type = 0; if (!object_type) { static const GTypeInfo object_info = { sizeof (DiaClockClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) dia_clock_class_init, (GClassFinalizeFunc) NULL, (gconstpointer) NULL, /* class_data */ sizeof (DiaClock), (guint16) 0, /* n_preallocs */ (GInstanceInitFunc) dia_clock_init, }; object_type = g_type_register_static (DIA_TYPE_CANVAS_ELEMENT, "DiaClock", &object_info, 0); } return object_type; } static void dia_clock_class_init (DiaClockClass *klass) { GObjectClass *object_class; DiaCanvasItemClass *item_class; object_class = (GObjectClass*) klass; item_class = DIA_CANVAS_ITEM_CLASS (klass); parent_class = g_type_class_peek_parent (klass); object_class->dispose = dia_clock_dispose; object_class->get_property = dia_clock_get_property; object_class->set_property = dia_clock_set_property; item_class->update = dia_clock_update; item_class->get_shape_iter = dia_clock_get_shape_iter; item_class->shape_next = dia_clock_shape_next; item_class->shape_value = dia_clock_shape_value; item_class->glue = dia_clock_glue; item_class->connect = dia_clock_connect; } static void dia_clock_init (DiaClock *item) { item->sec = 0; item->timer = 0; // g_timeout_add (200, clock_update, item); item->circle = dia_shape_new (DIA_SHAPE_ELLIPSE); item->hours = dia_shape_new (DIA_SHAPE_PATH); item->minutes = dia_shape_new (DIA_SHAPE_PATH); item->seconds = dia_shape_new (DIA_SHAPE_PATH); } static void dia_clock_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { switch (property_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void dia_clock_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { switch (property_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void dia_clock_dispose (GObject *object) { DiaClock *clock = (DiaClock*) object; g_message (G_STRLOC); if (clock->timer) { g_source_remove (clock->timer); clock->timer = 0; } if (clock->circle) { dia_shape_free (clock->circle); clock->circle = NULL; dia_shape_free (clock->hours); clock->hours = NULL; dia_shape_free (clock->minutes); clock->minutes = NULL; dia_shape_free (clock->seconds); clock->seconds = NULL; } G_OBJECT_CLASS (parent_class)->dispose (object); } static void dia_clock_update (DiaCanvasItem *item, gdouble affine[6]) { DiaClock *clock = (DiaClock*) item; DiaShape *circle, *hours, *minutes, *seconds; DiaPoint center, p; gdouble t, r; if (DIA_CANVAS_ITEM_CLASS (parent_class)->update) DIA_CANVAS_ITEM_CLASS (parent_class)->update (item, affine); circle = clock->circle; hours = clock->hours; minutes = clock->minutes; seconds = clock->seconds; center.x = clock->item.width / 2; center.y = clock->item.height / 2; r = MIN (clock->item.width, clock->item.height) / 2; dia_shape_ellipse (circle, ¢er, r + r, r + r); dia_shape_set_color (circle, DIA_COLOR(20,20,20)); dia_shape_ellipse_set_fill (circle, DIA_FILL_SOLID); dia_shape_ellipse_set_fill_color (circle, DIA_COLOR_A (40, 0, 0, 60)); dia_shape_ellipse_set_line_width (circle, 2.0); t = clock->sec * M_PI / 21600.0; /* 3600 * 6 */ p.x = sin (t) * r * 0.7 + center.x; p.y = -cos (t) * r * 0.7 + center.y; dia_shape_line (hours, ¢er, &p); dia_shape_path_set_line_width (hours, 4.0); dia_shape_request_update (hours); t = clock->sec * M_PI / 1800.0; p.x = sin (t) * r * 0.85 + center.x; p.y = -cos (t) * r * 0.85 + center.y; dia_shape_line (minutes, ¢er, &p); dia_shape_path_set_line_width (minutes, 2.0); dia_shape_request_update (minutes); t = clock->sec * M_PI / 30.0; p.x = sin (t) * r * 0.9 + center.x; p.y = -cos (t) * r * 0.9 + center.y; dia_shape_line (seconds, ¢er, &p); dia_shape_path_set_line_width (seconds, 1.0); dia_shape_set_color (seconds, DIA_COLOR (200, 50,50)); dia_shape_request_update (seconds); } static gboolean dia_clock_get_shape_iter (DiaCanvasItem *item, DiaCanvasIter *iter) { iter->data[0] = DIA_CLOCK (item)->circle; return TRUE; } static gboolean dia_clock_shape_next (DiaCanvasItem *item, DiaCanvasIter *iter) { DiaClock *c = (DiaClock*) item; if (iter->data[0] == c->circle) iter->data[0] = c->hours; else if (iter->data[0] == c->hours) iter->data[0] = c->minutes; else if (iter->data[0] == c->minutes) iter->data[0] = c->seconds; else iter->data[0] = NULL; return (iter->data[0] != NULL ? TRUE : FALSE); } static DiaShape* dia_clock_shape_value (DiaCanvasItem *item, DiaCanvasIter *iter) { return iter->data[0]; } static gdouble dia_clock_glue (DiaCanvasItem *item, DiaHandle *handle, gdouble *x, gdouble *y) { return G_MAXDOUBLE; } static gboolean dia_clock_connect (DiaCanvasItem *item, DiaHandle *handle) { return FALSE; }