diff options
author | seralph <seralph@ffa7fe5e-494d-0410-b361-a75ebd5db220> | 2009-10-14 12:05:48 +0000 |
---|---|---|
committer | seralph <seralph@ffa7fe5e-494d-0410-b361-a75ebd5db220> | 2009-10-14 12:05:48 +0000 |
commit | d5310034de132ebbc37e97969266e9732858a8dd (patch) | |
tree | f90804e754f65f2d06cebe78302339123dd3161d /navit/vehicle.c | |
parent | 3dee96744c8684f9159bc0037c7861d686db75bd (diff) | |
download | navit-d5310034de132ebbc37e97969266e9732858a8dd.tar.gz |
Add:Core:Add the possibility to define cursors in layout
git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit@2667 ffa7fe5e-494d-0410-b361-a75ebd5db220
Diffstat (limited to 'navit/vehicle.c')
-rw-r--r-- | navit/vehicle.c | 465 |
1 files changed, 339 insertions, 126 deletions
diff --git a/navit/vehicle.c b/navit/vehicle.c index 1fae77579..fe8c282db 100644 --- a/navit/vehicle.c +++ b/navit/vehicle.c @@ -1,6 +1,6 @@ /** * Navit, a modular navigation system. - * Copyright (C) 2005-2008 Navit Team + * Copyright (C) 2005-2009 Navit Team * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -26,20 +26,355 @@ #include "coord.h" #include "item.h" #include "log.h" -#include "callback.h" #include "plugin.h" -#include "vehicle.h" #include "transform.h" #include "util.h" +#include "event.h" +#include "coord.h" +#include "transform.h" +#include "projection.h" +#include "point.h" +#include "graphics.h" +#include "callback.h" +#include "color.h" +#include "layout.h" +#include "vehicle.h" struct vehicle { - struct vehicle_priv *priv; struct vehicle_methods meth; + struct vehicle_priv *priv; struct callback_list *cbl; struct log *nmea_log, *gpx_log; struct attr **attrs; + + // cursor + struct cursor *cursor; + struct callback *animate_callback; + struct event_timeout *animate_timer; + struct point cursor_pnt; + struct graphics *gra; + struct graphics_gc *bg; + struct transformation *trans; + int angle; + int speed; + int sequence; }; +static void vehicle_draw_do(struct vehicle *this_, int lazy); +static void vehicle_log_nmea(struct vehicle *this_, struct log *log); +static void vehicle_log_gpx(struct vehicle *this_, struct log *log); +static void vehicle_log_textfile(struct vehicle *this_, struct log *log); +static void vehicle_log_binfile(struct vehicle *this_, struct log *log); +static int vehicle_add_log(struct vehicle *this_, struct log *log); + + + +/** + * Creates a new vehicle + */ +struct vehicle * +vehicle_new(struct attr *parent, struct attr **attrs) +{ + struct vehicle *this_; + struct attr *source; + struct vehicle_priv *(*vehicletype_new) (struct vehicle_methods * + meth, + struct callback_list * + cbl, + struct attr ** attrs); + char *type, *colon; + struct pcoord center; + + dbg(1, "enter\n"); + source = attr_search(attrs, NULL, attr_source); + if (!source) { + dbg(0, "no source\n"); + return NULL; + } + + type = g_strdup(source->u.str); + colon = strchr(type, ':'); + if (colon) + *colon = '\0'; + dbg(1, "source='%s' type='%s'\n", source->u.str, type); + + vehicletype_new = plugin_get_vehicle_type(type); + if (!vehicletype_new) { + dbg(0, "invalid type '%s'\n", type); + return NULL; + } + this_ = g_new0(struct vehicle, 1); + this_->cbl = callback_list_new(); + this_->priv = vehicletype_new(&this_->meth, this_->cbl, attrs); + if (!this_->priv) { + dbg(0, "vehicletype_new failed\n"); + callback_list_destroy(this_->cbl); + g_free(this_); + return NULL; + } + this_->attrs=attr_list_dup(attrs); + + this_->trans=transform_new(); + center.pro=projection_screen; + center.x=0; + center.y=0; + transform_setup(this_->trans, ¢er, 16, 0); + + dbg(1, "leave\n"); + return this_; +} + +/** + * Destroys a vehicle + * + * @param this_ The vehicle to destroy + */ +void +vehicle_destroy(struct vehicle *this_) +{ + if (this_->animate_callback) { + callback_destroy(this_->animate_callback); + event_remove_timeout(this_->animate_timer); + } + transform_destroy(this_->trans); + this_->meth.destroy(this_->priv); + callback_list_destroy(this_->cbl); + attr_list_free(this_->attrs); + g_free(this_); +} + +/** + * Creates an attribute iterator to be used with vehicles + */ +struct attr_iter * +vehicle_attr_iter_new(void) +{ + return (struct attr_iter *)g_new0(void *,1); +} + +/** + * Destroys a vehicle attribute iterator + * + * @param iter a vehicle attr_iter + */ +void +vehicle_attr_iter_destroy(struct attr_iter *iter) +{ + g_free(iter); +} + + + +/** + * Generic get function + * + * @param this_ A vehicle + * @param type The attribute type to look for + * @param attr A struct attr to store the attribute + * @param iter A vehicle attr_iter + */ +int +vehicle_get_attr(struct vehicle *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter) +{ + int ret; + if (this_->meth.position_attr_get) { + ret=this_->meth.position_attr_get(this_->priv, type, attr); + if (ret) + return ret; + } + return attr_generic_get_attr(this_->attrs, NULL, type, attr, iter); +} + +/** + * Generic set function + * + * @param this_ A vehicle + * @param attr + * @param attrs + */ +int +vehicle_set_attr(struct vehicle *this_, struct attr *attr, + struct attr **attrs) +{ + int ret=1; + if (this_->meth.set_attr) + ret=this_->meth.set_attr(this_->priv, attr, attrs); + if (ret == 1 && attr->type != attr_navit) + this_->attrs=attr_generic_set_attr(this_->attrs, attr); + return ret != 0; +} + +/** + * Generic add function + * + * @param this_ A vehicle + * @param attr A struct 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: + ret=vehicle_add_log(this_, attr->u.log); + break; + // currently supporting oldstyle cursor config. + case attr_cursor: + vehicle_set_cursor(this_, attr->u.cursor); + break; + default: + break; + } + if (ret) + this_->attrs=attr_generic_add_attr(this_->attrs, attr); + return ret; +} + +/** + * @brief Generic remove function. + * + * Used to remove a callback from the vehicle. + * @param this_ A vehicle + * @param attr + */ +int +vehicle_remove_attr(struct vehicle *this_, struct attr *attr) +{ + switch (attr->type) { + case attr_callback: + callback_list_remove(this_->cbl, attr->u.callback); + break; + default: + return 0; + } + return 1; +} + + + +/** + * Sets the cursor of a vehicle. + * + * @param this_ A vehicle + * @param cursor A cursor + * @author Ralph Sennhauser (10/2009) + */ +void +vehicle_set_cursor(struct vehicle *this_, struct cursor *cursor) +{ + if (!cursor) { // we require this for now. + return; + } + + if (this_->animate_callback) { + event_remove_timeout(this_->animate_timer); + this_->animate_timer=NULL; // dangling pointer! prevent double freeing. + callback_destroy(this_->animate_callback); + this_->animate_callback=NULL; // dangling pointer! prevent double freeing. + } + if (cursor->interval) { + this_->animate_callback=callback_new_2(callback_cast(vehicle_draw_do), this_, 0); + this_->animate_timer=event_add_timeout(cursor->interval, 1, this_->animate_callback); + } + + if (this_->gra) { + this_->cursor_pnt.x+=(this_->cursor->w - cursor->w)/2; + this_->cursor_pnt.y+=(this_->cursor->h - cursor->h)/2; + graphics_overlay_resize(this_->gra, &this_->cursor_pnt, cursor->w, cursor->h, 65535, 0); + } + + struct point sc; + sc.x=cursor->w/2; + sc.y=cursor->h/2; + transform_set_screen_center(this_->trans, &sc); + + this_->cursor=cursor; +} + +/** + * Draws a vehicle on top of a graphics. + * + * @param this_ The vehicle + * @param gra The graphics + * @param pnt Screen coordinates of the vehicle. + * @param lazy use lazy draw mode. + * @param angle The angle relative to the map. + * @param speed The speed of the vehicle. + */ +void +vehicle_draw(struct vehicle *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_->cursor->w/2; + this_->cursor_pnt.y-=this_->cursor->h/2; + this_->angle=angle; + this_->speed=speed; + if (!this_->gra) { + struct color c; + this_->gra=graphics_overlay_new(gra, &this_->cursor_pnt, this_->cursor->w, this_->cursor->h, 65535, 0); + if (this_->gra) { + 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); + } + } + vehicle_draw_do(this_, lazy); +} + + + +static void +vehicle_draw_do(struct vehicle *this_, int lazy) +{ + if (!this_->cursor || !this_->cursor->attrs || !this_->gra) + return; + + struct point p; + struct cursor *cursor=this_->cursor; + int speed=this_->speed; + int angle=this_->angle; + int sequence=this_->sequence; + + transform_set_yaw(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, cursor->w, cursor->h); + struct attr **attr=cursor->attrs; + 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); + } + if (sequence < itm->sequence_range.max) + match=1; + } + ++attr; + } + graphics_draw_drag(this_->gra, &this_->cursor_pnt); + graphics_draw_mode(this_->gra, lazy ? draw_mode_end_lazy : draw_mode_end); + if (this_->animate_callback) { + ++this_->sequence; + if (cursor->sequence_range && cursor->sequence_range->max < this_->sequence) + this_->sequence=cursor->sequence_range->min; + if (! match && ! cursor->sequence_range) + this_->sequence=0; + } +} + static void vehicle_log_nmea(struct vehicle *this_, struct log *log) { @@ -197,125 +532,3 @@ vehicle_add_log(struct vehicle *this_, struct log *log) return 0; } -struct vehicle * -vehicle_new(struct attr *parent, struct attr **attrs) -{ - struct vehicle *this_; - struct attr *source; - struct vehicle_priv *(*vehicletype_new) (struct vehicle_methods * - meth, - struct callback_list * - cbl, - struct attr ** attrs); - char *type, *colon; - - dbg(1, "enter\n"); - source = attr_search(attrs, NULL, attr_source); - if (!source) { - dbg(0, "no source\n"); - return NULL; - } - - type = g_strdup(source->u.str); - colon = strchr(type, ':'); - if (colon) - *colon = '\0'; - dbg(1, "source='%s' type='%s'\n", source->u.str, type); - - vehicletype_new = plugin_get_vehicle_type(type); - if (!vehicletype_new) { - dbg(0, "invalid type '%s'\n", type); - return NULL; - } - this_ = g_new0(struct vehicle, 1); - this_->cbl = callback_list_new(); - this_->priv = vehicletype_new(&this_->meth, this_->cbl, attrs); - if (!this_->priv) { - dbg(0, "vehicletype_new failed\n"); - callback_list_destroy(this_->cbl); - g_free(this_); - return NULL; - } - this_->attrs=attr_list_dup(attrs); - dbg(1, "leave\n"); - - return this_; -} - -struct attr_iter * -vehicle_attr_iter_new(void) -{ - return (struct attr_iter *)g_new0(void *,1); -} - -void -vehicle_attr_iter_destroy(struct attr_iter *iter) -{ - g_free(iter); -} - - -int -vehicle_get_attr(struct vehicle *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter) -{ - int ret; - if (this_->meth.position_attr_get) { - ret=this_->meth.position_attr_get(this_->priv, type, attr); - if (ret) - return ret; - } - return attr_generic_get_attr(this_->attrs, NULL, type, attr, iter); -} - -int -vehicle_set_attr(struct vehicle *this_, struct attr *attr, - struct attr **attrs) -{ - int ret=1; - if (this_->meth.set_attr) - ret=this_->meth.set_attr(this_->priv, attr, attrs); - if (ret == 1 && attr->type != attr_navit) - this_->attrs=attr_generic_set_attr(this_->attrs, attr); - return ret != 0; -} - -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: - ret=vehicle_add_log(this_, attr->u.log); - break; - default: - break; - } - if (ret) - this_->attrs=attr_generic_add_attr(this_->attrs, attr); - return ret; -} - -int -vehicle_remove_attr(struct vehicle *this_, struct attr *attr) -{ - switch (attr->type) { - case attr_callback: - callback_list_remove(this_->cbl, attr->u.callback); - break; - default: - return 0; - } - return 1; -} - -void -vehicle_destroy(struct vehicle *this_) -{ - this_->meth.destroy(this_->priv); - callback_list_destroy(this_->cbl); - attr_list_free(this_->attrs); - g_free(this_); -} |