]> err.no Git - mapper/blobdiff - src/gtkcompass.c
Include settings.h so the banner macro hildon version works.
[mapper] / src / gtkcompass.c
index 682e2ab2073858074ade25fbe6a21795abe03ded..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,39 +98,43 @@ 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)
 {
-g_printf("%s()\n", __PRETTY_FUNCTION__);
-
 compass->gc_h=NULL;
 compass->gc_d=NULL;
 compass->gc_w=NULL;
 compass->dest_valid=FALSE;
 compass->way_valid=FALSE;
-compass->width=400;
+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;
 }
 
@@ -124,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;
 }
 
@@ -132,11 +159,10 @@ static void
 gtk_compass_finalize(GObject *object)
 {
 GtkCompass *compass;
-
-g_printf("%s()\n", __PRETTY_FUNCTION__);
        
 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,13 +175,11 @@ static void
 gtk_compass_size_request(GtkWidget     *widget, GtkRequisition *requisition)
 {
 GtkCompass *compass;
-
-g_printf("%s()\n", __PRETTY_FUNCTION__);
        
 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;
@@ -168,8 +192,6 @@ gtk_compass_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
 {
 GtkCompass *compass;
 
-g_printf("%s()\n", __PRETTY_FUNCTION__);
-
 g_return_if_fail(GTK_IS_COMPASS(widget));
 g_return_if_fail(allocation!=NULL);
 
@@ -205,8 +227,6 @@ GdkColor color;
 GdkWindowAttr attributes;
 gint attributes_mask;
 
-g_printf("%s()\n", __PRETTY_FUNCTION__);
-
 g_return_if_fail (GTK_IS_COMPASS(widget));
 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
 compass=GTK_COMPASS(widget);
@@ -243,7 +263,7 @@ if (!compass->gc_h) {
        color.blue=0x0000;
        compass->gc_h=gdk_gc_new(widget->window);
        gdk_gc_set_rgb_fg_color(compass->gc_h, &color);
-       gdk_gc_set_line_attributes(compass->gc_h, 6, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
+       gdk_gc_set_line_attributes(compass->gc_h, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
 }
 
 if (!compass->gc_d) {
@@ -267,7 +287,7 @@ if (!compass->gc_w) {
 }
 
 static void
-gtk_compass_draw_mark(GtkCompass *compass, GdkGC *gc, gdouble t)
+gtk_compass_draw_mark(GtkCompass *compass, GdkGC *gc, gfloat angle, gint size)
 {
 GtkWidget *widget;
 gint hs;
@@ -277,17 +297,17 @@ widget=GTK_WIDGET(compass);
 hs=compass->size/2;
 
 gdk_draw_line(widget->window,gc,
-       compass->xoffset+hs+((hs-5)*sin(t)),
-       compass->yoffset+compass->size-((hs-5)*cos(t)),
-       compass->xoffset+hs+((hs+5)*sin(t)),
-       compass->yoffset+compass->size-((hs+5)*cos(t)));
+       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
 gtk_compass_paint(GtkCompass *compass)
 {
 GtkWidget *widget;
-guint i, x, y, size, hsize;
+guint i, x, y, size, hsize, fs;
 gint dir;
 gfloat tmp;
 gchar *text;
@@ -297,55 +317,61 @@ 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/41;
+BOUND(fs, 1, 16);
+
+pango_context_set_matrix (compass->context, NULL);
 
 g_snprintf(htext, 8, "%3.0f°", compass->data->heading);
+pango_font_description_set_size(compass->fontdesc, (10+fs) * PANGO_SCALE);
+pango_layout_set_font_description(compass->layout, compass->fontdesc);
 pango_layout_set_text(compass->layout, htext, -1);
 pango_layout_get_pixel_size(compass->layout, &x, &y);
 
-gtk_paint_flat_box (widget->style,
-       widget->window,
-       GTK_STATE_NORMAL, GTK_SHADOW_NONE,
-       NULL, widget, "trough", 0, 0,
-       compass->width, compass->height);
-
 gdk_draw_layout(widget->window,
-       widget->style->fg_gc[GTK_STATE_NORMAL],
-       compass->xoffset+size/2-x/2,
+       compass->gc_h,
+       compass->xoffset+hsize-x/2,
        compass->yoffset+size-y-2, compass->layout);
 
 gdk_draw_arc(widget->window,
-       widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+       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,
-       widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
-       compass->xoffset + size / 2 + 3,
+       compass->gc_h,
+       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,
-       widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
-       compass->xoffset + size / 2 - 3,
+       compass->gc_h,
+       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,
-       widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
-       compass->xoffset + size / 2 - 3,
+       compass->gc_h,
+       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,
-       widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
-       compass->xoffset + size / 2 + 3,
+       compass->gc_h,
+       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++) {
-       dir = (gint) (compass->data->heading / 45) * 45 + angle[i];
+       PangoMatrix matrix = PANGO_MATRIX_INIT;
+       dir = (gint) (compass->heading / 45) * 45 + angle[i];
 
        switch (dir) {
        case 0:
@@ -381,46 +407,44 @@ for (i = 0; i < 5; i++) {
                break;
        }
 
-       tmp = ((dir - compass->data->heading) * (1.f / 180.f)) * G_PI;
-       gdk_draw_line(widget->window,
-             widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
-             compass->xoffset + size / 2 + ((size / 2 - 5) * sinf(tmp)),
-             compass->yoffset + size - ((size / 2 - 5) * cosf(tmp)),
-             compass->xoffset + size / 2 + ((size / 2 + 5) * sinf(tmp)),
-             compass->yoffset + size - ((size / 2 + 5) * cosf(tmp)));
+       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) * PANGO_SCALE);
+       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->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) * sinf(tmp)) - x / 2,
-    y = compass->yoffset + size - ((size / 2 + 15) * cosf(tmp)) - y / 2,
-    gdk_draw_layout(widget->window,
-           widget->style->fg_gc[GTK_STATE_NORMAL],
-           x, y, compass->layout);
-
-       if (compass->dest_valid) {
-               gtk_compass_draw_mark(compass, compass->gc_d, compass->dest_heading);
-       }
+       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->way_valid) {
-               gtk_compass_draw_mark(compass, compass->gc_w, compass->way_heading);
-       }
+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);
 }
 
-return TRUE;
+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;
+}
 
 static gboolean
 gtk_compass_expose(GtkWidget *widget, GdkEventExpose *event)
 {
 GtkCompass *compass;
+
 g_return_val_if_fail(GTK_IS_COMPASS(widget), FALSE);
 g_return_val_if_fail(event != NULL, FALSE);
 
@@ -429,16 +453,81 @@ 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)
 {
 GtkCompass *compass;
 
-g_printf("%s()\n", __PRETTY_FUNCTION__);
 g_return_if_fail(GTK_IS_COMPASS(widget));
 
 compass=GTK_COMPASS(widget);
-gtk_compass_paint(compass);
+gtk_widget_queue_draw_area(widget, 0, 0, compass->width, compass->height);
+}
+
+void 
+gtk_compass_set_way_heading(GtkWidget *widget, gboolean valid, gfloat heading)
+{
+GtkCompass *compass;
+g_return_if_fail(GTK_IS_COMPASS(widget));
+
+compass=GTK_COMPASS(widget);
+
+compass->way_valid=valid;
+compass->way_heading=heading;
+
+gtk_widget_queue_draw_area(widget, 0, 0, compass->width, compass->height);
+}
+
+void 
+gtk_compass_set_dest_heading(GtkWidget *widget, gboolean valid, gfloat heading)
+{
+GtkCompass *compass;
+g_return_if_fail(GTK_IS_COMPASS(widget));
+
+compass=GTK_COMPASS(widget);
+
+compass->dest_valid=valid;
+compass->dest_heading=heading;
 
-g_printf("%s(): return\n", __PRETTY_FUNCTION__);
+compass=GTK_COMPASS(widget);
+gtk_widget_queue_draw_area(widget, 0, 0, compass->width, compass->height);
 }
+