diff --git a/OsmAnd/res/layout/map_marker_item_date.xml b/OsmAnd/res/layout/map_marker_item_header.xml similarity index 100% rename from OsmAnd/res/layout/map_marker_item_date.xml rename to OsmAnd/res/layout/map_marker_item_header.xml diff --git a/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java b/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java index 709f1664df..f05f4db730 100644 --- a/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java +++ b/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java @@ -177,7 +177,7 @@ public class FavouritesDbHelper { sortAll(); saveCurrentPointsIntoFile(); } - context.getMapMarkersHelper().syncGroup(new MarkersSyncGroup(group.name, group.name, MarkersSyncGroup.FAVORITES_TYPE)); + context.getMapMarkersHelper().syncGroup(new MarkersSyncGroup(group.name, group.name, MarkersSyncGroup.FAVORITES_TYPE, group.color)); return true; } @@ -272,7 +272,7 @@ public class FavouritesDbHelper { } sortAll(); saveCurrentPointsIntoFile(); - context.getMapMarkersHelper().syncGroup(new MarkersSyncGroup(category, category, MarkersSyncGroup.FAVORITES_TYPE)); + context.getMapMarkersHelper().syncGroup(new MarkersSyncGroup(category, category, MarkersSyncGroup.FAVORITES_TYPE, p.getColor())); return true; } @@ -280,7 +280,7 @@ public class FavouritesDbHelper { p.setLatitude(lat); p.setLongitude(lon); saveCurrentPointsIntoFile(); - context.getMapMarkersHelper().syncGroup(new MarkersSyncGroup(p.getCategory(), p.getCategory(), MarkersSyncGroup.FAVORITES_TYPE)); + context.getMapMarkersHelper().syncGroup(new MarkersSyncGroup(p.getCategory(), p.getCategory(), MarkersSyncGroup.FAVORITES_TYPE, p.getColor())); return true; } @@ -597,6 +597,7 @@ public class FavouritesDbHelper { for (FavouritePoint p : gr.points) { p.setColor(color); } + markersHelper.syncGroup(new MarkersSyncGroup(gr.name, gr.name, MarkersSyncGroup.FAVORITES_TYPE, color)); } if (group.visible != visible) { FavoriteGroup gr = flatGroups.get(group.name); @@ -604,7 +605,7 @@ public class FavouritesDbHelper { for (FavouritePoint p : gr.points) { p.setVisible(visible); } - markersHelper.syncGroup(new MarkersSyncGroup(gr.name, gr.name, MarkersSyncGroup.FAVORITES_TYPE)); + markersHelper.syncGroup(new MarkersSyncGroup(gr.name, gr.name, MarkersSyncGroup.FAVORITES_TYPE, group.color)); } if (!group.name.equals(newName)) { FavoriteGroup gr = flatGroups.remove(group.name); @@ -624,7 +625,7 @@ public class FavouritesDbHelper { renamedGroup.points.add(p); } } - MarkersSyncGroup syncGroup = new MarkersSyncGroup(renamedGroup.name, renamedGroup.name, MarkersSyncGroup.FAVORITES_TYPE); + MarkersSyncGroup syncGroup = new MarkersSyncGroup(renamedGroup.name, renamedGroup.name, MarkersSyncGroup.FAVORITES_TYPE, group.color); markersHelper.addMarkersSyncGroup(syncGroup); markersHelper.syncGroup(syncGroup); } diff --git a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java index 8a4f8203d2..1830656109 100644 --- a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java +++ b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java @@ -3,6 +3,7 @@ package net.osmand.plus; import android.content.Context; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.v4.content.ContextCompat; import android.text.format.DateFormat; import net.osmand.IndexConstants; @@ -10,9 +11,11 @@ import net.osmand.data.FavouritePoint; import net.osmand.data.LatLon; import net.osmand.data.LocationPoint; import net.osmand.data.PointDescription; +import net.osmand.plus.FavouritesDbHelper.FavoriteGroup; import net.osmand.plus.GPXUtilities.GPXFile; import net.osmand.plus.GPXUtilities.WptPt; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; +import net.osmand.plus.helpers.ColorDialogs; import net.osmand.plus.mapmarkers.MapMarkersDbHelper; import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; @@ -24,9 +27,11 @@ import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Locale; +import java.util.Map; import static net.osmand.data.PointDescription.POINT_TYPE_MAP_MARKER; @@ -48,6 +53,8 @@ public class MapMarkersHelper { } public static class MapMarker implements LocationPoint { + private static int[] colors; + public String id; public LatLon point; private PointDescription pointDescription; @@ -132,34 +139,39 @@ public class MapMarkersHelper { return result; } - public static int getColorId(int colorIndex) { - int colorId; - switch (colorIndex) { - case 0: - colorId = R.color.marker_blue; - break; - case 1: - colorId = R.color.marker_green; - break; - case 2: - colorId = R.color.marker_orange; - break; - case 3: - colorId = R.color.marker_red; - break; - case 4: - colorId = R.color.marker_yellow; - break; - case 5: - colorId = R.color.marker_teal; - break; - case 6: - colorId = R.color.marker_purple; - break; - default: - colorId = R.color.marker_blue; + private static final int[] colorsIds = new int[]{ + R.color.marker_blue, + R.color.marker_green, + R.color.marker_orange, + R.color.marker_red, + R.color.marker_yellow, + R.color.marker_teal, + R.color.marker_purple + }; + + public static int[] getColors(Context context) { + if (colors != null) { + return colors; } - return colorId; + colors = new int[colorsIds.length]; + for (int i = 0; i < colorsIds.length; i++) { + colors[i] = ContextCompat.getColor(context, colorsIds[i]); + } + return colors; + } + + public static int getColorId(int colorIndex) { + return (colorIndex >= 0 && colorIndex < colorsIds.length) ? colorsIds[colorIndex] : colorsIds[0]; + } + + public static int getColorIndex(Context context, int color) { + int[] colors = getColors(context); + for (int i = 0; i < colors.length; i++) { + if (colors[i] == color) { + return i; + } + } + return -1; } } @@ -171,11 +183,20 @@ public class MapMarkersHelper { private String id; private String name; private int type; + private int color; + + public MarkersSyncGroup(@NonNull String id, @NonNull String name, int type, int color) { + this.id = id; + this.name = name; + this.type = type; + this.color = color; + } public MarkersSyncGroup(@NonNull String id, @NonNull String name, int type) { this.id = id; this.name = name; this.type = type; + this.color = -1; } public String getId() { @@ -189,6 +210,10 @@ public class MapMarkersHelper { public int getType() { return type; } + + public int getColor() { + return color; + } } public MapMarkersHelper(OsmandApplication ctx) { @@ -254,6 +279,55 @@ public class MapMarkersHelper { } } + public List getMarkersSortedByGroup() { + Map groupsMap = new LinkedHashMap<>(); + List noGroup = new ArrayList<>(); + for (MapMarker marker : mapMarkers) { + String groupName = marker.groupName; + if (groupName == null) { + noGroup.add(marker); + } else { + MapMarkerGroup group = groupsMap.get(groupName); + if (group == null) { + group = new MapMarkerGroup(groupName, marker.creationDate); + groupsMap.put(groupName, group); + } else { + long markerCreationDate = marker.creationDate; + if (markerCreationDate < group.getCreationDate()) { + group.setCreationDate(markerCreationDate); + } + } + group.getMapMarkers().add(marker); + } + } + List groups = new ArrayList<>(groupsMap.values()); + sortGroups(groups); + + List markers = new ArrayList<>(); + markers.addAll(noGroup); + for (MapMarkerGroup group : groups) { + markers.addAll(group.getMapMarkers()); + } + return markers; + } + + private void sortGroups(List groups) { + Collections.sort(groups, new Comparator() { + @Override + public int compare(MapMarkerGroup group1, MapMarkerGroup group2) { + long t1 = group1.creationDate; + long t2 = group2.creationDate; + if (t1 > t2) { + return -1; + } else if (t1 == t2) { + return 0; + } else { + return 1; + } + } + }); + } + private void sortHistoryMarkers() { sortMarkers(true, null); } @@ -335,7 +409,7 @@ public class MapMarkersHelper { List dbMarkers = markersDbHelper.getMarkersFromGroup(group); if (group.getType() == MarkersSyncGroup.FAVORITES_TYPE) { - FavouritesDbHelper.FavoriteGroup favGroup = ctx.getFavorites().getGroup(group.getName()); + FavoriteGroup favGroup = ctx.getFavorites().getGroup(group.getName()); if (favGroup == null) { return; } @@ -378,10 +452,13 @@ public class MapMarkersHelper { for (MapMarker marker : markers) { if (marker.id.equals(group.getId() + name)) { exists = true; - if (!marker.history && !marker.point.equals(latLon)) { + int colorIndex = MapMarker.getColorIndex(ctx, ColorDialogs.getNearestColor(group.getColor(), MapMarker.getColors(ctx))); + boolean updateColor = group.getColor() != -1 && marker.colorIndex != colorIndex; + if (!marker.history && (!marker.point.equals(latLon) || updateColor)) { for (MapMarker m : mapMarkers) { if (m.id.equals(marker.id)) { m.point = latLon; + m.colorIndex = colorIndex; updateMapMarker(m, true); break; } @@ -598,7 +675,8 @@ public class MapMarkersHelper { private void addMarkers(List points, List historyNames, @Nullable MarkersSyncGroup group) { if (points.size() > 0) { - int colorIndex = -1; + boolean randomColor = group == null || group.getColor() == -1; + int colorIndex = randomColor ? -1 : MapMarker.getColorIndex(ctx, ColorDialogs.getNearestColor(group.getColor(), MapMarker.getColors(ctx))); for (int i = 0; i < points.size(); i++) { LatLon point = points.get(i); PointDescription historyName = historyNames.get(i); @@ -611,14 +689,16 @@ public class MapMarkersHelper { if (pointDescription.isLocation() && Algorithms.isEmpty(pointDescription.getName())) { pointDescription.setName(PointDescription.getSearchAddressStr(ctx)); } - if (colorIndex == -1) { - if (mapMarkers.size() > 0) { - colorIndex = (mapMarkers.get(mapMarkers.size() - 1).colorIndex + 1) % MAP_MARKERS_COLORS_COUNT; + if (randomColor) { + if (colorIndex == -1) { + if (mapMarkers.size() > 0) { + colorIndex = (mapMarkers.get(mapMarkers.size() - 1).colorIndex + 1) % MAP_MARKERS_COLORS_COUNT; + } else { + colorIndex = 0; + } } else { - colorIndex = 0; + colorIndex = (colorIndex + 1) % MAP_MARKERS_COLORS_COUNT; } - } else { - colorIndex = (colorIndex + 1) % MAP_MARKERS_COLORS_COUNT; } MapMarker marker = new MapMarker(point, pointDescription, colorIndex, false, 0); @@ -775,4 +855,39 @@ public class MapMarkersHelper { } GPXUtilities.writeGpxFile(fout, file, ctx); } + + public static class MapMarkerGroup { + private String name; + private List mapMarkers = new ArrayList<>(); + private long creationDate; + + public MapMarkerGroup(String name, long creationDate) { + this.name = name; + this.creationDate = creationDate; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getMapMarkers() { + return mapMarkers; + } + + public void setMapMarkers(List mapMarkers) { + this.mapMarkers = mapMarkers; + } + + public long getCreationDate() { + return creationDate; + } + + public void setCreationDate(long creationDate) { + this.creationDate = creationDate; + } + } } diff --git a/OsmAnd/src/net/osmand/plus/activities/EditFavoriteGroupDialogFragment.java b/OsmAnd/src/net/osmand/plus/activities/EditFavoriteGroupDialogFragment.java index 3baa1d9318..9bb7048e14 100644 --- a/OsmAnd/src/net/osmand/plus/activities/EditFavoriteGroupDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/activities/EditFavoriteGroupDialogFragment.java @@ -176,7 +176,8 @@ public class EditFavoriteGroupDialogFragment extends BottomSheetDialogFragment { }); final MapMarkersHelper markersHelper = getMyApplication().getMapMarkersHelper(); - final MarkersSyncGroup syncGroup = new MarkersSyncGroup(group.name, group.name, MarkersSyncGroup.FAVORITES_TYPE); + final MarkersSyncGroup syncGroup = + new MarkersSyncGroup(group.name, group.name, MarkersSyncGroup.FAVORITES_TYPE, group.color); boolean groupSyncedWithMarkers = markersHelper.isGroupSynced(syncGroup.getId()); View addToMarkersView = view.findViewById(R.id.add_to_markers_view); diff --git a/OsmAnd/src/net/osmand/plus/activities/FavoritesTreeFragment.java b/OsmAnd/src/net/osmand/plus/activities/FavoritesTreeFragment.java index e187024fd6..3f19935655 100644 --- a/OsmAnd/src/net/osmand/plus/activities/FavoritesTreeFragment.java +++ b/OsmAnd/src/net/osmand/plus/activities/FavoritesTreeFragment.java @@ -407,7 +407,8 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment { List names = new LinkedList<>(); for (Map.Entry> entry : favoritesSelected.entrySet()) { FavoriteGroup favGr = helper.getGroup(entry.getKey()); - MarkersSyncGroup syncGr = new MarkersSyncGroup(favGr.name, favGr.name, MarkersSyncGroup.FAVORITES_TYPE); + MarkersSyncGroup syncGr = + new MarkersSyncGroup(favGr.name, favGr.name, MarkersSyncGroup.FAVORITES_TYPE, favGr.color); if (entry.getValue().size() == favGr.points.size()) { markersHelper.addMarkersSyncGroup(syncGr); } diff --git a/OsmAnd/src/net/osmand/plus/helpers/ColorDialogs.java b/OsmAnd/src/net/osmand/plus/helpers/ColorDialogs.java index 6618bad650..cc41d88242 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/ColorDialogs.java +++ b/OsmAnd/src/net/osmand/plus/helpers/ColorDialogs.java @@ -1,29 +1,29 @@ package net.osmand.plus.helpers; -import gnu.trove.list.array.TIntArrayList; - -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -import net.osmand.plus.OsmandApplication; -import net.osmand.plus.R; - import android.app.Activity; import android.content.Context; import android.content.res.Resources; +import android.graphics.Color; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.util.TypedValue; import android.view.View; import android.view.ViewGroup; -import android.widget.AdapterView.OnItemSelectedListener; import android.widget.AdapterView; +import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ArrayAdapter; -import android.widget.CheckedTextView; import android.widget.Spinner; import android.widget.TextView; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import gnu.trove.list.array.TIntArrayList; + import static android.util.TypedValue.COMPLEX_UNIT_DIP; public class ColorDialogs { @@ -39,7 +39,7 @@ public class ColorDialogs { R.string.rendering_value_pink_name, R.string.rendering_value_brown_name }; - + public static int[] pallette = new int[] { 0xb4d00d0d, 0xb4ff5020, @@ -66,6 +66,43 @@ public class ColorDialogs { "brown" }; + private static double getDistanceBetweenColors(int color1, int color2) { + double distance; + + double r1 = Color.red(color1); + double g1 = Color.green(color1); + double b1 = Color.blue(color1); + double a1 = Color.alpha(color1); + + double r2 = Color.red(color2); + double g2 = Color.green(color2); + double b2 = Color.blue(color2); + double a2 = Color.alpha(color2); + + distance = Math.sqrt(Math.pow(r1 - r2, 2) + Math.pow(g1 - g2, 2) + Math.pow(b1 - b2, 2)); + + if (distance == 0) { + distance = Math.sqrt(Math.pow(a1 - a2, 2)); + } + + return distance; + } + + public static int getNearestColor(int source, int[] colors) { + double distance = Double.MAX_VALUE; + + int index = 0; + for (int i = 0; i < colors.length; i++) { + double newDistance = getDistanceBetweenColors(source, colors[i]); + if (newDistance < distance) { + index = i; + distance = newDistance; + } + } + + return colors[index]; + } + public static int getColorByTag(String tag) { String t = tag.toLowerCase(); for (int i = 0; i < paletteColorTags.length; i++) { @@ -77,7 +114,7 @@ public class ColorDialogs { return 0; } - public static void setupColorSpinner(Context ctx, int selectedColor, final Spinner colorSpinner, + public static void setupColorSpinner(Context ctx, int selectedColor, final Spinner colorSpinner, final TIntArrayList colors) { OnItemSelectedListener listener = new OnItemSelectedListener() { @@ -93,7 +130,7 @@ public class ColorDialogs { @Override public void onNothingSelected(AdapterView parent) { } - + }; colors.add(pallette); List colorNames= new ArrayList(); @@ -175,7 +212,7 @@ public class ColorDialogs { public static int getRandomColor() { return pallette[new Random().nextInt(pallette.length)]; } - + public static String colorToString(int color) { String c = ""; if ((0xFF000000 & color) == 0xFF000000) { diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java index 328575d030..6ef6cbd9fa 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java @@ -9,14 +9,25 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import net.osmand.Location; +import net.osmand.data.LatLon; +import net.osmand.plus.OsmAndLocationProvider.OsmAndCompassListener; +import net.osmand.plus.OsmAndLocationProvider.OsmAndLocationListener; +import net.osmand.plus.OsmandApplication; import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.base.MapViewTrackingUtilities; +import net.osmand.plus.dashboard.DashLocationFragment; import net.osmand.plus.mapmarkers.adapters.MapMarkersGroupsAdapter; +import net.osmand.util.MapUtils; -public class MapMarkersGroupsFragment extends Fragment { +public class MapMarkersGroupsFragment extends Fragment implements OsmAndCompassListener, OsmAndLocationListener { public static final String TAG = "MapMarkersGroupsFragment"; private MapMarkersGroupsAdapter adapter; + private Float heading; + private Location location; + private boolean locationUpdateStarted; @Nullable @Override @@ -26,6 +37,7 @@ public class MapMarkersGroupsFragment extends Fragment { final MapActivity mapActivity = (MapActivity) getActivity(); adapter = new MapMarkersGroupsAdapter(mapActivity); + recyclerView.setAdapter(adapter); return recyclerView; } @@ -34,4 +46,91 @@ public class MapMarkersGroupsFragment extends Fragment { adapter.notifyDataSetChanged(); } } + + @Override + public void onResume() { + super.onResume(); + adapter.setScreenOrientation(DashLocationFragment.getScreenOrientation(getActivity())); + startLocationUpdate(); + } + + @Override + public void onPause() { + super.onPause(); + stopLocationUpdate(); + } + + void startLocationUpdate() { + OsmandApplication app = getMyApplication(); + if (app != null && !locationUpdateStarted) { + locationUpdateStarted = true; + app.getLocationProvider().removeCompassListener(app.getLocationProvider().getNavigationInfo()); + app.getLocationProvider().addCompassListener(this); + app.getLocationProvider().addLocationListener(this); + updateLocationUi(); + } + } + + void stopLocationUpdate() { + OsmandApplication app = getMyApplication(); + if (app != null && locationUpdateStarted) { + locationUpdateStarted = false; + app.getLocationProvider().removeLocationListener(this); + app.getLocationProvider().removeCompassListener(this); + app.getLocationProvider().addCompassListener(app.getLocationProvider().getNavigationInfo()); + } + } + + @Override + public void updateLocation(Location location) { + boolean newLocation = this.location == null && location != null; + boolean locationChanged = this.location != null && location != null + && this.location.getLatitude() != location.getLatitude() + && this.location.getLongitude() != location.getLongitude(); + if (newLocation || locationChanged) { + this.location = location; + updateLocationUi(); + } + } + + @Override + public void updateCompassValue(float value) { + // 99 in next line used to one-time initialize arrows (with reference vs. fixed-north direction) + // on non-compass devices + float lastHeading = heading != null ? heading : 99; + heading = value; + if (Math.abs(MapUtils.degreesDiff(lastHeading, heading)) > 5) { + updateLocationUi(); + } else { + heading = lastHeading; + } + } + + private OsmandApplication getMyApplication() { + if (getActivity() != null) { + return ((MapActivity) getActivity()).getMyApplication(); + } + return null; + } + + private void updateLocationUi() { + final MapActivity mapActivity = (MapActivity) getActivity(); + if (mapActivity != null && adapter != null) { + mapActivity.getMyApplication().runInUIThread(new Runnable() { + @Override + public void run() { + if (location == null) { + location = mapActivity.getMyApplication().getLocationProvider().getLastKnownLocation(); + } + MapViewTrackingUtilities utilities = mapActivity.getMapViewTrackingUtilities(); + boolean useCenter = !(utilities.isMapLinkedToLocation() && location != null); + + adapter.setUseCenter(useCenter); + adapter.setLocation(useCenter ? mapActivity.getMapLocation() : new LatLon(location.getLatitude(), location.getLongitude())); + adapter.setHeading(useCenter ? -mapActivity.getMapRotate() : heading != null ? heading : 99); + adapter.notifyDataSetChanged(); + } + }); + } + } } diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHistoryFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHistoryFragment.java index e40938ebd5..37aaa9d326 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHistoryFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHistoryFragment.java @@ -25,7 +25,7 @@ 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.MapMarkerHeaderViewHolder; import net.osmand.plus.mapmarkers.adapters.MapMarkerItemViewHolder; import net.osmand.plus.mapmarkers.adapters.MapMarkersHistoryAdapter; @@ -84,7 +84,7 @@ public class MapMarkersHistoryFragment extends Fragment implements MapMarkersHel @Override public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { - if (viewHolder instanceof MapMarkerDateViewHolder) { + if (viewHolder instanceof MapMarkerHeaderViewHolder) { return 0; } return super.getSwipeDirs(recyclerView, viewHolder); diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkerDateViewHolder.java b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkerHeaderViewHolder.java similarity index 76% rename from OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkerDateViewHolder.java rename to OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkerHeaderViewHolder.java index 7347d46604..8f6f7ddcc4 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkerDateViewHolder.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkerHeaderViewHolder.java @@ -7,12 +7,12 @@ import android.widget.TextView; import net.osmand.plus.R; -public class MapMarkerDateViewHolder extends RecyclerView.ViewHolder { +public class MapMarkerHeaderViewHolder extends RecyclerView.ViewHolder { final TextView date; final ImageButton optionsBtn; - public MapMarkerDateViewHolder(View itemView) { + public MapMarkerHeaderViewHolder(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/MapMarkersGroupsAdapter.java b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java index 1aebc80531..3d698fbae8 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java @@ -5,47 +5,218 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import net.osmand.data.LatLon; import net.osmand.plus.IconsCache; -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 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 MapMarkersGroupsAdapter extends RecyclerView.Adapter { +public class MapMarkersGroupsAdapter extends RecyclerView.Adapter { - private MapActivity mapActivity; - private List markers; + private static final int HEADER_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 items = new ArrayList<>(); private boolean night; + private int screenOrientation; + private LatLon location; + private Float heading; + private boolean useCenter; public MapMarkersGroupsAdapter(MapActivity mapActivity) { - this.mapActivity = mapActivity; - markers = mapActivity.getMyApplication().getMapMarkersHelper().getMapMarkers(); + this.app = mapActivity.getMyApplication(); night = !mapActivity.getMyApplication().getSettings().isLightContent(); + createDisplayGroups(); + } + + public void createDisplayGroups() { + items.clear(); + + List markersHistory = app.getMapMarkersHelper().getMarkersSortedByGroup(); + + int previousDateHeader = -1; + String previousNameHeader = ""; + int monthsDisplayed = 0; + + Calendar currentDateCalendar = Calendar.getInstance(); + currentDateCalendar.setTimeInMillis(System.currentTimeMillis()); + int currentDay = currentDateCalendar.get(Calendar.DAY_OF_YEAR); + int currentMonth = currentDateCalendar.get(Calendar.MONTH); + int currentYear = currentDateCalendar.get(Calendar.YEAR); + Calendar markerCalendar = Calendar.getInstance(); + for (int i = 0; i < markersHistory.size(); i++) { + MapMarker marker = markersHistory.get(i); + markerCalendar.setTimeInMillis(marker.creationDate); + int markerDay = markerCalendar.get(Calendar.DAY_OF_YEAR); + int markerMonth = markerCalendar.get(Calendar.MONTH); + int markerYear = markerCalendar.get(Calendar.YEAR); + String markerGroupName = marker.groupName; + if (markerGroupName != null && markerGroupName.equals("")) { + markerGroupName = app.getString(R.string.shared_string_favorites); + } + if (markerGroupName == null && markerYear == currentYear) { + if (markerDay == currentDay && previousDateHeader != TODAY_HEADER) { + items.add(TODAY_HEADER); + previousDateHeader = TODAY_HEADER; + } else if (markerDay == currentDay - 1 && previousDateHeader != YESTERDAY_HEADER) { + items.add(YESTERDAY_HEADER); + previousDateHeader = YESTERDAY_HEADER; + } else if (currentDay - markerDay >= 2 && currentDay - markerDay <= 8 && previousDateHeader != LAST_SEVEN_DAYS_HEADER) { + items.add(LAST_SEVEN_DAYS_HEADER); + previousDateHeader = LAST_SEVEN_DAYS_HEADER; + } else if (currentDay - markerDay > 8 && monthsDisplayed < 3 && previousDateHeader != markerMonth) { + items.add(markerMonth); + previousDateHeader = markerMonth; + monthsDisplayed += 1; + } else if (currentMonth - markerMonth >= 4 && previousDateHeader != THIS_YEAR_HEADER) { + items.add(THIS_YEAR_HEADER); + previousDateHeader = THIS_YEAR_HEADER; + } + } else if (markerGroupName == null && previousDateHeader != markerYear) { + items.add(markerYear); + previousDateHeader = markerYear; + } else if (markerGroupName != null && !previousNameHeader.equals(markerGroupName)) { + items.add(markerGroupName); + previousNameHeader = markerGroupName; + } + items.add(marker); + } + } + + public void setLocation(LatLon location) { + this.location = location; + } + + public void setHeading(Float heading) { + this.heading = heading; + } + + public void setUseCenter(boolean useCenter) { + this.useCenter = useCenter; + } + + public void setScreenOrientation(int screenOrientation) { + this.screenOrientation = screenOrientation; } @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); + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { + if (viewType == MARKER_TYPE) { + View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.map_marker_item_new, viewGroup, false); + return new MapMarkerItemViewHolder(view); + } else if (viewType == HEADER_TYPE) { + View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.map_marker_item_header, viewGroup, false); + return new MapMarkerHeaderViewHolder(view); + } else { + throw new IllegalArgumentException("Unsupported view type"); + } } @Override - public void onBindViewHolder(MapMarkerItemViewHolder mapMarkerItemViewHolder, int i) { - IconsCache iconsCache = mapActivity.getMyApplication().getIconsCache(); - MapMarkersHelper.MapMarker marker = markers.get(i); + public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { + IconsCache iconsCache = app.getIconsCache(); + if (holder instanceof MapMarkerItemViewHolder) { + final MapMarkerItemViewHolder itemViewHolder = (MapMarkerItemViewHolder) holder; + final MapMarker marker = (MapMarker) getItem(position); + itemViewHolder.iconReorder.setVisibility(View.GONE); + + int color = MapMarker.getColorId(marker.colorIndex); + itemViewHolder.icon.setImageDrawable(iconsCache.getIcon(R.drawable.ic_action_flag_dark, color)); + + itemViewHolder.title.setText(marker.getName(app)); + + itemViewHolder.description.setText(app.getString(R.string.passed, new SimpleDateFormat("MMM dd", Locale.getDefault()).format(new Date(marker.visitedDate)))); + + itemViewHolder.optionsBtn.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_reset_to_default_dark)); + itemViewHolder.optionsBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { +// int position = itemViewHolder.getAdapterPosition(); +// if (position < 0) { +// return; +// } +// app.getMapMarkersHelper().restoreMarkerFromHistory(marker, 0); +// notifyItemRemoved(position); + } + }); + itemViewHolder.flagIconLeftSpace.setVisibility(View.VISIBLE); + itemViewHolder.iconDirection.setVisibility(View.GONE); + itemViewHolder.leftPointSpace.setVisibility(View.GONE); + itemViewHolder.rightPointSpace.setVisibility(View.GONE); + if (position == getItemCount() - 1) { + itemViewHolder.bottomShadow.setVisibility(View.VISIBLE); + itemViewHolder.divider.setVisibility(View.GONE); + } else { + itemViewHolder.bottomShadow.setVisibility(View.GONE); + itemViewHolder.divider.setVisibility(View.VISIBLE); + } + } else if (holder instanceof MapMarkerHeaderViewHolder) { + final MapMarkerHeaderViewHolder dateViewHolder = (MapMarkerHeaderViewHolder) holder; + final Object header = getItem(position); + String headerString; + if (header instanceof Integer) { + Integer dateHeader = (Integer) header; + if (dateHeader == TODAY_HEADER) { + headerString = app.getString(R.string.today); + } else if (dateHeader == YESTERDAY_HEADER) { + headerString = app.getString(R.string.yesterday); + } else if (dateHeader == LAST_SEVEN_DAYS_HEADER) { + headerString = app.getString(R.string.last_seven_days); + } else if (dateHeader == THIS_YEAR_HEADER) { + headerString = app.getString(R.string.this_year); + } else if (dateHeader / 100 == 0) { + headerString = getMonth(dateHeader); + } else { + headerString = String.valueOf(dateHeader); + } + } else if (header instanceof String) { + headerString = (String) header; + } else { + throw new IllegalArgumentException("Unsupported header"); + } + dateViewHolder.date.setText(headerString); + } } + @Override + public int getItemViewType(int position) { + Object item = items.get(position); + if (item instanceof MapMarker) { + return MARKER_TYPE; + } else if (item instanceof String || item instanceof Integer) { + return HEADER_TYPE; + } else { + throw new IllegalArgumentException("Unsupported view type"); + } + } + @Override public int getItemCount() { - return markers.size(); + return items.size(); } - public MapMarkersHelper.MapMarker getItem(int position) { - return markers.get(position); + public Object getItem(int position) { + return items.get(position); } - public List getItems() { - return markers; - } + private String getMonth(int month) { + SimpleDateFormat dateFormat = new SimpleDateFormat("LLLL", Locale.getDefault()); + Date date = new Date(); + date.setMonth(month); + return dateFormat.format(date); + } } diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersHistoryAdapter.java b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersHistoryAdapter.java index c035fe1032..bb8e4d969c 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersHistoryAdapter.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersHistoryAdapter.java @@ -19,7 +19,7 @@ import java.util.Locale; public class MapMarkersHistoryAdapter extends RecyclerView.Adapter { - private static final int DATE_TYPE = 1; + private static final int HEADER_TYPE = 1; private static final int MARKER_TYPE = 2; private static final int TODAY_HEADER = 56; @@ -97,9 +97,9 @@ public class MapMarkersHistoryAdapter extends RecyclerView.Adapter