fix:gtk:Provide options to make the cursor more visible in gtk. Fixes ticket #22
authormattcallow <mattcallow@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Tue, 4 Mar 2008 06:11:23 +0000 (06:11 +0000)
committermattcallow <mattcallow@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Tue, 4 Mar 2008 06:11:23 +0000 (06:11 +0000)
git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk@939 ffa7fe5e-494d-0410-b361-a75ebd5db220

navit/src/attr_def.h
navit/src/cursor.c
navit/src/cursor.h
navit/src/graphics.c
navit/src/graphics.h
navit/src/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c
navit/src/graphics/opengl/graphics_opengl.c
navit/src/navit.c
navit/src/navit.xml

index 984aa96..79cd760 100644 (file)
@@ -47,6 +47,7 @@ ATTR(tracking)
 ATTR(menubar)
 ATTR(statusbar)
 ATTR(toolbar)
+ATTR(animate)
 ATTR2(0x0002ffff,type_int_end)
 ATTR2(0x00030000,type_string_begin)
 ATTR(type)
@@ -105,6 +106,7 @@ ATTR(center)
 ATTR2(0x0006ffff,type_coord_geo_end)
 ATTR2(0x00070000,type_color_begin)
 ATTR(color)
+ATTR(color2)
 ATTR2(0x0007ffff,type_color_end)
 ATTR2(0x00080000,type_object_begin)
 ATTR(navit)
index 109315e..ff2d4b5 100644 (file)
 
 struct cursor {
        struct graphics *gra;
-       struct graphics_gc *cursor_gc;
+#define NUM_GC 5
+       struct graphics_gc *cursor_gc[NUM_GC];
+       struct graphics_gc *cursor_gc2[NUM_GC];
+       int current_gc;
+       int last_dir;
+       int last_draw_dir;
+       guint animate_timer;    
        struct point cursor_pnt;
 };
 
