From 263a16d60e27a77c9c43dd571dc64154b6557bf1 Mon Sep 17 00:00:00 2001 From: Alexey Kulish Date: Mon, 8 May 2017 09:57:06 +0300 Subject: [PATCH] Fix web image viewer --- OsmAnd/res/layout-land/map_image_view.xml | 92 +++++++ OsmAnd/res/layout/main.xml | 5 + OsmAnd/res/layout/map_image_view.xml | 91 +++++++ .../mapcontextmenu/other/WebImageMenu.java | 230 ++++++++++++++++++ .../other/WebImageMenuFragment.java | 109 +++++++++ .../plus/mapillary/MapillaryImageCard.java | 125 +--------- .../plus/mapillary/MapillaryPlugin.java | 6 +- .../mapwidgets/MapInfoWidgetsFactory.java | 1 - 8 files changed, 533 insertions(+), 126 deletions(-) create mode 100644 OsmAnd/res/layout-land/map_image_view.xml create mode 100644 OsmAnd/res/layout/map_image_view.xml create mode 100644 OsmAnd/src/net/osmand/plus/mapcontextmenu/other/WebImageMenu.java create mode 100644 OsmAnd/src/net/osmand/plus/mapcontextmenu/other/WebImageMenuFragment.java diff --git a/OsmAnd/res/layout-land/map_image_view.xml b/OsmAnd/res/layout-land/map_image_view.xml new file mode 100644 index 0000000000..57de22d2e6 --- /dev/null +++ b/OsmAnd/res/layout-land/map_image_view.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OsmAnd/res/layout/main.xml b/OsmAnd/res/layout/main.xml index abb26e8676..af56ebccff 100644 --- a/OsmAnd/res/layout/main.xml +++ b/OsmAnd/res/layout/main.xml @@ -72,6 +72,11 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/WebImageMenu.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/WebImageMenu.java new file mode 100644 index 0000000000..620ae88ee8 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/WebImageMenu.java @@ -0,0 +1,230 @@ +package net.osmand.plus.mapcontextmenu.other; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.graphics.Color; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.view.View; +import android.view.ViewGroup; +import android.webkit.JavascriptInterface; +import android.webkit.WebView; +import android.widget.LinearLayout; + +import net.osmand.AndroidUtils; +import net.osmand.data.LatLon; +import net.osmand.plus.OsmandSettings; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.mapillary.MapillaryLayer; +import net.osmand.plus.views.OsmandMapTileView; + +public class WebImageMenu { + + private MapActivity mapActivity; + + private static final String KEY_WEB_IMAGE_MENU_TYPE = "key_web_image_menu_type"; + private static final String KEY_WEB_IMAGE_MENU_VIEWER_URL = "key_web_image_menu_viewer_url"; + private static final String KEY_WEB_IMAGE_MENU_LATLON = "key_web_image_menu_latlon"; + private static final String KEY_WEB_IMAGE_MENU_CA = "key_web_image_menu_ca"; + private static final String KEY_WEB_IMAGE_MENU_TITLE = "key_web_image_menu_title"; + private static final String KEY_WEB_IMAGE_MENU_DESCRIPTION = "key_web_image_menu_description"; + + private WebImageType type; + private String viewerUrl; + private LatLon latLon; + private double ca = Double.NaN; + private String title; + private String description; + + private int prevMapPosition = OsmandSettings.CENTER_CONSTANT; + + public enum WebImageType { + MAPILLARY + } + + private WebImageMenu(MapActivity mapActivity, @NonNull WebImageType type, @NonNull String viewerUrl, + LatLon latLon, double ca, String title, String description) { + this.mapActivity = mapActivity; + this.type = type; + this.viewerUrl = viewerUrl; + this.latLon = latLon; + this.ca = ca; + this.title = title; + this.description = description; + } + + public MapActivity getMapActivity() { + return mapActivity; + } + + public WebImageType getType() { + return type; + } + + public String getViewerUrl() { + return viewerUrl; + } + + public LatLon getLatLon() { + return latLon; + } + + public double getCa() { + return ca; + } + + public String getTitle() { + return title; + } + + public String getDescription() { + return description; + } + + public void saveMenu(Bundle bundle) { + bundle.putString(KEY_WEB_IMAGE_MENU_TYPE, type.name()); + bundle.putSerializable(KEY_WEB_IMAGE_MENU_VIEWER_URL, viewerUrl); + bundle.putSerializable(KEY_WEB_IMAGE_MENU_LATLON, latLon); + bundle.putString(KEY_WEB_IMAGE_MENU_TITLE, title); + bundle.putDouble(KEY_WEB_IMAGE_MENU_CA, ca); + if (description != null) { + bundle.putString(KEY_WEB_IMAGE_MENU_DESCRIPTION, description); + } + } + + public static WebImageMenu restoreMenu(Bundle bundle, MapActivity mapActivity) { + + try { + WebImageType type = WebImageType.valueOf(bundle.getString(KEY_WEB_IMAGE_MENU_TYPE)); + String viewerUrl = bundle.getString(KEY_WEB_IMAGE_MENU_VIEWER_URL); + LatLon latLon = null; + String title = bundle.getString(KEY_WEB_IMAGE_MENU_TITLE); + Object latLonObj = bundle.getSerializable(KEY_WEB_IMAGE_MENU_LATLON); + if (latLonObj != null) { + latLon = (LatLon) latLonObj; + } + Double ca = bundle.getDouble(KEY_WEB_IMAGE_MENU_CA, Double.NaN); + String description = bundle.getString(KEY_WEB_IMAGE_MENU_TITLE); + if (viewerUrl != null) { + return new WebImageMenu(mapActivity, type, viewerUrl, latLon, ca, title, description); + } else { + return null; + } + } catch (IllegalArgumentException e) { + return null; + } + } + + public void onResume() { + setImageLocation(latLon, ca, true); + } + + public void onPause() { + restoreMapPosition(); + setImageLocation(null, Double.NaN, false); + } + + public void setImageLocation(LatLon latLon, double ca, boolean animated) { + switch (type) { + + case MAPILLARY: + MapillaryLayer layer = mapActivity.getMapView().getLayerByClass(MapillaryLayer.class); + if (layer != null) { + layer.setSelectedImageLocation(latLon); + if (!Double.isNaN(ca)) { + layer.setSelectedImageCameraAngle((float) ca); + } else { + layer.setSelectedImageCameraAngle(null); + } + } + break; + } + + if (latLon != null) { + shiftMapPosition(); + if (animated) { + mapActivity.getMapView().getAnimatedDraggingThread().startMoving( + latLon.getLatitude(), latLon.getLongitude(), mapActivity.getMapView().getZoom(), true); + } else { + mapActivity.setMapLocation(latLon.getLatitude(), latLon.getLongitude()); + } + } else { + mapActivity.refreshMap(); + } + } + + private void shiftMapPosition() { + OsmandMapTileView mapView = mapActivity.getMapView(); + if (AndroidUiHelper.isOrientationPortrait(mapActivity)) { + if (mapView.getMapPosition() != OsmandSettings.MIDDLE_CONSTANT) { + prevMapPosition = mapView.getMapPosition(); + mapView.setMapPosition(OsmandSettings.MIDDLE_CONSTANT); + } + } else { + mapView.setMapPositionX(1); + } + } + + private void restoreMapPosition() { + if (AndroidUiHelper.isOrientationPortrait(mapActivity)) { + mapActivity.getMapView().setMapPosition(prevMapPosition); + } else { + mapActivity.getMapView().setMapPositionX(0); + } + } + + public View getContentView() { + switch (type) { + + case MAPILLARY: + return getWebView(viewerUrl); + + default: + return null; + } + } + + @SuppressLint({"SetJavaScriptEnabled", "AddJavascriptInterface"}) + private WebView getWebView(String url) { + final WebView webView = new WebView(mapActivity); + webView.setBackgroundColor(Color.argb(1, 0, 0, 0)); + //webView.setLayerType(WebView.LAYER_TYPE_SOFTWARE, null); + webView.setScrollContainer(false); + webView.getSettings().setJavaScriptEnabled(true); + if (type == WebImageType.MAPILLARY) { + webView.addJavascriptInterface(new MapillaryWebAppInterface(mapActivity), "Android"); + } + boolean portrait = AndroidUiHelper.isOrientationPortrait(mapActivity); + LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( + portrait ? ViewGroup.LayoutParams.MATCH_PARENT : AndroidUtils.dpToPx(mapActivity, 360f), + portrait ? AndroidUtils.dpToPx(mapActivity, 270f) : ViewGroup.LayoutParams.MATCH_PARENT); + webView.setLayoutParams(lp); + webView.loadUrl(url); + return webView; + } + + private class MapillaryWebAppInterface { + Context mContext; + + MapillaryWebAppInterface(Context c) { + mContext = c; + } + + @JavascriptInterface + public void onNodeChanged(double latitude, double longitude, double ca) { + LatLon latLon = null; + if (!Double.isNaN(latitude) && !Double.isNaN(longitude)) { + latLon = new LatLon(latitude, longitude); + } + setImageLocation(latLon, ca, false); + } + } + + public static WebImageMenu show(MapActivity mapActivity, WebImageType type, String viewerUrl, LatLon latLon, double ca, + String title, String description) { + WebImageMenu menu = new WebImageMenu(mapActivity, type, viewerUrl, latLon, ca, title, description); + WebImageMenuFragment.showInstance(menu); + return menu; + } +} diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/WebImageMenuFragment.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/WebImageMenuFragment.java new file mode 100644 index 0000000000..1c520c3c85 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/WebImageMenuFragment.java @@ -0,0 +1,109 @@ +package net.osmand.plus.mapcontextmenu.other; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.webkit.WebView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import net.osmand.plus.R; +import net.osmand.plus.activities.MapActivity; +import net.osmand.util.Algorithms; + +public class WebImageMenuFragment extends Fragment { + public static final String TAG = "WebImageMenuFragment"; + + private WebImageMenu menu; + private View view; + private LinearLayout viewerLayout; + private View contentView; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (savedInstanceState != null && getActivity() instanceof MapActivity) { + menu = WebImageMenu.restoreMenu(savedInstanceState, (MapActivity) getActivity()); + } + } + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + view = inflater.inflate(R.layout.map_image_view, container, false); + viewerLayout = (LinearLayout) view.findViewById(R.id.image_viewer); + contentView = menu.getContentView(); + if (contentView != null) { + viewerLayout.addView(contentView); + } + view.findViewById(R.id.image_close_button).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + dismiss(); + } + }); + if (!Algorithms.isEmpty(menu.getTitle())) { + ((TextView) view.findViewById(R.id.image_title)).setText(menu.getTitle()); + } + if (!Algorithms.isEmpty(menu.getDescription())) { + ((TextView) view.findViewById(R.id.image_description)).setText(menu.getDescription()); + } + return view; + } + + @Override + public void onResume() { + super.onResume(); + if (menu != null) { + menu.onResume(); + } + } + + @Override + public void onPause() { + super.onPause(); + if (menu != null) { + menu.onPause(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (viewerLayout != null && contentView != null) { + viewerLayout.removeView(contentView); + if (contentView instanceof WebView) { + ((WebView) contentView).loadUrl("about:blank"); + } + } + } + + @Override + public void onSaveInstanceState(Bundle outState) { + menu.saveMenu(outState); + } + + public static void showInstance(WebImageMenu menu) { + WebImageMenuFragment fragment = new WebImageMenuFragment(); + fragment.menu = menu; + menu.getMapActivity().getSupportFragmentManager().beginTransaction() + .replace(R.id.topFragmentContainer, fragment, TAG) + .addToBackStack(TAG).commit(); + } + + public void dismiss() { + MapActivity activity = menu.getMapActivity(); + if (activity != null) { + try { + activity.getSupportFragmentManager().popBackStack(TAG, + FragmentManager.POP_BACK_STACK_INCLUSIVE); + } catch (Exception e) { + e.printStackTrace(); + } + } + } +} diff --git a/OsmAnd/src/net/osmand/plus/mapillary/MapillaryImageCard.java b/OsmAnd/src/net/osmand/plus/mapillary/MapillaryImageCard.java index 776e5aa676..dd381c5820 100644 --- a/OsmAnd/src/net/osmand/plus/mapillary/MapillaryImageCard.java +++ b/OsmAnd/src/net/osmand/plus/mapillary/MapillaryImageCard.java @@ -1,144 +1,27 @@ package net.osmand.plus.mapillary; -import android.annotation.SuppressLint; -import android.content.Context; -import android.graphics.Color; import android.view.View; -import android.view.ViewGroup; -import android.webkit.JavascriptInterface; -import android.webkit.WebView; -import android.widget.LinearLayout; -import net.osmand.AndroidUtils; -import net.osmand.data.LatLon; -import net.osmand.plus.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; -import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard; -import net.osmand.plus.views.OsmandMapTileView; -import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarController; -import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarControllerType; +import net.osmand.plus.mapcontextmenu.other.WebImageMenu; +import net.osmand.plus.mapcontextmenu.other.WebImageMenu.WebImageType; import org.json.JSONObject; public class MapillaryImageCard extends ImageCard { - private int prevMapPosition = OsmandSettings.CENTER_CONSTANT; - public MapillaryImageCard(final MapActivity mapActivity, final JSONObject imageObject) { super(mapActivity, imageObject); this.icon = getMyApplication().getIconsCache().getIcon(R.drawable.ic_logo_mapillary); this.onClickListener = new View.OnClickListener() { @Override public void onClick(View v) { - final MapillaryImageViewerController toolbarController = new MapillaryImageViewerController(); - toolbarController.setTitle(getMyApplication().getString(R.string.mapillary)); - toolbarController.setCloseBtnVisible(false); - toolbarController.setBottomView(getWebView(getUrl())); - toolbarController.setOnBackButtonClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - getMapActivity().hideTopToolbar(toolbarController); - } - }); - toolbarController.setOnCloseToolbarListener(new Runnable() { - @Override - public void run() { - restoreMapPosition(); - setSelectedImageLocation(null, Double.NaN); - } - }); getMapActivity().getContextMenu().hideMenues(); - getMapActivity().showTopToolbar(toolbarController); - setSelectedImageLocation(getLocation(), getCa()); - + WebImageMenu.show(getMapActivity(), WebImageType.MAPILLARY, getUrl(), getLocation(), + getCa(), getMyApplication().getString(R.string.mapillary), null); } }; } - - @SuppressLint({"SetJavaScriptEnabled", "AddJavascriptInterface"}) - private WebView getWebView(String url) { - final WebView webView = new WebView(view.getContext()); - webView.setBackgroundColor(Color.BLACK); - //webView.setLayerType(WebView.LAYER_TYPE_SOFTWARE, null); - webView.setScrollContainer(false); - webView.getSettings().setJavaScriptEnabled(true); - webView.addJavascriptInterface(new WebAppInterface(view.getContext()), "Android"); - boolean portrait = AndroidUiHelper.isOrientationPortrait(getMapActivity()); - LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( - portrait ? ViewGroup.LayoutParams.MATCH_PARENT : AndroidUtils.dpToPx(getMyApplication(), 360f), - AndroidUtils.dpToPx(getMyApplication(), 200f)); - webView.setLayoutParams(lp); - webView.loadUrl(url); - return webView; - } - - private void shiftMapPosition() { - OsmandMapTileView mapView = getMapActivity().getMapView(); - if (AndroidUiHelper.isOrientationPortrait(getMapActivity())) { - if (mapView.getMapPosition() != OsmandSettings.MIDDLE_CONSTANT) { - prevMapPosition = mapView.getMapPosition(); - mapView.setMapPosition(OsmandSettings.MIDDLE_CONSTANT); - } - } else { - mapView.setMapPositionX(1); - } - } - - private void restoreMapPosition() { - if (AndroidUiHelper.isOrientationPortrait(getMapActivity())) { - getMapActivity().getMapView().setMapPosition(prevMapPosition); - } else { - getMapActivity().getMapView().setMapPositionX(0); - } - } - - private void setSelectedImageLocation(LatLon latLon, double ca) { - MapillaryLayer layer = getMapActivity().getMapView().getLayerByClass(MapillaryLayer.class); - if (layer != null) { - layer.setSelectedImageLocation(latLon); - if (!Double.isNaN(ca)) { - layer.setSelectedImageCameraAngle((float) ca); - } else { - layer.setSelectedImageCameraAngle(null); - } - if (latLon != null) { - shiftMapPosition(); - getMapActivity().setMapLocation(latLon.getLatitude(), latLon.getLongitude()); - } else { - getMapActivity().refreshMap(); - } - } - } - - private class WebAppInterface { - Context mContext; - - WebAppInterface(Context c) { - mContext = c; - } - - @JavascriptInterface - public void onNodeChanged(double latitude, double longitude, double ca) { - LatLon latLon = null; - if (!Double.isNaN(latitude) && !Double.isNaN(longitude)) { - latLon = new LatLon(latitude, longitude); - } - setSelectedImageLocation(latLon, ca); - } - } - - private static class MapillaryImageViewerController extends TopToolbarController { - - MapillaryImageViewerController() { - super(TopToolbarControllerType.ONLINE_IMAGE); - setBackBtnIconIds(R.drawable.ic_action_remove_dark, R.drawable.ic_action_remove_dark); - setBackBtnIconClrIds(0, 0); - setTitleTextClrIds(R.color.primary_text_dark, R.color.primary_text_dark); - setDescrTextClrIds(R.color.primary_text_dark, R.color.primary_text_dark); - setBgIds(R.color.osmand_orange, R.color.osmand_orange, - R.color.osmand_orange, R.color.osmand_orange); - } - } } diff --git a/OsmAnd/src/net/osmand/plus/mapillary/MapillaryPlugin.java b/OsmAnd/src/net/osmand/plus/mapillary/MapillaryPlugin.java index bebf89b99e..2df0d4b05e 100644 --- a/OsmAnd/src/net/osmand/plus/mapillary/MapillaryPlugin.java +++ b/OsmAnd/src/net/osmand/plus/mapillary/MapillaryPlugin.java @@ -108,10 +108,8 @@ public class MapillaryPlugin extends OsmandPlugin { if (settings.SHOW_MAPILLARY.get()) { mapillarySource = settings.getTileSourceByName(TileSourceManager.getMapillarySource().getName(), false); } - if (!Algorithms.objectEquals(mapillarySource, layer.getMap())) { - if (mapillarySource == null) { - mapView.removeLayer(layer); - } else if (mapView.getMapRenderer() == null) { + if (!Algorithms.objectEquals(mapillarySource, layer.getMap()) || !mapView.isLayerVisible(layer)) { + if (mapView.getMapRenderer() == null && !mapView.isLayerVisible(layer)) { mapView.addLayer(layer, layerOrder); } layer.setMap(mapillarySource); diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java index aa871538c5..6856dc9531 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java @@ -42,7 +42,6 @@ public class MapInfoWidgetsFactory { CONTEXT_MENU, TRACK_DETAILS, DISCOUNT, - ONLINE_IMAGE, } public TextInfoWidget createAltitudeControl(final MapActivity map) {