]> err.no Git - mapper/blobdiff - src/gtkcompass.c
Include settings.h so the banner macro hildon version works.
[mapper] / src / gtkcompass.c
index d2936d41d1a25fac6e277525c5f5e9c766506c9a..69b21046089fc133ecce983045b76648cac93d2e 100644 (file)
 #include <glib-object.h>
 #include "gtkcompass.h"
 
+#if 0
+#define DEBUG
+#endif
+
 static void gtk_compass_finalize (GObject *object);
 static void gtk_compass_size_request (GtkWidget *widget, GtkRequisition *requisition);
 static void gtk_compass_size_allocate (GtkWidget *widget, GtkAllocation *allocate);
@@ -36,16 +40,29 @@ static void gtk_compass_realize (GtkWidget *widget);
 static void gtk_compass_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
 static void gtk_compass_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
 static void gtk_compass_paint(GtkCompass *compass);
+static gboolean gtk_compass_refresh_cb(GtkWidget *widget);
 
 G_DEFINE_TYPE(GtkCompass, gtk_compass, GTK_TYPE_WIDGET);
 
 #define BOUND(x, a, b) { \
-    if((x) < (a)) \
-        (x) = (a); \
-    else if((x) > (b)) \
-        (x) = (b); \
+       if((x) < (a)) \
+               (x) = (a); \
+       else if((x) > (b)) \
+               (x) = (b); \
 }
 
+typedef struct _GtkCompassPriv GtkCompassPriv;
+struct _GtkCompassPriv
+{ 
+PangoContext *context;
+PangoLayout *layout;
+PangoFontDescription *fontdesc;
+};
+
+#define GTK_COMPASS_GET_PRIVATE(o) \
+       (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_COMPASS, GtkCompassPriv))
+
 static void
 gtk_compass_class_init (GtkCompassClass *class)
 {
@@ -63,6 +80,8 @@ widget_class->size_request = gtk_compass_size_request;
 widget_class->expose_event = gtk_compass_expose;
 widget_class->realize = gtk_compass_realize;
 widget_class->size_allocate = gtk_compass_size_allocate;
+
+g_type_class_add_private (object_class, sizeof (GtkCompassPriv));
 }
 
 static void
@@ -79,20 +98,20 @@ switch (prop_id) {
 }
 
 static void
-gtk_compass_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec   *pspec)
+gtk_compass_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec   *pspec)
 {
 GtkCompass *compass;
 g_return_if_fail(GTK_IS_COMPASS(object));
 compass=GTK_COMPASS(object);
 switch (prop_id) {
        default:
-               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+               G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
        break;
 }
 }
 
 static void
-gtk_compass_init (GtkCompass *compass)
+gtk_compass_init(GtkCompass *compass)
 {
 compass->gc_h=NULL;
 compass->gc_d=NULL;
@@ -101,15 +120,21 @@ compass->dest_valid=FALSE;
 compass->way_valid=FALSE;
 compass->width=300;
 compass->height=300;
+compass->esid=0;
 }
 
 static gboolean 
-gtk_compass_cb_button_press(GtkWidget * widget, GdkEventButton * event)
+gtk_compass_cb_button_press(GtkWidget *widget, GdkEventButton *event)
 {
 GtkCompass *compass;
 
 compass=GTK_COMPASS(widget);
 
+#ifdef DEBUG
+compass->data->heading=0;
+compass->heading=180;
+#endif
+
 return FALSE;
 }
 
@@ -122,7 +147,11 @@ GtkWidget *widget;
 compass=gtk_type_new(gtk_compass_get_type ());
 widget=GTK_WIDGET(compass);
 compass->data=data;
+compass->heading=0;
 g_signal_connect(G_OBJECT(widget), "button_press_event", G_CALLBACK(gtk_compass_cb_button_press), NULL);
+
+compass->esid=g_timeout_add(1000,(GSourceFunc)gtk_compass_refresh_cb, compass);
+
 return widget;
 }
 
@@ -133,6 +162,7 @@ GtkCompass *compass;
        
 g_return_if_fail(GTK_IS_COMPASS(object));
 compass=GTK_COMPASS(object);
