Add:Core:Made cursor configurable via navit.xml
authormartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Thu, 6 Nov 2008 13:45:21 +0000 (13:45 +0000)
committermartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Thu, 6 Nov 2008 13:45:21 +0000 (13:45 +0000)
git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk/navit@1653 ffa7fe5e-494d-0410-b361-a75ebd5db220

18 files changed:
navit/attr.c
navit/attr.h
navit/attr_def.h
navit/coord.c
navit/coord.h
navit/cursor.c
navit/cursor.h
navit/graphics.c
navit/graphics.h
navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c
navit/layout.c
navit/layout.h
navit/navit.c
navit/navit.xml
navit/projection.h
navit/transform.c
navit/vehicle.c
navit/xmlconfig.c

index 53fc5a0..2caa09c 100644 (file)
@@ -110,6 +110,9 @@ attr_new_from_text(const char *name, const char *value)
                g_free(type_str);
                break;
        case attr_order:
+       case attr_sequence_range:
+       case attr_angle_range:
+       case attr_speed_range:
                pos=strchr(value, '-');
                min=0;
                max=32767;
@@ -120,8 +123,8 @@ attr_new_from_text(const char *name, const char *value)
                        sscanf(value,"-%d",&max);
                else
                        sscanf(value,"%d-%d",&min, &max);
-               ret->u.order.min=min;
-               ret->u.order.max=max;
+               ret->u.range.min=min;
+               ret->u.range.max=max;
                break;
        default:
                if (attr >= attr_type_string_begin && attr <= attr_type_string_end) {
@@ -266,6 +269,24 @@ attr_generic_set_attr(struct attr **attrs, struct attr *attr)
        return curr;
 }
 
