summaryrefslogtreecommitdiff
path: root/navit/vehicle.c
diff options
context:
space:
mode:
authorseralph <seralph@ffa7fe5e-494d-0410-b361-a75ebd5db220>2009-10-14 12:05:48 +0000
committerseralph <seralph@ffa7fe5e-494d-0410-b361-a75ebd5db220>2009-10-14 12:05:48 +0000
commitd5310034de132ebbc37e97969266e9732858a8dd (patch)
treef90804e754f65f2d06cebe78302339123dd3161d /navit/vehicle.c
parent3dee96744c8684f9159bc0037c7861d686db75bd (diff)
downloadnavit-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.c465
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, &center, 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_);
-}