diff options
Diffstat (limited to 'navit/gui/internal/gui_internal.c')
-rw-r--r-- | navit/gui/internal/gui_internal.c | 5634 |
1 files changed, 2731 insertions, 2903 deletions
diff --git a/navit/gui/internal/gui_internal.c b/navit/gui/internal/gui_internal.c index 0a62ae010..726a03d17 100644 --- a/navit/gui/internal/gui_internal.c +++ b/navit/gui/internal/gui_internal.c @@ -105,13 +105,14 @@ const int SMALL_PROFILE=2; * [1] => MEDIUM PROFILE (screens larger than 320 in one dimension * [2] => Small profile (default) */ -static struct gui_config_settings config_profiles[]={ - {545,32,48,96,10} +static struct gui_config_settings config_profiles[]= { + {545,32,48,96,10} , {300,32,48,64,3} - ,{200,16,32,48,2} + ,{200,16,32,48,2} }; static void gui_internal_cmd_view_in_browser(struct gui_priv *this, struct widget *wm, void *data); +static void gui_internal_prepare_search_results_map(struct gui_priv *this, struct widget *table, struct coord_rect *r); static int gui_internal_is_active_vehicle(struct gui_priv *this, struct vehicle *vehicle); @@ -127,29 +128,25 @@ static int gui_internal_is_active_vehicle(struct gui_priv *this, struct vehicle * * @return image_struct Ptr to scaled image struct or NULL if not scaled or found */ -static struct graphics_image * -image_new_scaled(struct gui_priv *this, const char *name, int w, int h) -{ - struct graphics_image *ret=NULL; - char *full_path=NULL; - full_path=graphics_icon_path(name); - ret=graphics_image_new_scaled(this->gra, full_path, w, h); - dbg(lvl_debug,"Trying to load image '%s' (w=%d, h=%d): %s\n", name, w, h, ret ? "OK" : "NOT FOUND"); - g_free(full_path); - if (!ret) { - dbg(lvl_error,"Failed to load image for '%s' (w=%d, h=%d)\n", name, w, h); - full_path=graphics_icon_path("unknown"); - ret=graphics_image_new_scaled(this->gra, full_path, w, h); - g_free(full_path); - } - return ret; +static struct graphics_image *image_new_scaled(struct gui_priv *this, const char *name, int w, int h) { + struct graphics_image *ret=NULL; + char *full_path=NULL; + full_path=graphics_icon_path(name); + ret=graphics_image_new_scaled(this->gra, full_path, w, h); + dbg(lvl_debug,"Trying to load image '%s' (w=%d, h=%d): %s", name, w, h, ret ? "OK" : "NOT FOUND"); + g_free(full_path); + if (!ret) { + dbg(lvl_error,"Failed to load image for '%s' (w=%d, h=%d)", name, w, h); + full_path=graphics_icon_path("unknown"); + ret=graphics_image_new_scaled(this->gra, full_path, w, h); + g_free(full_path); + } + return ret; } #if 0 -static struct graphics_image * -image_new_o(struct gui_priv *this, char *name) -{ - return image_new_scaled(this, name, -1, -1); +static struct graphics_image *image_new_o(struct gui_priv *this, char *name) { + return image_new_scaled(this, name, -1, -1); } #endif @@ -164,9 +161,8 @@ image_new_o(struct gui_priv *this, char *name) * @return image_struct Ptr to scaled image struct or NULL if not scaled or found */ struct graphics_image * -image_new_xs(struct gui_priv *this, const char *name) -{ - return image_new_scaled(this, name, this->icon_xs, this->icon_xs); +image_new_xs(struct gui_priv *this, const char *name) { + return image_new_scaled(this, name, this->icon_xs, this->icon_xs); } /** @@ -178,9 +174,8 @@ image_new_xs(struct gui_priv *this, const char *name) * @return image_struct Ptr to scaled image struct or NULL if not scaled or found */ struct graphics_image * -image_new_s(struct gui_priv *this, const char *name) -{ - return image_new_scaled(this, name, this->icon_s, this->icon_s); +image_new_s(struct gui_priv *this, const char *name) { + return image_new_scaled(this, name, this->icon_s, this->icon_s); } /** @@ -191,108 +186,101 @@ image_new_s(struct gui_priv *this, const char *name) * @return image_struct Ptr to scaled image struct or NULL if not scaled or found */ struct graphics_image * -image_new_l(struct gui_priv *this, const char *name) -{ - return image_new_scaled(this, name, this->icon_l, this->icon_l); -} - - - -static int -gui_internal_button_attr_update(struct gui_priv *this, struct widget *w) -{ - struct widget *wi; - int is_on=0; - struct attr curr; - GList *l; - - if (w->get_attr(w->instance, w->on.type, &curr, NULL)) - is_on=curr.u.data == w->on.u.data; - else - is_on=w->deflt; - if (is_on != w->is_on) { - if (w->redraw) - this->redraw=1; - w->is_on=is_on; - l=g_list_first(w->children); - if (l) { - wi=l->data; - if (wi->img) - graphics_image_free(this->gra, wi->img); - wi->img=image_new_xs(this, is_on ? "gui_active" : "gui_inactive"); - } - if (w->is_on && w->off.type == attr_none) - w->state &= ~STATE_SENSITIVE; - else - w->state |= STATE_SENSITIVE; - return 1; - } - return 0; -} - -static void -gui_internal_button_attr_callback(struct gui_priv *this, struct widget *w) -{ - if (gui_internal_button_attr_update(this, w)) - gui_internal_widget_render(this, w); -} -static void -gui_internal_button_attr_pressed(struct gui_priv *this, struct widget *w, void *data) -{ - if (w->is_on) - w->set_attr(w->instance, &w->off); - else - w->set_attr(w->instance, &w->on); - gui_internal_button_attr_update(this, w); +image_new_l(struct gui_priv *this, const char *name) { + return image_new_scaled(this, name, this->icon_l, this->icon_l); +} + + + +static int gui_internal_button_attr_update(struct gui_priv *this, struct widget *w) { + struct widget *wi; + int is_on=0; + struct attr curr; + GList *l; + + if (w->get_attr(w->instance, w->on.type, &curr, NULL)) + is_on=curr.u.data == w->on.u.data; + else + is_on=w->deflt; + if (is_on != w->is_on) { + if (w->redraw) + this->redraw=1; + w->is_on=is_on; + l=g_list_first(w->children); + if (l) { + wi=l->data; + if (wi->img) + graphics_image_free(this->gra, wi->img); + wi->img=image_new_xs(this, is_on ? "gui_active" : "gui_inactive"); + } + if (w->is_on && w->off.type == attr_none) + w->state &= ~STATE_SENSITIVE; + else + w->state |= STATE_SENSITIVE; + return 1; + } + return 0; +} + +static void gui_internal_button_attr_callback(struct gui_priv *this, struct widget *w) { + if (gui_internal_button_attr_update(this, w)) + gui_internal_widget_render(this, w); +} +static void gui_internal_button_attr_pressed(struct gui_priv *this, struct widget *w, void *data) { + if (w->is_on) + w->set_attr(w->instance, &w->off); + else + w->set_attr(w->instance, &w->on); + gui_internal_button_attr_update(this, w); } struct widget * -gui_internal_button_navit_attr_new(struct gui_priv *this, const char *text, enum flags flags, struct attr *on, struct attr *off) -{ - struct graphics_image *image=NULL; - struct widget *ret; - if (!on && !off) - return NULL; - image=image_new_xs(this, "gui_inactive"); - ret=gui_internal_button_new_with_callback(this, text, image, flags, gui_internal_button_attr_pressed, NULL); - if (on) - ret->on=*on; - if (off) - ret->off=*off; - ret->get_attr=(int (*)(void *, enum attr_type, struct attr *, struct attr_iter *))navit_get_attr; - ret->set_attr=(int (*)(void *, struct attr *))navit_set_attr; - ret->remove_cb=(void (*)(void *, struct callback *))navit_remove_callback; - ret->instance=this->nav; - ret->cb=callback_new_attr_2(callback_cast(gui_internal_button_attr_callback), on?on->type:off->type, this, ret); - navit_add_callback(this->nav, ret->cb); - gui_internal_button_attr_update(this, ret); - return ret; +gui_internal_button_navit_attr_new(struct gui_priv *this, const char *text, enum flags flags, struct attr *on, + struct attr *off) { + struct graphics_image *image=NULL; + struct widget *ret; + if (!on && !off) + return NULL; + image=image_new_xs(this, "gui_inactive"); + ret=gui_internal_button_new_with_callback(this, text, image, flags, gui_internal_button_attr_pressed, NULL); + if (on) + ret->on=*on; + if (off) + ret->off=*off; + ret->get_attr=(int (*)(void *, enum attr_type, struct attr *, struct attr_iter *))navit_get_attr; + ret->set_attr=(int (*)(void *, struct attr *))navit_set_attr; + ret->remove_cb=(void (*)(void *, struct callback *))navit_remove_callback; + ret->instance=this->nav; + ret->cb=callback_new_attr_2(callback_cast(gui_internal_button_attr_callback), on?on->type:off->type, this, ret); + navit_add_callback(this->nav, ret->cb); + gui_internal_button_attr_update(this, ret); + return ret; } struct widget * -gui_internal_button_map_attr_new(struct gui_priv *this, const char *text, enum flags flags, struct map *map, struct attr *on, struct attr *off, int deflt) -{ - struct graphics_image *image=NULL; - struct widget *ret; - image=image_new_xs(this, "gui_inactive"); - if (!on && !off) - return NULL; - ret=gui_internal_button_new_with_callback(this, text, image, flags, gui_internal_button_attr_pressed, NULL); - if (on) - ret->on=*on; - if (off) - ret->off=*off; - ret->deflt=deflt; - ret->get_attr=(int (*)(void *, enum attr_type, struct attr *, struct attr_iter *))map_get_attr; - ret->set_attr=(int (*)(void *, struct attr *))map_set_attr; - ret->remove_cb=(void (*)(void *, struct callback *))map_remove_callback; - ret->instance=map; - ret->redraw=1; - ret->cb=callback_new_attr_2(callback_cast(gui_internal_button_attr_callback), on?on->type:off->type, this, ret); - map_add_callback(map, ret->cb); - gui_internal_button_attr_update(this, ret); - return ret; +gui_internal_button_map_attr_new(struct gui_priv *this, const char *text, enum flags flags, struct map *map, + struct attr *on, struct attr *off, int deflt) { + struct graphics_image *image=NULL; + struct widget *ret; + image=image_new_xs(this, "gui_inactive"); + if (!on && !off) + return NULL; + ret=gui_internal_button_new_with_callback(this, text, image, flags, gui_internal_button_attr_pressed, NULL); + if (on) + ret->on=*on; + if (off) + ret->off=*off; + ret->deflt=deflt; + ret->get_attr=(int (*)(void *, enum attr_type, struct attr *, struct attr_iter *))map_get_attr; + ret->set_attr=(int (*)(void *, struct attr *))map_set_attr; + ret->remove_cb=(void (*)(void *, struct callback *))map_remove_callback; + ret->instance=map; + ret->redraw=1; + ret->cb=callback_new_attr_2(callback_cast(gui_internal_button_attr_callback), on?on->type:off->type, this, ret); + map_add_callback(map, ret->cb); + gui_internal_button_attr_update(this, ret); + return ret; } @@ -312,89 +300,90 @@ gui_internal_button_map_attr_new(struct gui_priv *this, const char *text, enum f /* FIXME where is the implementation? */ -static void gui_internal_motion_cb(struct gui_priv *this) -{ - this->motion_timeout_event=NULL; - gui_internal_gesture_ring_add(this, &(this->current)); - - /* Check for scrollable table below the highligted item if there's a movement with the button pressed */ - if (this->pressed && this->highlighted) { - struct widget *wt=NULL; - struct widget *wr=NULL; - int dx,dy; - - /* Guard against accidental scrolling when user is likely going to swipe */ - gui_internal_gesture_get_vector(this, 1000, NULL, &dx, &dy); - if(abs(dx)>abs(dy) || abs(dy)<this->icon_s) - return; - - if(this->highlighted) - for(wr=this->highlighted;wr && wr->type!=widget_table_row;wr=wr->parent); - if(wr) - wt=wr->parent; - - if(wt && wt->type==widget_table && (wt->state & STATE_SCROLLABLE)) { - struct table_data *td=wt->data; - GList *top=NULL; - GList *btm=NULL; - GList *ttop, *tbtm; - - - - if(!wr || !wr->h) - return; - - if(this->current.y < wr->p.y && wr!=td->top_row->data ) { - int n=(wr->p.y-this->current.y)/wr->h+1; - - btm=td->bottom_row; - top=td->top_row; - - while(n-->0 && (tbtm=gui_internal_widget_table_next_row(btm))!=NULL && (ttop=gui_internal_widget_table_next_row(top))!=NULL) { - top=ttop; - btm=tbtm; - if(top->data==wr) - break; - } - this->pressed=2; - } else if (this->current.y > wr->p.y + wr->h ) { - int y=wt->p.y+wt->h-wr->h; - int n; - - if(td->scroll_buttons.button_box && td->scroll_buttons.button_box->p.y!=0) - y=td->scroll_buttons.button_box->p.y - td->scroll_buttons.button_box->h; - - if(y>this->current.y) - y=this->current.y; - - n=(y - wr->p.y )/wr->h; - - btm=td->bottom_row; - top=td->top_row; - - while(n-->0 && (ttop=gui_internal_widget_table_prev_row(top))!=NULL && (tbtm=gui_internal_widget_table_prev_row(btm))!=NULL) { - btm=tbtm; - top=ttop; - if(btm->data==wr) - break; - } - this->pressed=2; - } - if( top && btm && (td->top_row!=top || td->bottom_row!=btm) ) { - gui_internal_table_hide_rows(wt->data); - td->top_row=top; - td->bottom_row=btm; - graphics_draw_mode(this->gra, draw_mode_begin); - gui_internal_widget_render(this,wt); - graphics_draw_mode(this->gra, draw_mode_end); - } - - return; - } - } - - /* Else, just move highlight after pointer if there's nothing to scroll */ - gui_internal_highlight(this); +static void gui_internal_motion_cb(struct gui_priv *this) { + this->motion_timeout_event=NULL; + gui_internal_gesture_ring_add(this, &(this->current)); + + /* Check for scrollable table below the highligted item if there's a movement with the button pressed */ + if (this->pressed && this->highlighted) { + struct widget *wt=NULL; + struct widget *wr=NULL; + int dx,dy; + + /* Guard against accidental scrolling when user is likely going to swipe */ + gui_internal_gesture_get_vector(this, 1000, NULL, &dx, &dy); + if(abs(dx)>abs(dy) || abs(dy)<this->icon_s) + return; + + if(this->highlighted) + for(wr=this->highlighted; wr && wr->type!=widget_table_row; wr=wr->parent); + if(wr) + wt=wr->parent; + + if(wt && wt->type==widget_table && (wt->state & STATE_SCROLLABLE)) { + struct table_data *td=wt->data; + GList *top=NULL; + GList *btm=NULL; + GList *ttop, *tbtm; + + + + if(!wr || !wr->h) + return; + + if(this->current.y < wr->p.y && wr!=td->top_row->data ) { + int n=(wr->p.y-this->current.y)/wr->h+1; + + btm=td->bottom_row; + top=td->top_row; + + while(n-->0 && (tbtm=gui_internal_widget_table_next_row(btm))!=NULL + && (ttop=gui_internal_widget_table_next_row(top))!=NULL) { + top=ttop; + btm=tbtm; + if(top->data==wr) + break; + } + this->pressed=2; + } else if (this->current.y > wr->p.y + wr->h ) { + int y=wt->p.y+wt->h-wr->h; + int n; + + if(td->scroll_buttons.button_box && td->scroll_buttons.button_box->p.y!=0) + y=td->scroll_buttons.button_box->p.y - td->scroll_buttons.button_box->h; + + if(y>this->current.y) + y=this->current.y; + + n=(y - wr->p.y )/wr->h; + + btm=td->bottom_row; + top=td->top_row; + + while(n-->0 && (ttop=gui_internal_widget_table_prev_row(top))!=NULL + && (tbtm=gui_internal_widget_table_prev_row(btm))!=NULL) { + btm=tbtm; + top=ttop; + if(btm->data==wr) + break; + } + this->pressed=2; + } + if( top && btm && (td->top_row!=top || td->bottom_row!=btm) ) { + gui_internal_table_hide_rows(wt->data); + td->top_row=top; + td->bottom_row=btm; + graphics_draw_mode(this->gra, draw_mode_begin); + gui_internal_widget_render(this,wt); + graphics_draw_mode(this->gra, draw_mode_end); + } + + return; + } + } + + /* Else, just move highlight after pointer if there's nothing to scroll */ + gui_internal_highlight(this); } //############################################################################################################## @@ -402,229 +391,196 @@ static void gui_internal_motion_cb(struct gui_priv *this) //# Comment: //# Authors: Martin Schaller (04/2008) //############################################################################################################## -static void gui_internal_call_highlighted(struct gui_priv *this) -{ - if (! this->highlighted || ! this->highlighted->func) - return; - this->highlighted->reason=gui_internal_reason_click; - this->highlighted->func(this, this->highlighted, this->highlighted->data); -} - -void -gui_internal_say(struct gui_priv *this, struct widget *w, int questionmark) -{ - char *text=w->speech; - if (! this->speech) - return; - if (!text) - text=w->text; - if (!text) - text=w->name; - if (text) { - text=g_strdup_printf("%s%c", text, questionmark ? '?':'\0'); - navit_say(this->nav, text); - g_free(text); - } +static void gui_internal_call_highlighted(struct gui_priv *this) { + if (! this->highlighted || ! this->highlighted->func) + return; + this->highlighted->reason=gui_internal_reason_click; + this->highlighted->func(this, this->highlighted, this->highlighted->data); +} + +void gui_internal_say(struct gui_priv *this, struct widget *w, int questionmark) { + char *text=w->speech; + if (! this->speech) + return; + if (!text) + text=w->text; + if (!text) + text=w->name; + if (text) { + text=g_strdup_printf("%s%c", text, questionmark ? '?':'\0'); + navit_say(this->nav, text); + g_free(text); + } } -void -gui_internal_back(struct gui_priv *this, struct widget *w, void *data) -{ - gui_internal_prune_menu_count(this, 1, 1); +void gui_internal_back(struct gui_priv *this, struct widget *w, void *data) { + gui_internal_prune_menu_count(this, 1, 1); } -void -gui_internal_cmd_return(struct gui_priv *this, struct widget *wm, void *data) -{ - gui_internal_prune_menu(this, wm->data); +void gui_internal_cmd_return(struct gui_priv *this, struct widget *wm, void *data) { + gui_internal_prune_menu(this, wm->data); } -void -gui_internal_cmd_main_menu(struct gui_priv *this, struct widget *wm, void *data) -{ - struct widget *w=this->root.children->data; - if (w && w->menu_data && w->menu_data->href && !strcmp(w->menu_data->href,"#Main Menu")) - gui_internal_prune_menu(this, w); - else - gui_internal_html_main_menu(this); +void gui_internal_cmd_main_menu(struct gui_priv *this, struct widget *wm, void *data) { + struct widget *w=this->root.children->data; + if (w && w->menu_data && w->menu_data->href && !strcmp(w->menu_data->href,"#Main Menu")) + gui_internal_prune_menu(this, w); + else + gui_internal_html_main_menu(this); } struct widget * -gui_internal_time_help(struct gui_priv *this) -{ - struct widget *w,*wc,*wcn; - char timestr[64]; - struct tm *tm; - time_t timep; - - w=gui_internal_box_new(this, gravity_right_center|orientation_horizontal|flags_fill); - w->bl=this->spacing; - w->spx=this->spacing; - w->spx=10; - w->bl=10; - w->br=10; - w->bt=6; - w->bb=6; - if (this->flags & 64) { - wc=gui_internal_box_new(this, gravity_right_top|orientation_vertical|flags_fill); - wc->bl=10; - wc->br=20; - wc->bt=6; - wc->bb=6; - timep=time(NULL); - tm=localtime(&timep); - strftime(timestr, 64, "%H:%M %d.%m.%Y", tm); - wcn=gui_internal_label_new(this, timestr); - gui_internal_widget_append(wc, wcn); - gui_internal_widget_append(w, wc); - } - if (this->flags & 128) { - wcn=gui_internal_button_new_with_callback(this, _("Help"), image_new_l(this, "gui_help"), gravity_center|orientation_vertical|flags_fill, NULL, NULL); - gui_internal_widget_append(w, wcn); - } - return w; +gui_internal_time_help(struct gui_priv *this) { + struct widget *w,*wc,*wcn; + char timestr[64]; + struct tm *tm; + time_t timep; + + w=gui_internal_box_new(this, gravity_right_center|orientation_horizontal|flags_fill); + w->bl=this->spacing; + w->spx=this->spacing; + w->spx=10; + w->bl=10; + w->br=10; + w->bt=6; + w->bb=6; + if (this->flags & 64) { + wc=gui_internal_box_new(this, gravity_right_top|orientation_vertical|flags_fill); + wc->bl=10; + wc->br=20; + wc->bt=6; + wc->bb=6; + timep=time(NULL); + tm=localtime(&timep); + strftime(timestr, 64, "%H:%M %d.%m.%Y", tm); + wcn=gui_internal_label_new(this, timestr); + gui_internal_widget_append(wc, wcn); + gui_internal_widget_append(w, wc); + } + if (this->flags & 128) { + wcn=gui_internal_button_new_with_callback(this, _("Help"), image_new_l(this, "gui_help"), + gravity_center|orientation_vertical|flags_fill, NULL, NULL); + gui_internal_widget_append(w, wcn); + } + return w; } /** * Applies the configuration values to this based on the settings * specified in the configuration file (this->config) and - * the most approriate default profile based on screen resolution. + * the most appropriate default profile based on screen resolution. * * This function should be run after this->root is setup and could * be rerun after the window is resized. * * @author Steve Singer <ssinger_pg@sympatico.ca> (09/2008) */ -void -gui_internal_apply_config(struct gui_priv *this) -{ - struct gui_config_settings * current_config=0; - - dbg(lvl_debug,"w=%d h=%d\n", this->root.w, this->root.h); - /* - * Select default values from profile based on the screen. - */ - if((this->root.w > 320 || this->root.h > 320) && this->root.w > 240 && this->root.h > 240) - { - if((this->root.w > 640 || this->root.h > 640) && this->root.w > 480 && this->root.h > 480 ) - { - current_config = &config_profiles[LARGE_PROFILE]; +void gui_internal_apply_config(struct gui_priv *this) { + struct gui_config_settings * current_config=0; + + dbg(lvl_debug,"w=%d h=%d", this->root.w, this->root.h); + /* + * Select default values from profile based on the screen. + */ + if((this->root.w > 320 || this->root.h > 320) && this->root.w > 240 && this->root.h > 240) { + if((this->root.w > 640 || this->root.h > 640) && this->root.w > 480 && this->root.h > 480 ) { + current_config = &config_profiles[LARGE_PROFILE]; + } else { + current_config = &config_profiles[MEDIUM_PROFILE]; + } + } else { + current_config = &config_profiles[SMALL_PROFILE]; } - else - { - current_config = &config_profiles[MEDIUM_PROFILE]; - } - } - else - { - current_config = &config_profiles[SMALL_PROFILE]; - } - - /* - * Apply override values from config file - */ - if(this->config.font_size == -1 ) - { - this->font_size = current_config->font_size; - } - else - { - this->font_size = this->config.font_size; - } - - if(this->config.icon_xs == -1 ) - { - this->icon_xs = current_config->icon_xs; - } - else - { - this->icon_xs = this->config.icon_xs; - } - - if(this->config.icon_s == -1 ) - { - this->icon_s = current_config->icon_s; - } - else - { - this->icon_s = this->config.icon_s; - } - if(this->config.icon_l == -1 ) - { - this->icon_l = current_config->icon_l; - } - else - { - this->icon_l = this->config.icon_l; - } - if(this->config.spacing == -1 ) - { - this->spacing = current_config->spacing; - } - else - { - this->spacing = current_config->spacing; - } - if (!this->fonts[0]) { - int i,sizes[]={100,66,50}; - for (i = 0 ; i < 3 ; i++) { - if (this->font_name) - this->fonts[i]=graphics_named_font_new(this->gra,this->font_name,this->font_size*sizes[i]/100,1); - else - this->fonts[i]=graphics_font_new(this->gra,this->font_size*sizes[i]/100,1); - } - } - -} - - - - - -static void -gui_internal_cmd_set_destination(struct gui_priv *this, struct widget *wm, void *data) -{ - char *name=data; - dbg(lvl_info,"c=%d:0x%x,0x%x\n", wm->c.pro, wm->c.x, wm->c.y); - navit_set_destination(this->nav, &wm->c, name, 1); - if (this->flags & 512) { - struct attr follow; - follow.type=attr_follow; - follow.u.num=180; - navit_set_attr(this->nav, &this->osd_configuration); - navit_set_attr(this->nav, &follow); - navit_zoom_to_route(this->nav, 0); - } - gui_internal_prune_menu(this, NULL); -} - -static void -gui_internal_cmd_insert_destination_do(struct gui_priv *this, struct widget *wm, void *data) { - char *name=data; - int dstcount=navit_get_destination_count(this->nav)+1; - int pos,i; - struct pcoord *dst=g_alloca(dstcount*sizeof(struct pcoord)); - dstcount=navit_get_destinations(this->nav,dst,dstcount); - - pos=dstcount-wm->datai; - if(pos<0) - pos=0; - - for(i=dstcount;i>pos;i--) - dst[i]=dst[i-1]; - - dst[pos]=wm->c; - navit_add_destination_description(this->nav,&wm->c,(char*)data); - navit_set_destinations(this->nav,dst,dstcount+1,name,1); - gui_internal_prune_menu(this, NULL); + + /* + * Apply override values from config file + */ + if(this->config.font_size == -1 ) { + this->font_size = current_config->font_size; + } else { + this->font_size = this->config.font_size; + } + + if(this->config.icon_xs == -1 ) { + this->icon_xs = current_config->icon_xs; + } else { + this->icon_xs = this->config.icon_xs; + } + + if(this->config.icon_s == -1 ) { + this->icon_s = current_config->icon_s; + } else { + this->icon_s = this->config.icon_s; + } + if(this->config.icon_l == -1 ) { + this->icon_l = current_config->icon_l; + } else { + this->icon_l = this->config.icon_l; + } + if(this->config.spacing == -1 ) { + this->spacing = current_config->spacing; + } else { + this->spacing = this->config.spacing; + dbg(lvl_info, "Overriding default spacing %d with value %d provided in config file", current_config->spacing, + this->config.spacing); + } + if (!this->fonts[0]) { + int i,sizes[]= {100,66,50}; + for (i = 0 ; i < 3 ; i++) { + if (this->font_name) + this->fonts[i]=graphics_named_font_new(this->gra,this->font_name,this->font_size*sizes[i]/100,1); + else + this->fonts[i]=graphics_font_new(this->gra,this->font_size*sizes[i]/100,1); + } + } + +} + + + + + +static void gui_internal_cmd_set_destination(struct gui_priv *this, struct widget *wm, void *data) { + char *name=data; + dbg(lvl_info,"c=%d:0x%x,0x%x", wm->c.pro, wm->c.x, wm->c.y); + navit_set_destination(this->nav, &wm->c, name, 1); + if (this->flags & 512) { + struct attr follow; + follow.type=attr_follow; + follow.u.num=180; + navit_set_attr(this->nav, &this->osd_configuration); + navit_set_attr(this->nav, &follow); + navit_zoom_to_route(this->nav, 0); + } + gui_internal_prune_menu(this, NULL); +} + +static void gui_internal_cmd_insert_destination_do(struct gui_priv *this, struct widget *wm, void *data) { + char *name=data; + int dstcount=navit_get_destination_count(this->nav)+1; + int pos,i; + struct pcoord *dst=g_alloca(dstcount*sizeof(struct pcoord)); + dstcount=navit_get_destinations(this->nav,dst,dstcount); + + pos=dstcount-wm->datai; + if(pos<0) + pos=0; + + for(i=dstcount; i>pos; i--) + dst[i]=dst[i-1]; + + dst[pos]=wm->c; + navit_add_destination_description(this->nav,&wm->c,(char*)data); + navit_set_destinations(this->nav,dst,dstcount+1,name,1); + gui_internal_prune_menu(this, NULL); } /* @@ -634,7 +590,7 @@ gui_internal_cmd_insert_destination_do(struct gui_priv *this, struct widget *wm, * function passed as {@code cmd} will be called. * * Widget passed as wm parameter of the called cmd function will have item set to user chosen waypoint item. Its data will be set - * to zero-based choosen waypoint number, counting from the route end. Coordinates to wm->c will be copied from wm_->c if wm_ is not null. Otherwise, + * to zero-based chosen waypoint number, counting from the route end. Coordinates to wm->c will be copied from wm_->c if wm_ is not null. Otherwise, * waypoint coordinates will be copied to wm->c. * * @param this gui context @@ -644,82 +600,79 @@ gui_internal_cmd_insert_destination_do(struct gui_priv *this, struct widget *wm, * @param cmd Callback function which will be called on item selection * @param data data argument to be passed to the callback function */ -void -gui_internal_select_waypoint(struct gui_priv *this, const char *title, const char *hint, struct widget *wm_, void(*cmd)(struct gui_priv *priv, struct widget *widget, void *data),void *data) -{ - struct widget *wb,*w,*wtable,*row,*wc; - struct map *map; - struct map_rect *mr; - struct item *item; - char *text; - int i; - int dstcount=navit_get_destination_count(this->nav)+1; - - map=route_get_map(navit_get_route(this->nav)); - if(!map) - return; - mr = map_rect_new(map, NULL); - if(!mr) - return; - - wb=gui_internal_menu(this, title); - w=gui_internal_box_new(this, gravity_top_center|orientation_vertical|flags_expand|flags_fill); - gui_internal_widget_append(wb, w); - if(hint) - gui_internal_widget_append(w, gui_internal_label_new(this, hint)); - wtable = gui_internal_widget_table_new(this,gravity_left_top | flags_fill | flags_expand |orientation_vertical,1); - gui_internal_widget_append(w,wtable); - - i=0; - while((item = map_rect_get_item(mr))!=NULL) { - struct attr attr; - if(item->type!=type_waypoint && item->type!=type_route_end) - continue; - if (item_attr_get(item, attr_label, &attr)) { - text=g_strdup_printf(_("Waypoint %s"), map_convert_string_tmp(item->map, attr.u.str)); - } else - continue; - gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); - gui_internal_widget_append(row, wc=gui_internal_button_new_with_callback(this, text, - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - cmd, data)); - wc->item=*item; - if(wm_) - wc->c=wm_->c; - else { - struct coord c; - item_coord_get(item,&c,1); - wc->c.x=c.x; - wc->c.y=c.y; - wc->c.pro=map_projection(item->map); - } - i++; - wc->datai=dstcount-i; - g_free(text); - } - map_rect_destroy(mr); - gui_internal_menu_render(this); -} - -static void -gui_internal_cmd_insert_destination(struct gui_priv *this, struct widget *wm, void *data) -{ - gui_internal_select_waypoint(this, data, _("Select waypoint to insert the new one before"), wm, gui_internal_cmd_insert_destination_do, data); -} - - - -static void -gui_internal_cmd_set_position(struct gui_priv *this, struct widget *wm, void *data) -{ - struct attr v; - if(data) { - v.type=attr_vehicle; - v.u.vehicle=NULL; - navit_set_attr(this->nav, &v); - } - navit_set_position(this->nav, &wm->c); - gui_internal_prune_menu(this, NULL); +void gui_internal_select_waypoint(struct gui_priv *this, const char *title, const char *hint, struct widget *wm_, + void(*cmd)(struct gui_priv *priv, struct widget *widget, void *data),void *data) { + struct widget *wb,*w,*wtable,*row,*wc; + struct map *map; + struct map_rect *mr; + struct item *item; + char *text; + int i; + int dstcount=navit_get_destination_count(this->nav)+1; + + map=route_get_map(navit_get_route(this->nav)); + if(!map) + return; + mr = map_rect_new(map, NULL); + if(!mr) + return; + + wb=gui_internal_menu(this, title); + w=gui_internal_box_new(this, gravity_top_center|orientation_vertical|flags_expand|flags_fill); + gui_internal_widget_append(wb, w); + if(hint) + gui_internal_widget_append(w, gui_internal_label_new(this, hint)); + wtable = gui_internal_widget_table_new(this,gravity_left_top | flags_fill | flags_expand |orientation_vertical,1); + gui_internal_widget_append(w,wtable); + + i=0; + while((item = map_rect_get_item(mr))!=NULL) { + struct attr attr; + if(item->type!=type_waypoint && item->type!=type_route_end) + continue; + if (item_attr_get(item, attr_label, &attr)) { + text=g_strdup_printf(_("Waypoint %s"), map_convert_string_tmp(item->map, attr.u.str)); + } else + continue; + gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this, + gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, wc=gui_internal_button_new_with_callback(this, text, + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + cmd, data)); + wc->item=*item; + if(wm_) + wc->c=wm_->c; + else { + struct coord c; + item_coord_get(item,&c,1); + wc->c.x=c.x; + wc->c.y=c.y; + wc->c.pro=map_projection(item->map); + } + i++; + wc->datai=dstcount-i; + g_free(text); + } + map_rect_destroy(mr); + gui_internal_menu_render(this); +} + +static void gui_internal_cmd_insert_destination(struct gui_priv *this, struct widget *wm, void *data) { + gui_internal_select_waypoint(this, data, _("Select waypoint to insert the new one before"), wm, + gui_internal_cmd_insert_destination_do, data); +} + + + +static void gui_internal_cmd_set_position(struct gui_priv *this, struct widget *wm, void *data) { + struct attr v; + if(data) { + v.type=attr_vehicle; + v.u.vehicle=NULL; + navit_set_attr(this->nav, &v); + } + navit_set_position(this->nav, &wm->c); + gui_internal_prune_menu(this, NULL); } @@ -731,14 +684,12 @@ gui_internal_cmd_set_position(struct gui_priv *this, struct widget *wm, void *da * @brief Generic notification function for Editable widgets to call Another widget notification function when Enter is pressed in editable field. * The Editable widget should have data member pointing to the Another widget. */ -void -gui_internal_call_linked_on_finish(struct gui_priv *this, struct widget *wm, void *data) -{ - if (wm->reason==gui_internal_reason_keypress_finish && data) { - struct widget *w=data; - if(w->func) - w->func(this, w, w->data); - } +void gui_internal_call_linked_on_finish(struct gui_priv *this, struct widget *wm, void *data) { + if (wm->reason==gui_internal_reason_keypress_finish && data) { + struct widget *w=data; + if(w->func) + w->func(this, w, w->data); + } } struct widget * gui_internal_keyboard(struct gui_priv *this, int mode); @@ -747,345 +698,313 @@ struct widget * gui_internal_keyboard(struct gui_priv *this, int mode); struct widget * gui_internal_keyboard_show_native(struct gui_priv *this, struct widget *w, int mode, char *lang); -static void -gui_internal_cmd_delete_bookmark(struct gui_priv *this, struct widget *wm, void *data) -{ - struct attr mattr; - GList *l; - navit_get_attr(this->nav, attr_bookmarks, &mattr, NULL); - bookmarks_delete_bookmark(mattr.u.bookmarks,wm->text); - l=g_list_previous(g_list_previous(g_list_last(this->root.children))); - gui_internal_prune_menu(this, l->data); +static void gui_internal_cmd_delete_bookmark(struct gui_priv *this, struct widget *wm, void *data) { + struct attr mattr; + GList *l; + navit_get_attr(this->nav, attr_bookmarks, &mattr, NULL); + bookmarks_delete_bookmark(mattr.u.bookmarks,wm->text); + l=g_list_previous(g_list_previous(g_list_last(this->root.children))); + gui_internal_prune_menu(this, l->data); } /** - * Get a utf-8 string, return the same prepared for case insensitive search. Result should be g_free()d after use. + * @brief Remove the case in a string + * + * @warning Result should be g_free()d after use. + * + * @param s The input utf-8 string + * @return An equivalent string prepared for case insensitive search + */ +char *removecase(char *s) { + char *r; + r=linguistics_casefold(s); + return r; +} + +/** + * @brief Apply the command "View on Map", centers the map on the selected point and highlight this point using + * type_found_item style + * + * @param this The GUI context + * @param wm The widget that points to this function as a callback + * @param data Private data provided during callback (unused) */ -char * -removecase(char *s) -{ - char *r; - r=linguistics_casefold(s); - return r; -} - -static void -gui_internal_cmd_view_on_map(struct gui_priv *this, struct widget *wm, void *data) -{ - if (wm->item.type != type_none) { - enum item_type type; - if (wm->item.type < type_line) - type=type_selected_point; - else if (wm->item.type < type_area) - type=type_selected_point; - else - type=type_selected_area; - graphics_clear_selection(this->gra, NULL); - graphics_add_selection(this->gra, &wm->item, type, NULL); - } - navit_set_center(this->nav, &wm->c, 1); - gui_internal_prune_menu(this, NULL); -} - - -static void -gui_internal_cmd_view_attribute_details(struct gui_priv *this, struct widget *wm, void *data) -{ - struct widget *w,*wb; - struct map_rect *mr; - struct item *item; - struct attr attr; - char *text,*url; - int i; - - text=g_strdup_printf("Attribute %s",wm->name); - wb=gui_internal_menu(this, text); - g_free(text); - w=gui_internal_box_new(this, gravity_top_center|orientation_vertical|flags_expand|flags_fill); - gui_internal_widget_append(wb, w); - mr=map_rect_new(wm->item.map, NULL); - item = map_rect_get_item_byid(mr, wm->item.id_hi, wm->item.id_lo); - for (i = 0 ; i < wm->datai ; i++) { - item_attr_get(item, attr_any, &attr); - } - if (item_attr_get(item, attr_any, &attr)) { - url=NULL; - switch (attr.type) { - case attr_osm_nodeid: - url=g_strdup_printf("http://www.openstreetmap.org/browse/node/"LONGLONG_FMT"\n",*attr.u.num64); - break; - case attr_osm_wayid: - url=g_strdup_printf("http://www.openstreetmap.org/browse/way/"LONGLONG_FMT"\n",*attr.u.num64); - break; - case attr_osm_relationid: - url=g_strdup_printf("http://www.openstreetmap.org/browse/relation/"LONGLONG_FMT"\n",*attr.u.num64); - break; - default: - break; - } - if (url) { - gui_internal_widget_append(w, - wb=gui_internal_button_new_with_callback(this, _("View in Browser"), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_view_in_browser, NULL)); - wb->name=url; - } - } - map_rect_destroy(mr); - gui_internal_menu_render(this); -} - -static void -gui_internal_cmd_view_attributes(struct gui_priv *this, struct widget *wm, void *data) -{ - struct widget *w,*wb; - struct map_rect *mr; - struct item *item; - struct attr attr; - char *text; - int count=0; - - dbg(lvl_info,"item=%p 0x%x 0x%x\n", wm->item.map,wm->item.id_hi, wm->item.id_lo); - wb=gui_internal_menu(this, "Attributes"); - w=gui_internal_box_new(this, gravity_top_center|orientation_vertical|flags_expand|flags_fill); - gui_internal_widget_append(wb, w); - mr=map_rect_new(wm->item.map, NULL); - item = map_rect_get_item_byid(mr, wm->item.id_hi, wm->item.id_lo); - dbg(lvl_info,"item=%p\n", item); - if (item) { - text=g_strdup_printf("%s:%s", _("Item type"), item_to_name(item->type)); - gui_internal_widget_append(w, - wb=gui_internal_button_new(this, text, - NULL, gravity_left_center|orientation_horizontal|flags_fill)); - wb->name=g_strdup(text); - wb->item=wm->item; - g_free(text); - while(item_attr_get(item, attr_any, &attr)) { - char *attrtxt; - text=g_strdup_printf("%s:%s", attr_to_name(attr.type), attrtxt=attr_to_text(&attr, wm->item.map, 1)); - g_free(attrtxt); - gui_internal_widget_append(w, - wb=gui_internal_button_new_with_callback(this, text, - NULL, gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_view_attribute_details, NULL)); - wb->name=g_strdup(text); - wb->item=wm->item; - wb->datai=count++; - g_free(text); - } - text=g_strdup_printf("%s:0x%x,0x%x", "ID", item->id_hi, item->id_lo); - gui_internal_widget_append(w, - wb=gui_internal_button_new(this, text, - NULL, gravity_left_center|orientation_horizontal|flags_fill)); - wb->name=text; - wb->item=wm->item; - } - map_rect_destroy(mr); - gui_internal_menu_render(this); -} - -static void -gui_internal_cmd_view_in_browser(struct gui_priv *this, struct widget *wm, void *data) -{ - struct map_rect *mr; - struct item *item; - struct attr attr; - char *cmd=NULL; - - if (!wm->name) { - dbg(lvl_info,"item=%p 0x%x 0x%x\n", wm->item.map,wm->item.id_hi, wm->item.id_lo); - mr=map_rect_new(wm->item.map, NULL); - item = map_rect_get_item_byid(mr, wm->item.id_hi, wm->item.id_lo); - dbg(lvl_info,"item=%p\n", item); - if (item) { - while(item_attr_get(item, attr_url_local, &attr)) { - if (! cmd) - cmd=g_strdup_printf("navit-browser.sh '%s' &",map_convert_string_tmp(item->map,attr.u.str)); - } - } - map_rect_destroy(mr); - } else { - cmd=g_strdup_printf("navit-browser.sh '%s' &",wm->name); - } - if (cmd) { +static void gui_internal_cmd_view_on_map(struct gui_priv *this, struct widget *wm, void *data) { + + struct widget *w; + struct widget *wr; + struct widget *wi; + char *label; + + if (wm->item.type != type_none) { + enum item_type type; + if (wm->item.type < type_line) + type=type_selected_point; + else if (wm->item.type < type_area) + type=type_selected_point; + else + type=type_selected_area; + graphics_clear_selection(this->gra, NULL); + graphics_add_selection(this->gra, &wm->item, type, NULL); + } else { + if (wm->item.priv_data) + label = wm->item.priv_data; /* Use the label of the point to view on map */ + else + label = g_strdup(""); + w = gui_internal_widget_table_new(this, 0, 0); /* Create a basic table */ + gui_internal_widget_append(w,wr=gui_internal_widget_table_row_new(this,0)); /* In this table, add one row */ + gui_internal_widget_append(wr,wi=gui_internal_box_new_with_label(this,0, + label)); /* That row contains a widget of type widget_box */ + wi->name = label; /* Use the label of the point to view on map */ + wi->c.x=wm->c.x; /* Use the coordinates of the point to place it on the map */ + wi->c.y=wm->c.y; + gui_internal_prepare_search_results_map(this, w, NULL); + g_free(label); + wi->name = NULL; + gui_internal_widget_destroy(this, w); + } + navit_set_center(this->nav, &wm->c, 1); + gui_internal_prune_menu(this, NULL); +} + + +static void gui_internal_cmd_view_attribute_details(struct gui_priv *this, struct widget *wm, void *data) { + struct widget *w,*wb; + struct map_rect *mr; + struct item *item; + struct attr attr; + char *text,*url; + int i; + + text=g_strdup_printf("Attribute %s",wm->name); + wb=gui_internal_menu(this, text); + g_free(text); + w=gui_internal_box_new(this, gravity_top_center|orientation_vertical|flags_expand|flags_fill); + gui_internal_widget_append(wb, w); + mr=map_rect_new(wm->item.map, NULL); + item = map_rect_get_item_byid(mr, wm->item.id_hi, wm->item.id_lo); + for (i = 0 ; i < wm->datai ; i++) { + item_attr_get(item, attr_any, &attr); + } + if (item_attr_get(item, attr_any, &attr)) { + url=NULL; + switch (attr.type) { + case attr_osm_nodeid: + url=g_strdup_printf("http://www.openstreetmap.org/browse/node/"LONGLONG_FMT"\n",*attr.u.num64); + break; + case attr_osm_wayid: + url=g_strdup_printf("http://www.openstreetmap.org/browse/way/"LONGLONG_FMT"\n",*attr.u.num64); + break; + case attr_osm_relationid: + url=g_strdup_printf("http://www.openstreetmap.org/browse/relation/"LONGLONG_FMT"\n",*attr.u.num64); + break; + default: + break; + } + if (url) { + gui_internal_widget_append(w, + wb=gui_internal_button_new_with_callback(this, _("View in Browser"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_view_in_browser, NULL)); + wb->name=url; + } + } + map_rect_destroy(mr); + gui_internal_menu_render(this); +} + +static void gui_internal_cmd_view_attributes(struct gui_priv *this, struct widget *wm, void *data) { + struct widget *w,*wb; + struct map_rect *mr; + struct item *item; + struct attr attr; + char *text; + int count=0; + + dbg(lvl_info,"item=%p 0x%x 0x%x", wm->item.map,wm->item.id_hi, wm->item.id_lo); + wb=gui_internal_menu(this, "Attributes"); + w=gui_internal_box_new(this, gravity_top_center|orientation_vertical|flags_expand|flags_fill); + gui_internal_widget_append(wb, w); + mr=map_rect_new(wm->item.map, NULL); + item = map_rect_get_item_byid(mr, wm->item.id_hi, wm->item.id_lo); + dbg(lvl_info,"item=%p", item); + if (item) { + text=g_strdup_printf("%s:%s", _("Item type"), item_to_name(item->type)); + gui_internal_widget_append(w, + wb=gui_internal_button_new(this, text, + NULL, gravity_left_center|orientation_horizontal|flags_fill)); + wb->name=g_strdup(text); + wb->item=wm->item; + g_free(text); + while(item_attr_get(item, attr_any, &attr)) { + char *attrtxt; + text=g_strdup_printf("%s:%s", attr_to_name(attr.type), attrtxt=attr_to_text(&attr, wm->item.map, 1)); + g_free(attrtxt); + gui_internal_widget_append(w, + wb=gui_internal_button_new_with_callback(this, text, + NULL, gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_view_attribute_details, NULL)); + wb->name=g_strdup(text); + wb->item=wm->item; + wb->datai=count++; + g_free(text); + } + text=g_strdup_printf("%s:0x%x,0x%x", "ID", item->id_hi, item->id_lo); + gui_internal_widget_append(w, + wb=gui_internal_button_new(this, text, + NULL, gravity_left_center|orientation_horizontal|flags_fill)); + wb->name=text; + wb->item=wm->item; + } + map_rect_destroy(mr); + gui_internal_menu_render(this); +} + +static void gui_internal_cmd_view_in_browser(struct gui_priv *this, struct widget *wm, void *data) { + struct map_rect *mr; + struct item *item; + struct attr attr; + char *cmd=NULL; + + if (!wm->name) { + dbg(lvl_info,"item=%p 0x%x 0x%x", wm->item.map,wm->item.id_hi, wm->item.id_lo); + mr=map_rect_new(wm->item.map, NULL); + item = map_rect_get_item_byid(mr, wm->item.id_hi, wm->item.id_lo); + dbg(lvl_info,"item=%p", item); + if (item) { + while(item_attr_get(item, attr_url_local, &attr)) { + if (! cmd) + cmd=g_strdup_printf("navit-browser.sh '%s' &",map_convert_string_tmp(item->map,attr.u.str)); + } + } + map_rect_destroy(mr); + } else { + cmd=g_strdup_printf("navit-browser.sh '%s' &",wm->name); + } + if (cmd) { #ifdef HAVE_SYSTEM - system(cmd); + system(cmd); #else - dbg(lvl_error,"Error: External commands were disabled during compilation, cannot call '%s'.\n",cmd); + dbg(lvl_error,"Error: External commands were disabled during compilation, cannot call '%s'.",cmd); #endif - g_free(cmd); - } + g_free(cmd); + } } +/** + * @brief Create a map rect highlighting one of multiple points provided in argument @data and displayed using + * the style type_found_item (name for each point will also be displayed aside) + * + * @param this The GUI context + * @param table A table widget or any of its descendants. The table contain results to place on the map. + * Providing NULL here will remove all previous results from the map. + * @param[out] r The minimum rect focused to contain all results placed on the map (or unchanged if r==NULL) + */ +static void gui_internal_prepare_search_results_map(struct gui_priv *this, struct widget *table, struct coord_rect *r) { + struct widget *w; + GList *l; /* Cursor in the list of widgets */ + GList* list = NULL; /* List we will create to store the points to add to the result map */ + struct attr a; + GList* p; + + this->results_map_population=0; + + /* Find the table to populate the map */ + for(w=table; w && w->type!=widget_table; w=w->parent); + + if(!w) { + dbg(lvl_warning,"Can't find the results table - only map clean up is done."); + } else { + /* Create a GList containing all search results */ + for(l=w->children; l; l=g_list_next(l)) { + struct widget *wr=l->data; + if(wr->type==widget_table_row) { + struct widget *wi=wr->children->data; + if(wi->name==NULL) + continue; + struct lcoord *result = g_new0(struct lcoord, 1); + result->c.x=wi->c.x; + result->c.y=wi->c.y; + result->label=g_strdup(wi->name); + list = g_list_prepend(list, result); + } + } + } + this->results_map_population=navit_populate_search_results_map(this->nav, list, r); + /* Parse the GList starting at list and free all payloads before freeing the list itself */ + if (list) { + for(p=list; p; p=g_list_next(p)) { + if (((struct lcoord *)(p->data))->label) + g_free(((struct lcoord *)(p->data))->label); + } + } + g_list_free(list); + if(!this->results_map_population) + return; + a.type=attr_orientation; + a.u.num=0; + navit_set_attr(this->nav,&a); /* Set orientation to North */ + if (r) { + navit_zoom_to_rect(this->nav,r); + gui_internal_prune_menu(this, NULL); + } +} -/* - * @brief Transfers search results to a map. +/** + * @brief Apply the command "Show results on the map", highlighting one of multiple points using + * type_found_item style (with their respective name placed aside) * - * @param this The graphics context. - * @param wm called widget. - * @param data event data (pointer to the table widget containing results, or NULL to clean the result map without adding any new data). + * @param this The GUI context + * @param wm The widget that called us + * @param data Private data provided during callback (should be a pointer to the table widget containing results, + * or NULL to remove all previous results from the map). */ -static void -gui_internal_cmd_results_to_map(struct gui_priv *this, struct widget *wm, void *data) -{ - struct widget *w; - struct mapset *ms; - struct map *map; - struct map_rect *mr; - struct item *item; - GList *l; - struct coord_rect r; - struct attr a; - int count; - - ms=navit_get_mapset(this->nav); - - if(!ms) - return; - - map=mapset_get_map_by_name(ms, "search_results"); - if(!map) { - struct attr *attrs[10], attrmap; - enum attr_type types[]={attr_position_longitude,attr_position_latitude,attr_label,attr_none}; - int i; - - attrs[0]=g_new0(struct attr,1); - attrs[0]->type=attr_type; - attrs[0]->u.str="csv"; - - attrs[1]=g_new0(struct attr,1); - attrs[1]->type=attr_name; - attrs[1]->u.str="search_results"; - - attrs[2]=g_new0(struct attr,1); - attrs[2]->type=attr_charset; - attrs[2]->u.str="utf-8"; - - attrs[3]=g_new0(struct attr,1); - attrs[3]->type=attr_item_type; - attrs[3]->u.num=type_found_item; - - attrs[4]=g_new0(struct attr,1); - attrs[4]->type=attr_attr_types; - attrs[4]->u.attr_types=types; - attrs[5]=NULL; - - attrmap.type=attr_map; - map=attrmap.u.map=map_new(NULL,attrs); - if(map) - mapset_add_attr(ms,&attrmap); - - for(i=0;attrs[i];i++) - g_free(attrs[i]); - - } - - if(!map) - return; - - - mr = map_rect_new(map, NULL); - - if(!mr) - return; - - /* Clean the map */ - while((item = map_rect_get_item(mr))!=NULL) { - item_type_set(item,type_none); - } - - this->results_map_population=0; - - /* Find the table to pupulate the map */ - for(w=data; w && w->type!=widget_table;w=w->parent); - - if(!w) { - map_rect_destroy(mr); - dbg(lvl_warning,"Can't find the results table - only map clean up is done.\n"); - return; - } - - /* Populate the map with search results*/ - for(l=w->children, count=0;l;l=g_list_next(l)) { - struct widget *wr=l->data; - if(wr->type==widget_table_row) { - struct widget *wi=wr->children->data; - struct item* it; - if(wi->name==NULL) - continue; - dbg(lvl_info,"%s\n",wi->name); - it=map_rect_create_item(mr,type_found_item); - if(it) { - struct coord c; - struct attr a; - c.x=wi->c.x; - c.y=wi->c.y; - item_coord_set(it, &c, 1, change_mode_modify); - a.type=attr_label; - a.u.str=wi->name; - item_attr_set(it, &a, change_mode_modify); - if(!count++) - r.lu=r.rl=c; - else - coord_rect_extend(&r,&c); - } - } - } - map_rect_destroy(mr); - if(!count) - return; - a.type=attr_orientation; - a.u.num=0; - navit_set_attr(this->nav,&a); - navit_zoom_to_rect(this->nav,&r); - gui_internal_prune_menu(this, NULL); - this->results_map_population=count; +static void gui_internal_cmd_results_to_map(struct gui_priv *this, struct widget *wm, void *data) { + struct coord_rect r; + + gui_internal_prepare_search_results_map(this, (struct widget *)data, &r); } /* - * @brief Removes search results from a map. + * @brief Removes all existing search results from a map. * - * @param this The graphics context. - * @param wm called widget. - * @param data event data + * @param this The GUI context + * @param wm The widget that called us + * @param data Private data (unused). */ -static void -gui_internal_cmd_results_map_clean(struct gui_priv *this, struct widget *wm, void *data) -{ - gui_internal_cmd_results_to_map(this,wm,NULL); - gui_internal_prune_menu(this, NULL); - navit_draw(this->nav); -} - -static void -gui_internal_cmd_delete_waypoint(struct gui_priv *this, struct widget *wm, void *data) -{ - int dstcount=navit_get_destination_count(this->nav); - int i; - struct map_rect *mr; - struct item *item; - struct pcoord *dst=g_alloca(dstcount*sizeof(struct pcoord)); - dstcount=navit_get_destinations(this->nav,dst,dstcount); - mr=map_rect_new(wm->item.map, NULL); - i=0; - while((item=map_rect_get_item(mr))!=NULL) { - struct coord c; - if(item->type!=type_waypoint && item->type!=type_route_end) - continue; - if(item_is_equal_id(*item,wm->item)) - continue; - item_coord_get_pro(item,&c,1,projection_mg); - dst[i].x=c.x; - dst[i].y=c.y; - dst[i].pro=projection_mg; - i++; - } - map_rect_destroy(mr); - navit_set_destinations(this->nav,dst,i,NULL,1); - gui_internal_prune_menu(this, NULL); +static void gui_internal_cmd_results_map_clean(struct gui_priv *this, struct widget *wm, void *data) { + gui_internal_cmd_results_to_map(this,wm,NULL); + gui_internal_prune_menu(this, NULL); + navit_draw(this->nav); +} + +static void gui_internal_cmd_delete_waypoint(struct gui_priv *this, struct widget *wm, void *data) { + int dstcount=navit_get_destination_count(this->nav); + int i; + struct map_rect *mr; + struct item *item; + struct pcoord *dst=g_alloca(dstcount*sizeof(struct pcoord)); + dstcount=navit_get_destinations(this->nav,dst,dstcount); + mr=map_rect_new(wm->item.map, NULL); + i=0; + while((item=map_rect_get_item(mr))!=NULL) { + struct coord c; + if(item->type!=type_waypoint && item->type!=type_route_end) + continue; + if(item_is_equal_id(*item,wm->item)) + continue; + item_coord_get_pro(item,&c,1,projection_mg); + dst[i].x=c.x; + dst[i].y=c.y; + dst[i].pro=projection_mg; + i++; + } + map_rect_destroy(mr); + navit_set_destinations(this->nav,dst,i,NULL,1); + gui_internal_prune_menu(this, NULL); } @@ -1097,10 +1016,10 @@ gui_internal_cmd_delete_waypoint(struct gui_priv *this, struct widget *wm, void * argument or in WGS84 coordinates (i.e. latitude and longitude in degrees) via the {@code g_in} * argument. One of these must be supplied, the other should be {@code NULL}. * - * @param this The internal GUI instance + * @param this The GUI context * @param pc_in Projected coordinates of the position * @param g_in WGS84 coordinates of the position - * @param wm + * @param wm The widget that points to this function as a callback * @param name The display name for the position * @param flags Flags specifying the operations available from the GUI */ @@ -1119,275 +1038,296 @@ gui_internal_cmd_delete_waypoint(struct gui_priv *this, struct widget *wm, void * 2048: "Show search results on the map" * TODO define constants for these values */ -void -gui_internal_cmd_position_do(struct gui_priv *this, struct pcoord *pc_in, struct coord_geo *g_in, struct widget *wm, const char *name, int flags) -{ - struct widget *wb,*w,*wtable,*row,*wc,*wbc,*wclosest=NULL; - struct coord_geo g; - struct pcoord pc; - struct coord c; - char *coord; - - if (pc_in) { - pc=*pc_in; - c.x=pc.x; - c.y=pc.y; - dbg(lvl_info,"x=0x%x y=0x%x\n", c.x, c.y); - transform_to_geo(pc.pro, &c, &g); - } else if (g_in) { - struct attr attr; - if (!navit_get_attr(this->nav, attr_projection, &attr, NULL)) - return; - g=*g_in; - pc.pro=attr.u.projection; - transform_from_geo(pc.pro, &g, &c); - pc.x=c.x; - pc.y=c.y; - } else - return; - - wb=gui_internal_menu(this, name); - w=gui_internal_box_new(this, gravity_top_center|orientation_vertical|flags_expand|flags_fill); - gui_internal_widget_append(wb, w); - coord=gui_internal_coordinates(&pc, ' '); - gui_internal_widget_append(w, gui_internal_label_new(this, coord)); - g_free(coord); - wtable = gui_internal_widget_table_new(this,gravity_left_top | flags_fill | flags_expand |orientation_vertical,1); - gui_internal_widget_append(w,wtable); - - if ((flags & 1) && wm) { - gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); - gui_internal_widget_append(row, - wc=gui_internal_button_new_with_callback(this, _("Streets"), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_search_street_in_town, wm)); - wc->item=wm->item; - wc->selection_id=wm->selection_id; - } - if ((flags & 2) && wm) { - gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); - gui_internal_widget_append(row, - wc=gui_internal_button_new_with_callback(this, _("House numbers"), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_search_house_number_in_street, wm)); - wc->item=wm->item; - wc->selection_id=wm->selection_id; - } - if ((flags & 4) && wm) { - struct map_rect *mr; - struct item *item; - struct attr attr; - mr=map_rect_new(wm->item.map, NULL); - item = map_rect_get_item_byid(mr, wm->item.id_hi, wm->item.id_lo); - if (item) { - if (item_attr_get(item, attr_description, &attr)) - gui_internal_widget_append(w, gui_internal_label_new(this, map_convert_string_tmp(item->map,attr.u.str))); - if (item_attr_get(item, attr_url_local, &attr)) { - gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); - gui_internal_widget_append(row, - wb=gui_internal_button_new_with_callback(this, _("View in Browser"), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_view_in_browser, NULL)); - wb->item=wm->item; - } - gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); - gui_internal_widget_append(row, - wb=gui_internal_button_new_with_callback(this, _("View Attributes"), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_view_attributes, NULL)); - wb->item=wm->item; - } - map_rect_destroy(mr); - } - if (flags & 8) { - gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); - gui_internal_widget_append(row, - wbc=gui_internal_button_new_with_callback(this, _("Set as destination"), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_set_destination, g_strdup(name))); - wbc->data_free=g_free_func; - wbc->c=pc; - if(navit_get_destination_count(this->nav)>=1) { - gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); - gui_internal_widget_append(row, - wbc=gui_internal_button_new_with_callback(this, _("Visit before..."), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_insert_destination, g_strdup(name))); - wbc->data_free=g_free_func; - wbc->c=pc; - } - } - if (flags & 16) { - const char *text; - struct attr vehicle, source; - int deactivate=0; - if (navit_get_attr(this->nav, attr_vehicle, &vehicle, NULL) && vehicle.u.vehicle && - !(vehicle_get_attr(vehicle.u.vehicle, attr_source, &source, NULL) && source.u.str && !strcmp("demo://",source.u.str))) - deactivate=1; - - text=deactivate? _("Set as position (and deactivate vehicle)") : _("Set as position"); - - gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); - gui_internal_widget_append(row, - wbc=gui_internal_button_new_with_callback(this, text, - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_set_position, (void*)(long)deactivate)); - wbc->c=pc; - } - if (flags & 32) { - gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); - gui_internal_widget_append(row, - wbc=gui_internal_button_new_with_callback(this, _("Add as bookmark"), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_add_bookmark2, g_strdup(name))); - wbc->data_free=g_free_func; - wbc->c=pc; - } +void gui_internal_cmd_position_do(struct gui_priv *this, struct pcoord *pc_in, struct coord_geo *g_in, + struct widget *wm, const char *name, int flags) { + struct widget *wb,*w,*wtable,*row,*wc,*wbc,*wclosest=NULL; + struct coord_geo g; + struct pcoord pc; + struct coord c; + char *coord; + + if (pc_in) { + pc=*pc_in; + c.x=pc.x; + c.y=pc.y; + dbg(lvl_info,"x=0x%x y=0x%x", c.x, c.y); + transform_to_geo(pc.pro, &c, &g); + } else if (g_in) { + struct attr attr; + if (!navit_get_attr(this->nav, attr_projection, &attr, NULL)) + return; + g=*g_in; + pc.pro=attr.u.projection; + transform_from_geo(pc.pro, &g, &c); + pc.x=c.x; + pc.y=c.y; + } else + return; + + wb=gui_internal_menu(this, name); + w=gui_internal_box_new(this, gravity_top_center|orientation_vertical|flags_expand|flags_fill); + gui_internal_widget_append(wb, w); + coord=gui_internal_coordinates(&pc, ' '); + gui_internal_widget_append(w, gui_internal_label_new(this, coord)); + g_free(coord); + wtable = gui_internal_widget_table_new(this,gravity_left_top | flags_fill | flags_expand |orientation_vertical,1); + gui_internal_widget_append(w,wtable); + + if ((flags & 1) && wm) { + gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this, + gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, + wc=gui_internal_button_new_with_callback(this, _("Streets"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_search_street_in_town, wm)); + wc->item=wm->item; + wc->selection_id=wm->selection_id; + } + if ((flags & 2) && wm) { + gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this, + gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, + wc=gui_internal_button_new_with_callback(this, _("House numbers"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_search_house_number_in_street, wm)); + wc->item=wm->item; + wc->selection_id=wm->selection_id; + } + if ((flags & 4) && wm) { + struct map_rect *mr; + struct item *item; + struct attr attr; + mr=map_rect_new(wm->item.map, NULL); + item = map_rect_get_item_byid(mr, wm->item.id_hi, wm->item.id_lo); + if (item) { + if (item_attr_get(item, attr_description, &attr)) + gui_internal_widget_append(w, gui_internal_label_new(this, map_convert_string_tmp(item->map,attr.u.str))); + if (item_attr_get(item, attr_url_local, &attr)) { + gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this, + gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, + wb=gui_internal_button_new_with_callback(this, _("View in Browser"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_view_in_browser, NULL)); + wb->item=wm->item; + } + gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this, + gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, + wb=gui_internal_button_new_with_callback(this, _("View Attributes"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_view_attributes, NULL)); + wb->item=wm->item; + } + map_rect_destroy(mr); + } + if (flags & 8) { + gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this, + gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, + wbc=gui_internal_button_new_with_callback(this, _("Set as destination"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_set_destination, g_strdup(name))); + wbc->data_free=g_free_func; + wbc->c=pc; + if(navit_get_destination_count(this->nav)>=1) { + gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this, + gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, + wbc=gui_internal_button_new_with_callback(this, _("Visit before..."), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_insert_destination, g_strdup(name))); + wbc->data_free=g_free_func; + wbc->c=pc; + } + } + if (flags & 16) { + const char *text; + struct attr vehicle, source; + int deactivate=0; + if (navit_get_attr(this->nav, attr_vehicle, &vehicle, NULL) && vehicle.u.vehicle && + !(vehicle_get_attr(vehicle.u.vehicle, attr_source, &source, NULL) && source.u.str && !strcmp("demo://",source.u.str))) + deactivate=1; + + text=deactivate? _("Set as position (and deactivate vehicle)") : _("Set as position"); + + gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this, + gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, + wbc=gui_internal_button_new_with_callback(this, text, + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_set_position, (void*)(long)deactivate)); + wbc->c=pc; + } + if (flags & 32) { + gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this, + gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, + wbc=gui_internal_button_new_with_callback(this, _("Add as bookmark"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_add_bookmark2, g_strdup(name))); + wbc->data_free=g_free_func; + wbc->c=pc; + } #ifndef _MSC_VER //POIs are not operational under MSVC yet - if (flags & 64) { - gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); - gui_internal_widget_append(row, - wbc=gui_internal_button_new_with_callback(this, _("POIs"), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_pois, NULL)); - wbc->c=pc; - } + if (flags & 64) { + gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this, + gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, + wbc=gui_internal_button_new_with_callback(this, _("POIs"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_pois, NULL)); + wbc->c=pc; + } #endif /* _MSC_VER */ #if 0 - gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); - gui_internal_widget_append(row, - gui_internal_button_new(this, "Add to tour", - image_new_o(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill)); + gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this, + gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, + gui_internal_button_new(this, "Add to tour", + image_new_o(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill)); #endif - if (flags & 128) { - gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); - gui_internal_widget_append(row, - wbc=gui_internal_button_new_with_callback(this, _("View on map"), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_view_on_map, NULL)); - wbc->c=pc; - if ((flags & 4) && wm) - wbc->item=wm->item; - else - wbc->item.type=type_none; - } - if(flags & 256 && this->results_map_population) { - gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); - gui_internal_widget_append(row, - wbc=gui_internal_button_new_with_callback(this, _("Remove search results from the map"), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_results_map_clean, NULL)); - wbc->data=wm; - } - if(flags & 2048) { - gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); - gui_internal_widget_append(row, - wbc=gui_internal_button_new_with_callback(this, _("Show results on the map"), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_results_to_map, NULL)); - wbc->data=wm; - } - if ((flags & 256) || (flags & 1024)) { - struct displaylist_handle *dlh; - struct displaylist *display; - struct attr attr; - struct point p; - struct transformation *trans; - - char *text; - struct map_selection *sel; - GList *l, *ll; - - c.x=pc.x; - c.y=pc.y; - - trans=navit_get_trans(this->nav); - transform(trans,pc.pro,&c,&p,1,0,0,0); - display=navit_get_displaylist(this->nav); - dlh=graphics_displaylist_open(display); - sel=displaylist_get_selection(display); - l=displaylist_get_clicked_list(display, &p, this->radius); - for(ll=l;ll;ll=g_list_next(ll)) { - struct displayitem *di; - struct item *item; - struct map_rect *mr; - struct item *itemo; - - di=(struct displayitem*)ll->data; - item=graphics_displayitem_get_item(di); - - mr=map_rect_new(item->map, sel); - itemo=map_rect_get_item_byid(mr, item->id_hi, item->id_lo); - if(!itemo) { - map_rect_destroy(mr); - continue; - } - if (item_attr_get(itemo, attr_label, &attr)) { - text=g_strdup(map_convert_string_tmp(itemo->map, attr.u.str)); - } else - text=g_strdup(item_to_name(item->type)); - gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); - gui_internal_widget_append(row, wc=gui_internal_cmd_pois_item(this, NULL, itemo, NULL, NULL, -1, text)); - wc->c=pc; - g_free(wc->name); - wc->name=g_strdup(text); - wc->item=*itemo; - g_free(text); - map_rect_destroy(mr); - if(!wclosest) - wclosest=wc; - - } - g_list_free(l); - map_selection_destroy(sel); - graphics_displaylist_close(dlh); - } - if (flags & 512) { - gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); - gui_internal_widget_append(row, - wbc=gui_internal_button_new_with_callback(this, _("Cut Bookmark"), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_cut_bookmark, NULL)); - wbc->text=g_strdup(wm->text); - gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); - gui_internal_widget_append(row, - wbc=gui_internal_button_new_with_callback(this, _("Copy Bookmark"), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_copy_bookmark, NULL)); - wbc->text=g_strdup(wm->text); - gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); - gui_internal_widget_append(row, - wbc=gui_internal_button_new_with_callback(this, _("Rename Bookmark"), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_rename_bookmark, NULL)); - wbc->text=g_strdup(wm->text); - gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); - gui_internal_widget_append(row, - wbc=gui_internal_button_new_with_callback(this, _("Paste Bookmark"), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_paste_bookmark, NULL)); - gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); - gui_internal_widget_append(row, - wbc=gui_internal_button_new_with_callback(this, _("Delete Bookmark"), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_delete_bookmark, NULL)); - wbc->text=g_strdup(wm->text); - } - - if (wm && (wm->item.type==type_waypoint || wm->item.type==type_route_end)) { - gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); - gui_internal_widget_append(row, - wbc=gui_internal_button_new_with_callback(this, _("Delete waypoint"), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_delete_waypoint, NULL)); - wbc->item=wm->item; - } - - gui_internal_menu_render(this); - - if((flags & 1024) && wclosest) - gui_internal_cmd_view_attributes(this,wclosest,wclosest->data); + if (flags & 128) { + gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this, + gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, + wbc=gui_internal_button_new_with_callback(this, _("View on map"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_view_on_map, NULL)); + wbc->c=pc; + if ((flags & 4) && wm) { + wbc->item=wm->item; + } else { + wbc->item.type=type_none; + wbc->item.priv_data = g_strdup(name); /* Will be freed up by gui_internal_cmd_view_on_map() */ + } + } + if(flags & 256 && this->results_map_population) { + gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this, + gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, + wbc=gui_internal_button_new_with_callback(this, _("Remove search results from the map"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_results_map_clean, NULL)); + wbc->data=wm; + } + if(flags & 2048) { + gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this, + gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, + wbc=gui_internal_button_new_with_callback(this, _("Show results on the map"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_results_to_map, NULL)); + wbc->data=wm; + } + if ((flags & 256) || (flags & 1024)) { + struct displaylist_handle *dlh; + struct displaylist *display; + struct attr attr; + struct point p; + struct transformation *trans; + + char *text; + struct map_selection *sel; + GList *l, *ll; + + c.x=pc.x; + c.y=pc.y; + + trans=navit_get_trans(this->nav); + transform(trans,pc.pro,&c,&p,1,0,0,0); + display=navit_get_displaylist(this->nav); + dlh=graphics_displaylist_open(display); + sel=displaylist_get_selection(display); + l=displaylist_get_clicked_list(display, &p, this->radius); + for(ll=l; ll; ll=g_list_next(ll)) { + struct displayitem *di; + struct item *item; + struct map_rect *mr; + struct item *itemo; + + di=(struct displayitem*)ll->data; + item=graphics_displayitem_get_item(di); + + mr=map_rect_new(item->map, sel); + itemo=map_rect_get_item_byid(mr, item->id_hi, item->id_lo); + if(!itemo) { + map_rect_destroy(mr); + continue; + } + if (item_attr_get(itemo, attr_label, &attr)) { + text=g_strdup(map_convert_string_tmp(itemo->map, attr.u.str)); + } else + text=g_strdup(item_to_name(item->type)); + gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this, + gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, wc=gui_internal_cmd_pois_item(this, NULL, itemo, NULL, NULL, -1, text)); + wc->c=pc; + g_free(wc->name); + wc->name=g_strdup(text); + wc->item=*itemo; + g_free(text); + map_rect_destroy(mr); + if(!wclosest) + wclosest=wc; + + } + g_list_free(l); + map_selection_destroy(sel); + graphics_displaylist_close(dlh); + } + if (flags & 512) { + gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this, + gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, + wbc=gui_internal_button_new_with_callback(this, _("Cut Bookmark"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_cut_bookmark, NULL)); + wbc->text=g_strdup(wm->text); + gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this, + gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, + wbc=gui_internal_button_new_with_callback(this, _("Copy Bookmark"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_copy_bookmark, NULL)); + wbc->text=g_strdup(wm->text); + gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this, + gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, + wbc=gui_internal_button_new_with_callback(this, _("Rename Bookmark"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_rename_bookmark, NULL)); + wbc->text=g_strdup(wm->text); + gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this, + gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, + wbc=gui_internal_button_new_with_callback(this, _("Paste Bookmark"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_paste_bookmark, NULL)); + gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this, + gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, + wbc=gui_internal_button_new_with_callback(this, _("Delete Bookmark"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_delete_bookmark, NULL)); + wbc->text=g_strdup(wm->text); + } + + if (wm && (wm->item.type==type_waypoint || wm->item.type==type_route_end)) { + gui_internal_widget_append(wtable,row=gui_internal_widget_table_row_new(this, + gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, + wbc=gui_internal_button_new_with_callback(this, _("Delete waypoint"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_delete_waypoint, NULL)); + wbc->item=wm->item; + } + + gui_internal_menu_render(this); + + if((flags & 1024) && wclosest) + gui_internal_cmd_view_attributes(this,wclosest,wclosest->data); } @@ -1403,60 +1343,58 @@ gui_internal_cmd_position_do(struct gui_priv *this, struct pcoord *pc_in, struct 9 Item from the POI list */ -void -gui_internal_cmd_position(struct gui_priv *this, struct widget *wm, void *data) -{ - int flags; - - if(!data) - data=wm->data; - - switch ((long) data) { - case 0: - flags=8|16|32|64|128|256; - break; - case 1: - flags=8|16|32|64|256; - break; - case 2: - flags=4|8|16|32|64|128; - break; - case 3: - flags=1|4|8|16|32|64|128|2048; - flags &= this->flags_town; - break; - case 4: - gui_internal_search_town_in_country(this, wm); - return; - case 5: - flags=2|8|16|32|64|128|2048; - flags &= this->flags_street; - break; - case 6: - flags=8|16|32|64|128|2048; - flags &= this->flags_house_number; - break; - case 7: - flags=8|16|64|128|512; - break; - case 8: - flags=8|16|32|64|128; - break; - case 9: - flags=4|8|16|32|64|128|2048; - break; - default: - return; - } - switch (flags) { - case 2: - gui_internal_search_house_number_in_street(this, wm, NULL); - return; - case 8: - gui_internal_cmd_set_destination(this, wm, NULL); - return; - } - gui_internal_cmd_position_do(this, &wm->c, NULL, wm, wm->name ? wm->name : wm->text, flags); +void gui_internal_cmd_position(struct gui_priv *this, struct widget *wm, void *data) { + int flags; + + if(!data) + data=wm->data; + + switch ((long) data) { + case 0: + flags=8|16|32|64|128|256; + break; + case 1: + flags=8|16|32|64|256; + break; + case 2: + flags=4|8|16|32|64|128; + break; + case 3: + flags=1|4|8|16|32|64|128|2048; + flags &= this->flags_town; + break; + case 4: + gui_internal_search_town_in_country(this, wm); + return; + case 5: + flags=2|8|16|32|64|128|2048; + flags &= this->flags_street; + break; + case 6: + flags=8|16|32|64|128|2048; + flags &= this->flags_house_number; + break; + case 7: + flags=8|16|64|128|512; + break; + case 8: + flags=8|16|32|64|128; + break; + case 9: + flags=4|8|16|32|64|128|2048; + break; + default: + return; + } + switch (flags) { + case 2: + gui_internal_search_house_number_in_street(this, wm, NULL); + return; + case 8: + gui_internal_cmd_set_destination(this, wm, NULL); + return; + } + gui_internal_cmd_position_do(this, &wm->c, NULL, wm, wm->name ? wm->name : wm->text, flags); } @@ -1465,515 +1403,490 @@ gui_internal_cmd_position(struct gui_priv *this, struct widget *wm, void *data) /** * The "Bookmarks" section of the OSD - * + * */ -void -gui_internal_cmd_bookmarks(struct gui_priv *this, struct widget *wm, void *data) -{ - struct attr attr,mattr; - struct item *item; - char *label_full,*prefix=0; - int plen=0,hassub,found=0; - struct widget *wb,*w,*wbm; - struct coord c; - struct widget *tbl, *row; - - if (data) - prefix=g_strdup(data); - else { - if (wm && wm->prefix) - prefix=g_strdup(wm->prefix); - } - if ( prefix ) - plen=strlen(prefix); - - gui_internal_prune_menu_count(this, 1, 0); - wb=gui_internal_menu(this, _("Bookmarks")); - wb->background=this->background; - w=gui_internal_box_new(this, gravity_top_center|orientation_vertical|flags_expand|flags_fill); - //w->spy=this->spacing*3; - gui_internal_widget_append(wb, w); - - if(navit_get_attr(this->nav, attr_bookmarks, &mattr, NULL) ) { - if (!plen) { - bookmarks_move_root(mattr.u.bookmarks); - } else { - if (!strcmp(prefix,"..")) { - bookmarks_move_up(mattr.u.bookmarks); - g_free(prefix); - prefix=g_strdup(bookmarks_item_cwd(mattr.u.bookmarks)); - if (prefix) { - plen=strlen(prefix); - } else { - plen=0; - } - } else { - bookmarks_move_down(mattr.u.bookmarks,prefix); - } - - // "Back" button, when inside a bookmark folder - - if (plen) { - wbm=gui_internal_button_new_with_callback(this, "..", - image_new_xs(this, "gui_inactive"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_bookmarks, NULL); - wbm->prefix=g_strdup(".."); - gui_internal_widget_append(w, wbm); - - // load bookmark folder as Waypoints, if any - if (bookmarks_get_bookmark_count(mattr.u.bookmarks) > 0){ - wbm=gui_internal_button_new_with_callback(this, _("Bookmarks as waypoints"), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_load_bookmarks_as_waypoints, NULL); - wbm->prefix=g_strdup(prefix); - gui_internal_widget_append(w, wbm); - } - - // save Waypoints in bookmark folder, if route exists - if (navit_get_destination_count(this->nav) > 0){ - if (bookmarks_get_bookmark_count(mattr.u.bookmarks)==0){ - wbm=gui_internal_button_new_with_callback(this, _("Save waypoints"), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_replace_bookmarks_from_waypoints, NULL); - }else{ - wbm=gui_internal_button_new_with_callback(this, _("Replace with waypoints"), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_replace_bookmarks_from_waypoints, NULL); - } - wbm->prefix=g_strdup(prefix); - gui_internal_widget_append(w, wbm); - } - - // delete empty folder - if (bookmarks_get_bookmark_count(mattr.u.bookmarks)==0){ - gui_internal_widget_append(w, - wbm=gui_internal_button_new_with_callback(this, _("Delete Folder"), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_delete_bookmark_folder, NULL)); - wbm->prefix=g_strdup(prefix); - } - - } - } - - // Adds the Bookmark folders - wbm=gui_internal_button_new_with_callback(this, _("Add Bookmark folder"), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_add_bookmark_folder2, NULL); - gui_internal_widget_append(w, wbm); - - // Pastes the Bookmark - wbm=gui_internal_button_new_with_callback(this, _("Paste bookmark"), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_paste_bookmark, NULL); - gui_internal_widget_append(w, wbm); - - bookmarks_item_rewind(mattr.u.bookmarks); - - tbl=gui_internal_widget_table_new(this,gravity_left_top | flags_fill | flags_expand |orientation_vertical,1); - gui_internal_widget_append(w,tbl); - - while ((item=bookmarks_get_item(mattr.u.bookmarks))) { - if (!item_attr_get(item, attr_label, &attr)) continue; - label_full=map_convert_string_tmp(item->map,attr.u.str); - dbg(lvl_info,"full_labled: %s\n",label_full); - - // hassub == 1 if the item type is a sub-folder - if (item->type == type_bookmark_folder) { - hassub=1; - } else { - hassub=0; - } - - row=gui_internal_widget_table_row_new(this,gravity_left| flags_fill| orientation_horizontal); - gui_internal_widget_append(tbl, row); - wbm=gui_internal_button_new_with_callback(this, label_full, - image_new_xs(this, hassub ? "gui_inactive" : "gui_active" ), gravity_left_center|orientation_horizontal|flags_fill, - hassub ? gui_internal_cmd_bookmarks : gui_internal_cmd_position, NULL); - - gui_internal_widget_append(row,wbm); - if (item_coord_get(item, &c, 1)) { - wbm->c.x=c.x; - wbm->c.y=c.y; - wbm->c.pro=bookmarks_get_projection(mattr.u.bookmarks); - wbm->name=g_strdup_printf(_("Bookmark %s"),label_full); - wbm->text=g_strdup(label_full); - if (!hassub) { - wbm->data=(void*)7;//Mark us as a bookmark - } - wbm->prefix=g_strdup(label_full); - } else { - gui_internal_widget_destroy(this, row); - } - } - } - - g_free(prefix); - - if (found) - gui_internal_check_exit(this); - else - gui_internal_menu_render(this); -} - - - - -static void -gui_internal_keynav_highlight_next(struct gui_priv *this, int dx, int dy, int rotary); - -static int -gui_internal_keynav_find_next(struct widget *wi, struct widget *current_highlight, struct widget **result); - -static int -gui_internal_keynav_find_prev(struct widget *wi, struct widget *current_highlight, struct widget **result); - -static struct widget* -gui_internal_keynav_find_next_sensitive_child(struct widget *wi); - -void -gui_internal_keypress_do(struct gui_priv *this, char *key) -{ - struct widget *wi,*menu,*search_list; - int len=0; - char *text=NULL; - - menu=g_list_last(this->root.children)->data; - wi=gui_internal_find_widget(menu, NULL, STATE_EDIT); - if (wi) { - /* select first item of the searchlist */ - if (*key == NAVIT_KEY_RETURN) { - search_list=gui_internal_menu_data(this)->search_list; - if(search_list) { - GList *l=gui_internal_widget_table_top_row(this, search_list); - if (l && l->data) { - struct widget *w=l->data; - this->current.x=w->p.x+w->w/2; - this->current.y=w->p.y+w->h/2; - gui_internal_highlight(this); - } - } else { - wi->reason=gui_internal_reason_keypress_finish; - wi->func(this, wi, wi->data); - } - return; - } else if (*key == NAVIT_KEY_BACKSPACE) { - dbg(lvl_debug,"backspace\n"); - if (wi->text && wi->text[0]) { - len=g_utf8_prev_char(wi->text+strlen(wi->text))-wi->text; - wi->text[len]='\0'; - text=g_strdup(wi->text); - } - } else { - if (wi->state & STATE_CLEAR) { - dbg(lvl_info,"wi->state=0x%x\n", wi->state); - g_free(wi->text); - wi->text=NULL; - wi->state &= ~STATE_CLEAR; - dbg(lvl_info,"wi->state=0x%x\n", wi->state); - } - text=g_strdup_printf("%s%s", wi->text ? wi->text : "", key); - - gui_internal_keyboard_to_lower_case(this); - } - g_free(wi->text); - wi->text=text; - - if(!wi->text || !*wi->text) - gui_internal_keyboard_to_upper_case(this); - - if (wi->func) { - wi->reason=gui_internal_reason_keypress; - wi->func(this, wi, wi->data); - } - gui_internal_widget_render(this, wi); - } -} - - - - -char * -gui_internal_cmd_match_expand(char *pattern, struct attr **in) -{ - char p,*ret=g_strdup(pattern),*r=ret,*a; - int len; - while ((p=*pattern++)) { - switch (p) { - case '*': - *r='\0'; - a=attr_to_text(*in++,NULL,0); - len=strlen(ret)+strlen(a)+strlen(pattern)+1; - r=g_malloc(len); - strcpy(r, ret); - strcat(r, a); - g_free(ret); - g_free(a); - ret=r; - r=ret+strlen(ret); - break; - case '\\': - p=*pattern++; - default: - *r++=p; - } - } - *r++='\0'; - return ret; -} - -static int -gui_internal_match(const char *pattern, const char *string) -{ - char p,s; - while ((p=*pattern++)) { - switch (p) { - case '*': - while ((s=*string)) { - if (gui_internal_match(pattern,string)) - return 1; - string++; - } - break; - case '\\': - p=*pattern++; - default: - if (*string++ != p) - return 0; - } - } - return 1; -} - -int -gui_internal_set(char *remove, char *add) -{ - char *gui_file=g_strjoin(NULL, navit_get_user_data_directory(TRUE), "/gui_internal.txt", NULL); - char *gui_file_new=g_strjoin(NULL, navit_get_user_data_directory(TRUE), "/gui_internal_new.txt", NULL); - FILE *fo=fopen(gui_file_new,"w"); - FILE *fi=fopen(gui_file,"r"); - char *line=NULL; - int ret; - size_t size=0; - if (fi != NULL){ - while (getline(&line,&size,fi) > 0) { - int len=strlen(line); - if (len > 0 && line[len-1] == '\n') - line[len-1]='\0'; - dbg(lvl_debug,"line=%s\n",line); - if (!gui_internal_match(remove, line)) - fprintf(fo,"%s\n",line); - } - if (line) - free(line); - fclose(fi); - } - if (add) - fprintf(fo,"%s;\n",add); - fclose(fo); - unlink(gui_file); - ret=(rename(gui_file_new, gui_file)==0); - g_free(gui_file_new); - g_free(gui_file); - - return ret; -} - - - -static void -gui_internal_window_closed(struct gui_priv *this) -{ - gui_internal_cmd2_quit(this, NULL, NULL, NULL, NULL); -} - - -static void -gui_internal_cmd_map_download_do(struct gui_priv *this, struct widget *wm, void *data) -{ - char *text=g_strdup_printf(_("Download %s"),wm->name); - struct widget *w, *wb; - struct map *map=data; - double bllon,bllat,trlon,trlat; - - wb=gui_internal_menu(this, text); - g_free(text); - w=gui_internal_box_new(this, gravity_top_center|orientation_vertical|flags_expand|flags_fill); - w->spy=this->spacing*3; - gui_internal_widget_append(wb, w); - if (sscanf(wm->prefix,"%lf,%lf,%lf,%lf",&bllon,&bllat,&trlon,&trlat) == 4) { - struct coord_geo g; - struct map_selection sel; - struct map_rect *mr; - struct item *item; - - sel.next=NULL; - sel.order=255; - g.lng=bllon; - g.lat=trlat; - transform_from_geo(projection_mg, &g, &sel.u.c_rect.lu); - g.lng=trlon; - g.lat=bllat; - transform_from_geo(projection_mg, &g, &sel.u.c_rect.rl); - sel.range.min=type_none; - sel.range.max=type_last; - mr=map_rect_new(map, &sel); - while ((item=map_rect_get_item(mr))) { - dbg(lvl_info,"item\n"); - } - map_rect_destroy(mr); - } - - dbg(lvl_info,"bbox=%s\n",wm->prefix); - gui_internal_menu_render(this); -} - -void -gui_internal_cmd_map_download(struct gui_priv *this, struct widget *wm, void *data) -{ - struct attr on, off, download_enabled, download_disabled; - struct widget *w,*wb,*wma; - struct map *map=data; - FILE *f; - char *search,buffer[256]; - int found,sp_match=0; - - dbg(lvl_debug,"wm=%p prefix=%s\n",wm,wm->prefix); - - search=wm->prefix; - if (search) { - found=0; - while(search[sp_match] == ' ') - sp_match++; - sp_match++; - } else { - found=1; - } - on.type=off.type=attr_active; - on.u.num=1; - off.u.num=0; - wb=gui_internal_menu(this, wm->name?wm->name:_("Map Download")); - w=gui_internal_box_new(this, gravity_top_center|orientation_vertical|flags_expand|flags_fill); - w->spy=this->spacing*3; - gui_internal_widget_append(wb, w); - if (!search) { - wma=gui_internal_button_map_attr_new(this, _("Active"), gravity_left_center|orientation_horizontal|flags_fill, map, &on, &off, 1); - gui_internal_widget_append(w, wma); - } - - download_enabled.type=download_disabled.type=attr_update; - download_enabled.u.num=1; - download_disabled.u.num=0; - wma=gui_internal_button_map_attr_new(this - , _("Download Enabled") - , gravity_left_center|orientation_horizontal|flags_fill - , map - , &download_enabled - , &download_disabled - , 0); - gui_internal_widget_append(w, wma); - - - f=fopen("maps/areas.tsv","r"); - while (f && fgets(buffer, sizeof(buffer), f)) { - char *nl,*description,*description_size,*bbox,*size=NULL; - int sp=0; - if ((nl=strchr(buffer,'\n'))) - *nl='\0'; - if ((nl=strchr(buffer,'\r'))) - *nl='\0'; - while(buffer[sp] == ' ') - sp++; - if ((bbox=strchr(buffer,'\t'))) - *bbox++='\0'; - if (bbox && (size=strchr(bbox,'\t'))) - *size++='\0'; - if (search && !strcmp(buffer, search)) { - wma=gui_internal_button_new_with_callback(this, _("Download completely"), NULL, - gravity_left_center|orientation_horizontal|flags_fill, gui_internal_cmd_map_download_do, map); - wma->name=g_strdup(buffer+sp); - wma->prefix=g_strdup(bbox); - gui_internal_widget_append(w, wma); - found=1; - } else if (sp < sp_match) - found=0; - if (sp == sp_match && found && buffer[sp]) { - description=g_strdup(buffer+sp); - if (size) - description_size=g_strdup_printf("%s (%s)",description,size); - else - description_size=g_strdup(description); - wma=gui_internal_button_new_with_callback(this, description_size, NULL, - gravity_left_center|orientation_horizontal|flags_fill, gui_internal_cmd_map_download, map); - g_free(description_size); - wma->prefix=g_strdup(buffer); - wma->name=description; - gui_internal_widget_append(w, wma); - } - } - - gui_internal_menu_render(this); -} - -static void -gui_internal_cmd_set_active_vehicle(struct gui_priv *this, struct widget *wm, void *data) -{ - struct attr vehicle = {attr_vehicle,{wm->data}}; - navit_set_attr(this->nav, &vehicle); -} - -static void -gui_internal_cmd_show_satellite_status(struct gui_priv *this, struct widget *wm, void *data) -{ - struct widget *w,*wb,*row; - struct attr attr,sat_attr; - struct vehicle *v=wm->data; - char *str; - int i; - enum attr_type types[]={attr_sat_prn, attr_sat_elevation, attr_sat_azimuth, attr_sat_snr}; - - wb=gui_internal_menu(this, _("Show Satellite Status")); - gui_internal_menu_data(this)->redisplay=gui_internal_cmd_show_satellite_status; - gui_internal_menu_data(this)->redisplay_widget=wm; - w=gui_internal_box_new(this, gravity_top_center|orientation_vertical|flags_expand|flags_fill); - gui_internal_widget_append(wb, w); - w = gui_internal_widget_table_new(this,gravity_center | orientation_vertical | flags_expand | flags_fill, 0); - row = gui_internal_widget_table_row_new(this,gravity_left_top); - gui_internal_widget_append(row, gui_internal_label_new(this, " PRN ")); - gui_internal_widget_append(row, gui_internal_label_new(this, _(" Elevation "))); - gui_internal_widget_append(row, gui_internal_label_new(this, _(" Azimuth "))); - gui_internal_widget_append(row, gui_internal_label_new(this, " SNR ")); - gui_internal_widget_append(w,row); - while (vehicle_get_attr(v, attr_position_sat_item, &attr, NULL)) { - row = gui_internal_widget_table_row_new(this,gravity_left_top); - for (i = 0 ; i < sizeof(types)/sizeof(enum attr_type) ; i++) { - if (item_attr_get(attr.u.item, types[i], &sat_attr)) - str=g_strdup_printf("%ld", sat_attr.u.num); - else - str=g_strdup(""); - gui_internal_widget_append(row, gui_internal_label_new(this, str)); - g_free(str); - } - gui_internal_widget_append(w,row); - } - gui_internal_widget_append(wb, w); - gui_internal_menu_render(this); -} - -static void -gui_internal_cmd_show_nmea_data(struct gui_priv *this, struct widget *wm, void *data) -{ - struct widget *w,*wb; - struct attr attr; - struct vehicle *v=wm->data; - wb=gui_internal_menu(this, _("Show NMEA Data")); - gui_internal_menu_data(this)->redisplay=gui_internal_cmd_show_nmea_data; - gui_internal_menu_data(this)->redisplay_widget=wm; - w=gui_internal_box_new(this, gravity_top_center|orientation_vertical|flags_expand|flags_fill); - gui_internal_widget_append(wb, w); - if (vehicle_get_attr(v, attr_position_nmea, &attr, NULL)) - gui_internal_widget_append(w, gui_internal_text_new(this, attr.u.str, gravity_left_center|orientation_vertical)); - gui_internal_menu_render(this); +void gui_internal_cmd_bookmarks(struct gui_priv *this, struct widget *wm, void *data) { + struct attr attr,mattr; + struct item *item; + char *label_full,*prefix=0; + int plen=0,hassub,found=0; + struct widget *wb,*w,*wbm; + struct coord c; + struct widget *tbl, *row; + + if (data) + prefix=g_strdup(data); + else { + if (wm && wm->prefix) + prefix=g_strdup(wm->prefix); + } + if ( prefix ) + plen=strlen(prefix); + + gui_internal_prune_menu_count(this, 1, 0); + wb=gui_internal_menu(this, _("Bookmarks")); + wb->background=this->background; + w=gui_internal_box_new(this, gravity_top_center|orientation_vertical|flags_expand|flags_fill); + //w->spy=this->spacing*3; + gui_internal_widget_append(wb, w); + + if(navit_get_attr(this->nav, attr_bookmarks, &mattr, NULL) ) { + if (!plen) { + bookmarks_move_root(mattr.u.bookmarks); + } else { + if (!strcmp(prefix,"..")) { + bookmarks_move_up(mattr.u.bookmarks); + g_free(prefix); + prefix=g_strdup(bookmarks_item_cwd(mattr.u.bookmarks)); + if (prefix) { + plen=strlen(prefix); + } else { + plen=0; + } + } else { + bookmarks_move_down(mattr.u.bookmarks,prefix); + } + + // "Back" button, when inside a bookmark folder + + if (plen) { + wbm=gui_internal_button_new_with_callback(this, "..", + image_new_xs(this, "gui_inactive"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_bookmarks, NULL); + wbm->prefix=g_strdup(".."); + gui_internal_widget_append(w, wbm); + + // load bookmark folder as Waypoints, if any + if (bookmarks_get_bookmark_count(mattr.u.bookmarks) > 0) { + wbm=gui_internal_button_new_with_callback(this, _("Bookmarks as waypoints"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_load_bookmarks_as_waypoints, NULL); + wbm->prefix=g_strdup(prefix); + gui_internal_widget_append(w, wbm); + } + + // save Waypoints in bookmark folder, if route exists + if (navit_get_destination_count(this->nav) > 0) { + if (bookmarks_get_bookmark_count(mattr.u.bookmarks)==0) { + wbm=gui_internal_button_new_with_callback(this, _("Save waypoints"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_replace_bookmarks_from_waypoints, NULL); + } else { + wbm=gui_internal_button_new_with_callback(this, _("Replace with waypoints"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_replace_bookmarks_from_waypoints, NULL); + } + wbm->prefix=g_strdup(prefix); + gui_internal_widget_append(w, wbm); + } + + // delete empty folder + if (bookmarks_get_bookmark_count(mattr.u.bookmarks)==0) { + gui_internal_widget_append(w, + wbm=gui_internal_button_new_with_callback(this, _("Delete Folder"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_delete_bookmark_folder, NULL)); + wbm->prefix=g_strdup(prefix); + } + + } + } + + // Adds the Bookmark folders + wbm=gui_internal_button_new_with_callback(this, _("Add Bookmark folder"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_add_bookmark_folder2, NULL); + gui_internal_widget_append(w, wbm); + + // Pastes the Bookmark + wbm=gui_internal_button_new_with_callback(this, _("Paste bookmark"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_paste_bookmark, NULL); + gui_internal_widget_append(w, wbm); + + bookmarks_item_rewind(mattr.u.bookmarks); + + tbl=gui_internal_widget_table_new(this,gravity_left_top | flags_fill | flags_expand |orientation_vertical,1); + gui_internal_widget_append(w,tbl); + + while ((item=bookmarks_get_item(mattr.u.bookmarks))) { + if (!item_attr_get(item, attr_label, &attr)) continue; + label_full=map_convert_string_tmp(item->map,attr.u.str); + dbg(lvl_info,"full_labled: %s",label_full); + + // hassub == 1 if the item type is a sub-folder + if (item->type == type_bookmark_folder) { + hassub=1; + } else { + hassub=0; + } + + row=gui_internal_widget_table_row_new(this,gravity_left| flags_fill| orientation_horizontal); + gui_internal_widget_append(tbl, row); + wbm=gui_internal_button_new_with_callback(this, label_full, + image_new_xs(this, hassub ? "gui_inactive" : "gui_active" ), gravity_left_center|orientation_horizontal|flags_fill, + hassub ? gui_internal_cmd_bookmarks : gui_internal_cmd_position, NULL); + + gui_internal_widget_append(row,wbm); + if (item_coord_get(item, &c, 1)) { + wbm->c.x=c.x; + wbm->c.y=c.y; + wbm->c.pro=bookmarks_get_projection(mattr.u.bookmarks); + wbm->name=g_strdup_printf(_("Bookmark %s"),label_full); + wbm->text=g_strdup(label_full); + if (!hassub) { + wbm->data=(void*)7;//Mark us as a bookmark + } + wbm->prefix=g_strdup(label_full); + } else { + gui_internal_widget_destroy(this, row); + } + } + } + + g_free(prefix); + + if (found) + gui_internal_check_exit(this); + else + gui_internal_menu_render(this); +} + + + + +static void gui_internal_keynav_highlight_next(struct gui_priv *this, int dx, int dy, int rotary); + +static int gui_internal_keynav_find_next(struct widget *wi, struct widget *current_highlight, struct widget **result); + +static int gui_internal_keynav_find_prev(struct widget *wi, struct widget *current_highlight, struct widget **result); + +static struct widget* gui_internal_keynav_find_next_sensitive_child(struct widget *wi); + +void gui_internal_keypress_do(struct gui_priv *this, char *key) { + struct widget *wi,*menu,*search_list; + int len=0; + char *text=NULL; + + menu=g_list_last(this->root.children)->data; + wi=gui_internal_find_widget(menu, NULL, STATE_EDIT); + if (wi) { + /* select first item of the searchlist */ + if (*key == NAVIT_KEY_RETURN) { + search_list=gui_internal_menu_data(this)->search_list; + if(search_list) { + GList *l=gui_internal_widget_table_top_row(this, search_list); + if (l && l->data) { + struct widget *w=l->data; + this->current.x=w->p.x+w->w/2; + this->current.y=w->p.y+w->h/2; + gui_internal_highlight(this); + } + } else { + wi->reason=gui_internal_reason_keypress_finish; + wi->func(this, wi, wi->data); + } + return; + } else if (*key == NAVIT_KEY_BACKSPACE) { + dbg(lvl_debug,"backspace"); + if (wi->text && wi->text[0]) { + len=g_utf8_prev_char(wi->text+strlen(wi->text))-wi->text; + wi->text[len]='\0'; + text=g_strdup(wi->text); + } + } else { + if (wi->state & STATE_CLEAR) { + dbg(lvl_info,"wi->state=0x%x", wi->state); + g_free(wi->text); + wi->text=NULL; + wi->state &= ~STATE_CLEAR; + dbg(lvl_info,"wi->state=0x%x", wi->state); + } + text=g_strdup_printf("%s%s", wi->text ? wi->text : "", key); + + gui_internal_keyboard_to_lower_case(this); + } + g_free(wi->text); + wi->text=text; + + if(!wi->text || !*wi->text) + gui_internal_keyboard_to_upper_case(this); + + if (wi->func) { + wi->reason=gui_internal_reason_keypress; + wi->func(this, wi, wi->data); + } + gui_internal_widget_render(this, wi); + } +} + + + + +char *gui_internal_cmd_match_expand(char *pattern, struct attr **in) { + char p,*ret=g_strdup(pattern),*r=ret,*a; + int len; + while ((p=*pattern++)) { + switch (p) { + case '*': + *r='\0'; + a=attr_to_text(*in++,NULL,0); + len=strlen(ret)+strlen(a)+strlen(pattern)+1; + r=g_malloc(len); + strcpy(r, ret); + strcat(r, a); + g_free(ret); + g_free(a); + ret=r; + r=ret+strlen(ret); + break; + case '\\': + p=*pattern++; + default: + *r++=p; + } + } + *r++='\0'; + return ret; +} + +static int gui_internal_match(const char *pattern, const char *string) { + char p,s; + while ((p=*pattern++)) { + switch (p) { + case '*': + while ((s=*string)) { + if (gui_internal_match(pattern,string)) + return 1; + string++; + } + break; + case '\\': + p=*pattern++; + default: + if (*string++ != p) + return 0; + } + } + return 1; +} + +int gui_internal_set(char *remove, char *add) { + char *gui_file=g_strjoin(NULL, navit_get_user_data_directory(TRUE), "/gui_internal.txt", NULL); + char *gui_file_new=g_strjoin(NULL, navit_get_user_data_directory(TRUE), "/gui_internal_new.txt", NULL); + FILE *fo=fopen(gui_file_new,"w"); + FILE *fi=fopen(gui_file,"r"); + char *line=NULL; + int ret; + size_t size=0; + if (fi != NULL) { + while (getline(&line,&size,fi) > 0) { + int len=strlen(line); + if (len > 0 && line[len-1] == '\n') + line[len-1]='\0'; + dbg(lvl_debug,"line=%s",line); + if (!gui_internal_match(remove, line)) + fprintf(fo,"%s\n",line); + } + if (line) + free(line); + fclose(fi); + } + if (add) + fprintf(fo,"%s;\n",add); + fclose(fo); + unlink(gui_file); + ret=(rename(gui_file_new, gui_file)==0); + g_free(gui_file_new); + g_free(gui_file); + + return ret; +} + + + +static void gui_internal_window_closed(struct gui_priv *this) { + gui_internal_cmd2_quit(this, NULL, NULL, NULL, NULL); +} + + +static void gui_internal_cmd_map_download_do(struct gui_priv *this, struct widget *wm, void *data) { + char *text=g_strdup_printf(_("Download %s"),wm->name); + struct widget *w, *wb; + struct map *map=data; + double bllon,bllat,trlon,trlat; + + wb=gui_internal_menu(this, text); + g_free(text); + w=gui_internal_box_new(this, gravity_top_center|orientation_vertical|flags_expand|flags_fill); + w->spy=this->spacing*3; + gui_internal_widget_append(wb, w); + if (sscanf(wm->prefix,"%lf,%lf,%lf,%lf",&bllon,&bllat,&trlon,&trlat) == 4) { + struct coord_geo g; + struct map_selection sel; + struct map_rect *mr; + struct item *item; + + sel.next=NULL; + sel.order=255; + g.lng=bllon; + g.lat=trlat; + transform_from_geo(projection_mg, &g, &sel.u.c_rect.lu); + g.lng=trlon; + g.lat=bllat; + transform_from_geo(projection_mg, &g, &sel.u.c_rect.rl); + sel.range.min=type_none; + sel.range.max=type_last; + mr=map_rect_new(map, &sel); + while ((item=map_rect_get_item(mr))) { + dbg(lvl_info,"item"); + } + map_rect_destroy(mr); + } + + dbg(lvl_info,"bbox=%s",wm->prefix); + gui_internal_menu_render(this); +} + +void gui_internal_cmd_map_download(struct gui_priv *this, struct widget *wm, void *data) { + struct attr on, off, download_enabled, download_disabled; + struct widget *w,*wb,*wma; + struct map *map=data; + FILE *f; + char *search,buffer[256]; + int found,sp_match=0; + + dbg(lvl_debug,"wm=%p prefix=%s",wm,wm->prefix); + + search=wm->prefix; + if (search) { + found=0; + while(search[sp_match] == ' ') + sp_match++; + sp_match++; + } else { + found=1; + } + on.type=off.type=attr_active; + on.u.num=1; + off.u.num=0; + wb=gui_internal_menu(this, wm->name?wm->name:_("Map Download")); + w=gui_internal_box_new(this, gravity_top_center|orientation_vertical|flags_expand|flags_fill); + w->spy=this->spacing*3; + gui_internal_widget_append(wb, w); + if (!search) { + wma=gui_internal_button_map_attr_new(this, _("Active"), gravity_left_center|orientation_horizontal|flags_fill, map, &on, + &off, 1); + gui_internal_widget_append(w, wma); + } + + download_enabled.type=download_disabled.type=attr_update; + download_enabled.u.num=1; + download_disabled.u.num=0; + wma=gui_internal_button_map_attr_new(this + , _("Download Enabled") + , gravity_left_center|orientation_horizontal|flags_fill + , map + , &download_enabled + , &download_disabled + , 0); + gui_internal_widget_append(w, wma); + + + f=fopen("maps/areas.tsv","r"); + while (f && fgets(buffer, sizeof(buffer), f)) { + char *nl,*description,*description_size,*bbox,*size=NULL; + int sp=0; + if ((nl=strchr(buffer,'\n'))) + *nl='\0'; + if ((nl=strchr(buffer,'\r'))) + *nl='\0'; + while(buffer[sp] == ' ') + sp++; + if ((bbox=strchr(buffer,'\t'))) + *bbox++='\0'; + if (bbox && (size=strchr(bbox,'\t'))) + *size++='\0'; + if (search && !strcmp(buffer, search)) { + wma=gui_internal_button_new_with_callback(this, _("Download completely"), NULL, + gravity_left_center|orientation_horizontal|flags_fill, gui_internal_cmd_map_download_do, map); + wma->name=g_strdup(buffer+sp); + wma->prefix=g_strdup(bbox); + gui_internal_widget_append(w, wma); + found=1; + } else if (sp < sp_match) + found=0; + if (sp == sp_match && found && buffer[sp]) { + description=g_strdup(buffer+sp); + if (size) + description_size=g_strdup_printf("%s (%s)",description,size); + else + description_size=g_strdup(description); + wma=gui_internal_button_new_with_callback(this, description_size, NULL, + gravity_left_center|orientation_horizontal|flags_fill, gui_internal_cmd_map_download, map); + g_free(description_size); + wma->prefix=g_strdup(buffer); + wma->name=description; + gui_internal_widget_append(w, wma); + } + } + + gui_internal_menu_render(this); +} + +static void gui_internal_cmd_set_active_vehicle(struct gui_priv *this, struct widget *wm, void *data) { + struct attr vehicle = {attr_vehicle,{wm->data}}; + navit_set_attr(this->nav, &vehicle); +} + +static void gui_internal_cmd_show_satellite_status(struct gui_priv *this, struct widget *wm, void *data) { + struct widget *w,*wb,*row; + struct attr attr,sat_attr; + struct vehicle *v=wm->data; + char *str; + int i; + enum attr_type types[]= {attr_sat_prn, attr_sat_elevation, attr_sat_azimuth, attr_sat_snr}; + + wb=gui_internal_menu(this, _("Show Satellite Status")); + gui_internal_menu_data(this)->redisplay=gui_internal_cmd_show_satellite_status; + gui_internal_menu_data(this)->redisplay_widget=wm; + w=gui_internal_box_new(this, gravity_top_center|orientation_vertical|flags_expand|flags_fill); + gui_internal_widget_append(wb, w); + w = gui_internal_widget_table_new(this,gravity_center | orientation_vertical | flags_expand | flags_fill, 0); + row = gui_internal_widget_table_row_new(this,gravity_left_top); + gui_internal_widget_append(row, gui_internal_label_new(this, " PRN ")); + gui_internal_widget_append(row, gui_internal_label_new(this, _(" Elevation "))); + gui_internal_widget_append(row, gui_internal_label_new(this, _(" Azimuth "))); + gui_internal_widget_append(row, gui_internal_label_new(this, " SNR ")); + gui_internal_widget_append(w,row); + while (vehicle_get_attr(v, attr_position_sat_item, &attr, NULL)) { + row = gui_internal_widget_table_row_new(this,gravity_left_top); + for (i = 0 ; i < sizeof(types)/sizeof(enum attr_type) ; i++) { + if (item_attr_get(attr.u.item, types[i], &sat_attr)) + str=g_strdup_printf("%ld", sat_attr.u.num); + else + str=g_strdup(""); + gui_internal_widget_append(row, gui_internal_label_new(this, str)); + g_free(str); + } + gui_internal_widget_append(w,row); + } + gui_internal_widget_append(wb, w); + gui_internal_menu_render(this); +} + +static void gui_internal_cmd_show_nmea_data(struct gui_priv *this, struct widget *wm, void *data) { + struct widget *w,*wb; + struct attr attr; + struct vehicle *v=wm->data; + wb=gui_internal_menu(this, _("Show NMEA Data")); + gui_internal_menu_data(this)->redisplay=gui_internal_cmd_show_nmea_data; + gui_internal_menu_data(this)->redisplay_widget=wm; + w=gui_internal_box_new(this, gravity_top_center|orientation_vertical|flags_expand|flags_fill); + gui_internal_widget_append(wb, w); + if (vehicle_get_attr(v, attr_position_nmea, &attr, NULL)) + gui_internal_widget_append(w, gui_internal_text_new(this, attr.u.str, gravity_left_center|orientation_vertical)); + gui_internal_menu_render(this); } /** @@ -1981,8 +1894,8 @@ gui_internal_cmd_show_nmea_data(struct gui_priv *this, struct widget *wm, void * * one data item. */ struct vehicle_and_profilename { - struct vehicle *vehicle; - char *profilename; + struct vehicle *vehicle; + char *profilename; }; /** @@ -1990,40 +1903,36 @@ struct vehicle_and_profilename { * * @return true if the vehicle is active, false otherwise. */ -static int -gui_internal_is_active_vehicle(struct gui_priv *this, struct vehicle - *vehicle) -{ - struct attr active_vehicle; +static int gui_internal_is_active_vehicle(struct gui_priv *this, struct vehicle + *vehicle) { + struct attr active_vehicle; - if (!navit_get_attr(this->nav, attr_vehicle, &active_vehicle, NULL)) + if (!navit_get_attr(this->nav, attr_vehicle, &active_vehicle, NULL)) active_vehicle.u.vehicle=NULL; - return active_vehicle.u.vehicle == vehicle; -} - -static void -save_vehicle_xml(struct vehicle *v) -{ - struct attr attr; - struct attr_iter *iter=vehicle_attr_iter_new(); - int childs=0; - printf("<vehicle"); - while (vehicle_get_attr(v, attr_any_xml, &attr, iter)) { - if (ATTR_IS_OBJECT(attr.type)) - childs=1; - else { - char *attrtxt; - printf(" %s=\"%s\"",attr_to_name(attr.type),attrtxt=attr_to_text(&attr, NULL, 1)); - g_free(attrtxt); - } - } - if (childs) { - printf(">\n"); - printf("</vehicle>\n"); - } else - printf(" />\n"); - vehicle_attr_iter_destroy(iter); + return active_vehicle.u.vehicle == vehicle; +} + +static void save_vehicle_xml(struct vehicle *v) { + struct attr attr; + struct attr_iter *iter=vehicle_attr_iter_new(); + int childs=0; + printf("<vehicle"); + while (vehicle_get_attr(v, attr_any_xml, &attr, iter)) { + if (ATTR_IS_OBJECT(attr.type)) + childs=1; + else { + char *attrtxt; + printf(" %s=\"%s\"",attr_to_name(attr.type),attrtxt=attr_to_text(&attr, NULL, 1)); + g_free(attrtxt); + } + } + if (childs) { + printf(">\n"); + printf("</vehicle>\n"); + } else + printf(" />\n"); + vehicle_attr_iter_destroy(iter); } @@ -2032,169 +1941,162 @@ save_vehicle_xml(struct vehicle *v) * * @see gui_internal_add_vehicle_profile */ -static void -gui_internal_cmd_set_active_profile(struct gui_priv *this, struct - widget *wm, void *data) -{ - struct vehicle_and_profilename *vapn = data; - struct vehicle *v = vapn->vehicle; - char *profilename = vapn->profilename; - struct attr vehicle_name_attr; - char *vehicle_name = NULL; - struct attr profilename_attr; - struct attr vehicle; - - // Get the vehicle name - vehicle_get_attr(v, attr_name, &vehicle_name_attr, NULL); - vehicle_name = vehicle_name_attr.u.str; - - dbg(lvl_debug, "Changing vehicle %s to profile %s\n", vehicle_name, - profilename); - - // Change the profile name - profilename_attr.type = attr_profilename; - profilename_attr.u.str = profilename; - if(!vehicle_set_attr(v, &profilename_attr)) { - dbg(lvl_error, "Unable to set the vehicle's profile name\n"); - } - - navit_set_vehicleprofile_name(this->nav,profilename); - - save_vehicle_xml(v); +static void gui_internal_cmd_set_active_profile(struct gui_priv *this, struct + widget *wm, void *data) { + struct vehicle_and_profilename *vapn = data; + struct vehicle *v = vapn->vehicle; + char *profilename = vapn->profilename; + struct attr vehicle_name_attr; + char *vehicle_name = NULL; + struct attr profilename_attr; + struct attr vehicle; + + // Get the vehicle name + vehicle_get_attr(v, attr_name, &vehicle_name_attr, NULL); + vehicle_name = vehicle_name_attr.u.str; + + dbg(lvl_debug, "Changing vehicle %s to profile %s", vehicle_name, profilename); + + // Change the profile name + profilename_attr.type = attr_profilename; + profilename_attr.u.str = profilename; + if(!vehicle_set_attr(v, &profilename_attr)) { + dbg(lvl_error, "Unable to set the vehicle's profile name"); + } + + navit_set_vehicleprofile_name(this->nav,profilename); + + save_vehicle_xml(v); // Notify Navit that the routing should be re-done if this is the // active vehicle. - if (gui_internal_is_active_vehicle(this, v)) { - vehicle.u.vehicle=v; - } - else { + if (gui_internal_is_active_vehicle(this, v)) { + vehicle.u.vehicle=v; + } else { + + vehicle.u.vehicle=NULL; + } - vehicle.u.vehicle=NULL; - } - - vehicle.type=attr_vehicle; - navit_set_attr(this->nav, &vehicle); + vehicle.type=attr_vehicle; + navit_set_attr(this->nav, &vehicle); - - gui_internal_prune_menu_count(this, 1, 0); - gui_internal_menu_vehicle_settings(this, v, vehicle_name); + + gui_internal_prune_menu_count(this, 1, 0); + gui_internal_menu_vehicle_settings(this, v, vehicle_name); } /** * Adds the vehicle profile to the GUI, allowing the user to pick a * profile for the currently selected vehicle. */ -static void -gui_internal_add_vehicle_profile(struct gui_priv *this, struct widget - *parent, struct vehicle *v, struct vehicleprofile *profile) -{ - // Just here to show up in the translation file, nice and close to - // where the translations are actually used. - struct attr profile_attr; - struct attr *attr = NULL; - char *name = NULL; - char *active_profile = NULL; - char *label = NULL; - int active; - struct vehicle_and_profilename *context = NULL; +static void gui_internal_add_vehicle_profile(struct gui_priv *this, struct widget + *parent, struct vehicle *v, struct vehicleprofile *profile) { + // Just here to show up in the translation file, nice and close to + // where the translations are actually used. + struct attr profile_attr; + struct attr *attr = NULL; + char *name = NULL; + char *active_profile = NULL; + char *label = NULL; + int active; + struct vehicle_and_profilename *context = NULL; #ifdef ONLY_FOR_TRANSLATION - char *translations[] = {_n("car"), _n("bike"), _n("pedestrian")}; + char *translations[] = {_n("car"), _n("bike"), _n("pedestrian")}; #endif - // Figure out the profile name - attr = attr_search(profile->attrs, NULL, attr_name); - if (!attr) { - dbg(lvl_error, "Adding vehicle profile failed. attr==NULL"); - return; - } - name = attr->u.str; - - // Determine whether the profile is the active one - if (vehicle_get_attr(v, attr_profilename, &profile_attr, NULL)) - active_profile = profile_attr.u.str; - active = active_profile != NULL && !strcmp(name, active_profile); - - dbg(lvl_debug, "Adding vehicle profile %s, active=%s/%i\n", name, - active_profile, active); - - // Build a translatable label. - if(active) { - label = g_strdup_printf(_("Current profile: %s"), _(name)); - } else { - label = g_strdup_printf(_("Change profile to: %s"), _(name)); - } - - // Create the context object (the vehicle and the desired profile) - context = g_new0(struct vehicle_and_profilename, 1); - context->vehicle = v; - context->profilename = name; - - // Add the button - gui_internal_widget_append(parent, - gui_internal_button_new_with_callback( - this, label, - image_new_xs(this, active ? "gui_active" : "gui_inactive"), - gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_set_active_profile, context)); - - free(label); -} - -void -gui_internal_menu_vehicle_settings(struct gui_priv *this, struct vehicle *v, char *name) -{ - struct widget *w,*wb,*row; - struct attr attr; + // Figure out the profile name + attr = attr_search(profile->attrs, NULL, attr_name); + if (!attr) { + dbg(lvl_error, "Adding vehicle profile failed. attr==NULL"); + return; + } + name = attr->u.str; + + // Determine whether the profile is the active one + if (vehicle_get_attr(v, attr_profilename, &profile_attr, NULL)) + active_profile = profile_attr.u.str; + active = active_profile != NULL && !strcmp(name, active_profile); + + dbg(lvl_debug, "Adding vehicle profile %s, active=%s/%i", name, active_profile, active); + + // Build a translatable label. + if(active) { + label = g_strdup_printf(_("Current profile: %s"), _(name)); + } else { + label = g_strdup_printf(_("Change profile to: %s"), _(name)); + } + + // Create the context object (the vehicle and the desired profile) + context = g_new0(struct vehicle_and_profilename, 1); + context->vehicle = v; + context->profilename = name; + + // Add the button + gui_internal_widget_append(parent, + gui_internal_button_new_with_callback( + this, label, + image_new_xs(this, active ? "gui_active" : "gui_inactive"), + gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_set_active_profile, context)); + + free(label); +} + +void gui_internal_menu_vehicle_settings(struct gui_priv *this, struct vehicle *v, char *name) { + struct widget *w,*wb,*row; + struct attr attr; struct vehicleprofile *profile = NULL; - GList *profiles; + GList *profiles; - wb=gui_internal_menu(this, name); - w=gui_internal_widget_table_new(this, gravity_top_center|orientation_vertical|flags_expand|flags_fill,1); - gui_internal_widget_append(wb, w); + wb=gui_internal_menu(this, name); + w=gui_internal_widget_table_new(this, gravity_top_center|orientation_vertical|flags_expand|flags_fill,1); + gui_internal_widget_append(wb, w); // Add the "Set as active" button if this isn't the active // vehicle. - if (!gui_internal_is_active_vehicle(this, v)) { - gui_internal_widget_append(w, row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); - gui_internal_widget_append(row, - gui_internal_button_new_with_callback(this, _("Set as active"), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_set_active_vehicle, v)); - } - - if (vehicle_get_attr(v, attr_position_sat_item, &attr, NULL)) { - gui_internal_widget_append(w, row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); - gui_internal_widget_append(row, - gui_internal_button_new_with_callback(this, _("Show Satellite status"), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_show_satellite_status, v)); - } - if (vehicle_get_attr(v, attr_position_nmea, &attr, NULL)) { - gui_internal_widget_append(w, row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); - gui_internal_widget_append(row, - gui_internal_button_new_with_callback(this, _("Show NMEA data"), - image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, - gui_internal_cmd_show_nmea_data, v)); - } + if (!gui_internal_is_active_vehicle(this, v)) { + gui_internal_widget_append(w, row=gui_internal_widget_table_row_new(this, + gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, + gui_internal_button_new_with_callback(this, _("Set as active"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_set_active_vehicle, v)); + } + + if (vehicle_get_attr(v, attr_position_sat_item, &attr, NULL)) { + gui_internal_widget_append(w, row=gui_internal_widget_table_row_new(this, + gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, + gui_internal_button_new_with_callback(this, _("Show Satellite status"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_show_satellite_status, v)); + } + if (vehicle_get_attr(v, attr_position_nmea, &attr, NULL)) { + gui_internal_widget_append(w, row=gui_internal_widget_table_row_new(this, + gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(row, + gui_internal_button_new_with_callback(this, _("Show NMEA data"), + image_new_xs(this, "gui_active"), gravity_left_center|orientation_horizontal|flags_fill, + gui_internal_cmd_show_nmea_data, v)); + } // Add all the possible vehicle profiles to the menu - profiles = navit_get_vehicleprofiles(this->nav); + profiles = navit_get_vehicleprofiles(this->nav); while(profiles) { profile = (struct vehicleprofile *)profiles->data; - gui_internal_widget_append(w, row=gui_internal_widget_table_row_new(this,gravity_left|orientation_horizontal|flags_fill)); + gui_internal_widget_append(w, row=gui_internal_widget_table_row_new(this, + gravity_left|orientation_horizontal|flags_fill)); gui_internal_add_vehicle_profile(this, row, v, profile); - profiles = g_list_next(profiles); + profiles = g_list_next(profiles); } - callback_list_call_attr_2(this->cbl, attr_vehicle, w, v); - gui_internal_menu_render(this); + callback_list_call_attr_2(this->cbl, attr_vehicle, w, v); + gui_internal_menu_render(this); } -void -gui_internal_cmd_vehicle_settings(struct gui_priv *this, struct widget *wm, void *data) -{ - gui_internal_menu_vehicle_settings(this, wm->data, wm->text); +void gui_internal_cmd_vehicle_settings(struct gui_priv *this, struct widget *wm, void *data) { + gui_internal_menu_vehicle_settings(this, wm->data, wm->text); } @@ -2205,255 +2107,227 @@ gui_internal_cmd_vehicle_settings(struct gui_priv *this, struct widget *wm, void //# Comment: //# Authors: Martin Schaller (04/2008) //############################################################################################################## -static void gui_internal_motion(void *data, struct point *p) -{ - - struct gui_priv *this=data; - if (!this->root.children) { - navit_handle_motion(this->nav, p); - return; - } - if (!this->pressed) - return; - this->current=*p; - if(!this->motion_timeout_callback) - this->motion_timeout_callback=callback_new_1(callback_cast(gui_internal_motion_cb), this); - if(!this->motion_timeout_event) - this->motion_timeout_event=event_add_timeout(30,0, this->motion_timeout_callback); -} - -void -gui_internal_evaluate(struct gui_priv *this, const char *command) -{ - if (command) - command_evaluate(&this->self, command); -} - - -void -gui_internal_enter(struct gui_priv *this, int ignore) -{ - struct graphics *gra=this->gra; - if (ignore != -1) - this->ignore_button=ignore; - - navit_block(this->nav, 1); - graphics_overlay_disable(gra, 1); - this->root.p.x=0; - this->root.p.y=0; - this->root.background=this->background; -} - -void -gui_internal_leave(struct gui_priv *this) -{ - graphics_draw_mode(this->gra, draw_mode_end); -} - -void -gui_internal_set_click_coord(struct gui_priv *this, struct point *p) -{ - struct coord c; - struct coord_geo g; - struct attr attr; - struct transformation *trans; - attr_free(this->click_coord_geo); - this->click_coord_geo=NULL; - if (p) { - trans=navit_get_trans(this->nav); - transform_reverse(trans, p, &c); - dbg(lvl_debug,"x=0x%x y=0x%x\n", c.x, c.y); - this->clickp.pro=transform_get_projection(trans); - this->clickp.x=c.x; - this->clickp.y=c.y; - transform_to_geo(this->clickp.pro, &c, &g); - attr.u.coord_geo=&g; - attr.type=attr_click_coord_geo; - this->click_coord_geo=attr_dup(&attr); - } -} - -static void -gui_internal_set_position_coord(struct gui_priv *this) -{ - struct transformation *trans; - struct attr attr,attrp; - struct coord c; - - attr_free(this->position_coord_geo); - this->position_coord_geo=NULL; - if (navit_get_attr(this->nav, attr_vehicle, &attr, NULL) && attr.u.vehicle - && vehicle_get_attr(attr.u.vehicle, attr_position_coord_geo, &attrp, NULL)) { - trans=navit_get_trans(this->nav); - this->position_coord_geo=attr_dup(&attrp); - this->vehiclep.pro=transform_get_projection(trans); - transform_from_geo(this->vehiclep.pro, attrp.u.coord_geo, &c); - this->vehiclep.x=c.x; - this->vehiclep.y=c.y; - } -} - -void -gui_internal_enter_setup(struct gui_priv *this) -{ - if (!this->mouse_button_clicked_on_map) - gui_internal_set_position_coord(this); -} - -void -gui_internal_cmd_menu(struct gui_priv *this, int ignore, char *href) -{ - dbg(lvl_debug,"enter\n"); - gui_internal_enter(this, ignore); - gui_internal_enter_setup(this); - // draw menu - if (href) - gui_internal_html_load_href(this, href, 0); - else - gui_internal_html_main_menu(this); -} - - - -static void -gui_internal_cmd_log_do(struct gui_priv *this, struct widget *widget) -{ - if (widget->text && strlen(widget->text)) { - if (this->position_coord_geo) - navit_textfile_debug_log_at(this->nav, &this->vehiclep, "type=log_entry label=\"%s\"",widget->text); - else - navit_textfile_debug_log(this->nav, "type=log_entry label=\"%s\"",widget->text); - } - g_free(widget->text); - widget->text=NULL; - gui_internal_prune_menu(this, NULL); - gui_internal_check_exit(this); -} - -void -gui_internal_cmd_log_clicked(struct gui_priv *this, struct widget *widget, void *data) -{ - gui_internal_cmd_log_do(this, widget->data); -} - - -void -gui_internal_check_exit(struct gui_priv *this) -{ - struct graphics *gra=this->gra; - if (! this->root.children) { - gui_internal_search_idle_end(this); - gui_internal_search_list_destroy(this); - graphics_overlay_disable(gra, 0); - if (!navit_block(this->nav, 0)) { - if (this->redraw) - navit_draw(this->nav); - else - navit_draw_displaylist(this->nav); - } - } -} - -static int -gui_internal_get_attr(struct gui_priv *this, enum attr_type type, struct attr *attr) -{ - switch (type) { - case attr_active: - attr->u.num=this->root.children != NULL; - break; - case attr_click_coord_geo: - if (!this->click_coord_geo) - return 0; - *attr=*this->click_coord_geo; - break; - case attr_position_coord_geo: - if (!this->position_coord_geo) - return 0; - *attr=*this->position_coord_geo; - break; - case attr_pitch: - attr->u.num=this->pitch; - break; - case attr_button: - attr->u.num=this->mouse_button_clicked_on_map; - break; - case attr_navit: - attr->u.navit=this->nav; - break; - case attr_fullscreen: - attr->u.num=(this->fullscreen > 0); - break; - default: - return 0; - } - attr->type=type; - return 1; -} - -static int -gui_internal_add_attr(struct gui_priv *this, struct attr *attr) -{ - switch (attr->type) { - case attr_xml_text: - g_free(this->html_text); - this->html_text=g_strdup(attr->u.str); - return 1; - default: - return 0; - } -} - -static int -gui_internal_set_attr(struct gui_priv *this, struct attr *attr) -{ - switch (attr->type) { - case attr_fullscreen: - if ((this->fullscreen > 0) != (attr->u.num > 0)) { - graphics_draw_mode(this->gra, draw_mode_end); - this->win->fullscreen(this->win, attr->u.num > 0); - graphics_draw_mode(this->gra, draw_mode_begin); - } - this->fullscreen=attr->u.num; - return 1; - case attr_menu_on_map_click: - this->menu_on_map_click=attr->u.num; - return 1; - case attr_on_map_click: - g_free(this->on_map_click); - this->on_map_click=g_strdup(attr->u.str); - return 1; - default: - dbg(lvl_error,"Unknown attribute: %s\n",attr_to_name(attr->type)); - return 1; - } -} - -static void gui_internal_dbus_signal(struct gui_priv *this, struct point *p) -{ - struct displaylist_handle *dlh; - struct displaylist *display; - struct displayitem *di; - struct attr cb,**attr_list=NULL; - int valid=0; - - display=navit_get_displaylist(this->nav); - dlh=graphics_displaylist_open(display); - while ((di=graphics_displaylist_next(dlh))) { - struct item *item=graphics_displayitem_get_item(di); - if (item_is_point(*item) && graphics_displayitem_get_displayed(di) && - graphics_displayitem_within_dist(display, di, p, this->radius)) { - struct map_rect *mr=map_rect_new(item->map, NULL); - struct item *itemo=map_rect_get_item_byid(mr, item->id_hi, item->id_lo); - struct attr attr; - if (itemo && item_attr_get(itemo, attr_data, &attr)) - attr_list=attr_generic_add_attr(attr_list, &attr); - map_rect_destroy(mr); - } - } - graphics_displaylist_close(dlh); - if (attr_list && navit_get_attr(this->nav, attr_callback_list, &cb, NULL)) - callback_list_call_attr_4(cb.u.callback_list, attr_command, "dbus_send_signal", attr_list, NULL, &valid); - attr_list_free(attr_list); +static void gui_internal_motion(void *data, struct point *p) { + + struct gui_priv *this=data; + if (!this->root.children) { + navit_handle_motion(this->nav, p); + return; + } + if (!this->pressed) + return; + this->current=*p; + if(!this->motion_timeout_callback) + this->motion_timeout_callback=callback_new_1(callback_cast(gui_internal_motion_cb), this); + if(!this->motion_timeout_event) + this->motion_timeout_event=event_add_timeout(30,0, this->motion_timeout_callback); +} + +void gui_internal_evaluate(struct gui_priv *this, const char *command) { + if (command) + command_evaluate(&this->self, command); +} + + +void gui_internal_enter(struct gui_priv *this, int ignore) { + struct graphics *gra=this->gra; + if (ignore != -1) + this->ignore_button=ignore; + + navit_block(this->nav, 1); + graphics_overlay_disable(gra, 1); + this->root.p.x=0; + this->root.p.y=0; + this->root.background=this->background; +} + +void gui_internal_leave(struct gui_priv *this) { + graphics_draw_mode(this->gra, draw_mode_end); +} + +void gui_internal_set_click_coord(struct gui_priv *this, struct point *p) { + struct coord c; + struct coord_geo g; + struct attr attr; + struct transformation *trans; + attr_free(this->click_coord_geo); + this->click_coord_geo=NULL; + if (p) { + trans=navit_get_trans(this->nav); + transform_reverse(trans, p, &c); + dbg(lvl_debug,"x=0x%x y=0x%x", c.x, c.y); + this->clickp.pro=transform_get_projection(trans); + this->clickp.x=c.x; + this->clickp.y=c.y; + transform_to_geo(this->clickp.pro, &c, &g); + attr.u.coord_geo=&g; + attr.type=attr_click_coord_geo; + this->click_coord_geo=attr_dup(&attr); + } +} + +static void gui_internal_set_position_coord(struct gui_priv *this) { + struct transformation *trans; + struct attr attr,attrp; + struct coord c; + + attr_free(this->position_coord_geo); + this->position_coord_geo=NULL; + if (navit_get_attr(this->nav, attr_vehicle, &attr, NULL) && attr.u.vehicle + && vehicle_get_attr(attr.u.vehicle, attr_position_coord_geo, &attrp, NULL)) { + trans=navit_get_trans(this->nav); + this->position_coord_geo=attr_dup(&attrp); + this->vehiclep.pro=transform_get_projection(trans); + transform_from_geo(this->vehiclep.pro, attrp.u.coord_geo, &c); + this->vehiclep.x=c.x; + this->vehiclep.y=c.y; + } +} + +void gui_internal_enter_setup(struct gui_priv *this) { + if (!this->mouse_button_clicked_on_map) + gui_internal_set_position_coord(this); +} + +void gui_internal_cmd_menu(struct gui_priv *this, int ignore, char *href) { + dbg(lvl_debug,"enter"); + gui_internal_enter(this, ignore); + gui_internal_enter_setup(this); + // draw menu + if (href) + gui_internal_html_load_href(this, href, 0); + else + gui_internal_html_main_menu(this); +} + + + +static void gui_internal_cmd_log_do(struct gui_priv *this, struct widget *widget) { + if (widget->text && strlen(widget->text)) { + if (this->position_coord_geo) + navit_textfile_debug_log_at(this->nav, &this->vehiclep, "type=log_entry label=\"%s\"",widget->text); + else + navit_textfile_debug_log(this->nav, "type=log_entry label=\"%s\"",widget->text); + } + g_free(widget->text); + widget->text=NULL; + gui_internal_prune_menu(this, NULL); + gui_internal_check_exit(this); +} + +void gui_internal_cmd_log_clicked(struct gui_priv *this, struct widget *widget, void *data) { + gui_internal_cmd_log_do(this, widget->data); +} + + +void gui_internal_check_exit(struct gui_priv *this) { + struct graphics *gra=this->gra; + if (! this->root.children) { + gui_internal_search_idle_end(this); + gui_internal_search_list_destroy(this); + graphics_overlay_disable(gra, 0); + if (!navit_block(this->nav, 0)) { + if (this->redraw) + navit_draw(this->nav); + else + navit_draw_displaylist(this->nav); + } + } +} + +static int gui_internal_get_attr(struct gui_priv *this, enum attr_type type, struct attr *attr) { + switch (type) { + case attr_active: + attr->u.num=this->root.children != NULL; + break; + case attr_click_coord_geo: + if (!this->click_coord_geo) + return 0; + *attr=*this->click_coord_geo; + break; + case attr_position_coord_geo: + if (!this->position_coord_geo) + return 0; + *attr=*this->position_coord_geo; + break; + case attr_pitch: + attr->u.num=this->pitch; + break; + case attr_button: + attr->u.num=this->mouse_button_clicked_on_map; + break; + case attr_navit: + attr->u.navit=this->nav; + break; + case attr_fullscreen: + attr->u.num=(this->fullscreen > 0); + break; + default: + return 0; + } + attr->type=type; + return 1; +} + +static int gui_internal_add_attr(struct gui_priv *this, struct attr *attr) { + switch (attr->type) { + case attr_xml_text: + g_free(this->html_text); + this->html_text=g_strdup(attr->u.str); + return 1; + default: + return 0; + } +} + +static int gui_internal_set_attr(struct gui_priv *this, struct attr *attr) { + switch (attr->type) { + case attr_fullscreen: + if ((this->fullscreen > 0) != (attr->u.num > 0)) { + graphics_draw_mode(this->gra, draw_mode_end); + this->win->fullscreen(this->win, attr->u.num > 0); + graphics_draw_mode(this->gra, draw_mode_begin); + } + this->fullscreen=attr->u.num; + return 1; + case attr_menu_on_map_click: + this->menu_on_map_click=attr->u.num; + return 1; + case attr_on_map_click: + g_free(this->on_map_click); + this->on_map_click=g_strdup(attr->u.str); + return 1; + default: + dbg(lvl_error,"Unknown attribute: %s",attr_to_name(attr->type)); + return 1; + } +} + +static void gui_internal_dbus_signal(struct gui_priv *this, struct point *p) { + struct displaylist_handle *dlh; + struct displaylist *display; + struct displayitem *di; + struct attr cb,**attr_list=NULL; + int valid=0; + + display=navit_get_displaylist(this->nav); + dlh=graphics_displaylist_open(display); + while ((di=graphics_displaylist_next(dlh))) { + struct item *item=graphics_displayitem_get_item(di); + if (item_is_point(*item) && graphics_displayitem_get_displayed(di) && + graphics_displayitem_within_dist(display, di, p, this->radius)) { + struct map_rect *mr=map_rect_new(item->map, NULL); + struct item *itemo=map_rect_get_item_byid(mr, item->id_hi, item->id_lo); + struct attr attr; + if (itemo && item_attr_get(itemo, attr_data, &attr)) + attr_list=attr_generic_add_attr(attr_list, &attr); + map_rect_destroy(mr); + } + } + graphics_displaylist_close(dlh); + if (attr_list && navit_get_attr(this->nav, attr_callback_list, &cb, NULL)) + callback_list_call_attr_4(cb.u.callback_list, attr_command, "dbus_send_signal", attr_list, NULL, &valid); + attr_list_free(attr_list); } /** @@ -2461,55 +2335,53 @@ static void gui_internal_dbus_signal(struct gui_priv *this, struct point *p) * * @author Martin Bruns (05/2012), mdankov */ -static int -gui_internal_coordinate_parse(char *s, char plus, char minus, double *x) -{ - int sign=0; - char *degree, *minute, *second; - double tmp; - - if(!s) - return 0; - - if (strchr(s, minus)!=NULL) - sign=-1; - else if (strchr(s, plus)!=NULL) - sign=1; - - if(!sign) - return 0; - - - /* Can't just use strtok here because ° is multibyte sequence in utf8 */ - degree=s; - minute=strstr(s,"°"); - if(minute) { - *minute=0; - minute+=strlen("°"); - } - - sscanf(degree, "%lf", x); - - if(strchr(degree, plus) || strchr(degree, minus)) { - dbg(lvl_debug,"degree %c/%c found\n",plus,minus); - } else {/* DEGREES_MINUTES */ - if(!minute) - return 0; - minute = strtok(minute,"'"); - sscanf(minute, "%lf", &tmp); - *x+=tmp/60; - if(strchr(minute, plus) || strchr(minute, minus)) { - dbg(lvl_debug,"minute %c/%c found\n",plus,minus); - } else { /* DEGREES_MINUTES_SECONDS */ - second=strtok(NULL,""); - if(!second) - return 0; - sscanf(second, "%lf", &tmp); - *x+=tmp/3600; - } - } - *x *= sign; - return 1; +static int gui_internal_coordinate_parse(char *s, char plus, char minus, double *x) { + int sign=0; + char *degree, *minute, *second; + double tmp; + + if(!s) + return 0; + + if (strchr(s, minus)!=NULL) + sign=-1; + else if (strchr(s, plus)!=NULL) + sign=1; + + if(!sign) + return 0; + + + /* Can't just use strtok here because ° is multibyte sequence in utf8 */ + degree=s; + minute=strstr(s,"°"); + if(minute) { + *minute=0; + minute+=strlen("°"); + } + + sscanf(degree, "%lf", x); + + if(strchr(degree, plus) || strchr(degree, minus)) { + dbg(lvl_debug,"degree %c/%c found",plus,minus); + } else {/* DEGREES_MINUTES */ + if(!minute) + return 0; + minute = strtok(minute,"'"); + sscanf(minute, "%lf", &tmp); + *x+=tmp/60; + if(strchr(minute, plus) || strchr(minute, minus)) { + dbg(lvl_debug,"minute %c/%c found",plus,minus); + } else { /* DEGREES_MINUTES_SECONDS */ + second=strtok(NULL,""); + if(!second) + return 0; + sscanf(second, "%lf", &tmp); + *x+=tmp/3600; + } + } + *x *= sign; + return 1; } //############################################################################################################## @@ -2517,35 +2389,34 @@ gui_internal_coordinate_parse(char *s, char plus, char minus, double *x) //# Comment: //# Authors: Martin Bruns (05/2012) //############################################################################################################## -static void -gui_internal_cmd_enter_coord_do(struct gui_priv *this, struct widget *widget) -{ - char *lat, *lng; - char *widgettext; - double latitude, longitude; - dbg(lvl_debug,"text entered:%s\n", widget->text); - - /* possible entry can be identical to coord_format output but only space between lat and lng is allowed */ - widgettext=g_ascii_strup(widget->text,-1); - - lat=strtok(widgettext," "); - lng=strtok(NULL,""); - - if(!lat || !lng){ - g_free(widgettext); - return; - } - if( gui_internal_coordinate_parse(lat, 'N', 'S', &latitude) && gui_internal_coordinate_parse(lng, 'E', 'W', &longitude) ) { - g_free(widgettext); - widgettext=g_strdup_printf("%lf %lf", longitude, latitude); - pcoord_parse(widgettext, projection_mg, &widget->c ); - } else if(!pcoord_parse(widget->text, projection_mg, &widget->c )) { - g_free(widgettext); - return; - } - g_free(widgettext); - - gui_internal_cmd_position(this, widget, (void*)8); +static void gui_internal_cmd_enter_coord_do(struct gui_priv *this, struct widget *widget) { + char *lat, *lng; + char *widgettext; + double latitude, longitude; + dbg(lvl_debug,"text entered:%s", widget->text); + + /* possible entry can be identical to coord_format output but only space between lat and lng is allowed */ + widgettext=g_ascii_strup(widget->text,-1); + + lat=strtok(widgettext," "); + lng=strtok(NULL,""); + + if(!lat || !lng) { + g_free(widgettext); + return; + } + if( gui_internal_coordinate_parse(lat, 'N', 'S', &latitude) + && gui_internal_coordinate_parse(lng, 'E', 'W', &longitude) ) { + g_free(widgettext); + widgettext=g_strdup_printf("%lf %lf", longitude, latitude); + pcoord_parse(widgettext, projection_mg, &widget->c ); + } else if(!pcoord_parse(widget->text, projection_mg, &widget->c )) { + g_free(widgettext); + return; + } + g_free(widgettext); + + gui_internal_cmd_position(this, widget, (void*)8); } //############################################################################################################## @@ -2553,11 +2424,9 @@ gui_internal_cmd_enter_coord_do(struct gui_priv *this, struct widget *widget) //# Comment: //# Authors: Martin Bruns (05/2012) //############################################################################################################## -void -gui_internal_cmd_enter_coord_clicked(struct gui_priv *this, struct widget *widget, void *data) -{ - dbg(lvl_debug,"entered\n"); - gui_internal_cmd_enter_coord_do(this, widget->data); +void gui_internal_cmd_enter_coord_clicked(struct gui_priv *this, struct widget *widget, void *data) { + dbg(lvl_debug,"entered"); + gui_internal_cmd_enter_coord_do(this, widget->data); } /** @@ -2565,263 +2434,271 @@ gui_internal_cmd_enter_coord_clicked(struct gui_priv *this, struct widget *widge * * @author Martin Schaller (04/2008), Stefan Klumpp (04/2008) */ -static void gui_internal_button(void *data, int pressed, int button, struct point *p) -{ - struct gui_priv *this=data; - struct graphics *gra=this->gra; - - dbg(lvl_debug,"enter %d %d\n", pressed, button); - // if still on the map (not in the menu, yet): - dbg(lvl_debug,"children=%p ignore_button=%d\n",this->root.children,this->ignore_button); - if (!this->root.children || this->ignore_button) { - - this->ignore_button=0; - // check whether the position of the mouse changed during press/release OR if it is the scrollwheel - if (!navit_handle_button(this->nav, pressed, button, p, NULL)) { - dbg(lvl_debug,"navit has handled button\n"); - return; - } - dbg(lvl_debug,"menu_on_map_click=%d\n",this->menu_on_map_click); - if (button != 1) - return; - if (this->on_map_click || this->menu_on_map_click) { - this->mouse_button_clicked_on_map=1; - gui_internal_set_click_coord(this, p); - gui_internal_set_position_coord(this); - if (this->on_map_click) - command_evaluate(&this->self, this->on_map_click); - else - gui_internal_cmd_menu(this, 0, NULL); - this->mouse_button_clicked_on_map=0; - } else if (this->signal_on_map_click) { - gui_internal_dbus_signal(this, p); - return; - } - return; - } - - - /* - * If already in the menu: - */ - - if (pressed) { - this->pressed=1; - this->current=*p; - gui_internal_gesture_ring_clear(this); - gui_internal_gesture_ring_add(this, p); - gui_internal_highlight(this); - } else { - int dx,dy; - gui_internal_gesture_ring_add(this, p); - gui_internal_gesture_get_vector(this, 300, NULL, &dx, &dy); - this->current.x=-1; - this->current.y=-1; - graphics_draw_mode(gra, draw_mode_begin); - if(!gui_internal_gesture_do(this) && this->pressed!=2 && abs(dx)<this->icon_s && abs(dy)<this->icon_s) - gui_internal_call_highlighted(this); - this->pressed=0; - if (!event_main_loop_has_quit()) { - gui_internal_highlight(this); - graphics_draw_mode(gra, draw_mode_end); - gui_internal_check_exit(this); - } - } -} - -static void -gui_internal_setup(struct gui_priv *this) -{ - struct color cbh={0x9fff,0x9fff,0x9fff,0xffff}; - struct color cf={0xbfff,0xbfff,0xbfff,0xffff}; - struct graphics *gra=this->gra; - unsigned char *buffer; - char *gui_file; - int size; - - if (this->background) - return; - this->background=graphics_gc_new(gra); - this->background2=graphics_gc_new(gra); - this->highlight_background=graphics_gc_new(gra); - graphics_gc_set_foreground(this->highlight_background, &cbh); - this->foreground=graphics_gc_new(gra); - graphics_gc_set_foreground(this->foreground, &cf); - this->text_background=graphics_gc_new(gra); - this->text_foreground=graphics_gc_new(gra); - graphics_gc_set_foreground(this->background, &this->background_color); - graphics_gc_set_foreground(this->background2, &this->background2_color); - graphics_gc_set_foreground(this->text_background, &this->text_background_color); - graphics_gc_set_foreground(this->text_foreground, &this->text_foreground_color); - gui_file=g_strjoin(NULL, navit_get_user_data_directory(TRUE), "/gui_internal.txt", NULL); - if (file_get_contents(gui_file,&buffer,&size)) { - char *command=g_malloc(size+1); - strncpy(command,(const char *)buffer,size); - command[size]=0; - command_evaluate(&this->self, command); - g_free(command); - g_free(buffer); - } - g_free(gui_file); +static void gui_internal_button(void *data, int pressed, int button, struct point *p) { + struct gui_priv *this=data; + struct graphics *gra=this->gra; + + dbg(lvl_debug,"enter %d %d", pressed, button); + // if still on the map (not in the menu, yet): + dbg(lvl_debug,"children=%p ignore_button=%d",this->root.children,this->ignore_button); + if (!this->root.children || this->ignore_button) { + + this->ignore_button=0; + // check whether the position of the mouse changed during press/release OR if it is the scrollwheel + if (!navit_handle_button(this->nav, pressed, button, p, NULL)) { + dbg(lvl_debug,"navit has handled button"); + return; + } + dbg(lvl_debug,"menu_on_map_click=%d",this->menu_on_map_click); + if (button != 1) + return; + if (this->on_map_click || this->menu_on_map_click) { + this->mouse_button_clicked_on_map=1; + gui_internal_set_click_coord(this, p); + gui_internal_set_position_coord(this); + if (this->on_map_click) + command_evaluate(&this->self, this->on_map_click); + else + gui_internal_cmd_menu(this, 0, NULL); + this->mouse_button_clicked_on_map=0; + } else if (this->signal_on_map_click) { + gui_internal_dbus_signal(this, p); + return; + } + return; + } + + + /* + * If already in the menu: + */ + + if (pressed) { + this->pressed=1; + this->current=*p; + gui_internal_gesture_ring_clear(this); + gui_internal_gesture_ring_add(this, p); + gui_internal_highlight(this); + } else { + int dx,dy; + gui_internal_gesture_ring_add(this, p); + gui_internal_gesture_get_vector(this, 300, NULL, &dx, &dy); + this->current.x=-1; + this->current.y=-1; + graphics_draw_mode(gra, draw_mode_begin); + if(!gui_internal_gesture_do(this) && this->pressed!=2 && abs(dx)<this->icon_s && abs(dy)<this->icon_s) + gui_internal_call_highlighted(this); + this->pressed=0; + if (!event_main_loop_has_quit()) { + gui_internal_highlight(this); + graphics_draw_mode(gra, draw_mode_end); + gui_internal_check_exit(this); + } + } +} + +static void gui_internal_setup(struct gui_priv *this) { + struct color cbh= {0x9fff,0x9fff,0x9fff,0xffff}; + struct color cf= {0xbfff,0xbfff,0xbfff,0xffff}; + struct graphics *gra=this->gra; + unsigned char *buffer; + char *gui_file; + int size; + + if (this->background) + return; + this->background=graphics_gc_new(gra); + this->background2=graphics_gc_new(gra); + this->highlight_background=graphics_gc_new(gra); + graphics_gc_set_foreground(this->highlight_background, &cbh); + this->foreground=graphics_gc_new(gra); + graphics_gc_set_foreground(this->foreground, &cf); + this->text_background=graphics_gc_new(gra); + this->text_foreground=graphics_gc_new(gra); + graphics_gc_set_foreground(this->background, &this->background_color); + graphics_gc_set_foreground(this->background2, &this->background2_color); + graphics_gc_set_foreground(this->text_background, &this->text_background_color); + graphics_gc_set_foreground(this->text_foreground, &this->text_foreground_color); + gui_file=g_strjoin(NULL, navit_get_user_data_directory(TRUE), "/gui_internal.txt", NULL); + if (file_get_contents(gui_file,&buffer,&size)) { + char *command=g_malloc(size+1); + strncpy(command,(const char *)buffer,size); + command[size]=0; + command_evaluate(&this->self, command); + g_free(command); + g_free(buffer); + } + g_free(gui_file); +} + +/** + * @brief Callback function invoked when display area is resized + * + * @param data A generic argument structure pointer, here we use it to store the the internal GUI context (this) + * @param wnew The new width of the display area + * @param hnew The new height of the display area + * + * @author Martin Schaller + * @date 2008/04 + */ +static void gui_internal_resize(void *data, int wnew, int hnew) { + GList *l; + struct widget *w; + + struct gui_priv *this=data; + int changed=0; + + gui_internal_setup(this); + + changed=gui_internal_menu_needs_resizing(this, &(this->root), wnew, hnew); + + /* + * If we're drawing behind system bars on Android, watching for actual size changes will not catch + * fullscreen toggle events. As a workaround, always assume a size change if padding is supplied. + */ + if (!changed && this->gra && graphics_get_data(this->gra, "padding")) + changed = 1; + navit_handle_resize(this->nav, wnew, hnew); + if (this->root.children) { + if (changed) { + l = g_list_last(this->root.children); + if (l) { + w=l->data; + if (!gui_internal_widget_reload_href(this, + w)) { /* If the foremost widget is a HTML menu, reload & redraw it from its href */ + /* If not, resize the foremost widget */ + dbg(lvl_debug, "Current GUI displayed is not a menu"); + dbg(lvl_debug, "Will call resize with w=%d, h=%d", wnew, hnew) + gui_internal_menu_resize(this, wnew, hnew); + gui_internal_menu_render(this); + } else { + dbg(lvl_debug,"Current GUI displayed is a menu"); + } + } + } else { + gui_internal_menu_render(this); + } + } } -//############################################################################################################## -//# Description: -//# Comment: -//# Authors: Martin Schaller (04/2008) -//############################################################################################################## -static void gui_internal_resize(void *data, int w, int h) -{ - struct gui_priv *this=data; - int changed=0; - - gui_internal_setup(this); - - if (this->root.w != w || this->root.h != h) { - this->root.w=w; - this->root.h=h; - changed=1; - } - /* - * If we're drawing behind system bars on Android, watching for actual size changes will not catch - * fullscreen toggle events. As a workaround, always assume a size change if padding is supplied. - */ - if (!changed && this->gra && graphics_get_data(this->gra, "padding")) - changed = 1; - dbg(lvl_debug,"w=%d h=%d children=%p\n", w, h, this->root.children); - navit_handle_resize(this->nav, w, h); - if (this->root.children) { - if (changed) { - gui_internal_html_main_menu(this); - } else { - gui_internal_menu_render(this); - } - } -} - -static void -gui_internal_keynav_point(struct widget *w, int dx, int dy, struct point *p) -{ - p->x=w->p.x+w->w/2; - p->y=w->p.y+w->h/2; - if (dx < 0) - p->x=w->p.x; - if (dx > 0) - p->x=w->p.x+w->w; - if (dy < 0) - p->y=w->p.y; - if (dy > 0) - p->y=w->p.y+w->h; -} - -static struct widget* -gui_internal_keynav_find_next_sensitive_child(struct widget *wi) { - GList *l=wi->children; - if (wi->state & STATE_OFFSCREEN) - return NULL; - if (wi->state & STATE_SENSITIVE) - return wi; - while (l) { - struct widget* tmp = gui_internal_keynav_find_next_sensitive_child(l->data); - if (tmp) - return tmp; - l=g_list_next(l); - } - return NULL; -} - -static int -gui_internal_keynav_find_next(struct widget *wi, struct widget *current_highlight, struct widget **result) { - GList *l=wi->children; - if (wi == current_highlight) - return 1; - while (l) { - struct widget *child=l->data; - l=g_list_next(l); - if (gui_internal_keynav_find_next(child, current_highlight, result)) { - while (l) { - struct widget *new = gui_internal_keynav_find_next_sensitive_child(l->data); - if (new) { - *result = new; - /* Found one! */ - return 0; - } - l=g_list_next(l); - } - /* Try parent */ - return 1; - } - } - return 0; +static void gui_internal_keynav_point(struct widget *w, int dx, int dy, struct point *p) { + p->x=w->p.x+w->w/2; + p->y=w->p.y+w->h/2; + if (dx < 0) + p->x=w->p.x; + if (dx > 0) + p->x=w->p.x+w->w; + if (dy < 0) + p->y=w->p.y; + if (dy > 0) + p->y=w->p.y+w->h; +} + +static struct widget* gui_internal_keynav_find_next_sensitive_child(struct widget *wi) { + GList *l=wi->children; + if (wi->state & STATE_OFFSCREEN) + return NULL; + if (wi->state & STATE_SENSITIVE) + return wi; + while (l) { + struct widget* tmp = gui_internal_keynav_find_next_sensitive_child(l->data); + if (tmp) + return tmp; + l=g_list_next(l); + } + return NULL; +} + +static int gui_internal_keynav_find_next(struct widget *wi, struct widget *current_highlight, struct widget **result) { + GList *l=wi->children; + if (wi == current_highlight) + return 1; + while (l) { + struct widget *child=l->data; + l=g_list_next(l); + if (gui_internal_keynav_find_next(child, current_highlight, result)) { + while (l) { + struct widget *new = gui_internal_keynav_find_next_sensitive_child(l->data); + if (new) { + *result = new; + /* Found one! */ + return 0; + } + l=g_list_next(l); + } + /* Try parent */ + return 1; + } + } + return 0; } #define RESULT_FOUND 1 #define NO_RESULT_YET 0 -static int -gui_internal_keynav_find_prev(struct widget *wi, struct widget *current_highlight, struct widget **result) { - if (wi == current_highlight && *result) { - // Reached current widget; last widget found is the result. - return RESULT_FOUND; - } - // If widget is off-screen, do not recurse into it. - if (wi->state & STATE_OFFSCREEN) - return NO_RESULT_YET; - if (wi->state & STATE_SENSITIVE) - *result= wi; - GList *l=wi->children; - while (l) { - struct widget *child=l->data; - if (gui_internal_keynav_find_prev(child, current_highlight, result) == RESULT_FOUND) { - return RESULT_FOUND; - } - l=g_list_next(l); - } - // If no sensitive widget is found before "current_highlight", return the last sensitive widget when - // recursion terminates. - return NO_RESULT_YET; -} - -static void -gui_internal_keynav_find_closest(struct widget *wi, struct point *p, int dx, int dy, int *distance, struct widget **result) -{ - GList *l=wi->children; - // Skip hidden elements - if (wi->p.x==0 && wi->p.y==0 && wi->w==0 && wi->h==0) - return; - if ((wi->state & STATE_SENSITIVE) ) { - int dist1,dist2; - struct point wp; - gui_internal_keynav_point(wi, -dx, -dy, &wp); - if (dx) { - dist1=(wp.x-p->x)*dx; - dist2=wp.y-p->y; - } else if (dy) { - dist1=(wp.y-p->y)*dy; - dist2=wp.x-p->x; - } else { - dist2=wp.x-p->x; - dist1=wp.y-p->y; - if (dist1 < 0) - dist1=-dist1; - } - dbg(lvl_debug,"checking %d,%d %d %d against %d,%d-%d,%d result %d,%d\n", p->x, p->y, dx, dy, wi->p.x, wi->p.y, wi->p.x+wi->w, wi->p.y+wi->h, dist1, dist2); - if (dist1 >= 0) { - if (dist2 < 0) - dist1-=dist2; - else - dist1+=dist2; - if (dist1 < *distance) { - *result=wi; - *distance=dist1; - } - } - } - while (l) { - struct widget *child=l->data; - gui_internal_keynav_find_closest(child, p, dx, dy, distance, result); - l=g_list_next(l); - } +static int gui_internal_keynav_find_prev(struct widget *wi, struct widget *current_highlight, struct widget **result) { + if (wi == current_highlight && *result) { + // Reached current widget; last widget found is the result. + return RESULT_FOUND; + } + // If widget is off-screen, do not recurse into it. + if (wi->state & STATE_OFFSCREEN) + return NO_RESULT_YET; + if (wi->state & STATE_SENSITIVE) + *result= wi; + GList *l=wi->children; + while (l) { + struct widget *child=l->data; + if (gui_internal_keynav_find_prev(child, current_highlight, result) == RESULT_FOUND) { + return RESULT_FOUND; + } + l=g_list_next(l); + } + // If no sensitive widget is found before "current_highlight", return the last sensitive widget when + // recursion terminates. + return NO_RESULT_YET; +} + +static void gui_internal_keynav_find_closest(struct widget *wi, struct point *p, int dx, int dy, int *distance, + struct widget **result) { + GList *l=wi->children; + // Skip hidden elements + if (wi->p.x==0 && wi->p.y==0 && wi->w==0 && wi->h==0) + return; + if ((wi->state & STATE_SENSITIVE) ) { + int dist1,dist2; + struct point wp; + gui_internal_keynav_point(wi, -dx, -dy, &wp); + if (dx) { + dist1=(wp.x-p->x)*dx; + dist2=wp.y-p->y; + } else if (dy) { + dist1=(wp.y-p->y)*dy; + dist2=wp.x-p->x; + } else { + dist2=wp.x-p->x; + dist1=wp.y-p->y; + if (dist1 < 0) + dist1=-dist1; + } + dbg(lvl_debug,"checking %d,%d %d %d against %d,%d-%d,%d result %d,%d", p->x, p->y, dx, dy, wi->p.x, wi->p.y, + wi->p.x+wi->w, wi->p.y+wi->h, dist1, dist2); + if (dist1 >= 0) { + if (dist2 < 0) + dist1-=dist2; + else + dist1+=dist2; + if (dist1 < *distance) { + *result=wi; + *distance=dist1; + } + } + } + while (l) { + struct widget *child=l->data; + gui_internal_keynav_find_closest(child, p, dx, dy, distance, result); + l=g_list_next(l); + } } /** @@ -2836,59 +2713,56 @@ gui_internal_keynav_find_closest(struct widget *wi, struct point *p, int dx, int * @param rotary (0/1) input from rotary encoder - dx indicates forwards/backwards movement * through all widgets */ -static void -gui_internal_keynav_highlight_next(struct gui_priv *this, int dx, int dy, int rotary) -{ - struct widget *result,*menu=g_list_last(this->root.children)->data; - struct widget *current_highlight = NULL; - struct point p; - int distance; - if (this->highlighted && this->highlighted_menu == menu) { - gui_internal_keynav_point(this->highlighted, dx, dy, &p); - current_highlight = this->highlighted; - } - else { - p.x=0; - p.y=0; - distance=INT_MAX; - result=NULL; - gui_internal_keynav_find_closest(menu, &p, 0, 0, &distance, &result); - if (result) { - gui_internal_keynav_point(result, dx, dy, &p); - dbg(lvl_debug,"result origin=%p p=%d,%d\n", result, p.x, p.y); - current_highlight = result; - } - } - result=NULL; - distance=INT_MAX; - if (rotary && dx > 0) - gui_internal_keynav_find_next(menu, current_highlight, &result); - else if (rotary && dx < 0) - gui_internal_keynav_find_prev(menu, current_highlight, &result); - else - gui_internal_keynav_find_closest(menu, &p, dx, dy, &distance, &result); - dbg(lvl_debug,"result=%p\n", result); - if (! result) { - if (dx < 0) { - p.x=this->root.w; - if (rotary) p.y = this->root.h; - } - if (dx > 0) { - p.x=0; - if (rotary) p.y = 0; - } - if (dy < 0) - p.y=this->root.h; - if (dy > 0) - p.y=0; - result=NULL; - distance=INT_MAX; - gui_internal_keynav_find_closest(menu, &p, dx, dy, &distance, &result); - dbg(lvl_debug,"wraparound result=%p\n", result); - } - gui_internal_highlight_do(this, result); - if (result) - gui_internal_say(this, result, 1); +static void gui_internal_keynav_highlight_next(struct gui_priv *this, int dx, int dy, int rotary) { + struct widget *result,*menu=g_list_last(this->root.children)->data; + struct widget *current_highlight = NULL; + struct point p; + int distance; + if (this->highlighted && this->highlighted_menu == menu) { + gui_internal_keynav_point(this->highlighted, dx, dy, &p); + current_highlight = this->highlighted; + } else { + p.x=0; + p.y=0; + distance=INT_MAX; + result=NULL; + gui_internal_keynav_find_closest(menu, &p, 0, 0, &distance, &result); + if (result) { + gui_internal_keynav_point(result, dx, dy, &p); + dbg(lvl_debug,"result origin=%p p=%d,%d", result, p.x, p.y); + current_highlight = result; + } + } + result=NULL; + distance=INT_MAX; + if (rotary && dx > 0) + gui_internal_keynav_find_next(menu, current_highlight, &result); + else if (rotary && dx < 0) + gui_internal_keynav_find_prev(menu, current_highlight, &result); + else + gui_internal_keynav_find_closest(menu, &p, dx, dy, &distance, &result); + dbg(lvl_debug,"result=%p", result); + if (! result) { + if (dx < 0) { + p.x=this->root.w; + if (rotary) p.y = this->root.h; + } + if (dx > 0) { + p.x=0; + if (rotary) p.y = 0; + } + if (dy < 0) + p.y=this->root.h; + if (dy > 0) + p.y=0; + result=NULL; + distance=INT_MAX; + gui_internal_keynav_find_closest(menu, &p, dx, dy, &distance, &result); + dbg(lvl_debug,"wraparound result=%p", result); + } + gui_internal_highlight_do(this, result); + if (result) + gui_internal_say(this, result, 1); } //############################################################################################################## @@ -2896,87 +2770,86 @@ gui_internal_keynav_highlight_next(struct gui_priv *this, int dx, int dy, int ro //# Comment: //# Authors: Martin Schaller (04/2008) //############################################################################################################## -static void gui_internal_keypress(void *data, char *key) -{ - struct gui_priv *this=data; - int w,h; - struct point p; - if (!this->root.children) { - transform_get_size(navit_get_trans(this->nav), &w, &h); - switch (*key) { - case NAVIT_KEY_UP: - p.x=w/2; - p.y=0; - navit_set_center_screen(this->nav, &p, 1); - break; - case NAVIT_KEY_DOWN: - p.x=w/2; - p.y=h; - navit_set_center_screen(this->nav, &p, 1); - break; - case NAVIT_KEY_LEFT: - p.x=0; - p.y=h/2; - navit_set_center_screen(this->nav, &p, 1); - break; - case NAVIT_KEY_RIGHT: - p.x=w; - p.y=h/2; - navit_set_center_screen(this->nav, &p, 1); - break; - case NAVIT_KEY_ZOOM_IN: - navit_zoom_in(this->nav, 2, NULL); - break; - case NAVIT_KEY_ZOOM_OUT: - navit_zoom_out(this->nav, 2, NULL); - break; - case NAVIT_KEY_RETURN: - case NAVIT_KEY_MENU: - gui_internal_set_click_coord(this, NULL); - gui_internal_cmd_menu(this, 0, NULL); - break; - } - return; - } - graphics_draw_mode(this->gra, draw_mode_begin); - switch (*key) { - case NAVIT_KEY_PAGE_DOWN: - gui_internal_keynav_highlight_next(this,1,0,1); - break; - case NAVIT_KEY_PAGE_UP: - gui_internal_keynav_highlight_next(this,-1,0,1); - break; - case NAVIT_KEY_LEFT: - gui_internal_keynav_highlight_next(this,-1,0,0); - break; - case NAVIT_KEY_RIGHT: - gui_internal_keynav_highlight_next(this,1,0,0); - break; - case NAVIT_KEY_UP: - gui_internal_keynav_highlight_next(this,0,-1,0); - break; - case NAVIT_KEY_DOWN: - gui_internal_keynav_highlight_next(this,0,1,0); - break; - case NAVIT_KEY_BACK: - if (g_list_length(this->root.children) > 1) - gui_internal_back(this, NULL, NULL); - else - gui_internal_prune_menu(this, NULL); - break; - case NAVIT_KEY_RETURN: - if (this->highlighted && this->highlighted_menu == g_list_last(this->root.children)->data) - gui_internal_call_highlighted(this); - else - gui_internal_keypress_do(this, key); - break; - default: - gui_internal_keypress_do(this, key); - } - if (!event_main_loop_has_quit()) { - graphics_draw_mode(this->gra, draw_mode_end); - gui_internal_check_exit(this); - } +static void gui_internal_keypress(void *data, char *key) { + struct gui_priv *this=data; + int w,h; + struct point p; + if (!this->root.children) { + transform_get_size(navit_get_trans(this->nav), &w, &h); + switch (*key) { + case NAVIT_KEY_UP: + p.x=w/2; + p.y=0; + navit_set_center_screen(this->nav, &p, 1); + break; + case NAVIT_KEY_DOWN: + p.x=w/2; + p.y=h; + navit_set_center_screen(this->nav, &p, 1); + break; + case NAVIT_KEY_LEFT: + p.x=0; + p.y=h/2; + navit_set_center_screen(this->nav, &p, 1); + break; + case NAVIT_KEY_RIGHT: + p.x=w; + p.y=h/2; + navit_set_center_screen(this->nav, &p, 1); + break; + case NAVIT_KEY_ZOOM_IN: + navit_zoom_in(this->nav, 2, NULL); + break; + case NAVIT_KEY_ZOOM_OUT: + navit_zoom_out(this->nav, 2, NULL); + break; + case NAVIT_KEY_RETURN: + case NAVIT_KEY_MENU: + gui_internal_set_click_coord(this, NULL); + gui_internal_cmd_menu(this, 0, NULL); + break; + } + return; + } + graphics_draw_mode(this->gra, draw_mode_begin); + switch (*key) { + case NAVIT_KEY_PAGE_DOWN: + gui_internal_keynav_highlight_next(this,1,0,1); + break; + case NAVIT_KEY_PAGE_UP: + gui_internal_keynav_highlight_next(this,-1,0,1); + break; + case NAVIT_KEY_LEFT: + gui_internal_keynav_highlight_next(this,-1,0,0); + break; + case NAVIT_KEY_RIGHT: + gui_internal_keynav_highlight_next(this,1,0,0); + break; + case NAVIT_KEY_UP: + gui_internal_keynav_highlight_next(this,0,-1,0); + break; + case NAVIT_KEY_DOWN: + gui_internal_keynav_highlight_next(this,0,1,0); + break; + case NAVIT_KEY_BACK: + if (g_list_length(this->root.children) > 1) + gui_internal_back(this, NULL, NULL); + else + gui_internal_prune_menu(this, NULL); + break; + case NAVIT_KEY_RETURN: + if (this->highlighted && this->highlighted_menu == g_list_last(this->root.children)->data) + gui_internal_call_highlighted(this); + else + gui_internal_keypress_do(this, key); + break; + default: + gui_internal_keypress_do(this, key); + } + if (!event_main_loop_has_quit()) { + graphics_draw_mode(this->gra, draw_mode_end); + gui_internal_check_exit(this); + } } @@ -2985,45 +2858,43 @@ static void gui_internal_keypress(void *data, char *key) //# Comment: //# Authors: Martin Schaller (04/2008) //############################################################################################################## -static int gui_internal_set_graphics(struct gui_priv *this, struct graphics *gra) -{ - struct window *win; - struct transformation *trans=navit_get_trans(this->nav); - - win=graphics_get_data(gra, "window"); - if (! win) { - dbg(lvl_error, "failed to obtain window from graphics plugin, cannot set graphics\n"); - return 1; - } - navit_ignore_graphics_events(this->nav, 1); - this->gra=gra; - this->win=win; - navit_ignore_graphics_events(this->nav, 1); - transform_get_size(trans, &this->root.w, &this->root.h); - this->resize_cb=callback_new_attr_1(callback_cast(gui_internal_resize), attr_resize, this); - graphics_add_callback(gra, this->resize_cb); - this->button_cb=callback_new_attr_1(callback_cast(gui_internal_button), attr_button, this); - graphics_add_callback(gra, this->button_cb); - this->motion_cb=callback_new_attr_1(callback_cast(gui_internal_motion), attr_motion, this); - graphics_add_callback(gra, this->motion_cb); - this->keypress_cb=callback_new_attr_1(callback_cast(gui_internal_keypress), attr_keypress, this); - graphics_add_callback(gra, this->keypress_cb); - this->window_closed_cb=callback_new_attr_1(callback_cast(gui_internal_window_closed), attr_window_closed, this); - graphics_add_callback(gra, this->window_closed_cb); - - // set fullscreen if needed - if (this->fullscreen) - this->win->fullscreen(this->win, this->fullscreen != 0); - /* Was resize callback already issued? */ - if (navit_get_ready(this->nav) & 2) - gui_internal_setup(this); - return 0; -} - -static void gui_internal_disable_suspend(struct gui_priv *this) -{ - if (this->win->disable_suspend) - this->win->disable_suspend(this->win); +static int gui_internal_set_graphics(struct gui_priv *this, struct graphics *gra) { + struct window *win; + struct transformation *trans=navit_get_trans(this->nav); + + win=graphics_get_data(gra, "window"); + if (! win) { + dbg(lvl_error, "failed to obtain window from graphics plugin, cannot set graphics"); + return 1; + } + navit_ignore_graphics_events(this->nav, 1); + this->gra=gra; + this->win=win; + navit_ignore_graphics_events(this->nav, 1); + transform_get_size(trans, &this->root.w, &this->root.h); + this->resize_cb=callback_new_attr_1(callback_cast(gui_internal_resize), attr_resize, this); + graphics_add_callback(gra, this->resize_cb); + this->button_cb=callback_new_attr_1(callback_cast(gui_internal_button), attr_button, this); + graphics_add_callback(gra, this->button_cb); + this->motion_cb=callback_new_attr_1(callback_cast(gui_internal_motion), attr_motion, this); + graphics_add_callback(gra, this->motion_cb); + this->keypress_cb=callback_new_attr_1(callback_cast(gui_internal_keypress), attr_keypress, this); + graphics_add_callback(gra, this->keypress_cb); + this->window_closed_cb=callback_new_attr_1(callback_cast(gui_internal_window_closed), attr_window_closed, this); + graphics_add_callback(gra, this->window_closed_cb); + + // set fullscreen if needed + if (this->fullscreen) + this->win->fullscreen(this->win, this->fullscreen != 0); + /* Was resize callback already issued? */ + if (navit_get_ready(this->nav) & 2) + gui_internal_setup(this); + return 0; +} + +static void gui_internal_disable_suspend(struct gui_priv *this) { + if (this->win->disable_suspend) + this->win->disable_suspend(this->win); } //############################################################################################################## @@ -3032,181 +2903,159 @@ static void gui_internal_disable_suspend(struct gui_priv *this) //# Authors: Martin Schaller (04/2008) //############################################################################################################## struct gui_methods gui_internal_methods = { - NULL, - NULL, - gui_internal_set_graphics, - NULL, - NULL, - NULL, - gui_internal_disable_suspend, - gui_internal_get_attr, - gui_internal_add_attr, - gui_internal_set_attr, + NULL, + NULL, + gui_internal_set_graphics, + NULL, + NULL, + NULL, + gui_internal_disable_suspend, + gui_internal_get_attr, + gui_internal_add_attr, + gui_internal_set_attr, }; -static void -gui_internal_add_callback(struct gui_priv *priv, struct callback *cb) -{ - callback_list_add(priv->cbl, cb); +static void gui_internal_add_callback(struct gui_priv *priv, struct callback *cb) { + callback_list_add(priv->cbl, cb); } -static void -gui_internal_remove_callback(struct gui_priv *priv, struct callback *cb) -{ - callback_list_remove(priv->cbl, cb); +static void gui_internal_remove_callback(struct gui_priv *priv, struct callback *cb) { + callback_list_remove(priv->cbl, cb); } static struct gui_internal_methods gui_internal_methods_ext = { - gui_internal_add_callback, - gui_internal_remove_callback, - gui_internal_menu_render, - image_new_xs, - image_new_l, + gui_internal_add_callback, + gui_internal_remove_callback, + gui_internal_menu_render, + image_new_xs, + image_new_l, }; -static enum flags -gui_internal_get_flags(struct widget *widget) -{ - return widget->flags; +static enum flags gui_internal_get_flags(struct widget *widget) { + return widget->flags; } -static void -gui_internal_set_flags(struct widget *widget, enum flags flags) -{ - widget->flags=flags; +static void gui_internal_set_flags(struct widget *widget, enum flags flags) { + widget->flags=flags; } -static int -gui_internal_get_state(struct widget *widget) -{ - return widget->state; +static int gui_internal_get_state(struct widget *widget) { + return widget->state; } -static void -gui_internal_set_state(struct widget *widget, int state) -{ - widget->state=state; +static void gui_internal_set_state(struct widget *widget, int state) { + widget->state=state; } -static void -gui_internal_set_func(struct widget *widget, void (*func)(struct gui_priv *priv, struct widget *widget, void *data)) -{ - widget->func=func; +static void gui_internal_set_func(struct widget *widget, void (*func)(struct gui_priv *priv, struct widget *widget, + void *data)) { + widget->func=func; } -static void -gui_internal_set_data(struct widget *widget, void *data) -{ - widget->data=data; +static void gui_internal_set_data(struct widget *widget, void *data) { + widget->data=data; } -static void -gui_internal_set_default_background(struct gui_priv *this, struct widget *widget) -{ - widget->background=this->background; +static void gui_internal_set_default_background(struct gui_priv *this, struct widget *widget) { + widget->background=this->background; } static struct gui_internal_widget_methods gui_internal_widget_methods = { - gui_internal_widget_append, - gui_internal_button_new, - gui_internal_button_new_with_callback, - gui_internal_box_new, - gui_internal_label_new, - gui_internal_image_new, - gui_internal_keyboard, - gui_internal_menu, - gui_internal_get_flags, - gui_internal_set_flags, - gui_internal_get_state, - gui_internal_set_state, - gui_internal_set_func, - gui_internal_set_data, - gui_internal_set_default_background, + gui_internal_widget_append, + gui_internal_button_new, + gui_internal_button_new_with_callback, + gui_internal_box_new, + gui_internal_label_new, + gui_internal_image_new, + gui_internal_keyboard, + gui_internal_menu, + gui_internal_get_flags, + gui_internal_set_flags, + gui_internal_get_state, + gui_internal_set_state, + gui_internal_set_func, + gui_internal_set_data, + gui_internal_set_default_background, }; /** * @brief finds the intersection point of 2 lines * - * @param coord a1, a2, b1, b2 : coords of the start and + * @param coord a1, a2, b1, b2 : coords of the start and * end of the first and the second line * @param coord res, will become the coords of the intersection if found * @return : TRUE if intersection found, otherwise FALSE */ -int -line_intersection(struct coord* a1, struct coord *a2, struct coord * b1, struct coord *b2, struct coord *res) -{ - int n, a, b; - int adx=a2->x-a1->x; - int ady=a2->y-a1->y; - int bdx=b2->x-b1->x; - int bdy=b2->y-b1->y; - n = bdy * adx - bdx * ady; - a = bdx * (a1->y - b1->y) - bdy * (a1->x - b1->x); - b = adx * (a1->y - b1->y) - ady * (a1->x - b1->x); - if (n < 0) { - n = -n; - a = -a; - b = -b; - } - if (a < 0 || b < 0) - return FALSE; - if (a > n || b > n) - return FALSE; - if (n == 0) { - dbg(lvl_info,"a=%d b=%d n=%d\n", a, b, n); - dbg(lvl_info,"a1=0x%x,0x%x ad %d,%d\n", a1->x, a1->y, adx, ady); - dbg(lvl_info,"b1=0x%x,0x%x bd %d,%d\n", b1->x, b1->y, bdx, bdy); - dbg(lvl_info,"No intersection found, lines assumed parallel ?\n"); - return FALSE; - } - res->x = a1->x + a * adx / n; - res->y = a1->y + a * ady / n; - return TRUE; +int line_intersection(struct coord* a1, struct coord *a2, struct coord * b1, struct coord *b2, struct coord *res) { + int n, a, b; + int adx=a2->x-a1->x; + int ady=a2->y-a1->y; + int bdx=b2->x-b1->x; + int bdy=b2->y-b1->y; + n = bdy * adx - bdx * ady; + a = bdx * (a1->y - b1->y) - bdy * (a1->x - b1->x); + b = adx * (a1->y - b1->y) - ady * (a1->x - b1->x); + if (n < 0) { + n = -n; + a = -a; + b = -b; + } + if (a < 0 || b < 0) + return FALSE; + if (a > n || b > n) + return FALSE; + if (n == 0) { + dbg(lvl_info,"a=%d b=%d n=%d", a, b, n); + dbg(lvl_info,"a1=0x%x,0x%x ad %d,%d", a1->x, a1->y, adx, ady); + dbg(lvl_info,"b1=0x%x,0x%x bd %d,%d", b1->x, b1->y, bdx, bdy); + dbg(lvl_info,"No intersection found, lines assumed parallel ?"); + return FALSE; + } + res->x = a1->x + a * adx / n; + res->y = a1->y + a * ady / n; + return TRUE; } struct heightline * -item_get_heightline(struct item *item) -{ - struct heightline *ret=NULL; - struct street_data *sd; - struct attr attr; - int i,height; - - if (item_attr_get(item, attr_label, &attr)) { - height=atoi(attr.u.str); - sd=street_get_data(item); - if (sd && sd->count > 1) { - ret=g_malloc(sizeof(struct heightline)+sd->count*sizeof(struct coord)); - ret->bbox.lu=sd->c[0]; - ret->bbox.rl=sd->c[0]; - ret->count=sd->count; - ret->height=height; - for (i = 0 ; i < sd->count ; i++) { - ret->c[i]=sd->c[i]; - coord_rect_extend(&ret->bbox, sd->c+i); - } - } - street_data_free(sd); - } - return ret; +item_get_heightline(struct item *item) { + struct heightline *ret=NULL; + struct street_data *sd; + struct attr attr; + int i,height; + + if (item_attr_get(item, attr_label, &attr)) { + height=atoi(attr.u.str); + sd=street_get_data(item); + if (sd && sd->count > 1) { + ret=g_malloc(sizeof(struct heightline)+sd->count*sizeof(struct coord)); + ret->bbox.lu=sd->c[0]; + ret->bbox.rl=sd->c[0]; + ret->count=sd->count; + ret->height=height; + for (i = 0 ; i < sd->count ; i++) { + ret->c[i]=sd->c[i]; + coord_rect_extend(&ret->bbox, sd->c+i); + } + } + street_data_free(sd); + } + return ret; } /** * @brief Called when the route is updated. */ -void -gui_internal_route_update(struct gui_priv * this, struct navit * navit, struct vehicle *v) -{ +void gui_internal_route_update(struct gui_priv * this, struct navit * navit, struct vehicle *v) { - if(this->route_data.route_showing) { - gui_internal_populate_route_table(this,navit); - graphics_draw_mode(this->gra, draw_mode_begin); - gui_internal_menu_render(this); - graphics_draw_mode(this->gra, draw_mode_end); - } + if(this->route_data.route_showing) { + gui_internal_populate_route_table(this,navit); + graphics_draw_mode(this->gra, draw_mode_begin); + gui_internal_menu_render(this); + graphics_draw_mode(this->gra, draw_mode_end); + } } @@ -3218,14 +3067,12 @@ gui_internal_route_update(struct gui_priv * this, struct navit * navit, struct v * The main purpose of this function is to remove the widgets from * references route_data because those widgets are about to be freed. */ -void -gui_internal_route_screen_free(struct gui_priv * this_,struct widget * w) -{ - if(this_) { - this_->route_data.route_showing=0; - this_->route_data.route_table=NULL; - g_free(w); - } +void gui_internal_route_screen_free(struct gui_priv * this_,struct widget * w) { + if(this_) { + this_->route_data.route_showing=0; + this_->route_data.route_table=NULL; + g_free(w); + } } @@ -3235,85 +3082,83 @@ gui_internal_route_screen_free(struct gui_priv * this_,struct widget * w) * @param this The gui context * @param navit The navit object */ -void -gui_internal_populate_route_table(struct gui_priv * this, struct navit * navit) -{ - struct map * map=NULL; - struct map_rect * mr=NULL; - struct navigation * nav = NULL; - struct item * item =NULL; - struct attr attr,route; - struct widget * label = NULL; - struct widget * row = NULL; - struct coord c; - nav = navit_get_navigation(navit); - if(!nav) { - return; - } - map = navigation_get_map(nav); - if(map) - mr = map_rect_new(map,NULL); - if(mr) { - GList *toprow; - struct item topitem={0}; - toprow=gui_internal_widget_table_top_row(this, this->route_data.route_table); - if(toprow && toprow->data) - topitem=((struct widget*)toprow->data)->item; - gui_internal_widget_table_clear(this,this->route_data.route_table); - if (navit_get_attr(navit, attr_route, &route, NULL)) { - struct attr destination_length, destination_time; - char *length=NULL,*time=NULL,*length_time; - if (route_get_attr(route.u.route, attr_destination_length, &destination_length, NULL)) - length=attr_to_text_ext(&destination_length, NULL, attr_format_with_units, attr_format_default, NULL); - if (route_get_attr(route.u.route, attr_destination_time, &destination_time, NULL)) - time=attr_to_text_ext(&destination_time, NULL, attr_format_with_units, attr_format_default, NULL); - row = gui_internal_widget_table_row_new(this, - gravity_left - | flags_fill - | orientation_horizontal); - gui_internal_widget_append(this->route_data.route_table,row); - length_time=g_strdup_printf("%s %s",length,time); - label = gui_internal_label_new(this,length_time); - g_free(length_time); - g_free(length); - g_free(time); - gui_internal_widget_append(row,label); - } - while((item = map_rect_get_item(mr))) { - if(item_attr_get(item,attr_navigation_long,&attr)) { - row = gui_internal_widget_table_row_new(this, - gravity_left - | flags_fill - | orientation_horizontal); - gui_internal_widget_append(this->route_data.route_table,row); - - label = gui_internal_label_new(this,map_convert_string_tmp(item->map,attr.u.str)); - gui_internal_widget_append(row,label); - - label->item=*item; - row->item=*item; - item_coord_get(item, &c, 1); - label->c.x=c.x; - label->c.y=c.y; - label->c.pro=map_projection(map); - label->func=gui_internal_cmd_position; - label->state|=STATE_SENSITIVE; - label->data=(void*)2; - if(toprow && item->id_hi==topitem.id_hi && item->id_lo==topitem.id_lo && item->map==topitem.map) - gui_internal_widget_table_set_top_row(this, this->route_data.route_table, row); - } - - } - map_rect_destroy(mr); - } +void gui_internal_populate_route_table(struct gui_priv * this, struct navit * navit) { + struct map * map=NULL; + struct map_rect * mr=NULL; + struct navigation * nav = NULL; + struct item * item =NULL; + struct attr attr,route; + struct widget * label = NULL; + struct widget * row = NULL; + struct coord c; + nav = navit_get_navigation(navit); + if(!nav) { + return; + } + map = navigation_get_map(nav); + if(map) + mr = map_rect_new(map,NULL); + if(mr) { + GList *toprow; + struct item topitem= {0}; + toprow=gui_internal_widget_table_top_row(this, this->route_data.route_table); + if(toprow && toprow->data) + topitem=((struct widget*)toprow->data)->item; + gui_internal_widget_table_clear(this,this->route_data.route_table); + if (navit_get_attr(navit, attr_route, &route, NULL)) { + struct attr destination_length, destination_time; + char *length=NULL,*time=NULL,*length_time; + if (route_get_attr(route.u.route, attr_destination_length, &destination_length, NULL)) + length=attr_to_text_ext(&destination_length, NULL, attr_format_with_units, attr_format_default, NULL); + if (route_get_attr(route.u.route, attr_destination_time, &destination_time, NULL)) + time=attr_to_text_ext(&destination_time, NULL, attr_format_with_units, attr_format_default, NULL); + row = gui_internal_widget_table_row_new(this, + gravity_left + | flags_fill + | orientation_horizontal); + gui_internal_widget_append(this->route_data.route_table,row); + length_time=g_strdup_printf("%s %s",length,time); + label = gui_internal_label_new(this,length_time); + g_free(length_time); + g_free(length); + g_free(time); + gui_internal_widget_append(row,label); + } + while((item = map_rect_get_item(mr))) { + if(item_attr_get(item,attr_navigation_long,&attr)) { + row = gui_internal_widget_table_row_new(this, + gravity_left + | flags_fill + | orientation_horizontal); + gui_internal_widget_append(this->route_data.route_table,row); + + label = gui_internal_label_new(this,map_convert_string_tmp(item->map,attr.u.str)); + gui_internal_widget_append(row,label); + + label->item=*item; + row->item=*item; + item_coord_get(item, &c, 1); + label->c.x=c.x; + label->c.y=c.y; + label->c.pro=map_projection(map); + label->func=gui_internal_cmd_position; + label->state|=STATE_SENSITIVE; + label->data=(void*)2; + if(toprow && item->id_hi==topitem.id_hi && item->id_lo==topitem.id_lo && item->map==topitem.map) + gui_internal_widget_table_set_top_row(this, this->route_data.route_table, row); + } + + } + map_rect_destroy(mr); + } } /* - * Command interface wrapper for commands which can be used both from gui html and to enter internal gui (for example, from osd or dbus). + * Command interface wrapper for commands which can be used both from gui html and to enter internal gui (for example, from osd or dbus). * Set first command argument to integer 1, if this command was called by mouse click from oustside of gui (default). Set it to 0 * if command is called by some other means (dbus signal, for example). If first argument is non integer, it's passed on * to actual handler. - * + * */ @@ -3322,142 +3167,126 @@ gui_internal_populate_route_table(struct gui_priv * this, struct navit * navit) //# Comment: //# Authors: Martin Schaller (04/2008) //############################################################################################################## -static struct gui_priv * gui_internal_new(struct navit *nav, struct gui_methods *meth, struct attr **attrs, struct gui *gui) -{ - struct color color_white={0xffff,0xffff,0xffff,0xffff}; - struct color color_black={0x0,0x0,0x0,0xffff}; - struct color back2_color={0x4141,0x4141,0x4141,0xffff}; - - struct gui_priv *this; - struct attr *attr; - *meth=gui_internal_methods; - this=g_new0(struct gui_priv, 1); - this->nav=nav; - - this->self.type=attr_gui; - this->self.u.gui=gui; - - if ((attr=attr_search(attrs, NULL, attr_menu_on_map_click))) - this->menu_on_map_click=attr->u.num; - else - this->menu_on_map_click=1; - - if ((attr=attr_search(attrs, NULL, attr_on_map_click))) - this->on_map_click=g_strdup(attr->u.str); - - if ((attr=attr_search(attrs, NULL, attr_signal_on_map_click))) - this->signal_on_map_click=attr->u.num; - gui_internal_command_init(this, attrs); - - if( (attr=attr_search(attrs,NULL,attr_font_size))) - { - this->config.font_size=attr->u.num; - } - else - { - this->config.font_size=-1; - } - if( (attr=attr_search(attrs,NULL,attr_icon_xs))) - { - this->config.icon_xs=attr->u.num; - } - else - { - this->config.icon_xs=-1; - } - if( (attr=attr_search(attrs,NULL,attr_icon_l))) - { - this->config.icon_l=attr->u.num; - } - else - { - this->config.icon_l=-1; - } - if( (attr=attr_search(attrs,NULL,attr_icon_s))) - { - this->config.icon_s=attr->u.num; - } - else - { - this->config.icon_s=-1; - } - if( (attr=attr_search(attrs,NULL,attr_spacing))) - { - this->config.spacing=attr->u.num; - } - else - { - this->config.spacing=-1; - } - if( (attr=attr_search(attrs,NULL,attr_gui_speech))) - { - this->speech=attr->u.num; - } - if( (attr=attr_search(attrs,NULL,attr_keyboard))) - this->keyboard=attr->u.num; - else - this->keyboard=1; +static struct gui_priv * gui_internal_new(struct navit *nav, struct gui_methods *meth, struct attr **attrs, + struct gui *gui) { + struct color color_white= {0xffff,0xffff,0xffff,0xffff}; + struct color color_black= {0x0,0x0,0x0,0xffff}; + struct color back2_color= {0x4141,0x4141,0x4141,0xffff}; + + struct gui_priv *this; + struct attr *attr; + *meth=gui_internal_methods; + this=g_new0(struct gui_priv, 1); + this->nav=nav; + + this->self.type=attr_gui; + this->self.u.gui=gui; + + if ((attr=attr_search(attrs, NULL, attr_menu_on_map_click))) + this->menu_on_map_click=attr->u.num; + else + this->menu_on_map_click=1; + + if ((attr=attr_search(attrs, NULL, attr_on_map_click))) + this->on_map_click=g_strdup(attr->u.str); + + if ((attr=attr_search(attrs, NULL, attr_signal_on_map_click))) + this->signal_on_map_click=attr->u.num; + gui_internal_command_init(this, attrs); + + if( (attr=attr_search(attrs,NULL,attr_font_size))) { + this->config.font_size=attr->u.num; + } else { + this->config.font_size=-1; + } + if( (attr=attr_search(attrs,NULL,attr_icon_xs))) { + this->config.icon_xs=attr->u.num; + } else { + this->config.icon_xs=-1; + } + if( (attr=attr_search(attrs,NULL,attr_icon_l))) { + this->config.icon_l=attr->u.num; + } else { + this->config.icon_l=-1; + } + if( (attr=attr_search(attrs,NULL,attr_icon_s))) { + this->config.icon_s=attr->u.num; + } else { + this->config.icon_s=-1; + } + if( (attr=attr_search(attrs,NULL,attr_spacing))) { + this->config.spacing=attr->u.num; + } else { + this->config.spacing=-1; + } + if( (attr=attr_search(attrs,NULL,attr_gui_speech))) { + this->speech=attr->u.num; + } + if( (attr=attr_search(attrs,NULL,attr_keyboard))) + this->keyboard=attr->u.num; + else + this->keyboard=1; if( (attr=attr_search(attrs,NULL,attr_fullscreen))) - this->fullscreen=attr->u.num; - - if( (attr=attr_search(attrs,NULL,attr_flags))) - this->flags=attr->u.num; - if( (attr=attr_search(attrs,NULL,attr_background_color))) - this->background_color=*attr->u.color; - else - this->background_color=color_black; - if( (attr=attr_search(attrs,NULL,attr_background_color2))) - this->background2_color=*attr->u.color; - else - this->background2_color=back2_color; - if( (attr=attr_search(attrs,NULL,attr_text_color))) - this->text_foreground_color=*attr->u.color; - else - this->text_foreground_color=color_white; - if( (attr=attr_search(attrs,NULL,attr_text_background))) - this->text_background_color=*attr->u.color; - else - this->text_background_color=color_black; - if( (attr=attr_search(attrs,NULL,attr_columns))) - this->cols=attr->u.num; - if( (attr=attr_search(attrs,NULL,attr_osd_configuration))) - this->osd_configuration=*attr; - - if( (attr=attr_search(attrs,NULL,attr_pitch))) - this->pitch=attr->u.num; - else - this->pitch=20; - if( (attr=attr_search(attrs,NULL,attr_flags_town))) - this->flags_town=attr->u.num; - else - this->flags_town=-1; - if( (attr=attr_search(attrs,NULL,attr_flags_street))) - this->flags_street=attr->u.num; - else - this->flags_street=-1; - if( (attr=attr_search(attrs,NULL,attr_flags_house_number))) - this->flags_house_number=attr->u.num; - else - this->flags_house_number=-1; - if( (attr=attr_search(attrs,NULL,attr_radius))) - this->radius=attr->u.num; - else - this->radius=10; - if( (attr=attr_search(attrs,NULL,attr_font))) - this->font_name=g_strdup(attr->u.str); - - if((attr=attr_search(attrs, NULL, attr_hide_impossible_next_keys))) - this->hide_keys = attr->u.num; - else - this->hide_keys = 0; - - this->data.priv=this; - this->data.gui=&gui_internal_methods_ext; - this->data.widget=&gui_internal_widget_methods; - this->cbl=callback_list_new(); - - return this; + this->fullscreen=attr->u.num; + + if( (attr=attr_search(attrs,NULL,attr_flags))) + this->flags=attr->u.num; + if( (attr=attr_search(attrs,NULL,attr_background_color))) + this->background_color=*attr->u.color; + else + this->background_color=color_black; + if( (attr=attr_search(attrs,NULL,attr_background_color2))) + this->background2_color=*attr->u.color; + else + this->background2_color=back2_color; + if( (attr=attr_search(attrs,NULL,attr_text_color))) + this->text_foreground_color=*attr->u.color; + else + this->text_foreground_color=color_white; + if( (attr=attr_search(attrs,NULL,attr_text_background))) + this->text_background_color=*attr->u.color; + else + this->text_background_color=color_black; + if( (attr=attr_search(attrs,NULL,attr_columns))) + this->cols=attr->u.num; + if( (attr=attr_search(attrs,NULL,attr_osd_configuration))) + this->osd_configuration=*attr; + + if( (attr=attr_search(attrs,NULL,attr_pitch))) + this->pitch=attr->u.num; + else + this->pitch=20; + if( (attr=attr_search(attrs,NULL,attr_flags_town))) + this->flags_town=attr->u.num; + else + this->flags_town=-1; + if( (attr=attr_search(attrs,NULL,attr_flags_street))) + this->flags_street=attr->u.num; + else + this->flags_street=-1; + if( (attr=attr_search(attrs,NULL,attr_flags_house_number))) + this->flags_house_number=attr->u.num; + else + this->flags_house_number=-1; + if( (attr=attr_search(attrs,NULL,attr_radius))) + this->radius=attr->u.num; + else + this->radius=10; + if( (attr=attr_search(attrs,NULL,attr_font))) + this->font_name=g_strdup(attr->u.str); + + if((attr=attr_search(attrs, NULL, attr_hide_impossible_next_keys))) + this->hide_keys = attr->u.num; + else + this->hide_keys = 0; + + this->data.priv=this; + this->data.gui=&gui_internal_methods_ext; + this->data.widget=&gui_internal_widget_methods; + this->cbl=callback_list_new(); + + return this; } //############################################################################################################## @@ -3465,7 +3294,6 @@ static struct gui_priv * gui_internal_new(struct navit *nav, struct gui_methods //# Comment: //# Authors: Martin Schaller (04/2008) //############################################################################################################## -void plugin_init(void) -{ - plugin_register_category_gui("internal", gui_internal_new); +void plugin_init(void) { + plugin_register_category_gui("internal", gui_internal_new); } |