From 97926db4c7a19b58353036e04218a3f669277f73 Mon Sep 17 00:00:00 2001 From: tinloaf Date: Mon, 30 Mar 2009 14:09:24 +0000 Subject: [PATCH] Add:Core:Adding relative sizes and positions for OSDs git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk@2174 ffa7fe5e-494d-0410-b361-a75ebd5db220 --- navit/navit/attr.c | 17 +++- navit/navit/attr.h | 4 + navit/navit/attr_def.h | 25 ++++- .../gtk_drawing_area/graphics_gtk_drawing_area.c | 61 ++++++++++-- navit/navit/osd.c | 107 ++++++++++++++++----- navit/navit/osd.h | 11 ++- navit/navit/osd/core/osd_core.c | 59 +++++++++--- 7 files changed, 229 insertions(+), 55 deletions(-) diff --git a/navit/navit/attr.c b/navit/navit/attr.c index b8a1722..d5ba5bf 100644 --- a/navit/navit/attr.c +++ b/navit/navit/attr.c @@ -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 diff --git a/navit/navit/attr.h b/navit/navit/attr.h index d0469cd..25a9c26 100644 --- a/navit/navit/attr.h +++ b/navit/navit/attr.h @@ -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 { diff --git a/navit/navit/attr_def.h b/navit/navit/attr_def.h index 1358dd9..b050ccf 100644 --- a/navit/navit/attr_def.h +++ b/navit/navit/attr_def.h @@ -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) diff --git a/navit/navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c b/navit/navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c index 628ff27..f27af7b 100644 --- a/navit/navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c +++ b/navit/navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c @@ -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; diff --git a/navit/navit/osd.c b/navit/navit/osd.c index a6e1ccc..f18abe6 100644 --- a/navit/navit/osd.c +++ b/navit/navit/osd.c @@ -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; diff --git a/navit/navit/osd.h b/navit/navit/osd.h index 2df822d..99b760d 100644 --- a/navit/navit/osd.h +++ b/navit/navit/osd.h @@ -23,18 +23,25 @@ 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 */ diff --git a/navit/navit/osd/core/osd_core.c b/navit/navit/osd/core/osd_core.c index da1f58a..8901d78 100644 --- a/navit/navit/osd/core/osd_core.c +++ b/navit/navit/osd/core/osd_core.c @@ -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; -- 2.7.4