diff options
author | Pierre GRANDIN <pgrandin@users.noreply.github.com> | 2016-02-22 15:13:56 -0800 |
---|---|---|
committer | Pierre GRANDIN <pgrandin@users.noreply.github.com> | 2016-02-22 15:13:56 -0800 |
commit | 2c77286a6c08af6f77866671af31d3f99719d22a (patch) | |
tree | 4b505b22819fc04898c04376defc896a3d8aa251 | |
parent | 7eaf614763af6a9a4b1c9d3753e35c5bdbcfa8ee (diff) | |
parent | 0c95f9992ce02fe6c4da86005f69ba433842aa5f (diff) | |
download | navit-2c77286a6c08af6f77866671af31d3f99719d22a.tar.gz |
Merge pull request #73 from mvglasow/android-laf-rebasedR6603
Add:port_android:Look and feel update
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 Binary files differnew file mode 100644 index 000000000..7516b2fbd --- /dev/null +++ b/navit/android/res/drawable-hdpi/ic_notify.png diff --git a/navit/android/res/drawable-hdpi/icon.png b/navit/android/res/drawable-hdpi/icon.png Binary files differindex 3b01b5c3d..311c57b59 100644 --- a/navit/android/res/drawable-hdpi/icon.png +++ b/navit/android/res/drawable-hdpi/icon.png diff --git a/navit/android/res/drawable-ldpi/ic_notify.png b/navit/android/res/drawable-ldpi/ic_notify.png Binary files differnew file mode 100644 index 000000000..010d55fb3 --- /dev/null +++ b/navit/android/res/drawable-ldpi/ic_notify.png diff --git a/navit/android/res/drawable-ldpi/icon.png b/navit/android/res/drawable-ldpi/icon.png Binary files differindex b72d1e40b..da2553687 100644 --- a/navit/android/res/drawable-ldpi/icon.png +++ b/navit/android/res/drawable-ldpi/icon.png diff --git a/navit/android/res/drawable-mdpi/ic_notify.png b/navit/android/res/drawable-mdpi/ic_notify.png Binary files differnew file mode 100644 index 000000000..d6de8d53f --- /dev/null +++ b/navit/android/res/drawable-mdpi/ic_notify.png diff --git a/navit/android/res/drawable-mdpi/icon.png b/navit/android/res/drawable-mdpi/icon.png Binary files differindex 33bbab7f6..f8f68e8bc 100644 --- a/navit/android/res/drawable-mdpi/icon.png +++ b/navit/android/res/drawable-mdpi/icon.png diff --git a/navit/android/res/drawable-xhdpi/ic_notify.png b/navit/android/res/drawable-xhdpi/ic_notify.png Binary files differnew file mode 100644 index 000000000..72371c974 --- /dev/null +++ b/navit/android/res/drawable-xhdpi/ic_notify.png diff --git a/navit/android/res/drawable-xhdpi/icon.png b/navit/android/res/drawable-xhdpi/icon.png Binary files differnew file mode 100644 index 000000000..649fb32d4 --- /dev/null +++ b/navit/android/res/drawable-xhdpi/icon.png diff --git a/navit/android/res/drawable-xxhdpi/ic_notify.png b/navit/android/res/drawable-xxhdpi/ic_notify.png Binary files differnew file mode 100644 index 000000000..d47a41154 --- /dev/null +++ b/navit/android/res/drawable-xxhdpi/ic_notify.png diff --git a/navit/android/res/drawable-xxhdpi/icon.png b/navit/android/res/drawable-xxhdpi/icon.png Binary files differnew file mode 100644 index 000000000..398945c23 --- /dev/null +++ b/navit/android/res/drawable-xxhdpi/icon.png 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> |