groups) {
StringBuilder html = new StringBuilder();
html.append("My Favorites
");
for (FavoriteGroup group : groups) {
- html.append(""+group.name+"
");
- for(FavouritePoint fp : group.points) {
- String url = "geo:"+((float)fp.getLatitude())+","+((float)fp.getLongitude())+"?m="+fp.getName();
+ html.append("" + group.name + "
");
+ for (FavouritePoint fp : group.points) {
+ String url = "geo:" + ((float) fp.getLatitude()) + "," + ((float) fp.getLongitude()) + "?m=" + fp.getName();
html.append("" + fp.getName() + " - " + "geo:"
+ ((float) fp.getLatitude()) + "," + ((float) fp.getLongitude()) + "
");
-
- if(!Algorithms.isEmpty(fp.getDescription())) {
+
+ if (!Algorithms.isEmpty(fp.getDescription())) {
html.append(": " + fp.getDescription());
}
html.append("
");
@@ -521,7 +565,7 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment {
@Override
protected void onPostExecute(Void res) {
hideProgressBar();
- if(getActivity() == null) {
+ if (getActivity() == null) {
// user quit application
return;
}
@@ -763,13 +807,17 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment {
if (ch.isChecked()) {
groupsToDelete.add(model);
if (fvs != null) {
- favoritesSelected.addAll(fvs);
+ Set set = favoritesSelected.get(model.name);
+ if (set != null) {
+ set.addAll(model.points);
+ } else {
+ set = new LinkedHashSet<>(model.points);
+ favoritesSelected.put(model.name, set);
+ }
}
} else {
groupsToDelete.remove(model);
- if (fvs != null) {
- favoritesSelected.removeAll(fvs);
- }
+ favoritesSelected.remove(model.name);
}
favouritesAdapter.notifyDataSetInvalidated();
updateSelectionMode(actionMode);
@@ -820,6 +868,7 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment {
ImageView icon = (ImageView) row.findViewById(R.id.favourite_icon);
final FavouritePoint model = getChild(groupPosition, childPosition);
+ final FavoriteGroup group = getGroup(groupPosition);
boolean visible = model.isVisible();
row.setTag(model);
@@ -864,16 +913,26 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment {
final CheckBox ch = (CheckBox) row.findViewById(R.id.toggle_item);
if (selectionMode) {
ch.setVisibility(View.VISIBLE);
- ch.setChecked(favoritesSelected.contains(model));
+ ch.setChecked(favoritesSelected.get(group.name) != null && favoritesSelected.get(group.name).contains(model));
row.findViewById(R.id.favourite_icon).setVisibility(View.GONE);
ch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (ch.isChecked()) {
- favoritesSelected.add(model);
+ Set set = favoritesSelected.get(group.name);
+ if (set != null) {
+ set.add(model);
+ } else {
+ set = new LinkedHashSet<>();
+ set.add(model);
+ favoritesSelected.put(group.name, set);
+ }
} else {
- favoritesSelected.remove(model);
+ Set set = favoritesSelected.get(group.name);
+ if (set != null) {
+ set.remove(model);
+ }
}
updateSelectionMode(actionMode);
}
diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
index 8187f17f61..92f0a4aa9a 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
@@ -614,18 +614,6 @@ public class MapActivityActions implements DialogProvider {
}).createItem());
if (settings.USE_MAP_MARKERS.get()) {
optionsMenuHelper.addItem(new ItemBuilder().setTitleId(R.string.map_markers, mapActivity)
- .setIcon(R.drawable.ic_action_flag_dark)
- .setListener(new ContextMenuAdapter.ItemClickListener() {
- @Override
- public boolean onContextMenuClick(ArrayAdapter adapter, int itemId, int pos, boolean isChecked) {
- app.logEvent(mapActivity, "drawer_markers_open");
- MapActivity.clearPrevActivityIntent();
- mapActivity.getDashboard().setDashboardVisibility(true, DashboardType.MAP_MARKERS);
- return false;
- }
- }).createItem());
-
- optionsMenuHelper.addItem(new ItemBuilder().setTitle("New map markers")
.setIcon(R.drawable.ic_action_flag_dark)
.setListener(new ContextMenuAdapter.ItemClickListener() {
@Override
diff --git a/OsmAnd/src/net/osmand/plus/activities/SettingsNavigationActivity.java b/OsmAnd/src/net/osmand/plus/activities/SettingsNavigationActivity.java
index eda15c2989..7978fe9b15 100644
--- a/OsmAnd/src/net/osmand/plus/activities/SettingsNavigationActivity.java
+++ b/OsmAnd/src/net/osmand/plus/activities/SettingsNavigationActivity.java
@@ -202,12 +202,14 @@ public class SettingsNavigationActivity extends SettingsBaseActivity {
speedNames[i] = speedLimitsKm[i] + " " + getString(R.string.km_h);
}
registerListPreference(settings.SPEED_LIMIT_EXCEED, screen, speedNames, speedLimitsKm);
+ registerListPreference(settings.SWITCH_MAP_DIRECTION_TO_COMPASS, screen, speedNames, speedLimitsKm);
} else {
String[] speedNames = new String[speedLimitsKm.length];
for (int i =0; i 1) {
mapView.setRotate(-val);
}
@@ -201,13 +203,17 @@ public class MapViewTrackingUtilities implements OsmAndLocationListener, IMapLoc
zoom = autozoom(location);
}
int currentMapRotation = settings.ROTATE_MAP.get();
+ float speedForDirectionOfMovement = settings.SWITCH_MAP_DIRECTION_TO_COMPASS.get();
+ boolean smallSpeedForDirectionOfMovement = speedForDirectionOfMovement != 0 && isSmallSpeedForDirectionOfMovement(location, speedForDirectionOfMovement);
boolean smallSpeedForCompass = isSmallSpeedForCompass(location);
boolean smallSpeedForAnimation = isSmallSpeedForAnimation(location);
// boolean virtualBearing = fMode && settings.SNAP_TO_ROAD.get();
showViewAngle = (!location.hasBearing() || smallSpeedForCompass) && (tb != null &&
tb.containsLatLon(location.getLatitude(), location.getLongitude()));
if (currentMapRotation == OsmandSettings.ROTATE_MAP_BEARING) {
- if (location.hasBearing() && !smallSpeedForCompass) {
+ if (smallSpeedForDirectionOfMovement) {
+ showViewAngle = routePlanningMode;
+ } else if (location.hasBearing() && !smallSpeedForCompass) {
// special case when bearing equals to zero (we don't change anything)
if (location.getBearing() != 0f) {
rotation = -location.getBearing();
@@ -216,7 +222,7 @@ public class MapViewTrackingUtilities implements OsmAndLocationListener, IMapLoc
} else if(currentMapRotation == OsmandSettings.ROTATE_MAP_COMPASS) {
showViewAngle = routePlanningMode; // disable compass rotation in that mode
}
- registerUnregisterSensor(location);
+ registerUnregisterSensor(location, smallSpeedForDirectionOfMovement);
if (settings.ANIMATE_MY_LOCATION.get() && !smallSpeedForAnimation && !movingToMyLocation &&
settings.WAKE_ON_VOICE_INT.get() == 0) {
mapView.getAnimatedDraggingThread().startMoving(
@@ -233,7 +239,7 @@ public class MapViewTrackingUtilities implements OsmAndLocationListener, IMapLoc
} else if(location != null) {
showViewAngle = (!location.hasBearing() || isSmallSpeedForCompass(location)) && (tb != null &&
tb.containsLatLon(location.getLatitude(), location.getLongitude()));
- registerUnregisterSensor(location);
+ registerUnregisterSensor(location, false);
}
RoutingHelper routingHelper = app.getRoutingHelper();
followingMode = routingHelper.isFollowingMode();
@@ -252,6 +258,10 @@ public class MapViewTrackingUtilities implements OsmAndLocationListener, IMapLoc
}
}
+ public static boolean isSmallSpeedForDirectionOfMovement(Location location, float speedToDirectionOfMovement) {
+ return !location.hasSpeed() || location.getSpeed() < speedToDirectionOfMovement;
+ }
+
public static boolean isSmallSpeedForCompass(Location location) {
return !location.hasSpeed() || location.getSpeed() < 0.5;
}
@@ -285,14 +295,15 @@ public class MapViewTrackingUtilities implements OsmAndLocationListener, IMapLoc
&& !settings.CENTER_POSITION_ON_MAP.get() ?
OsmandSettings.BOTTOM_CONSTANT : OsmandSettings.CENTER_CONSTANT);
}
- registerUnregisterSensor(app.getLocationProvider().getLastKnownLocation());
+ registerUnregisterSensor(app.getLocationProvider().getLastKnownLocation(), false);
}
- private void registerUnregisterSensor(net.osmand.Location location) {
+ private void registerUnregisterSensor(net.osmand.Location location, boolean smallSpeedForDirectionOfMovement) {
int currentMapRotation = settings.ROTATE_MAP.get();
boolean registerCompassListener = ((showViewAngle || contextMenu != null) && location != null)
- || (currentMapRotation == OsmandSettings.ROTATE_MAP_COMPASS && !routePlanningMode);
+ || (currentMapRotation == OsmandSettings.ROTATE_MAP_COMPASS && !routePlanningMode)
+ || (currentMapRotation == OsmandSettings.ROTATE_MAP_BEARING && smallSpeedForDirectionOfMovement);
// show point view only if gps enabled
if(sensorRegistered != registerCompassListener) {
app.getLocationProvider().registerOrUnregisterCompassListener(registerCompassListener);
diff --git a/OsmAnd/src/net/osmand/plus/dashboard/DashLocationFragment.java b/OsmAnd/src/net/osmand/plus/dashboard/DashLocationFragment.java
index 3f13b90922..474a6638bc 100644
--- a/OsmAnd/src/net/osmand/plus/dashboard/DashLocationFragment.java
+++ b/OsmAnd/src/net/osmand/plus/dashboard/DashLocationFragment.java
@@ -120,6 +120,12 @@ public abstract class DashLocationFragment extends DashBaseFragment {
public static void updateLocationView(boolean useCenter, LatLon fromLoc, Float h,
ImageView arrow, int arrowResId, TextView txt, LatLon toLoc,
int screenOrientation, OsmandApplication app, Context ctx, boolean paint) {
+ updateLocationView(useCenter, fromLoc, h, arrow, arrowResId, 0, txt, toLoc, screenOrientation, app, ctx, paint);
+ }
+
+ public static void updateLocationView(boolean useCenter, LatLon fromLoc, Float h,
+ ImageView arrow, int arrowResId, int color, TextView txt, LatLon toLoc,
+ int screenOrientation, OsmandApplication app, Context ctx, boolean paint) {
float[] mes = new float[2];
if (fromLoc != null && toLoc != null) {
Location.distanceBetween(toLoc.getLatitude(), toLoc.getLongitude(), fromLoc.getLatitude(), fromLoc.getLongitude(), mes);
@@ -136,7 +142,7 @@ public abstract class DashLocationFragment extends DashBaseFragment {
} else {
dd = (DirectionDrawable) arrow.getDrawable();
}
- dd.setImage(arrowResId, useCenter ? R.color.color_distance : R.color.color_myloc_distance);
+ dd.setImage(arrowResId, color == 0 ? useCenter ? R.color.color_distance : R.color.color_myloc_distance : color);
if (fromLoc == null || h == null || toLoc == null) {
dd.setAngle(0);
} else {
diff --git a/OsmAnd/src/net/osmand/plus/helpers/MapMarkerDialogHelper.java b/OsmAnd/src/net/osmand/plus/helpers/MapMarkerDialogHelper.java
index 35823dfcba..4b88b2089b 100644
--- a/OsmAnd/src/net/osmand/plus/helpers/MapMarkerDialogHelper.java
+++ b/OsmAnd/src/net/osmand/plus/helpers/MapMarkerDialogHelper.java
@@ -354,7 +354,7 @@ public class MapMarkerDialogHelper {
@Override
public void onClick(DialogInterface dialog, int which) {
listAdapter.notifyDataSetInvalidated();
- markersHelper.removeActiveMarkers();
+ markersHelper.moveAllActiveMarkersToHistory();
if (markersHelper.getMapMarkersHistory().size() == 0) {
mapActivity.getDashboard().hideDashboard();
} else if (helperCallbacks != null) {
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/MapMarkerMenuController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/MapMarkerMenuController.java
index 4e0bf8570f..875b8f0fdb 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/MapMarkerMenuController.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/MapMarkerMenuController.java
@@ -10,7 +10,6 @@ import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.helpers.MapMarkerDialogHelper;
import net.osmand.plus.mapcontextmenu.MenuBuilder;
import net.osmand.plus.mapcontextmenu.MenuController;
-import net.osmand.plus.mapillary.MapillaryPlugin;
import net.osmand.util.Algorithms;
public class MapMarkerMenuController extends MenuController {
@@ -25,8 +24,7 @@ public class MapMarkerMenuController extends MenuController {
leftTitleButtonController = new TitleButtonController() {
@Override
public void buttonPressed() {
- markersHelper.removeMapMarker(getMapMarker().index);
- markersHelper.addMapMarkerHistory(getMapMarker());
+ markersHelper.moveMapMarkerToHistory(getMapMarker());
getMapActivity().getContextMenu().close();
}
};
diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/HistoryMarkerMenuBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/HistoryMarkerMenuBottomSheetDialogFragment.java
new file mode 100644
index 0000000000..6d751f9138
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/mapmarkers/HistoryMarkerMenuBottomSheetDialogFragment.java
@@ -0,0 +1,149 @@
+package net.osmand.plus.mapmarkers;
+
+import android.os.Build;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.view.ContextThemeWrapper;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import net.osmand.AndroidUtils;
+import net.osmand.plus.MapMarkersHelper.MapMarker;
+import net.osmand.plus.R;
+import net.osmand.plus.base.BottomSheetDialogFragment;
+import net.osmand.plus.helpers.AndroidUiHelper;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+public class HistoryMarkerMenuBottomSheetDialogFragment extends BottomSheetDialogFragment {
+
+ public final static String TAG = "HistoryMarkerMenuBottomSheetDialogFragment";
+
+ public static final String MARKER_POSITION = "marker_position";
+ public static final String MARKER_NAME = "marker_name";
+ public static final String MARKER_COLOR_INDEX = "marker_color_index";
+ public static final String MARKER_VISITED_DATE = "marker_visited_date";
+
+ private HistoryMarkerMenuFragmentListener listener;
+ private boolean portrait;
+
+ public void setListener(HistoryMarkerMenuFragmentListener listener) {
+ this.listener = listener;
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ portrait = AndroidUiHelper.isOrientationPortrait(getActivity());
+ boolean nightMode = getMyApplication().getDaynightHelper().isNightModeForMapControls();
+ final int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme;
+
+ final View mainView = View.inflate(new ContextThemeWrapper(getContext(), themeRes), R.layout.fragment_marker_history_bottom_sheet_dialog, container);
+ if (portrait) {
+ AndroidUtils.setBackground(getActivity(), mainView, nightMode, R.drawable.bg_bottom_menu_light, R.drawable.bg_bottom_menu_dark);
+ }
+
+ Bundle arguments = getArguments();
+ if (arguments != null) {
+ final int pos = arguments.getInt(MARKER_POSITION);
+ String markerName = arguments.getString(MARKER_NAME);
+ int markerColorIndex = arguments.getInt(MARKER_COLOR_INDEX);
+ long markerVisitedDate = arguments.getLong(MARKER_VISITED_DATE);
+ ((TextView) mainView.findViewById(R.id.map_marker_title)).setText(markerName);
+ ((ImageView) mainView.findViewById(R.id.map_marker_icon)).setImageDrawable(getIcon(R.drawable.ic_action_flag_dark, MapMarker.getColorId(markerColorIndex)));
+ ((TextView) mainView.findViewById(R.id.map_marker_passed_info)).setText(getString(R.string.passed, new SimpleDateFormat("MMM dd", Locale.getDefault()).format(new Date(markerVisitedDate))));
+
+ mainView.findViewById(R.id.make_active_row).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (listener != null) {
+ listener.onMakeMarkerActive(pos);
+ }
+ dismiss();
+ }
+ });
+ mainView.findViewById(R.id.delete_row).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (listener != null) {
+ listener.onDeleteMarker(pos);
+ }
+ dismiss();
+ }
+ });
+ }
+
+ ((ImageView) mainView.findViewById(R.id.make_active_icon)).setImageDrawable(getContentIcon(R.drawable.ic_action_reset_to_default_dark));
+ ((ImageView) mainView.findViewById(R.id.delete_icon)).setImageDrawable(getContentIcon(R.drawable.ic_action_delete_dark));
+
+ mainView.findViewById(R.id.cancel_row).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ dismiss();
+ }
+ });
+
+ final int screenHeight = AndroidUtils.getScreenHeight(getActivity());
+ final int statusBarHeight = AndroidUtils.getStatusBarHeight(getActivity());
+ final int navBarHeight = AndroidUtils.getNavBarHeight(getActivity());
+
+ mainView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ final View scrollView = mainView.findViewById(R.id.history_marker_scroll_view);
+ int scrollViewHeight = scrollView.getHeight();
+ int dividerHeight = AndroidUtils.dpToPx(getContext(), 1);
+ int cancelButtonHeight = getContext().getResources().getDimensionPixelSize(R.dimen.bottom_sheet_cancel_button_height);
+ int spaceForScrollView = screenHeight - statusBarHeight - navBarHeight - dividerHeight - cancelButtonHeight;
+ if (scrollViewHeight > spaceForScrollView) {
+ scrollView.getLayoutParams().height = spaceForScrollView;
+ scrollView.requestLayout();
+ }
+
+ if (!portrait) {
+ if (screenHeight - statusBarHeight - mainView.getHeight()
+ >= AndroidUtils.dpToPx(getActivity(), 8)) {
+ AndroidUtils.setBackground(getActivity(), mainView, false,
+ R.drawable.bg_bottom_sheet_topsides_landscape_light, R.drawable.bg_bottom_sheet_topsides_landscape_dark);
+ } else {
+ AndroidUtils.setBackground(getActivity(), mainView, false,
+ R.drawable.bg_bottom_sheet_sides_landscape_light, R.drawable.bg_bottom_sheet_sides_landscape_dark);
+ }
+ }
+
+ ViewTreeObserver obs = mainView.getViewTreeObserver();
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ obs.removeOnGlobalLayoutListener(this);
+ } else {
+ obs.removeGlobalOnLayoutListener(this);
+ }
+ }
+ });
+
+ return mainView;
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ if (!portrait) {
+ final Window window = getDialog().getWindow();
+ WindowManager.LayoutParams params = window.getAttributes();
+ params.width = getActivity().getResources().getDimensionPixelSize(R.dimen.landscape_bottom_sheet_dialog_fragment_width);
+ window.setAttributes(params);
+ }
+ }
+
+ interface HistoryMarkerMenuFragmentListener {
+ void onMakeMarkerActive(int pos);
+ void onDeleteMarker(int pos);
+ }
+}
diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersActiveFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersActiveFragment.java
index 3b2fb3d96d..ca0af55967 100644
--- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersActiveFragment.java
+++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersActiveFragment.java
@@ -49,7 +49,7 @@ public class MapMarkersActiveFragment extends Fragment implements OsmAndCompassL
@Override
public void onItemClick(View view) {
- int pos = recyclerView.indexOfChild(view);
+ int pos = recyclerView.getChildAdapterPosition(view);
MapMarker marker = adapter.getItem(pos);
mapActivity.getMyApplication().getSettings().setMapLocationToShow(marker.getLatitude(), marker.getLongitude(),
15, marker.getPointDescription(mapActivity), true, marker);
@@ -67,7 +67,9 @@ public class MapMarkersActiveFragment extends Fragment implements OsmAndCompassL
public void onDragEnded(RecyclerView.ViewHolder holder) {
toPosition = holder.getAdapterPosition();
if (toPosition >= 0 && fromPosition >= 0 && toPosition != fromPosition) {
- mapActivity.getMyApplication().getMapMarkersHelper().saveMapMarkers(adapter.getItems(), null);
+ hideSnackbar();
+ mapActivity.getMyApplication().getMapMarkersHelper().checkAndFixActiveMarkersOrderIfNeeded();
+ adapter.notifyDataSetChanged();
}
}
});
@@ -121,15 +123,27 @@ public class MapMarkersActiveFragment extends Fragment implements OsmAndCompassL
return null;
}
+ void setShowDirectionEnabled(boolean showDirectionEnabled) {
+ if (adapter != null) {
+ adapter.setShowDirectionEnabled(showDirectionEnabled);
+ }
+ }
+
void updateAdapter() {
if (adapter != null) {
adapter.notifyDataSetChanged();
}
}
+ void hideSnackbar() {
+ if (adapter != null) {
+ adapter.hideSnackbar();
+ }
+ }
+
private void updateLocationUi() {
final MapActivity mapActivity = (MapActivity) getActivity();
- if (mapActivity != null) {
+ if (mapActivity != null && adapter != null) {
mapActivity.getMyApplication().runInUIThread(new Runnable() {
@Override
public void run() {
@@ -141,7 +155,7 @@ public class MapMarkersActiveFragment extends Fragment implements OsmAndCompassL
adapter.setUseCenter(useCenter);
adapter.setLocation(useCenter ? mapActivity.getMapLocation() : new LatLon(location.getLatitude(), location.getLongitude()));
- adapter.setHeading(useCenter ? -mapActivity.getMapRotate() : heading);
+ adapter.setHeading(useCenter ? -mapActivity.getMapRotate() : heading != null ? heading : 99);
adapter.notifyDataSetChanged();
}
});
diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDbHelper.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDbHelper.java
new file mode 100644
index 0000000000..ba49cfd77d
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDbHelper.java
@@ -0,0 +1,509 @@
+package net.osmand.plus.mapmarkers;
+
+import android.support.annotation.Nullable;
+
+import net.osmand.data.LatLon;
+import net.osmand.data.PointDescription;
+import net.osmand.plus.MapMarkersHelper.MapMarker;
+import net.osmand.plus.MapMarkersHelper.MarkersSyncGroup;
+import net.osmand.plus.OsmandApplication;
+import net.osmand.plus.OsmandSettings;
+import net.osmand.plus.api.SQLiteAPI.SQLiteConnection;
+import net.osmand.plus.api.SQLiteAPI.SQLiteCursor;
+import net.osmand.plus.helpers.SearchHistoryHelper;
+
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+
+public class MapMarkersDbHelper {
+
+ private static final int DB_VERSION = 2;
+ public static final String DB_NAME = "map_markers_db";
+
+ private static final String MARKERS_TABLE_NAME = "map_markers";
+ private static final String MARKERS_COL_ID = "marker_id";
+ private static final String MARKERS_COL_LAT = "marker_lat";
+ private static final String MARKERS_COL_LON = "marker_lon";
+ private static final String MARKERS_COL_DESCRIPTION = "marker_description";
+ private static final String MARKERS_COL_ACTIVE = "marker_active";
+ private static final String MARKERS_COL_ADDED = "marker_added";
+ private static final String MARKERS_COL_VISITED = "marker_visited";
+ private static final String MARKERS_COL_GROUP_NAME = "group_name";
+ private static final String MARKERS_COL_GROUP_KEY = "group_key";
+ private static final String MARKERS_COL_COLOR = "marker_color";
+ private static final String MARKERS_COL_NEXT_KEY = "marker_next_key";
+
+ private static final String MARKERS_TABLE_CREATE = "CREATE TABLE IF NOT EXISTS " +
+ MARKERS_TABLE_NAME + " (" +
+ MARKERS_COL_ID + " TEXT PRIMARY KEY, " +
+ MARKERS_COL_LAT + " double, " +
+ MARKERS_COL_LON + " double, " +
+ MARKERS_COL_DESCRIPTION + " TEXT, " +
+ MARKERS_COL_ACTIVE + " int, " + // 1 = true, 0 = false
+ MARKERS_COL_ADDED + " long, " +
+ MARKERS_COL_VISITED + " long, " +
+ MARKERS_COL_GROUP_NAME + " TEXT, " +
+ MARKERS_COL_GROUP_KEY + " TEXT, " +
+ MARKERS_COL_COLOR + " int, " +
+ MARKERS_COL_NEXT_KEY + " TEXT);";
+
+ private static final String MARKERS_TABLE_SELECT = "SELECT " +
+ MARKERS_COL_ID + ", " +
+ MARKERS_COL_LAT + ", " +
+ MARKERS_COL_LON + ", " +
+ MARKERS_COL_DESCRIPTION + ", " +
+ MARKERS_COL_ACTIVE + ", " +
+ MARKERS_COL_ADDED + ", " +
+ MARKERS_COL_VISITED + ", " +
+ MARKERS_COL_GROUP_NAME + ", " +
+ MARKERS_COL_GROUP_KEY + ", " +
+ MARKERS_COL_COLOR + ", " +
+ MARKERS_COL_NEXT_KEY +
+ " FROM " + MARKERS_TABLE_NAME;
+
+ private static final String GROUPS_TABLE_NAME = "map_markers_groups";
+ private static final String GROUPS_COL_ID = "group_id";
+ private static final String GROUPS_COL_NAME = "group_name";
+ private static final String GROUPS_COL_TYPE = "group_type";
+
+ private static final String GROUPS_TABLE_CREATE = "CREATE TABLE IF NOT EXISTS " +
+ GROUPS_TABLE_NAME + " (" +
+ GROUPS_COL_ID + " TEXT PRIMARY KEY, " +
+ GROUPS_COL_NAME + " TEXT, " +
+ GROUPS_COL_TYPE + " int);";
+
+ private static final String GROUPS_TABLE_SELECT = "SELECT " +
+ GROUPS_COL_ID + ", " +
+ GROUPS_COL_NAME + ", " +
+ GROUPS_COL_TYPE +
+ " FROM " + GROUPS_TABLE_NAME;
+
+ public static final String TAIL_NEXT_VALUE = "tail_next";
+ public static final String HISTORY_NEXT_VALUE = "history_next";
+
+ private final OsmandApplication context;
+
+ public MapMarkersDbHelper(OsmandApplication context) {
+ this.context = context;
+ }
+
+ private SQLiteConnection openConnection(boolean readonly) {
+ SQLiteConnection conn = context.getSQLiteAPI().getOrCreateDatabase(DB_NAME, readonly);
+ int version = conn.getVersion();
+ if (version == 0 || DB_VERSION != version) {
+ if (readonly) {
+ conn.close();
+ conn = context.getSQLiteAPI().getOrCreateDatabase(DB_NAME, false);
+ }
+ version = conn.getVersion();
+ conn.setVersion(DB_VERSION);
+ if (version == 0) {
+ onCreate(conn);
+ } else {
+ onUpgrade(conn, version, DB_VERSION);
+ }
+ }
+ return conn;
+ }
+
+ private void onCreate(SQLiteConnection db) {
+ db.execSQL(MARKERS_TABLE_CREATE);
+ db.execSQL(GROUPS_TABLE_CREATE);
+ saveExistingMarkersToDb();
+ }
+
+ private void onUpgrade(SQLiteConnection db, int oldVersion, int newVersion) {
+
+ }
+
+ private void saveExistingMarkersToDb() {
+ OsmandSettings settings = context.getSettings();
+
+ List ips = settings.getMapMarkersPoints();
+ List desc = settings.getMapMarkersPointDescriptions(ips.size());
+ List colors = settings.getMapMarkersColors(ips.size());
+ int colorIndex = 0;
+ for (int i = 0; i < ips.size(); i++) {
+ if (colors.size() > i) {
+ colorIndex = colors.get(i);
+ }
+ MapMarker marker = new MapMarker(ips.get(i), PointDescription.deserializeFromString(desc.get(i), ips.get(i)),
+ colorIndex, false, i);
+ marker.history = false;
+ addMarker(marker, true);
+ }
+
+ ips = settings.getMapMarkersHistoryPoints();
+ desc = settings.getMapMarkersHistoryPointDescriptions(ips.size());
+ colors = settings.getMapMarkersHistoryColors(ips.size());
+ for (int i = 0; i < ips.size(); i++) {
+ if (colors.size() > i) {
+ colorIndex = colors.get(i);
+ }
+ MapMarker marker = new MapMarker(ips.get(i), PointDescription.deserializeFromString(desc.get(i), ips.get(i)),
+ colorIndex, false, i);
+ marker.history = true;
+ addMarker(marker, true);
+ }
+ }
+
+ public void addGroup(String id, String name, int type) {
+ SQLiteConnection db = openConnection(false);
+ if (db != null) {
+ try {
+ db.execSQL("INSERT INTO " + GROUPS_TABLE_NAME + " VALUES (?, ?, ?)", new Object[]{id, name, type});
+ } finally {
+ db.close();
+ }
+ }
+ }
+
+ public List getAllGroups() {
+ List res = new LinkedList<>();
+ SQLiteConnection db = openConnection(true);
+ if (db != null) {
+ try {
+ SQLiteCursor query = db.rawQuery(GROUPS_TABLE_SELECT, null);
+ if (query.moveToFirst()) {
+ do {
+ res.add(readSyncGroup(query));
+ } while (query.moveToNext());
+ }
+ query.close();
+ } finally {
+ db.close();
+ }
+ }
+ return res;
+ }
+
+ @Nullable
+ public MarkersSyncGroup getGroup(String id) {
+ MarkersSyncGroup res = null;
+ SQLiteConnection db = openConnection(true);
+ if (db != null) {
+ try {
+ SQLiteCursor query = db.rawQuery(GROUPS_TABLE_SELECT + " WHERE " + GROUPS_COL_ID + " = ?", new String[]{id});
+ if (query.moveToFirst()) {
+ res = readSyncGroup(query);
+ }
+ query.close();
+ } finally {
+ db.close();
+ }
+ }
+ return res;
+ }
+
+ private MarkersSyncGroup readSyncGroup(SQLiteCursor query) {
+ String id = query.getString(0);
+ String name = query.getString(1);
+ int type = query.getInt(2);
+
+ return new MarkersSyncGroup(id, name, type);
+ }
+
+ public void removeMarkersSyncGroup(String id) {
+ SQLiteConnection db = openConnection(true);
+ if (db != null) {
+ try {
+ db.execSQL("DELETE FROM " + GROUPS_TABLE_NAME + " WHERE " + GROUPS_COL_ID + " = ?", new Object[]{id});
+ } finally {
+ db.close();
+ }
+ }
+ }
+
+ public void removeActiveMarkersFromSyncGroup(String syncGroupId) {
+ SQLiteConnection db = openConnection(true);
+ if (db != null) {
+ try {
+ db.execSQL("DELETE FROM " + MARKERS_TABLE_NAME +
+ " WHERE " + MARKERS_COL_GROUP_KEY + " = ?" +
+ " AND " + MARKERS_COL_ACTIVE + " = ?",
+ new Object[]{syncGroupId, 1});
+ } finally {
+ db.close();
+ }
+ }
+ }
+
+ public void addMarker(MapMarker marker) {
+ addMarker(marker, false);
+ }
+
+ private void addMarker(MapMarker marker, boolean saveExisting) {
+ SQLiteConnection db = openConnection(false);
+ if (db != null) {
+ try {
+ insertLast(db, marker, saveExisting);
+ } finally {
+ db.close();
+ }
+ }
+ }
+
+ private void insertLast(SQLiteConnection db, MapMarker marker, boolean saveExisting) {
+ long currentTime;
+ if (saveExisting) {
+ Calendar cal = Calendar.getInstance();
+ cal.add(Calendar.MONTH, -1);
+ currentTime = cal.getTimeInMillis();
+ } else {
+ currentTime = System.currentTimeMillis();
+ }
+ if (marker.id == null) {
+ marker.id = String.valueOf(currentTime) + String.valueOf(new Random().nextInt(900) + 100);
+ }
+ marker.creationDate = currentTime;
+ String descr = PointDescription.serializeToString(marker.getOriginalPointDescription());
+ int active = marker.history ? 0 : 1;
+ long visited = saveExisting ? currentTime : 0;
+
+ PointDescription pointDescription = marker.getOriginalPointDescription();
+ if (pointDescription != null && !pointDescription.isSearchingAddress(context)) {
+ SearchHistoryHelper.getInstance(context)
+ .addNewItemToHistory(marker.getLatitude(), marker.getLongitude(), pointDescription);
+ }
+
+ if (!marker.history) {
+ db.execSQL("UPDATE " + MARKERS_TABLE_NAME + " SET " + MARKERS_COL_NEXT_KEY + " = ? " +
+ "WHERE " + MARKERS_COL_NEXT_KEY + " = ?", new Object[]{marker.id, TAIL_NEXT_VALUE});
+ }
+
+ db.execSQL("INSERT INTO " + MARKERS_TABLE_NAME + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+ new Object[]{marker.id, marker.getLatitude(), marker.getLongitude(), descr, active,
+ currentTime, visited, marker.groupName, marker.groupKey, marker.colorIndex,
+ marker.history ? HISTORY_NEXT_VALUE : TAIL_NEXT_VALUE});
+ }
+
+ public List getMarkersFromGroup(MarkersSyncGroup group) {
+ List res = new LinkedList<>();
+ SQLiteConnection db = openConnection(true);
+ if (db != null) {
+ try {
+ SQLiteCursor query = db.rawQuery(MARKERS_TABLE_SELECT + " WHERE " + MARKERS_COL_GROUP_KEY + " = ?",
+ new String[]{group.getId()});
+ if (query.moveToFirst()) {
+ do {
+ res.add(readItem(query));
+ } while (query.moveToNext());
+ }
+ query.close();
+ } finally {
+ db.close();
+ }
+ }
+ return res;
+ }
+
+ @Nullable
+ public MapMarker getMarker(String id) {
+ MapMarker res = null;
+ SQLiteConnection db = openConnection(true);
+ if (db != null) {
+ try {
+ SQLiteCursor query = db.rawQuery(MARKERS_TABLE_SELECT + " WHERE " + MARKERS_COL_ID + " = ?", new String[]{id});
+ if (query.moveToFirst()) {
+ res = readItem(query);
+ }
+ query.close();
+ } finally {
+ db.close();
+ }
+ }
+ return res;
+ }
+
+ public List getActiveMarkers() {
+ List res = new LinkedList<>();
+ HashMap markers = new LinkedHashMap<>();
+ SQLiteConnection db = openConnection(true);
+ if (db != null) {
+ try {
+ SQLiteCursor query = db.rawQuery(MARKERS_TABLE_SELECT + " WHERE " + MARKERS_COL_ACTIVE + " = ?",
+ new String[]{String.valueOf(1)});
+ if (query.moveToFirst()) {
+ do {
+ MapMarker marker = readItem(query);
+ markers.put(marker.id, marker);
+ } while (query.moveToNext());
+ }
+ query.close();
+ } finally {
+ db.close();
+ }
+ buildLinkedList(markers, res);
+ }
+ return res;
+ }
+
+ private MapMarker readItem(SQLiteCursor query) {
+ String id = query.getString(0);
+ double lat = query.getDouble(1);
+ double lon = query.getDouble(2);
+ String desc = query.getString(3);
+ boolean active = query.getInt(4) == 1;
+ long added = query.getLong(5);
+ long visited = query.getLong(6);
+ String groupName = query.getString(7);
+ String groupKey = query.getString(8);
+ int colorIndex = query.getInt(9);
+ String nextKey = query.getString(10);
+
+ LatLon latLon = new LatLon(lat, lon);
+ MapMarker marker = new MapMarker(latLon, PointDescription.deserializeFromString(desc, latLon),
+ colorIndex, false, 0);
+ marker.id = id;
+ marker.history = !active;
+ marker.creationDate = added;
+ marker.visitedDate = visited;
+ marker.groupName = groupName;
+ marker.groupKey = groupKey;
+ marker.nextKey = nextKey;
+
+ return marker;
+ }
+
+ private void buildLinkedList(HashMap markers, List res) {
+ if (!markers.isEmpty()) {
+ int count = 1;
+ for (MapMarker marker : markers.values()) {
+ if (!markers.keySet().contains(marker.nextKey) || count == markers.size()) {
+ res.add(0, marker);
+ markers.remove(marker.id);
+ break;
+ }
+ count++;
+ }
+ buildLinkedList(markers, res);
+ }
+ }
+
+ public void updateMarker(MapMarker marker) {
+ SQLiteConnection db = openConnection(false);
+ if (db != null) {
+ try {
+ String descr = PointDescription.serializeToString(marker.getOriginalPointDescription());
+ db.execSQL("UPDATE " + MARKERS_TABLE_NAME + " SET " +
+ MARKERS_COL_LAT + " = ?, " +
+ MARKERS_COL_LON + " = ?, " +
+ MARKERS_COL_DESCRIPTION + " = ?, " +
+ MARKERS_COL_COLOR + " = ? " +
+ "WHERE " + MARKERS_COL_ID + " = ?",
+ new Object[]{marker.getLatitude(), marker.getLongitude(), descr, marker.colorIndex, marker.id});
+ } finally {
+ db.close();
+ }
+ }
+ }
+
+ public void changeActiveMarkerPosition(MapMarker moved, @Nullable MapMarker next) {
+ SQLiteConnection db = openConnection(false);
+ if (db != null) {
+ try {
+ db.execSQL("UPDATE " + MARKERS_TABLE_NAME + " SET " + MARKERS_COL_NEXT_KEY + " = ? " +
+ "WHERE " + MARKERS_COL_ID + " = ?", new Object[]{next == null ? TAIL_NEXT_VALUE : next.id, moved.id});
+ } finally {
+ db.close();
+ }
+ }
+ }
+
+ public void moveMarkerToHistory(MapMarker marker) {
+ SQLiteConnection db = openConnection(false);
+ if (db != null) {
+ try {
+ marker.visitedDate = System.currentTimeMillis();
+
+ db.execSQL("UPDATE " + MARKERS_TABLE_NAME + " SET " +
+ MARKERS_COL_ACTIVE + " = ?, " +
+ MARKERS_COL_VISITED + " = ?, " +
+ MARKERS_COL_NEXT_KEY + " = ? " +
+ "WHERE " + MARKERS_COL_ID + " = ?", new Object[]{0, marker.visitedDate, HISTORY_NEXT_VALUE, marker.id});
+ } finally {
+ db.close();
+ }
+ }
+ }
+
+ public void moveAllActiveMarkersToHistory(long timestamp) {
+ SQLiteConnection db = openConnection(false);
+ if (db != null) {
+ try {
+ db.execSQL("UPDATE " + MARKERS_TABLE_NAME + " SET " +
+ MARKERS_COL_ACTIVE + " = ?, " +
+ MARKERS_COL_VISITED + " = ?, " +
+ MARKERS_COL_NEXT_KEY + " = ? " +
+ "WHERE " + MARKERS_COL_ACTIVE + " = ?", new Object[]{0, timestamp, HISTORY_NEXT_VALUE, 1});
+ } finally {
+ db.close();
+ }
+ }
+ }
+
+ public void restoreMapMarkerFromHistory(MapMarker marker) {
+ SQLiteConnection db = openConnection(false);
+ if (db != null) {
+ try {
+ db.execSQL("UPDATE " + MARKERS_TABLE_NAME + " SET " +
+ MARKERS_COL_ACTIVE + " = ? " +
+ "WHERE " + MARKERS_COL_ID + " = ? " +
+ "AND " + MARKERS_COL_ACTIVE + " = ?",
+ new Object[]{1, marker.id, 0});
+ } finally {
+ db.close();
+ }
+ }
+ }
+
+ public List getMarkersHistory() {
+ List markers = new LinkedList<>();
+ SQLiteConnection db = openConnection(true);
+ if (db != null) {
+ try {
+ SQLiteCursor query = db.rawQuery(MARKERS_TABLE_SELECT + " WHERE " + MARKERS_COL_ACTIVE + " = ?",
+ new String[]{String.valueOf(0)});
+ if (query.moveToFirst()) {
+ do {
+ markers.add(readItem(query));
+ } while (query.moveToNext());
+ }
+ query.close();
+ } finally {
+ db.close();
+ }
+ }
+ return markers;
+ }
+
+ public void removeMarker(MapMarker marker, boolean history) {
+ SQLiteConnection db = openConnection(true);
+ if (db != null) {
+ try {
+ db.execSQL("DELETE FROM " + MARKERS_TABLE_NAME +
+ " WHERE " + MARKERS_COL_ID + " = ?" +
+ " AND " + MARKERS_COL_ACTIVE + " = ?",
+ new Object[]{marker.id, history ? 0 : 1});
+ } finally {
+ db.close();
+ }
+ }
+ }
+
+ public void clearAllMarkersHistory() {
+ SQLiteConnection db = openConnection(true);
+ if (db != null) {
+ try {
+ db.execSQL("DELETE FROM " + MARKERS_TABLE_NAME + " WHERE " + MARKERS_COL_ACTIVE + " = ?",
+ new Object[]{0});
+ } finally {
+ db.close();
+ }
+ }
+ }
+}
diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDialogFragment.java
index 99c05a9550..dc4c5c25f7 100644
--- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDialogFragment.java
+++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDialogFragment.java
@@ -4,30 +4,47 @@ import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.BottomNavigationView;
+import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
+import android.support.v4.content.ContextCompat;
+import android.support.v4.view.ViewPager;
import android.support.v7.widget.Toolbar;
+import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.TextView;
import android.widget.Toast;
import net.osmand.plus.LockableViewPager;
+import net.osmand.plus.MapMarkersHelper;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
+import net.osmand.plus.dashboard.DashboardOnMap;
+import net.osmand.plus.mapmarkers.ShowDirectionBottomSheetDialogFragment.ShowDirectionFragmentListener;
import net.osmand.plus.mapmarkers.MarkerOptionsBottomSheetDialogFragment.MarkerOptionsFragmentListener;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Map;
public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragment {
public static final String TAG = "MapMarkersDialogFragment";
+ private MapMarkersActiveFragment activeFragment;
+ private MapMarkersGroupsFragment groupsFragment;
+ private MapMarkersHistoryFragment historyFragment;
+
+ private Snackbar snackbar;
+ private LockableViewPager viewPager;
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -40,11 +57,37 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
+ List fragments = getChildFragmentManager().getFragments();
+ if (fragments != null) {
+ for (Fragment fragment : fragments) {
+ if (fragment instanceof MapMarkersActiveFragment) {
+ activeFragment = (MapMarkersActiveFragment) fragment;
+ } else if (fragment instanceof MapMarkersGroupsFragment) {
+ groupsFragment = (MapMarkersGroupsFragment) fragment;
+ } else if (fragment instanceof MapMarkersHistoryFragment) {
+ historyFragment = (MapMarkersHistoryFragment) fragment;
+ }
+ }
+ }
+ if (activeFragment == null) {
+ activeFragment = new MapMarkersActiveFragment();
+ }
+ if (groupsFragment == null) {
+ groupsFragment = new MapMarkersGroupsFragment();
+ }
+ if (historyFragment == null) {
+ historyFragment = new MapMarkersHistoryFragment();
+ }
+
FragmentManager fragmentManager = getChildFragmentManager();
Fragment markerOptionsFragment = fragmentManager.findFragmentByTag(MarkerOptionsBottomSheetDialogFragment.TAG);
if (markerOptionsFragment != null) {
((MarkerOptionsBottomSheetDialogFragment) markerOptionsFragment).setListener(createMarkerOptionsFragmentListener());
}
+ Fragment showDirectionFragment = fragmentManager.findFragmentByTag(ShowDirectionBottomSheetDialogFragment.TAG);
+ if (showDirectionFragment != null) {
+ ((ShowDirectionBottomSheetDialogFragment) showDirectionFragment).setListener(createShowDirectionFragmentListener());
+ }
View mainView = inflater.inflate(R.layout.fragment_map_markers_dialog, container);
@@ -66,7 +109,7 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm
}
});
- final LockableViewPager viewPager = mainView.findViewById(R.id.map_markers_view_pager);
+ viewPager = mainView.findViewById(R.id.map_markers_view_pager);
viewPager.setSwipeLocked(true);
final MapMarkersViewPagerAdapter adapter = new MapMarkersViewPagerAdapter(getChildFragmentManager());
viewPager.setAdapter(adapter);
@@ -77,21 +120,33 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.action_active:
- ((MapMarkersActiveFragment) adapter.getItem(0)).startLocationUpdate();
+ activeFragment.startLocationUpdate();
if (viewPager.getCurrentItem() != 0) {
- ((MapMarkersActiveFragment) adapter.getItem(0)).updateAdapter();
+ activeFragment.updateAdapter();
+ historyFragment.hideSnackbar();
}
viewPager.setCurrentItem(0);
optionsButton.setVisibility(View.VISIBLE);
return true;
- case R.id.action_history:
- ((MapMarkersActiveFragment) adapter.getItem(0)).stopLocationUpdate();
+ case R.id.action_groups:
+ activeFragment.stopLocationUpdate();
if (viewPager.getCurrentItem() != 1) {
- ((MapMarkersHistoryFragment) adapter.getItem(1)).updateAdapter();
+ groupsFragment.updateAdapter();
+ activeFragment.hideSnackbar();
+ historyFragment.hideSnackbar();
}
viewPager.setCurrentItem(1);
optionsButton.setVisibility(View.GONE);
return true;
+ case R.id.action_history:
+ activeFragment.stopLocationUpdate();
+ if (viewPager.getCurrentItem() != 2) {
+ historyFragment.updateAdapter();
+ activeFragment.hideSnackbar();
+ }
+ viewPager.setCurrentItem(2);
+ optionsButton.setVisibility(View.GONE);
+ return true;
}
return false;
}
@@ -106,6 +161,9 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm
private MarkerOptionsFragmentListener createMarkerOptionsFragmentListener() {
return new MarkerOptionsFragmentListener() {
+
+ final MapActivity mapActivity = getMapActivity();
+
@Override
public void sortByOnClick() {
Toast.makeText(getContext(), "Sort by", Toast.LENGTH_SHORT).show();
@@ -113,26 +171,61 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm
@Override
public void showDirectionOnClick() {
- Toast.makeText(getContext(), "Show direction", Toast.LENGTH_SHORT).show();
+ ShowDirectionBottomSheetDialogFragment fragment = new ShowDirectionBottomSheetDialogFragment();
+ fragment.setListener(createShowDirectionFragmentListener());
+ fragment.show(mapActivity.getSupportFragmentManager(), ShowDirectionBottomSheetDialogFragment.TAG);
}
@Override
public void buildRouteOnClick() {
- Toast.makeText(getContext(), "Build route", Toast.LENGTH_SHORT).show();
+ mapActivity.getDashboard().setDashboardVisibility(true, DashboardOnMap.DashboardType.MAP_MARKERS_SELECTION);
+ dismiss();
}
@Override
public void saveAsNewTrackOnClick() {
- Toast.makeText(getContext(), "Save as new track", Toast.LENGTH_SHORT).show();
+ mapActivity.getMyApplication().getMapMarkersHelper().generateGpx();
}
@Override
public void moveAllToHistoryOnClick() {
- Toast.makeText(getContext(), "Move all to history", Toast.LENGTH_SHORT).show();
+ final MapMarkersHelper helper = mapActivity.getMyApplication().getMapMarkersHelper();
+ final List markers = new ArrayList<>(helper.getMapMarkers());
+ helper.moveAllActiveMarkersToHistory();
+ activeFragment.updateAdapter();
+ snackbar = Snackbar.make(viewPager, R.string.all_markers_moved_to_history, Snackbar.LENGTH_LONG)
+ .setAction(R.string.shared_string_undo, new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ helper.restoreMarkersFromHistory(markers);
+ activeFragment.updateAdapter();
+ }
+ });
+ View snackBarView = snackbar.getView();
+ TextView tv = (TextView) snackBarView.findViewById(android.support.design.R.id.snackbar_action);
+ tv.setTextColor(ContextCompat.getColor(mapActivity, R.color.color_dialog_buttons_dark));
+ snackbar.show();
}
};
}
+ private ShowDirectionFragmentListener createShowDirectionFragmentListener() {
+ return new ShowDirectionFragmentListener() {
+
+ final MapActivity mapActivity = getMapActivity();
+
+ @Override
+ public void onMapMarkersModeChanged(boolean showDirectionEnabled) {
+ mapActivity.getMapLayers().getMapWidgetRegistry().updateMapMarkersMode(mapActivity);
+ activeFragment.setShowDirectionEnabled(showDirectionEnabled);
+ activeFragment.updateAdapter();
+ }
+ };
+ }
+
+ private MapActivity getMapActivity() {
+ return (MapActivity) getActivity();
+ }
public static boolean showInstance(@NonNull MapActivity mapActivity) {
try {
@@ -153,7 +246,7 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm
MapMarkersViewPagerAdapter(FragmentManager fm) {
super(fm);
- fragments = Arrays.asList(new MapMarkersActiveFragment(), new MapMarkersHistoryFragment());
+ fragments = Arrays.asList(activeFragment, groupsFragment, historyFragment);
}
@Override
diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java
new file mode 100644
index 0000000000..328575d030
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java
@@ -0,0 +1,37 @@
+package net.osmand.plus.mapmarkers;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import net.osmand.plus.activities.MapActivity;
+import net.osmand.plus.mapmarkers.adapters.MapMarkersGroupsAdapter;
+
+public class MapMarkersGroupsFragment extends Fragment {
+
+ public static final String TAG = "MapMarkersGroupsFragment";
+
+ private MapMarkersGroupsAdapter adapter;
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ final RecyclerView recyclerView = new RecyclerView(getContext());
+ recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
+ final MapActivity mapActivity = (MapActivity) getActivity();
+
+ adapter = new MapMarkersGroupsAdapter(mapActivity);
+ return recyclerView;
+ }
+
+ void updateAdapter() {
+ if (adapter != null) {
+ adapter.notifyDataSetChanged();
+ }
+ }
+}
diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHistoryFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHistoryFragment.java
index f5ef8026e3..e40938ebd5 100644
--- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHistoryFragment.java
+++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHistoryFragment.java
@@ -1,52 +1,261 @@
package net.osmand.plus.mapmarkers;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.Rect;
import android.os.Bundle;
import android.support.annotation.Nullable;
-import android.support.v4.app.DialogFragment;
+import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
+import android.support.v4.content.ContextCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.TextView;
-import net.osmand.data.PointDescription;
+import net.osmand.plus.MapMarkersHelper;
import net.osmand.plus.MapMarkersHelper.MapMarker;
+import net.osmand.plus.OsmandApplication;
+import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
+import net.osmand.plus.mapmarkers.adapters.MapMarkerDateViewHolder;
+import net.osmand.plus.mapmarkers.adapters.MapMarkerItemViewHolder;
import net.osmand.plus.mapmarkers.adapters.MapMarkersHistoryAdapter;
-public class MapMarkersHistoryFragment extends Fragment {
+public class MapMarkersHistoryFragment extends Fragment implements MapMarkersHelper.MapMarkerChangedListener {
- MapMarkersHistoryAdapter adapter;
+ private MapMarkersHistoryAdapter adapter;
+ private OsmandApplication app;
+ private Paint backgroundPaint = new Paint();
+ private Paint iconPaint = new Paint();
+ private Paint textPaint = new Paint();
+ private Snackbar snackbar;
+
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ app = getMyApplication();
+ }
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ final boolean night = !app.getSettings().isLightContent();
+ final MapActivity mapActivity = (MapActivity) getActivity();
+
+ backgroundPaint.setColor(ContextCompat.getColor(getActivity(), night ? R.color.dashboard_divider_dark : R.color.dashboard_divider_light));
+ backgroundPaint.setStyle(Paint.Style.FILL_AND_STROKE);
+ backgroundPaint.setAntiAlias(true);
+ iconPaint.setAntiAlias(true);
+ iconPaint.setFilterBitmap(true);
+ iconPaint.setDither(true);
+ textPaint.setTextSize(getResources().getDimension(R.dimen.default_desc_text_size));
+ textPaint.setFakeBoldText(true);
+ textPaint.setAntiAlias(true);
+
+ final String delStr = getString(R.string.shared_string_delete).toUpperCase();
+ final String activateStr = getString(R.string.local_index_mi_restore).toUpperCase();
+ Rect bounds = new Rect();
+
+ textPaint.getTextBounds(activateStr, 0, activateStr.length(), bounds);
+ final int activateStrWidth = bounds.width();
+ final int textHeight = bounds.height();
+
+ Fragment historyMarkerMenuFragment = mapActivity.getSupportFragmentManager().findFragmentByTag(HistoryMarkerMenuBottomSheetDialogFragment.TAG);
+ if (historyMarkerMenuFragment != null) {
+ ((HistoryMarkerMenuBottomSheetDialogFragment) historyMarkerMenuFragment).setListener(createHistoryMarkerMenuListener());
+ }
+
final RecyclerView recyclerView = new RecyclerView(getContext());
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
- final MapActivity mapActivity = (MapActivity) getActivity();
+
+ ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
+ private float marginSides = getResources().getDimension(R.dimen.list_content_padding);
+ private Bitmap deleteBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_action_delete_dark);
+ private Bitmap resetBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_action_reset_to_default_dark);
+ private boolean iconHidden;
+
+ @Override
+ public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
+ if (viewHolder instanceof MapMarkerDateViewHolder) {
+ return 0;
+ }
+ return super.getSwipeDirs(recyclerView, viewHolder);
+ }
+
+ @Override
+ public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
+ return false;
+ }
+
+ @Override
+ public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
+ if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE && viewHolder instanceof MapMarkerItemViewHolder) {
+ if (!iconHidden && isCurrentlyActive) {
+ ((MapMarkerItemViewHolder) viewHolder).optionsBtn.setVisibility(View.GONE);
+ iconHidden = true;
+ }
+ View itemView = viewHolder.itemView;
+ int colorIcon;
+ int colorText;
+ if (Math.abs(dX) > itemView.getWidth() / 2) {
+ colorIcon = R.color.map_widget_blue;
+ colorText = R.color.map_widget_blue;
+ } else {
+ colorIcon = night ? 0 : R.color.icon_color;
+ colorText = R.color.dashboard_subheader_text_light;
+ }
+ if (colorIcon != 0) {
+ iconPaint.setColorFilter(new PorterDuffColorFilter(ContextCompat.getColor(getActivity(), colorIcon), PorterDuff.Mode.SRC_IN));
+ }
+ textPaint.setColor(ContextCompat.getColor(getActivity(), colorText));
+ float textMarginTop = ((float) itemView.getHeight() - (float) textHeight) / 2;
+ if (dX > 0) {
+ c.drawRect(itemView.getLeft(), itemView.getTop(), dX, itemView.getBottom(), backgroundPaint);
+ float iconMarginTop = ((float) itemView.getHeight() - (float) deleteBitmap.getHeight()) / 2;
+ c.drawBitmap(deleteBitmap, itemView.getLeft() + marginSides, itemView.getTop() + iconMarginTop, iconPaint);
+ c.drawText(delStr, itemView.getLeft() + 2 * marginSides + deleteBitmap.getWidth(), itemView.getTop() + textMarginTop + textHeight, textPaint);
+ } else {
+ c.drawRect(itemView.getRight() + dX, itemView.getTop(), itemView.getRight(), itemView.getBottom(), backgroundPaint);
+ float iconMarginTop = ((float) itemView.getHeight() - (float) resetBitmap.getHeight()) / 2;
+ c.drawBitmap(resetBitmap, itemView.getRight() - resetBitmap.getWidth() - marginSides, itemView.getTop() + iconMarginTop, iconPaint);
+ c.drawText(activateStr, itemView.getRight() - resetBitmap.getWidth() - 2 * marginSides - activateStrWidth, itemView.getTop() + textMarginTop + textHeight, textPaint);
+ }
+ }
+ super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
+ }
+
+ @Override
+ public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
+ if (viewHolder instanceof MapMarkerItemViewHolder) {
+ ((MapMarkerItemViewHolder) viewHolder).optionsBtn.setVisibility(View.VISIBLE);
+ iconHidden = false;
+ }
+ super.clearView(recyclerView, viewHolder);
+ }
+
+ @Override
+ public void onSwiped(RecyclerView.ViewHolder viewHolder, final int direction) {
+ final int pos = viewHolder.getAdapterPosition();
+ Object item = adapter.getItem(pos);
+ if (item instanceof MapMarker) {
+ final MapMarker marker = (MapMarker) item;
+ int snackbarStringRes;
+ if (direction == ItemTouchHelper.LEFT) {
+ app.getMapMarkersHelper().restoreMarkerFromHistory((MapMarker) item, 0);
+ snackbarStringRes = R.string.marker_moved_to_active;
+ } else {
+ app.getMapMarkersHelper().removeMarkerFromHistory((MapMarker) item);
+ snackbarStringRes = R.string.item_removed;
+ }
+ adapter.notifyItemRemoved(pos);
+ snackbar = Snackbar.make(viewHolder.itemView, snackbarStringRes, Snackbar.LENGTH_LONG)
+ .setAction(R.string.shared_string_undo, new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (direction == ItemTouchHelper.LEFT) {
+ app.getMapMarkersHelper().moveMapMarkerToHistory(marker);
+ } else {
+ app.getMapMarkersHelper().addMarker(marker);
+ }
+ }
+ });
+ View snackBarView = snackbar.getView();
+ TextView tv = (TextView) snackBarView.findViewById(android.support.design.R.id.snackbar_action);
+ tv.setTextColor(ContextCompat.getColor(mapActivity, R.color.color_dialog_buttons_dark));
+ snackbar.show();
+ }
+ }
+ };
+ ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
+ itemTouchHelper.attachToRecyclerView(recyclerView);
adapter = new MapMarkersHistoryAdapter(mapActivity.getMyApplication());
adapter.setAdapterListener(new MapMarkersHistoryAdapter.MapMarkersHistoryAdapterListener() {
@Override
public void onItemClick(View view) {
- int pos = recyclerView.indexOfChild(view);
- MapMarker marker = adapter.getItem(pos);
- mapActivity.getMyApplication().getSettings().setMapLocationToShow(marker.getLatitude(), marker.getLongitude(),
- 15, new PointDescription(PointDescription.POINT_TYPE_LOCATION, marker.getPointDescription(mapActivity).getName()),
- false, null);
- MapActivity.launchMapActivityMoveToTop(mapActivity);
- ((DialogFragment) getParentFragment()).dismiss();
+ int pos = recyclerView.getChildAdapterPosition(view);
+ Object item = adapter.getItem(pos);
+ if (item instanceof MapMarker) {
+ MapMarker marker = (MapMarker) item;
+ HistoryMarkerMenuBottomSheetDialogFragment fragment = new HistoryMarkerMenuBottomSheetDialogFragment();
+ Bundle arguments = new Bundle();
+ arguments.putInt(HistoryMarkerMenuBottomSheetDialogFragment.MARKER_POSITION, pos);
+ arguments.putString(HistoryMarkerMenuBottomSheetDialogFragment.MARKER_NAME, marker.getName(mapActivity));
+ arguments.putInt(HistoryMarkerMenuBottomSheetDialogFragment.MARKER_COLOR_INDEX, marker.colorIndex);
+ arguments.putLong(HistoryMarkerMenuBottomSheetDialogFragment.MARKER_VISITED_DATE, marker.visitedDate);
+ fragment.setArguments(arguments);
+ fragment.setListener(createHistoryMarkerMenuListener());
+ fragment.show(mapActivity.getSupportFragmentManager(), HistoryMarkerMenuBottomSheetDialogFragment.TAG);
+ }
}
});
recyclerView.setAdapter(adapter);
+ app.getMapMarkersHelper().addListener(this);
+
return recyclerView;
}
+ void hideSnackbar() {
+ if (snackbar != null && snackbar.isShown()) {
+ snackbar.dismiss();
+ }
+ }
+
+ private HistoryMarkerMenuBottomSheetDialogFragment.HistoryMarkerMenuFragmentListener createHistoryMarkerMenuListener() {
+ return new HistoryMarkerMenuBottomSheetDialogFragment.HistoryMarkerMenuFragmentListener() {
+ @Override
+ public void onMakeMarkerActive(int pos) {
+ Object item = adapter.getItem(pos);
+ if (item instanceof MapMarker) {
+ app.getMapMarkersHelper().restoreMarkerFromHistory((MapMarker) item, 0);
+ adapter.notifyItemRemoved(pos);
+ }
+ }
+
+ @Override
+ public void onDeleteMarker(int pos) {
+ Object item = adapter.getItem(pos);
+ if (item instanceof MapMarker) {
+ app.getMapMarkersHelper().removeMarkerFromHistory((MapMarker) item);
+ adapter.notifyItemRemoved(pos);
+ }
+ }
+ };
+ }
+
+ @Override
+ public void onDestroy() {
+ app.getMapMarkersHelper().removeListener(this);
+ super.onDestroy();
+ }
+
void updateAdapter() {
if (adapter != null) {
+ adapter.createHeaders();
adapter.notifyDataSetChanged();
}
}
+
+ public OsmandApplication getMyApplication() {
+ return (OsmandApplication) getActivity().getApplication();
+ }
+
+ @Override
+ public void onMapMarkerChanged(MapMarker mapMarker) {
+ updateAdapter();
+ }
+
+ @Override
+ public void onMapMarkersChanged() {
+ updateAdapter();
+ }
}
diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MarkerOptionsBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MarkerOptionsBottomSheetDialogFragment.java
index 2bcf3d1325..0415556cea 100644
--- a/OsmAnd/src/net/osmand/plus/mapmarkers/MarkerOptionsBottomSheetDialogFragment.java
+++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MarkerOptionsBottomSheetDialogFragment.java
@@ -3,6 +3,7 @@ package net.osmand.plus.mapmarkers;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
+import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -13,6 +14,7 @@ import android.widget.ImageView;
import android.widget.TextView;
import net.osmand.AndroidUtils;
+import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.base.BottomSheetDialogFragment;
import net.osmand.plus.helpers.AndroidUiHelper;
@@ -32,16 +34,31 @@ public class MarkerOptionsBottomSheetDialogFragment extends BottomSheetDialogFra
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
portrait = AndroidUiHelper.isOrientationPortrait(getActivity());
+ boolean nightMode = getMyApplication().getDaynightHelper().isNightModeForMapControls();
+ final int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme;
- final View mainView = inflater.inflate(R.layout.fragment_marker_options_bottom_sheet_dialog, container);
+ final View mainView = View.inflate(new ContextThemeWrapper(getContext(), themeRes), R.layout.fragment_marker_options_bottom_sheet_dialog, container);
if (portrait) {
- AndroidUtils.setBackground(getActivity(), mainView, false, R.drawable.bg_bottom_menu_light, R.drawable.bg_bottom_menu_dark);
+ AndroidUtils.setBackground(getActivity(), mainView, nightMode, R.drawable.bg_bottom_menu_light, R.drawable.bg_bottom_menu_dark);
}
((ImageView) mainView.findViewById(R.id.sort_by_icon))
.setImageDrawable(getIcon(R.drawable.ic_sort_waypoint_dark, R.color.on_map_icon_color));
- ((ImageView) mainView.findViewById(R.id.show_direction_icon))
- .setImageDrawable(getIcon(R.drawable.ic_sort_waypoint_dark, R.color.on_map_icon_color));
+ OsmandSettings.MapMarkersMode mode = getMyApplication().getSettings().MAP_MARKERS_MODE.get();
+ ImageView showDirectionIcon = (ImageView) mainView.findViewById(R.id.show_direction_icon);
+ int imageResId = 0;
+ switch (mode) {
+ case TOOLBAR:
+ imageResId = R.drawable.ic_action_device_topbar;
+ break;
+ case WIDGETS:
+ imageResId = R.drawable.ic_action_device_widget;
+ break;
+ }
+ showDirectionIcon.setBackgroundDrawable(getIcon(R.drawable.ic_action_device_top, R.color.on_map_icon_color));
+ if (imageResId != 0) {
+ showDirectionIcon.setImageDrawable(getIcon(imageResId, R.color.dashboard_blue));
+ }
((ImageView) mainView.findViewById(R.id.build_route_icon))
.setImageDrawable(getIcon(R.drawable.map_directions, R.color.on_map_icon_color));
((ImageView) mainView.findViewById(R.id.save_as_new_track_icon))
@@ -49,7 +66,7 @@ public class MarkerOptionsBottomSheetDialogFragment extends BottomSheetDialogFra
((ImageView) mainView.findViewById(R.id.move_all_to_history_icon))
.setImageDrawable(getIcon(R.drawable.ic_action_history2, R.color.on_map_icon_color));
- ((TextView) mainView.findViewById(R.id.show_direction_text_view)).setText("Top bar");
+ ((TextView) mainView.findViewById(R.id.show_direction_text_view)).setText(getMyApplication().getSettings().MAP_MARKERS_MODE.get().toHumanString(getActivity()));
mainView.findViewById(R.id.sort_by_row).setOnClickListener(new View.OnClickListener() {
@Override
@@ -113,7 +130,7 @@ public class MarkerOptionsBottomSheetDialogFragment extends BottomSheetDialogFra
final View scrollView = mainView.findViewById(R.id.marker_options_scroll_view);
int scrollViewHeight = scrollView.getHeight();
int dividerHeight = AndroidUtils.dpToPx(getContext(), 1);
- int cancelButtonHeight = getContext().getResources().getDimensionPixelSize(R.dimen.measure_distance_bottom_sheet_cancel_button_height);
+ int cancelButtonHeight = getContext().getResources().getDimensionPixelSize(R.dimen.bottom_sheet_cancel_button_height);
int spaceForScrollView = screenHeight - statusBarHeight - navBarHeight - dividerHeight - cancelButtonHeight;
if (scrollViewHeight > spaceForScrollView) {
scrollView.getLayoutParams().height = spaceForScrollView;
diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/ShowDirectionBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/ShowDirectionBottomSheetDialogFragment.java
new file mode 100644
index 0000000000..43148b2a13
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/mapmarkers/ShowDirectionBottomSheetDialogFragment.java
@@ -0,0 +1,239 @@
+package net.osmand.plus.mapmarkers;
+
+import android.os.Build;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.content.ContextCompat;
+import android.view.ContextThemeWrapper;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.ImageView;
+import android.widget.RadioButton;
+import android.widget.TextView;
+
+import net.osmand.AndroidUtils;
+import net.osmand.plus.OsmandSettings;
+import net.osmand.plus.R;
+import net.osmand.plus.base.BottomSheetDialogFragment;
+import net.osmand.plus.helpers.AndroidUiHelper;
+
+public class ShowDirectionBottomSheetDialogFragment extends BottomSheetDialogFragment {
+
+ public final static String TAG = "ShowDirectionBottomSheetDialogFragment";
+
+ private ShowDirectionFragmentListener listener;
+ private boolean portrait;
+ private View mainView;
+ private boolean night;
+
+ public void setListener(ShowDirectionFragmentListener listener) {
+ this.listener = listener;
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ portrait = AndroidUiHelper.isOrientationPortrait(getActivity());
+ night = !getMyApplication().getSettings().isLightContent();
+ final int themeRes = night ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme;
+
+ mainView = View.inflate(new ContextThemeWrapper(getContext(), themeRes), R.layout.fragment_marker_show_direction_bottom_sheet_dialog, container);
+ if (portrait) {
+ AndroidUtils.setBackground(getActivity(), mainView, night, R.drawable.bg_bottom_menu_light, R.drawable.bg_bottom_menu_dark);
+ }
+
+ OsmandSettings.MapMarkersMode mode = getMyApplication().getSettings().MAP_MARKERS_MODE.get();
+ highlightSelectedItem(mode, true);
+
+ if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ mainView.findViewById(R.id.images_row).setVisibility(View.GONE);
+ } else {
+ ImageView topBarImage = (ImageView) mainView.findViewById(R.id.top_bar_image);
+ ImageView widgetImage = (ImageView) mainView.findViewById(R.id.widget_image);
+ if (night) {
+ topBarImage.setImageResource(R.drawable.img_help_markers_topbar_night);
+ widgetImage.setImageResource(R.drawable.img_help_markers_widgets_night);
+ } else {
+ topBarImage.setImageResource(R.drawable.img_help_markers_topbar_day);
+ widgetImage.setImageResource(R.drawable.img_help_markers_widgets_day);
+ }
+
+ mainView.findViewById(R.id.top_bar_image_text).setOnTouchListener(new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View view, MotionEvent motionEvent) {
+ return false;
+ }
+ });
+ topBarImage.setOnClickListener(showDirectionOnClickListener);
+
+ mainView.findViewById(R.id.widget_image_text).setOnTouchListener(new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View view, MotionEvent motionEvent) {
+ return false;
+ }
+ });
+ widgetImage.setOnClickListener(showDirectionOnClickListener);
+ }
+
+ if (night) {
+ ((TextView) mainView.findViewById(R.id.show_direction_title)).setTextColor(getResources().getColor(R.color.ctx_menu_info_text_dark));
+ }
+
+ ImageView topBarIcon = (ImageView) mainView.findViewById(R.id.top_bar_icon);
+ topBarIcon.setBackgroundDrawable(getIcon(R.drawable.ic_action_device_top, R.color.on_map_icon_color));
+ topBarIcon.setImageDrawable(getIcon(R.drawable.ic_action_device_topbar, R.color.dashboard_blue));
+
+ ImageView widgetIcon = (ImageView) mainView.findViewById(R.id.widget_icon);
+ widgetIcon.setBackgroundDrawable(getIcon(R.drawable.ic_action_device_top, R.color.on_map_icon_color));
+ widgetIcon.setImageDrawable(getIcon(R.drawable.ic_action_device_widget, R.color.dashboard_blue));
+
+ ImageView noneIcon = (ImageView) mainView.findViewById(R.id.none_icon);
+ noneIcon.setBackgroundDrawable(getIcon(R.drawable.ic_action_device_top, R.color.on_map_icon_color));
+
+ mainView.findViewById(R.id.top_bar_row).setOnClickListener(showDirectionOnClickListener);
+ mainView.findViewById(R.id.widget_row).setOnClickListener(showDirectionOnClickListener);
+ mainView.findViewById(R.id.none_row).setOnClickListener(showDirectionOnClickListener);
+
+ mainView.findViewById(R.id.cancel_row).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ dismiss();
+ }
+ });
+
+ final int screenHeight = AndroidUtils.getScreenHeight(getActivity());
+ final int statusBarHeight = AndroidUtils.getStatusBarHeight(getActivity());
+ final int navBarHeight = AndroidUtils.getNavBarHeight(getActivity());
+
+ mainView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ final View scrollView = mainView.findViewById(R.id.marker_show_direction_scroll_view);
+ int scrollViewHeight = scrollView.getHeight();
+ int dividerHeight = AndroidUtils.dpToPx(getContext(), 1);
+ int cancelButtonHeight = getContext().getResources().getDimensionPixelSize(R.dimen.bottom_sheet_cancel_button_height);
+ int spaceForScrollView = screenHeight - statusBarHeight - navBarHeight - dividerHeight - cancelButtonHeight;
+ if (scrollViewHeight > spaceForScrollView) {
+ scrollView.getLayoutParams().height = spaceForScrollView;
+ scrollView.requestLayout();
+ }
+
+ if (!portrait) {
+ if (screenHeight - statusBarHeight - mainView.getHeight()
+ >= AndroidUtils.dpToPx(getActivity(), 8)) {
+ AndroidUtils.setBackground(getActivity(), mainView, false,
+ R.drawable.bg_bottom_sheet_topsides_landscape_light, R.drawable.bg_bottom_sheet_topsides_landscape_dark);
+ } else {
+ AndroidUtils.setBackground(getActivity(), mainView, false,
+ R.drawable.bg_bottom_sheet_sides_landscape_light, R.drawable.bg_bottom_sheet_sides_landscape_dark);
+ }
+ }
+
+ ViewTreeObserver obs = mainView.getViewTreeObserver();
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ obs.removeOnGlobalLayoutListener(this);
+ } else {
+ obs.removeGlobalOnLayoutListener(this);
+ }
+ }
+ });
+
+ return mainView;
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ if (!portrait) {
+ final Window window = getDialog().getWindow();
+ WindowManager.LayoutParams params = window.getAttributes();
+ params.width = getActivity().getResources().getDimensionPixelSize(R.dimen.landscape_bottom_sheet_dialog_fragment_width);
+ window.setAttributes(params);
+ }
+ }
+
+ private void highlightSelectedItem(OsmandSettings.MapMarkersMode mode, boolean check) {
+ int iconBgColor = check ? R.color.dashboard_blue : R.color.on_map_icon_color;
+ int iconColor = check ? R.color.color_dialog_buttons_dark : R.color.dashboard_blue;
+ int textColor = ContextCompat.getColor(getContext(), check ? R.color.dashboard_blue : night ? R.color.color_white : R.color.color_black);
+ switch (mode) {
+ case TOOLBAR:
+ ((RadioButton) mainView.findViewById(R.id.top_bar_radio_button)).setChecked(check);
+ ImageView topBarIcon = (ImageView) mainView.findViewById(R.id.top_bar_icon);
+ if (check) {
+ mainView.findViewById(R.id.top_bar_row).setBackgroundColor(ContextCompat.getColor(getContext(), R.color.show_direction_menu_selected_item_bg));
+ } else {
+ mainView.findViewById(R.id.top_bar_row).setBackgroundResource(0);
+ }
+ ((TextView) mainView.findViewById(R.id.top_bar_text)).setTextColor(textColor);
+ topBarIcon.setBackgroundDrawable(getIcon(R.drawable.ic_action_device_top, iconBgColor));
+ topBarIcon.setImageDrawable(getIcon(R.drawable.ic_action_device_topbar, iconColor));
+ break;
+ case WIDGETS:
+ ((RadioButton) mainView.findViewById(R.id.widget_radio_button)).setChecked(check);
+ ImageView widgetIcon = (ImageView) mainView.findViewById(R.id.widget_icon);
+ if (check) {
+ mainView.findViewById(R.id.widget_row).setBackgroundColor(ContextCompat.getColor(getContext(), R.color.show_direction_menu_selected_item_bg));
+ } else {
+ mainView.findViewById(R.id.widget_row).setBackgroundResource(0);
+ }
+ ((TextView) mainView.findViewById(R.id.widget_text)).setTextColor(textColor);
+ widgetIcon.setBackgroundDrawable(getIcon(R.drawable.ic_action_device_top, iconBgColor));
+ widgetIcon.setImageDrawable(getIcon(R.drawable.ic_action_device_widget, iconColor));
+ break;
+ case NONE:
+ ((RadioButton) mainView.findViewById(R.id.none_radio_button)).setChecked(check);
+ ImageView noneIcon = (ImageView) mainView.findViewById(R.id.none_icon);
+ if (check) {
+ mainView.findViewById(R.id.none_row).setBackgroundColor(ContextCompat.getColor(getContext(), R.color.show_direction_menu_selected_item_bg));
+ } else {
+ mainView.findViewById(R.id.none_row).setBackgroundResource(0);
+ }
+ ((TextView) mainView.findViewById(R.id.none_text)).setTextColor(textColor);
+ noneIcon.setBackgroundDrawable(getIcon(R.drawable.ic_action_device_top, iconBgColor));
+ break;
+ }
+ }
+
+ private View.OnClickListener showDirectionOnClickListener = new View.OnClickListener() {
+
+ @Override
+ public void onClick(View view) {
+ OsmandSettings.MapMarkersMode previousMode = getMyApplication().getSettings().MAP_MARKERS_MODE.get();
+ highlightSelectedItem(previousMode, false);
+ boolean showDirectionEnabled = false;
+ switch (view.getId()) {
+ case R.id.top_bar_image:
+ case R.id.top_bar_row:
+ getMyApplication().getSettings().MAP_MARKERS_MODE.set(OsmandSettings.MapMarkersMode.TOOLBAR);
+ highlightSelectedItem(OsmandSettings.MapMarkersMode.TOOLBAR, true);
+ showDirectionEnabled = true;
+ break;
+ case R.id.widget_image:
+ case R.id.widget_row:
+ getMyApplication().getSettings().MAP_MARKERS_MODE.set(OsmandSettings.MapMarkersMode.WIDGETS);
+ highlightSelectedItem(OsmandSettings.MapMarkersMode.WIDGETS, true);
+ showDirectionEnabled = true;
+ break;
+ case R.id.none_row:
+ getMyApplication().getSettings().MAP_MARKERS_MODE.set(OsmandSettings.MapMarkersMode.NONE);
+ highlightSelectedItem(OsmandSettings.MapMarkersMode.NONE, true);
+ showDirectionEnabled = false;
+ break;
+ }
+ if (listener != null) {
+ listener.onMapMarkersModeChanged(showDirectionEnabled);
+ }
+ dismiss();
+ }
+ };
+
+ interface ShowDirectionFragmentListener {
+ void onMapMarkersModeChanged(boolean showDirectionEnabled);
+ }
+}
diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkerDateViewHolder.java b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkerDateViewHolder.java
new file mode 100644
index 0000000000..7347d46604
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkerDateViewHolder.java
@@ -0,0 +1,20 @@
+package net.osmand.plus.mapmarkers.adapters;
+
+import android.support.v7.widget.RecyclerView;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.TextView;
+
+import net.osmand.plus.R;
+
+public class MapMarkerDateViewHolder extends RecyclerView.ViewHolder {
+
+ final TextView date;
+ final ImageButton optionsBtn;
+
+ public MapMarkerDateViewHolder(View itemView) {
+ super(itemView);
+ date = itemView.findViewById(R.id.date_title);
+ optionsBtn = itemView.findViewById(R.id.date_options_button);
+ }
+}
diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkerItemViewHolder.java b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkerItemViewHolder.java
index d3042e2090..8b41e6d81c 100644
--- a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkerItemViewHolder.java
+++ b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkerItemViewHolder.java
@@ -10,24 +10,36 @@ import net.osmand.plus.R;
public class MapMarkerItemViewHolder extends RecyclerView.ViewHolder {
+ final View mainLayout;
final ImageView iconDirection;
final ImageView iconReorder;
final ImageView icon;
final TextView title;
final TextView distance;
+ final View flagIconLeftSpace;
+ final View leftPointSpace;
final TextView point;
+ final View rightPointSpace;
final TextView description;
- final ImageButton optionsBtn;
+ public final ImageButton optionsBtn;
+ final View divider;
+ final View bottomShadow;
public MapMarkerItemViewHolder(View view) {
super(view);
+ mainLayout = view.findViewById(R.id.main_layout);
iconDirection = (ImageView) view.findViewById(R.id.map_marker_direction_icon);
iconReorder = (ImageView) view.findViewById(R.id.map_marker_reorder_icon);
icon = (ImageView) view.findViewById(R.id.map_marker_icon);
title = (TextView) view.findViewById(R.id.map_marker_title);
distance = (TextView) view.findViewById(R.id.map_marker_distance);
+ flagIconLeftSpace = view.findViewById(R.id.flag_icon_left_space);
+ leftPointSpace = view.findViewById(R.id.map_marker_left_point_space);
point = (TextView) view.findViewById(R.id.map_marker_point_text_view);
+ rightPointSpace = view.findViewById(R.id.map_marker_right_point_space);
description = (TextView) view.findViewById(R.id.map_marker_description);
optionsBtn = (ImageButton) view.findViewById(R.id.map_marker_options_button);
+ divider = view.findViewById(R.id.divider);
+ bottomShadow = view.findViewById(R.id.bottom_shadow);
}
}
diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersActiveAdapter.java b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersActiveAdapter.java
index 20cfc06e1a..d531c4d1f7 100644
--- a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersActiveAdapter.java
+++ b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersActiveAdapter.java
@@ -1,22 +1,29 @@
package net.osmand.plus.mapmarkers.adapters;
import android.support.design.widget.Snackbar;
+import android.support.v4.content.ContextCompat;
import android.support.v4.view.MotionEventCompat;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
import net.osmand.data.LatLon;
import net.osmand.plus.IconsCache;
import net.osmand.plus.MapMarkersHelper.MapMarker;
+import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.dashboard.DashLocationFragment;
+import java.text.SimpleDateFormat;
import java.util.Collections;
+import java.util.Date;
import java.util.List;
+import java.util.Locale;
public class MapMarkersActiveAdapter extends RecyclerView.Adapter
implements MapMarkersItemTouchHelperCallback.ItemTouchHelperAdapter {
@@ -24,15 +31,24 @@ public class MapMarkersActiveAdapter extends RecyclerView.Adapter markers;
private MapMarkersActiveAdapterListener listener;
+ private Snackbar snackbar;
+ private boolean showDirectionEnabled;
private LatLon location;
private Float heading;
private boolean useCenter;
private int screenOrientation;
+ private boolean night;
public MapMarkersActiveAdapter(MapActivity mapActivity) {
this.mapActivity = mapActivity;
markers = mapActivity.getMyApplication().getMapMarkersHelper().getMapMarkers();
+ night = !mapActivity.getMyApplication().getSettings().isLightContent();
+ showDirectionEnabled = mapActivity.getMyApplication().getSettings().MAP_MARKERS_MODE.get() != OsmandSettings.MapMarkersMode.NONE;
+ }
+
+ public void setShowDirectionEnabled(boolean showDirectionEnabled) {
+ this.showDirectionEnabled = showDirectionEnabled;
}
public void setAdapterListener(MapMarkersActiveAdapterListener listener) {
@@ -56,7 +72,7 @@ public class MapMarkersActiveAdapter extends RecyclerView.Adapter 1) {
+ notifyItemChanged(1);
+ } else if (position == getItemCount()) {
+ notifyItemChanged(position - 1);
+ }
- Snackbar.make(holder.itemView, R.string.item_removed, Snackbar.LENGTH_LONG)
+ snackbar = Snackbar.make(holder.itemView, mapActivity.getString(R.string.marker_moved_to_history), Snackbar.LENGTH_LONG)
.setAction(R.string.shared_string_undo, new View.OnClickListener() {
@Override
public void onClick(View view) {
- undone[0] = true;
- mapActivity.getMyApplication().getMapMarkersHelper().addMapMarker(marker, position);
+ mapActivity.getMyApplication().getMapMarkersHelper().restoreMarkerFromHistory(marker, position);
notifyItemInserted(position);
- }
- })
- .addCallback(new Snackbar.Callback() {
- @Override
- public void onDismissed(Snackbar transientBottomBar, int event) {
- if (!undone[0]) {
- mapActivity.getMyApplication().getMapMarkersHelper().addMapMarkerHistory(marker);
+ if (showDirectionEnabled && position < 2 && getItemCount() > 2) {
+ notifyItemChanged(2);
+ } else if (position == getItemCount() - 1) {
+ notifyItemChanged(position - 1);
}
}
- }).show();
+ });
+ View snackBarView = snackbar.getView();
+ TextView tv = (TextView) snackBarView.findViewById(android.support.design.R.id.snackbar_action);
+ tv.setTextColor(ContextCompat.getColor(mapActivity, R.color.color_dialog_buttons_dark));
+ snackbar.show();
}
});
DashLocationFragment.updateLocationView(useCenter, location,
- heading, holder.iconDirection, holder.distance,
- marker.getLatitude(), marker.getLongitude(),
- screenOrientation, mapActivity.getMyApplication(), mapActivity);
+ heading, markerImageViewToUpdate, drawableResToUpdate, pos < 2 ? markerColor : 0,
+ holder.distance, markerLatLon,
+ screenOrientation, mapActivity.getMyApplication(), mapActivity, true);
}
@Override
@@ -143,6 +207,12 @@ public class MapMarkersActiveAdapter extends RecyclerView.Adapter {
+
+ private MapActivity mapActivity;
+ private List markers;
+ private boolean night;
+
+ public MapMarkersGroupsAdapter(MapActivity mapActivity) {
+ this.mapActivity = mapActivity;
+ markers = mapActivity.getMyApplication().getMapMarkersHelper().getMapMarkers();
+ night = !mapActivity.getMyApplication().getSettings().isLightContent();
+ }
+
+ @Override
+ public MapMarkerItemViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
+ View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.map_marker_item_new, viewGroup, false);
+ return new MapMarkerItemViewHolder(view);
+ }
+
+ @Override
+ public void onBindViewHolder(MapMarkerItemViewHolder mapMarkerItemViewHolder, int i) {
+ IconsCache iconsCache = mapActivity.getMyApplication().getIconsCache();
+ MapMarkersHelper.MapMarker marker = markers.get(i);
+ }
+
+ @Override
+ public int getItemCount() {
+ return markers.size();
+ }
+
+ public MapMarkersHelper.MapMarker getItem(int position) {
+ return markers.get(position);
+ }
+
+ public List getItems() {
+ return markers;
+ }
+}
diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersHistoryAdapter.java b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersHistoryAdapter.java
index 173774b4e7..c035fe1032 100644
--- a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersHistoryAdapter.java
+++ b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersHistoryAdapter.java
@@ -10,17 +10,76 @@ import net.osmand.plus.MapMarkersHelper.MapMarker;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
import java.util.List;
+import java.util.Locale;
-public class MapMarkersHistoryAdapter extends RecyclerView.Adapter {
+public class MapMarkersHistoryAdapter extends RecyclerView.Adapter {
+
+ private static final int DATE_TYPE = 1;
+ private static final int MARKER_TYPE = 2;
+
+ private static final int TODAY_HEADER = 56;
+ private static final int YESTERDAY_HEADER = 57;
+ private static final int LAST_SEVEN_DAYS_HEADER = 58;
+ private static final int THIS_YEAR_HEADER = 59;
private OsmandApplication app;
- private List markers;
+ private List