+g_source_remove(compass->esid);
 
 if (GTK_WIDGET(object)->parent && GTK_WIDGET_MAPPED(object)) {
        gtk_widget_unmap(GTK_WIDGET(object));
@@ -149,7 +179,7 @@ GtkCompass *compass;
 g_return_if_fail(GTK_IS_COMPASS(widget));
 g_return_if_fail(requisition != NULL);
        
-compass = GTK_COMPASS (widget);
+compass=GTK_COMPASS(widget);
        
 requisition->width=400;
 requisition->height=300;
@@ -257,7 +287,7 @@ if (!compass->gc_w) {
 }
 
 static void
-gtk_compass_draw_mark(GtkCompass *compass, GdkGC *gc, gdouble angle, gint size)
+gtk_compass_draw_mark(GtkCompass *compass, GdkGC *gc, gfloat angle, gint size)
 {
 GtkWidget *widget;
 gint hs;
@@ -267,10 +297,10 @@ widget=GTK_WIDGET(compass);
 hs=compass->size/2;
 
 gdk_draw_line(widget->window,gc,
-       compass->xoffset+hs+((hs-size)*sin(angle)),
-       compass->yoffset+compass->size-((hs-size)*cos(angle)),
-       compass->xoffset+hs+((hs+size)*sin(angle)),
-       compass->yoffset+compass->size-((hs+size)*cos(angle)));
+       compass->xoffset+hs+((hs-size)*sinf(angle)),
+       compass->yoffset+compass->size-((hs-size)*cosf(angle)),
+       compass->xoffset+hs+((hs+size)*sinf(angle)),
+       compass->yoffset+compass->size-((hs+size)*cosf(angle)));
 }
 
 static void
@@ -287,9 +317,13 @@ gint fsize[5] = { 0, 4, 10, 4, 0 };
 
 widget=GTK_WIDGET(compass);
 size=compass->size;
+#if 1
 hsize=size/2;
+#else
+hsize=0;
+#endif
 
-fs=size/42;
+fs=size/41;
 BOUND(fs, 1, 16);
 
 pango_context_set_matrix (compass->context, NULL);
