ATTR(menubar)
ATTR(statusbar)
ATTR(toolbar)
+ATTR(animate)
ATTR2(0x0002ffff,type_int_end)
ATTR2(0x00030000,type_string_begin)
ATTR(type)
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)
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;
};
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;
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);
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;
}
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_);
}
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 */
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)
{
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);
};
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);
}
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
}
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
}
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 {
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);
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);
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;
}
-->
<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"/>
-->