summaryrefslogtreecommitdiff
path: root/navit/android/src/org/navitproject/navit/NavitGraphics.java
diff options
context:
space:
mode:
Diffstat (limited to 'navit/android/src/org/navitproject/navit/NavitGraphics.java')
-rw-r--r--navit/android/src/org/navitproject/navit/NavitGraphics.java189
1 files changed, 181 insertions, 8 deletions
diff --git a/navit/android/src/org/navitproject/navit/NavitGraphics.java b/navit/android/src/org/navitproject/navit/NavitGraphics.java
index 728b49878..a41ab52be 100644
--- a/navit/android/src/org/navitproject/navit/NavitGraphics.java
+++ b/navit/android/src/org/navitproject/navit/NavitGraphics.java
@@ -25,23 +25,31 @@ 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;
import android.graphics.PointF;
import android.graphics.Rect;
+import android.os.Build;
import android.os.Handler;
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;
@@ -55,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;
@@ -68,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)
{
@@ -197,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()
@@ -352,7 +369,7 @@ public class NavitGraphics
{
float x = a.x - b.x;
float y = a.y - b.y;
- return FloatMath.sqrt(x * x + y * y);
+ return (float)Math.sqrt(x * x + y * y);
}
private PointF getFloatValue(Object instance, Object argument)
@@ -685,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)
{
@@ -704,7 +730,22 @@ public class NavitGraphics
}
relativelayout.addView(view);
+ /* The navigational and status bar tinting code is meaningful only on API19+ */
+ if(Build.VERSION.SDK_INT >= 19)
+ {
+ frameLayout = new FrameLayout(activity);
+ frameLayout.addView(relativelayout);
+ navigationTintView = new SystemBarTintView(activity);
+ statusTintView = new SystemBarTintView(activity);
+ frameLayout.addView(navigationTintView);
+ frameLayout.addView(statusTintView);
+ activity.setContentView(frameLayout);
+ }
+ else
+ {
activity.setContentView(relativelayout);
+ }
+
view.requestFocus();
}
else
@@ -781,6 +822,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);
@@ -789,13 +831,144 @@ 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 Adjust views used to tint navigation and status bars.
+ *
+ * This method is called from handleResize.
+ *
+ * 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.
+ *
+ */
+ private void adjustSystemBarsTintingViews() {
+
+ /* frameLayout is only created on platforms supporting navigation and status bar tinting */
+ if (frameLayout == null)
+ return;
+
+ if (!(activity instanceof Navit)) {
+ Log.e("NavitGraphics", "Main Activity is not a Navit instance, cannot update padding");
+ return;
+ }
+
+ 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)
+ */
+ final 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);
+ }
+
+ /**
+ * @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.
+ *
+ */
+ 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));
+
+ adjustSystemBarsTintingViews();
+
+ 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.
+ *
+ * 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.
+ *
+ * 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)
+ 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;
}
+ public void setPaddingChangedCallback(int id)
+ {
+ PaddingChangedCallbackID = id;
+ }
public void setButtonCallback(int id)
{
ButtonCallbackID = id;
@@ -921,7 +1094,7 @@ public class NavitGraphics
//Log.e("NavitGraphics","draw_image");
// float fx = x;
// float fy = y;
- draw_canvas.drawBitmap(bitmap, x, y, paint);
+ draw_canvas.drawBitmap(bitmap, x, y, null);
}
/* takes an image and draws it on the screen as a prerendered maptile