+struct attr **
+attr_generic_add_attr(struct attr **attrs, struct attr *attr)
+{
+       struct attr **curr=attrs;
+       int i,count=0;
+       while (curr && *curr) {
+               curr++;
+               count++;
+       }
+       curr=g_new0(struct attr *, count+2);
+       for (i = 0 ; i < count ; i++)
+               curr[i]=attrs[i];
+       curr[count]=attr_dup(attr);
+       curr[count+1]=NULL;
+       g_free(attrs);
+       return curr;
+}
+
 int
 attr_data_size(struct attr *attr)
 {
@@ -322,9 +343,11 @@ attr_dup(struct attr *attr)
        int size;
        struct attr *ret=g_new0(struct attr, 1);
        ret->type=attr->type;
-       if (attr->type >= attr_type_int_begin && attr->type <= attr_type_int_end) {
+       if (attr->type >= attr_type_int_begin && attr->type <= attr_type_int_end) 
                ret->u.num=attr->u.num;
-       } else {
+       else if (attr->type >= attr_type_object_begin && attr->type <= attr_type_object_end) 
+               ret->u.data=attr->u.data;
+       else {
                size=attr_data_size(attr);
                if (size) {
                        ret->u.data=g_malloc(size);
index a6b0727..2d1cf93 100644 (file)
@@ -84,9 +84,10 @@ struct attr {
                struct arrows *arrows;
                struct element *element;
                struct speech *speech;
-               struct order {
+               struct cursor *cursor;
+               struct range {
                        short min, max;
-               } order;
+               } range;
                int *dash;
                enum item_type *item_types;
        } u;
index 9a9ee2b..97d9c5d 100644 (file)
@@ -167,6 +167,9 @@ ATTR(order)
 ATTR(item_type)
 ATTR(item_types)
 ATTR(dash)
+ATTR(sequence_range)
+ATTR(angle_range)
+ATTR(speed_range)
 ATTR2(0x0004ffff,type_special_end)
 ATTR2(0x00050000,type_double_begin)
 ATTR(position_height)
@@ -208,6 +211,7 @@ ATTR(mapset)
 ATTR(osd)
 ATTR(plugin)
 ATTR(speech)
+ATTR(coord)
 ATTR2(0x0008ffff,type_object_end)
 ATTR2(0x00090000,type_coord_begin)
 ATTR2(0x0009ffff,type_coord_end)
index fc262bb..7879347 100644 (file)
@@ -23,6 +23,7 @@
 #include <string.h>
 #include <math.h>
 #include "debug.h"
+#include "item.h"
 #include "coord.h"
 #include "transform.h"
 #include "projection.h"
@@ -57,6 +58,18 @@ coord_new(int x, int y)
        return c;
 }
 
+struct coord *
+coord_new_from_attrs(struct attr *parent, struct attr **attrs)
+{
+       struct attr *x,*y;
+       x=attr_search(attrs, NULL, attr_x);
+       y=attr_search(attrs, NULL, attr_y);
+       if (!x || !y)
+               return NULL;
+       return coord_new(x->u.num, y->u.num);
+}
+
+
 void
 coord_destroy(struct coord *c)
 {
index 030bf22..3ffef90 100644 (file)
@@ -60,9 +60,11 @@ struct coord_geo_cart {
 };
 
 enum projection;
+struct attr;
 
 struct coord * coord_get(unsigned char **p);
 struct coord * coord_new(int x, int y);
+struct coord * coord_new_from_attrs(struct attr *parent, struct attr **attrs);
 void coord_destroy(struct coord *c);
 int coord_parse(const char *c_str, enum projection pro, struct coord *c_ret);
 void coord_print(enum projection pro, struct coord *c, FILE *out);
index 2a7ef57..56b156e 100644 (file)
 #include "color.h"
 #include "cursor.h"
 #include "compass.h"
+#include "item.h"
+#include "layout.h"
 #include "event.h"
 /* #include "track.h" */
 
 
-
 struct cursor {
+       int w,h;
        struct graphics *gra;
-#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;
        struct callback *animate_callback;
        struct event_timeout *animate_timer;    
        struct point cursor_pnt;
+       struct graphics_gc *bg;
+       struct attr **attrs;
+       struct transformation *trans;
+       int sequence;
+       int angle;
+       int speed;
 };
 
 
-void
-cursor_draw(struct cursor *this_, struct point *pnt, int dir, int draw_dir, int force)
+
+static void
+cursor_draw_do(struct cursor *this_, int lazy)
 {
-       int x=this_->cursor_pnt.x;
-       int y=this_->cursor_pnt.y;
-       int r=12,lw=2;
-       double dx,dy;
-       double fac1,fac2;
-       struct point cpnt[3];
-       struct graphics *gra=this_->gra;
+       struct point p;
+       int speed=this_->speed;
+       int angle=this_->angle;
 
-       if (pnt && x == pnt->x && y == pnt->y && !force)
+       if (!this_->attrs || !this_->gra)
                return;
-       if (!graphics_ready(gra))
+       if (!this_->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;
-       graphics_draw_restore(gra, &cpnt[0], (r+lw)*2, (r+lw)*2);
-       if (pnt) {
-               graphics_draw_mode(gra, draw_mode_cursor);
-               this_->cursor_pnt=*pnt;
-               x=pnt->x;
-               y=pnt->y;
-               cpnt[0].x=x;
-               cpnt[0].y=y;
-               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);
-
-                       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_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);
+       transform_set_angle(this_->trans, this_->angle);
+       graphics_draw_mode(this_->gra, draw_mode_begin);
+       p.x=0;
+       p.y=0;
+       graphics_draw_rectangle(this_->gra, this_->bg, &p, this_->w, this_->h);
+       for (;;) {
+               struct attr **attr=this_->attrs;
+               int sequence=this_->sequence;
+               int match=0;
+               while (*attr) {
+                       if ((*attr)->type == attr_itemgra) {
+                               struct itemgra *itm=(*attr)->u.itemgra;
+                               dbg(1,"speed %d-%d %d\n", itm->speed_range.min, itm->speed_range.max, speed);
+                               if (speed >= itm->speed_range.min && speed <= itm->speed_range.max &&  
+                                   angle >= itm->angle_range.min && angle <= itm->angle_range.max &&  
+                                   sequence >= itm->sequence_range.min && sequence <= itm->sequence_range.max) {
+                                       graphics_draw_itemgra(this_->gra, itm, this_->trans);
+                                       match=1;
+                               }
                        }
+                       attr++;
+               }
+               if (match) {
+                       break;
                } else {
-                       cpnt[1]=cpnt[0];
-                       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);
+                       if (this_->sequence) 
+                               this_->sequence=0;
+                       else
+                               break;
                }
-               graphics_draw_mode(gra, draw_mode_end);
        }
+       graphics_draw_drag(this_->gra, &this_->cursor_pnt);
+       graphics_draw_mode(this_->gra, lazy ? draw_mode_end_lazy : draw_mode_end);
+}
+
+void
+cursor_draw(struct cursor *this_, struct graphics *gra, struct point *pnt, int lazy, int angle, int speed)
+{
+       if (angle < 0)
+               angle+=360;
+       dbg(1,"enter this=%p gra=%p pnt=%p lazy=%d dir=%d speed=%d\n", this_, gra, pnt, lazy, angle, speed);
+       dbg(1,"point %d,%d\n", pnt->x, pnt->y);
+       this_->cursor_pnt=*pnt;
+       this_->cursor_pnt.x-=this_->w/2;
+       this_->cursor_pnt.y-=this_->h/2;
+       this_->angle=angle;
+       this_->speed=speed;
+       if (!this_->gra) {
+               struct color c;
+               this_->gra=graphics_overlay_new(gra, &this_->cursor_pnt, this_->w, this_->h, 65535);
+               this_->bg=graphics_gc_new(this_->gra);
+               c.r=0; c.g=0; c.b=0; c.a=0;
+               graphics_gc_set_foreground(this_->bg, &c);
+               graphics_background_gc(this_->gra, this_->bg);
+       }
+       cursor_draw_do(this_, lazy);
 }
 
 static void
 cursor_animate(struct cursor * this)
 {
-       struct point p;
-       this->current_gc++;
-       if (this->current_gc >= NUM_GC)
-               this->current_gc=0;
-       p.x = this->cursor_pnt.x;
-       p.y = this->cursor_pnt.y;
-       cursor_draw(this, &p, this->last_dir, this->last_draw_dir, 1);
+       this->sequence++;
+       cursor_draw_do(this, 0);
+}
+
+int
+cursor_add_attr(struct cursor *this_, struct attr *attr)
+{
+        int ret=1;
+        switch (attr->type) {
+        case attr_itemgra:
+                break;
+       default:
+               ret=0;
+        }
+        if (ret)
+                this_->attrs=attr_generic_add_attr(this_->attrs, attr);
+        return ret;
 }
 
 struct cursor *
-cursor_new(struct graphics *gra, struct color *c, struct color *c2, int animate)
+cursor_new(struct attr *parent, struct attr **attrs)
 {
-       unsigned char dash_list[] = { 4, 6 };
-       int i;
-       struct cursor *this=g_new(struct cursor,1);
-       dbg(2,"enter gra=%p c=%p\n", gra, c);
-       this->gra=gra;
-       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) {
+       struct cursor *this=g_new0(struct cursor,1);
+       struct attr *w,*h, *interval;
+       struct pcoord center;
+       struct point scenter;
+       w=attr_search(attrs, NULL, attr_w);
+       h=attr_search(attrs, NULL, attr_h);
+       if (! w || ! h)
+               return NULL;
+
+       this->w=w->u.num;
+       this->h=h->u.num;
+       this->trans=transform_new();
+       center.pro=projection_screen;
+       center.x=0;
+       center.y=0;
+       transform_setup(this->trans, &center, 16, 0);
+       scenter.x=this->w/2;
+       scenter.y=this->h/2;
+       transform_set_screen_center(this->trans, &scenter);
+       interval=attr_search(attrs, NULL, attr_interval);
+       if (interval) {
                this->animate_callback=callback_new_1(callback_cast(cursor_animate), this);
-               this->animate_timer=event_add_timeout(250, 1, this->animate_callback);
+               this->animate_timer=event_add_timeout(interval->u.num, 1, this->animate_callback);
        }
-       this->cursor_pnt.x = 0;
-       this->cursor_pnt.y = 0;
        dbg(2,"ret=%p\n", this);
        return this;
 }
@@ -180,15 +183,10 @@ cursor_new(struct graphics *gra, struct color *c, struct color *c2, int animate)
 void
 cursor_destroy(struct cursor *this_)
 {
-       int i;
-
-       callback_destroy(this_->animate_callback);
-       event_remove_timeout(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]);
+       if (this_->animate_callback) {
+               callback_destroy(this_->animate_callback);
+               event_remove_timeout(this_->animate_timer);
        }
+       transform_destroy(this_->trans);
        g_free(this_);
 }
index 0f15b6e..e5868cc 100644 (file)
@@ -25,8 +25,9 @@ struct color;
 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 color *c2, int animate);
+void cursor_draw(struct cursor *this_, struct graphics *gra, struct point *pnt, int lazy, int dir, int speed);
+int cursor_add_attr(struct cursor *this_, struct attr *attr);
+struct cursor *cursor_new(struct attr *parent, struct attr **attrs);
 void cursor_destroy(struct cursor *this_);
 /* end of prototypes */
 
index dfba61e..212f117 100644 (file)
@@ -753,6 +753,52 @@ static void xdisplay_draw_elements(struct graphics *gra, GHashTable *display_lis
                graphics_gc_destroy(gc);
 }
 
+void
+graphics_draw_itemgra(struct graphics *gra, struct itemgra *itm, struct transformation *t)
+{
+       GList *es;
+       struct point p;
+       char *label=NULL;
+       struct graphics_gc *gc = NULL;
+       es=itm->elements;
+       while (es) {
+               struct element *e=es->data;
+               int count=e->coord_count;
+               struct point pnt[count];
+               transform(t, projection_screen, e->coord, pnt, count, 0);
+               gc=graphics_gc_new(gra);
+               gc->meth.gc_set_foreground(gc->priv, &e->color);
+               switch (e->type) {
+               case element_polyline:
+                       if (e->u.polyline.width > 1) 
+                               gc->meth.gc_set_linewidth(gc->priv, e->u.polyline.width);
+                       if (e->u.polyline.width > 0 && e->u.polyline.dash_num > 0)
+                               graphics_gc_set_dashes(gc, e->u.polyline.width, 
+                                                      e->u.polyline.offset,
+                                                      e->u.polyline.dash_table,
+                                                      e->u.polyline.dash_num);
+                       gra->meth.draw_lines(gra->priv, gc->priv, pnt, count);
+                       break;
+               case element_circle:
+                       if (e->u.circle.width > 1) 
+                               gc->meth.gc_set_linewidth(gc->priv, e->u.polyline.width);
+                       gra->meth.draw_circle(gra->priv, gc->priv, &pnt[0], e->u.circle.radius);
+                       if (label && e->text_size) {
+                               p.x=pnt[0].x+3;
+                               p.y=pnt[0].y+10;
+                       if (! gra->font[e->text_size])
+                               gra->font[e->text_size]=graphics_font_new(gra, e->text_size*20, 0);
+                               gra->meth.draw_text(gra->priv, gra->gc[2]->priv, gra->gc[1]->priv, gra->font[e->text_size]->priv, label, &p, 0x10000, 0);
+                       }
+               break;
+               default:
+                       dbg(0,"dont know how to draw %d\n", e->type);
+               }
+               graphics_gc_destroy(gc);
+               es=g_list_next(es);
+       }
+}
+
 /**
  * FIXME
  * @param <>
index 0aa5b67..f1831ef 100644 (file)
@@ -34,7 +34,7 @@ struct transformation;
 struct display_list;
 
 enum draw_mode_num {
-       draw_mode_begin, draw_mode_end, draw_mode_cursor
+       draw_mode_begin, draw_mode_end, draw_mode_cursor, draw_mode_end_lazy
 };
 
 struct graphics_priv;
index dae6e31..551edd3 100644 (file)
@@ -21,6 +21,7 @@
 #include "config.h"
 #include <gtk/gtk.h>
 #include <gdk/gdkkeysyms.h>
+#include <stdlib.h>
 #if !defined(GDK_Book) || !defined(GDK_Calendar)
 #include <X11/XF86keysym.h>
 #endif
@@ -61,6 +62,8 @@ struct graphics_priv {
        int background_ready;
        GdkColormap *colormap;
        struct point p;
+       struct point pclean;
+       int cleanup;
        int width;
        int height;
        int win_w;
@@ -361,12 +364,17 @@ draw_image_warp(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct po
 #endif
 
 static void
-overlay_rect(struct graphics_priv *parent, struct graphics_priv *overlay, GdkRectangle *r)
-{
-       r->x=overlay->p.x;
+overlay_rect(struct graphics_priv *parent, struct graphics_priv *overlay, int clean, GdkRectangle *r)
+{
+       if (clean) {
+               r->x=overlay->pclean.x;
+               r->y=overlay->pclean.y;
+       } else {
+               r->x=overlay->p.x;
+               r->y=overlay->p.y;
+       }
        if (r->x < 0)
                r->x += parent->width;
-       r->y=overlay->p.y;
        if (r->y < 0)
                r->y += parent->height;
        r->width=overlay->width;
@@ -391,7 +399,7 @@ overlay_draw(struct graphics_priv *parent, struct graphics_priv *overlay, GdkRec
        if (parent->overlay_disabled || overlay->overlay_disabled)
                return;
        dbg(1,"r->x=%d r->y=%d r->width=%d r->height=%d\n", r->x, r->y, r->width, r->height);
-       overlay_rect(parent, overlay, &or);
+       overlay_rect(parent, overlay, 0, &or);
        dbg(1,"or.x=%d or.y=%d or.width=%d or.height=%d\n", or.x, or.y, or.width, or.height);
        or.x-=r->x;
        or.y-=r->y;
@@ -436,6 +444,10 @@ draw_restore(struct graphics_priv *gr, struct point *p, int w, int h)
 static void
 draw_drag(struct graphics_priv *gr, struct point *p)
 {
+       if (!gr->cleanup) {
+               gr->pclean=gr->p;
+               gr->cleanup=1;
+       }
        if (p)
                gr->p=*p;
        else {
@@ -478,6 +490,7 @@ static void
 draw_mode(struct graphics_priv *gr, enum draw_mode_num mode)
 {
        GdkRectangle r;
+       struct graphics_priv *overlay;
 #if 0
        if (mode == draw_mode_begin) {
                if (! gr->parent && gr->background_gc)
@@ -486,7 +499,12 @@ draw_mode(struct graphics_priv *gr, enum draw_mode_num mode)
 #endif
        if (mode == draw_mode_end && gr->mode != draw_mode_cursor) {
                if (gr->parent) {
-                       overlay_rect(gr->parent, gr, &r);
+                       if (gr->cleanup) {
+                               overlay_rect(gr->parent, gr, 1, &r);
+                               gtk_drawing_area_draw(gr->parent, &r);
+                               gr->cleanup=0;
+                       }
+                       overlay_rect(gr->parent, gr, 0, &r);
                        gtk_drawing_area_draw(gr->parent, &r);
                } else {
                        r.x=0;
@@ -494,6 +512,11 @@ draw_mode(struct graphics_priv *gr, enum draw_mode_num mode)
                        r.width=gr->width;
                        r.height=gr->height;
                        gtk_drawing_area_draw(gr, &r);
+                       overlay=gr->overlays;
+                       while (overlay) {
+                               overlay->cleanup=0;
+                               overlay=overlay->next;
+                       }
                }
        }
        gr->mode=mode;
index 7d0fd26..41722a2 100644 (file)
@@ -22,6 +22,7 @@
 #include "item.h"
 #include "attr.h"
 #include "layout.h"
+#include "coord.h"
 #include "debug.h"
 
 struct layout * layout_new(struct attr *parent, struct attr **attrs)
@@ -91,19 +92,40 @@ layer_add_attr(struct layer *layer, struct attr *attr)
 struct itemgra * itemgra_new(struct attr *parent, struct attr **attrs)
 {
        struct itemgra *itm;
-       struct attr *order, *item_types;
+       struct attr *order, *item_types, *speed_range, *angle_range, *sequence_range;
        enum item_type *type;
+       struct range defrange;
        
+       itm = g_new0(struct itemgra, 1);
        order=attr_search(attrs, NULL, attr_order);
        item_types=attr_search(attrs, NULL, attr_item_types);
-       if (! order || ! item_types)
-               return NULL;
-       itm = g_new0(struct itemgra, 1);
-       itm->order=order->u.order;
-       type=item_types->u.item_types;
-       while (type && *type != type_none) {
-               itm->type=g_list_append(itm->type, GINT_TO_POINTER(*type));
-               type++;
+       speed_range=attr_search(attrs, NULL, attr_speed_range);
+       angle_range=attr_search(attrs, NULL, attr_angle_range);
+       sequence_range=attr_search(attrs, NULL, attr_sequence_range);
+       defrange.min=0;
+       defrange.max=32767;
+       if (order) 
+               itm->order=order->u.range;
+       else 
+               itm->order=defrange;
+       if (speed_range) 
+               itm->speed_range=speed_range->u.range;
+       else 
+               itm->speed_range=defrange;
+       if (angle_range) 
+               itm->angle_range=angle_range->u.range;
+       else 
+               itm->angle_range=defrange;
+       if (sequence_range) 
+               itm->sequence_range=sequence_range->u.range;
+       else 
+               itm->sequence_range=defrange;
+       if (item_types) {
+               type=item_types->u.item_types;
+               while (type && *type != type_none) {
+                       itm->type=g_list_append(itm->type, GINT_TO_POINTER(*type));
+                       type++;
+               }
        }
        return itm;
 }
@@ -236,7 +258,7 @@ struct circle *
 circle_new(struct attr *parent, struct attr **attrs)
 {
        struct element *e;
-       
+
        e = g_new0(struct element, 1);
        e->type=element_circle;
        element_set_color(e, attrs);
@@ -271,11 +293,11 @@ icon_new(struct attr *parent, struct attr **attrs)
        e = g_malloc0(sizeof(*e)+strlen(src->u.str)+1);
        e->type=element_icon;
        e->u.icon.src=(char *)(e+1);
-       if (w=attr_search(attrs, NULL, attr_w))
+       if ((w=attr_search(attrs, NULL, attr_w)))
                e->u.icon.width=w->u.num;
        else
                e->u.icon.width=-1;
-       if (h=attr_search(attrs, NULL, attr_h))
+       if ((h=attr_search(attrs, NULL, attr_h)))
                e->u.icon.height=h->u.num;
        else
                e->u.icon.height=-1;
@@ -305,3 +327,15 @@ arrows_new(struct attr *parent, struct attr **attrs)
        return (struct arrows *)e;      
 }
 
+int
+element_add_attr(struct element *e, struct attr *attr)
+{
+       switch (attr->type) {
+       case attr_coord:
+               e->coord=g_realloc(e->coord,(e->coord_count+1)*sizeof(struct coord));
+               e->coord[e->coord_count++]=*attr->u.coord;
+               return 1;
+       default:
+               return 0;
+       }
+}
index 22963f7..ea2e885 100644 (file)
@@ -52,11 +52,13 @@ struct element {
                        int height;
                } icon;
        } u;
+       int coord_count;
+       struct coord *coord;
 };
 
 
 struct itemgra { 
-       struct order order;
+       struct range order,sequence_range,speed_range,angle_range;
        GList *type;
        GList *elements;
 };
@@ -86,5 +88,6 @@ struct text *text_new(struct attr *parent, struct attr **attrs);
 struct icon *icon_new(struct attr *parent, struct attr **attrs);
 struct image *image_new(struct attr *parent, struct attr **attrs);
 struct arrows *arrows_new(struct attr *parent, struct attr **attrs);
+int element_add_attr(struct element *e, struct attr *attr);
 #endif
 
index 5c50074..36681c1 100644 (file)
@@ -178,13 +178,13 @@ navit_draw(struct navit *this_)
                return;
        }
        transform_setup_source_rect(this_->trans);
-       graphics_draw(this_->gra, this_->displaylist, this_->mapsets, this_->trans, this_->layout_current);
        l=this_->vehicles;
        while (l) {
                nv=l->data;
                navit_vehicle_draw(this_, nv, NULL);
                l=g_list_next(l);
        }
+       graphics_draw(this_->gra, this_->displaylist, this_->mapsets, this_->trans, this_->layout_current);
 }
 
 void
@@ -1228,7 +1228,6 @@ 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->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);
@@ -1595,10 +1594,24 @@ navit_remove_callback(struct navit *this_, struct callback *cb)
 static void
 navit_vehicle_draw(struct navit *this_, struct navit_vehicle *nv, struct point *pnt)
 {
-       struct point pnt2;
+       struct point cursor_pnt;
        enum projection pro;
+       struct attr cursor;
+
        if (this_->blocked)
                return;
+       if (! vehicle_get_attr(nv->vehicle, attr_cursor, &cursor, NULL))
+               return;
+       if (! cursor.u.cursor)
+               return;
+       if (pnt)
+               cursor_pnt=*pnt;
+       else {
+               pro=transform_get_projection(this_->trans);
+               transform(this_->trans, pro, &nv->coord, &cursor_pnt, 1, 0);
+       }
+       cursor_draw(cursor.u.cursor, this_->gra, &cursor_pnt, pnt ? 0:1, transform_get_angle(this_->trans, 0)-nv->dir, nv->speed);
+#if 0  
        if (pnt)
                pnt2=*pnt;
        else {
@@ -1610,6 +1623,7 @@ navit_vehicle_draw(struct navit *this_, struct navit_vehicle *nv, struct point *
 #else
        cursor_draw(nv->cursor, &pnt2, nv->dir-transform_get_angle(this_->trans, 0), nv->speed > 2, 1);
 #endif
+#endif
 }
 
 static void
index e8e7534..9f30b0c 100644 (file)
@@ -62,17 +62,55 @@ http://wiki.navit-project.org/index.php/Configuring_NavIt
                        <!--Navit can write a tracklog in several formats (gpx, nmea or textfile):
                        <log type="gpx" data="track_%Y%m%d-%i.gpx" flush_size="1000" flush_time="30" />
                        -->
+                      <cursor w="26" h="26">
+                               <itemgra>
+                                       <circle color="#0000ff" radius="24" width="2">
+                                               <coord x="0" y="0" />
+                                       </circle>
+                               </itemgra>
+                               <itemgra speed_range="-2">
+                                       <polyline color="#0000ff" width="2" >
+                                               <coord x="0" y="0" />
+                                               <coord x="0" y="0" />
+                                       </polyline>
+                               </itemgra>
+                               <itemgra speed_range="3-">
+                                       <polyline color="#0000ff" width="2" >
+                                               <coord x="-7" y="-10" />
+                                               <coord x="0" y="12" />
+                                               <coord x="7" y="-10" />
+                                       </polyline>
+                               </itemgra>
+                       </cursor>
                </vehicle>
 
-               <!-- 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"/>
                -->
 
-               <vehicle name="Demo" enabled="no" source="demo://" color="#0000aa"/>
-
+               <vehicle name="Demo" enabled="no" source="demo://"/>
+                      <cursor w="26" h="26">
+                               <itemgra>
+                                       <circle color="#0000ff" radius="24" width="2">
+                                               <coord x="0" y="0" />
+                                       </circle>
+                               </itemgra>
+                               <itemgra speed_range="-2">
+                                       <polyline color="#0000ff" width="2" >
+                                               <coord x="0" y="0" />
+                                               <coord x="0" y="0" />
+                                       </polyline>
+                               </itemgra>
+                               <itemgra speed_range="3-">
+                                       <polyline color="#0000ff" width="2" >
+                                               <coord x="-7" y="-10" />
+                                               <coord x="0" y="12" />
+                                               <coord x="7" y="-10" />
+                                       </polyline>
+                               </itemgra>
+                       </cursor>
+               </vehicle>
                <tracking>
                </tracking>
                
index 1cd703f..01317bc 100644 (file)
@@ -21,7 +21,7 @@
 #define NAVIT_PROJECTION_H
 
 enum projection {
-       projection_none, projection_mg, projection_garmin
+       projection_none, projection_mg, projection_garmin, projection_screen,
 };
 
 enum map_datum {
index 720434e..1e3ad99 100644 (file)
@@ -318,6 +318,12 @@ transform_set_screen_selection(struct transformation *t, struct map_selection *s
        }
 }
 
+void
+transform_set_screen_center(struct transformation *t, struct point *p)
+{
+       t->screen_center=*p;
+}
+
 #if 0
 void
 transform_set_size(struct transformation *t, int width, int height)
@@ -841,6 +847,12 @@ transform_within_dist_item(struct coord *ref, enum item_type type, struct coord
        return transform_within_dist_polygon(ref, c, count, dist);
 }
 
+void
+transform_destroy(struct transformation *t)
+{
+       g_free(t);
+}
+
 
 /*
 Note: there are many mathematically equivalent ways to express these formulas. As usual, not all of them are computationally equivalent.
index bcd9ae9..3faeafe 100644 (file)
@@ -187,16 +187,20 @@ vehicle_set_attr(struct vehicle *this_, struct attr *attr,
 int
 vehicle_add_attr(struct vehicle *this_, struct attr *attr)
 {
+       int ret=1;
        switch (attr->type) {
        case attr_callback:
                callback_list_add(this_->cbl, attr->u.callback);
                break;
        case attr_log:
-               return vehicle_add_log(this_, attr->u.log);
+               ret=vehicle_add_log(this_, attr->u.log);
+               break;
        default:
-               return 0;
+               break;
        }
-       return 1;
+       if (ret)
+               this_->attrs=attr_generic_add_attr(this_->attrs, attr);
+       return ret;
 }
 
 int
index f153a08..2dae988 100644 (file)
@@ -39,6 +39,7 @@
 #include "gui.h"
 #include "osd.h"
 #include "log.h"
+#include "cursor.h"
 #include "xmlconfig.h"
 #include "config.h"
 
@@ -298,14 +299,19 @@ struct element_func {
        { "layout", "navit", NULL, NEW(layout_new), ADD(layout_add_attr)},
        { "layer", "layout", NULL, NEW(layer_new), ADD(layer_add_attr)},
        { "itemgra", "layer", NULL, NEW(itemgra_new), ADD(itemgra_add_attr)},
-       { "circle", "itemgra", NULL, NEW(circle_new)},
+       { "circle", "itemgra", NULL, NEW(circle_new), ADD(element_add_attr)},
+       { "coord", "circle", NULL, NEW(coord_new_from_attrs)},
        { "icon", "itemgra", NULL, NEW(icon_new)},
        { "image", "itemgra", NULL, NEW(image_new)},
        { "text", "itemgra", NULL, NEW(text_new)},
-       { "polygon", "itemgra", NULL, NEW(polygon_new)},
-       { "polyline", "itemgra", NULL, NEW(polyline_new)},
+       { "polygon", "itemgra", NULL, NEW(polygon_new), ADD(element_add_attr)},
+       { "coord", "polygon", NULL, NEW(coord_new_from_attrs)},
+       { "polyline", "itemgra", NULL, NEW(polyline_new), ADD(element_add_attr)},
+       { "coord", "polyline", NULL, NEW(coord_new_from_attrs)},
        { "arrows", "itemgra", NULL, NEW(arrows_new)},
        { "vehicle", "navit", NULL, NEW(vehicle_new), ADD(vehicle_add_attr) },
+       { "cursor", "vehicle", NULL, NEW(cursor_new), ADD(cursor_add_attr)},
+       { "itemgra", "cursor", NULL, NEW(itemgra_new), ADD(itemgra_add_attr)},
        { "log", "vehicle", NULL, NEW(log_new)},
        { "log", "navit", NULL, NEW(log_new)},
        { "window_items", "navit", xmlconfig_window_items},