@@ -302,42 +336,42 @@ pango_layout_get_pixel_size(compass->layout, &x, &y);
 
 gdk_draw_layout(widget->window,
        compass->gc_h,
-       compass->xoffset+size/2-x/2,
+       compass->xoffset+hsize-x/2,
        compass->yoffset+size-y-2, compass->layout);
 
 gdk_draw_arc(widget->window,
        compass->gc_h,
        FALSE,
-       compass->xoffset, compass->yoffset+size/2, size, size, 0, 64 * 180);
+       compass->xoffset, compass->yoffset+hsize, size - fs, size - fs, 0, 64 * 360);
 
 /* Simple arrow for heading */
 gdk_draw_line(widget->window,
        compass->gc_h,
-       compass->xoffset + size / 2 + 3,
+       compass->xoffset + hsize + 3,
        compass->yoffset + size - y - 5,
-       compass->xoffset + size / 2, compass->yoffset + size / 2 + 5);
+       compass->xoffset + hsize, compass->yoffset + hsize + 5);
 
 gdk_draw_line(widget->window,
        compass->gc_h,
-       compass->xoffset + size / 2 - 3,
+       compass->xoffset + hsize - 3,
        compass->yoffset + size - y - 5,
-       compass->xoffset + size / 2, compass->yoffset + size / 2 + 5);
+       compass->xoffset + hsize, compass->yoffset + hsize + 5);
 
 gdk_draw_line(widget->window,
        compass->gc_h,
-       compass->xoffset + size / 2 - 3,
+       compass->xoffset + hsize - 3,
        compass->yoffset + size - y - 5,
-       compass->xoffset + size / 2, compass->yoffset + size - y - 8);
+       compass->xoffset + hsize, compass->yoffset + size - y - 8);
 
 gdk_draw_line(widget->window,
        compass->gc_h,
-       compass->xoffset + size / 2 + 3,
+       compass->xoffset + hsize + 3,
        compass->yoffset + size - y - 5,
-       compass->xoffset + size / 2, compass->yoffset + size - y - 8);
+       compass->xoffset + hsize, compass->yoffset + size - y - 8);
 
 for (i = 0; i < 5; i++) {
        PangoMatrix matrix = PANGO_MATRIX_INIT;
-       dir = (gint) (compass->data->heading / 45) * 45 + angle[i];
+       dir = (gint) (compass->heading / 45) * 45 + angle[i];
 
        switch (dir) {
        case 0:
@@ -373,31 +407,35 @@ for (i = 0; i < 5; i++) {
                break;
        }
 
-       tmp = ((dir - compass->data->heading) * (1.f / 180.f)) * G_PI;
+       tmp = ((dir - compass->heading) * (1.f / 180.f)) * G_PI;
 
        gtk_compass_draw_mark(compass, compass->gc_h, tmp, 6);
 
        x = fsize[i];
-       if (abs((guint) (compass->data->heading / 45) * 45 - compass->data->heading)
-           > abs((guint) (compass->data->heading / 45) * 45 + 45 - compass->data->heading) && (i > 0))
+       if (abs((guint) (compass->heading / 45) * 45 - compass->heading)
+           > abs((guint) (compass->heading / 45) * 45 + 45 - compass->heading) && (i > 0))
                        x = fsize[i - 1];
 
        pango_font_description_set_size(compass->fontdesc, (10 + x + fs) * PANGO_SCALE);
        pango_layout_set_font_description(compass->layout, compass->fontdesc);
        pango_layout_set_text(compass->layout, text, -1);
-       pango_matrix_rotate (&matrix, -(dir-compass->data->heading));
+       pango_matrix_rotate (&matrix, -(dir-compass->heading));
        pango_context_set_matrix (compass->context, &matrix);
        pango_layout_get_pixel_size(compass->layout, &x, &y);
-       x = compass->xoffset + size / 2 + ((size / 2 + 15 + fs) * sinf(tmp)) - x / 2,
-    y = compass->yoffset + size - ((size / 2 + 15 + fs) * cosf(tmp)) - y / 2,
+       x = compass->xoffset + hsize + ((hsize + 15 + fs) * sinf(tmp)) - x / 2,
+    y = compass->yoffset + size - ((hsize + 15 + fs) * cosf(tmp)) - y / 2,
     gdk_draw_layout(widget->window, compass->gc_h, x, y, compass->layout);
 }
 
-if (compass->dest_valid)
-       gtk_compass_draw_mark(compass, compass->gc_d, compass->dest_heading, 10);
+if (compass->dest_valid) {
+       tmp=((compass->dest_heading-compass->heading) * (1.f / 180.f)) * G_PI;
+       gtk_compass_draw_mark(compass, compass->gc_d, tmp, 10);
+}
 
-if (compass->way_valid)
-       gtk_compass_draw_mark(compass, compass->gc_w, compass->way_heading, 10);
+if (compass->way_valid) {
+       tmp=((compass->way_heading-compass->heading) * (1.f / 180.f)) * G_PI;
+       gtk_compass_draw_mark(compass, compass->gc_w, tmp, 10);
+}
 
 return;
 }
@@ -415,6 +453,44 @@ gtk_compass_paint(compass);
 return TRUE;
 }
 
+static gboolean
+gtk_compass_refresh_cb(GtkWidget *widget)
+{
+GtkCompass *compass;
+gfloat tmp;
+
+g_return_val_if_fail(GTK_IS_COMPASS(widget), FALSE);
+
+compass=GTK_COMPASS(widget);
+
+if ((GTK_WIDGET_MAPPED(widget)==FALSE) || (GTK_WIDGET_VISIBLE(widget)==FALSE)) {
+       compass->heading=compass->data->heading;
+       return TRUE;
+}
+
+if (compass->heading==compass->data->heading)
+       return TRUE;
+
+tmp=fabsf(compass->heading-compass->data->heading);
+if (tmp>5)
+       tmp=tmp/2.2;
+else
+       compass->heading=compass->data->heading;
+
+if (compass->heading<compass->data->heading)
+       compass->heading+=tmp;
+
+if (compass->heading>compass->data->heading)
+       compass->heading-=tmp;
+
+#ifdef DEBUG
+g_printf("%.2f %.2f\n", compass->heading, compass->data->heading);
+#endif
+
+gtk_widget_queue_draw_area(widget, 0, 0, compass->width, compass->height);
+return TRUE;
+}
+
 void
 gtk_compass_refresh(GtkWidget *widget)
 {