From 595430993252adf48bb2cdf2e5ea1b90a1ab86a8 Mon Sep 17 00:00:00 2001 From: mvglasow Date: Fri, 6 Nov 2015 17:14:33 +0100 Subject: Add:port_android:OSD button and command to show Android menu Signed-off-by: mvglasow --- .../android/src/org/navitproject/navit/Navit.java | 10 ++ .../src/org/navitproject/navit/NavitGraphics.java | 20 ++++ navit/attr_def.h | 1 + navit/graphics/android/graphics_android.c | 101 ++++++++++++++++- navit/osd/core/osd_core.c | 6 +- navit/xpm/Makefile.am | 1 + navit/xpm/gui_android_menu.svg | 120 +++++++++++++++++++++ navit/xslt/android.xslt | 1 + navit/xslt/osd_android.xslt | 8 ++ navit/xslt/osd_minimum.xslt | 2 +- 10 files changed, 267 insertions(+), 3 deletions(-) create mode 100644 navit/xpm/gui_android_menu.svg create mode 100644 navit/xslt/osd_android.xslt (limited to 'navit') diff --git a/navit/android/src/org/navitproject/navit/Navit.java b/navit/android/src/org/navitproject/navit/Navit.java index 90fcbe5eb..5449a3431 100644 --- a/navit/android/src/org/navitproject/navit/Navit.java +++ b/navit/android/src/org/navitproject/navit/Navit.java @@ -590,6 +590,16 @@ public class Navit extends Activity break; } } + + /** + * @brief Shows the Options menu. + * + * Calling this method has the same effect as pressing the hardware Menu button, where present, or touching + * the overflow button in the Action bar. + */ + public void showMenu() { + openOptionsMenu(); + } void setDestination(float latitude, float longitude, String address) { Toast.makeText( getApplicationContext(),getString(R.string.address_search_set_destination) + "\n" + address, Toast.LENGTH_LONG).show(); //TRANS diff --git a/navit/android/src/org/navitproject/navit/NavitGraphics.java b/navit/android/src/org/navitproject/navit/NavitGraphics.java index 728b49878..08f4fbe3e 100644 --- a/navit/android/src/org/navitproject/navit/NavitGraphics.java +++ b/navit/android/src/org/navitproject/navit/NavitGraphics.java @@ -32,6 +32,7 @@ import android.graphics.Paint; import android.graphics.Path; import android.graphics.PointF; import android.graphics.Rect; +import android.os.Build; import android.os.Handler; import android.os.Message; import android.util.FloatMath; @@ -41,6 +42,7 @@ import android.view.KeyEvent; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; +import android.view.ViewConfiguration; import android.view.inputmethod.InputMethodManager; import android.widget.RelativeLayout; @@ -792,6 +794,24 @@ public class NavitGraphics private int SizeChangedCallbackID, ButtonCallbackID, MotionCallbackID, KeypressCallbackID; // private int count; + /** + * @brief Returns whether the device has a hardware menu button. + * + * Only Android versions starting with ICS (API version 14) support the API call to detect the presence of a + * Menu button. On earlier Android versions, the following assumptions will be made: On API levels up to 10, + * this method will always return {@code true}, as these Android versions relied on devices having a physical + * Menu button. On API levels 11 through 13 (Honeycomb releases), this method will always return + * {@code false}, as Honeycomb was a tablet-only release and did not require devices to have a Menu button. + */ + public boolean hasMenuButton() { + if (Build.VERSION.SDK_INT <= 10) + return true; + else if (Build.VERSION.SDK_INT <= 13) + return false; + else + return ViewConfiguration.get(activity.getApplication()).hasPermanentMenuKey(); + } + public void setSizeChangedCallback(int id) { SizeChangedCallbackID = id; diff --git a/navit/attr_def.h b/navit/attr_def.h index 2b945226c..b8217f4a7 100644 --- a/navit/attr_def.h +++ b/navit/attr_def.h @@ -253,6 +253,7 @@ ATTR(persistent) ATTR(waypoints_flag) /* toggle for "set as destination" to switch between start a new route or add */ ATTR(no_warning_if_map_file_missing) ATTR(duplicate) +ATTR(has_menu_button) ATTR2(0x0002ffff,type_int_end) ATTR2(0x00030000,type_string_begin) ATTR(type) diff --git a/navit/graphics/android/graphics_android.c b/navit/graphics/android/graphics_android.c index a543252ce..efde8358a 100644 --- a/navit/graphics/android/graphics_android.c +++ b/navit/graphics/android/graphics_android.c @@ -25,6 +25,8 @@ #include "point.h" #include "graphics.h" #include "color.h" +#include "item.h" +#include "xmlconfig.h" #include "plugin.h" #include "event.h" #include "debug.h" @@ -549,6 +551,19 @@ set_activity(jobject graphics) return 1; } +/** + * @brief Initializes a new Android graphics instance. + * + * This initializes a new Android graphics instance, which can either be the main view or an overlay. + * + * @param ret The new graphics instance + * @param parent The graphics instance that contains the new instance ({@code NULL} for the main view) + * @param p The position of the overlay in its parent ({@code NULL} for the main view) + * @param w The width of the overlay (0 for the main view) + * @param h The height of the overlay (0 for the main view) + * @param wraparound (0 for the main view) + * @param use_camera Whether to use the camera (0 for overlays) + */ static int graphics_android_init(struct graphics_priv *ret, struct graphics_priv *parent, struct point *pnt, int w, int h, int wraparound, int use_camera) { @@ -686,7 +701,7 @@ graphics_android_init(struct graphics_priv *ret, struct graphics_priv *parent, s } static jclass NavitClass; -static jmethodID Navit_disableSuspend, Navit_exit, Navit_fullscreen, Navit_runOptionsItem; +static jmethodID Navit_disableSuspend, Navit_exit, Navit_fullscreen, Navit_runOptionsItem, Navit_showMenu; static int graphics_android_fullscreen(struct window *win, int on) @@ -702,6 +717,17 @@ graphics_android_disable_suspend(struct window *win) (*jnienv)->CallVoidMethod(jnienv, android_activity, Navit_disableSuspend); } +/** + * @brief Runs an item from the Android menu. + * + * This is a callback function which implements multiple API functions. + * + * @param this The {@code graohics_prov} structure + * @param function The API function which was called + * @param in Parameters to pass to the API function + * @param out Points to a buffer which will receive a pointer to the output of the command + * @param valid + */ static void graphics_android_cmd_runMenuItem(struct graphics_priv *this, char *function, struct attr **in, struct attr ***out, int *valid) { @@ -717,18 +743,57 @@ graphics_android_cmd_runMenuItem(struct graphics_priv *this, char *function, str (*jnienv)->CallVoidMethod(jnienv, android_activity, Navit_runOptionsItem, ncmd); } +/** + * @brief Shows the Android menu. + * + * This is the callback function associated with the {@code menu()} API function. + * + * @param this The {@code graohics_prov} structure + * @param function The API function which was called + * @param in Parameters to pass to the API function + * @param out Points to a buffer which will receive a pointer to the output of the command + * @param valid + */ +static void +graphics_android_cmd_menu(struct graphics_priv *this, char *function, struct attr **in, struct attr ***out, int *valid) +{ + dbg(lvl_debug, "enter\n"); + (*jnienv)->CallVoidMethod(jnienv, android_activity, Navit_showMenu); +} + +/** + * The command table. Each entry consists of an API function name and the callback function which implements + * this command. + */ static struct command_table commands[] = { {"map_download_dialog",command_cast(graphics_android_cmd_runMenuItem)}, {"set_map_location",command_cast(graphics_android_cmd_runMenuItem)}, {"backup_restore_dialog",command_cast(graphics_android_cmd_runMenuItem)}, + {"menu", command_cast(graphics_android_cmd_menu)}, }; +/** + * @brief Creates a new Android graphics instance. + * + * This method is called when the graphics plugin is initialized. It creates the main view, i.e. the map view. + * Unless overlay mode is enabled, it also holds any OSD items. + * + * @param nav The navit instance. + * @param meth The methods for the new graphics instance + * @param attrs The attributes for the new graphics instance + * @param cbl The callback list for the new graphics instance + * + * @return The new graphics instance + */ static struct graphics_priv * graphics_android_new(struct navit *nav, struct graphics_methods *meth, struct attr **attrs, struct callback_list *cbl) { struct graphics_priv *ret; struct attr *attr; int use_camera=0; + jmethodID cid; + + dbg(lvl_debug, "enter\n"); if (!event_request_system("android","graphics_android")) return NULL; ret=g_new0(struct graphics_priv, 1); @@ -746,6 +811,22 @@ graphics_android_new(struct navit *nav, struct graphics_methods *meth, struct at } image_cache_hash = g_hash_table_new(g_str_hash, g_str_equal); if (graphics_android_init(ret, NULL, NULL, 0, 0, 0, use_camera)) { + cid = (*jnienv)->GetMethodID(jnienv, ret->NavitGraphicsClass, "hasMenuButton", "()Z"); + if (cid != NULL) { + attr = g_new0(struct attr, 1); + attr->type = attr_has_menu_button; + attr->u.num = (*jnienv)->CallBooleanMethod(jnienv, ret->NavitGraphics, cid); + + /* + * Although the attribute refers to information obtained by the graphics plugin, we are storing it + * with the navit object: the object is easier to access from anywhere in the program, and ultimately + * it refers to a configuration value affecting all of Navit, thus users are likely to look for it in + * the navit object (as the fact that graphics also handles input devices is not immedately obvious). + */ + navit_object_set_attr((struct navit_object *) nav, attr); + dbg(lvl_debug, "attr_has_menu_button=%d\n", attr->u.num); + g_free(attr); + } dbg(lvl_debug,"returning %p\n",ret); return ret; } else { @@ -754,6 +835,21 @@ graphics_android_new(struct navit *nav, struct graphics_methods *meth, struct at } } +/** + * @brief Creates a new overlay + * + * This method creates a graphics instance for a new overlay. If overlay mode is enabled, a separate overlay is + * created for each OSD item. + * + * @param gr The parent graphics instance, i.e. the one which will contain the overlay. + * @param meth The methods for the new graphics instance + * @param p The position of the overlay in its parent + * @param w The width of the overlay + * @param h The height of the overlay + * @param wraparound + * + * @return The graphics instance for the new overlay + */ static struct graphics_priv * overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int wraparound) { @@ -971,6 +1067,9 @@ event_android_new(struct event_methods *meth) Navit_runOptionsItem = (*jnienv)->GetMethodID(jnienv, NavitClass, "runOptionsItem", "(I)V"); if (Navit_runOptionsItem == NULL) return NULL; + Navit_showMenu = (*jnienv)->GetMethodID(jnienv, NavitClass, "showMenu", "()V"); + if (Navit_showMenu == NULL) + return NULL; dbg(lvl_debug,"ok\n"); *meth=event_android_methods; diff --git a/navit/osd/core/osd_core.c b/navit/osd/core/osd_core.c index 56bcd2325..8166e54a2 100644 --- a/navit/osd/core/osd_core.c +++ b/navit/osd/core/osd_core.c @@ -1414,6 +1414,9 @@ osd_compass_new(struct navit *nav, struct osd_methods *meth, struct osd_button { int use_overlay; + /* FIXME: do we need navit_init_cb? It is set in two places but never read. + * osd_button_new sets it to osd_button_init (init callback), and + * osd_button_init sets it to osd_std_click (click callback). */ struct callback *draw_cb,*navit_init_cb; struct graphics_image *img; char *src_dir,*src; @@ -1513,7 +1516,7 @@ osd_button_icon_path(struct osd_button *this_, char *src) { if (!this_->src_dir) return graphics_icon_path(src); - return g_strdup_printf("%s%s%s",this_->src_dir, G_DIR_SEPARATOR_S, src); + return g_strdup_printf("%s%s%s", this_->src_dir, G_DIR_SEPARATOR_S, src); } int @@ -2003,6 +2006,7 @@ osd_nav_next_turn_new(struct navit *nav, struct osd_methods *meth, struct nav_toggle_announcer { int w,h; + /* FIXME this is actually the click callback, which is set once but never read. Do we need this? */ struct callback *navit_init_cb; char *icon_src; int icon_h, icon_w, active, last_state; diff --git a/navit/xpm/Makefile.am b/navit/xpm/Makefile.am index 2ba0d3a5c..40b7cc851 100644 --- a/navit/xpm/Makefile.am +++ b/navit/xpm/Makefile.am @@ -56,6 +56,7 @@ image_DATA += nav_right_2_32.xpm svgs = gui_about.svg svgs += gui_actions.svg svgs += gui_active.svg +svgs += gui_android_menu.svg svgs += gui_bookmark.svg svgs += gui_formerdests.svg svgs += gui_display.svg diff --git a/navit/xpm/gui_android_menu.svg b/navit/xpm/gui_android_menu.svg new file mode 100644 index 000000000..b47eae076 --- /dev/null +++ b/navit/xpm/gui_android_menu.svg @@ -0,0 +1,120 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/navit/xslt/android.xslt b/navit/xslt/android.xslt index 28b9d8245..29802fee2 100644 --- a/navit/xslt/android.xslt +++ b/navit/xslt/android.xslt @@ -9,6 +9,7 @@ + diff --git a/navit/xslt/osd_android.xslt b/navit/xslt/osd_android.xslt new file mode 100644 index 000000000..c5f4afb4d --- /dev/null +++ b/navit/xslt/osd_android.xslt @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/navit/xslt/osd_minimum.xslt b/navit/xslt/osd_minimum.xslt index cda88dc88..5b42769f4 100644 --- a/navit/xslt/osd_minimum.xslt +++ b/navit/xslt/osd_minimum.xslt @@ -18,7 +18,7 @@ - + -- cgit v1.2.1