diff --git a/OsmAnd/res/layout/fragment_measurement_tool.xml b/OsmAnd/res/layout/fragment_measurement_tool.xml index 9b2d999161..6e2250ea2e 100644 --- a/OsmAnd/res/layout/fragment_measurement_tool.xml +++ b/OsmAnd/res/layout/fragment_measurement_tool.xml @@ -81,27 +81,28 @@ android:layout_height="1dp" android:background="?attr/dashboard_divider"/> - + android:layout_height="match_parent"/> - + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/OsmandSettings.java index 93b7f97da9..03147d4e8b 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/OsmandSettings.java @@ -1244,7 +1244,8 @@ public class OsmandSettings { // this value string is synchronized with settings_pref.xml preference name public static final int CENTER_CONSTANT = 0; public static final int BOTTOM_CONSTANT = 1; - public static final int MIDDLE_CONSTANT = 2; + public static final int MIDDLE_BOTTOM_CONSTANT = 2; + public static final int MIDDLE_TOP_CONSTANT = 3; public final CommonPreference CENTER_POSITION_ON_MAP = new BooleanPreference("center_position_on_map", false).makeProfile(); // this value string is synchronized with settings_pref.xml preference name diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/dialogs/ContextMenuCardDialog.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/dialogs/ContextMenuCardDialog.java index 29fc6b6395..1474b371d7 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/dialogs/ContextMenuCardDialog.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/dialogs/ContextMenuCardDialog.java @@ -3,7 +3,6 @@ package net.osmand.plus.mapcontextmenu.builders.cards.dialogs; import android.os.Bundle; import android.support.annotation.NonNull; import android.view.Menu; -import android.view.MenuItem; import android.view.View; import net.osmand.plus.OsmandSettings; @@ -12,8 +11,6 @@ import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.mapillary.MapillaryImageDialog; import net.osmand.plus.views.OsmandMapTileView; -import java.util.List; - public abstract class ContextMenuCardDialog { private MapActivity mapActivity; @@ -109,9 +106,9 @@ public abstract class ContextMenuCardDialog { private void shiftMapPosition() { OsmandMapTileView mapView = mapActivity.getMapView(); if (AndroidUiHelper.isOrientationPortrait(mapActivity)) { - if (mapView.getMapPosition() != OsmandSettings.MIDDLE_CONSTANT) { + if (mapView.getMapPosition() != OsmandSettings.MIDDLE_BOTTOM_CONSTANT) { prevMapPosition = mapView.getMapPosition(); - mapView.setMapPosition(OsmandSettings.MIDDLE_CONSTANT); + mapView.setMapPosition(OsmandSettings.MIDDLE_BOTTOM_CONSTANT); } } else { mapView.setMapPositionX(1); diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolAdapter.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolAdapter.java new file mode 100644 index 0000000000..a2c4e79f69 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolAdapter.java @@ -0,0 +1,109 @@ +package net.osmand.plus.measurementtool; + +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.TextView; + +import net.osmand.plus.GPXUtilities.WptPt; +import net.osmand.plus.IconsCache; +import net.osmand.plus.OsmAndFormatter; +import net.osmand.plus.R; +import net.osmand.plus.activities.MapActivity; +import net.osmand.util.MapUtils; + +import java.util.List; + +class MeasurementToolAdapter extends RecyclerView.Adapter { + + private final MapActivity mapActivity; + private final List points; + private RemovePointListener removePointListener; + private ItemClickListener itemClickListener; + + MeasurementToolAdapter(MapActivity mapActivity, List points) { + this.mapActivity = mapActivity; + this.points = points; + } + + void setRemovePointListener(RemovePointListener listener) { + this.removePointListener = listener; + } + + public void setItemClickListener(ItemClickListener itemClickListener) { + this.itemClickListener = itemClickListener; + } + + @Override + public Holder onCreateViewHolder(ViewGroup viewGroup, int i) { + View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.measure_points_list_item, viewGroup, false); + final boolean nightMode = mapActivity.getMyApplication().getDaynightHelper().isNightModeForMapControls(); + if (!nightMode) { + view.findViewById(R.id.points_divider).setBackgroundResource(R.drawable.divider); + } + view.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + itemClickListener.onItemClick(view); + } + }); + return new Holder(view); + } + + @Override + public void onBindViewHolder(final Holder holder, int pos) { + IconsCache iconsCache = mapActivity.getMyApplication().getIconsCache(); + holder.icon.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_measure_point)); + holder.title.setText(mapActivity.getString(R.string.plugin_distance_point) + " - " + (pos + 1)); + if (pos < 1) { + holder.descr.setText(mapActivity.getString(R.string.shared_string_control_start)); + } else { + float dist = 0; + for (int i = 1; i <= pos; i++) { + dist += MapUtils.getDistance(points.get(i - 1).lat, points.get(i - 1).lon, + points.get(i).lat, points.get(i).lon); + } + holder.descr.setText(OsmAndFormatter.getFormattedDistance(dist, mapActivity.getMyApplication())); + } + holder.deleteBtn.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_remove_dark)); + holder.deleteBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + points.remove(holder.getAdapterPosition()); + removePointListener.onPointRemove(); + } + }); + } + + @Override + public int getItemCount() { + return points.size(); + } + + static class Holder extends RecyclerView.ViewHolder { + + final ImageView icon; + final TextView title; + final TextView descr; + final ImageButton deleteBtn; + + Holder(View view) { + super(view); + icon = (ImageView) view.findViewById(R.id.measure_point_icon); + title = (TextView) view.findViewById(R.id.measure_point_title); + descr = (TextView) view.findViewById(R.id.measure_point_descr); + deleteBtn = (ImageButton) view.findViewById(R.id.measure_point_remove_image_button); + } + } + + interface RemovePointListener { + void onPointRemove(); + } + + interface ItemClickListener { + void onItemClick(View view); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java index 1e1375926e..82d4440e6b 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java @@ -10,6 +10,8 @@ import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.content.ContextCompat; import android.support.v7.app.AlertDialog; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; import android.support.v7.widget.SwitchCompat; import android.text.Editable; import android.text.TextWatcher; @@ -34,6 +36,7 @@ import net.osmand.plus.IconsCache; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.views.OsmandMapTileView; import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory; import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarController; import net.osmand.plus.widgets.IconPopupMenu; @@ -46,6 +49,7 @@ import java.util.LinkedList; import java.util.Locale; import static net.osmand.plus.GPXUtilities.GPXFile; +import static net.osmand.plus.OsmandSettings.MIDDLE_TOP_CONSTANT; import static net.osmand.plus.helpers.GpxImportHelper.GPX_SUFFIX; public class MeasurementToolFragment extends Fragment { @@ -53,12 +57,14 @@ public class MeasurementToolFragment extends Fragment { public static final String TAG = "MeasurementToolFragment"; private MeasurementToolBarController toolBarController; + private MeasurementToolAdapter adapter; private TextView distanceTv; private TextView pointsTv; private String pointsSt; private boolean wasCollapseButtonVisible; private boolean pointsDetailsOpened; + private int previousMapPosition; @Nullable @Override @@ -109,10 +115,13 @@ public class MeasurementToolFragment extends Fragment { if (measurementLayer.undoPointOnClick()) { enable(undoBtn); } else { - disable(undoBtn); + disable(undoBtn, upDownBtn); + downBtnOnClick(mainView, iconsCache.getThemedIcon(R.drawable.ic_action_arrow_up)); } + adapter.notifyDataSetChanged(); enable(redoBtn); updateText(); + mapActivity.refreshMap(); } }); @@ -125,8 +134,10 @@ public class MeasurementToolFragment extends Fragment { } else { disable(redoBtn); } - enable(undoBtn); + adapter.notifyDataSetChanged(); + enable(undoBtn, upDownBtn); updateText(); + mapActivity.refreshMap(); } }); @@ -137,6 +148,7 @@ public class MeasurementToolFragment extends Fragment { enable(undoBtn, upDownBtn); disable(redoBtn); updateText(); + adapter.notifyDataSetChanged(); } }); @@ -188,6 +200,32 @@ public class MeasurementToolFragment extends Fragment { mapActivity.showTopToolbar(toolBarController); } + adapter = new MeasurementToolAdapter(getMapActivity(), measurementLayer.getMeasurementPoints()); + final RecyclerView rv = mainView.findViewById(R.id.measure_points_recycler_view); + adapter.setRemovePointListener(new MeasurementToolAdapter.RemovePointListener() { + @Override + public void onPointRemove() { + adapter.notifyDataSetChanged(); + measurementLayer.resetCachePoints(); + disable(redoBtn); + updateText(); + mapActivity.refreshMap(); + if (measurementLayer.getPointsCount() < 1) { + downBtnOnClick(mainView, iconsCache.getThemedIcon(R.drawable.ic_action_arrow_up)); + disable(upDownBtn, undoBtn); + } + } + }); + adapter.setItemClickListener(new MeasurementToolAdapter.ItemClickListener() { + @Override + public void onItemClick(View view) { + int pos = rv.indexOfChild(view); + measurementLayer.moveMapToPoint(pos); + } + }); + rv.setLayoutManager(new LinearLayoutManager(getContext())); + rv.setAdapter(adapter); + return view; } @@ -195,12 +233,28 @@ public class MeasurementToolFragment extends Fragment { pointsDetailsOpened = true; view.findViewById(R.id.points_list_container).setVisibility(View.VISIBLE); ((ImageButton) view.findViewById(R.id.up_down_button)).setImageDrawable(icon); + MapActivity mapActivity = getMapActivity(); + if (mapActivity != null) { + OsmandMapTileView tileView = mapActivity.getMapView(); + previousMapPosition = tileView.getMapPosition(); + tileView.setMapPosition(MIDDLE_TOP_CONSTANT); + mapActivity.refreshMap(); + } } private void downBtnOnClick(View view, Drawable icon) { pointsDetailsOpened = false; view.findViewById(R.id.points_list_container).setVisibility(View.GONE); ((ImageButton) view.findViewById(R.id.up_down_button)).setImageDrawable(icon); + setPreviousMapPosition(); + } + + private void setPreviousMapPosition() { + MapActivity mapActivity = getMapActivity(); + if (mapActivity != null) { + mapActivity.getMapView().setMapPosition(previousMapPosition); + mapActivity.refreshMap(); + } } private void saveAsGpxOnClick(MapActivity mapActivity) { @@ -336,6 +390,11 @@ public class MeasurementToolFragment extends Fragment { public void onDestroyView() { super.onDestroyView(); exitMeasurementMode(); + adapter.setRemovePointListener(null); + adapter.setItemClickListener(null); + if (pointsDetailsOpened) { + setPreviousMapPosition(); + } } private MapActivity getMapActivity() { diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java index 1ea5208cc6..722b59b5b2 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java @@ -28,18 +28,18 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL private OsmandMapTileView view; private boolean inMeasurementMode; - private LinkedList measurementPoints = new LinkedList<>(); + private final LinkedList measurementPoints = new LinkedList<>(); private LinkedList cacheMeasurementPoints = new LinkedList<>(); private Bitmap centerIconDay; private Bitmap centerIconNight; private Bitmap pointIcon; private Paint bitmapPaint; - private RenderingLineAttributes lineAttrs = new RenderingLineAttributes("rulerLine"); - private Path path = new Path(); + private final RenderingLineAttributes lineAttrs = new RenderingLineAttributes("measureDistanceLine"); + private final Path path = new Path(); private int marginX; private int marginY; - private TIntArrayList tx = new TIntArrayList(); - private TIntArrayList ty = new TIntArrayList(); + private final TIntArrayList tx = new TIntArrayList(); + private final TIntArrayList ty = new TIntArrayList(); @Override public void initLayer(OsmandMapTileView view) { @@ -70,7 +70,7 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL return measurementPoints.size(); } - public LinkedList getMeasurementPoints() { + LinkedList getMeasurementPoints() { return measurementPoints; } @@ -141,6 +141,10 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL canvas.rotate(tb.getRotate(), center.x, center.y); } + void resetCachePoints() { + cacheMeasurementPoints = new LinkedList<>(measurementPoints); + } + void addPointOnClick() { RotatedTileBox tb = view.getCurrentRotatedTileBox(); LatLon l = tb.getLatLonFromPixel(tb.getCenterPixelX(), tb.getCenterPixelY()); @@ -154,7 +158,7 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL } else { measurementPoints.add(pt); } - cacheMeasurementPoints = new LinkedList<>(measurementPoints); + resetCachePoints(); view.refreshMap(); } @@ -174,6 +178,11 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL return cacheMeasurementPoints.size() > measurementPoints.size(); } + void moveMapToPoint(int pos) { + WptPt pt = measurementPoints.get(pos); + view.getAnimatedDraggingThread().startMoving(pt.getLatitude(), pt.getLongitude(), view.getZoom(), true); + } + @Override public void destroyLayer() { diff --git a/OsmAnd/src/net/osmand/plus/views/MapQuickActionLayer.java b/OsmAnd/src/net/osmand/plus/views/MapQuickActionLayer.java index c5365d41ff..f5129c680a 100644 --- a/OsmAnd/src/net/osmand/plus/views/MapQuickActionLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/MapQuickActionLayer.java @@ -218,7 +218,7 @@ public class MapQuickActionLayer extends OsmandMapLayer implements QuickActionRe private void enterMovingMode(RotatedTileBox tileBox) { previousMapPosition = view.getMapPosition(); - view.setMapPosition(OsmandSettings.MIDDLE_CONSTANT); + view.setMapPosition(OsmandSettings.MIDDLE_BOTTOM_CONSTANT); MapContextMenu menu = mapActivity.getContextMenu(); LatLon ll = menu.isActive() && tileBox.containsLatLon(menu.getLatLon()) ? menu.getLatLon() : tileBox.getCenterLatLon(); diff --git a/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java b/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java index 2553ffaaad..4ddb967c7d 100644 --- a/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java +++ b/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java @@ -578,8 +578,10 @@ public class OsmandMapTileView implements IMapDownloaderCallback { final float ratioy; if (mapPosition == OsmandSettings.BOTTOM_CONSTANT) { ratioy = 0.85f; - } else if (mapPosition == OsmandSettings.MIDDLE_CONSTANT) { + } else if (mapPosition == OsmandSettings.MIDDLE_BOTTOM_CONSTANT) { ratioy = 0.70f; + } else if (mapPosition == OsmandSettings.MIDDLE_TOP_CONSTANT) { + ratioy = 0.25f; } else { ratioy = 0.5f; }