diff options
Diffstat (limited to 'navit/layout.c')
-rw-r--r-- | navit/layout.c | 555 |
1 files changed, 555 insertions, 0 deletions
diff --git a/navit/layout.c b/navit/layout.c new file mode 100644 index 00000000..04935ef8 --- /dev/null +++ b/navit/layout.c @@ -0,0 +1,555 @@ +/** + * Navit, a modular navigation system. + * 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 + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <glib.h> +#include <string.h> +#include "item.h" +#include "attr.h" +#include "layout.h" +#include "coord.h" +#include "debug.h" + + +struct layout * layout_new(struct attr *parent, struct attr **attrs) +{ + struct layout *l; + struct color def_color = {0xffff, 0xefef, 0xb7b7, 0xffff}; + struct attr *name_attr,*color_attr,*order_delta_attr,*font_attr,*day_attr,*night_attr; + + if (! (name_attr=attr_search(attrs, NULL, attr_name))) + return NULL; + l = g_new0(struct layout, 1); + l->name = g_strdup(name_attr->u.str); + if ((font_attr=attr_search(attrs, NULL, attr_font))) { + l->font = g_strdup(font_attr->u.str); + } + if ((day_attr=attr_search(attrs, NULL, attr_daylayout))) { + l->dayname = g_strdup(day_attr->u.str); + } + if ((night_attr=attr_search(attrs, NULL, attr_nightlayout))) { + l->nightname = g_strdup(night_attr->u.str); + } + if ((color_attr=attr_search(attrs, NULL, attr_color))) + l->color = *color_attr->u.color; + else + l->color = def_color; + if ((order_delta_attr=attr_search(attrs, NULL, attr_order_delta))) + l->order_delta=order_delta_attr->u.num; + return l; +} + +struct attr_iter { + GList *last; +}; + + +struct attr_iter * +layout_attr_iter_new(void) +{ + return g_new0(struct attr_iter, 1); +} + +void +layout_attr_iter_destroy(struct attr_iter *iter) +{ + g_free(iter); +} + +int +layout_get_attr(struct layout *layout, enum attr_type type, struct attr *attr, struct attr_iter *iter) +{ + GList *cursor,*layer; + attr->type=type; + switch (type) { + case attr_cursor: + cursor=layout->cursors; + while (cursor) { + if (!iter || iter->last == g_list_previous(cursor)) { + attr->u.cursor=cursor->data; + if (iter) + iter->last=cursor; + return 1; + } + cursor=g_list_next(cursor); + } + break; + case attr_layer: + layer=layout->layers; + while (layer) { + if (!iter || iter->last == g_list_previous(layer)) { + attr->u.layer=layer->data; + if (iter) + iter->last=layer; + return 1; + } + layer=g_list_next(layer); + } + break; + default: + break; + } + return 0; +} + + +int +layout_add_attr(struct layout *layout, struct attr *attr) +{ + switch (attr->type) { + case attr_cursor: + layout->cursors = g_list_append(layout->cursors, attr->u.cursor); + return 1; + case attr_layer: + layout->layers = g_list_append(layout->layers, attr->u.layer); + return 1; + default: + return 0; + } +} + +/** + * Searchs the layout for a cursor with the given name. + * + * @param layout The layout + * @param name The name + * @returns A pointer to cursor with the given name or the name default or NULL. + * @author Ralph Sennhauser (10/2009) +*/ +struct cursor * +layout_get_cursor(struct layout *this_, char *name) +{ + GList *c; + struct cursor *d=NULL; + + c=g_list_first(this_->cursors); + while (c) { + if (! strcmp(((struct cursor *)c->data)->name, name)) + return c->data; + if (! strcmp(((struct cursor *)c->data)->name, "default")) + d=c->data; + c=g_list_next(c); + } + return d; +} + + + +struct cursor * +cursor_new(struct attr *parent, struct attr **attrs) +{ + struct attr *w, *h, *name, *interval, *sequence_range; + + w=attr_search(attrs, NULL, attr_w); + h=attr_search(attrs, NULL, attr_h); + if (! w || ! h) + return NULL; + + struct cursor *this=g_new0(struct cursor,1); + this->w=w->u.num; + this->h=h->u.num; + name=attr_search(attrs, NULL, attr_name); + if (name) + this->name=g_strdup(name->u.str); + else + this->name=g_strdup("default"); + interval=attr_search(attrs, NULL, attr_interval); + if (interval) + this->interval=interval->u.num; + sequence_range=attr_search(attrs, NULL, attr_sequence_range); + if (sequence_range) { + struct range *r=g_new0(struct range,1); + r->min=sequence_range->u.range.min; + r->max=sequence_range->u.range.max; + this->sequence_range=r; + } + else { + this->sequence_range=NULL; + } + dbg(2,"ret=%p\n", this); + return this; +} + +void +cursor_destroy(struct cursor *this_) +{ + if (this_->sequence_range) + g_free(this_->sequence_range); + if (this_->name) { + g_free(this_->name); + } + g_free(this_); +} + +int +cursor_add_attr(struct cursor *this_, struct attr *attr) +{ + switch (attr->type) { + case attr_itemgra: + this_->attrs=attr_generic_add_attr(this_->attrs, attr); + return 1; + default: + break; + } + return 0; +} + +static int +layer_set_attr_do(struct layer *l, struct attr *attr, int init) +{ + switch (attr->type) { + case attr_active: + l->active = attr->u.num; + return 1; + case attr_details: + l->details = attr->u.num; + return 1; + case attr_name: + g_free(l->name); + l->name = g_strdup(attr->u.str); + return 1; + default: + return 0; + } +} + + + +struct layer * layer_new(struct attr *parent, struct attr **attrs) +{ + struct layer *l; + + l = g_new0(struct layer, 1); + l->active=1; + for (;*attrs; attrs++) { + layer_set_attr_do(l, *attrs, 1); + } + return l; +} + +int +layer_get_attr(struct layer *layer, enum attr_type type, struct attr *attr, struct attr_iter *iter) +{ + attr->type=type; + switch(type) { + case attr_active: + attr->u.num=layer->active; + return 1; + case attr_details: + attr->u.num=layer->details; + return 1; + case attr_name: + if (layer->name) { + attr->u.str=layer->name; + return 1; + } + break; + default: + return 0; + } + return 0; +} + +int +layer_add_attr(struct layer *layer, struct attr *attr) +{ + switch (attr->type) { + case attr_itemgra: + layer->itemgras = g_list_append(layer->itemgras, attr->u.itemgra); + return 1; + default: + return 0; + } +} + +int +layer_set_attr(struct layer *layer, struct attr *attr) +{ + return layer_set_attr_do(layer, attr, 0); +} + +struct itemgra * itemgra_new(struct attr *parent, struct attr **attrs) +{ + struct itemgra *itm; + struct attr *order, *item_types, *speed_range, *angle_range, *sequence_range; + enum item_type *type; + struct range defrange; + + itm = g_new0(struct itemgra, 1); + order=attr_search(attrs, NULL, attr_order); + item_types=attr_search(attrs, NULL, attr_item_types); + speed_range=attr_search(attrs, NULL, attr_speed_range); + angle_range=attr_search(attrs, NULL, attr_angle_range); + sequence_range=attr_search(attrs, NULL, attr_sequence_range); + defrange.min=0; + defrange.max=32767; + if (order) + itm->order=order->u.range; + else + itm->order=defrange; + if (speed_range) + itm->speed_range=speed_range->u.range; + else + itm->speed_range=defrange; + if (angle_range) + itm->angle_range=angle_range->u.range; + else + itm->angle_range=defrange; + if (sequence_range) + itm->sequence_range=sequence_range->u.range; + else + itm->sequence_range=defrange; + if (item_types) { + type=item_types->u.item_types; + while (type && *type != type_none) { + itm->type=g_list_append(itm->type, GINT_TO_POINTER(*type)); + type++; + } + } + return itm; +} +int +itemgra_add_attr(struct itemgra *itemgra, struct attr *attr) +{ + switch (attr->type) { + case attr_polygon: + case attr_polyline: + case attr_circle: + case attr_text: + case attr_icon: + case attr_image: + case attr_arrows: + itemgra->elements = g_list_append(itemgra->elements, attr->u.element); + return 1; + default: + dbg(0,"unknown: %s\n", attr_to_name(attr->type)); + return 0; + } +} + +static void +element_set_color(struct element *e, struct attr **attrs) +{ + struct attr *color; + color=attr_search(attrs, NULL, attr_color); + if (color) + e->color=*color->u.color; +} + + +static void +element_set_background_color(struct color *c, struct attr **attrs) +{ + struct attr *color; + color=attr_search(attrs, NULL, attr_background_color); + if (color) + *c=*color->u.color; +} + + +static void +element_set_text_size(struct element *e, struct attr **attrs) +{ + struct attr *text_size; + text_size=attr_search(attrs, NULL, attr_text_size); + if (text_size) + e->text_size=text_size->u.num; +} + +static void +element_set_polyline_width(struct element *e, struct attr **attrs) +{ + struct attr *width; + width=attr_search(attrs, NULL, attr_width); + if (width) + e->u.polyline.width=width->u.num; +} + +static void +element_set_polyline_directed(struct element *e, struct attr **attrs) +{ + struct attr *directed; + directed=attr_search(attrs, NULL, attr_directed); + if (directed) + e->u.polyline.directed=directed->u.num; +} + +static void +element_set_polyline_dash(struct element *e, struct attr **attrs) +{ + struct attr *dash; + int i; + + dash=attr_search(attrs, NULL, attr_dash); + if (dash) { + for (i=0; i<4; i++) { + if (!dash->u.dash[i]) + break; + e->u.polyline.dash_table[i] = dash->u.dash[i]; + } + e->u.polyline.dash_num=i; + } +} + +static void +element_set_polyline_offset(struct element *e, struct attr **attrs) +{ + struct attr *offset; + offset=attr_search(attrs, NULL, attr_offset); + if (offset) + e->u.polyline.offset=offset->u.num; +} + +static void +element_set_circle_width(struct element *e, struct attr **attrs) +{ + struct attr *width; + width=attr_search(attrs, NULL, attr_width); + if (width) + e->u.circle.width=width->u.num; +} + +static void +element_set_circle_radius(struct element *e, struct attr **attrs) +{ + struct attr *radius; + radius=attr_search(attrs, NULL, attr_radius); + if (radius) + e->u.circle.radius=radius->u.num; +} + +struct polygon * +polygon_new(struct attr *parent, struct attr **attrs) +{ + struct element *e; + e = g_new0(struct element, 1); + e->type=element_polygon; + element_set_color(e, attrs); + + return (struct polygon *)e; +} + +struct polyline * +polyline_new(struct attr *parent, struct attr **attrs) +{ + struct element *e; + + e = g_new0(struct element, 1); + e->type=element_polyline; + element_set_color(e, attrs); + element_set_polyline_width(e, attrs); + element_set_polyline_directed(e, attrs); + element_set_polyline_dash(e, attrs); + element_set_polyline_offset(e, attrs); + return (struct polyline *)e; +} + +struct circle * +circle_new(struct attr *parent, struct attr **attrs) +{ + struct element *e; + + e = g_new0(struct element, 1); + e->type=element_circle; + e->color = COLOR_BLACK; + e->u.circle.background_color = COLOR_WHITE; + element_set_color(e, attrs); + element_set_background_color(&e->u.circle.background_color, attrs); + element_set_text_size(e, attrs); + element_set_circle_width(e, attrs); + element_set_circle_radius(e, attrs); + + return (struct circle *)e; +} + +struct text * +text_new(struct attr *parent, struct attr **attrs) +{ + struct element *e; + + e = g_new0(struct element, 1); + e->type=element_text; + element_set_text_size(e, attrs); + e->color = COLOR_BLACK; + e->u.text.background_color = COLOR_WHITE; + element_set_color(e, attrs); + element_set_background_color(&e->u.text.background_color, attrs); + + return (struct text *)e; +} + +struct icon * +icon_new(struct attr *parent, struct attr **attrs) +{ + struct element *e; + struct attr *src,*w,*h,*rotation; + src=attr_search(attrs, NULL, attr_src); + if (! src) + return NULL; + + e = g_malloc0(sizeof(*e)+strlen(src->u.str)+1); + e->type=element_icon; + e->u.icon.src=(char *)(e+1); + if ((w=attr_search(attrs, NULL, attr_w))) + e->u.icon.width=w->u.num; + else + e->u.icon.width=-1; + if ((h=attr_search(attrs, NULL, attr_h))) + e->u.icon.height=h->u.num; + else + e->u.icon.height=-1; + if ((rotation=attr_search(attrs, NULL, attr_rotation))) + e->u.icon.rotation=rotation->u.num; + strcpy(e->u.icon.src,src->u.str); + + return (struct icon *)e; +} + +struct image * +image_new(struct attr *parent, struct attr **attrs) +{ + struct element *e; + + e = g_malloc0(sizeof(*e)); + e->type=element_image; + + return (struct image *)e; +} + +struct arrows * +arrows_new(struct attr *parent, struct attr **attrs) +{ + struct element *e; + e = g_malloc0(sizeof(*e)); + e->type=element_arrows; + element_set_color(e, attrs); + return (struct arrows *)e; +} + +int +element_add_attr(struct element *e, struct attr *attr) +{ + switch (attr->type) { + case attr_coord: + e->coord=g_realloc(e->coord,(e->coord_count+1)*sizeof(struct coord)); + e->coord[e->coord_count++]=*attr->u.coord; + return 1; + default: + return 0; + } +} |