Add:Core:Adding relative sizes and positions for OSDs
authortinloaf <tinloaf@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Mon, 30 Mar 2009 14:09:24 +0000 (14:09 +0000)
committertinloaf <tinloaf@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Mon, 30 Mar 2009 14:09:24 +0000 (14:09 +0000)
git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk@2174 ffa7fe5e-494d-0410-b361-a75ebd5db220

navit/navit/attr.c
navit/navit/attr.h
navit/navit/attr_def.h
navit/navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c
navit/navit/osd.c
navit/navit/osd.h
navit/navit/osd/core/osd_core.c

index b8a1722..d5ba5bf 100644 (file)
@@ -135,7 +135,22 @@ attr_new_from_text(const char *name, const char *value)
                }
                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
index d0469cd..25a9c26 100644 (file)
@@ -67,6 +67,10 @@ enum attr_type {
 #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 {
index 1358dd9..b050ccf 100644 (file)
@@ -33,12 +33,12 @@ ATTR(position_sat_item)
 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)
@@ -65,7 +65,7 @@ ATTR(announce_name_systematic_first)
 ATTR(antialias)
 ATTR(order_delta)
 ATTR(baudrate)
-ATTR(font_size)
+ATTR(font_size_remove)
 ATTR(icon_xs)
 ATTR(icon_l)
 ATTR(icon_s)
@@ -109,6 +109,21 @@ ATTR(pitch)
 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)
index 628ff27..f27af7b 100644 (file)
@@ -72,6 +72,7 @@ struct graphics_priv {
        int win_h;
        int visible;
        int overlay_disabled;
+       int overlay_autodisabled;
        int a;
        int wraparound;
        struct graphics_priv *parent;
@@ -465,7 +466,7 @@ overlay_draw(struct graphics_priv *parent, struct graphics_priv *overlay, GdkRec
        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);
@@ -803,15 +804,28 @@ static void
 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;
        }
 
@@ -823,8 +837,14 @@ overlay_resize(struct graphics_priv *this, struct point *p, int w, int h, int al
                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);
        }
@@ -833,15 +853,38 @@ overlay_resize(struct graphics_priv *this, struct point *p, int w, int h, int al
 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;
index a6e1ccc..f18abe6 100644 (file)
@@ -38,8 +38,8 @@ struct osd {
 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)
@@ -82,6 +82,41 @@ osd_std_click(struct osd_item *this, struct navit *nav, int pressed, int button,
 }
 
 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;
@@ -113,38 +148,61 @@ osd_set_std_attr(struct attr **attrs, struct osd_item *item, int flags)
                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
@@ -159,7 +217,7 @@ osd_std_config(struct osd_item *item, struct navit *navit)
 }
 
 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;
 
@@ -181,13 +239,11 @@ osd_set_std_graphic(struct navit *nav, struct osd_item *item)
 
        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
@@ -195,6 +251,7 @@ osd_std_draw(struct osd_item *item)
 {
        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;
index 2df822d..99b760d 100644 (file)
 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;
 };
@@ -48,7 +55,7 @@ void osd_wrap_point(struct point *p, struct navit *nav);
 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 */
index da1f58a..8901d78 100644 (file)
@@ -194,7 +194,7 @@ osd_compass_init(struct compass *this, struct navit *nav)
 {
        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;
@@ -219,7 +219,9 @@ osd_compass_new(struct navit *nav, struct osd_methods *meth,
        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;
@@ -258,7 +260,7 @@ osd_button_init(struct osd_button *this, struct navit *nav)
        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;
@@ -282,6 +284,9 @@ osd_button_new(struct navit *nav, struct osd_methods *meth,
        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);
@@ -406,7 +411,7 @@ osd_nav_next_turn_draw(struct nav_next_turn *this, struct navit *navit,
 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);
 }
@@ -421,8 +426,10 @@ osd_nav_next_turn_new(struct navit *nav, struct osd_methods *meth,
        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;
@@ -527,7 +534,7 @@ osd_nav_toggle_announcer_draw(struct nav_toggle_announcer *this, struct navit *n
 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);
@@ -542,8 +549,10 @@ osd_nav_toggle_announcer_new(struct navit *nav, struct osd_methods *meth, struct
 
        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);
 
@@ -602,7 +611,7 @@ osd_speed_warner_draw(struct osd_speed_warner *this, struct navit *navit, struct
 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});
@@ -618,8 +627,10 @@ osd_speed_warner_new(struct navit *nav, struct osd_methods *meth, struct attr **
        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)
@@ -739,7 +750,7 @@ static void
 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;
@@ -879,12 +890,23 @@ osd_text_draw(struct osd_text *this, struct navit *navit, struct vehicle *v)
                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:
@@ -895,7 +917,12 @@ osd_text_draw(struct osd_text *this, struct navit *navit, struct vehicle *v)
                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);
                }
@@ -941,7 +968,7 @@ static void
 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);
 
@@ -958,7 +985,9 @@ osd_text_new(struct navit *nav, struct osd_methods *meth,
        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;
@@ -1045,7 +1074,7 @@ osd_gps_status_draw(struct gps_status *this, struct navit *navit,
 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);
 }
@@ -1060,8 +1089,10 @@ osd_gps_status_new(struct navit *nav, struct osd_methods *meth,
        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;
@@ -1146,7 +1177,7 @@ osd_volume_click(struct volume *this, struct navit *nav, int pressed, int button
 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);
 }
@@ -1161,8 +1192,10 @@ osd_volume_new(struct navit *nav, struct osd_methods *meth,
        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;