diff --git a/code/boot.js b/code/boot.js
index c66dcadf..220e1531 100644
--- a/code/boot.js
+++ b/code/boot.js
@@ -566,8 +566,8 @@ function boot() {
window.iitcLoaded = true;
window.runHooks('iitcLoaded');
- if (typeof android !== 'undefined' && android && android.removeSplashScreen) {
- android.removeSplashScreen();
+ if (typeof android !== 'undefined' && android && android.bootFinished) {
+ android.bootFinished();
}
}
diff --git a/external/taphold.js b/external/taphold.js
index cf16e280..e889b126 100644
--- a/external/taphold.js
+++ b/external/taphold.js
@@ -106,12 +106,16 @@
$(this).bind((touchSupported ? "touchstart" : "mousedown"), data, startHandler)
.bind((touchSupported ? "touchend" : "mouseup"), stopHandler)
.bind((touchSupported ? "touchmove" : "mouseleave"), leaveHandler);
+ if(touchSupported)
+ $(this).bind("touchcancel", leaveHandler);
},
teardown: function(namespaces)
{
$(this).unbind((touchSupported ? "touchstart" : "mousedown"), startHandler)
.unbind((touchSupported ? "touchend" : "mouseup"), stopHandler)
.unbind((touchSupported ? "touchmove" : "mouseleave"), leaveHandler);
+ if(touchSupported)
+ $(this).unbind("touchcancel", leaveHandler);
}
};
})(jQuery);
diff --git a/mobile/AndroidManifest.xml b/mobile/AndroidManifest.xml
index fda15a23..29831632 100644
--- a/mobile/AndroidManifest.xml
+++ b/mobile/AndroidManifest.xml
@@ -1,8 +1,8 @@
+ android:versionCode="51"
+ android:versionName="0.7.1">
+ android:theme="@style/AppTheme">
-
\ No newline at end of file
+
diff --git a/mobile/libs/android-support-v4.jar b/mobile/libs/android-support-v4.jar
index 428bdbc0..cf12d283 100644
Binary files a/mobile/libs/android-support-v4.jar and b/mobile/libs/android-support-v4.jar differ
diff --git a/mobile/res/drawable-hdpi/collections_view_as_list.png b/mobile/res/drawable-hdpi/collections_view_as_list.png
new file mode 100644
index 00000000..e45ea1fd
Binary files /dev/null and b/mobile/res/drawable-hdpi/collections_view_as_list.png differ
diff --git a/mobile/res/drawable-hdpi/collections_view_as_list_compact.png b/mobile/res/drawable-hdpi/collections_view_as_list_compact.png
new file mode 100644
index 00000000..4a92e2c0
Binary files /dev/null and b/mobile/res/drawable-hdpi/collections_view_as_list_compact.png differ
diff --git a/mobile/res/drawable-hdpi/drawer_shadow.9.png b/mobile/res/drawable-hdpi/drawer_shadow.9.png
new file mode 100644
index 00000000..224cc4ff
Binary files /dev/null and b/mobile/res/drawable-hdpi/drawer_shadow.9.png differ
diff --git a/mobile/res/drawable-hdpi/ic_debug.png b/mobile/res/drawable-hdpi/ic_debug.png
new file mode 100644
index 00000000..8ed186b4
Binary files /dev/null and b/mobile/res/drawable-hdpi/ic_debug.png differ
diff --git a/mobile/res/drawable-hdpi/ic_drawer.png b/mobile/res/drawable-hdpi/ic_drawer.png
new file mode 100644
index 00000000..ff7b1def
Binary files /dev/null and b/mobile/res/drawable-hdpi/ic_drawer.png differ
diff --git a/mobile/res/drawable-hdpi/social_cc_bcc.png b/mobile/res/drawable-hdpi/social_cc_bcc.png
new file mode 100644
index 00000000..8c4f8b31
Binary files /dev/null and b/mobile/res/drawable-hdpi/social_cc_bcc.png differ
diff --git a/mobile/res/drawable-mdpi/collections_view_as_list.png b/mobile/res/drawable-mdpi/collections_view_as_list.png
new file mode 100644
index 00000000..9c748b0b
Binary files /dev/null and b/mobile/res/drawable-mdpi/collections_view_as_list.png differ
diff --git a/mobile/res/drawable-mdpi/collections_view_as_list_compact.png b/mobile/res/drawable-mdpi/collections_view_as_list_compact.png
new file mode 100644
index 00000000..a53ef7c0
Binary files /dev/null and b/mobile/res/drawable-mdpi/collections_view_as_list_compact.png differ
diff --git a/mobile/res/drawable-mdpi/drawer_shadow.9.png b/mobile/res/drawable-mdpi/drawer_shadow.9.png
new file mode 100644
index 00000000..3797f99c
Binary files /dev/null and b/mobile/res/drawable-mdpi/drawer_shadow.9.png differ
diff --git a/mobile/res/drawable-mdpi/ic_debug.png b/mobile/res/drawable-mdpi/ic_debug.png
new file mode 100644
index 00000000..ac20ea13
Binary files /dev/null and b/mobile/res/drawable-mdpi/ic_debug.png differ
diff --git a/mobile/res/drawable-mdpi/ic_drawer.png b/mobile/res/drawable-mdpi/ic_drawer.png
new file mode 100644
index 00000000..fb681ba2
Binary files /dev/null and b/mobile/res/drawable-mdpi/ic_drawer.png differ
diff --git a/mobile/res/drawable-mdpi/social_cc_bcc.png b/mobile/res/drawable-mdpi/social_cc_bcc.png
new file mode 100644
index 00000000..9ec127ed
Binary files /dev/null and b/mobile/res/drawable-mdpi/social_cc_bcc.png differ
diff --git a/mobile/res/drawable-xhdpi/collections_view_as_list.png b/mobile/res/drawable-xhdpi/collections_view_as_list.png
new file mode 100644
index 00000000..95708234
Binary files /dev/null and b/mobile/res/drawable-xhdpi/collections_view_as_list.png differ
diff --git a/mobile/res/drawable-xhdpi/collections_view_as_list_compact.png b/mobile/res/drawable-xhdpi/collections_view_as_list_compact.png
new file mode 100644
index 00000000..c8f46e41
Binary files /dev/null and b/mobile/res/drawable-xhdpi/collections_view_as_list_compact.png differ
diff --git a/mobile/res/drawable-xhdpi/drawer_shadow.9.png b/mobile/res/drawable-xhdpi/drawer_shadow.9.png
new file mode 100644
index 00000000..fa3d853e
Binary files /dev/null and b/mobile/res/drawable-xhdpi/drawer_shadow.9.png differ
diff --git a/mobile/res/drawable-xhdpi/ic_debug.png b/mobile/res/drawable-xhdpi/ic_debug.png
new file mode 100644
index 00000000..aeb96b06
Binary files /dev/null and b/mobile/res/drawable-xhdpi/ic_debug.png differ
diff --git a/mobile/res/drawable-xhdpi/ic_drawer.png b/mobile/res/drawable-xhdpi/ic_drawer.png
new file mode 100644
index 00000000..b9bc3d70
Binary files /dev/null and b/mobile/res/drawable-xhdpi/ic_drawer.png differ
diff --git a/mobile/res/drawable-xhdpi/social_cc_bcc.png b/mobile/res/drawable-xhdpi/social_cc_bcc.png
new file mode 100644
index 00000000..4153807e
Binary files /dev/null and b/mobile/res/drawable-xhdpi/social_cc_bcc.png differ
diff --git a/mobile/res/layout/activity_main.xml b/mobile/res/layout/activity_main.xml
index 01392b66..d4a8ccbc 100644
--- a/mobile/res/layout/activity_main.xml
+++ b/mobile/res/layout/activity_main.xml
@@ -1,18 +1,45 @@
-
+
-
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mobile/res/layout/list_item_narrow.xml b/mobile/res/layout/list_item_narrow.xml
new file mode 100644
index 00000000..64771748
--- /dev/null
+++ b/mobile/res/layout/list_item_narrow.xml
@@ -0,0 +1,10 @@
+
+
diff --git a/mobile/res/layout/list_item_selectable.xml b/mobile/res/layout/list_item_selectable.xml
new file mode 100644
index 00000000..a82df550
--- /dev/null
+++ b/mobile/res/layout/list_item_selectable.xml
@@ -0,0 +1,11 @@
+
+
diff --git a/mobile/res/layout/map_options_header.xml b/mobile/res/layout/map_options_header.xml
new file mode 100644
index 00000000..6efdd616
--- /dev/null
+++ b/mobile/res/layout/map_options_header.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mobile/res/menu/main.xml b/mobile/res/menu/main.xml
index 479e4446..941cd9bc 100644
--- a/mobile/res/menu/main.xml
+++ b/mobile/res/menu/main.xml
@@ -6,64 +6,24 @@
android:showAsAction="ifRoom|collapseActionView"
android:actionViewClass="android.widget.SearchView" />
-
-
- -
-
+ android:title="@string/locate">
-
-
- -
+ android:title="@string/layer_chooser">
-
-
- -
-
- -
-
-
+ -
+
\ No newline at end of file
diff --git a/mobile/res/values/strings.xml b/mobile/res/values/strings.xml
index 2e067082..8699ebec 100644
--- a/mobile/res/values/strings.xml
+++ b/mobile/res/values/strings.xml
@@ -7,6 +7,8 @@
Share using…
Copy to clipboard
Settings
+ Show navigation menu
+ Hide navigation menu
Reload IITC
Print Version
Toggle fullscreen
@@ -53,7 +55,17 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.]]>
-
+
+
+ • Navigation: swipe from the left edge of your screen (or click the app icon) to evoke the Navigation Drawer.
+ Click the app icon again to return to the map.
+ • Layers/Highlights: swipe from the right edge of your screen (or click the layer-chooser icon in the ActionBar)
+ to evoke the Layer Drawer]]>
+
+
+
+
+
UI
Misc
IITC Plugins
@@ -63,7 +75,7 @@
Show zoom control
Shows +/- buttons even on multitouch capable devices.
Hide Action Bar in fullscreen mode
- Nice for screenshots. Note: IITCM cannot be controlled without Action Bar.
+ Nice for screenshots. Note: IITCm can still be controlled via the Navigation Drawers
Force desktop mode
Nice for tablets, looks awful on smartphones
Force https
@@ -81,13 +93,6 @@
IITC source
Load IITC main script from url or use local script. Currently used source:
- Chat
- Full
- Compact
- Public
- Faction
- Info
- Debug
Clear Cookies
Search
Choose account to login
@@ -100,8 +105,8 @@
Share
Browser
- Base Layers
- Overlay Layers
- Deselect/Select all
+ Highlighter
+ Base Layer
+ Overlay Layers
\ No newline at end of file
diff --git a/mobile/res/values/styles.xml b/mobile/res/values/styles.xml
index 7843ae20..d8351bc3 100644
--- a/mobile/res/values/styles.xml
+++ b/mobile/res/values/styles.xml
@@ -17,4 +17,6 @@
+ #99111111
+
\ No newline at end of file
diff --git a/mobile/res/xml/preferences.xml b/mobile/res/xml/preferences.xml
index 49c89c40..7fc502d4 100644
--- a/mobile/res/xml/preferences.xml
+++ b/mobile/res/xml/preferences.xml
@@ -26,7 +26,7 @@
android:key="pref_fullscreen_actionbar"
android:title="@string/pref_fullscreen_actionbar"
android:summary="@string/pref_fullscreen_actionbar_sum"
- android:defaultValue="false" />
+ android:defaultValue="true" />
{
- public HighlighterAdapter() {
- super(mIitc, android.R.layout.simple_list_item_1);
- clear();
- }
-
- @Override
- public void add(String object) {
- super.remove(object); // to avoid duplicates
- super.add(object);
- }
-
- @Override
- public void clear() {
- super.clear();
- add("No Highlights");// Probably must be the same as window._no_highlighter
- }
- }
-
- private IITC_Mobile mIitc;
- private ActionBar mActionBar;
- private SharedPreferences mPrefs;
- private HighlighterAdapter mHighlighters;
-
- private String mActiveHighlighter = null;
- private boolean mDesktopMode = false;
- private boolean mFullscreen = false;
- private boolean mHideInFullscreen = false;
- private int mPane = android.R.id.home;
-
- public IITC_ActionBarHelper(IITC_Mobile activity, ActionBar bar) {
- mIitc = activity;
- mActionBar = bar;
- mPrefs = PreferenceManager.getDefaultSharedPreferences(activity);
- mHighlighters = new HighlighterAdapter();
-
- mActionBar.setDisplayShowHomeEnabled(true); // show icon
- mActionBar.setListNavigationCallbacks(mHighlighters, this);
-
- onPrefChanged(); // also calls updateActionBar()
- }
-
- private void updateActionBar() {
- boolean showHighlighter = true;
-
- if (mDesktopMode) {
- mActionBar.setDisplayHomeAsUpEnabled(false); // Hide "up" indicator
- mActionBar.setHomeButtonEnabled(false); // Make icon unclickable
- mActionBar.setTitle(mIitc.getString(R.string.app_name));
- } else {
- if (mPane != android.R.id.home) {
- mActionBar.setDisplayHomeAsUpEnabled(true); // Show "up" indicator
- mActionBar.setHomeButtonEnabled(true);// Make icon clickable
- showHighlighter = false;
- }
- else {
- mActionBar.setDisplayHomeAsUpEnabled(false); // Hide "up" indicator
- mActionBar.setHomeButtonEnabled(false); // Make icon unclickable
- }
- mActionBar.setTitle(IITC_Mobile.PANE_TITLES.get(mPane, mIitc.getString(R.string.app_name)));
- }
-
- if (mHighlighters.getCount() < 2) // there should always be "No Highlights"
- showHighlighter = false;
-
- if (showHighlighter) {
- mActionBar.setDisplayShowTitleEnabled(false); // Hide title
- mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
- setActiveHighlighter(mActiveHighlighter);
- } else {
- mActionBar.setDisplayShowTitleEnabled(true); // Show title
- mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
- }
- if (mFullscreen && mHideInFullscreen)
- mActionBar.hide();
- else
- mActionBar.show();
- }
-
- public void addPortalHighlighter(String name) {
- mHighlighters.add(name);
-
- if (name.equals(mActiveHighlighter))
- setActiveHighlighter(name);
-
- updateActionBar();
- }
-
- public boolean hideInFullscreen() {
- return mHideInFullscreen;
- }
-
- @Override
- public boolean onNavigationItemSelected(int position, long itemId) {
- String name = mHighlighters.getItem(position);
- mIitc.getWebView().loadUrl("javascript: window.changePortalHighlights('" + name + "')");
- return true;
- }
-
- public void onPrefChanged() {
- mDesktopMode = mPrefs.getBoolean("pref_force_desktop", false);
- mHideInFullscreen = mPrefs.getBoolean("pref_fullscreen_actionbar", false);
- updateActionBar();
- }
-
- public void reset() {
- mHighlighters.clear();
- mPane = android.R.id.home;
- updateActionBar();
- }
-
- public void setActiveHighlighter(String name) {
- mActiveHighlighter = name;
-
- if (mActionBar.getNavigationMode() == ActionBar.NAVIGATION_MODE_LIST) {
- int position = mHighlighters.getPosition(mActiveHighlighter);
- if (position >= 0 && position < mActionBar.getNavigationItemCount())
- mActionBar.setSelectedNavigationItem(position);
- }
- }
-
- public void setFullscreen(boolean fullscreen) {
- mFullscreen = fullscreen;
- if (mFullscreen && mHideInFullscreen) {
- // show a toast with instructions to exit the fullscreen mode again
- Toast.makeText(mIitc, "Press back button to exit fullscreen", Toast.LENGTH_SHORT).show();
- }
-
- updateActionBar();
- }
-
- public void switchTo(int button) {
- mPane = button;
- updateActionBar();
- }
-}
diff --git a/mobile/src/com/cradle/iitc_mobile/IITC_JSInterface.java b/mobile/src/com/cradle/iitc_mobile/IITC_JSInterface.java
index cd3cbf94..c26c8e21 100644
--- a/mobile/src/com/cradle/iitc_mobile/IITC_JSInterface.java
+++ b/mobile/src/com/cradle/iitc_mobile/IITC_JSInterface.java
@@ -1,66 +1,48 @@
package com.cradle.iitc_mobile;
-import android.app.Activity;
-import android.app.AlertDialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
-import android.content.DialogInterface.OnMultiChoiceClickListener;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.util.Log;
-import android.view.View;
import android.webkit.JavascriptInterface;
-import android.widget.AdapterView;
-import android.widget.ListView;
import android.widget.Toast;
+import com.cradle.iitc_mobile.IITC_NavigationHelper.Pane;
import com.cradle.iitc_mobile.share.ShareActivity;
-import org.json.JSONArray;
-import org.json.JSONException;
-
-import java.util.HashMap;
+import java.util.Locale;
// provide communication between IITC script and android app
public class IITC_JSInterface {
-
// context of main activity
- private final Context mContext;
- private final HashMap mLayerIds;
- private boolean[] mOverlayIsActive;
- private int mActiveBaseLayer;
- private String[] mOverlayLayers, mBaseLayers;
- private int mNumBaseLayers;
- private int mNumOverlayLayers;
+ private IITC_Mobile mIitc;
- IITC_JSInterface(Context c) {
- mLayerIds = new HashMap();
- mContext = c;
+ IITC_JSInterface(IITC_Mobile iitc) {
+ mIitc = iitc;
}
// open dialog to send geo intent for navigation apps like gmaps or waze etc...
@JavascriptInterface
public void intentPosLink(double lat, double lng, int zoom, String title, boolean isPortal) {
- Intent intent = new Intent(mContext, ShareActivity.class);
+ Intent intent = new Intent(mIitc, ShareActivity.class);
intent.putExtra("lat", lat);
intent.putExtra("lng", lng);
intent.putExtra("zoom", zoom);
intent.putExtra("title", title);
intent.putExtra("isPortal", isPortal);
- mContext.startActivity(intent);
+ mIitc.startActivity(intent);
}
// share a string to the IITC share activity. only uses the share tab.
@JavascriptInterface
public void shareString(String str) {
- Intent intent = new Intent(mContext, ShareActivity.class);
+ Intent intent = new Intent(mIitc, ShareActivity.class);
intent.putExtra("shareString", str);
intent.putExtra("onlyShare", true);
- mContext.startActivity(intent);
+ mIitc.startActivity(intent);
}
// disable javascript injection while spinner is enabled
@@ -68,26 +50,25 @@ public class IITC_JSInterface {
@JavascriptInterface
public void spinnerEnabled(boolean en) {
Log.d("iitcm", "disableJS? " + en);
- ((IITC_Mobile) mContext).getWebView().disableJS(en);
+ mIitc.getWebView().disableJS(en);
}
// copy link to specific portal to android clipboard
@JavascriptInterface
public void copy(String s) {
- ClipboardManager clipboard = (ClipboardManager) mContext
+ ClipboardManager clipboard = (ClipboardManager) mIitc
.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("Copied Text ", s);
clipboard.setPrimaryClip(clip);
- Toast.makeText(mContext, "copied to clipboard", Toast.LENGTH_SHORT)
- .show();
+ Toast.makeText(mIitc, "copied to clipboard", Toast.LENGTH_SHORT).show();
}
@JavascriptInterface
public int getVersionCode() {
int versionCode = 0;
try {
- PackageInfo pInfo = mContext.getPackageManager()
- .getPackageInfo(mContext.getPackageName(), 0);
+ PackageInfo pInfo = mIitc.getPackageManager()
+ .getPackageInfo(mIitc.getPackageName(), 0);
versionCode = pInfo.versionCode;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
@@ -97,250 +78,72 @@ public class IITC_JSInterface {
@JavascriptInterface
public void switchToPane(final String id) {
- final IITC_Mobile iitcm = (IITC_Mobile) mContext;
-
- iitcm.runOnUiThread(new Runnable() {
+ mIitc.runOnUiThread(new Runnable() {
@Override
public void run() {
- IITC_ActionBarHelper actionbar = iitcm.getActionBarHelper();
- Integer button = IITC_Mobile.PANES.get(id);
+ Pane pane;
+ try {
+ pane = Pane.valueOf(id.toUpperCase(Locale.getDefault()));
+ } catch (IllegalArgumentException e) {
+ pane = Pane.MAP;
+ }
- if (button == null)
- button = android.R.id.home;
-
- actionbar.switchTo(button);
- iitcm.backStackUpdate(button);
+ mIitc.setCurrentPane(pane);
}
});
}
- @JavascriptInterface
- public void dialogOpened(String id, boolean open) {
- ((IITC_Mobile) mContext).dialogOpened(id, open);
- }
-
@JavascriptInterface
public void dialogFocused(String id) {
- ((IITC_Mobile) mContext).setFocusedDialog(id);
+ mIitc.setFocusedDialog(id);
}
@JavascriptInterface
- public void removeSplashScreen() {
- Log.d("iitcm", "removing splash screen");
- final IITC_Mobile iitc = ((IITC_Mobile) mContext);
+ public void dialogOpened(String id, boolean open) {
+ mIitc.dialogOpened(id, open);
+ }
- iitc.runOnUiThread(new Runnable() {
+ @JavascriptInterface
+ public void bootFinished() {
+ Log.d("iitcm", "...boot finished");
+
+ mIitc.runOnUiThread(new Runnable() {
@Override
public void run() {
- iitc.findViewById(R.id.iitc_webview).setVisibility(View.VISIBLE);
- iitc.findViewById(R.id.imageLoading).setVisibility(View.GONE);
+ mIitc.setLoadingState(false);
+
+ mIitc.getMapSettings().onBootFinished();
}
});
}
// get layers and list them in a dialog
@JavascriptInterface
- public void setLayers(String base_layer, String overlay_layer) {
-
- /*
- * the layer strings have a form like:
- * [{"layerId":27,"name":"MapQuest OSM","active":true},
- * {"layerId":28,"name":"Default Ingress Map","active":false}]
- * Put it in a JSONArray and parse it
- */
- JSONArray base_layersJSON = null;
- JSONArray overlay_layersJSON = null;
- try {
- base_layersJSON = new JSONArray(base_layer);
- overlay_layersJSON = new JSONArray(overlay_layer);
- } catch (JSONException e) {
- e.printStackTrace();
- }
-
- // get length and initialize arrays
- mNumBaseLayers = base_layersJSON.length();
- mNumOverlayLayers = overlay_layersJSON.length();
- mOverlayIsActive = new boolean[mNumOverlayLayers];
- mOverlayLayers = new String[mNumOverlayLayers];
- mBaseLayers = new String[mNumBaseLayers];
- mLayerIds.clear();
-
- // --------------- base layers ------------------------
- for (int i = 0; i < mNumBaseLayers; ++i) {
- try {
- String layer = base_layersJSON.getString(i);
- layer = layer.replace("{", "");
- layer = layer.replace("}", "");
- /*
- * we now should have a string like
- * ["layerId":27,"name":"MapQuest OSM","active":true]
- * split it on ,
- */
- String[] layers = layer.split(",");
- /*
- * we should have 3 strings in a form like
- * "name":"MapQuest OSM"
- * get the values and get rid of the quotation marks
- */
- String id = "";
- String name = "";
- boolean isActive = false;
- for (String b_layer : layers) {
- String[] values = b_layer.split(":");
- if (values[0].contains("active")) isActive = values[1].equals("true");
- if (values[0].contains("layerId")) id = values[1];
- if (values[0].contains("name")) name = values[1];
- }
- name = name.replace("\"", "");
- mLayerIds.put(name, id);
- this.mBaseLayers[i] = name;
- if (isActive) mActiveBaseLayer = i;
- } catch (JSONException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ public void setLayers(final String base_layer, final String overlay_layer) {
+ mIitc.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mIitc.getMapSettings().setLayers(base_layer, overlay_layer);
}
- }
-
- // --------------- overlay layers ------------------------
- for (int i = 0; i < mNumOverlayLayers; ++i) {
- try {
- String layer = overlay_layersJSON.getString(i);
- layer = layer.replace("{", "");
- layer = layer.replace("}", "");
- String[] layers = layer.split(",");
- String id = "";
- String name = "";
- boolean isActive = false;
- for (String o_layer : layers) {
- String[] values = o_layer.split(":");
- if (values[0].contains("active")) isActive = values[1].equals("true");
- if (values[0].contains("layerId")) id = values[1];
- if (values[0].contains("name")) name = values[1];
- }
- name = name.replace("\"", "");
- mLayerIds.put(name, id);
- this.mOverlayLayers[i] = name;
- this.mOverlayIsActive[i] = isActive;
- } catch (JSONException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- // show overlay layers by default
- showMultiSelection();
+ });
}
@JavascriptInterface
public void addPortalHighlighter(final String name) {
- final IITC_Mobile iitc = ((IITC_Mobile) mContext);
- iitc.runOnUiThread(new Runnable() {
+ mIitc.runOnUiThread(new Runnable() {
@Override
public void run() {
- iitc.getActionBarHelper().addPortalHighlighter(name);
+ mIitc.getMapSettings().addPortalHighlighter(name);
}
});
}
@JavascriptInterface
public void setActiveHighlighter(final String name) {
- final IITC_Mobile iitc = ((IITC_Mobile) mContext);
- iitc.runOnUiThread(new Runnable() {
+ mIitc.runOnUiThread(new Runnable() {
@Override
public void run() {
- iitc.getActionBarHelper().setActiveHighlighter(name);
- }
- });
- }
-
- // show all overlay layers in a multi selection list dialog
- private void showMultiSelection() {
- // build the layer chooser dialog
- AlertDialog.Builder d_m = new AlertDialog.Builder(mContext);
- OnMultiChoiceClickListener m_listener = new OnMultiChoiceClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which, boolean isChecked) {
- // activate clicked layer
- showLayer(mLayerIds.get(mOverlayLayers[which]), isChecked);
- }
- };
- d_m.setMultiChoiceItems(mOverlayLayers, mOverlayIsActive, m_listener);
- // switch to base layers
- d_m.setPositiveButton(R.string.base_layers, new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- showSingleSelection();
- dialog.dismiss();
- }
- });
- d_m.setNegativeButton(R.string.close, new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- }
- });
- d_m.setTitle(R.string.overlay_layers);
- final AlertDialog dialog = d_m.create();
- final ListView list = dialog.getListView();
- list.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
- boolean disable = false;
-
- @Override
- public boolean onItemLongClick(AdapterView> adapterView, View view, int i, long l) {
- int j = 0;
- for (String layer : mOverlayLayers) {
- if (!mOverlayLayers[j].contains("DEBUG")) {
- // uncheck the item + set the boolean in the isActive array
- mOverlayIsActive[j] = disable;
- list.setItemChecked(j, disable);
- showLayer(mLayerIds.get(layer), disable);
- }
- ++j;
- }
- disable = !disable;
- return true;
- }
- });
- dialog.show();
- }
-
- // show all base layers in a single selection list dialog
- private void showSingleSelection() {
- OnClickListener s_listener = new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // activate clicked layer
- showLayer(mLayerIds.get(mBaseLayers[which]), true);
- mActiveBaseLayer = which;
- }
- };
- AlertDialog.Builder d_s = new AlertDialog.Builder(mContext);
- d_s.setSingleChoiceItems(mBaseLayers, mActiveBaseLayer, s_listener);
- // switch to overlay layers
- d_s.setPositiveButton(R.string.overlay_layers, new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- showMultiSelection();
- dialog.dismiss();
- }
- });
- d_s.setNegativeButton(R.string.close, new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- }
- });
- d_s.setTitle(R.string.base_layers);
- final AlertDialog dialog = d_s.create();
- dialog.show();
- }
-
- private void showLayer(final String id, final boolean enable) {
- ((Activity) mContext).runOnUiThread(new Runnable() {
- @Override
- public void run() {
- ((IITC_Mobile) mContext).getWebView().loadUrl("javascript: " +
- "window.layerChooser.showLayer("
- + id + "," + enable + ");");
+ mIitc.getMapSettings().setActiveHighlighter(name);
}
});
}
diff --git a/mobile/src/com/cradle/iitc_mobile/IITC_MapSettings.java b/mobile/src/com/cradle/iitc_mobile/IITC_MapSettings.java
new file mode 100644
index 00000000..c97c65a6
--- /dev/null
+++ b/mobile/src/com/cradle/iitc_mobile/IITC_MapSettings.java
@@ -0,0 +1,286 @@
+package com.cradle.iitc_mobile;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.AdapterView.OnItemLongClickListener;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ArrayAdapter;
+import android.widget.CheckedTextView;
+import android.widget.ListView;
+import android.widget.Spinner;
+import android.widget.TextView;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.Comparator;
+
+public class IITC_MapSettings implements OnItemSelectedListener, OnItemClickListener, OnItemLongClickListener {
+ private class HighlighterAdapter extends ArrayAdapter {
+ private HighlighterComparator mComparator = new HighlighterComparator();
+
+ private HighlighterAdapter(int resource) {
+ super(mIitc, resource);
+ clear();
+ }
+
+ @Override
+ public void add(String object) {
+ super.remove(object); // to avoid duplicates
+ super.add(object);
+ super.sort(mComparator);
+ }
+
+ @Override
+ public void clear() {
+ super.clear();
+ add("No Highlights");// Probably must be the same as window._no_highlighter
+ }
+ }
+
+ private class HighlighterComparator implements Comparator {
+ @Override
+ public int compare(String lhs, String rhs) {
+ // Move "No Highlights" on top. Sort the rest alphabetically
+ if (lhs.equals("No Highlights"))
+ return -1000;
+ else if (rhs.equals("No Highlights"))
+ return 1000;
+ else
+ return lhs.compareTo(rhs);
+ }
+ }
+
+ private class Layer {
+ boolean active;
+ int id;
+ String name;
+
+ @Override
+ public String toString() {
+ return name;
+ }
+ }
+
+ private class LayerAdapter extends ArrayAdapter
+ {
+ public LayerAdapter(int resource) {
+ super(mIitc, resource);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ Layer item = getItem(position);
+ View view = (TextView) super.getView(position, convertView, parent);
+
+ if (view instanceof CheckedTextView)
+ ((CheckedTextView) view).setChecked(item.active);
+ return view;
+ }
+ }
+
+ private IITC_Mobile mIitc;
+
+ private ArrayAdapter mHighlighters;
+ private ArrayAdapter mBaseLayers;
+ private ArrayAdapter mOverlayLayers;
+
+ private Spinner mSpinnerBaseMap;
+ private Spinner mSpinnerHighlighter;
+ private ListView mListViewOverlayLayers;
+
+ private String mActiveHighlighter;
+ private int mActiveLayer;
+
+ private boolean mLoading = true;
+
+ public IITC_MapSettings(IITC_Mobile activity) {
+ mIitc = activity;
+
+ mHighlighters = new HighlighterAdapter(R.layout.list_item_narrow);
+ mBaseLayers = new LayerAdapter(R.layout.list_item_narrow);
+ mOverlayLayers = new LayerAdapter(android.R.layout.simple_list_item_multiple_choice);
+
+ mHighlighters.setDropDownViewResource(R.layout.list_item_selectable);
+ mBaseLayers.setDropDownViewResource(R.layout.list_item_selectable);
+
+ LayoutInflater inflater = (LayoutInflater) mIitc.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ View header = inflater.inflate(R.layout.map_options_header, null);
+
+ mSpinnerHighlighter = (Spinner) header.findViewById(R.id.spinnerHighlighter);
+ mSpinnerBaseMap = (Spinner) header.findViewById(R.id.spinnerBaseLayer);
+ mListViewOverlayLayers = (ListView) mIitc.findViewById(R.id.right_drawer);
+
+ mListViewOverlayLayers.addHeaderView(header);
+
+ mSpinnerHighlighter.setAdapter(mHighlighters);
+ mSpinnerBaseMap.setAdapter(mBaseLayers);
+ mListViewOverlayLayers.setAdapter(mOverlayLayers);
+
+ mSpinnerHighlighter.setOnItemSelectedListener(this);
+ mSpinnerBaseMap.setOnItemSelectedListener(this);
+ mListViewOverlayLayers.setOnItemClickListener(this);
+ mListViewOverlayLayers.setOnItemLongClickListener(this);
+ }
+
+ private void setLayer(Layer layer) {
+ if (!mLoading)
+ mIitc.getWebView().loadUrl(
+ "javascript: window.layerChooser.showLayer(" + layer.id + "," + layer.active + ");");
+ }
+
+ public void addPortalHighlighter(String name) {
+ mHighlighters.add(name);
+
+ // to select active highlighter. must be called every time because of sorting
+ setActiveHighlighter(mActiveHighlighter);
+ }
+
+ public void onBootFinished() {
+ mLoading = false;
+ updateLayers();
+ }
+
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ position--; // The ListView header counts as an item as well.
+
+ Layer item = mOverlayLayers.getItem(position);
+ item.active = !item.active;
+ setLayer(item);
+ mOverlayLayers.notifyDataSetChanged();
+ }
+
+ @Override
+ public boolean onItemLongClick(AdapterView> parent, View view, int position, long id) {
+ position--; // The ListView header counts as an item as well.
+ boolean active = !mOverlayLayers.getItem(position).active;
+
+ for (int i = 0; i < mOverlayLayers.getCount(); i++) {
+ Layer item = mOverlayLayers.getItem(i);
+ if (item.name.contains("DEBUG")) continue;
+ if (active == item.active) continue; // no need to set same value again
+ item.active = active;
+ setLayer(item);
+ }
+
+ mOverlayLayers.notifyDataSetChanged();
+
+ return true;
+ }
+
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int position, long id) {
+ if (mLoading) return;
+
+ if (parent.equals(mSpinnerHighlighter)) {
+ String name = mHighlighters.getItem(position);
+ mIitc.getWebView().loadUrl("javascript: window.changePortalHighlights('" + name + "')");
+ }
+ else if (parent.equals(mSpinnerBaseMap)) {
+ mBaseLayers.getItem(mActiveLayer).active = false; // set old layer to hidden, but no need to really hide
+
+ Layer layer = mBaseLayers.getItem(position);
+ layer.active = true;
+ setLayer(layer);
+ }
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parent) {
+ // ignore
+ }
+
+ public void reset() {
+ mHighlighters.clear();
+ mBaseLayers.clear();
+ mOverlayLayers.clear();
+
+ mIitc.getNavigationHelper().setHighlighter(null);
+
+ mLoading = true;
+ }
+
+ public void setActiveHighlighter(String name) {
+ mActiveHighlighter = name;
+
+ int position = mHighlighters.getPosition(mActiveHighlighter);
+ if (position >= 0 && position < mHighlighters.getCount())
+ mSpinnerHighlighter.setSelection(position);
+
+ mIitc.getNavigationHelper().setHighlighter(name);
+ }
+
+ public void setLayers(String base_layer, String overlay_layer) {
+ /*
+ * the layer strings have a form like:
+ * [{"layerId":27,"name":"MapQuest OSM","active":true},
+ * {"layerId":28,"name":"Default Ingress Map","active":false}]
+ * Put it in a JSONArray and parse it
+ */
+ JSONArray base_layers = null;
+ JSONArray overlay_layers = null;
+
+ try {
+ base_layers = new JSONArray(base_layer);
+ overlay_layers = new JSONArray(overlay_layer);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ return;
+ }
+
+ mActiveLayer = 0;
+ mBaseLayers.setNotifyOnChange(false);
+ mBaseLayers.clear();
+ for (int i = 0; i < base_layers.length(); i++) {
+ try {
+ JSONObject layerObj = base_layers.getJSONObject(i);
+ Layer layer = new Layer();
+
+ layer.id = layerObj.getInt("layerId");
+ layer.name = layerObj.getString("name");
+ layer.active = layerObj.getBoolean("active");
+
+ if (layer.active)
+ // getCount() will be the index of the layer we are about to add
+ mActiveLayer = mBaseLayers.getCount();
+
+ mBaseLayers.add(layer);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ continue;
+ }
+ }
+ mBaseLayers.notifyDataSetChanged();
+ mSpinnerBaseMap.setSelection(mActiveLayer);
+
+ mOverlayLayers.setNotifyOnChange(false);
+ mOverlayLayers.clear();
+ for (int i = 0; i < overlay_layers.length(); i++) {
+ try {
+ JSONObject layerObj = overlay_layers.getJSONObject(i);
+ Layer layer = new Layer();
+
+ layer.id = layerObj.getInt("layerId");
+ layer.name = layerObj.getString("name");
+ layer.active = layerObj.getBoolean("active");
+
+ mOverlayLayers.add(layer);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ continue;
+ }
+ }
+ mOverlayLayers.notifyDataSetChanged();
+ }
+
+ public void updateLayers() {
+ if (!mLoading)
+ mIitc.getWebView().loadUrl("javascript: window.layerChooser.getLayers()");
+ }
+}
diff --git a/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java b/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java
index b8d84c83..af56d2c4 100644
--- a/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java
+++ b/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java
@@ -18,7 +18,6 @@ import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.util.Log;
-import android.util.SparseArray;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
@@ -30,10 +29,12 @@ import android.webkit.WebView;
import android.widget.SearchView;
import android.widget.Toast;
+import com.cradle.iitc_mobile.IITC_NavigationHelper.Pane;
+
import java.io.IOException;
import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.HashMap;
+import java.util.Locale;
+import java.util.Stack;
public class IITC_Mobile extends Activity {
@@ -52,37 +53,17 @@ public class IITC_Mobile extends Activity {
private boolean mDesktopMode = false;
private boolean mAdvancedMenu = false;
private boolean mReloadNeeded = false;
- private final ArrayList mDialogStack = new ArrayList();
+ private final Stack mDialogStack = new Stack();
private SharedPreferences mSharedPrefs;
- private IITC_ActionBarHelper mActionBarHelper;
+ private IITC_NavigationHelper mNavigationHelper;
+ private IITC_MapSettings mMapSettings;
// Used for custom back stack handling
- private final ArrayList mBackStack = new ArrayList();
+ private final Stack mBackStack = new Stack();
private boolean mBackStackPush = true;
- private int mCurrentPane = android.R.id.home;
+ private Pane mCurrentPane = Pane.MAP;
private boolean mBackButtonPressed = false;
- public static final SparseArray PANE_TITLES = new SparseArray();
- public static final HashMap PANES = new HashMap();
-
- static {
- PANES.put("map", android.R.id.home);
- PANES.put("info", R.id.menu_info);
- PANES.put("full", R.id.menu_full);
- PANES.put("compact", R.id.menu_compact);
- PANES.put("public", R.id.menu_public);
- PANES.put("faction", R.id.menu_faction);
- PANES.put("debug", R.id.menu_debug);
-
- // No need to declare android.R.id.home - that title is default
- PANE_TITLES.append(R.id.menu_info, "Info");
- PANE_TITLES.append(R.id.menu_full, "Full");
- PANE_TITLES.append(R.id.menu_compact, "Compact");
- PANE_TITLES.append(R.id.menu_public, "Public");
- PANE_TITLES.append(R.id.menu_faction, "Faction");
- PANE_TITLES.append(R.id.menu_debug, "Debug");
- }
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -94,7 +75,9 @@ public class IITC_Mobile extends Activity {
mIitcWebView = (IITC_WebView) findViewById(R.id.iitc_webview);
// pass ActionBar to helper because we deprecated getActionBar
- mActionBarHelper = new IITC_ActionBarHelper(this, super.getActionBar());
+ mNavigationHelper = new IITC_NavigationHelper(this, super.getActionBar());
+
+ mMapSettings = new IITC_MapSettings(this);
// do something if user changed something in the settings
mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
@@ -104,24 +87,27 @@ public class IITC_Mobile extends Activity {
SharedPreferences sharedPreferences, String key) {
if (key.equals("pref_force_desktop")) {
mDesktopMode = sharedPreferences.getBoolean("pref_force_desktop", false);
- mActionBarHelper.onPrefChanged();
- invalidateOptionsMenu();
+ mNavigationHelper.onPrefChanged();
}
if (key.equals("pref_user_loc"))
mIsLocEnabled = sharedPreferences.getBoolean("pref_user_loc",
false);
if (key.equals("pref_fullscreen_actionbar")) {
- mActionBarHelper.onPrefChanged();
+ mNavigationHelper.onPrefChanged();
return;
}
if (key.equals("pref_advanced_menu")) {
mAdvancedMenu = sharedPreferences.getBoolean("pref_advanced_menu", false);
+ mNavigationHelper.setDebugMode(mAdvancedMenu);
invalidateOptionsMenu();
// no reload needed
return;
}
- // no reload needed
- if (key.equals("pref_press_twice_to_exit") || key.equals("pref_share_selected_tab"))
+
+ if (key.equals("pref_press_twice_to_exit")
+ || key.equals("pref_share_selected_tab")
+ || key.equals("pref_messages"))
+ // no reload needed
return;
mReloadNeeded = true;
@@ -224,8 +210,8 @@ public class IITC_Mobile extends Activity {
(SearchView) mSearchMenuItem.getActionView();
searchView.setQuery(query, false);
searchView.clearFocus();
- mActionBarHelper.switchTo(android.R.id.home);
- backStackUpdate(android.R.id.home);
+
+ switchToPane(Pane.MAP);
mIitcWebView.loadUrl("javascript:search('" + query + "');");
return;
}
@@ -318,45 +304,63 @@ public class IITC_Mobile extends Activity {
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
+ mNavigationHelper.onConfigurationChanged(newConfig);
+
Log.d("iitcm", "configuration changed...restoring...reset idleTimer");
mIitcWebView.loadUrl("javascript: window.idleTime = 0");
mIitcWebView.loadUrl("javascript: window.renderUpdateStatus()");
}
+ @Override
+ protected void onPostCreate(Bundle savedInstanceState) {
+ super.onPostCreate(savedInstanceState);
+ mNavigationHelper.onPostCreate(savedInstanceState);
+ }
+
// we want a self defined behavior for the back button
@Override
public void onBackPressed() {
- // first kill all open iitc dialogs
+ // exit fullscreen mode if it is enabled and action bar is disabled or the back stack is empty
+ if (mFullscreenMode && (mBackStack.isEmpty() || mNavigationHelper.hideInFullscreen())) {
+ toggleFullscreen();
+ return;
+ }
+
+ // close drawer if opened
+ if (mNavigationHelper.isDrawerOpened()) {
+ mNavigationHelper.closeDrawers();
+ return;
+ }
+
+ // kill all open iitc dialogs
if (!mDialogStack.isEmpty()) {
- int last = mDialogStack.size() - 1;
- String id = mDialogStack.get(last);
+ String id = mDialogStack.pop();
mIitcWebView.loadUrl("javascript: " +
"var selector = $(window.DIALOGS['" + id + "']); " +
"selector.dialog('close'); " +
"selector.remove();");
return;
}
- // exit fullscreen mode if it is enabled and action bar is disabled
- // or the back stack is empty
- if (mFullscreenMode && (mBackStack.isEmpty() || mActionBarHelper.hideInFullscreen())) {
- this.toggleFullscreen();
- } else if (!mBackStack.isEmpty()) {
- // Pop last item from backstack and pretend the relevant menu item was clicked
+
+ // Pop last item from backstack and pretend the relevant menu item was clicked
+ if (!mBackStack.isEmpty()) {
backStackPop();
+ return;
+ }
+
+ if (mBackButtonPressed || !mSharedPrefs.getBoolean("pref_press_twice_to_exit", false)) {
+ super.onBackPressed();
+ return;
} else {
- if (mBackButtonPressed || !mSharedPrefs.getBoolean("pref_press_twice_to_exit", false))
- super.onBackPressed();
- else {
- mBackButtonPressed = true;
- Toast.makeText(this, "Press twice to exit", Toast.LENGTH_SHORT).show();
- // reset back button after 2 seconds
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- mBackButtonPressed = false;
- }
- }, 2000);
- }
+ mBackButtonPressed = true;
+ Toast.makeText(this, "Press twice to exit", Toast.LENGTH_SHORT).show();
+ // reset back button after 2 seconds
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mBackButtonPressed = false;
+ }
+ }, 2000);
}
}
@@ -364,31 +368,30 @@ public class IITC_Mobile extends Activity {
// shouldn't be called when back stack is empty
// catch wrong usage
if (mBackStack.isEmpty()) {
- // Empty back stack means we should be at home (ie map) screen
- mActionBarHelper.switchTo(android.R.id.home);
- mIitcWebView.loadUrl("javascript: window.show('map');");
- return;
+ mBackStack.push(Pane.MAP);
}
- int index = mBackStack.size() - 1;
- int itemId = mBackStack.remove(index);
+
+ Pane pane = mBackStack.pop();
mBackStackPush = false;
- handleMenuItemSelected(itemId);
+ switchToPane(pane);
}
- public void backStackUpdate(int itemId) {
+ public void setCurrentPane(Pane pane) {
// ensure no double adds
- if (itemId == mCurrentPane) return;
- if (itemId == android.R.id.home) {
- mBackStack.clear();
- mBackStackPush = true;
- } else {
- if (mBackStackPush)
- mBackStack.add(mCurrentPane);
- else
- mBackStackPush = true;
- }
+ if (pane == mCurrentPane) return;
- mCurrentPane = itemId;
+ if (mBackStackPush)
+ mBackStack.push(mCurrentPane);
+ else
+ mBackStackPush = true;
+
+ mCurrentPane = pane;
+ mNavigationHelper.switchTo(pane);
+ }
+
+ public void switchToPane(Pane pane) {
+ String name = pane.name().toLowerCase(Locale.getDefault());
+ mIitcWebView.loadUrl("javascript: window.show('" + name + "');");
}
@Override
@@ -397,30 +400,47 @@ public class IITC_Mobile extends Activity {
getMenuInflater().inflate(R.menu.main, menu);
// Get the SearchView and set the searchable configuration
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
- this.mSearchMenuItem = menu.findItem(R.id.menu_search);
+ mSearchMenuItem = menu.findItem(R.id.menu_search);
final SearchView searchView =
(SearchView) mSearchMenuItem.getActionView();
// Assumes current activity is the searchable activity
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false); // Do not iconify the widget; expand it by default
- // enable/disable mDesktopMode menu
- enableDesktopUI(menu);
- enableAdvancedMenu(menu);
return true;
}
@Override
- public boolean onOptionsItemSelected(MenuItem item) {
- // Handle item selection
- final int itemId = item.getItemId();
- boolean result = handleMenuItemSelected(itemId);
- return result || super.onOptionsItemSelected(item);
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ if (mNavigationHelper != null) {
+ boolean visible = !mNavigationHelper.isDrawerOpened();
+
+ for (int i = 0; i < menu.size(); i++)
+ if (menu.getItem(i).getItemId() != R.id.action_settings) {
+ // clear cookies is part of the advanced menu
+ if (menu.getItem(i).getItemId() == R.id.menu_clear_cookies) {
+ menu.getItem(i).setVisible(mAdvancedMenu & visible);
+ } else {
+ menu.getItem(i).setVisible(visible);
+ }
+ }
+ }
+
+ return super.onPrepareOptionsMenu(menu);
}
- public boolean handleMenuItemSelected(int itemId) {
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (mNavigationHelper.onOptionsItemSelected(item))
+ return true;
+
+ // Handle item selection
+ final int itemId = item.getItemId();
+
switch (itemId) {
case android.R.id.home:
- mIitcWebView.loadUrl("javascript: window.show('map');");
+ mBackStack.clear();
+ mBackStackPush = false;
+ switchToPane(Pane.MAP);
return true;
case R.id.reload_button:
reloadIITC();
@@ -429,14 +449,10 @@ public class IITC_Mobile extends Activity {
toggleFullscreen();
return true;
case R.id.layer_chooser:
- // Force map view to handle potential issue with back stack
- if (!mBackStack.isEmpty() && mCurrentPane != android.R.id.home)
- mIitcWebView.loadUrl("javascript: window.show('map');");
- // the getLayers function calls the setLayers method of IITC_JSInterface
- mIitcWebView.loadUrl("javascript: window.layerChooser.getLayers()");
+ mNavigationHelper.openRightDrawer();
return true;
case R.id.locate: // get the users current location and focus it on map
- mIitcWebView.loadUrl("javascript: window.show('map');");
+ switchToPane(Pane.MAP);
// get location from network by default
if (!mIsLocEnabled) {
mIitcWebView.loadUrl("javascript: " +
@@ -455,24 +471,6 @@ public class IITC_Mobile extends Activity {
.getIITCVersion());
startActivity(intent);
return true;
- case R.id.menu_info:
- mIitcWebView.loadUrl("javascript: window.show('info');");
- return true;
- case R.id.menu_full:
- mIitcWebView.loadUrl("javascript: window.show('full');");
- return true;
- case R.id.menu_compact:
- mIitcWebView.loadUrl("javascript: window.show('compact');");
- return true;
- case R.id.menu_public:
- mIitcWebView.loadUrl("javascript: window.show('public');");
- return true;
- case R.id.menu_faction:
- mIitcWebView.loadUrl("javascript: window.show('faction');");
- return true;
- case R.id.menu_debug:
- mIitcWebView.loadUrl("javascript: window.show('debug')");
- return true;
case R.id.menu_clear_cookies:
CookieManager cm = CookieManager.getInstance();
cm.removeAllCookie();
@@ -483,10 +481,12 @@ public class IITC_Mobile extends Activity {
}
public void reloadIITC() {
- mActionBarHelper.reset();
+ mNavigationHelper.reset();
+ mMapSettings.reset();
mBackStack.clear();
+ mBackStackPush = true;
// iitc starts on map after reload
- mCurrentPane = android.R.id.home;
+ mCurrentPane = Pane.MAP;
loadUrl(mIntelUrl);
mReloadNeeded = false;
}
@@ -512,7 +512,7 @@ public class IITC_Mobile extends Activity {
// inject the iitc-script and load the intel url
// plugins are injected onPageFinished
public void loadUrl(String url) {
- showSplashScreen();
+ setLoadingState(true);
url = addUrlParam(url);
loadIITC();
mIitcWebView.loadUrl(url);
@@ -534,7 +534,7 @@ public class IITC_Mobile extends Activity {
public void toggleFullscreen() {
mFullscreenMode = !mFullscreenMode;
- mActionBarHelper.setFullscreen(mFullscreenMode);
+ mNavigationHelper.setFullscreen(mFullscreenMode);
// toggle notification bar
WindowManager.LayoutParams attrs = getWindow().getAttributes();
@@ -584,18 +584,7 @@ public class IITC_Mobile extends Activity {
public void loginSucceeded() {
// garbage collection
mLogin = null;
- showSplashScreen();
- }
-
- // disable/enable some menu buttons...
- public void enableDesktopUI(Menu menu) {
- MenuItem item;
- item = menu.findItem(R.id.menu_chat);
- item.setVisible(!mDesktopMode);
- item = menu.findItem(R.id.menu_info);
- item.setVisible(!mDesktopMode);
- item = menu.findItem(R.id.menu_debug);
- item.setVisible(!mDesktopMode);
+ setLoadingState(true);
}
// remove dialog and add it back again
@@ -604,37 +593,35 @@ public class IITC_Mobile extends Activity {
public void setFocusedDialog(String id) {
Log.d("iitcm", "Dialog " + id + " focused");
mDialogStack.remove(id);
- mDialogStack.add(id);
+ mDialogStack.push(id);
}
// called by the javascript interface
public void dialogOpened(String id, boolean open) {
if (open) {
Log.d("iitcm", "Dialog " + id + " added");
- mDialogStack.add(id);
+ mDialogStack.push(id);
} else {
Log.d("iitcm", "Dialog " + id + " closed");
mDialogStack.remove(id);
}
}
- public void showSplashScreen() {
- if (!mSharedPrefs.getBoolean("pref_disable_splash", false)) {
+ public void setLoadingState(boolean isLoading) {
+ mNavigationHelper.setLoadingState(isLoading);
+
+ if (isLoading && !mSharedPrefs.getBoolean("pref_disable_splash", false)) {
findViewById(R.id.iitc_webview).setVisibility(View.GONE);
findViewById(R.id.imageLoading).setVisibility(View.VISIBLE);
+ } else {
+ findViewById(R.id.iitc_webview).setVisibility(View.VISIBLE);
+ findViewById(R.id.imageLoading).setVisibility(View.GONE);
}
}
- public void enableAdvancedMenu(Menu menu) {
- MenuItem item;
- item = menu.findItem(R.id.menu_debug);
- item.setVisible(mAdvancedMenu);
- item = menu.findItem(R.id.menu_clear_cookies);
- item.setVisible(mAdvancedMenu);
- }
-
/**
- * @deprecated ActionBar related stuff should be handled by ActionBarHelper
+ * @deprecated ActionBar related stuff should be handled by IITC_NavigationHelper
+ * @see getNavigationHelper()
*/
@Deprecated
@Override
@@ -642,7 +629,11 @@ public class IITC_Mobile extends Activity {
return super.getActionBar();
}
- public IITC_ActionBarHelper getActionBarHelper() {
- return mActionBarHelper;
+ public IITC_NavigationHelper getNavigationHelper() {
+ return mNavigationHelper;
+ }
+
+ public IITC_MapSettings getMapSettings() {
+ return mMapSettings;
}
}
diff --git a/mobile/src/com/cradle/iitc_mobile/IITC_NavigationHelper.java b/mobile/src/com/cradle/iitc_mobile/IITC_NavigationHelper.java
new file mode 100644
index 00000000..d0676fd1
--- /dev/null
+++ b/mobile/src/com/cradle/iitc_mobile/IITC_NavigationHelper.java
@@ -0,0 +1,351 @@
+package com.cradle.iitc_mobile;
+
+import android.app.ActionBar;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.DialogInterface.OnDismissListener;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.os.Handler;
+import android.preference.PreferenceManager;
+import android.support.v4.app.ActionBarDrawerToggle;
+import android.support.v4.widget.DrawerLayout;
+import android.text.Html;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+public class IITC_NavigationHelper extends ActionBarDrawerToggle implements OnItemClickListener {
+ // Show/hide the up arrow on the very left
+ // getActionBar().setDisplayHomeAsUpEnabled(enabled);
+
+ // Show/hide the activity icon/logo
+ // getActionBar().setDisplayShowHomeEnabled(enabled);
+
+ // Show/hide the activity title
+ // getActionBar().setDisplayShowTitleEnabled(enabled);
+
+ // Makes the icon/title clickable
+ // getActionBar().setHomeButtonEnabled(enabled);
+
+ private class NavigationAdapter extends ArrayAdapter {
+ public NavigationAdapter() {
+ super(mIitc, R.layout.list_item_selectable);
+
+ add(Pane.MAP);
+ add(Pane.INFO);
+ add(Pane.FULL);
+ add(Pane.COMPACT);
+ add(Pane.PUBLIC);
+ add(Pane.FACTION);
+
+ if (mPrefs.getBoolean("pref_advanced_menu", false))
+ add(Pane.DEBUG);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ TextView view = (TextView) super.getView(position, convertView, parent);
+ Pane item = getItem(position);
+ if (item == Pane.MAP)
+ view.setText("Map");
+ else
+ view.setText(getPaneTitle(item));
+
+ int icon = 0;
+ switch (item)
+ {
+ case MAP:
+ icon = R.drawable.location_map;
+ break;
+ case INFO:
+ icon = R.drawable.action_about;
+ break;
+ case FULL:
+ icon = R.drawable.collections_view_as_list;
+ break;
+ case COMPACT:
+ icon = R.drawable.collections_view_as_list_compact;
+ break;
+ case PUBLIC:
+ icon = R.drawable.social_group;
+ break;
+ case FACTION:
+ icon = R.drawable.social_cc_bcc;
+ break;
+ case DEBUG:
+ icon = R.drawable.ic_debug;
+ break;
+ }
+
+ if (icon != 0)
+ view.setCompoundDrawablesWithIntrinsicBounds(icon, 0, 0, 0);
+
+ return view;
+ }
+ }
+
+ public static enum Pane {
+ COMPACT, DEBUG, FACTION, FULL, INFO, MAP, PUBLIC
+ }
+
+ public static final int NOTICE_DRAWERS = 1 << 0;
+ public static final int NOTICE_INFO = 1 << 1;
+ // next one would be 1<<2; (this results in 1,2,4,8,...)
+
+ private IITC_Mobile mIitc;
+ private ActionBar mActionBar;
+ private SharedPreferences mPrefs;
+ private NavigationAdapter mNavigationAdapter;
+ private DrawerLayout mDrawerLayout;
+ private ListView mDrawerLeft;
+ private View mDrawerRight;
+
+ private boolean mDesktopMode = false;
+ private boolean mFullscreen = false;
+ private boolean mIsLoading;
+ private boolean mHideInFullscreen = false;
+ private Pane mPane = Pane.MAP;
+ private String mHighlighter = null;
+
+ public IITC_NavigationHelper(IITC_Mobile activity, ActionBar bar) {
+ super(activity, (DrawerLayout) activity.findViewById(R.id.drawer_layout),
+ R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close);
+
+ mIitc = activity;
+ mActionBar = bar;
+ mDrawerLeft = (ListView) activity.findViewById(R.id.left_drawer);
+ mDrawerRight = activity.findViewById(R.id.right_drawer);
+ mDrawerLayout = (DrawerLayout) activity.findViewById(R.id.drawer_layout);
+
+ mPrefs = PreferenceManager.getDefaultSharedPreferences(activity);
+
+ mActionBar.setDisplayShowHomeEnabled(true); // show icon
+
+ mNavigationAdapter = new NavigationAdapter();
+ mDrawerLeft.setAdapter(mNavigationAdapter);
+ mDrawerLeft.setOnItemClickListener(this);
+ mDrawerLeft.setItemChecked(0, true);
+ mDrawerLayout.setDrawerListener(this);
+
+ onPrefChanged(); // also calls updateActionBar()
+
+ showNotice(NOTICE_DRAWERS);
+ }
+
+ private void showNotice(final int which) {
+ if ((mPrefs.getInt("pref_messages", 0) & which) != 0)
+ return;
+
+ String text;
+ switch (which) {
+ case NOTICE_DRAWERS:
+ text = mIitc.getText(R.string.notice_drawers).toString();
+ break;
+ case NOTICE_INFO:
+ text = mIitc.getText(R.string.notice_info).toString();
+ break;
+ default:
+ return;
+ }
+
+ TextView message = new TextView(mIitc);
+ message.setPadding(20, 20, 20, 20);
+ message.setText(Html.fromHtml(text));
+
+ AlertDialog dialog = new AlertDialog.Builder(mIitc)
+ .setView(message)
+ .setCancelable(true)
+ .setPositiveButton(android.R.string.ok, new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.cancel();
+ }
+ })
+ .create();
+ dialog.setOnDismissListener(new OnDismissListener() {
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ int value = mPrefs.getInt("pref_messages", 0);
+ value |= which;
+
+ mPrefs
+ .edit()
+ .putInt("pref_messages", value)
+ .commit();
+ }
+ });
+ dialog.show();
+ }
+
+ private void updateActionBar() {
+ int position = mNavigationAdapter.getPosition(mPane);
+ if (position >= 0 && position < mNavigationAdapter.getCount())
+ mDrawerLeft.setItemChecked(position, true);
+
+ if (mDesktopMode) {
+ mActionBar.setDisplayHomeAsUpEnabled(false); // Hide "up" indicator
+ mActionBar.setHomeButtonEnabled(false); // Make icon unclickable
+ mActionBar.setTitle(mIitc.getString(R.string.app_name));
+ mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, mDrawerLeft);
+ mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, mDrawerRight);
+ setDrawerIndicatorEnabled(false);
+ } else {
+ if (mIsLoading) {
+ mActionBar.setDisplayHomeAsUpEnabled(false); // Hide "up" indicator
+ mActionBar.setHomeButtonEnabled(false);// Make icon unclickable
+ mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
+ setDrawerIndicatorEnabled(false);
+ } else {
+ mActionBar.setDisplayHomeAsUpEnabled(true); // Show "up" indicator
+ mActionBar.setHomeButtonEnabled(true);// Make icon clickable
+ mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
+
+ if (mPane == Pane.MAP || mDrawerLayout.isDrawerOpen(mDrawerLeft))
+ setDrawerIndicatorEnabled(true);
+ else
+ setDrawerIndicatorEnabled(false);
+ }
+
+ if (mDrawerLayout.isDrawerOpen(mDrawerLeft))
+ mActionBar.setTitle(mIitc.getString(R.string.app_name));
+ else
+ mActionBar.setTitle(getPaneTitle(mPane));
+ }
+
+ boolean mapVisible = mDesktopMode || mPane == Pane.MAP;
+ if ("No Highlights".equals(mHighlighter) || isDrawerOpened() || !mapVisible)
+ mActionBar.setSubtitle(null);
+ else
+ mActionBar.setSubtitle(mHighlighter);
+
+ if (mFullscreen && mHideInFullscreen)
+ mActionBar.hide();
+ else
+ mActionBar.show();
+ }
+
+ public void closeDrawers() {
+ mDrawerLayout.closeDrawers();
+ }
+
+ public String getPaneTitle(Pane pane)
+ {
+ switch (pane) {
+ case INFO:
+ return "Info";
+ case FULL:
+ return "Full";
+ case COMPACT:
+ return "Compact";
+ case PUBLIC:
+ return "Public";
+ case FACTION:
+ return "Faction";
+ case DEBUG:
+ return "Debug";
+ default:
+ return mIitc.getString(R.string.app_name);
+ }
+ }
+
+ public boolean hideInFullscreen() {
+ return mHideInFullscreen;
+ }
+
+ public boolean isDrawerOpened() {
+ return mDrawerLayout.isDrawerOpen(mDrawerLeft) || mDrawerLayout.isDrawerOpen(mDrawerRight);
+ }
+
+ @Override
+ public void onDrawerClosed(View drawerView) {
+ super.onDrawerClosed(drawerView);
+
+ // delay invalidating to prevent flickering in case another drawer is opened
+ (new Handler()).postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mIitc.invalidateOptionsMenu();
+ updateActionBar();
+ }
+ }, 200);
+ }
+
+ @Override
+ public void onDrawerOpened(View drawerView) {
+ super.onDrawerOpened(drawerView);
+ mIitc.invalidateOptionsMenu();
+ updateActionBar();
+ mDrawerLayout.closeDrawer(drawerView.equals(mDrawerLeft) ? mDrawerRight : mDrawerLeft);
+ }
+
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ Pane item = mNavigationAdapter.getItem(position);
+ mIitc.switchToPane(item);
+
+ if (item == Pane.INFO)
+ showNotice(NOTICE_INFO);
+
+ mDrawerLayout.closeDrawer(mDrawerLeft);
+ }
+
+ public void onPostCreate(Bundle savedInstanceState) {
+ // Sync the toggle state after onRestoreInstanceState has occurred.
+ syncState();
+ }
+
+ public void onPrefChanged() {
+ mDesktopMode = mPrefs.getBoolean("pref_force_desktop", false);
+ mHideInFullscreen = mPrefs.getBoolean("pref_fullscreen_actionbar", true);
+ updateActionBar();
+ }
+
+ public void openRightDrawer() {
+ if (mDrawerLayout.getDrawerLockMode(mDrawerRight) == DrawerLayout.LOCK_MODE_UNLOCKED)
+ mDrawerLayout.openDrawer(mDrawerRight);
+ }
+
+ public void reset() {
+ mPane = Pane.MAP;
+ updateActionBar();
+ }
+
+ public void setDebugMode(boolean enabled) {
+ mNavigationAdapter.remove(Pane.DEBUG); // avoid duplicates
+ if (enabled)
+ mNavigationAdapter.add(Pane.DEBUG);
+ }
+
+ public void setFullscreen(boolean fullscreen) {
+ mFullscreen = fullscreen;
+ if (mFullscreen && mHideInFullscreen) {
+ // show a toast with instructions to exit the fullscreen mode again
+ Toast.makeText(mIitc, "Press back button to exit fullscreen", Toast.LENGTH_SHORT).show();
+ }
+
+ updateActionBar();
+ }
+
+ public void setHighlighter(String name) {
+ mHighlighter = name;
+ updateActionBar();
+ }
+
+ public void setLoadingState(boolean isLoading) {
+ mIsLoading = isLoading;
+ updateActionBar();
+ }
+
+ public void switchTo(Pane pane) {
+ mPane = pane;
+
+ updateActionBar();
+ }
+}
diff --git a/mobile/src/com/cradle/iitc_mobile/IITC_WebView.java b/mobile/src/com/cradle/iitc_mobile/IITC_WebView.java
index 6e932266..c0966c28 100644
--- a/mobile/src/com/cradle/iitc_mobile/IITC_WebView.java
+++ b/mobile/src/com/cradle/iitc_mobile/IITC_WebView.java
@@ -42,7 +42,7 @@ public class IITC_WebView extends WebView {
+ "/databases/");
mSettings.setAppCachePath(this.getContext().getCacheDir()
.getAbsolutePath());
- this.mJsInterface = new IITC_JSInterface(mContext);
+ this.mJsInterface = new IITC_JSInterface((IITC_Mobile) mContext);
this.addJavascriptInterface(mJsInterface, "android");
this.setWebChromeClient(new WebChromeClient() {
@@ -53,7 +53,7 @@ public class IITC_WebView extends WebView {
*/
@Override
public void onGeolocationPermissionsShowPrompt(String origin,
- GeolocationPermissions.Callback callback) {
+ GeolocationPermissions.Callback callback) {
callback.invoke(origin, true, false);
}
@@ -76,7 +76,7 @@ public class IITC_WebView extends WebView {
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
if (consoleMessage.messageLevel() == ConsoleMessage.MessageLevel.ERROR) {
Log.d("iitcm", consoleMessage.message());
- mJsInterface.removeSplashScreen();
+ ((IITC_Mobile) getContext()).setLoadingState(false);
}
return super.onConsoleMessage(consoleMessage);
}
diff --git a/mobile/src/com/cradle/iitc_mobile/async/CheckHttpResponse.java b/mobile/src/com/cradle/iitc_mobile/async/CheckHttpResponse.java
index e7df6056..431dee3c 100644
--- a/mobile/src/com/cradle/iitc_mobile/async/CheckHttpResponse.java
+++ b/mobile/src/com/cradle/iitc_mobile/async/CheckHttpResponse.java
@@ -43,7 +43,7 @@ public class CheckHttpResponse extends AsyncTask {
int code = response.getStatusLine().getStatusCode();
if (code != HttpStatus.SC_OK) {
Log.d("iitcm", "received error code: " + code);
- mJsInterface.removeSplashScreen();
+ ((IITC_Mobile) mContext).setLoadingState(false);
// TODO: remove when google login issue is fixed
if (urls[0].contains("uberauth=WILL_NOT_SIGN_IN")) {
return true;