@@ -45,6 +51,8 @@ cursor_draw(struct cursor *this_, struct point *pnt, int dir, int draw_dir, int
                return;
        if (!graphics_ready(gra))
                return;
+       this_->last_dir = dir;
+       this_->last_draw_dir = draw_dir;
        cpnt[0]=this_->cursor_pnt;
        cpnt[0].x-=r+lw;
        cpnt[0].y-=r+lw;
@@ -56,7 +64,9 @@ cursor_draw(struct cursor *this_, struct point *pnt, int dir, int draw_dir, int
                y=pnt->y;
                cpnt[0].x=x;
                cpnt[0].y=y;
-               graphics_draw_circle(gra, this_->cursor_gc, &cpnt[0], r*2);
+               graphics_draw_circle(gra, this_->cursor_gc[this_->current_gc], &cpnt[0], r*2);
+               if (this_->cursor_gc2[this_->current_gc])
+                       graphics_draw_circle(gra, this_->cursor_gc2[this_->current_gc], &cpnt[0], r*2-4);
                if (draw_dir) {
                        dx=sin(M_PI*dir/180.0);
                        dy=-cos(M_PI*dir/180.0);
@@ -69,24 +79,77 @@ cursor_draw(struct cursor *this_, struct point *pnt, int dir, int draw_dir, int
                        cpnt[1].y=y+dy*r;
                        cpnt[2].x=x-dx*fac1-dy*fac2;
                        cpnt[2].y=y-dy*fac1+dx*fac2;
-                       graphics_draw_lines(gra, this_->cursor_gc, cpnt, 3);
+                       graphics_draw_lines(gra, this_->cursor_gc[this_->current_gc], cpnt, 3);
+
+                       if (this_->cursor_gc2[this_->current_gc]) {
+                               r-=4;
+                               fac1=0.7*r;
+                               fac2=0.4*r;     
+                               cpnt[0].x=x-dx*fac1+dy*fac2;
+                               cpnt[0].y=y-dy*fac1-dx*fac2;
+                               cpnt[1].x=x+dx*r;
+                               cpnt[1].y=y+dy*r;
+                               cpnt[2].x=x-dx*fac1-dy*fac2;
+                               cpnt[2].y=y-dy*fac1+dx*fac2;
+                               graphics_draw_lines(gra, this_->cursor_gc2[this_->current_gc], cpnt, 3);
+                       }
                } else {
                        cpnt[1]=cpnt[0];
-                       graphics_draw_lines(gra, this_->cursor_gc, cpnt, 2);
+                       graphics_draw_lines(gra, this_->cursor_gc[this_->current_gc], cpnt, 2);
+                       if (this_->cursor_gc2[this_->current_gc])
+                               graphics_draw_circle(gra, this_->cursor_gc2[this_->current_gc], &cpnt[0], 4);
                }
                graphics_draw_mode(gra, draw_mode_end);
        }
 }
 
+static gboolean cursor_animate(struct cursor * this)
+{
+       this->current_gc++;
+       if (this->current_gc >= NUM_GC)
+               this->current_gc=0;
+       struct point p;
+       p.x = this->cursor_pnt.x;
+       p.y = this->cursor_pnt.y;
+       cursor_draw(this, &p, this->last_dir, this->last_draw_dir, 1);
+       return TRUE;
+}
+
 struct cursor *
-cursor_new(struct graphics *gra, struct color *c)
+cursor_new(struct graphics *gra, struct color *c, struct color *c2, int animate)
 {
+       unsigned char dash_list[] = { 4, 6 };
+       int i;
        dbg(2,"enter gra=%p c=%p\n", gra, c);
        struct cursor *this=g_new(struct cursor,1);
        this->gra=gra;
-       this->cursor_gc=graphics_gc_new(gra);
-       graphics_gc_set_foreground(this->cursor_gc, c);
-       graphics_gc_set_linewidth(this->cursor_gc, 2);
+       this->animate_timer=0;
+       for (i=0;i<NUM_GC;i++) {
+               this->cursor_gc[i]=NULL;
+               this->cursor_gc2[i]=NULL;
+       }
+       this->current_gc=0;
+       for (i=0;i<NUM_GC;i++) {
+               this->cursor_gc[i]=graphics_gc_new(gra);
+               graphics_gc_set_foreground(this->cursor_gc[i], c);
+               graphics_gc_set_linewidth(this->cursor_gc[i], 2);
+               if (c2) {
+                       this->cursor_gc2[i]=graphics_gc_new(gra);
+                       graphics_gc_set_foreground(this->cursor_gc2[i], c2);
+               }
+               if (animate) {
+                       graphics_gc_set_dashes(this->cursor_gc[i], 2, (NUM_GC-i)*2, dash_list, 2);
+                       if(this->cursor_gc2[i])
+                               graphics_gc_set_dashes(this->cursor_gc2[i], 2, i*2, dash_list, 2);
+               } else {
+                       graphics_gc_set_linewidth(this->cursor_gc[i], 2);
+                       if(this->cursor_gc2[i])
+                               graphics_gc_set_linewidth(this->cursor_gc2[i], 2);
+                       break; // no need to create other GCs if we are not animating
+               }
+       }
+       if (animate)
+               this->animate_timer=g_timeout_add(250, (GSourceFunc)cursor_animate, (gpointer *)this);  
        dbg(2,"ret=%p\n", this);
        return this;
 }
@@ -94,6 +157,13 @@ cursor_new(struct graphics *gra, struct color *c)
 void
 cursor_destroy(struct cursor *this_)
 {
-       graphics_gc_destroy(this_->cursor_gc);
+       int i;
+       if (this_->animate_timer)
+               g_source_remove(this_->animate_timer);
+       for (i=0;i<NUM_GC;i++)
+               if(this_->cursor_gc[i])
+                       graphics_gc_destroy(this_->cursor_gc[i]);
+               if(this_->cursor_gc2[i])
+                       graphics_gc_destroy(this_->cursor_gc2[i]);
        g_free(this_);
 }
index 7e7ec5e..203ef08 100644 (file)
@@ -7,7 +7,7 @@ struct cursor;
 struct graphics;
 struct point;
 void cursor_draw(struct cursor *this_, struct point *pnt, int dir, int draw_dir, int force);
-struct cursor *cursor_new(struct graphics *gra, struct color *c);
+struct cursor *cursor_new(struct graphics *gra, struct color *c, struct color *c2, int animate);
 void cursor_destroy(struct cursor *this_);
 /* end of prototypes */
 
index 6843aff..a4e188d 100644 (file)
@@ -139,6 +139,13 @@ graphics_gc_set_linewidth(struct graphics_gc *gc, int width)
        gc->meth.gc_set_linewidth(gc->priv, width);
 }
 
