Add:gui_internal:On-Screen-Keyboard now works partly
authormartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Thu, 19 Jun 2008 21:18:22 +0000 (21:18 +0000)
committermartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Thu, 19 Jun 2008 21:18:22 +0000 (21:18 +0000)
git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk@1150 ffa7fe5e-494d-0410-b361-a75ebd5db220

navit/navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c
navit/navit/gui/internal/gui_internal.c
navit/navit/keys.h
navit/navit/transform.c
navit/navit/transform.h

index e0ab088..b55a675 100644 (file)
@@ -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;
index b6faef4..ef22ae3 100644 (file)
@@ -30,6 +30,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
+#include <math.h>
 #include <libintl.h>
 #include <glib.h>
 #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);
+               }
        }
 } 
 
index d06d01e..57af500 100644 (file)
@@ -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
index f835843..2676492 100644 (file)
@@ -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.
 
index 6fcfce0..d305ea7 100644 (file)
 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
 }