}
if (attr >= attr_type_int_begin && attr <= attr_type_int_end) {
ret->u.num=atoi(value);
- if (attr >= attr_type_boolean_begin) { // also check for yes and no
+
+ if ((attr >= attr_type_rel_abs_begin) && (attr < attr_type_boolean_begin)) {
+ /* Absolute values are from -0x40000000 - 0x40000000, with 0x0 being 0 (who would have thought that?)
+ Relative values are from 0x40000001 - 0x80000000, with 0x60000000 being 0 */
+ if (strchr(value, '%')) {
+ if ((ret->u.num > 0x20000000) || (ret->u.num < -0x1FFFFFFF)) {
+ dbg(0, "Relative possibly-relative attribute with invalid value %i\n", ret->u.num);
+ }
+
+ ret->u.num += 0x60000000;
+ } else {
+ if ((ret->u.num > 0x40000000) || (ret->u.num < -0x40000000)) {
+ dbg(0, "Non-relative possibly-relative attribute with invalid value %i\n", ret->u.num);
+ }
+ }
+ } else if (attr >= attr_type_boolean_begin) { // also check for yes and no
if (g_ascii_strcasecmp(value,"no") && g_ascii_strcasecmp(value,"0") && g_ascii_strcasecmp(value,"false"))
ret->u.num=1;
else
#define AF_BIKE (1<<30)
#define AF_PEDESTRIAN (1<<31)
+/* Values for attributes that could carry relative values */
+#define ATTR_REL_MAXABS 0x40000000
+#define ATTR_REL_RELSHIFT 0x60000000
+
struct attr {
enum attr_type type;
union {
ATTR2(0x0001ffff,type_item_end)
ATTR2(0x00020000,type_int_begin)
-ATTR(h)
+ATTR(h_remove)
ATTR(id)
ATTR(flags)
-ATTR(w)
-ATTR(x)
-ATTR(y)
+ATTR(w_remove)
+ATTR(x_remove)
+ATTR(y_remove)
ATTR(flush_size)
ATTR(flush_time)
ATTR(zipfile_ref)
ATTR(antialias)
ATTR(order_delta)
ATTR(baudrate)
-ATTR(font_size)
+ATTR(font_size_remove)
ATTR(icon_xs)
ATTR(icon_l)
ATTR(icon_s)
ATTR(roll)
ATTR(yaw)
ATTR(route_status)
+
+ATTR2(0x00027500,type_rel_abs_begin)
+/* These attributes are int that can either hold relative *
+ * or absolute values. A relative value is indicated by *
+ * adding 0x60000000. *
+ * *
+ * The range of valid absolute values is -0x40000000 to *
+ * 0x40000000, the range of relative values is from *
+ * -0x20000000 to 0x20000000. */
+ATTR(h)
+ATTR(w)
+ATTR(x)
+ATTR(y)
+ATTR(font_size)
+
ATTR2(0x00028000,type_boolean_begin)
/* boolean */
ATTR(overwrite)
int win_h;
int visible;
int overlay_disabled;
+ int overlay_autodisabled;
int a;
int wraparound;
struct graphics_priv *parent;
GdkRectangle or,ir;
struct graphics_gc_priv *bg=overlay->background_gc;
- if (parent->overlay_disabled || overlay->overlay_disabled)
+ if (parent->overlay_disabled || overlay->overlay_disabled || overlay->overlay_autodisabled)
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, 0, &or);
overlay_resize(struct graphics_priv *this, struct point *p, int w, int h, int alpha, int wraparound)
{
int changed = 0;
+ int w2,h2;
+
+ if (w == 0) {
+ w2 = 1;
+ } else {
+ w2 = w;
+ }
+
+ if (h == 0) {
+ h2 = 1;
+ } else {
+ h2 = h;
+ }
this->p = *p;
- if (this->width != w) {
- this->width = w;
+ if (this->width != w2) {
+ this->width = w2;
changed = 1;
}
- if (this->height != h) {
- this->height = h;
+ if (this->height != h2) {
+ this->height = h2;
changed = 1;
}
g_object_unref(this->drawable);
g_object_unref(this->background);
- this->drawable=gdk_pixmap_new(this->parent->widget->window, w, h, -1);
- this->background=gdk_pixmap_new(this->parent->widget->window, w, h, -1);
+ this->drawable=gdk_pixmap_new(this->parent->widget->window, w2, h2, -1);
+ this->background=gdk_pixmap_new(this->parent->widget->window, w2, h2, -1);
+
+ if ((w == 0) || (h == 0)) {
+ this->overlay_autodisabled = 1;
+ } else {
+ this->overlay_autodisabled = 0;
+ }
callback_list_call_attr_2(this->cbl, attr_resize, (void *)this->width, (void *)this->height);
}
static struct graphics_priv *
overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int alpha, int wraparound)
{
+ int w2,h2;
struct graphics_priv *this=graphics_gtk_drawing_area_new_helper(meth);
- this->drawable=gdk_pixmap_new(gr->widget->window, w, h, -1);
this->colormap=gr->colormap;
this->widget=gr->widget;
this->p=*p;
this->width=w;
this->height=h;
this->parent=gr;
- this->background=gdk_pixmap_new(gr->widget->window, w, h, -1);
+
+ /* If either height or width is 0, we set it to 1 to avoid warnings, and
+ * disable the overlay. */
+ if (h == 0) {
+ h2 = 1;
+ } else {
+ h2 = h;
+ }
+
+ if (w == 0) {
+ w2 = 1;
+ } else {
+ w2 = w;
+ }
+
+ this->background=gdk_pixmap_new(gr->widget->window, w2, h2, -1);
+ this->drawable=gdk_pixmap_new(gr->widget->window, w2, h2, -1);
+
+ if ((w == 0) || (h == 0)) {
+ this->overlay_autodisabled = 1;
+ } else {
+ this->overlay_autodisabled = 0;
+ }
+
this->next=gr->overlays;
this->a=alpha >> 8;
this->wraparound=wraparound;
struct osd *
osd_new(struct attr *parent, struct attr **attrs)
{
- struct osd *o;
- struct osd_priv *(*new)(struct navit *nav, struct osd_methods *meth, struct attr **attrs);
+ struct osd *o;
+ struct osd_priv *(*new)(struct navit *nav, struct osd_methods *meth, struct attr **attrs);
struct attr *type=attr_search(attrs, NULL, attr_type);
if (! type)
}
void
+osd_std_resize(struct osd_item *item)
+{
+ graphics_overlay_resize(item->gr, &item->p, item->w, item->h, 65535, 1);
+}
+
+void
+osd_std_calculate_sizes(struct osd_item *item, struct osd_priv *priv, int w, int h)
+{
+ struct attr vehicle_attr;
+
+ if (item->rel_w) {
+ item->w = (item->rel_w * w) / 100;
+ }
+
+ if (item->rel_h) {
+ item->h = (item->rel_h * h) / 100;
+ }
+
+ if (item->rel_x) {
+ item->p.x = (item->rel_x * w) / 100;
+ }
+
+ if (item->rel_y) {
+ item->p.y = (item->rel_y * h) / 100;
+ }
+
+ osd_std_resize(item);
+ if (item->meth.draw) {
+ if (navit_get_attr(item->navit, attr_vehicle, &vehicle_attr, NULL)) {
+ item->meth.draw(priv, item->navit, vehicle_attr.u.vehicle);
+ }
+ }
+}
+
+void
osd_set_std_attr(struct attr **attrs, struct osd_item *item, int flags)
{
struct attr *attr;
item->osd_configuration = attr->u.num;
attr = attr_search(attrs, NULL, attr_w);
- if (attr)
- item->w = attr->u.num;
+ if (attr) {
+ if (attr->u.num > ATTR_REL_MAXABS) {
+ item->rel_w = attr->u.num - ATTR_REL_RELSHIFT;
+ } else {
+ item->rel_w = 0;
+ item->w = attr->u.num;
+ }
+ }
attr = attr_search(attrs, NULL, attr_h);
- if (attr)
- item->h = attr->u.num;
+ if (attr) {
+ if (attr->u.num > ATTR_REL_MAXABS) {
+ item->rel_h = attr->u.num - ATTR_REL_RELSHIFT;
+ } else {
+ item->rel_h = 0;
+ item->h = attr->u.num;
+ }
+ }
attr = attr_search(attrs, NULL, attr_x);
- if (attr)
- item->p.x = attr->u.num;
+ if (attr) {
+ if (attr->u.num > ATTR_REL_MAXABS) {
+ item->rel_x = attr->u.num - ATTR_REL_RELSHIFT;
+ } else {
+ item->rel_x = 0;
+ item->p.x = attr->u.num;
+ }
+ }
attr = attr_search(attrs, NULL, attr_y);
- if (attr)
- item->p.y = attr->u.num;
+ if (attr) {
+ if (attr->u.num > ATTR_REL_MAXABS) {
+ item->rel_y = attr->u.num - ATTR_REL_RELSHIFT;
+ } else {
+ item->rel_y = 0;
+ item->p.y = attr->u.num;
+ }
+ }
attr = attr_search(attrs, NULL, attr_font_size);
if (attr)
item->font_size = attr->u.num;
-
+
attr=attr_search(attrs, NULL, attr_background_color);
if (attr)
item->color_bg=*attr->u.color;
attr = attr_search(attrs, NULL, attr_command);
if (attr)
item->command = g_strdup(attr->u.str);
- attr=attr_search(attrs, NULL, attr_text_color);
- if (attr)
- item->text_color=*attr->u.color;
- attr=attr_search(attrs, NULL, attr_flags);
- if (attr)
- item->attr_flags=attr->u.num;
-
+ attr=attr_search(attrs, NULL, attr_text_color);
+ if (attr)
+ item->text_color=*attr->u.color;
+ attr=attr_search(attrs, NULL, attr_flags);
+ if (attr)
+ item->attr_flags=attr->u.num;
}
void
}
void
-osd_set_std_graphic(struct navit *nav, struct osd_item *item)
+osd_set_std_graphic(struct navit *nav, struct osd_item *item, struct osd_priv *priv)
{
struct graphics *navit_gr;
item->cb = callback_new_attr_2(callback_cast(osd_std_config), attr_osd_configuration, item, nav);
navit_add_callback(nav, item->cb);
- osd_std_config(item, nav);
-}
-void
-osd_std_resize(struct osd_item *item)
-{
- graphics_overlay_resize(item->gr, &item->p, item->w, item->h, 65535, 1);
+ item->resize_cb = callback_new_attr_2(callback_cast(osd_std_calculate_sizes), attr_resize, item, priv);
+ graphics_add_callback(navit_gr, item->resize_cb);
+
+ osd_std_config(item, nav);
}
void
{
struct point p[2];
int flags=item->attr_flags;
+
graphics_draw_mode(item->gr, draw_mode_begin);
p[0].x=0;
p[0].y=0;
struct osd_priv;
struct osd_methods {
- void (*osd_destroy)(struct osd_priv *osd);
+ void (*osd_destroy)(struct osd_priv *osd);
};
+struct osd_item_methods {
+ void (*draw)(struct osd_priv *osd, struct navit *navit, struct vehicle *v);
+};
struct osd_item {
struct point p;
+ struct osd_item_methods meth;
int flags, attr_flags, w, h, fg_line_width, font_size, osd_configuration, configured;
+ int rel_w, rel_h, rel_x, rel_y;
struct color color_bg, color_white, text_color;
+ struct navit *navit;
struct graphics *gr;
struct graphics_gc *graphic_bg, *graphic_fg_white, *graphic_fg_text;
struct graphics_font *font;
struct callback *cb;
+ struct callback *resize_cb;
int pressed;
char *command;
};
void osd_std_click(struct osd_item *this, struct navit *nav, int pressed, int button, struct point *p);
void osd_set_std_attr(struct attr **attrs, struct osd_item *item, int flags);
void osd_std_config(struct osd_item *item, struct navit *navit);
-void osd_set_std_graphic(struct navit *nav, struct osd_item *item);
+void osd_set_std_graphic(struct navit *nav, struct osd_item *item, struct osd_priv *priv);
void osd_std_resize(struct osd_item *item);
void osd_std_draw(struct osd_item *item);
/* end of prototypes */
{
struct color c;
- osd_set_std_graphic(nav, &this->osd_item);
+ osd_set_std_graphic(nav, &this->osd_item, (struct osd_priv *)this);
this->green = graphics_gc_new(this->osd_item.gr);
c.r = 0;
this->osd_item.p.y = 20;
this->osd_item.w = 60;
this->osd_item.h = 80;
+ this->osd_item.navit = nav;
this->osd_item.font_size = 200;
+ this->osd_item.meth.draw = &osd_compass_draw;
osd_set_std_attr(attrs, &this->osd_item, 2);
navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_compass_init), attr_navit, this));
return (struct osd_priv *) this;
if (this->use_overlay) {
struct graphics_image *img;
struct point p;
- osd_set_std_graphic(nav, &this->item);
+ osd_set_std_graphic(nav, &this->item, (struct osd_priv *)this);
img=graphics_image_new(this->item.gr, this->src);
p.x=(this->item.w-this->img->width)/2;
p.y=(this->item.h-this->img->height)/2;
struct osd_button *this = g_new0(struct osd_button, 1);
struct attr *attr;
+ this->item.navit = nav;
+ this->item.meth.draw = &osd_button_draw;
+
osd_set_std_attr(attrs, &this->item, 1);
attr=attr_search(attrs, NULL, attr_use_overlay);
static void
osd_nav_next_turn_init(struct nav_next_turn *this, struct navit *nav)
{
- osd_set_std_graphic(nav, &this->osd_item);
+ osd_set_std_graphic(nav, &this->osd_item, (struct osd_priv *)this);
navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_nav_next_turn_draw), attr_position_coord_geo, this));
osd_nav_next_turn_draw(this, nav, NULL);
}
this->osd_item.p.x = 20;
this->osd_item.p.y = -80;
this->osd_item.w = 70;
+ this->osd_item.navit = nav;
this->osd_item.h = 70;
this->osd_item.font_size = 200;
+ this->osd_item.meth.draw = &osd_nav_next_turn_draw;
osd_set_std_attr(attrs, &this->osd_item, 0);
this->icon_w = -1;
static void
osd_nav_toggle_announcer_init(struct nav_toggle_announcer *this, struct navit *nav)
{
- osd_set_std_graphic(nav, &this->item);
+ osd_set_std_graphic(nav, &this->item, (struct osd_priv *)this);
navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_nav_toggle_announcer_draw), attr_speech, this));
navit_add_callback(nav, this->navit_init_cb = callback_new_attr_1(callback_cast(osd_std_click), attr_button, &this->item));
osd_nav_toggle_announcer_draw(this, nav, NULL);
this->item.w = 48;
this->item.h = 48;
- this->item.p.x = -64;
- this->item.p.y = 76;
+ this->item.p.x = -64;
+ this->item.navit = nav;
+ this->item.p.y = 76;
+ this->item.meth.draw = &osd_nav_toggle_announcer_draw;
osd_set_std_attr(attrs, &this->item, 0);
static void
osd_speed_warner_init(struct osd_speed_warner *this, struct navit *nav)
{
- osd_set_std_graphic(nav, &this->item);
+ osd_set_std_graphic(nav, &this->item, (struct osd_priv *)this);
navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_speed_warner_draw), attr_position_coord_geo, this));
this->red=graphics_gc_new(this->item.gr);
graphics_gc_set_foreground(this->red, &(struct color ){0xffff,0,0,0xffff});
this->item.p.x=-80;
this->item.p.y=20;
this->item.w=60;
+ this->item.navit = nav;
this->item.h=60;
this->active=-1;
+ this->item.meth.draw = &osd_speed_warner_draw;
osd_set_std_attr(attrs, &this->item, 2);
this->d=this->item.w;
if (this->item.h < this->d)
osd_text_draw(struct osd_text *this, struct navit *navit, struct vehicle *v)
{
struct point p, p2[4];
- char *str,*next,*start,*end,*key,*subkey,*index,*value;
+ char *str,*next,*last,*start,*end,*key,*subkey,*index,*value;
int do_draw = 0;
struct attr attr, vehicle_attr, maxspeed_attr;
struct navigation *nav = NULL;
g_free(str);
str=next;
}
- lines=1;
+ lines=0;
next=str;
+ last=str;
while ((next=strstr(next, "\\n"))) {
+ last = next;
lines++;
next++;
}
+
+ while (*last) {
+ if (! g_ascii_isspace(*last)) {
+ lines++;
+ break;
+ }
+ last++;
+ }
+
dbg(1,"this->align=%d\n", this->align);
switch (this->align & 51) {
case 1:
break;
case 16: // Grow from top to bottom
p.y = 0;
- this->osd_item.h = lines * (height+yspacing);
+ if (lines != 0) {
+ this->osd_item.h = (lines-1) * (height+yspacing) + height;
+ } else {
+ this->osd_item.h = 0;
+ }
+
if (do_draw) {
osd_std_resize(&this->osd_item);
}
osd_text_init(struct osd_text *this, struct navit *nav)
{
- osd_set_std_graphic(nav, &this->osd_item);
+ osd_set_std_graphic(nav, &this->osd_item, (struct osd_priv *)this);
navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_text_draw), attr_position_coord_geo, this));
osd_text_draw(this, nav, NULL);
this->osd_item.p.y = 20;
this->osd_item.w = 60;
this->osd_item.h = 20;
+ this->osd_item.navit = nav;
this->osd_item.font_size = 200;
+ this->osd_item.meth.draw = &osd_text_draw;
osd_set_std_attr(attrs, &this->osd_item, 2);
this->active = -1;
static void
osd_gps_status_init(struct gps_status *this, struct navit *nav)
{
- osd_set_std_graphic(nav, &this->osd_item);
+ osd_set_std_graphic(nav, &this->osd_item, (struct osd_priv *)this);
navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_gps_status_draw), attr_position_coord_geo, this));
osd_gps_status_draw(this, nav, NULL);
}
this->osd_item.p.x = 20;
this->osd_item.p.y = -80;
this->osd_item.w = 60;
+ this->osd_item.navit = nav;
this->osd_item.h = 40;
this->osd_item.font_size = 200;
+ this->osd_item.meth.draw = &osd_gps_status_draw;
osd_set_std_attr(attrs, &this->osd_item, 0);
this->icon_w = -1;
static void
osd_volume_init(struct volume *this, struct navit *nav)
{
- osd_set_std_graphic(nav, &this->osd_item);
+ osd_set_std_graphic(nav, &this->osd_item, (struct osd_priv *)this);
navit_add_callback(nav, this->click_cb = callback_new_attr_1(callback_cast (osd_volume_click), attr_button, this));
osd_volume_draw(this, nav);
}
this->osd_item.p.x = 20;
this->osd_item.p.y = -80;
this->osd_item.w = 60;
+ this->osd_item.navit = nav;
this->osd_item.h = 40;
this->osd_item.font_size = 200;
+ this->osd_item.meth.draw = &osd_volume_draw;
osd_set_std_attr(attrs, &this->osd_item, 0);
this->icon_w = -1;