+void
+graphics_gc_set_dashes(struct graphics_gc *gc, int width, int offset, unsigned char dash_list[], int n)
+{
+       if (gc->meth.gc_set_dashes)
+               gc->meth.gc_set_dashes(gc->priv, width, offset, dash_list, n);
+}
+
 struct graphics_image *
 graphics_image_new(struct graphics *gra, char *path)
 {
index 6cd4811..067f588 100644 (file)
@@ -62,7 +62,7 @@ struct graphics_font {
 struct graphics_gc_methods {
        void (*gc_destroy)(struct graphics_gc_priv *gc);
        void (*gc_set_linewidth)(struct graphics_gc_priv *gc, int width);
-       void (*gc_set_dashes)(struct graphics_gc_priv *gc, unsigned char dash_list[], int n);
+       void (*gc_set_dashes)(struct graphics_gc_priv *gc, int width, int offset, unsigned char dash_list[], int n);
        void (*gc_set_foreground)(struct graphics_gc_priv *gc, struct color *c);
        void (*gc_set_background)(struct graphics_gc_priv *gc, struct color *c);
 };
@@ -112,6 +112,7 @@ void graphics_gc_destroy(struct graphics_gc *gc);
 void graphics_gc_set_foreground(struct graphics_gc *gc, struct color *c);
 void graphics_gc_set_background(struct graphics_gc *gc, struct color *c);
 void graphics_gc_set_linewidth(struct graphics_gc *gc, int width);
+void graphics_gc_set_dashes(struct graphics_gc *gc, int width, int offset, unsigned char dash_list[], int n);
 struct graphics_image *graphics_image_new(struct graphics *gra, char *path);
 void graphics_image_free(struct graphics *gra, struct graphics_image *img);
 void graphics_draw_restore(struct graphics *this_, struct point *p, int w, int h);
index c647950..f9540b1 100644 (file)
@@ -160,10 +160,10 @@ gc_set_linewidth(struct graphics_gc_priv *gc, int w)
 }
 
 static void
-gc_set_dashes(struct graphics_gc_priv *gc, unsigned char *dash_list, int n)
+gc_set_dashes(struct graphics_gc_priv *gc, int w, int offset, unsigned char *dash_list, int n)
 {
-       gdk_gc_set_dashes(gc->gc, 0, (gint8 *)dash_list, n);
-       gdk_gc_set_line_attributes(gc->gc, 1, GDK_LINE_ON_OFF_DASH, GDK_CAP_ROUND, GDK_JOIN_ROUND);
+       gdk_gc_set_dashes(gc->gc, offset, (gint8 *)dash_list, n);
+       gdk_gc_set_line_attributes(gc->gc, w, GDK_LINE_ON_OFF_DASH, GDK_CAP_ROUND, GDK_JOIN_ROUND);
 }
 
 static void
index 9ad7bbe..fce72f4 100644 (file)
@@ -123,11 +123,11 @@ gc_set_linewidth(struct graphics_gc_priv *gc, int w)
 }
 
 static void
