Skip to content

Commit

Permalink
Merge pull request navit-gps#52 from mvglasow/trac1325.rebased
Browse files Browse the repository at this point in the history
Add:port_android:OSD button to show Android menu
  • Loading branch information
mvglasow committed Jan 3, 2016
2 parents 92cbe43 + 7c59b3c commit f1dda62
Show file tree
Hide file tree
Showing 10 changed files with 286 additions and 14 deletions.
26 changes: 15 additions & 11 deletions navit/android/src/org/navitproject/navit/Navit.java
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@ public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB)
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
else
this.getActionBar().hide();

dialogs = new NavitDialogs(this);

Expand Down Expand Up @@ -590,6 +592,16 @@ public void runOptionsItem(int id)
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
Expand Down Expand Up @@ -690,25 +702,17 @@ public void onDestroy()
NavitDestroy();
}

public void fullscreen(int fullscreen)
{
if(fullscreen != 0)
{
public void fullscreen(int fullscreen) {
if(fullscreen != 0) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB)
this.getActionBar().hide();
}
else
{
else {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB)
this.getActionBar().show();
}
}


public void disableSuspend()
{
wl.acquire();
Expand Down
20 changes: 20 additions & 0 deletions navit/android/src/org/navitproject/navit/NavitGraphics.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
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;
Expand All @@ -41,6 +42,7 @@
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;

Expand Down Expand Up @@ -792,6 +794,24 @@ public void handleMessage(Message msg)
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;
Expand Down
1 change: 1 addition & 0 deletions navit/attr_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
101 changes: 100 additions & 1 deletion navit/graphics/android/graphics_android.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
Expand All @@ -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)
{
Expand All @@ -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);
Expand All @@ -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 {
Expand All @@ -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)
{
Expand Down Expand Up @@ -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;
Expand Down
20 changes: 19 additions & 1 deletion navit/osd/core/osd_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1412,12 +1412,29 @@ 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;
};


/**
* @brief Adjusts width and height of an OSD item to fit the image it displays.
*
* A width or height of 0%, stored in relative attributes as {@code ATTR_REL_RELSHIFT}, is used as a flag
* indicating that the respective dimension is unset, i.e. determined by the dimensions of its image.
*
* If this is the case for height and/or width, the respective dimension will be updated to fit the image.
*
* Note that this method is used by several OSD items, notably {@code osd_image}, {@code osd_button} and
* {@code osd_android_menu}.
*
* @param opc The OSD item
* @param img The image displayed by the item
*/
static void
osd_button_adjust_sizes(struct osd_priv_common *opc, struct graphics_image *img)
{
Expand Down Expand Up @@ -1511,7 +1528,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
Expand Down Expand Up @@ -2001,6 +2018,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;
Expand Down
1 change: 1 addition & 0 deletions navit/xpm/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit f1dda62

Please sign in to comment.