From: martin-s Date: Thu, 19 Jun 2008 21:18:22 +0000 (+0000) Subject: Add:gui_internal:On-Screen-Keyboard now works partly X-Git-Tag: navit-0.5.0.5194svn~4006 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a1315c6a0f3c54d98e6fda3179799a49b36d14b9;p=profile%2Fivi%2Fnavit.git Add:gui_internal:On-Screen-Keyboard now works partly git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk@1150 ffa7fe5e-494d-0410-b361-a75ebd5db220 --- diff --git a/navit/navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c b/navit/navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c index e0ab088..b55a675 100644 --- a/navit/navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c +++ b/navit/navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c @@ -907,7 +907,7 @@ keypress(GtkWidget *widget, GdkEventKey *event, gpointer user_data) struct graphics_priv *this=user_data; if (! this->keypress_callback) return FALSE; - if (event->keyval >= 32 && event->keyval < 127) { + if ((event->keyval >= 32 && event->keyval < 127) || event->keyval == 8 || event->keyval == 13) { (*this->keypress_callback)(this->motion_callback_data, event->keyval); return FALSE; } @@ -924,6 +924,12 @@ keypress(GtkWidget *widget, GdkEventKey *event, gpointer user_data) case GDK_Right: (*this->keypress_callback)(this->motion_callback_data, NAVIT_KEY_RIGHT); break; + case GDK_BackSpace: + (*this->keypress_callback)(this->motion_callback_data, NAVIT_KEY_BACKSPACE); + break; + case GDK_Return: + (*this->keypress_callback)(this->motion_callback_data, NAVIT_KEY_RETURN); + break; case GDK_Book: (*this->keypress_callback)(this->motion_callback_data, NAVIT_KEY_ZOOM_IN); break; @@ -931,6 +937,7 @@ keypress(GtkWidget *widget, GdkEventKey *event, gpointer user_data) (*this->keypress_callback)(this->motion_callback_data, NAVIT_KEY_ZOOM_OUT); break; default: + dbg(0,"keyval 0x%x\n", event->keyval); break; } return FALSE; diff --git a/navit/navit/gui/internal/gui_internal.c b/navit/navit/gui/internal/gui_internal.c index b6faef4..ef22ae3 100644 --- a/navit/navit/gui/internal/gui_internal.c +++ b/navit/navit/gui/internal/gui_internal.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include "config.h" @@ -57,6 +58,7 @@ #define STATE_SELECTED 2 #define STATE_HIGHLIGHTED 4 #define STATE_SENSITIVE 8 +#define STATE_EDIT 16 enum widget_type { widget_box=1, @@ -152,6 +154,7 @@ struct gui_priv { struct widget root; struct widget *highlighted; struct widget *highlighted_menu; + struct pcoord click, vehicle; }; static void gui_internal_widget_render(struct gui_priv *this, struct widget *w); @@ -202,6 +205,7 @@ image_new_scaled(struct gui_priv *this, char *name, int w, int h) return NULL; } + static struct graphics_image * image_new_o(struct gui_priv *this, char *name) { @@ -227,6 +231,34 @@ image_new_l(struct gui_priv *this, char *name) return image_new_scaled(this, name, this->icon_l, this->icon_l); } +static char * +coordinates(struct pcoord *pc, char sep) +{ + struct coord_geo g; + struct coord c; + char latc='N',lngc='W'; + int lat_deg,lat_min,lat_sec; + int lng_deg,lng_min,lng_sec; + c.x=pc->x; + c.y=pc->y; + transform_to_geo(pc->pro, &c, &g); + if (g.lat < 0) { + g.lat=-g.lat; + latc='S'; + } + if (g.lng < 0) { + g.lng=-g.lng; + lngc='E'; + } + lat_deg=g.lat; + lat_min=fmod(g.lat*60,60); + lat_sec=fmod(g.lat*3600,60); + lng_deg=g.lng; + lng_min=fmod(g.lng*60,60); + lng_sec=fmod(g.lng*3600,60); + return g_strdup_printf("%d°%d'%d\" %c%c%d°%d'%d\" %c",lat_deg,lat_min,lat_sec,latc,sep,lng_deg,lng_min,lng_sec,lngc); +} + static void gui_internal_background_render(struct gui_priv *this, struct widget *w) { @@ -458,12 +490,10 @@ gui_internal_find_widget(struct widget *wi, struct point *p, int flags) GList *l=wi->children; struct widget *ret,*child; - if (wi->p.x > p->x || wi->p.y > p->y || wi->p.x + wi->w < p->x || wi->p.y + wi->h < p->y) { + if (p && (wi->p.x > p->x || wi->p.y > p->y || wi->p.x + wi->w < p->x || wi->p.y + wi->h < p->y)) return NULL; - } - if (wi->state & flags) { + if (wi->state & flags) return wi; - } while (l) { child=l->data; ret=gui_internal_find_widget(child, p, flags); @@ -1008,6 +1038,27 @@ gui_internal_cmd_position(struct gui_priv *this, struct widget *wm) } static void +gui_internal_cmd_point(struct gui_priv *this, struct widget *wm) +{ + struct widget *wb,*w; + struct pcoord *pc; + char *coord; + + pc=&this->click; + wb=gui_internal_menu(this, "Map Point"); + w=gui_internal_box_new(this, gravity_top_center|orientation_vertical|flags_expand|flags_fill); + gui_internal_widget_append(wb, w); + coord=coordinates(pc, ' '); + gui_internal_widget_append(w, gui_internal_label_new(this, coord)); + g_free(coord); + gui_internal_widget_append(w, + 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, wm)); + gui_internal_menu_render(this); + +} +static void gui_internal_cmd_bookmarks(struct gui_priv *this, struct widget *wm) { struct attr attr,mattr; @@ -1076,22 +1127,53 @@ gui_internal_cmd_bookmarks(struct gui_priv *this, struct widget *wm) gui_internal_menu_render(this); } +static void gui_internal_keypress_do(struct gui_priv *this, int key) +{ + struct widget *wi,*menu; + int len=0; + char *text; + + menu=g_list_last(this->root.children)->data; + wi=gui_internal_find_widget(menu, NULL, STATE_EDIT); + if (wi) { + if (key == NAVIT_KEY_BACKSPACE && wi->text && (len=strlen(wi->text))) { + wi->text[--len]=' '; + text=g_strdup_printf("%s ", wi->text); + } else + text=g_strdup_printf("%s%c", wi->text ? wi->text : "", key); + g_free(wi->text); + wi->text=text; + gui_internal_widget_render(this, wi); + if (key == NAVIT_KEY_BACKSPACE) { + wi->text[len]='\0'; + gui_internal_widget_render(this, wi); + } + } +} + + static void gui_internal_cmd_keypress(struct gui_priv *this, struct widget *wm) { - dbg(0,"enter\n"); + gui_internal_keypress_do(this, (int) wm->data); } static void gui_internal_cmd_town(struct gui_priv *this, struct widget *wm) { - struct widget *wb,*wkbd,*wk,*w,*wr; + struct widget *wb,*wkbd,*wk,*w,*wr,*we; int i; wb=gui_internal_menu(this, "Town"); w=gui_internal_box_new(this, gravity_center|orientation_vertical|flags_expand|flags_fill); gui_internal_widget_append(wb, w); - wr=gui_internal_box_new(this, gravity_center|orientation_vertical|flags_expand|flags_fill); + wr=gui_internal_box_new(this, gravity_top_center|orientation_vertical|flags_expand|flags_fill); gui_internal_widget_append(w, wr); + we=gui_internal_box_new(this, gravity_left_center|orientation_horizontal|flags_fill); + gui_internal_widget_append(wr, we); + gui_internal_widget_append(we, wk=gui_internal_label_new(this, NULL)); + wk->state |= STATE_EDIT; + wk->background=this->background; + wk->flags |= flags_expand|flags_fill; wkbd=gui_internal_box_new(this, gravity_center|orientation_horizontal_vertical|flags_fill); wkbd->cols=7; gui_internal_widget_append(w, wkbd); @@ -1102,6 +1184,7 @@ gui_internal_cmd_town(struct gui_priv *this, struct widget *wm) gui_internal_widget_append(wkbd, wk=gui_internal_button_new_with_callback(this, text, NULL, gravity_center|orientation_vertical, gui_internal_cmd_keypress, NULL)); + wk->data=text[0]; wk->background=this->background; wk->bl=8; wk->br=8; @@ -1183,17 +1266,20 @@ gui_internal_cmd_abort_navigation(struct gui_priv *this, struct widget *wm) static void gui_internal_cmd_actions(struct gui_priv *this, struct widget *wm) { - struct widget *w; + struct widget *w,*wc; + char *coord; w=gui_internal_menu(this, "Actions"); gui_internal_widget_append(w, gui_internal_button_new_with_callback(this, "Bookmarks", image_new_l(this, "gui_bookmark"), gravity_center|orientation_vertical, gui_internal_cmd_bookmarks, NULL)); + coord=coordinates(&this->click, '\n'); gui_internal_widget_append(w, - gui_internal_button_new_with_callback(this, "172°15'23\" E\n55°23'44\" S", + wc=gui_internal_button_new_with_callback(this, coord, image_new_l(this, "gui_map"), gravity_center|orientation_vertical, - gui_internal_cmd_bookmarks, NULL)); + gui_internal_cmd_point, NULL)); + g_free(coord); gui_internal_widget_append(w, gui_internal_button_new_with_callback(this, "172°15'23\" E\n55°23'44\" S", image_new_l(this, "gui_rules"), gravity_center|orientation_vertical, @@ -1373,14 +1459,22 @@ static void gui_internal_button(void *data, int pressed, int button, struct poin { struct gui_priv *this=data; struct graphics *gra=this->gra; + struct transformation *trans; + struct coord c; // if still on the map (not in the menu, yet): if (!this->root.children) { // 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) || button >=4) // Maybe there's a better way to do this return; + navit_block(this->nav, 1); graphics_overlay_disable(gra, 1); + trans=navit_get_trans(this->nav); + this->click.pro=transform_get_projection(trans); + transform_reverse(trans, p, &c); + this->click.x=c.x; + this->click.y=c.y; // draw menu this->root.p.x=0; this->root.p.y=0; @@ -1470,7 +1564,12 @@ static void gui_internal_keypress(void *data, int key) navit_zoom_out(this->nav, 2, NULL); break; default: - dbg(0,"key=%d\n", key); + dbg(1,"key=%d\n", key, this); + if (this->root.children) { + graphics_draw_mode(this->gra, draw_mode_begin); + gui_internal_keypress_do(this, key); + graphics_draw_mode(this->gra, draw_mode_end); + } } } diff --git a/navit/navit/keys.h b/navit/navit/keys.h index d06d01e..57af500 100644 --- a/navit/navit/keys.h +++ b/navit/navit/keys.h @@ -1,5 +1,7 @@ #define NAVIT_KEY_LEFT 2 #define NAVIT_KEY_RIGHT 6 +#define NAVIT_KEY_BACKSPACE 8 +#define NAVIT_KEY_RETURN 13 #define NAVIT_KEY_DOWN 14 #define NAVIT_KEY_ZOOM_OUT 15 #define NAVIT_KEY_UP 16 diff --git a/navit/navit/transform.c b/navit/navit/transform.c index f835843..2676492 100644 --- a/navit/navit/transform.c +++ b/navit/navit/transform.c @@ -30,6 +30,7 @@ #include "transform.h" #include "projection.h" #include "point.h" +#include "item.h" struct transformation { long scale; /* Scale factor */ @@ -724,6 +725,108 @@ transform_within_border(struct transformation *this_, struct point *p, int borde return 0; } +int +transform_within_dist_point(struct coord *ref, struct coord *c, int dist) +{ + if (c->x-dist > ref->x) + return 0; + if (c->x+dist < ref->x) + return 0; + if (c->y-dist > ref->y) + return 0; + if (c->y+dist < ref->y) + return 0; + if ((c->x-ref->x)*(c->x-ref->x) + (c->y-ref->y)*(c->y-ref->y) <= dist*dist) + return 1; + return 0; +} + +int +transform_within_dist_line(struct coord *ref, struct coord *c0, struct coord *c1, int dist) +{ + int vx,vy,wx,wy; + int n1,n2; + struct coord lc; + + if (c0->x < c1->x) { + if (c0->x-dist > ref->x) + return 0; + if (c1->x+dist < ref->x) + return 0; + } else { + if (c1->x-dist > ref->x) + return 0; + if (c0->x+dist < ref->x) + return 0; + } + if (c0->y < c1->y) { + if (c0->y-dist > ref->y) + return 0; + if (c1->y+dist < ref->y) + return 0; + } else { + if (c1->y-dist > ref->y) + return 0; + if (c0->y+dist < ref->y) + return 0; + } + vx=c1->x-c0->x; + vy=c1->y-c0->y; + wx=ref->x-c0->x; + wy=ref->y-c0->y; + + n1=vx*wx+vy*wy; + if ( n1 <= 0 ) + return transform_within_dist_point(ref, c0, dist); + n2=vx*vx+vy*vy; + if ( n2 <= n1 ) + return transform_within_dist_point(ref, c1, dist); + + lc.x=c0->x+vx*n1/n2; + lc.y=c0->y+vy*n1/n2; + return transform_within_dist_point(ref, &lc, dist); +} + +int +transform_within_dist_polyline(struct coord *ref, struct coord *c, int count, int close, int dist) +{ + int i; + for (i = 0 ; i < count-1 ; i++) { + if (transform_within_dist_line(ref,c+i,c+i+1,dist)) { + return 1; + } + } + if (close) + return (transform_within_dist_line(ref,c,c+count-1,dist)); + return 0; +} + +int +transform_within_dist_polygon(struct coord *ref, struct coord *c, int count, int dist) +{ + int i, j, ci = 0; + for (i = 0, j = count-1; i < count; j = i++) { + if ((((c[i].y <= ref->y) && ( ref->y < c[j].y )) || + ((c[j].y <= ref->y) && ( ref->y < c[i].y))) && + (ref->x < (c[j].x - c[i].x) * (ref->y - c[i].y) / (c[j].y - c[i].y) + c[i].x)) + ci = !ci; + } + if (! ci) + return transform_within_dist_polyline(ref, c, count, dist, 1); + return 1; +} + +int +transform_within_dist_item(struct coord *ref, enum item_type type, struct coord *c, int count, int dist) +{ + if (type < type_line) + return transform_within_dist_point(ref, c, dist); + if (type < type_area) + return transform_within_dist_polyline(ref, c, count, 0, dist); + return transform_within_dist_polygon(ref, c, count, dist); +} + + /* Note: there are many mathematically equivalent ways to express these formulas. As usual, not all of them are computationally equivalent. diff --git a/navit/navit/transform.h b/navit/navit/transform.h index 6fcfce0..d305ea7 100644 --- a/navit/navit/transform.h +++ b/navit/navit/transform.h @@ -24,9 +24,12 @@ extern "C" { #endif /* prototypes */ +enum item_type; +enum map_datum; enum projection; struct coord; struct coord_geo; +struct coord_geo_cart; struct map_selection; struct pcoord; struct point; @@ -35,7 +38,10 @@ struct transformation *transform_new(void); void transform_to_geo(enum projection pro, struct coord *c, struct coord_geo *g); void transform_from_geo(enum projection pro, struct coord_geo *g, struct coord *c); void transform_from_to(struct coord *cfrom, enum projection from, struct coord *cto, enum projection to); -int transform(struct transformation *t, enum projection pro, struct coord *c, struct point *p, int count, int flags); +void transform_geo_to_cart(struct coord_geo *geo, double a, double b, struct coord_geo_cart *cart); +void transform_cart_to_geo(struct coord_geo_cart *cart, double a, double b, struct coord_geo *geo); +void transform_datum(struct coord_geo *from, enum map_datum from_datum, struct coord_geo *to, enum map_datum to_datum); +int transform(struct transformation *t, enum projection pro, struct coord *c, struct point *p, int count, int unique); void transform_reverse(struct transformation *t, struct point *p, struct coord *c); enum projection transform_get_projection(struct transformation *this_); void transform_set_projection(struct transformation *this_, enum projection pro); @@ -59,6 +65,11 @@ int transform_distance_polyline_sq(struct coord *c, int count, struct coord *ref void transform_print_deg(double deg); int transform_get_angle_delta(struct coord *c1, struct coord *c2, int dir); int transform_within_border(struct transformation *this_, struct point *p, int border); +int transform_within_dist_point(struct coord *ref, struct coord *c, int dist); +int transform_within_dist_line(struct coord *ref, struct coord *c0, struct coord *c1, int dist); +int transform_within_dist_polyline(struct coord *ref, struct coord *c, int count, int close, int dist); +int transform_within_dist_polygon(struct coord *ref, struct coord *c, int count, int dist); +int transform_within_dist_item(struct coord *ref, enum item_type type, struct coord *c, int count, int dist); /* end of prototypes */ #ifdef __cplusplus }