-gc_set_dashes(struct graphics_gc_priv *gc, unsigned char *dash_list, int n)
+gc_set_dashes(struct graphics_gc_priv *gc, int width, int offset, unsigned char *dash_list, int n)
 {
 #if 0
-       gdk_gc_set_dashes(gc->gc, 0, (gint8 *)dash_list, n);
-       gdk_gc_set_line_attributes(gc->gc, 1, GDK_LINE_ON_OFF_DASH, GDK_CAP_ROUND, GDK_JOIN_ROUND);
+       gdk_gc_set_dashes(gc->gc, offset, (gint8 *)dash_list, n);
+       gdk_gc_set_line_attributes(gc->gc, width, GDK_LINE_ON_OFF_DASH, GDK_CAP_ROUND, GDK_JOIN_ROUND);
 #endif
 }
 
index 6fb5c02..7da01b7 100644 (file)
@@ -50,10 +50,12 @@ struct navit_vehicle {
        int dir;
        int speed;
        struct color c;
+       struct color *c2;
        struct menu *menu;
        struct cursor *cursor;
        struct vehicle *vehicle;
        struct attr callback;
+       int animate_cursor;
 };
 
 struct navit {
@@ -1104,7 +1106,7 @@ navit_init(struct navit *this_)
        while (l) {
                dbg(1,"parsed one vehicle\n");
                nv=l->data;
-               nv->cursor=cursor_new(this_->gra, &nv->c);
+               nv->cursor=cursor_new(this_->gra, &nv->c, nv->c2, nv->animate_cursor);
                nv->callback.type=attr_callback;
                nv->callback.u.callback=callback_new_2(callback_cast(navit_vehicle_update), this_, nv);
                vehicle_add_attr(nv->vehicle, &nv->callback, NULL);
@@ -1479,10 +1481,11 @@ struct navit_vehicle *
 navit_add_vehicle(struct navit *this_, struct vehicle *v, struct attr **attrs)
 {
        struct navit_vehicle *nv=g_new0(struct navit_vehicle, 1);
-       struct attr *name,*update,*follow,*color,*active;
+       struct attr *name,*update,*follow,*color,*active, *color2, *animate;
        nv->vehicle=v;
        nv->update=1;
        nv->follow=0;
+       nv->animate_cursor=0;
        nv->name="Noname";
        if ((name=attr_search(attrs, NULL, attr_name)))
                nv->name=g_strdup(name->u.str);
@@ -1492,12 +1495,17 @@ navit_add_vehicle(struct navit *this_, struct vehicle *v, struct attr **attrs)
                nv->follow=nv->follow=follow->u.num;
        if ((color=attr_search(attrs, NULL, attr_color)))
                nv->c=*(color->u.color);
+       if ((color2=attr_search(attrs, NULL, attr_color2)))
+               nv->c2=color2->u.color;
+       else
+               nv->c2=NULL;
        nv->update_curr=nv->update;
        nv->follow_curr=nv->follow;
        this_->vehicles=g_list_append(this_->vehicles, nv);
        if ((active=attr_search(attrs, NULL, attr_active)) && active->u.num)
                navit_set_vehicle(this_, nv);
-
+       if ((animate=attr_search(attrs, NULL, attr_animate)))
+               nv->animate_cursor=animate->u.num;
        return nv;
 }
 
index 50c2856..41ca143 100644 (file)
@@ -22,6 +22,10 @@ Change to your home coordinates.
 -->
        
        <vehicle name="Meins" enabled="yes" active="1" source="gpsd://localhost" gpsd_query="w+xjr+" color="#0000ff"/>
+       <!-- To improve visibility of the cursor in gtk, you may optionally add:
+               color2="#rrggbb"  - draws a second cursor inside the original, in the specified colour
+               animate="1" - animates the cursor, as series of moving dots
+       -->
        <!-- For SDL, you should add follow="1" refresh="1" to have the view centered on your position
        <vehicle name="Meins" enabled="yes" source="gpsd://localhost" color="#0000ff" follow="1" refresh="1"/>
        -->