summaryrefslogtreecommitdiff
path: root/navit/gui/internal
diff options
context:
space:
mode:
Diffstat (limited to 'navit/gui/internal')
-rw-r--r--navit/gui/internal/gui_internal.c59
-rw-r--r--navit/gui/internal/gui_internal.h5
-rw-r--r--navit/gui/internal/gui_internal_bookmark.c6
-rw-r--r--navit/gui/internal/gui_internal_command.c125
-rw-r--r--navit/gui/internal/gui_internal_html.c7
-rw-r--r--navit/gui/internal/gui_internal_keyboard.c147
-rw-r--r--navit/gui/internal/gui_internal_keyboard.h1
-rw-r--r--navit/gui/internal/gui_internal_menu.c61
-rw-r--r--navit/gui/internal/gui_internal_poi.c2
-rw-r--r--navit/gui/internal/gui_internal_search.c13
-rw-r--r--navit/gui/internal/gui_internal_widget.c41
11 files changed, 353 insertions, 114 deletions
diff --git a/navit/gui/internal/gui_internal.c b/navit/gui/internal/gui_internal.c
index 3affd52e4..fd450b57c 100644
--- a/navit/gui/internal/gui_internal.c
+++ b/navit/gui/internal/gui_internal.c
@@ -88,6 +88,7 @@
#include "gui_internal_gesture.h"
#include "gui_internal_poi.h"
#include "gui_internal_command.h"
+#include "gui_internal_keyboard.h"
/**
@@ -743,9 +744,7 @@ gui_internal_call_linked_on_finish(struct gui_priv *this, struct widget *wm, voi
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
@@ -1674,9 +1673,15 @@ gui_internal_keypress_do(struct gui_priv *this, char *key)
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);
@@ -2668,6 +2673,12 @@ static void gui_internal_resize(void *data, int w, int h)
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) {
@@ -2697,7 +2708,9 @@ gui_internal_keynav_point(struct widget *w, int dx, int dy, struct point *p)
static struct widget*
gui_internal_keynav_find_next_sensitive_child(struct widget *wi) {
GList *l=wi->children;
- if (wi && wi->state & STATE_SENSITIVE)
+ 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);
@@ -2742,6 +2755,9 @@ gui_internal_keynav_find_prev(struct widget *wi, struct widget *current_highligh
// 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;
@@ -3102,12 +3118,14 @@ static struct gui_internal_widget_methods gui_internal_widget_methods = {
gui_internal_set_default_background,
};
-
-/*
- * @brief Displays Route information
+/**
+ * @brief finds the intersection point of 2 lines
+ *
+ * @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
*/
-/* FIXME where is the implementation? */
-
int
line_intersection(struct coord* a1, struct coord *a2, struct coord * b1, struct coord *b2, struct coord *res)
{
@@ -3125,18 +3143,19 @@ line_intersection(struct coord* a1, struct coord *a2, struct coord * b1, struct
b = -b;
}
if (a < 0 || b < 0)
- return 0;
+ return FALSE;
if (a > n || b > n)
- return 0;
+ 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_assert(n != 0);
+ 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 1;
+ return TRUE;
}
struct heightline *
@@ -3166,18 +3185,6 @@ item_get_heightline(struct item *item)
return ret;
}
-
-/*
- * @brief Displays Route Height Profile
- *
- * @li The name of the active vehicle
- * @param wm The button that was pressed.
- * @param v Unused
- */
-/* FIXME where is the implementation? */
-
-
-
/**
* @brief Called when the route is updated.
*/
@@ -3445,5 +3452,5 @@ static struct gui_priv * gui_internal_new(struct navit *nav, struct gui_methods
//##############################################################################################################
void plugin_init(void)
{
- plugin_register_gui_type("internal", gui_internal_new);
+ plugin_register_category_gui("internal", gui_internal_new);
}
diff --git a/navit/gui/internal/gui_internal.h b/navit/gui/internal/gui_internal.h
index cbe1e20df..ea5ab79ae 100644
--- a/navit/gui/internal/gui_internal.h
+++ b/navit/gui/internal/gui_internal.h
@@ -1,15 +1,14 @@
-struct widget; // defined in gui_internal.c
+struct widget;
struct graphics_image;
struct gui_priv;
-#define STATE_VISIBLE 1
-#define STATE_SELECTED 2
#define STATE_HIGHLIGHTED 4
#define STATE_SENSITIVE 8
#define STATE_EDIT 16
#define STATE_CLEAR 32
#define STATE_EDITABLE 64
#define STATE_SCROLLABLE 128
+#define STATE_OFFSCREEN 256
#define GESTURE_RINGSIZE 100
diff --git a/navit/gui/internal/gui_internal_bookmark.c b/navit/gui/internal/gui_internal_bookmark.c
index 21102ba1a..eed0de123 100644
--- a/navit/gui/internal/gui_internal_bookmark.c
+++ b/navit/gui/internal/gui_internal_bookmark.c
@@ -104,6 +104,8 @@ gui_internal_cmd_add_bookmark2(struct gui_priv *this, struct widget *wm, void *d
gui_internal_widget_append(w, wl);
if (this->keyboard)
gui_internal_widget_append(w, gui_internal_keyboard(this, VKBD_FLAG_2 | gui_internal_keyboard_init_mode(getenv("LANG"))));
+ else
+ gui_internal_keyboard_show_native(this, w, VKBD_FLAG_2 | gui_internal_keyboard_init_mode(getenv("LANG")), getenv("LANG"));
gui_internal_menu_render(this);
}
@@ -132,6 +134,8 @@ gui_internal_cmd_add_bookmark_folder2(struct gui_priv *this, struct widget *wm,
gui_internal_widget_append(w, wl);
if (this->keyboard)
gui_internal_widget_append(w, gui_internal_keyboard(this, VKBD_FLAG_2 | gui_internal_keyboard_init_mode(getenv("LANG"))));
+ else
+ gui_internal_keyboard_show_native(this, w, VKBD_FLAG_2 | gui_internal_keyboard_init_mode(getenv("LANG")), getenv("LANG"));
gui_internal_menu_render(this);
}
@@ -161,6 +165,8 @@ gui_internal_cmd_rename_bookmark(struct gui_priv *this, struct widget *wm, void
gui_internal_widget_append(w, wl);
if (this->keyboard)
gui_internal_widget_append(w, gui_internal_keyboard(this, VKBD_FLAG_2 | gui_internal_keyboard_init_mode(getenv("LANG"))));
+ else
+ gui_internal_keyboard_show_native(this, w, VKBD_FLAG_2 | gui_internal_keyboard_init_mode(getenv("LANG")), getenv("LANG"));
gui_internal_menu_render(this);
}
diff --git a/navit/gui/internal/gui_internal_command.c b/navit/gui/internal/gui_internal_command.c
index 98a736fb8..d26bd677d 100644
--- a/navit/gui/internal/gui_internal_command.c
+++ b/navit/gui/internal/gui_internal_command.c
@@ -294,6 +294,8 @@ gui_internal_cmd_enter_coord(struct gui_priv *this, char *function, struct attr
if (this->keyboard)
gui_internal_widget_append(w, gui_internal_keyboard(this, VKBD_DEGREE));
+ else
+ gui_internal_keyboard_show_native(this, w, VKBD_DEGREE, NULL);
gui_internal_menu_render(this);
}
@@ -444,13 +446,21 @@ gui_internal_cmd2_setting_layout(struct gui_priv *this, char *function, struct a
navit_attr_iter_destroy(iter);
gui_internal_menu_render(this);
}
+
+/*
+ * @brief Displays Route Height Profile
+ *
+ * displays a heightprofile if a route is active and
+ * some heightinfo is provided by means of a map
+ *
+ * the name of the file providing the heightlines must
+ * comply with *.heightlines.bin
+ *
+ */
static void
gui_internal_cmd2_route_height_profile(struct gui_priv *this, char *function, struct attr **in, struct attr ***out, int *valid)
{
-
-
struct widget * menu, *box;
-
struct map * map=NULL;
struct map_rect * mr=NULL;
struct route * route;
@@ -458,17 +468,18 @@ gui_internal_cmd2_route_height_profile(struct gui_priv *this, char *function, st
struct mapset *ms;
struct mapset_handle *msh;
int x,i,first=1,dist=0;
+ int diagram_points_count = 0;
struct coord c,last,res;
struct coord_rect rbbox,dbbox;
struct map_selection sel;
struct heightline *heightline,*heightlines=NULL;
struct diagram_point *min,*diagram_point,*diagram_points=NULL;
+ struct point p[2];
sel.next=NULL;
sel.order=18;
sel.range.min=type_height_line_1;
sel.range.max=type_height_line_3;
-
menu=gui_internal_menu(this,_("Height Profile"));
box = gui_internal_box_new(this, gravity_left_top| orientation_vertical | flags_fill | flags_expand);
gui_internal_widget_append(menu, box);
@@ -489,11 +500,24 @@ gui_internal_cmd2_route_height_profile(struct gui_priv *this, char *function, st
}
}
map_rect_destroy(mr);
+ mr = NULL;
ms=navit_get_mapset(this->nav);
if (!first && ms) {
+ int heightmap_installed = FALSE;
msh=mapset_open(ms);
while ((map=mapset_next(msh, 1))) {
- mr=map_rect_new(map, &sel);
+ struct attr name_attr;
+ if (map_get_attr(map, attr_name, &name_attr, NULL)){
+ dbg(lvl_debug,"map name = %s\n",name_attr.u.str);
+ if (strstr(name_attr.u.str,".heightlines.bin")){
+ dbg(lvl_info,"reading heightlines from map %s\n",name_attr.u.str);
+ mr=map_rect_new(map, &sel);
+ heightmap_installed = TRUE;
+ }
+ else {
+ dbg(lvl_debug,"ignoring map %s\n",name_attr.u.str);
+ }
+ }
if (mr) {
while((item = map_rect_get_item(mr))) {
if (item->type >= sel.range.min && item->type <= sel.range.max) {
@@ -505,9 +529,20 @@ gui_internal_cmd2_route_height_profile(struct gui_priv *this, char *function, st
}
}
map_rect_destroy(mr);
+ mr = NULL;
}
}
mapset_close(msh);
+ if (!heightmap_installed){
+ char *text;
+ struct widget *w;
+ text=g_strdup_printf("%s",_("please install a map *.heightlines.bin to provide elevationdata"));
+ gui_internal_widget_append(box, w=gui_internal_label_new(this, text));
+ w->flags=gravity_bottom_center|orientation_horizontal|flags_fill;
+ g_free(text);
+ gui_internal_menu_render(this);
+ return;
+ }
}
}
map=NULL;
@@ -537,7 +572,8 @@ gui_internal_cmd2_route_height_profile(struct gui_priv *this, char *function, st
diagram_point->c.y=heightline->height;
diagram_point->next=diagram_points;
diagram_points=diagram_point;
- dbg(lvl_info,"%d %d\n", diagram_point->c.x, diagram_point->c.y);
+ diagram_points_count ++;
+ dbg(lvl_debug,"%d %d\n", diagram_point->c.x, diagram_point->c.y);
}
}
}
@@ -548,18 +584,30 @@ gui_internal_cmd2_route_height_profile(struct gui_priv *this, char *function, st
}
last=c;
}
-
}
}
-
+ while (heightlines){
+ heightline=heightlines;
+ heightlines=heightlines->next;
+ g_free(heightline);
+ }
if(mr)
map_rect_destroy(mr);
- gui_internal_menu_render(this);
-
- if(!diagram_points)
+ if(diagram_points_count < 2){
+ char *text;
+ struct widget *w;
+ text=g_strdup_printf("%s",_("The route must cross at least 2 heightlines"));
+ gui_internal_widget_append(box, w=gui_internal_label_new(this, text));
+ w->flags=gravity_bottom_center|orientation_horizontal|flags_fill;
+ g_free(text);
+ gui_internal_menu_render(this);
+ if(diagram_points)
+ g_free(diagram_points);
return;
+ }
+ gui_internal_menu_render(this);
first=1;
diagram_point=diagram_points;
while (diagram_point) {
@@ -571,38 +619,42 @@ gui_internal_cmd2_route_height_profile(struct gui_priv *this, char *function, st
coord_rect_extend(&dbbox, &diagram_point->c);
diagram_point=diagram_point->next;
}
- dbg(lvl_info,"%d %d %d %d\n", dbbox.lu.x, dbbox.lu.y, dbbox.rl.x, dbbox.rl.y);
+ dbg(lvl_debug,"%d %d %d %d\n", dbbox.lu.x, dbbox.lu.y, dbbox.rl.x, dbbox.rl.y);
if (dbbox.rl.x > dbbox.lu.x && dbbox.lu.x*100/(dbbox.rl.x-dbbox.lu.x) <= 25)
dbbox.lu.x=0;
if (dbbox.lu.y > dbbox.rl.y && dbbox.rl.y*100/(dbbox.lu.y-dbbox.rl.y) <= 25)
dbbox.rl.y=0;
- dbg(lvl_info,"%d,%d %dx%d\n", box->p.x, box->p.y, box->w, box->h);
+ dbg(lvl_debug,"%d,%d %dx%d\n", box->p.x, box->p.y, box->w, box->h);
x=dbbox.lu.x;
first=1;
- for (;;) {
- struct point p[2];
- min=NULL;
- diagram_point=diagram_points;
- while (diagram_point) {
- if (diagram_point->c.x >= x && (!min || min->c.x > diagram_point->c.x))
- min=diagram_point;
- diagram_point=diagram_point->next;
+ if (diagram_points_count > 1 && dbbox.rl.x != dbbox.lu.x && dbbox.lu.y != dbbox.rl.y){
+ for (;;) {
+ min=NULL;
+ diagram_point=diagram_points;
+ while (diagram_point) {
+ if (diagram_point->c.x >= x && (!min || min->c.x > diagram_point->c.x))
+ min=diagram_point;
+ diagram_point=diagram_point->next;
+ }
+ if (! min)
+ break;
+ p[1].x=(min->c.x-dbbox.lu.x)*(box->w-10)/(dbbox.rl.x-dbbox.lu.x)+box->p.x+5;
+ p[1].y=(box->h)-5-(min->c.y-dbbox.rl.y)*(box->h-10)/(dbbox.lu.y-dbbox.rl.y)+box->p.y;
+ dbg(lvl_debug,"%d,%d=%d,%d\n",min->c.x, min->c.y, p[1].x,p[1].y);
+ graphics_draw_circle(this->gra, this->foreground, &p[1], 2);
+ if (first)
+ first=0;
+ else
+ graphics_draw_lines(this->gra, this->foreground, p, 2);
+ p[0]=p[1];
+ x=min->c.x+1;
}
- if (! min)
- break;
- p[1].x=(min->c.x-dbbox.lu.x)*(box->w-10)/(dbbox.rl.x-dbbox.lu.x)+box->p.x+5;
- p[1].y=(min->c.y-dbbox.rl.y)*(box->h-10)/(dbbox.lu.y-dbbox.rl.y)+box->p.y+5;
- dbg(lvl_info,"%d,%d=%d,%d\n",min->c.x, min->c.y, p[1].x,p[1].y);
- graphics_draw_circle(this->gra, this->foreground, &p[1], 2);
- if (first)
- first=0;
- else
- graphics_draw_lines(this->gra, this->foreground, p, 2);
- p[0]=p[1];
- x=min->c.x+1;
}
-
-
+ while (diagram_points){
+ diagram_point=diagram_points;
+ diagram_points=diagram_points->next;
+ g_free(diagram_point);
+ }
}
static void
@@ -860,6 +912,8 @@ gui_internal_cmd_log(struct gui_priv *this)
gui_internal_widget_append(w, wl);
if (this->keyboard)
gui_internal_widget_append(w, gui_internal_keyboard(this, VKBD_FLAG_2 | gui_internal_keyboard_init_mode(getenv("LANG"))));
+ else
+ gui_internal_keyboard_show_native(this, w, VKBD_FLAG_2 | gui_internal_keyboard_init_mode(getenv("LANG")), getenv("LANG"));
gui_internal_menu_render(this);
gui_internal_leave(this);
}
@@ -1075,7 +1129,6 @@ error:
return;
}
-
static void
gui_internal_cmd_img(struct gui_priv * this, char *function, struct attr **in, struct attr ***out, int *valid)
{
diff --git a/navit/gui/internal/gui_internal_html.c b/navit/gui/internal/gui_internal_html.c
index 8350dbdcc..9b42fbdec 100644
--- a/navit/gui/internal/gui_internal_html.c
+++ b/navit/gui/internal/gui_internal_html.c
@@ -491,9 +491,12 @@ gui_internal_html_menu(struct gui_priv *this, const char *document, char *anchor
callback_list_call_attr_2(this->cbl,attr_gui,anchor,&doc);
gui_internal_html_parse_text(this, doc);
g_free(doc);
- if (this->keyboard_required && this->keyboard) {
+ if (this->keyboard_required) {
this->html_container->flags=gravity_center|orientation_vertical|flags_expand|flags_fill;
- gui_internal_widget_append(this->html_container, gui_internal_keyboard(this, VKBD_FLAG_2 | gui_internal_keyboard_init_mode(getenv("LANG"))));
+ if (this->keyboard)
+ gui_internal_widget_append(this->html_container, gui_internal_keyboard(this, VKBD_FLAG_2 | gui_internal_keyboard_init_mode(getenv("LANG"))));
+ else
+ gui_internal_keyboard_show_native(this, this->html_container, VKBD_FLAG_2 | gui_internal_keyboard_init_mode(getenv("LANG")), getenv("LANG"));
}
gui_internal_menu_render(this);
graphics_draw_mode(this->gra, draw_mode_end);
diff --git a/navit/gui/internal/gui_internal_keyboard.c b/navit/gui/internal/gui_internal_keyboard.c
index ea71eb593..3dc6ae556 100644
--- a/navit/gui/internal/gui_internal_keyboard.c
+++ b/navit/gui/internal/gui_internal_keyboard.c
@@ -12,39 +12,61 @@
#include "gui_internal_menu.h"
#include "gui_internal_keyboard.h"
+/**
+ * @brief Switch keyboard mode to uppercase if it's in lowercase mode and {@code VKBD_MODE_2} is set.
+ *
+ * Called when there's no input left in the input field.
+ *
+ * @param this The internal GUI instance
+ */
void
gui_internal_keyboard_to_upper_case(struct gui_priv *this)
{
struct menu_data *md;
+
+ if (!this->keyboard)
+ return;
+
md=gui_internal_menu_data(this);
- // Switch to lowercase after the first key is pressed
- if (md->keyboard_mode == 10) // Latin
- gui_internal_keyboard_do(this, md->keyboard, 2);
- if (md->keyboard_mode == 34) // Umlaut
- gui_internal_keyboard_do(this, md->keyboard, 26);
- if (md->keyboard_mode == 50) // Russian/Ukrainian/Belorussian
- gui_internal_keyboard_do(this, md->keyboard, 42);
+
+ if (md->keyboard_mode == (VKBD_LATIN_LOWER | VKBD_FLAG_2))
+ gui_internal_keyboard_do(this, md->keyboard, VKBD_LATIN_UPPER | VKBD_FLAG_2);
+ if (md->keyboard_mode == (VKBD_UMLAUT_LOWER | VKBD_FLAG_2))
+ gui_internal_keyboard_do(this, md->keyboard, VKBD_UMLAUT_UPPER | VKBD_FLAG_2);
+ if (md->keyboard_mode == (VKBD_CYRILLIC_LOWER | VKBD_FLAG_2))
+ gui_internal_keyboard_do(this, md->keyboard, VKBD_CYRILLIC_UPPER | VKBD_FLAG_2);
}
+/**
+ * @brief Switch keyboard mode to lowercase if it's in uppercase mode and {@code VKBD_MODE_2} is set.
+ *
+ * Called on each alphanumeric input.
+ *
+ * @param this The internal GUI instance
+ */
void
gui_internal_keyboard_to_lower_case(struct gui_priv *this)
{
struct menu_data *md;
+
+ if (!this->keyboard)
+ return;
+
md=gui_internal_menu_data(this);
- // Switch to lowercase after the first key is pressed
- if (md->keyboard_mode == (VKBD_LATIN_UPPER | VKBD_FLAG_2)) // Latin
+
+ if (md->keyboard_mode == (VKBD_LATIN_UPPER | VKBD_FLAG_2))
gui_internal_keyboard_do(this, md->keyboard, VKBD_LATIN_LOWER | VKBD_FLAG_2);
- if (md->keyboard_mode == (VKBD_UMLAUT_UPPER | VKBD_FLAG_2)) // Umlaut
+ if (md->keyboard_mode == (VKBD_UMLAUT_UPPER | VKBD_FLAG_2))
gui_internal_keyboard_do(this, md->keyboard, VKBD_UMLAUT_LOWER | VKBD_FLAG_2);
- if (md->keyboard_mode == (VKBD_CYRILLIC_UPPER | VKBD_FLAG_2)) // Russian/Ukrainian/Belorussian
+ if (md->keyboard_mode == (VKBD_CYRILLIC_UPPER | VKBD_FLAG_2))
gui_internal_keyboard_do(this, md->keyboard, VKBD_CYRILLIC_LOWER | VKBD_FLAG_2);
}
/**
* @brief Processes a key press on the internal GUI keyboard
*
- * If the keyboard is currently in uppercase mode and {@code VKBD_MODE_2} is set, it is then switched to
- * the corresponding lowercase mode.
+ * If the keyboard is currently in uppercase mode and {@code VKBD_MODE_2} is set, it is tswitched to
+ * the corresponding lowercase mode in {@code gui_internal_keypress_do}.
*
* @param this The internal GUI instance
* @param wm
@@ -101,7 +123,7 @@ struct gui_internal_keyb_mode {
/*16: VKBD_NUMERIC */ {"123", 2, VKBD_LATIN_UPPER, VKBD_UMLAUT_UPPER},
/*24: VKBD_UMLAUT_UPPER */ {"ÄÖÜ", 2, VKBD_UMLAUT_LOWER, VKBD_LATIN_UPPER},
/*32: VKBD_UMLAUT_LOWER */ {"äöü", 2, VKBD_UMLAUT_UPPER, VKBD_LATIN_LOWER},
- /*40: VKBD_CYRILLIC_UPPER*/ {"АБВ", 2, VKBD_CYRILLIC_UPPER, VKBD_LATIN_UPPER},
+ /*40: VKBD_CYRILLIC_UPPER*/ {"АБВ", 2, VKBD_CYRILLIC_LOWER, VKBD_LATIN_UPPER},
/*48: VKBD_CYRILLIC_LOWER*/ {"абв", 2, VKBD_CYRILLIC_UPPER, VKBD_LATIN_LOWER},
/*56: VKBD_DEGREE */ {"DEG", 2, VKBD_FLAG_2, VKBD_FLAG_2}
};
@@ -435,3 +457,100 @@ gui_internal_keyboard_init_mode(char *lang)
g_free(lang);
return ret;
}
+
+
+/**
+ * @brief Hides the platform's native on-screen keyboard or other input method
+ *
+ * This function is called as the {@code wfree} method of the placeholder widget for the platform's
+ * native on-screen keyboard. It is a wrapper around the corresponding method of the graphics plugin,
+ * which takes care of all platform-specific actions to hide the on-screen input method it previously
+ * displayed.
+ *
+ * A call to this function indicates that Navit no longer needs the input method and is about to destroy
+ * its placeholder widget. Navit will subsequently reclaim any screen real estate it may have previously
+ * reserved for the input method.
+ *
+ * This function will free the {@code struct graphics_keyboard} pointed to by {@code w->data}
+ *
+ * @param this The internal GUI instance
+ * @param w The placeholder widget
+ */
+void gui_internal_keyboard_hide_native(struct gui_priv *this_, struct widget *w) {
+ struct graphics_keyboard *kbd = (struct graphics_keyboard *) w->data;
+
+ if (kbd) {
+ graphics_hide_native_keyboard(this_->gra, kbd);
+ g_free(kbd->lang);
+ g_free(kbd->gui_priv);
+ } else
+ dbg(lvl_warning, "no graphics_keyboard found, cleanup failed\n");
+ g_free(w);
+}
+
+
+/**
+ * @brief Shows the platform's native on-screen keyboard or other input method
+ *
+ * This method is a wrapper around the corresponding method of the graphics plugin, which takes care of
+ * all platform-specific details. In particular, it is up to the graphics plugin to determine how to
+ * handle the request: it may show its on-screen keyboard or another input method (such as stroke
+ * recognition). It may choose to simply ignore the request, which will typically occur when a hardware
+ * keyboard (or other hardware input) is available.
+ *
+ * The platform's native input method may obstruct parts of Navit's UI. To prevent parts of the UI from
+ * becoming unreachable, this method will insert an empty box widget in the appropriate size at the
+ * appropriate position, provided the graphics plugin reports the correct values. Otherwise a zero-size
+ * widget is inserted. If the graphics driver decides not to display an on-screen input method, no
+ * widget will be created and the return value will be {@code NULL}.
+ *
+ * The widget's {@code wfree} function, to be called when the widget is destroyed, will be used to hide
+ * the platform keyboard when it is no longer needed.
+ *
+ * @param this The internal GUI instance
+ * @param w The parent of the widget requiring text input
+ * @param mode The requested keyboard mode
+ * @param lang The language for text input, used to select a keyboard layout
+ *
+ * @return The placeholder widget for the on-screen keyboard, may be {@code NULL}
+ */
+struct widget * gui_internal_keyboard_show_native(struct gui_priv *this, struct widget *w, int mode, char *lang) {
+ struct widget *ret = NULL;
+ struct menu_data *md = gui_internal_menu_data(this);
+ struct graphics_keyboard *kbd = g_new0(struct graphics_keyboard, 1);
+ int res;
+
+ kbd->mode = mode;
+ if (lang)
+ kbd->lang = g_strdup(lang);
+ res = graphics_show_native_keyboard(this->gra, kbd);
+
+ switch(res) {
+ case -1:
+ dbg(lvl_error, "graphics has no show_native_keyboard method, cannot display keyboard\n");
+ /* no break */
+ case 0:
+ g_free(kbd);
+ return NULL;
+ }
+
+ ret = gui_internal_box_new(this, gravity_center|orientation_horizontal_vertical|flags_fill);
+ md->keyboard = ret;
+ md->keyboard_mode=mode;
+ ret->wfree = gui_internal_keyboard_hide_native;
+ if (kbd->h < 0) {
+ ret->h = w->h;
+ ret->hmin = w->hmin;
+ } else
+ ret->h = kbd->h;
+ if (kbd->w < 0) {
+ ret->w = w->w;
+ ret->wmin = w->wmin;
+ } else
+ ret->w = kbd->w;
+ dbg(lvl_error, "ret->w=%d, ret->h=%d\n", ret->w, ret->h);
+ ret->data = (void *) kbd;
+ gui_internal_widget_append(w, ret);
+ dbg(lvl_error, "return\n");
+ return ret;
+}
diff --git a/navit/gui/internal/gui_internal_keyboard.h b/navit/gui/internal/gui_internal_keyboard.h
index 336ba2c01..9b9039224 100644
--- a/navit/gui/internal/gui_internal_keyboard.h
+++ b/navit/gui/internal/gui_internal_keyboard.h
@@ -24,6 +24,7 @@ struct gui_priv;
struct widget;
struct widget *gui_internal_keyboard_do(struct gui_priv *this, struct widget *wkbdb, int mode);
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);
int gui_internal_keyboard_init_mode(char *lang);
void gui_internal_keyboard_to_upper_case(struct gui_priv *this);
void gui_internal_keyboard_to_lower_case(struct gui_priv *this);
diff --git a/navit/gui/internal/gui_internal_menu.c b/navit/gui/internal/gui_internal_menu.c
index 7769953b9..33def9983 100644
--- a/navit/gui/internal/gui_internal_menu.c
+++ b/navit/gui/internal/gui_internal_menu.c
@@ -91,10 +91,31 @@ gui_internal_prune_menu_count(struct gui_priv *this, int count, int render)
}
}
+
+/**
+ * @brief Initializes a GUI screen
+ *
+ * This method initializes the internal GUI's screen on which all other elements (such as HTML menus,
+ * dialogs or others) are displayed.
+ *
+ * It sets up a view hierarchy, which includes a title bar and a client area to hold widgets defined by
+ * the caller.
+ *
+ * @param this The GUI instance
+ * @param label The label to display in the top bar
+ *
+ * @return The container for caller-defined widgets
+ */
struct widget *
gui_internal_menu(struct gui_priv *this, const char *label)
{
struct widget *menu,*w,*w1,*topbox;
+ struct padding *padding = NULL;
+
+ if (this->gra) {
+ padding = graphics_get_data(this->gra, "padding");
+ } else
+ dbg(lvl_warning, "cannot get padding: this->gra is NULL\n");
gui_internal_search_idle_end(this);
topbox=gui_internal_box_new_with_label(this, 0, label);
@@ -102,8 +123,18 @@ gui_internal_menu(struct gui_priv *this, const char *label)
topbox->h=this->root.h;
gui_internal_widget_append(&this->root, topbox);
menu=gui_internal_box_new(this, gravity_left_center|orientation_vertical);
- menu->w=this->root.w;
- menu->h=this->root.h;
+
+ if (padding) {
+ menu->p.x = padding->left;
+ menu->p.y = padding->top;
+ menu->w = topbox->w - padding->left - padding->right;
+ menu->h = topbox->h - padding->top - padding->bottom;
+ } else {
+ menu->p.x = 0;
+ menu->p.y = 0;
+ menu->w = topbox->w;
+ menu->h = topbox->h;
+ }
menu->background=this->background;
gui_internal_apply_config(this);
topbox->menu_data=g_new0(struct menu_data, 1);
@@ -134,8 +165,17 @@ gui_internal_menu(struct gui_priv *this, const char *label)
}
if (this->flags & 192) {
menu=gui_internal_box_new(this, gravity_left_center|orientation_vertical);
- menu->w=this->root.w;
- menu->h=this->root.h;
+ if (padding) {
+ menu->p.x = padding->left;
+ menu->p.y = padding->top;
+ menu->w = topbox->w - padding->left - padding->right;
+ menu->h = topbox->h - padding->top - padding->bottom;
+ } else {
+ menu->p.x = 0;
+ menu->p.y = 0;
+ menu->w = topbox->w;
+ menu->h = topbox->h;
+ }
w1=gui_internal_time_help(this);
gui_internal_widget_append(menu, w1);
w1=gui_internal_box_new(this, gravity_center|orientation_horizontal_vertical|flags_expand|flags_fill);
@@ -147,8 +187,17 @@ gui_internal_menu(struct gui_priv *this, const char *label)
gui_internal_widget_reset_pack(this, topbox);
topbox->w=this->root.w;
topbox->h=this->root.h;
- menu->w=this->root.w;
- menu->h=this->root.h;
+ if (padding) {
+ menu->p.x = padding->left;
+ menu->p.y = padding->top;
+ menu->w = topbox->w - padding->left - padding->right;
+ menu->h = topbox->h - padding->top - padding->bottom;
+ } else {
+ menu->p.x = 0;
+ menu->p.y = 0;
+ menu->w = topbox->w;
+ menu->h = topbox->h;
+ }
return w;
}
diff --git a/navit/gui/internal/gui_internal_poi.c b/navit/gui/internal/gui_internal_poi.c
index c3eed5e60..d4ffea8b3 100644
--- a/navit/gui/internal/gui_internal_poi.c
+++ b/navit/gui/internal/gui_internal_poi.c
@@ -533,6 +533,8 @@ gui_internal_cmd_pois_filter(struct gui_priv *this, struct widget *wm, void *dat
if (this->keyboard)
gui_internal_widget_append(w, gui_internal_keyboard(this, keyboard_mode));
+ else
+ gui_internal_keyboard_show_native(this, w, keyboard_mode, getenv("LANG"));
gui_internal_menu_render(this);
diff --git a/navit/gui/internal/gui_internal_search.c b/navit/gui/internal/gui_internal_search.c
index a0d6a3b2e..e5e137e07 100644
--- a/navit/gui/internal/gui_internal_search.c
+++ b/navit/gui/internal/gui_internal_search.c
@@ -212,6 +212,9 @@ gui_internal_highlight_possible_keys(struct gui_priv *this, char *possible_keys)
{
struct menu_data *md;
+ if (!this->keyboard)
+ return;
+
md=gui_internal_menu_data(this);
if (md && md->keyboard && !(this->flags & 2048)) {
GList *lk=md->keyboard->children;
@@ -225,9 +228,9 @@ gui_internal_highlight_possible_keys(struct gui_priv *this, char *possible_keys)
if (child_->data && strcmp("\b", child_->data)) { // FIXME don't disable special keys
if ( (strlen(possible_keys) == 0) ||
(g_strrstr(possible_keys, child_->data)!=NULL ) ) {
- child_->state|= STATE_HIGHLIGHTED|STATE_VISIBLE|STATE_SENSITIVE|STATE_CLEAR ;
+ child_->state|= STATE_HIGHLIGHTED|STATE_SENSITIVE|STATE_CLEAR ;
} else {
- child_->state&= ~(STATE_HIGHLIGHTED|STATE_VISIBLE|STATE_SELECTED) ;
+ child_->state&= ~STATE_HIGHLIGHTED;
}
gui_internal_widget_render(this,child_);
}
@@ -431,13 +434,9 @@ gui_internal_search_changed(struct gui_priv *this, struct widget *wm, void *data
search_attr.type=attr_house_number;
search_attr.u.str=wm->text;
search_list_search(this->sl, &search_attr, 1);
- // Text is not necessarily entered via the on-screen keyboard,
- // but we now switch it to lower case anyway.
- gui_internal_keyboard_to_lower_case(this);
gui_internal_search_idle_start(this, wm->name, search_list, param);
} else {
// If not enough content is entered, we highlight all keys.
- gui_internal_keyboard_to_upper_case(this);
gui_internal_highlight_possible_keys(this, "");
}
l=g_list_last(this->root.children);
@@ -570,6 +569,8 @@ gui_internal_search(struct gui_priv *this, const char *what, const char *type, i
wk->name=g_strdup(type);
if (this->keyboard)
gui_internal_widget_append(w, gui_internal_keyboard(this, keyboard_mode));
+ else
+ gui_internal_keyboard_show_native(this, w, keyboard_mode, getenv("LANG"));
gui_internal_menu_render(this);
}
diff --git a/navit/gui/internal/gui_internal_widget.c b/navit/gui/internal/gui_internal_widget.c
index e78abb3dd..1dd28837f 100644
--- a/navit/gui/internal/gui_internal_widget.c
+++ b/navit/gui/internal/gui_internal_widget.c
@@ -321,18 +321,18 @@ static void gui_internal_box_render(struct gui_priv *this, struct widget *w)
gui_internal_background_render(this, w);
if (w->foreground && w->border) {
- struct point pnt[5];
- pnt[0]=w->p;
- pnt[1].x=pnt[0].x+w->w;
- pnt[1].y=pnt[0].y;
- pnt[2].x=pnt[0].x+w->w;
- pnt[2].y=pnt[0].y+w->h;
- pnt[3].x=pnt[0].x;
- pnt[3].y=pnt[0].y+w->h;
- pnt[4]=pnt[0];
- graphics_gc_set_linewidth(w->foreground, w->border ? w->border : 1);
- graphics_draw_lines(this->gra, w->foreground, pnt, 5);
- graphics_gc_set_linewidth(w->foreground, 1);
+ struct point pnt[5];
+ pnt[0]=w->p;
+ pnt[1].x=pnt[0].x+w->w;
+ pnt[1].y=pnt[0].y;
+ pnt[2].x=pnt[0].x+w->w;
+ pnt[2].y=pnt[0].y+w->h;
+ pnt[3].x=pnt[0].x;
+ pnt[3].y=pnt[0].y+w->h;
+ pnt[4]=pnt[0];
+ graphics_gc_set_linewidth(w->foreground, w->border ? w->border : 1);
+ graphics_draw_lines(this->gra, w->foreground, pnt, 5);
+ graphics_gc_set_linewidth(w->foreground, 1);
}
l=w->children;
@@ -1226,7 +1226,7 @@ gui_internal_table_render(struct gui_priv * this, struct widget * w)
GList * current_desc=NULL;
struct table_data * table_data = (struct table_data*)w->data;
int drawing_space_left=1;
- int is_first_page=1;
+ int is_first_page;
struct table_column_desc * dim=NULL;
dbg_assert(table_data);
@@ -1238,16 +1238,17 @@ gui_internal_table_render(struct gui_priv * this, struct widget * w)
/*
* Skip rows that are on previous pages.
*/
- cur_row = w->children;
if(table_data->top_row && table_data->top_row != w->children && !table_data->scroll_buttons.button_box_hide)
{
cur_row = table_data->top_row;
is_first_page=0;
} else {
+ cur_row = w->children;
table_data->top_row=NULL;
+ is_first_page=1;
}
- /* First, let's deactivate all columns that are in rows which are *before*
+ /* First, let's mark all columns as off-screen that are in rows which are *before*
* our current page.
* */
GList *row = w->children;
@@ -1263,7 +1264,7 @@ gui_internal_table_render(struct gui_priv * this, struct widget * w)
cur_column=g_list_next(cur_column))
{
struct widget * cur_widget = (struct widget*) cur_column->data;
- cur_widget->state &= ~STATE_SENSITIVE;
+ cur_widget->state |= STATE_OFFSCREEN;
}
row = g_list_next(row);
}
@@ -1297,8 +1298,6 @@ gui_internal_table_render(struct gui_priv * this, struct widget * w)
cur_column=g_list_next(cur_column))
{
struct widget * cur_widget = (struct widget*) cur_column->data;
- dim = (struct table_column_desc*)current_desc->data;
-
if (drawing_space_left) {
cur_widget->p.x=x;
cur_widget->w=dim->width;
@@ -1309,7 +1308,7 @@ gui_internal_table_render(struct gui_priv * this, struct widget * w)
/* We pack the widget before rendering to ensure that the x and y
* coordinates get pushed down.
*/
- cur_widget->state |= STATE_SENSITIVE;
+ cur_widget->state &= ~STATE_OFFSCREEN;
gui_internal_widget_pack(this,cur_widget);
gui_internal_widget_render(this,cur_widget);
@@ -1318,8 +1317,8 @@ gui_internal_table_render(struct gui_priv * this, struct widget * w)
max_height = dim->height;
}
} else {
- /* Deactivate contents that we don't have space for. */
- cur_widget->state &= ~STATE_SENSITIVE;
+ /* Mark contents that we don't have space for. */
+ cur_widget->state |= STATE_OFFSCREEN;
}
}