summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre GRANDIN <pgrandin@users.noreply.github.com>2016-02-22 15:13:56 -0800
committerPierre GRANDIN <pgrandin@users.noreply.github.com>2016-02-22 15:13:56 -0800
commit2c77286a6c08af6f77866671af31d3f99719d22a (patch)
tree4b505b22819fc04898c04376defc896a3d8aa251
parent7eaf614763af6a9a4b1c9d3753e35c5bdbcfa8ee (diff)
parent0c95f9992ce02fe6c4da86005f69ba433842aa5f (diff)
downloadnavit-2c77286a6c08af6f77866671af31d3f99719d22a.tar.gz
Merge pull request #73 from mvglasow/android-laf-rebasedR6603
Add:port_android:Look and feel update
-rw-r--r--ci/build_android.sh2
-rw-r--r--ci/build_android_x86.sh2
-rw-r--r--navit/android.c8
-rw-r--r--navit/android/AndroidManifest.xml.cmake6
-rw-r--r--navit/android/AndroidManifest.xml.in3
-rw-r--r--navit/android/res/drawable-hdpi/ic_notify.pngbin0 -> 634 bytes
-rw-r--r--navit/android/res/drawable-hdpi/icon.pngbin6054 -> 5949 bytes
-rw-r--r--navit/android/res/drawable-ldpi/ic_notify.pngbin0 -> 370 bytes
-rw-r--r--navit/android/res/drawable-ldpi/icon.pngbin1966 -> 2208 bytes
-rw-r--r--navit/android/res/drawable-mdpi/ic_notify.pngbin0 -> 462 bytes
-rw-r--r--navit/android/res/drawable-mdpi/icon.pngbin3595 -> 3353 bytes
-rw-r--r--navit/android/res/drawable-xhdpi/ic_notify.pngbin0 -> 832 bytes
-rw-r--r--navit/android/res/drawable-xhdpi/icon.pngbin0 -> 8858 bytes
-rw-r--r--navit/android/res/drawable-xxhdpi/ic_notify.pngbin0 -> 1216 bytes
-rw-r--r--navit/android/res/drawable-xxhdpi/icon.pngbin0 -> 15235 bytes
-rw-r--r--navit/android/res/values-v19/styles.xml31
-rw-r--r--navit/android/res/values-v21/styles.xml46
-rw-r--r--navit/android/res/values/styles.xml42
-rw-r--r--navit/android/src/org/navitproject/navit/Navit.java64
-rw-r--r--navit/android/src/org/navitproject/navit/NavitGraphics.java146
-rw-r--r--navit/graphics.h15
-rw-r--r--navit/graphics/android/graphics_android.c68
-rw-r--r--navit/gui/internal/gui_internal.c6
-rw-r--r--navit/gui/internal/gui_internal_menu.c46
-rw-r--r--navit/navit.c26
-rw-r--r--navit/osd.c66
-rw-r--r--navit/xpm/ic_notify.svg261
27 files changed, 807 insertions, 31 deletions
diff --git a/ci/build_android.sh b/ci/build_android.sh
index 6525541ba..a063bf2fa 100644
--- a/ci/build_android.sh
+++ b/ci/build_android.sh
@@ -46,7 +46,7 @@ android list targets
mkdir $CIRCLE_ARTIFACTS/android/
cp ~/navit/navit/android/CMakeLists.txt $CIRCLE_ARTIFACTS/android/
-cmake -DCMAKE_TOOLCHAIN_FILE=$CMAKE_FILE -DCACHE_SIZE='(20*1024*1024)' -DAVOID_FLOAT=1 -DSAMPLE_MAP=n -DBUILD_MAPTOOL=n -DANDROID_API_VERSION=19 $SOURCE_PATH
+cmake -DCMAKE_TOOLCHAIN_FILE=$CMAKE_FILE -DCACHE_SIZE='(20*1024*1024)' -DAVOID_FLOAT=1 -DSAMPLE_MAP=n -DBUILD_MAPTOOL=n -DANDROID_API_VERSION=21 -DANDROID_NDK_API_VERSION=19 $SOURCE_PATH
make || exit 1
if [[ "${CIRCLE_BRANCH}" == "master" ]]; then
make apkg-release && mv navit/android/bin/Navit-release-unsigned.apk $CIRCLE_ARTIFACTS/navit-$CIRCLE_SHA1-release-unsigned.apk || exit 1
diff --git a/ci/build_android_x86.sh b/ci/build_android_x86.sh
index 695556e07..6755ad347 100644
--- a/ci/build_android_x86.sh
+++ b/ci/build_android_x86.sh
@@ -11,7 +11,7 @@ mkdir android-x86 && cd android-x86
android list targets
-cmake -DCMAKE_TOOLCHAIN_FILE=$CMAKE_FILE -DAVOID_FLOAT=1 -DSAMPLE_MAP=n -DBUILD_MAPTOOL=n -DANDROID_API_VERSION=19 -DDISABLE_CXX=1 -DDISABLE_QT=1 ../ || exit -1
+cmake -DCMAKE_TOOLCHAIN_FILE=$CMAKE_FILE -DAVOID_FLOAT=1 -DSAMPLE_MAP=n -DBUILD_MAPTOOL=n -DANDROID_API_VERSION=21 -DANDROID_NDK_API_VERSION=19 -DDISABLE_CXX=1 -DDISABLE_QT=1 ../ || exit -1
make || exit -1
if [[ "${CIRCLE_BRANCH}" == "master" ]]; then
diff --git a/navit/android.c b/navit/android.c
index d35c105cf..6e62da1b3 100644
--- a/navit/android.c
+++ b/navit/android.c
@@ -118,6 +118,14 @@ Java_org_navitproject_navit_NavitGraphics_SizeChangedCallback( JNIEnv* env, jobj
}
JNIEXPORT void JNICALL
+Java_org_navitproject_navit_NavitGraphics_PaddingChangedCallback(JNIEnv* env, jobject thiz, int id, int left, int top, int right, int bottom)
+{
+ dbg(lvl_debug,"enter %p %d %d %d %d\n",(struct callback *)id, left, top, right, bottom);
+ if (id)
+ callback_call_4((struct callback *)id, left, top, right, bottom);
+}
+
+JNIEXPORT void JNICALL
Java_org_navitproject_navit_NavitGraphics_ButtonCallback( JNIEnv* env, jobject thiz, int id, int pressed, int button, int x, int y)
{
dbg(lvl_debug,"enter %p %d %d\n",(struct callback *)id,pressed,button);
diff --git a/navit/android/AndroidManifest.xml.cmake b/navit/android/AndroidManifest.xml.cmake
index 9267f65a3..b5bd757cb 100644
--- a/navit/android/AndroidManifest.xml.cmake
+++ b/navit/android/AndroidManifest.xml.cmake
@@ -17,10 +17,12 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application android:label="@string/app_name"
android:icon="@drawable/icon"
- android:name=".NavitAppConfig">
+ android:name=".NavitAppConfig"
+ android:theme="@style/NavitBaseTheme">
<activity android:name="Navit"
android:label="@string/app_name"
- android:configChanges="locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|fontScale|screenSize">
+ android:configChanges="locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|fontScale|screenSize"
+ android:theme="@style/NavitTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
diff --git a/navit/android/AndroidManifest.xml.in b/navit/android/AndroidManifest.xml.in
index 5a43ee277..085276623 100644
--- a/navit/android/AndroidManifest.xml.in
+++ b/navit/android/AndroidManifest.xml.in
@@ -7,7 +7,8 @@
android:installLocation="auto">
<application android:label="@string/app_name"
android:icon="@drawable/icon"
- android:name=".NavitAppConfig">
+ android:name=".NavitAppConfig"
+ android:theme="@style/NavitTheme">
<activity android:name="Navit"
android:label="@string/app_name"
android:configChanges="locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|fontScale|screenSize">
diff --git a/navit/android/res/drawable-hdpi/ic_notify.png b/navit/android/res/drawable-hdpi/ic_notify.png
new file mode 100644
index 000000000..7516b2fbd
--- /dev/null
+++ b/navit/android/res/drawable-hdpi/ic_notify.png
Binary files differ
diff --git a/navit/android/res/drawable-hdpi/icon.png b/navit/android/res/drawable-hdpi/icon.png
index 3b01b5c3d..311c57b59 100644
--- a/navit/android/res/drawable-hdpi/icon.png
+++ b/navit/android/res/drawable-hdpi/icon.png
Binary files differ
diff --git a/navit/android/res/drawable-ldpi/ic_notify.png b/navit/android/res/drawable-ldpi/ic_notify.png
new file mode 100644
index 000000000..010d55fb3
--- /dev/null
+++ b/navit/android/res/drawable-ldpi/ic_notify.png
Binary files differ
diff --git a/navit/android/res/drawable-ldpi/icon.png b/navit/android/res/drawable-ldpi/icon.png
index b72d1e40b..da2553687 100644
--- a/navit/android/res/drawable-ldpi/icon.png
+++ b/navit/android/res/drawable-ldpi/icon.png
Binary files differ
diff --git a/navit/android/res/drawable-mdpi/ic_notify.png b/navit/android/res/drawable-mdpi/ic_notify.png
new file mode 100644
index 000000000..d6de8d53f
--- /dev/null
+++ b/navit/android/res/drawable-mdpi/ic_notify.png
Binary files differ
diff --git a/navit/android/res/drawable-mdpi/icon.png b/navit/android/res/drawable-mdpi/icon.png
index 33bbab7f6..f8f68e8bc 100644
--- a/navit/android/res/drawable-mdpi/icon.png
+++ b/navit/android/res/drawable-mdpi/icon.png
Binary files differ
diff --git a/navit/android/res/drawable-xhdpi/ic_notify.png b/navit/android/res/drawable-xhdpi/ic_notify.png
new file mode 100644
index 000000000..72371c974
--- /dev/null
+++ b/navit/android/res/drawable-xhdpi/ic_notify.png
Binary files differ
diff --git a/navit/android/res/drawable-xhdpi/icon.png b/navit/android/res/drawable-xhdpi/icon.png
new file mode 100644
index 000000000..649fb32d4
--- /dev/null
+++ b/navit/android/res/drawable-xhdpi/icon.png
Binary files differ
diff --git a/navit/android/res/drawable-xxhdpi/ic_notify.png b/navit/android/res/drawable-xxhdpi/ic_notify.png
new file mode 100644
index 000000000..d47a41154
--- /dev/null
+++ b/navit/android/res/drawable-xxhdpi/ic_notify.png
Binary files differ
diff --git a/navit/android/res/drawable-xxhdpi/icon.png b/navit/android/res/drawable-xxhdpi/icon.png
new file mode 100644
index 000000000..398945c23
--- /dev/null
+++ b/navit/android/res/drawable-xxhdpi/icon.png
Binary files differ
diff --git a/navit/android/res/values-v19/styles.xml b/navit/android/res/values-v19/styles.xml
new file mode 100644
index 000000000..b3ea5c14f
--- /dev/null
+++ b/navit/android/res/values-v19/styles.xml
@@ -0,0 +1,31 @@
+<resources>
+
+ <!--
+ Base application theme for API 19+. This theme completely replaces
+ NavitBaseTheme from BOTH res/values/styles.xml and
+ res/values-v19/styles.xml on API 19+ devices.
+ -->
+ <style name="NavitBaseTheme" parent="android:Theme.Holo">
+
+ <!-- Main theme colors -->
+ <!-- your app branding color for the app bar -->
+ <item name="android:colorPrimary">@color/navitYellow500</item>
+ <!-- darker variant for the status bar and contextual app bars -->
+ <item name="android:colorPrimaryDark">@color/navitYellow700</item>
+ <!-- theme UI controls like checkboxes and text fields -->
+ <item name="android:colorAccent">@color/navitBlue500</item>
+ </style>
+
+ <!--
+ Main Activity theme for API 19+. This theme completely replaces
+ NavitTheme from BOTH res/values/styles.xml and
+ res/values-v19/styles.xml on API 19+ devices.
+ -->
+ <style name="NavitTheme" parent="NavitBaseTheme">
+
+ <!-- API 19 theme customizations can go here. -->
+ <item name="android:windowTranslucentNavigation">true</item>
+ <item name="android:windowTranslucentStatus">true</item>
+ </style>
+
+</resources> \ No newline at end of file
diff --git a/navit/android/res/values-v21/styles.xml b/navit/android/res/values-v21/styles.xml
new file mode 100644
index 000000000..a1d66bb3d
--- /dev/null
+++ b/navit/android/res/values-v21/styles.xml
@@ -0,0 +1,46 @@
+<resources>
+
+ <!--
+ Base application theme for API 21+. This theme completely replaces
+ NavitBaseTheme from BOTH res/values/styles.xml and
+ res/values-v.../styles.xml on API 21+ devices.
+ -->
+ <style name="NavitBaseTheme" parent="android:Theme.Material">
+
+ <!-- Main theme colors -->
+ <!-- your app branding color for the app bar -->
+ <item name="android:colorPrimary">@color/navitYellow500</item>
+ <!-- darker variant for the status bar and contextual app bars -->
+ <item name="android:colorPrimaryDark">@color/navitYellow700</item>
+ <!-- theme UI controls like checkboxes and text fields -->
+ <item name="android:colorAccent">@color/navitBlue500</item>
+ </style>
+
+ <!--
+ Main Activity theme for API 21+. This theme completely replaces
+ NavitTheme from BOTH res/values/styles.xml and
+ res/values-v21/styles.xml on API 21+ devices.
+ -->
+ <style name="NavitTheme" parent="NavitBaseTheme">
+
+ <!-- API 21 theme customizations can go here. -->
+
+ <!--
+ Don't use translucent system bars on API 21 as they are drawn with a semitransparent
+ black background which can't be changed.
+ -->
+ <item name="android:windowTranslucentNavigation">false</item>
+ <item name="android:windowTranslucentStatus">false</item>
+
+ <!--
+ We could set any semi-transparent color here (or change it in code), but this would not
+ be available on API 19/20. Simply specifying full transparency allows us to implement a
+ separate mechanism that will work on all versions.
+ -->
+ <item name="android:navigationBarColor">@android:color/transparent</item>
+ <item name="android:statusBarColor">@android:color/transparent</item>
+
+ <item name="android:windowDrawsSystemBarBackgrounds">true</item>
+ </style>
+
+</resources> \ No newline at end of file
diff --git a/navit/android/res/values/styles.xml b/navit/android/res/values/styles.xml
new file mode 100644
index 000000000..91094e222
--- /dev/null
+++ b/navit/android/res/values/styles.xml
@@ -0,0 +1,42 @@
+<resources>
+
+ <!--
+ Base application theme, dependent on API level. This theme is replaced
+ by NavitBaseTheme from res/values-vXX/styles.xml on newer devices.
+ -->
+ <style name="NavitBaseTheme" parent="android:Theme.Holo">
+ <!--
+ Theme customizations available in newer API levels can go in
+ res/values-vXX/styles.xml, while customizations related to
+ backward-compatibility can go here.
+ -->
+ </style>
+
+ <!-- Theme for Navit's main Activity. -->
+ <style name="NavitTheme" parent="NavitBaseTheme">
+ <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+ </style>
+
+ <!-- TODO complete list of shades for both colors -->
+ <!--
+ Primary color is derived average of icon colors (500 in Android parlance):
+ 213 164 19 #d5a411 hsl 45 92 84
+
+ Dark color is normally the 600 color (i.e. slightly darker than 500)
+ 209 155 19 #d19b13 hsl 43 91 82
+ -->
+
+
+ <!-- Yellow from Navit icon background (300 and 700 are the extremes of the gradient, 500 is the average, 900 is the line color) -->
+ <color name="navitYellow300">#e9cb14</color>
+ <color name="navitYellow500">#d5a411</color>
+ <!-- <color name="navitYellow600">#d19b13</color> -->
+ <color name="navitYellow700">#c17d11</color>
+ <color name="navitYellow900">#43350f</color>
+
+ <!-- Blue from arrow in Navit icon (500 is the midpoint of the gradient, 300 is the end, 900 is the line color) -->
+ <color name="navitBlue300">#329eff</color>
+ <color name="navitBlue500">#1a6cb6</color>
+ <color name="navitBlue900">#1f3157</color>
+
+</resources> \ No newline at end of file
diff --git a/navit/android/src/org/navitproject/navit/Navit.java b/navit/android/src/org/navitproject/navit/Navit.java
index a117ccd6d..920b79a98 100644
--- a/navit/android/src/org/navitproject/navit/Navit.java
+++ b/navit/android/src/org/navitproject/navit/Navit.java
@@ -25,13 +25,18 @@ import java.io.InputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import android.annotation.TargetApi;
import android.app.Activity;
+import android.app.ActivityManager.TaskDescription;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.Notification;
@@ -44,9 +49,15 @@ import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Configuration;
import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.Point;
import android.media.AudioManager;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Message;
@@ -59,6 +70,7 @@ import android.util.Log;
import android.view.Display;
import android.view.Menu;
import android.view.MenuItem;
+import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
@@ -75,6 +87,11 @@ public class Navit extends Activity
private NavitActivityResult ActivityResults[];
public static InputMethodManager mgr = null;
public static DisplayMetrics metrics = null;
+ public static int status_bar_height = 0;
+ public static int action_bar_default_height = 0;
+ public static int navigation_bar_height = 0;
+ public static int navigation_bar_height_landscape= 0;
+ public static int navigation_bar_width = 0;
public static Boolean show_soft_keyboard = false;
public static Boolean show_soft_keyboard_now_showing = false;
public static long last_pressed_menu_key = 0L;
@@ -97,6 +114,7 @@ public class Navit extends Activity
static final String NAVIT_DATA_SHARE_DIR = NAVIT_DATA_DIR + "/share";
static final String FIRST_STARTUP_FILE = NAVIT_DATA_SHARE_DIR + "/has_run_once.txt";
public static final String NAVIT_PREFS = "NavitPrefs";
+ Boolean isFullscreen = false;
public void removeFileIfExists(String source) {
File file = new File(source);
@@ -267,12 +285,29 @@ public class Navit extends Activity
// Setup the status bar notification
// This notification is removed in the exit() function
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); // Grab a handle to the NotificationManager
- Notification NavitNotification = new Notification(R.drawable.icon, getString(R.string.notification_ticker), System.currentTimeMillis()); // Create a new notification, with the text string to show when the notification first appears
+ Notification NavitNotification = new Notification(R.drawable.ic_notify, getString(R.string.notification_ticker), System.currentTimeMillis()); // Create a new notification, with the text string to show when the notification first appears
PendingIntent appIntent = PendingIntent.getActivity(getApplicationContext(), 0, getIntent(), 0);
NavitNotification.setLatestEventInfo(getApplicationContext(), "Navit", getString(R.string.notification_event_default), appIntent); // Set the text in the notification
NavitNotification.flags|=Notification.FLAG_ONGOING_EVENT; // Ensure that the notification appears in Ongoing
nm.notify(R.string.app_name, NavitNotification); // Set the notification
+ // Status and navigation bar sizes
+ // These are platform defaults and do not change with rotation, but we have to figure out which ones apply
+ // (is the navigation bar visible? on the side or at the bottom?)
+ Resources resources = getResources();
+ int shid = resources.getIdentifier("status_bar_height", "dimen", "android");
+ int adhid = resources.getIdentifier("action_bar_default_height", "dimen", "android");
+ int nhid = resources.getIdentifier("navigation_bar_height", "dimen", "android");
+ int nhlid = resources.getIdentifier("navigation_bar_height_landscape", "dimen", "android");
+ int nwid = resources.getIdentifier("navigation_bar_width", "dimen", "android");
+ status_bar_height = (shid > 0) ? resources.getDimensionPixelSize(shid) : 0;
+ action_bar_default_height = (adhid > 0) ? resources.getDimensionPixelSize(adhid) : 0;
+ navigation_bar_height = (nhid > 0) ? resources.getDimensionPixelSize(nhid) : 0;
+ navigation_bar_height_landscape = (nhid > 0) ? resources.getDimensionPixelSize(nhlid) : 0;
+ navigation_bar_width = (nwid > 0) ? resources.getDimensionPixelSize(nwid) : 0;
+ Log.d(TAG, String.format("status_bar_height=%d, action_bar_default_height=%d, navigation_bar_height=%d, navigation_bar_height_landscape=%d, navigation_bar_width=%d",
+ status_bar_height, action_bar_default_height, navigation_bar_height, navigation_bar_height_landscape, navigation_bar_width));
+
// get the local language -------------
Locale locale = java.util.Locale.getDefault();
String lang = locale.getLanguage();
@@ -382,7 +417,13 @@ public class Navit extends Activity
public void onResume()
{
super.onResume();
- Log.e("Navit", "OnResume");
+ Log.d("Navit", "OnResume");
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
+ /* Required to make system bars fully transparent */
+ getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
+ }
//InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
// DEBUG
// intent_data = "google.navigation:q=Wien Burggasse 27";
@@ -593,6 +634,7 @@ public class Navit extends Activity
}
}
+
/**
* @brief Shows the Options menu.
*
@@ -703,7 +745,10 @@ public class Navit extends Activity
}
public void fullscreen(int fullscreen) {
- if(fullscreen != 0) {
+ int w, h;
+
+ isFullscreen = (fullscreen != 0);
+ if (isFullscreen) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
}
@@ -711,6 +756,19 @@ public class Navit extends Activity
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
+
+ Display display_ = getWindowManager().getDefaultDisplay();
+ if (Build.VERSION.SDK_INT < 17) {
+ w = display_.getWidth();
+ h = display_.getHeight();
+ } else {
+ Point size = new Point();
+ display_.getRealSize(size);
+ w = size.x;
+ h = size.y;
+ }
+ Log.d(TAG, String.format("Toggle fullscreen, w=%d, h=%d", w, h));
+ N_NavitGraphics.handleResize(w, h);
}
public void disableSuspend()
diff --git a/navit/android/src/org/navitproject/navit/NavitGraphics.java b/navit/android/src/org/navitproject/navit/NavitGraphics.java
index 08f4fbe3e..005f79bf2 100644
--- a/navit/android/src/org/navitproject/navit/NavitGraphics.java
+++ b/navit/android/src/org/navitproject/navit/NavitGraphics.java
@@ -25,8 +25,11 @@ import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
@@ -38,12 +41,15 @@ import android.os.Message;
import android.util.FloatMath;
import android.util.Log;
import android.view.ContextMenu;
+import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
+import android.view.ViewGroup.LayoutParams;
import android.view.inputmethod.InputMethodManager;
+import android.widget.FrameLayout;
import android.widget.RelativeLayout;
@@ -57,8 +63,12 @@ public class NavitGraphics
int pos_y;
int pos_wraparound;
int overlay_disabled;
+ int bgcolor;
float trackball_x, trackball_y;
View view;
+ SystemBarTintView navigationTintView;
+ SystemBarTintView statusTintView;
+ FrameLayout frameLayout;
RelativeLayout relativelayout;
NavitCamera camera;
Activity activity;
@@ -70,6 +80,14 @@ public class NavitGraphics
private static long interval_for_long_press = 200L;
private Handler timer_handler = new Handler();
+
+ public void setBackgroundColor(int bgcolor) {
+ this.bgcolor = bgcolor;
+ if (navigationTintView != null)
+ navigationTintView.setBackgroundColor(bgcolor);
+ if (statusTintView != null)
+ statusTintView.setBackgroundColor(bgcolor);
+ }
public void SetCamera(int use_camera)
{
@@ -199,11 +217,8 @@ public class NavitGraphics
Log.e("Navit", "NavitGraphics -> onSizeChanged scaledDensity="
+ Navit.metrics.scaledDensity);
super.onSizeChanged(w, h, oldw, oldh);
- draw_bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
- draw_canvas = new Canvas(draw_bitmap);
- bitmap_w = w;
- bitmap_h = h;
- SizeChangedCallback(SizeChangedCallbackID, w, h);
+
+ handleResize(w, h);
}
public void do_longpress_action()
@@ -687,6 +702,15 @@ public class NavitGraphics
}
+ private class SystemBarTintView extends View {
+
+ public SystemBarTintView(Context context) {
+ super(context);
+ this.setBackgroundColor(bgcolor);
+ }
+
+ }
+
public NavitGraphics(final Activity activity, NavitGraphics parent, int x, int y, int w, int h,
int wraparound, int use_camera)
{
@@ -699,14 +723,21 @@ public class NavitGraphics
view.setFocusable(true);
view.setFocusableInTouchMode(true);
view.setKeepScreenOn(true);
+ frameLayout = new FrameLayout(activity);
relativelayout = new RelativeLayout(activity);
+ frameLayout.addView(relativelayout);
if (use_camera != 0)
{
SetCamera(use_camera);
}
relativelayout.addView(view);
+
+ navigationTintView = new SystemBarTintView(activity);
+ statusTintView = new SystemBarTintView(activity);
+ frameLayout.addView(navigationTintView);
+ frameLayout.addView(statusTintView);
- activity.setContentView(relativelayout);
+ activity.setContentView(frameLayout);
view.requestFocus();
}
else
@@ -783,6 +814,7 @@ public class NavitGraphics
};
public native void SizeChangedCallback(int id, int x, int y);
+ public native void PaddingChangedCallback(int id, int left, int right, int top, int bottom);
public native void KeypressCallback(int id, String s);
public native int CallbackMessageChannel(int i, String s);
public native void ButtonCallback(int id, int pressed, int button, int x, int y);
@@ -791,8 +823,100 @@ public class NavitGraphics
public static native String[][] GetAllCountries();
private Canvas draw_canvas;
private Bitmap draw_bitmap;
- private int SizeChangedCallbackID, ButtonCallbackID, MotionCallbackID, KeypressCallbackID;
+ private int SizeChangedCallbackID, PaddingChangedCallbackID, ButtonCallbackID, MotionCallbackID, KeypressCallbackID;
// private int count;
+
+ /**
+ * @brief Handles resize events.
+ *
+ * This method is called whenever the main View is resized in any way. This is the case when its
+ * {@code onSizeChanged()} event handler fires or when toggling Fullscreen mode.
+ *
+ * It (re-)evaluates if and where the navigation bar is going to be shown, and calculates the
+ * padding for objects which should not be obstructed.
+ */
+ public void handleResize(int w, int h) {
+ if (this.parent_graphics != null)
+ this.parent_graphics.handleResize(w, h);
+ else {
+ Log.d("NavitGraphics", String.format("handleResize w=%d h=%d", w, h));
+ /*
+ * The code would work on API14+ but is meaningful only on API17+
+ */
+ if (Build.VERSION.SDK_INT >= 17) {
+ Navit navit = null;
+ if (activity instanceof Navit) {
+ navit = (Navit) activity;
+ /*
+ * Determine visibility of status bar.
+ * The status bar is always visible unless we are in fullscreen mode.
+ */
+ final Boolean isStatusShowing = !navit.isFullscreen;
+
+ /*
+ * Determine visibility of navigation bar.
+ * This logic is based on the presence of a hardware menu button and is known to work on
+ * devices which allow switching between hw and sw buttons (OnePlus One running CyanogenMod).
+ */
+ final Boolean isNavShowing = !ViewConfiguration.get(navit.getApplication()).hasPermanentMenuKey();
+
+ Log.d("NavitGraphics", String.format("isStatusShowing=%b isNavShowing=%b", isStatusShowing, isNavShowing));
+
+ /*
+ * Determine where the navigation bar would be displayed.
+ * Logic is taken from AOSP RenderSessionImpl.findNavigationBar()
+ * (platform/frameworks/base/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java)
+ */
+ Boolean isLandscape = (navit.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE);
+ final Boolean isNavAtBottom = (!isLandscape) || (navit.getResources().getConfiguration().smallestScreenWidthDp >= 600);
+ Log.d("NavitGraphics", String.format("isNavAtBottom=%b (Configuration.smallestScreenWidthDp=%d, isLandscape=%b)",
+ isNavAtBottom, navit.getResources().getConfiguration().smallestScreenWidthDp, isLandscape));
+
+ int left = 0;
+ int top = isStatusShowing ? Navit.status_bar_height : 0;
+ int right = (isNavShowing && !isNavAtBottom) ? Navit.navigation_bar_width : 0;
+ final int bottom = (!(isNavShowing && isNavAtBottom)) ? 0 : isLandscape ? Navit.navigation_bar_height_landscape : Navit.navigation_bar_height;
+
+ /* hide tint bars during update to prevent ugly effects */
+ statusTintView.setVisibility(View.GONE);
+ navigationTintView.setVisibility(View.GONE);
+
+ frameLayout.post(new Runnable() {
+ @Override
+ public void run() {
+ statusTintView.setVisibility(isStatusShowing ? View.VISIBLE : View.GONE);
+ FrameLayout.LayoutParams statusLayoutParams = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, Navit.status_bar_height, Gravity.TOP);
+ /* Prevent tint views from overlapping when navigation is on the right */
+ statusLayoutParams.setMargins(0, 0, (isNavShowing && !isNavAtBottom) ? Navit.navigation_bar_width : 0, 0);
+ statusTintView.setLayoutParams(statusLayoutParams);
+ Log.d("NavitGraphics", String.format("statusTintView: width=%d height=%d",
+ statusTintView.getWidth(), statusTintView.getHeight()));
+
+ navigationTintView.setVisibility(isNavShowing ? View.VISIBLE : View.GONE);
+ LayoutParams navigationLayoutParams = new FrameLayout.LayoutParams(
+ isNavAtBottom ? LayoutParams.MATCH_PARENT : Navit.navigation_bar_width, // X
+ isNavAtBottom ? bottom : LayoutParams.MATCH_PARENT, // Y
+ Gravity.BOTTOM | Gravity.RIGHT);
+ navigationTintView.setLayoutParams(navigationLayoutParams);
+ Log.d("NavitGraphics", String.format("navigationTintView: width=%d height=%d",
+ navigationTintView.getWidth(), navigationTintView.getHeight()));
+ }
+ });
+
+ Log.d("NavitGraphics", String.format("Padding left=%d top=%d right=%d bottom=%d", left, top, right, bottom));
+
+ PaddingChangedCallback(PaddingChangedCallbackID, left, top, right, bottom);
+ } else
+ Log.e("NavitGraphics", "Main Activity is not a Navit instance, cannot update padding");
+ }
+
+ draw_bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
+ draw_canvas = new Canvas(draw_bitmap);
+ bitmap_w = w;
+ bitmap_h = h;
+ SizeChangedCallback(SizeChangedCallbackID, w, h);
+ }
+ }
/**
* @brief Returns whether the device has a hardware menu button.
@@ -802,6 +926,10 @@ public class NavitGraphics
* 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.
+ *
+ * Note that this method is not aware of non-standard mechanisms on some customized builds of Android. For
+ * example, CyanogenMod has an option to add a menu button to the navigation bar. Even with that option,
+ * this method will still return `false`.
*/
public boolean hasMenuButton() {
if (Build.VERSION.SDK_INT <= 10)
@@ -816,6 +944,10 @@ public class NavitGraphics
{
SizeChangedCallbackID = id;
}
+ public void setPaddingChangedCallback(int id)
+ {
+ PaddingChangedCallbackID = id;
+ }
public void setButtonCallback(int id)
{
ButtonCallbackID = id;
diff --git a/navit/graphics.h b/navit/graphics.h
index fb18347cf..44bd6c919 100644
--- a/navit/graphics.h
+++ b/navit/graphics.h
@@ -74,6 +74,21 @@ struct graphics_image_buffer {
* @see graphics_gtk_drawing_area#plugin_init()
* @see graphics_android#plugin_init()
*/
+
+/**
+ * Describes areas at each edge of the application window which may be obstructed by the system UI.
+ *
+ * This allows the map to use all available space, including areas which may be obscured by system UI
+ * elements, while constraining other elements such as OSDs or UI controls to an area that is guaranteed
+ * to be visible as long as Navit is in the foreground.
+ */
+struct padding {
+ int left;
+ int top;
+ int right;
+ int bottom;
+};
+
struct graphics_methods {
void (*graphics_destroy)(struct graphics_priv *gr);
void (*draw_mode)(struct graphics_priv *gr, enum draw_mode_num mode);
diff --git a/navit/graphics/android/graphics_android.c b/navit/graphics/android/graphics_android.c
index 2bfbacab4..2bf9ed952 100644
--- a/navit/graphics/android/graphics_android.c
+++ b/navit/graphics/android/graphics_android.c
@@ -39,7 +39,8 @@ struct graphics_priv {
jmethodID NavitGraphics_draw_polyline, NavitGraphics_draw_polygon, NavitGraphics_draw_rectangle,
NavitGraphics_draw_circle, NavitGraphics_draw_text, NavitGraphics_draw_image,
NavitGraphics_draw_image_warp, NavitGraphics_draw_mode, NavitGraphics_draw_drag,
- NavitGraphics_overlay_disable, NavitGraphics_overlay_resize, NavitGraphics_SetCamera;
+ NavitGraphics_overlay_disable, NavitGraphics_overlay_resize, NavitGraphics_SetCamera,
+ NavitGraphics_setBackgroundColor;
jclass PaintClass;
jmethodID Paint_init,Paint_setStrokeWidth,Paint_setARGB;
@@ -64,6 +65,8 @@ struct graphics_priv {
struct callback_list *cbl;
struct window win;
+ struct padding *padding;
+ jint bgcolor;
};
struct graphics_font_priv {
@@ -419,9 +422,11 @@ static struct graphics_priv * overlay_new(struct graphics_priv *gr, struct graph
static void *
get_data(struct graphics_priv *this, const char *type)
{
- if (strcmp(type,"window"))
- return NULL;
- return &this->win;
+ if (!strcmp(type,"padding"))
+ return this->padding;
+ if (!strcmp(type,"window"))
+ return &this->win;
+ return NULL;
}
static void image_free(struct graphics_priv *gr, struct graphics_image_priv *priv)
@@ -463,6 +468,18 @@ set_attr(struct graphics_priv *gra, struct attr *attr)
case attr_use_camera:
(*jnienv)->CallVoidMethod(jnienv, gra->NavitGraphics, gra->NavitGraphics_SetCamera, attr->u.num);
return 1;
+ case attr_background_color:
+ gra->bgcolor = (attr->u.color->a / 0x101) << 24
+ | (attr->u.color->r / 0x101) << 16
+ | (attr->u.color->g / 0x101) << 8
+ | (attr->u.color->b / 0x101);
+ dbg(lvl_debug, "set attr_background_color %04x %04x %04x %04x (%08x)\n",
+ attr->u.color->r, attr->u.color->g, attr->u.color->b, attr->u.color->a, gra->bgcolor);
+ if (gra->NavitGraphics_setBackgroundColor != NULL)
+ (*jnienv)->CallVoidMethod(jnienv, gra->NavitGraphics, gra->NavitGraphics_setBackgroundColor, gra->bgcolor);
+ else
+ dbg(lvl_error, "NavitGraphics.setBackgroundColor not found, cannot set background color\n");
+ return 1;
default:
return 0;
}
@@ -496,10 +513,21 @@ static void
resize_callback(struct graphics_priv *gra, int w, int h)
{
dbg(lvl_debug,"w=%d h=%d ok\n",w,h);
+ dbg(lvl_debug,"gra=%p, %d callbacks in list\n", gra, g_list_length(gra->cbl));
callback_list_call_attr_2(gra->cbl, attr_resize, (void *)w, (void *)h);
}
static void
+padding_callback(struct graphics_priv *gra, int left, int top, int right, int bottom)
+{
+ dbg(lvl_debug, "win.padding left=%d top=%d right=%d bottom=%d ok\n", left, top, right, bottom);
+ gra->padding->left = left;
+ gra->padding->top = top;
+ gra->padding->right = right;
+ gra->padding->bottom = bottom;
+}
+
+static void
motion_callback(struct graphics_priv *gra, int x, int y)
{
struct point p;
@@ -569,6 +597,8 @@ graphics_android_init(struct graphics_priv *ret, struct graphics_priv *parent, s
jmethodID cid, Context_getPackageName;
dbg(lvl_debug,"at 2 jnienv=%p\n",jnienv);
+ if (parent)
+ ret->padding = parent->padding;
if (!find_class_global("android/graphics/Paint", &ret->PaintClass))
return 0;
if (!find_method(ret->PaintClass, "<init>", "(I)V", &ret->Paint_init))
@@ -644,6 +674,14 @@ graphics_android_init(struct graphics_priv *ret, struct graphics_priv *parent, s
cb=callback_new_1(callback_cast(resize_callback), ret);
(*jnienv)->CallVoidMethod(jnienv, ret->NavitGraphics, cid, (int)cb);
+ cid = (*jnienv)->GetMethodID(jnienv, ret->NavitGraphicsClass, "setPaddingChangedCallback", "(I)V");
+ if (cid == NULL) {
+ dbg(lvl_error,"no SetPaddingCallback method found\n");
+ return 0; /* exception thrown */
+ }
+ cb=callback_new_1(callback_cast(padding_callback), ret);
+ (*jnienv)->CallVoidMethod(jnienv, ret->NavitGraphics, cid, (int)cb);
+
cid = (*jnienv)->GetMethodID(jnienv, ret->NavitGraphicsClass, "setButtonCallback", "(I)V");
if (cid == NULL) {
dbg(lvl_error,"no SetButtonCallback method found\n");
@@ -790,6 +828,7 @@ graphics_android_new(struct navit *nav, struct graphics_methods *meth, struct at
struct attr *attr;
int use_camera=0;
jmethodID cid;
+ jint android_bgcolor;
dbg(lvl_debug, "enter\n");
if (!event_request_system("android","graphics_android"))
@@ -801,6 +840,23 @@ graphics_android_new(struct navit *nav, struct graphics_methods *meth, struct at
ret->win.priv=ret;
ret->win.fullscreen=graphics_android_fullscreen;
ret->win.disable_suspend=graphics_android_disable_suspend;
+ ret->padding = g_new0(struct padding, 1);
+ ret->padding->left = 0;
+ ret->padding->top = 0;
+ ret->padding->right = 0;
+ ret->padding->bottom = 0;
+ /* attr_background_color is the background color for system bars (API 17+ only) */
+ if ((attr=attr_search(attrs, NULL, attr_background_color))) {
+ ret->bgcolor = (attr->u.color->a / 0x101) << 24
+ | (attr->u.color->r / 0x101) << 16
+ | (attr->u.color->g / 0x101) << 8
+ | (attr->u.color->b / 0x101);
+ dbg(lvl_debug, "attr_background_color %04x %04x %04x %04x (%08x)\n",
+ attr->u.color->r, attr->u.color->g, attr->u.color->b, attr->u.color->a, ret->bgcolor);
+ } else {
+ /* default is the same as for OSD */
+ ret->bgcolor = 0x60000000;
+ }
if ((attr=attr_search(attrs, NULL, attr_use_camera))) {
use_camera=attr->u.num;
}
@@ -825,6 +881,10 @@ graphics_android_new(struct navit *nav, struct graphics_methods *meth, struct at
dbg(lvl_debug, "attr_has_menu_button=%d\n", attr->u.num);
g_free(attr);
}
+ ret->NavitGraphics_setBackgroundColor = (*jnienv)->GetMethodID(jnienv, ret->NavitGraphicsClass, "setBackgroundColor", "(I)V");
+ if (ret->NavitGraphics_setBackgroundColor != NULL) {
+ (*jnienv)->CallVoidMethod(jnienv, ret->NavitGraphics, ret->NavitGraphics_setBackgroundColor, ret->bgcolor);
+ }
dbg(lvl_debug,"returning %p\n",ret);
return ret;
} else {
diff --git a/navit/gui/internal/gui_internal.c b/navit/gui/internal/gui_internal.c
index 3affd52e4..08066cbc4 100644
--- a/navit/gui/internal/gui_internal.c
+++ b/navit/gui/internal/gui_internal.c
@@ -2668,6 +2668,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) {
diff --git a/navit/gui/internal/gui_internal_menu.c b/navit/gui/internal/gui_internal_menu.c
index 854571195..33def9983 100644
--- a/navit/gui/internal/gui_internal_menu.c
+++ b/navit/gui/internal/gui_internal_menu.c
@@ -110,6 +110,12 @@ 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);
@@ -117,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);
@@ -149,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);
@@ -162,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/navit.c b/navit/navit.c
index 9500570ff..5eb0353db 100644
--- a/navit/navit.c
+++ b/navit/navit.c
@@ -2318,6 +2318,10 @@ navit_set_cursors(struct navit *this_)
/**
* @brief Calculates the position of the cursor on the screen.
*
+ * This method considers padding if supported by the graphics plugin. In that case, the inner rectangle
+ * (i.e. screen size minus padding) will be used to center the cursor and to determine cursor offset (as
+ * specified in `this_->radius`).
+ *
* @param this_ The navit object
* @param p Receives the screen coordinates for the cursor
* @param keep_orientation Whether to maintain the current map orientation. If false, the map will be
@@ -2331,6 +2335,7 @@ navit_get_cursor_pnt(struct navit *this_, struct point *p, int keep_orientation,
{
int width, height;
struct navit_vehicle *nv=this_->vehicle;
+ struct padding *padding = NULL;
float offset=this_->radius; // Cursor offset from the center of the screen (percent).
#if 0 /* Better improve track.c to get that issue resolved or make it configurable with being off the default, the jumping back to the center is a bit annoying */
@@ -2348,7 +2353,20 @@ navit_get_cursor_pnt(struct navit *this_, struct point *p, int keep_orientation,
}
#endif
+ if (this_->gra) {
+ padding = graphics_get_data(this_->gra, "padding");
+ } else
+ dbg(lvl_warning, "cannot get padding: this->gra is NULL\n");
+
transform_get_size(this_->trans, &width, &height);
+ dbg(lvl_debug, "width=%d height=%d\n", width, height);
+
+ if (padding) {
+ width -= (padding->left + padding->right);
+ height -= (padding->top + padding->bottom);
+ dbg(lvl_debug, "corrected for padding: width=%d height=%d\n", width, height);
+ }
+
if (this_->orientation == -1 || keep_orientation) {
p->x=50*width/100;
p->y=(50 + offset)*height/100;
@@ -2367,6 +2385,14 @@ navit_get_cursor_pnt(struct navit *this_, struct point *p, int keep_orientation,
if (dir)
*dir=this_->orientation;
}
+
+ if (padding) {
+ p->x += padding->left;
+ p->y += padding->top;
+ }
+
+ dbg(lvl_debug, "x=%d y=%d, offset=%f\n", p->x, p->y, offset);
+
return 1;
}
diff --git a/navit/osd.c b/navit/osd.c
index 38371f6cd..a2b88b0ad 100644
--- a/navit/osd.c
+++ b/navit/osd.c
@@ -171,15 +171,42 @@ osd_std_resize(struct osd_item *item)
* or relative height is set to 0% (int value is equal to ATTR_REL_RELSHIFT),
* object width (height) is not changed here, for button and image osds it means
* to derive values from the underlying image.
- * @param item
- * @param w Available screen width in pixels (the width that corresponds to
- * 100%)
- * @param h Available screen height in pixels (the height that corresponds to
- * 100%)
+ *
+ * This method considers padding if the graphics plugin supports it (i.e. its `get_data` method returns
+ * a valid pointer if `"padding"` is supplied as its arument): It will offset the origin of the item by
+ * the amount of padding in the left and top edges, and will reduce `w` and `h` by the total amount of
+ * padding in the respective dimension to obtain the equivalent of 100%.
+ *
+ * If the graphics driver does not support padding, none of these corrections take place (this is
+ * equivalent to 0 padding on all sides).
+ *
+ * @param item The item whose size and position are to be calculated
+ * @param w Available screen width in pixels
+ * @param h Available screen height in pixels
*/
void
osd_std_calculate_sizes(struct osd_item *item, int w, int h)
{
+ struct padding *padding = NULL;
+
+ if (item->gr) {
+ padding = graphics_get_data(item->gr, "padding");
+ if (padding) {
+ dbg(lvl_debug, "Got padding=%p for item=%p (item->gr=%p): left=%d top=%d right=%d bottom=%d\n",
+ padding, item, item->gr, padding->left, padding->top, padding->right, padding->bottom);
+ } else {
+ dbg(lvl_debug, "Got padding=%p for item=%p (item->gr=%p)\n",
+ padding, item, item->gr);
+ }
+ } else
+ dbg(lvl_warning, "cannot get padding for item=%p: item->gr is NULL\n", item);
+
+ /* reduce w and h by total padding in the respective dimension */
+ if (padding) {
+ w -= (padding->left + padding->right);
+ h -= (padding->top + padding->bottom);
+ }
+
if(item->rel_w!=ATTR_REL_RELSHIFT)
item->w=attr_rel2real(item->rel_w, w, 1);
if(item->w<0)
@@ -190,6 +217,12 @@ osd_std_calculate_sizes(struct osd_item *item, int w, int h)
item->h=0;
item->p.x=attr_rel2real(item->rel_x, w, 1);
item->p.y=attr_rel2real(item->rel_y, h, 1);
+
+ /* add left and top padding to item->p */
+ if (padding) {
+ item->p.x += padding->left;
+ item->p.y += padding->top;
+ }
}
/**
@@ -409,9 +442,30 @@ void
osd_set_std_graphic(struct navit *nav, struct osd_item *item, struct osd_priv *priv)
{
struct graphics *navit_gr;
+ int w, h;
+ struct padding *padding = NULL;
navit_gr = navit_get_graphics(nav);
- osd_std_calculate_sizes(item, navit_get_width(nav), navit_get_height(nav));
+ w = navit_get_width(nav);
+ h = navit_get_height(nav);
+
+ padding = graphics_get_data(navit_gr, "padding");
+
+ if (padding) {
+ dbg(lvl_debug, "Got padding=%p for item=%p: left=%d top=%d right=%d bottom=%d\n",
+ padding, item, padding->left, padding->top, padding->right, padding->bottom);
+ w -= (padding->left + padding->right);
+ h -= (padding->top + padding->bottom);
+ } else
+ dbg(lvl_debug, "Padding is NULL\n");
+
+ osd_std_calculate_sizes(item, w, h);
+
+ if (padding) {
+ item->p.x += padding->left;
+ item->p.y += padding->top;
+ }
+
item->gr = graphics_overlay_new(navit_gr, &item->p, item->w, item->h, 1);
item->graphic_bg = graphics_gc_new(item->gr);
diff --git a/navit/xpm/ic_notify.svg b/navit/xpm/ic_notify.svg
new file mode 100644
index 000000000..8bf846dae
--- /dev/null
+++ b/navit/xpm/ic_notify.svg
@@ -0,0 +1,261 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="22"
+ height="22"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.91 r13725"
+ version="1.0"
+ sodipodi:docname="ic_notify.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ inkscape:export-filename="/home/michael/src/navit/navit/android/res/drawable-hdpi/ic_notify.png"
+ inkscape:export-xdpi="147.27"
+ inkscape:export-ydpi="147.27">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3365">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.61904764;"
+ offset="0"
+ id="stop3367" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3369" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3320">
+ <stop
+ style="stop-color:#116cbf;stop-opacity:1;"
+ offset="0"
+ id="stop3322" />
+ <stop
+ id="stop3354"
+ offset="0.08"
+ style="stop-color:#116cbf;stop-opacity:1;" />
+ <stop
+ id="stop3352"
+ offset="0.4893617"
+ style="stop-color:#1a6cb6;stop-opacity:1;" />
+ <stop
+ style="stop-color:#329eff;stop-opacity:1;"
+ offset="1"
+ id="stop3324" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3308">
+ <stop
+ style="stop-color:#062643;stop-opacity:1;"
+ offset="0"
+ id="stop3310" />
+ <stop
+ style="stop-color:#0d5799;stop-opacity:1;"
+ offset="1"
+ id="stop3312" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3235">
+ <stop
+ style="stop-color:#c17d11;stop-opacity:1;"
+ offset="0"
+ id="stop3237" />
+ <stop
+ style="stop-color:#e9cb14;stop-opacity:1;"
+ offset="1"
+ id="stop3239" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3227">
+ <stop
+ style="stop-color:#76650c;stop-opacity:1;"
+ offset="0"
+ id="stop3229" />
+ <stop
+ style="stop-color:#76650c;stop-opacity:0;"
+ offset="1"
+ id="stop3231" />
+ </linearGradient>
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="15.556349 : 133.02972 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective10" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3308"
+ id="linearGradient3314"
+ x1="-7.7781754"
+ y1="4.2563133"
+ x2="43.133514"
+ y2="4.2563133"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="33.636364"
+ inkscape:cx="10.429299"
+ inkscape:cy="11"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer2"
+ showgrid="false"
+ inkscape:window-width="1280"
+ inkscape:window-height="948"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ showborder="true"
+ inkscape:window-maximized="1"
+ inkscape:object-paths="true"
+ inkscape:snap-bbox="false"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:object-nodes="true"
+ showguides="false" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Calque 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ style="display:inline" />
+ <g
+ inkscape:groupmode="layer"
+ id="layer2"
+ inkscape:label="lignes"
+ style="display:inline">
+ <path
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.79098374;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ d="m 3.1845705,2.9140622 c -1.0886716,0 -1.9765625,0.8878909 -1.9765625,1.9765625 l 0,5.6269533 C 2.9051239,9.2613772 5.0602154,8.3513287 7.0419924,8.0273435 l -2.625,-0.9511719 0.056641,-0.4589844 c 2.9757823,-0.3155887 5.8357996,0.1963758 8.5898436,1.375 l 0.216797,0.091797 -2.070313,4.9648438 -0.955078,-2.207031 c -2.0698525,1.111236 -3.5135663,3.176209 -4.333984,6.246094 l -0.089844,0.333984 -4.6230469,-3.347656 0,3.035156 c 0,1.088672 0.8878909,1.976563 1.9765625,1.976563 l 15.6289064,0 c 1.088671,0 1.978515,-0.887891 1.978515,-1.976563 l 0,-12.2187502 c 0,-1.0886716 -0.889844,-1.9765625 -1.978515,-1.9765625 l -15.6289064,0 z"
+ id="path4971"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ inkscape:groupmode="layer"
+ id="layer4"
+ inkscape:label="bulle"
+ style="display:none">
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient3314);fill-opacity:1;stroke:#1f3157;stroke-width:5.30526352;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path3305"
+ sodipodi:cx="17.67767"
+ sodipodi:cy="4.2563133"
+ sodipodi:rx="25.455845"
+ sodipodi:ry="25.455845"
+ d="m 43.133514,4.2563133 a 25.455845,25.455845 0 1 1 -50.9116894,0 25.455845,25.455845 0 1 1 50.9116894,0 z"
+ transform="matrix(1.3194444,0,0,1.3194444,18.394598,29.399489)" />
+ </g>
+ <g
+ inkscape:groupmode="layer"
+ id="layer3"
+ inkscape:label="rose des vents"
+ style="display:none">
+ <g
+ id="g3256"
+ transform="matrix(0.7071068,0.7071068,-0.7071068,0.7071068,36.903806,-19.093669)"
+ style="opacity:0.5">
+ <path
+ transform="translate(67.5,7)"
+ d="m -25.999999,61.185085 -5.673657,-27.511429 -27.511429,-5.673655 27.511429,-5.673657 5.673655,-27.5114293 5.673657,27.5114293 27.5114293,5.673655 -27.5114293,5.673657 z"
+ inkscape:randomized="0"
+ inkscape:rounded="0"
+ inkscape:flatsided="false"
+ sodipodi:arg2="2.3561945"
+ sodipodi:arg1="1.5707963"
+ sodipodi:r2="8.0237608"
+ sodipodi:r1="33.185085"
+ sodipodi:cy="28"
+ sodipodi:cx="-26"
+ sodipodi:sides="4"
+ id="path3258"
+ style="fill:#167bd9;fill-opacity:1;stroke:none"
+ sodipodi:type="star" />
+ <path
+ transform="translate(67.5,7)"
+ d="m -25.999999,61.185085 6.826343,-33.011429 -40.011429,-0.173655 33.011429,6.826343 0.173655,-40.0114293 -6.826343,33.0114293 40.0114293,0.173655 -33.0114293,-6.826343 z"
+ inkscape:randomized="0"
+ inkscape:rounded="0"
+ inkscape:flatsided="false"
+ sodipodi:arg2="0.025433549"
+ sodipodi:arg1="1.5707963"
+ sodipodi:r2="6.8285527"
+ sodipodi:r1="33.185085"
+ sodipodi:cy="28"
+ sodipodi:cx="-26"
+ sodipodi:sides="4"
+ id="path3260"
+ style="fill:#c3dff9;fill-opacity:1;stroke:none"
+ sodipodi:type="star" />
+ </g>
+ <g
+ id="g3252">
+ <path
+ transform="translate(67.5,7)"
+ d="m -25.999999,61.185085 -5.673657,-27.511429 -27.511429,-5.673655 27.511429,-5.673657 5.673655,-27.5114293 5.673657,27.5114293 27.5114293,5.673655 -27.5114293,5.673657 z"
+ inkscape:randomized="0"
+ inkscape:rounded="0"
+ inkscape:flatsided="false"
+ sodipodi:arg2="2.3561945"
+ sodipodi:arg1="1.5707963"
+ sodipodi:r2="8.0237608"
+ sodipodi:r1="33.185085"
+ sodipodi:cy="28"
+ sodipodi:cx="-26"
+ sodipodi:sides="4"
+ id="path3248"
+ style="fill:#167bd9;fill-opacity:1;stroke:none"
+ sodipodi:type="star" />
+ <path
+ transform="translate(67.5,7)"
+ d="m -25.999999,61.185085 6.826343,-33.011429 -40.011429,-0.173655 33.011429,6.826343 0.173655,-40.0114293 -6.826343,33.0114293 40.0114293,0.173655 -33.0114293,-6.826343 z"
+ inkscape:randomized="0"
+ inkscape:rounded="0"
+ inkscape:flatsided="false"
+ sodipodi:arg2="0.025433549"
+ sodipodi:arg1="1.5707963"
+ sodipodi:r2="6.8285527"
+ sodipodi:r1="33.185085"
+ sodipodi:cy="28"
+ sodipodi:cx="-26"
+ sodipodi:sides="4"
+ id="path3250"
+ style="fill:#c3dff9;fill-opacity:1;stroke:none"
+ sodipodi:type="star" />
+ </g>
+ </g>
+ <g
+ inkscape:groupmode="layer"
+ id="layer6"
+ inkscape:label="ondes"
+ style="display:inline" />
+ <g
+ inkscape:groupmode="layer"
+ id="layer5"
+ inkscape:label="flèche"
+ style="display:inline" />
+</svg>