Merge pull request #11046 from osmandapp/master

update test branch
This commit is contained in:
Hardy 2021-03-02 00:53:51 +01:00 committed by GitHub
commit c519aa1341
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
119 changed files with 1873 additions and 733 deletions

View file

@ -4,6 +4,7 @@ import net.osmand.Location;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion; import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule; import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;
import net.osmand.data.LatLon;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils; import net.osmand.util.MapUtils;
import net.osmand.util.TransliterationHelper; import net.osmand.util.TransliterationHelper;
@ -37,7 +38,9 @@ public class RouteDataObject {
public int[] nameIds; public int[] nameIds;
// mixed array [0, height, cumulative_distance height, cumulative_distance, height, ...] - length is length(points)*2 // mixed array [0, height, cumulative_distance height, cumulative_distance, height, ...] - length is length(points)*2
public float[] heightDistanceArray = null; public float[] heightDistanceArray = null;
public float heightByCurrentLocation;
private static final Log LOG = PlatformUtil.getLog(RouteDataObject.class); private static final Log LOG = PlatformUtil.getLog(RouteDataObject.class);
public RouteDataObject(RouteRegion region) { public RouteDataObject(RouteRegion region) {
this.region = region; this.region = region;
} }
@ -165,53 +168,67 @@ public class RouteDataObject {
} }
public float[] calculateHeightArray() { public float[] calculateHeightArray() {
if(heightDistanceArray != null) { return calculateHeightArray(null);
}
public float[] calculateHeightArray(LatLon currentLocation) {
if (heightDistanceArray != null) {
return heightDistanceArray; return heightDistanceArray;
} }
int startHeight = Algorithms.parseIntSilently(getValue("osmand_ele_start"), HEIGHT_UNDEFINED); int startHeight = Algorithms.parseIntSilently(getValue("osmand_ele_start"), HEIGHT_UNDEFINED);
int endHeight = Algorithms.parseIntSilently(getValue("osmand_ele_end"), startHeight); int endHeight = Algorithms.parseIntSilently(getValue("osmand_ele_end"), startHeight);
if(startHeight == HEIGHT_UNDEFINED) { if (startHeight == HEIGHT_UNDEFINED) {
heightDistanceArray = new float[0]; heightDistanceArray = new float[0];
return heightDistanceArray; return heightDistanceArray;
} }
heightDistanceArray = new float[2*getPointsLength()]; heightDistanceArray = new float[2 * getPointsLength()];
double plon = 0; double plon = 0;
double plat = 0; double plat = 0;
float prevHeight = startHeight; float prevHeight = heightByCurrentLocation = startHeight;
for(int k = 0; k < getPointsLength(); k++) { double prevDistance = 0;
for (int k = 0; k < getPointsLength(); k++) {
double lon = MapUtils.get31LongitudeX(getPoint31XTile(k)); double lon = MapUtils.get31LongitudeX(getPoint31XTile(k));
double lat = MapUtils.get31LatitudeY(getPoint31YTile(k)); double lat = MapUtils.get31LatitudeY(getPoint31YTile(k));
if(k > 0) { if (k > 0) {
double dd = MapUtils.getDistance(plat, plon, lat, lon); double dd = MapUtils.getDistance(plat, plon, lat, lon);
float height = HEIGHT_UNDEFINED; float height = HEIGHT_UNDEFINED;
if(k == getPointsLength() - 1) { if (k == getPointsLength() - 1) {
height = endHeight; height = endHeight;
} else { } else {
String asc = getValue(k, "osmand_ele_asc"); String asc = getValue(k, "osmand_ele_asc");
if(asc != null && asc.length() > 0) { if (asc != null && asc.length() > 0) {
height = (prevHeight + Float.parseFloat(asc)); height = (prevHeight + Float.parseFloat(asc));
} else { } else {
String desc = getValue(k, "osmand_ele_desc"); String desc = getValue(k, "osmand_ele_desc");
if(desc != null && desc.length() > 0) { if (desc != null && desc.length() > 0) {
height = (prevHeight - Float.parseFloat(desc)); height = (prevHeight - Float.parseFloat(desc));
} }
} }
} }
heightDistanceArray[2*k] = (float) dd; heightDistanceArray[2 * k] = (float) dd;
heightDistanceArray[2*k+1] = height; heightDistanceArray[2 * k + 1] = height;
if(height != HEIGHT_UNDEFINED) {
if (currentLocation != null) {
double distance = MapUtils.getDistance(currentLocation, lat, lon);
if (height != HEIGHT_UNDEFINED && distance < prevDistance) {
prevDistance = distance;
heightByCurrentLocation = height;
}
}
if (height != HEIGHT_UNDEFINED) {
// interpolate undefined // interpolate undefined
double totalDistance = dd; double totalDistance = dd;
int startUndefined = k; int startUndefined = k;
while(startUndefined - 1 >= 0 && heightDistanceArray[2*(startUndefined - 1)+1] == HEIGHT_UNDEFINED) { while (startUndefined - 1 >= 0 && heightDistanceArray[2 * (startUndefined - 1) + 1] == HEIGHT_UNDEFINED) {
startUndefined --; startUndefined--;
totalDistance += heightDistanceArray[2*(startUndefined)]; totalDistance += heightDistanceArray[2 * (startUndefined)];
} }
if(totalDistance > 0) { if (totalDistance > 0) {
double angle = (height - prevHeight) / totalDistance; double angle = (height - prevHeight) / totalDistance;
for(int j = startUndefined; j < k; j++) { for (int j = startUndefined; j < k; j++) {
heightDistanceArray[2*j+1] = (float) ((heightDistanceArray[2*j] * angle) + heightDistanceArray[2*j-1]); heightDistanceArray[2 * j + 1] = (float) ((heightDistanceArray[2 * j] * angle) + heightDistanceArray[2 * j - 1]);
} }
} }
prevHeight = height; prevHeight = height;
@ -223,6 +240,9 @@ public class RouteDataObject {
} }
plat = lat; plat = lat;
plon = lon; plon = lon;
if (currentLocation != null) {
prevDistance = MapUtils.getDistance(currentLocation, plat, plon);
}
} }
return heightDistanceArray; return heightDistanceArray;
} }
@ -231,34 +251,34 @@ public class RouteDataObject {
return id; return id;
} }
public String getName(){ public String getName() {
if(names != null ) { if (names != null) {
return names.get(region.nameTypeRule); return names.get(region.nameTypeRule);
} }
return null; return null;
} }
public String getName(String lang){ public String getName(String lang) {
return getName(lang, false); return getName(lang, false);
} }
public String getName(String lang, boolean transliterate){ public String getName(String lang, boolean transliterate) {
if(names != null ) { if (names != null) {
if(Algorithms.isEmpty(lang)) { if (Algorithms.isEmpty(lang)) {
return names.get(region.nameTypeRule); return names.get(region.nameTypeRule);
} }
int[] kt = names.keys(); int[] kt = names.keys();
for(int i = 0 ; i < kt.length; i++) { for (int i = 0; i < kt.length; i++) {
int k = kt[i]; int k = kt[i];
if(region.routeEncodingRules.size() > k) { if (region.routeEncodingRules.size() > k) {
if(("name:"+lang).equals(region.routeEncodingRules.get(k).getTag())) { if (("name:" + lang).equals(region.routeEncodingRules.get(k).getTag())) {
return names.get(k); return names.get(k);
} }
} }
} }
String nmDef = names.get(region.nameTypeRule); String nmDef = names.get(region.nameTypeRule);
if(transliterate && nmDef != null && nmDef.length() > 0) { if (transliterate && nmDef != null && nmDef.length() > 0) {
return TransliterationHelper.transliterate(nmDef); return TransliterationHelper.transliterate(nmDef);
} }
return nmDef; return nmDef;
@ -279,20 +299,20 @@ public class RouteDataObject {
// return getDestinationRef(direction); // return getDestinationRef(direction);
//} //}
if (names != null) { if (names != null) {
if(Algorithms.isEmpty(lang)) { if (Algorithms.isEmpty(lang)) {
return names.get(region.refTypeRule); return names.get(region.refTypeRule);
} }
int[] kt = names.keys(); int[] kt = names.keys();
for(int i = 0 ; i < kt.length; i++) { for (int i = 0; i < kt.length; i++) {
int k = kt[i]; int k = kt[i];
if(region.routeEncodingRules.size() > k) { if (region.routeEncodingRules.size() > k) {
if(("ref:"+lang).equals(region.routeEncodingRules.get(k).getTag())) { if (("ref:" + lang).equals(region.routeEncodingRules.get(k).getTag())) {
return names.get(k); return names.get(k);
} }
} }
} }
String refDefault = names.get(region.refTypeRule); String refDefault = names.get(region.refTypeRule);
if(transliterate && refDefault != null && refDefault.length() > 0) { if (transliterate && refDefault != null && refDefault.length() > 0) {
return TransliterationHelper.transliterate(refDefault); return TransliterationHelper.transliterate(refDefault);
} }
return refDefault; return refDefault;
@ -307,13 +327,13 @@ public class RouteDataObject {
String refTagDefault = "destination:ref"; String refTagDefault = "destination:ref";
String refDefault = null; String refDefault = null;
for(int i = 0 ; i < kt.length; i++) { for (int i = 0; i < kt.length; i++) {
int k = kt[i]; int k = kt[i];
if(region.routeEncodingRules.size() > k) { if (region.routeEncodingRules.size() > k) {
if(refTag.equals(region.routeEncodingRules.get(k).getTag())) { if (refTag.equals(region.routeEncodingRules.get(k).getTag())) {
return names.get(k); return names.get(k);
} }
if(refTagDefault.equals(region.routeEncodingRules.get(k).getTag())) { if (refTagDefault.equals(region.routeEncodingRules.get(k).getTag())) {
refDefault = names.get(k); refDefault = names.get(k);
} }
} }
@ -326,12 +346,12 @@ public class RouteDataObject {
return null; return null;
} }
public String getDestinationName(String lang, boolean transliterate, boolean direction){ public String getDestinationName(String lang, boolean transliterate, boolean direction) {
//Issue #3289: Treat destination:ref like a destination, not like a ref //Issue #3289: Treat destination:ref like a destination, not like a ref
String destRef = ((getDestinationRef(direction) == null) || getDestinationRef(direction).equals(getRef(lang, transliterate, direction))) ? "" : getDestinationRef(direction); String destRef = ((getDestinationRef(direction) == null) || getDestinationRef(direction).equals(getRef(lang, transliterate, direction))) ? "" : getDestinationRef(direction);
String destRef1 = Algorithms.isEmpty(destRef) ? "" : destRef + ", "; String destRef1 = Algorithms.isEmpty(destRef) ? "" : destRef + ", ";
if(names != null) { if (names != null) {
int[] kt = names.keys(); int[] kt = names.keys();
// Issue #3181: Parse destination keys in this order: // Issue #3181: Parse destination keys in this order:
@ -341,35 +361,35 @@ public class RouteDataObject {
// destination // destination
String destinationTagLangFB = "destination:lang:XX"; String destinationTagLangFB = "destination:lang:XX";
if(!Algorithms.isEmpty(lang)) { if (!Algorithms.isEmpty(lang)) {
destinationTagLangFB = (direction == true) ? "destination:lang:" + lang + ":forward" : "destination:lang:" + lang + ":backward"; destinationTagLangFB = (direction == true) ? "destination:lang:" + lang + ":forward" : "destination:lang:" + lang + ":backward";
} }
String destinationTagFB = (direction == true) ? "destination:forward" : "destination:backward"; String destinationTagFB = (direction == true) ? "destination:forward" : "destination:backward";
String destinationTagLang = "destination:lang:XX"; String destinationTagLang = "destination:lang:XX";
if(!Algorithms.isEmpty(lang)) { if (!Algorithms.isEmpty(lang)) {
destinationTagLang = "destination:lang:" + lang; destinationTagLang = "destination:lang:" + lang;
} }
String destinationTagDefault = "destination"; String destinationTagDefault = "destination";
String destinationDefault = null; String destinationDefault = null;
for(int i = 0 ; i < kt.length; i++) { for (int i = 0; i < kt.length; i++) {
int k = kt[i]; int k = kt[i];
if(region.routeEncodingRules.size() > k) { if (region.routeEncodingRules.size() > k) {
if(!Algorithms.isEmpty(lang) && destinationTagLangFB.equals(region.routeEncodingRules.get(k).getTag())) { if (!Algorithms.isEmpty(lang) && destinationTagLangFB.equals(region.routeEncodingRules.get(k).getTag())) {
return destRef1 + ((transliterate) ? TransliterationHelper.transliterate(names.get(k)) : names.get(k)); return destRef1 + ((transliterate) ? TransliterationHelper.transliterate(names.get(k)) : names.get(k));
} }
if(destinationTagFB.equals(region.routeEncodingRules.get(k).getTag())) { if (destinationTagFB.equals(region.routeEncodingRules.get(k).getTag())) {
return destRef1 + ((transliterate) ? TransliterationHelper.transliterate(names.get(k)) : names.get(k)); return destRef1 + ((transliterate) ? TransliterationHelper.transliterate(names.get(k)) : names.get(k));
} }
if(!Algorithms.isEmpty(lang) && destinationTagLang.equals(region.routeEncodingRules.get(k).getTag())) { if (!Algorithms.isEmpty(lang) && destinationTagLang.equals(region.routeEncodingRules.get(k).getTag())) {
return destRef1 + ((transliterate) ? TransliterationHelper.transliterate(names.get(k)) : names.get(k)); return destRef1 + ((transliterate) ? TransliterationHelper.transliterate(names.get(k)) : names.get(k));
} }
if(destinationTagDefault.equals(region.routeEncodingRules.get(k).getTag())) { if (destinationTagDefault.equals(region.routeEncodingRules.get(k).getTag())) {
destinationDefault = names.get(k); destinationDefault = names.get(k);
} }
} }
} }
if(destinationDefault != null) { if (destinationDefault != null) {
return destRef1 + ((transliterate) ? TransliterationHelper.transliterate(destinationDefault) : destinationDefault); return destRef1 + ((transliterate) ? TransliterationHelper.transliterate(destinationDefault) : destinationDefault);
} }
} }
@ -400,14 +420,14 @@ public class RouteDataObject {
RestrictionInfo ri = new RestrictionInfo(); RestrictionInfo ri = new RestrictionInfo();
ri.toWay = getRestrictionId(k); ri.toWay = getRestrictionId(k);
ri.type = getRestrictionType(k); ri.type = getRestrictionType(k);
if(restrictionsVia != null && k < restrictionsVia.length) { if (restrictionsVia != null && k < restrictionsVia.length) {
ri.viaWay = restrictionsVia[k]; ri.viaWay = restrictionsVia[k];
} }
return ri; return ri;
} }
public long getRestrictionVia(int i) { public long getRestrictionVia(int i) {
if(restrictionsVia != null && restrictionsVia.length > i) { if (restrictionsVia != null && restrictionsVia.length > i) {
return restrictionsVia[i]; return restrictionsVia[i];
} }
return 0; return 0;
@ -441,7 +461,7 @@ public class RouteDataObject {
} }
if (insNames) { if (insNames) {
pointNames = new String[opointNames.length + 1][]; pointNames = new String[opointNames.length + 1][];
pointNameTypes = new int[opointNameTypes.length +1][]; pointNameTypes = new int[opointNameTypes.length + 1][];
} }
int i = 0; int i = 0;
for (; i < pos; i++) { for (; i < pos; i++) {
@ -590,7 +610,7 @@ public class RouteDataObject {
} }
public static float parseSpeed(String v, float def) { public static float parseSpeed(String v, float def) {
if(v.equals("none")) { if (v.equals("none")) {
return RouteDataObject.NONE_MAX_SPEED; return RouteDataObject.NONE_MAX_SPEED;
} else { } else {
int i = Algorithms.findFirstNumberEndIndex(v); int i = Algorithms.findFirstNumberEndIndex(v);
@ -614,20 +634,20 @@ public class RouteDataObject {
f += Float.parseFloat(v.substring(0, i)); f += Float.parseFloat(v.substring(0, i));
String pref = v.substring(i, v.length()).trim(); String pref = v.substring(i, v.length()).trim();
float add = 0; float add = 0;
for(int ik = 0; ik < pref.length(); ik++) { for (int ik = 0; ik < pref.length(); ik++) {
if(Algorithms.isDigit(pref.charAt(ik)) || pref.charAt(ik) == '.' || pref.charAt(ik) == '-') { if (Algorithms.isDigit(pref.charAt(ik)) || pref.charAt(ik) == '.' || pref.charAt(ik) == '-') {
int first = Algorithms.findFirstNumberEndIndex(pref.substring(ik)); int first = Algorithms.findFirstNumberEndIndex(pref.substring(ik));
if(first != -1) { if (first != -1) {
add = parseLength(pref.substring(ik), 0); add = parseLength(pref.substring(ik), 0);
pref = pref.substring(0, ik); pref = pref.substring(0, ik);
} }
break; break;
} }
} }
if(pref.contains("km")) { if (pref.contains("km")) {
f *= 1000; f *= 1000;
} }
if(pref.contains("\"") || pref.contains("in")) { if (pref.contains("\"") || pref.contains("in")) {
f *= 0.0254; f *= 0.0254;
} else if (pref.contains("\'") || pref.contains("ft") || pref.contains("feet")) { } else if (pref.contains("\'") || pref.contains("ft") || pref.contains("feet")) {
// foot to meters // foot to meters
@ -673,27 +693,27 @@ public class RouteDataObject {
return false; return false;
} }
public boolean roundabout(){ public boolean roundabout() {
int sz = types.length; int sz = types.length;
for(int i=0; i<sz; i++) { for (int i = 0; i < sz; i++) {
RouteTypeRule r = region.quickGetEncodingRule(types[i]); RouteTypeRule r = region.quickGetEncodingRule(types[i]);
if(r.roundabout()) { if (r.roundabout()) {
return true; return true;
} else if(r.onewayDirection() != 0 && loop()) { } else if (r.onewayDirection() != 0 && loop()) {
return true; return true;
} }
} }
return false; return false;
} }
public boolean tunnel(){ public boolean tunnel() {
int sz = types.length; int sz = types.length;
for(int i=0; i<sz; i++) { for (int i = 0; i < sz; i++) {
RouteTypeRule r = region.quickGetEncodingRule(types[i]); RouteTypeRule r = region.quickGetEncodingRule(types[i]);
if(r.getTag().equals("tunnel") && r.getValue().equals("yes")) { if (r.getTag().equals("tunnel") && r.getValue().equals("yes")) {
return true; return true;
} }
if(r.getTag().equals("layer") && r.getValue().equals("-1")) { if (r.getTag().equals("layer") && r.getValue().equals("-1")) {
return true; return true;
} }
} }
@ -882,7 +902,7 @@ public class RouteDataObject {
public boolean bearingVsRouteDirection(Location loc) { public boolean bearingVsRouteDirection(Location loc) {
boolean direction = true; boolean direction = true;
if(loc != null && loc.hasBearing()) { if (loc != null && loc.hasBearing()) {
double diff = MapUtils.alignAngleDifference(directionRoute(0, true) - loc.getBearing() / 180f * Math.PI); double diff = MapUtils.alignAngleDifference(directionRoute(0, true) - loc.getBearing() / 180f * Math.PI);
direction = Math.abs(diff) < Math.PI / 2f; direction = Math.abs(diff) < Math.PI / 2f;
} }
@ -932,13 +952,13 @@ public class RouteDataObject {
} }
public double distance(int startPoint, int endPoint) { public double distance(int startPoint, int endPoint) {
if(startPoint > endPoint) { if (startPoint > endPoint) {
int k = endPoint; int k = endPoint;
endPoint = startPoint; endPoint = startPoint;
startPoint = k; startPoint = k;
} }
double d = 0; double d = 0;
for(int k = startPoint; k < endPoint && k < getPointsLength() -1; k++) { for (int k = startPoint; k < endPoint && k < getPointsLength() - 1; k++) {
int x = getPoint31XTile(k); int x = getPoint31XTile(k);
int y = getPoint31YTile(k); int y = getPoint31YTile(k);
int kx = getPoint31XTile(k + 1); int kx = getPoint31XTile(k + 1);
@ -974,16 +994,16 @@ public class RouteDataObject {
// translate into meters // translate into meters
total += simplifyDistance(x, y, px, py); total += simplifyDistance(x, y, px, py);
} while (total < dist); } while (total < dist);
return -Math.atan2( x - px, y - py ); return -Math.atan2(x - px, y - py);
} }
private double simplifyDistance(int x, int y, int px, int py) { private double simplifyDistance(int x, int y, int px, int py) {
return Math.abs(px - x) * 0.011d + Math.abs(py - y) * 0.01863d; return Math.abs(px - x) * 0.011d + Math.abs(py - y) * 0.01863d;
} }
private static void assertTrueLength(String vl, float exp){ private static void assertTrueLength(String vl, float exp) {
float dest = parseLength(vl, 0); float dest = parseLength(vl, 0);
if(exp != dest) { if (exp != dest) {
System.err.println("FAIL " + vl + " " + dest); System.err.println("FAIL " + vl + " " + dest);
} else { } else {
System.out.println("OK " + vl); System.out.println("OK " + vl);
@ -1054,7 +1074,7 @@ public class RouteDataObject {
public RestrictionInfo next; // optional to simulate linked list public RestrictionInfo next; // optional to simulate linked list
public int length() { public int length() {
if(next == null) { if (next == null) {
return 1; return 1;
} }
return next.length() + 1; return next.length() + 1;
@ -1064,13 +1084,13 @@ public class RouteDataObject {
public void setRestriction(int k, long to, int type, long viaWay) { public void setRestriction(int k, long to, int type, long viaWay) {
long valto = (to << RouteDataObject.RESTRICTION_SHIFT) | ((long) type & RouteDataObject.RESTRICTION_MASK); long valto = (to << RouteDataObject.RESTRICTION_SHIFT) | ((long) type & RouteDataObject.RESTRICTION_MASK);
restrictions[k] = valto; restrictions[k] = valto;
if(viaWay != 0) { if (viaWay != 0) {
setRestrictionVia(k, viaWay); setRestrictionVia(k, viaWay);
} }
} }
public void setRestrictionVia(int k, long viaWay) { public void setRestrictionVia(int k, long viaWay) {
if(restrictionsVia != null) { if (restrictionsVia != null) {
long[] nrestrictionsVia = new long[Math.max(k + 1, restrictions.length)]; long[] nrestrictionsVia = new long[Math.max(k + 1, restrictions.length)];
System.arraycopy(restrictions, 0, nrestrictionsVia, 0, restrictions.length); System.arraycopy(restrictions, 0, nrestrictionsVia, 0, restrictions.length);
restrictionsVia = nrestrictionsVia; restrictionsVia = nrestrictionsVia;

View file

@ -0,0 +1,448 @@
package net.osmand.router;
import net.osmand.GPXUtilities;
import net.osmand.PlatformUtil;
import net.osmand.osm.edit.Node;
import net.osmand.osm.edit.OsmMapUtils;
import net.osmand.util.MapUtils;
import org.apache.commons.logging.Log;
import java.util.ArrayList;
import java.util.List;
public class RouteColorize {
public int zoom;
public double[] latitudes;
public double[] longitudes;
public double[] values;
public double minValue;
public double maxValue;
public double[][] palette;
private List<RouteColorizationPoint> dataList;
public static final int DARK_GREY = rgbaToDecimal(92, 92, 92, 255);
public static final int LIGHT_GREY = rgbaToDecimal(200, 200, 200, 255);
public static final int RED = rgbaToDecimal(255,1,1,255);
public static final int GREEN = rgbaToDecimal(46,185,0,191);
public static final int YELLOW = rgbaToDecimal(255,222,2,227);
public enum ValueType {
ELEVATION,
SPEED,
SLOPE,
NONE
}
private final int VALUE_INDEX = 0;
private final int DECIMAL_COLOR_INDEX = 1;//sRGB decimal format
private final int RED_COLOR_INDEX = 1;//RGB
private final int GREEN_COLOR_INDEX = 2;//RGB
private final int BLUE_COLOR_INDEX = 3;//RGB
private final int ALPHA_COLOR_INDEX = 4;//RGBA
private ValueType valueType;
public static int SLOPE_RANGE = 150;//150 meters
private static final double MIN_DIFFERENCE_SLOPE = 0.05d;//5%
private static final Log LOG = PlatformUtil.getLog(RouteColorize.class);
/**
* @param minValue can be NaN
* @param maxValue can be NaN
* @param palette array {{value,color},...} - color in sRGB (decimal) format OR {{value,RED,GREEN,BLUE,ALPHA},...} - color in RGBA format
*/
public RouteColorize(int zoom, double[] latitudes, double[] longitudes, double[] values, double minValue, double maxValue, double[][] palette) {
this.zoom = zoom;
this.latitudes = latitudes;
this.longitudes = longitudes;
this.values = values;
this.minValue = minValue;
this.maxValue = maxValue;
this.palette = palette;
if (Double.isNaN(minValue) || Double.isNaN(maxValue)) {
calculateMinMaxValue();
}
checkPalette();
sortPalette();
}
/**
* @param type ELEVATION, SPEED, SLOPE
*/
public RouteColorize(int zoom, GPXUtilities.GPXFile gpxFile, ValueType type) {
if (!gpxFile.hasTrkPt()) {
LOG.warn("GPX file is not consist of track points");
return;
}
List<Double> latList = new ArrayList<>();
List<Double> lonList = new ArrayList<>();
List<Double> valList = new ArrayList<>();
for (GPXUtilities.Track t : gpxFile.tracks) {
for (GPXUtilities.TrkSegment ts : t.segments) {
for (GPXUtilities.WptPt p : ts.points) {
latList.add(p.lat);
lonList.add(p.lon);
if (type == ValueType.SPEED) {
valList.add(p.speed);
} else {
valList.add(p.ele);
}
}
}
}
this.zoom = zoom;
latitudes = listToArray(latList);
longitudes = listToArray(lonList);
if (type == ValueType.SLOPE) {
values = calculateSlopesByElevations(latitudes, longitudes, listToArray(valList), SLOPE_RANGE);
} else {
values = listToArray(valList);
}
calculateMinMaxValue();
valueType = type;
checkPalette();
sortPalette();
}
/**
* Calculate slopes from elevations needs for right colorizing
*
* @param slopeRange - in what range calculate the derivative, usually we used 150 meters
* @return slopes array, in the begin and the end present NaN values!
*/
public double[] calculateSlopesByElevations(double[] latitudes, double[] longitudes, double[] elevations, double slopeRange) {
double[] newElevations = elevations;
for (int i = 2; i < elevations.length - 2; i++) {
newElevations[i] = elevations[i - 2]
+ elevations[i - 1]
+ elevations[i]
+ elevations[i + 1]
+ elevations[i + 2];
newElevations[i] /= 5;
}
elevations = newElevations;
double[] slopes = new double[elevations.length];
if (latitudes.length != longitudes.length || latitudes.length != elevations.length) {
LOG.warn("Sizes of arrays latitudes, longitudes and values are not match");
return slopes;
}
double[] distances = new double[elevations.length];
double totalDistance = 0.0d;
distances[0] = totalDistance;
for (int i = 0; i < elevations.length - 1; i++) {
totalDistance += MapUtils.getDistance(latitudes[i], longitudes[i], latitudes[i + 1], longitudes[i + 1]);
distances[i + 1] = totalDistance;
}
for (int i = 0; i < elevations.length; i++) {
if (distances[i] < slopeRange / 2 || distances[i] > totalDistance - slopeRange / 2) {
slopes[i] = Double.NaN;
} else {
double[] arg = findDerivativeArguments(distances, elevations, i, slopeRange);
slopes[i] = (arg[1] - arg[0]) / (arg[3] - arg[2]);
}
}
return slopes;
}
public List<RouteColorizationPoint> getResult(boolean simplify) {
List<RouteColorizationPoint> result = new ArrayList<>();
if (simplify) {
result = simplify();
} else {
for (int i = 0; i < latitudes.length; i++) {
result.add(new RouteColorizationPoint(i, latitudes[i], longitudes[i], values[i]));
}
}
for (RouteColorizationPoint data : result) {
data.color = getColorByValue(data.val);
}
return result;
}
public int getColorByValue(double value) {
if (Double.isNaN(value)) {
value = (minValue + maxValue) / 2;
}
for (int i = 0; i < palette.length - 1; i++) {
if (value == palette[i][VALUE_INDEX])
return (int) palette[i][DECIMAL_COLOR_INDEX];
if (value >= palette[i][VALUE_INDEX] && value <= palette[i + 1][VALUE_INDEX]) {
int minPaletteColor = (int) palette[i][DECIMAL_COLOR_INDEX];
int maxPaletteColor = (int) palette[i + 1][DECIMAL_COLOR_INDEX];
double minPaletteValue = palette[i][VALUE_INDEX];
double maxPaletteValue = palette[i + 1][VALUE_INDEX];
double percent = (value - minPaletteValue) / (maxPaletteValue - minPaletteValue);
double resultRed = getRed(minPaletteColor) + percent * (getRed(maxPaletteColor) - getRed(minPaletteColor));
double resultGreen = getGreen(minPaletteColor) + percent * (getGreen(maxPaletteColor) - getGreen(minPaletteColor));
double resultBlue = getBlue(minPaletteColor) + percent * (getBlue(maxPaletteColor) - getBlue(minPaletteColor));
double resultAlpha = getAlpha(minPaletteColor) + percent * (getAlpha(maxPaletteColor) - getAlpha(minPaletteColor));
return rgbaToDecimal((int) resultRed, (int) resultGreen, (int) resultBlue, (int) resultAlpha);
}
}
return getDefaultColor();
}
public void setPalette(double[][] palette) {
this.palette = palette;
checkPalette();
sortPalette();
}
private int getDefaultColor() {
return rgbaToDecimal(0, 0, 0, 0);
}
private List<RouteColorizationPoint> simplify() {
if (dataList == null) {
dataList = new ArrayList<>();
for (int i = 0; i < latitudes.length; i++) {
//System.out.println(latitudes[i] + " " + longitudes[i] + " " + values[i]);
dataList.add(new RouteColorizationPoint(i, latitudes[i], longitudes[i], values[i]));
}
}
List<Node> nodes = new ArrayList<>();
List<Node> result = new ArrayList<>();
for (RouteColorizationPoint data : dataList) {
nodes.add(new net.osmand.osm.edit.Node(data.lat, data.lon, data.id));
}
OsmMapUtils.simplifyDouglasPeucker(nodes, zoom + 5, 1, result, true);
List<RouteColorizationPoint> simplified = new ArrayList<>();
for (int i = 1; i < result.size() - 1; i++) {
int prevId = (int) result.get(i - 1).getId();
int currentId = (int) result.get(i).getId();
List<RouteColorizationPoint> sublist = dataList.subList(prevId, currentId);
simplified.addAll(getExtremums(sublist));
}
return simplified;
}
private List<RouteColorizationPoint> getExtremums(List<RouteColorizationPoint> subDataList) {
if (subDataList.size() <= 2) {
return subDataList;
}
List<RouteColorizationPoint> result = new ArrayList<>();
double min;
double max;
min = max = subDataList.get(0).val;
for (RouteColorizationPoint pt : subDataList) {
if (min > pt.val) {
min = pt.val;
}
if (max < pt.val) {
max = pt.val;
}
}
double diff = max - min;
result.add(subDataList.get(0));
for (int i = 1; i < subDataList.size() - 1; i++) {
double prev = subDataList.get(i - 1).val;
double current = subDataList.get(i).val;
double next = subDataList.get(i + 1).val;
RouteColorizationPoint currentData = subDataList.get(i);
if ((current > prev && current > next) || (current < prev && current < next)
|| (current < prev && current == next) || (current == prev && current < next)
|| (current > prev && current == next) || (current == prev && current > next)) {
RouteColorizationPoint prevInResult;
if (result.size() > 0) {
prevInResult = result.get(0);
if (prevInResult.val / diff > MIN_DIFFERENCE_SLOPE) {
result.add(currentData);
}
} else
result.add(currentData);
}
}
result.add(subDataList.get(subDataList.size() - 1));
return result;
}
private void checkPalette() {
if (palette == null || palette.length < 2 || palette[0].length < 2 || palette[1].length < 2) {
LOG.info("Will use default palette");
palette = new double[3][2];
double[][] defaultPalette = {
{minValue, GREEN},
{valueType == ValueType.SLOPE ? 0 : (minValue + maxValue) / 2, YELLOW},
{maxValue, RED}
};
palette = defaultPalette;
}
double min;
double max = min = palette[0][VALUE_INDEX];
int minIndex = 0;
int maxIndex = 0;
double[][] sRGBPalette = new double[palette.length][2];
for (int i = 0; i < palette.length; i++) {
double[] p = palette[i];
if (p.length == 2) {
sRGBPalette[i] = p;
} else if (p.length == 4) {
int color = rgbaToDecimal((int) p[RED_COLOR_INDEX], (int) p[GREEN_COLOR_INDEX], (int) p[BLUE_COLOR_INDEX], 255);
sRGBPalette[i] = new double[]{p[VALUE_INDEX], color};
} else if (p.length >= 5) {
int color = rgbaToDecimal((int) p[RED_COLOR_INDEX], (int) p[GREEN_COLOR_INDEX], (int) p[BLUE_COLOR_INDEX], (int) p[ALPHA_COLOR_INDEX]);
sRGBPalette[i] = new double[]{p[VALUE_INDEX], color};
}
if (p[VALUE_INDEX] > max) {
max = p[VALUE_INDEX];
maxIndex = i;
}
if (p[VALUE_INDEX] < min) {
min = p[VALUE_INDEX];
minIndex = i;
}
}
palette = sRGBPalette;
if (minValue < min) {
palette[minIndex][VALUE_INDEX] = minValue;
}
if (maxValue > max) {
palette[maxIndex][VALUE_INDEX] = maxValue;
}
}
private void sortPalette() {
java.util.Arrays.sort(palette, new java.util.Comparator<double[]>() {
public int compare(double[] a, double[] b) {
return Double.compare(a[VALUE_INDEX], b[VALUE_INDEX]);
}
});
}
/**
* @return double[minElevation, maxElevation, minDist, maxDist]
*/
private double[] findDerivativeArguments(double[] distances, double[] elevations, int index, double slopeRange) {
double[] result = new double[4];
double minDist = distances[index] - slopeRange / 2;
double maxDist = distances[index] + slopeRange / 2;
result[0] = Double.NaN;
result[1] = Double.NaN;
result[2] = minDist;
result[3] = maxDist;
int closestMaxIndex = -1;
int closestMinIndex = -1;
for (int i = index; i < distances.length; i++) {
if (distances[i] == maxDist) {
result[1] = elevations[i];
break;
}
if (distances[i] > maxDist) {
closestMaxIndex = i;
break;
}
}
for (int i = index; i >= 0; i--) {
if (distances[i] == minDist) {
result[0] = elevations[i];
break;
}
if (distances[i] < minDist) {
closestMinIndex = i;
break;
}
}
if (closestMaxIndex > 0) {
double diff = distances[closestMaxIndex] - distances[closestMaxIndex - 1];
double coef = (maxDist - distances[closestMaxIndex - 1]) / diff;
if (coef > 1 || coef < 0) {
LOG.warn("Coefficient fo max must be 0..1 , coef=" + coef);
}
result[1] = (1 - coef) * elevations[closestMaxIndex - 1] + coef * elevations[closestMaxIndex];
}
if (closestMinIndex >= 0) {
double diff = distances[closestMinIndex + 1] - distances[closestMinIndex];
double coef = (minDist - distances[closestMinIndex]) / diff;
if (coef > 1 || coef < 0) {
LOG.warn("Coefficient for min must be 0..1 , coef=" + coef);
}
result[0] = (1 - coef) * elevations[closestMinIndex] + coef * elevations[closestMinIndex + 1];
}
if (Double.isNaN(result[0]) || Double.isNaN(result[1])) {
LOG.warn("Elevations wasn't calculated");
}
return result;
}
private void calculateMinMaxValue() {
if (values.length == 0)
return;
minValue = maxValue = Double.NaN;
for (double value : values) {
if ((Double.isNaN(maxValue) || Double.isNaN(minValue)) && !Double.isNaN(value))
maxValue = minValue = value;
if (minValue > value)
minValue = value;
if (maxValue < value)
maxValue = value;
}
}
private double[] listToArray(List<Double> doubleList) {
double[] result = new double[doubleList.size()];
for (int i = 0; i < doubleList.size(); i++) {
result[i] = doubleList.get(i);
}
return result;
}
private static int rgbaToDecimal(int r, int g, int b, int a) {
int value = ((a & 0xFF) << 24) |
((r & 0xFF) << 16) |
((g & 0xFF) << 8) |
((b & 0xFF) << 0);
return value;
}
private int getRed(int value) {
return (value >> 16) & 0xFF;
}
private int getGreen(int value) {
return (value >> 8) & 0xFF;
}
private int getBlue(int value) {
return (value >> 0) & 0xFF;
}
private int getAlpha(int value) {
return (value >> 24) & 0xff;
}
public static class RouteColorizationPoint {
int id;
public double lat;
public double lon;
public double val;
public int color;
RouteColorizationPoint(int id, double lat, double lon, double val) {
this.id = id;
this.lat = lat;
this.lon = lon;
this.val = val;
}
}
}

View file

@ -53,6 +53,8 @@ public class Algorithms {
public static final int XML_FILE_SIGNATURE = 0x3c3f786d; public static final int XML_FILE_SIGNATURE = 0x3c3f786d;
public static final int OBF_FILE_SIGNATURE = 0x08029001; public static final int OBF_FILE_SIGNATURE = 0x08029001;
public static final int SQLITE_FILE_SIGNATURE = 0x53514C69; public static final int SQLITE_FILE_SIGNATURE = 0x53514C69;
public static final int BZIP_FILE_SIGNATURE = 0x425a;
public static final int GZIP_FILE_SIGNATURE = 0x1f8b;
public static String normalizeSearchText(String s) { public static String normalizeSearchText(String s) {
boolean norm = false; boolean norm = false;
@ -322,6 +324,24 @@ public class Algorithms {
return test == ZIP_FILE_SIGNATURE; return test == ZIP_FILE_SIGNATURE;
} }
public static boolean checkFileSignature(InputStream inputStream, int fileSignature) throws IOException {
if (inputStream == null) return false;
int firstBytes;
if (isSmallFileSignature(fileSignature)) {
firstBytes = readSmallInt(inputStream);
} else {
firstBytes = readInt(inputStream);
}
if (inputStream.markSupported()) {
inputStream.reset();
}
return firstBytes == fileSignature;
}
public static boolean isSmallFileSignature(int fileSignature) {
return fileSignature == BZIP_FILE_SIGNATURE || fileSignature == GZIP_FILE_SIGNATURE;
}
/** /**
* Checks, whether the child directory is a subdirectory of the parent * Checks, whether the child directory is a subdirectory of the parent
* directory. * directory.
@ -358,6 +378,14 @@ public class Algorithms {
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + ch4); return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + ch4);
} }
public static int readSmallInt(InputStream in) throws IOException {
int ch1 = in.read();
int ch2 = in.read();
if ((ch1 | ch2) < 0)
throw new EOFException();
return ((ch1 << 8) + ch2);
}
public static String capitalizeFirstLetterAndLowercase(String s) { public static String capitalizeFirstLetterAndLowercase(String s) {
if (s != null && s.length() > 1) { if (s != null && s.length() > 1) {
// not very efficient algorithm // not very efficient algorithm
@ -537,6 +565,13 @@ public class Algorithms {
} }
} }
public static ByteArrayInputStream createByteArrayIS(InputStream in) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
streamCopy(in, out);
in.close();
return new ByteArrayInputStream(out.toByteArray());
}
@SuppressWarnings("ResultOfMethodCallIgnored") @SuppressWarnings("ResultOfMethodCallIgnored")
public static void updateAllExistingImgTilesToOsmandFormat(File f) { public static void updateAllExistingImgTilesToOsmandFormat(File f) {
if (f.isDirectory()) { if (f.isDirectory()) {

View file

@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M6,2C4.8954,2 4,2.8954 4,4V20C4,21.1046 4.8954,22 6,22H18C19.1046,22 20,21.1046 20,20V8H16C14.8954,8 14,7.1046 14,6V2H6ZM9,9H7V11H9V9ZM7,13H9V15H7V13ZM7,17H9V19H7V17ZM11,11V9H17V11H11ZM17,15V13H11V15H17ZM17,19V17H11V19H17Z"
android:fillColor="#ffffff"
android:fillType="evenOdd"/>
<path
android:pathData="M14,2L20,8H16C14.8954,8 14,7.1046 14,6V2Z"
android:strokeAlpha="0.5"
android:fillColor="#ffffff"
android:fillAlpha="0.5"/>
<path
android:pathData="M17,9H11V11H17V9Z"
android:strokeAlpha="0.2"
android:fillColor="#ffffff"
android:fillAlpha="0.2"/>
<path
android:pathData="M11,13H17V15H11V13Z"
android:strokeAlpha="0.2"
android:fillColor="#ffffff"
android:fillAlpha="0.2"/>
<path
android:pathData="M11,17H17V19H11V17Z"
android:strokeAlpha="0.2"
android:fillColor="#ffffff"
android:fillAlpha="0.2"/>
</vector>

View file

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M12,0.9999L16,4.9999L12,8.9999L12,6C8.6863,6 6,8.6863 6,12C6,12.7351 6.1322,13.4394 6.3741,14.0903L4.8574,15.6071C4.309,14.5232 4,13.2977 4,12C4,7.5817 7.5817,4 12,4V0.9999Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M12,15.0001L12,18C15.3137,18 18,15.3137 18,12C18,11.2649 17.8678,10.5606 17.6258,9.9097L19.1426,8.3929C19.691,9.4768 20,10.7023 20,12C20,16.4183 16.4183,20 12,20V23.0001L8,19.0001L12,15.0001Z"
android:fillColor="#ffffff"/>
</vector>

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<net.osmand.plus.widgets.FlowLayout
android:id="@+id/color_items"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp" />
</LinearLayout>

View file

@ -21,12 +21,12 @@
<PreferenceCategory <PreferenceCategory
android:key="select_color" android:key="select_color"
android:layout="@layout/preference_category_with_descr" android:layout="@layout/preference_category_with_right_text"
android:title="@string/select_color" /> android:title="@string/select_color" />
<Preference <Preference
android:key="color_items" android:key="color_items"
android:layout="@layout/preference_color_select" android:layout="@layout/preference_colors_card"
android:title="@string/select_color" android:title="@string/select_color"
android:selectable="false"/> android:selectable="false"/>

View file

@ -336,6 +336,43 @@ public class AndroidUtils {
); );
} }
public static ColorStateList createCheckedColorIntStateList(@ColorInt int normal, @ColorInt int checked) {
return createCheckedColorIntStateList(false, normal, checked, 0, 0);
}
public static ColorStateList createCheckedColorIntStateList(boolean night,
@ColorInt int lightNormal, @ColorInt int lightChecked,
@ColorInt int darkNormal, @ColorInt int darkChecked) {
return createColorIntStateList(night, android.R.attr.state_checked,
lightNormal, lightChecked, darkNormal, darkChecked);
}
public static ColorStateList createEnabledColorIntStateList(@ColorInt int normal, @ColorInt int pressed) {
return createEnabledColorIntStateList(false, normal, pressed, 0, 0);
}
public static ColorStateList createEnabledColorIntStateList(boolean night,
@ColorInt int lightNormal, @ColorInt int lightPressed,
@ColorInt int darkNormal, @ColorInt int darkPressed) {
return createColorIntStateList(night, android.R.attr.state_enabled,
lightNormal, lightPressed, darkNormal, darkPressed);
}
private static ColorStateList createColorIntStateList(boolean night, int state,
@ColorInt int lightNormal, @ColorInt int lightState,
@ColorInt int darkNormal, @ColorInt int darkState) {
return new ColorStateList(
new int[][]{
new int[]{state},
new int[]{}
},
new int[]{
night ? darkState : lightState,
night ? darkNormal : lightNormal
}
);
}
public static StateListDrawable createCheckedStateListDrawable(Drawable normal, Drawable checked) { public static StateListDrawable createCheckedStateListDrawable(Drawable normal, Drawable checked) {
return createStateListDrawable(normal, checked, android.R.attr.state_checked); return createStateListDrawable(normal, checked, android.R.attr.state_checked);
} }

View file

@ -133,7 +133,7 @@ public class ConnectedApp implements Comparable<ConnectedApp> {
CompoundButton btn = view.findViewById(R.id.toggle_item); CompoundButton btn = view.findViewById(R.id.toggle_item);
if (btn != null && btn.getVisibility() == View.VISIBLE) { if (btn != null && btn.getVisibility() == View.VISIBLE) {
btn.setChecked(!btn.isChecked()); btn.setChecked(!btn.isChecked());
menuAdapter.getItem(position).setColorRes(btn.isChecked() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); menuAdapter.getItem(position).setColor(app, btn.isChecked() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID);
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
return false; return false;
} }
@ -146,7 +146,7 @@ public class ConnectedApp implements Comparable<ConnectedApp> {
if (layersPref.set(isChecked)) { if (layersPref.set(isChecked)) {
ContextMenuItem item = adapter.getItem(position); ContextMenuItem item = adapter.getItem(position);
if (item != null) { if (item != null) {
item.setColorRes(isChecked ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); item.setColor(app, isChecked ? R.color.osmand_orange : ContextMenuItem.INVALID_ID);
item.setSelected(isChecked); item.setSelected(isChecked);
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
} }
@ -162,7 +162,7 @@ public class ConnectedApp implements Comparable<ConnectedApp> {
.setListener(listener) .setListener(listener)
.setSelected(layersEnabled) .setSelected(layersEnabled)
.setIcon(R.drawable.ic_extension_dark) .setIcon(R.drawable.ic_extension_dark)
.setColor(layersEnabled ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setColor(app, layersEnabled ? R.color.osmand_orange : ContextMenuItem.INVALID_ID)
.createItem()); .createItem());
} }

View file

@ -417,8 +417,12 @@ public class OsmandAidlApi {
} }
private void registerReceiver(BroadcastReceiver rec, MapActivity ma, String filter) { private void registerReceiver(BroadcastReceiver rec, MapActivity ma, String filter) {
try {
receivers.put(filter, rec); receivers.put(filter, rec);
ma.registerReceiver(rec, new IntentFilter(filter)); ma.registerReceiver(rec, new IntentFilter(filter));
} catch (IllegalStateException e) {
LOG.error(e);
}
} }
private void registerRemoveMapWidgetReceiver(MapActivity mapActivity) { private void registerRemoveMapWidgetReceiver(MapActivity mapActivity) {

View file

@ -11,6 +11,9 @@ import androidx.annotation.Nullable;
import androidx.annotation.StringRes; import androidx.annotation.StringRes;
import net.osmand.GPXUtilities.WptPt; import net.osmand.GPXUtilities.WptPt;
import net.osmand.Location;
import net.osmand.ResultMatcher;
import net.osmand.binary.RouteDataObject;
import net.osmand.plus.FavouritesDbHelper; import net.osmand.plus.FavouritesDbHelper;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.settings.backend.BooleanPreference; import net.osmand.plus.settings.backend.BooleanPreference;
@ -42,6 +45,8 @@ public class FavouritePoint implements Serializable, LocationPoint {
private boolean visible = true; private boolean visible = true;
private SpecialPointType specialPointType = null; private SpecialPointType specialPointType = null;
private BackgroundType backgroundType = null; private BackgroundType backgroundType = null;
private double altitude;
private long timestamp;
public FavouritePoint() { public FavouritePoint() {
} }
@ -50,10 +55,24 @@ public class FavouritePoint implements Serializable, LocationPoint {
this.latitude = latitude; this.latitude = latitude;
this.longitude = longitude; this.longitude = longitude;
this.category = category; this.category = category;
if(name == null) { if (name == null) {
name = ""; name = "";
} }
this.name = name; this.name = name;
timestamp = System.currentTimeMillis();
initPersonalType();
}
public FavouritePoint(double latitude, double longitude, String name, String category, double altitude, long timestamp) {
this.latitude = latitude;
this.longitude = longitude;
this.category = category;
if (name == null) {
name = "";
}
this.name = name;
this.altitude = altitude;
this.timestamp = timestamp != 0 ? timestamp : System.currentTimeMillis();
initPersonalType(); initPersonalType();
} }
@ -69,19 +88,50 @@ public class FavouritePoint implements Serializable, LocationPoint {
this.address = favouritePoint.address; this.address = favouritePoint.address;
this.iconId = favouritePoint.iconId; this.iconId = favouritePoint.iconId;
this.backgroundType = favouritePoint.backgroundType; this.backgroundType = favouritePoint.backgroundType;
this.altitude = favouritePoint.altitude;
this.timestamp = favouritePoint.timestamp;
initPersonalType(); initPersonalType();
} }
private void initPersonalType() { private void initPersonalType() {
if(FavouritesDbHelper.FavoriteGroup.PERSONAL_CATEGORY.equals(category)) { if (FavouritesDbHelper.FavoriteGroup.PERSONAL_CATEGORY.equals(category)) {
for(SpecialPointType p : SpecialPointType.values()) { for (SpecialPointType p : SpecialPointType.values()) {
if(p.typeName.equals(this.name)) { if (p.typeName.equals(this.name)) {
this.specialPointType = p; this.specialPointType = p;
} }
} }
} }
} }
public void initAltitude(OsmandApplication app) {
initAltitude(app, null);
}
public void initAltitude(OsmandApplication app, final Runnable callback) {
Location location = new Location("", latitude, longitude);
app.getLocationProvider().getRouteSegment(location, null, false,
new ResultMatcher<RouteDataObject>() {
@Override
public boolean publish(RouteDataObject routeDataObject) {
if (routeDataObject != null) {
LatLon latLon = new LatLon(latitude, longitude);
routeDataObject.calculateHeightArray(latLon);
altitude = routeDataObject.heightByCurrentLocation;
}
if (callback != null) {
callback.run();
}
return true;
}
@Override
public boolean isCancelled() {
return false;
}
});
}
public SpecialPointType getSpecialPointType() { public SpecialPointType getSpecialPointType() {
return specialPointType; return specialPointType;
} }
@ -171,6 +221,22 @@ public class FavouritePoint implements Serializable, LocationPoint {
this.longitude = longitude; this.longitude = longitude;
} }
public double getAltitude() {
return altitude;
}
public void setAltitude(double altitude) {
this.altitude = altitude;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
public String getCategory() { public String getCategory() {
return category; return category;
} }
@ -200,7 +266,7 @@ public class FavouritePoint implements Serializable, LocationPoint {
initPersonalType(); initPersonalType();
} }
public String getDescription () { public String getDescription() {
return description; return description;
} }
@ -256,7 +322,8 @@ public class FavouritePoint implements Serializable, LocationPoint {
} else if (!originObjectName.equals(fp.originObjectName)) } else if (!originObjectName.equals(fp.originObjectName))
return false; return false;
return (this.latitude == fp.latitude) && (this.longitude == fp.longitude); return (this.latitude == fp.latitude) && (this.longitude == fp.longitude) &&
(this.altitude == fp.altitude) && (this.timestamp == fp.timestamp);
} }
@Override @Override
@ -265,6 +332,8 @@ public class FavouritePoint implements Serializable, LocationPoint {
int result = 1; int result = 1;
result = prime * result + (int) Math.floor(latitude * 10000); result = prime * result + (int) Math.floor(latitude * 10000);
result = prime * result + (int) Math.floor(longitude * 10000); result = prime * result + (int) Math.floor(longitude * 10000);
result = prime * result + (int) Math.floor(altitude * 10000);
result = prime * result + (int) Math.floor(timestamp * 10000);
result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((category == null) ? 0 : category.hashCode()); result = prime * result + ((category == null) ? 0 : category.hashCode());
result = prime * result + ((description == null) ? 0 : description.hashCode()); result = prime * result + ((description == null) ? 0 : description.hashCode());
@ -289,7 +358,9 @@ public class FavouritePoint implements Serializable, LocationPoint {
this.iconId = iconId; this.iconId = iconId;
} }
public String getCategory() { return FavouritesDbHelper.FavoriteGroup.PERSONAL_CATEGORY; } public String getCategory() {
return FavouritesDbHelper.FavoriteGroup.PERSONAL_CATEGORY;
}
public String getName() { public String getName() {
return typeName; return typeName;
@ -384,7 +455,7 @@ public class FavouritePoint implements Serializable, LocationPoint {
name = ""; name = "";
} }
FavouritePoint fp; FavouritePoint fp;
fp = new FavouritePoint(pt.lat, pt.lon, name, categoryName); fp = new FavouritePoint(pt.lat, pt.lon, name, categoryName, pt.ele, pt.time);
fp.setDescription(pt.desc); fp.setDescription(pt.desc);
if (pt.comment != null) { if (pt.comment != null) {
fp.setOriginObjectName(pt.comment); fp.setOriginObjectName(pt.comment);
@ -405,6 +476,8 @@ public class FavouritePoint implements Serializable, LocationPoint {
WptPt pt = new WptPt(); WptPt pt = new WptPt();
pt.lat = getLatitude(); pt.lat = getLatitude();
pt.lon = getLongitude(); pt.lon = getLongitude();
pt.ele = getAltitude();
pt.time = getTimestamp();
if (!isVisible()) { if (!isVisible()) {
pt.getExtensionsToWrite().put(HIDDEN, "true"); pt.getExtensionsToWrite().put(HIDDEN, "true");
} }

View file

@ -249,8 +249,7 @@ public class ContextMenuAdapter {
final ContextMenuItem item = getItem(position); final ContextMenuItem item = getItem(position);
int layoutId = item.getLayout(); int layoutId = item.getLayout();
layoutId = layoutId != ContextMenuItem.INVALID_ID ? layoutId : DEFAULT_LAYOUT_ID; layoutId = layoutId != ContextMenuItem.INVALID_ID ? layoutId : DEFAULT_LAYOUT_ID;
int currentModeColorRes = app.getSettings().getApplicationMode().getIconColorInfo().getColor(nightMode); int currentModeColor = app.getSettings().getApplicationMode().getProfileColor(nightMode);
int currentModeColor = ContextCompat.getColor(app, currentModeColorRes);
if (layoutId == R.layout.mode_toggles) { if (layoutId == R.layout.mode_toggles) {
final Set<ApplicationMode> selected = new LinkedHashSet<>(); final Set<ApplicationMode> selected = new LinkedHashSet<>();
return AppModeDialog.prepareAppModeDrawerView((Activity) getContext(), return AppModeDialog.prepareAppModeDrawerView((Activity) getContext(),
@ -278,15 +277,13 @@ public class ContextMenuAdapter {
} }
if (layoutId == R.layout.main_menu_drawer_btn_switch_profile || if (layoutId == R.layout.main_menu_drawer_btn_switch_profile ||
layoutId == R.layout.main_menu_drawer_btn_configure_profile) { layoutId == R.layout.main_menu_drawer_btn_configure_profile) {
int colorResId = item.getColorRes(); int colorNoAlpha = item.getColor();
int colorNoAlpha = ContextCompat.getColor(app, colorResId);
TextView title = convertView.findViewById(R.id.title); TextView title = convertView.findViewById(R.id.title);
title.setText(item.getTitle()); title.setText(item.getTitle());
if (layoutId == R.layout.main_menu_drawer_btn_switch_profile) { if (layoutId == R.layout.main_menu_drawer_btn_switch_profile) {
ImageView icon = convertView.findViewById(R.id.icon); ImageView icon = convertView.findViewById(R.id.icon);
icon.setImageDrawable(mIconsCache.getIcon(item.getIcon(), colorResId)); icon.setImageDrawable(mIconsCache.getPaintedIcon(item.getIcon(), colorNoAlpha));
ImageView icArrow = convertView.findViewById(R.id.ic_expand_list); ImageView icArrow = convertView.findViewById(R.id.ic_expand_list);
icArrow.setImageDrawable(mIconsCache.getIcon(item.getSecondaryIcon())); icArrow.setImageDrawable(mIconsCache.getIcon(item.getSecondaryIcon()));
TextView desc = convertView.findViewById(R.id.description); TextView desc = convertView.findViewById(R.id.description);
@ -306,11 +303,8 @@ public class ContextMenuAdapter {
return convertView; return convertView;
} }
if (layoutId == R.layout.profile_list_item) { if (layoutId == R.layout.profile_list_item) {
int tag = item.getTag(); int tag = item.getTag();
int colorNoAlpha = item.getColor();
int colorResId = item.getColorRes();
int colorNoAlpha = ContextCompat.getColor(app, colorResId);
TextView title = convertView.findViewById(R.id.title); TextView title = convertView.findViewById(R.id.title);
TextView desc = convertView.findViewById(R.id.description); TextView desc = convertView.findViewById(R.id.description);
ImageView icon = convertView.findViewById(R.id.icon); ImageView icon = convertView.findViewById(R.id.icon);
@ -331,7 +325,7 @@ public class ContextMenuAdapter {
AndroidUiHelper.updateVisibility(icon, true); AndroidUiHelper.updateVisibility(icon, true);
AndroidUiHelper.updateVisibility(desc, true); AndroidUiHelper.updateVisibility(desc, true);
AndroidUtils.setTextPrimaryColor(app, title, nightMode); AndroidUtils.setTextPrimaryColor(app, title, nightMode);
icon.setImageDrawable(mIconsCache.getIcon(item.getIcon(), colorResId)); icon.setImageDrawable(mIconsCache.getPaintedIcon(item.getIcon(), colorNoAlpha));
desc.setText(item.getDescription()); desc.setText(item.getDescription());
boolean selectedMode = tag == PROFILES_CHOSEN_PROFILE_TAG; boolean selectedMode = tag == PROFILES_CHOSEN_PROFILE_TAG;
if (selectedMode) { if (selectedMode) {
@ -419,17 +413,18 @@ public class ContextMenuAdapter {
} }
} else { } else {
if (item.getIcon() != ContextMenuItem.INVALID_ID) { if (item.getIcon() != ContextMenuItem.INVALID_ID) {
int colorRes = item.getColorRes(); Integer color = item.getColor();
if (colorRes == ContextMenuItem.INVALID_ID) { Drawable drawable;
if (!item.shouldSkipPainting()) { if (color == null) {
colorRes = lightTheme ? R.color.icon_color_default_light : R.color.icon_color_default_dark; int colorRes = lightTheme ? R.color.icon_color_default_light : R.color.icon_color_default_dark;
} else { colorRes = item.shouldSkipPainting() ? 0 : colorRes;
colorRes = 0; drawable = mIconsCache.getIcon(item.getIcon(), colorRes);
}
} else if (profileDependent) { } else if (profileDependent) {
colorRes = currentModeColorRes; drawable = mIconsCache.getPaintedIcon(item.getIcon(), currentModeColor);
} else {
drawable = mIconsCache.getPaintedIcon(item.getIcon(), color);
} }
final Drawable drawable = mIconsCache.getIcon(item.getIcon(), colorRes);
((AppCompatImageView) convertView.findViewById(R.id.icon)).setImageDrawable(drawable); ((AppCompatImageView) convertView.findViewById(R.id.icon)).setImageDrawable(drawable);
convertView.findViewById(R.id.icon).setVisibility(View.VISIBLE); convertView.findViewById(R.id.icon).setVisibility(View.VISIBLE);
} else if (convertView.findViewById(R.id.icon) != null) { } else if (convertView.findViewById(R.id.icon) != null) {

View file

@ -19,8 +19,8 @@ public class ContextMenuItem {
private String title; private String title;
@DrawableRes @DrawableRes
private int mIcon; private int mIcon;
@ColorRes @ColorInt
private int colorRes; private Integer color;
@DrawableRes @DrawableRes
private int secondaryIcon; private int secondaryIcon;
private Boolean selected; private Boolean selected;
@ -48,7 +48,7 @@ public class ContextMenuItem {
private ContextMenuItem(@StringRes int titleId, private ContextMenuItem(@StringRes int titleId,
String title, String title,
@DrawableRes int icon, @DrawableRes int icon,
@ColorRes int colorRes, @ColorInt Integer color,
@DrawableRes int secondaryIcon, @DrawableRes int secondaryIcon,
Boolean selected, Boolean selected,
int progress, int progress,
@ -72,7 +72,7 @@ public class ContextMenuItem {
this.titleId = titleId; this.titleId = titleId;
this.title = title; this.title = title;
this.mIcon = icon; this.mIcon = icon;
this.colorRes = colorRes; this.color = color;
this.secondaryIcon = secondaryIcon; this.secondaryIcon = secondaryIcon;
this.selected = selected; this.selected = selected;
this.progress = progress; this.progress = progress;
@ -109,23 +109,17 @@ public class ContextMenuItem {
return mIcon; return mIcon;
} }
@ColorRes @ColorInt
public int getColorRes() { public Integer getColor() {
return colorRes; return color;
}
@ColorRes
public int getThemedColorRes(Context context) {
if (skipPaintingWithoutColor || getColorRes() != INVALID_ID) {
return getColorRes();
} else {
return UiUtilities.getDefaultColorRes(context);
}
} }
@ColorInt @ColorInt
public int getThemedColor(Context context) { public int getThemedColor(Context context) {
return ContextCompat.getColor(context, getThemedColorRes(context)); if (skipPaintingWithoutColor || color != null) {
return color;
}
return ContextCompat.getColor(context, UiUtilities.getDefaultColorRes(context));
} }
@DrawableRes @DrawableRes
@ -212,8 +206,10 @@ public class ContextMenuItem {
this.secondaryIcon = secondaryIcon; this.secondaryIcon = secondaryIcon;
} }
public void setColorRes(int colorRes) { public void setColor(Context context, @ColorRes int colorRes) {
this.colorRes = colorRes; if (colorRes != INVALID_ID) {
this.color = ContextCompat.getColor(context, colorRes);
}
} }
public void setSelected(boolean selected) { public void setSelected(boolean selected) {
@ -268,8 +264,8 @@ public class ContextMenuItem {
private String mTitle; private String mTitle;
@DrawableRes @DrawableRes
private int mIcon = INVALID_ID; private int mIcon = INVALID_ID;
@ColorRes @ColorInt
private int mColorRes = INVALID_ID; private Integer mColor = null;
@DrawableRes @DrawableRes
private int mSecondaryIcon = INVALID_ID; private int mSecondaryIcon = INVALID_ID;
private Boolean mSelected = null; private Boolean mSelected = null;
@ -307,8 +303,15 @@ public class ContextMenuItem {
return this; return this;
} }
public ItemBuilder setColor(@ColorRes int colorRes) { public ItemBuilder setColor(@ColorInt Integer color) {
mColorRes = colorRes; mColor = color;
return this;
}
public ItemBuilder setColor(Context context, @ColorRes int colorRes) {
if (colorRes != INVALID_ID) {
mColor = ContextCompat.getColor(context, colorRes);
}
return this; return this;
} }
@ -422,7 +425,7 @@ public class ContextMenuItem {
} }
public ContextMenuItem createItem() { public ContextMenuItem createItem() {
ContextMenuItem item = new ContextMenuItem(mTitleId, mTitle, mIcon, mColorRes, mSecondaryIcon, ContextMenuItem item = new ContextMenuItem(mTitleId, mTitle, mIcon, mColor, mSecondaryIcon,
mSelected, mProgress, mLayout, mLoading, mIsCategory, mIsClickable, mSkipPaintingWithoutColor, mSelected, mProgress, mLayout, mLoading, mIsCategory, mIsClickable, mSkipPaintingWithoutColor,
mOrder, mDescription, mOnUpdateCallback, mItemClickListener, mIntegerListener, mProgressListener, mOrder, mDescription, mOnUpdateCallback, mItemClickListener, mIntegerListener, mProgressListener,
mItemDeleteAction, mHideDivider, mHideCompoundButton, mMinHeight, mTag, mId); mItemDeleteAction, mHideDivider, mHideCompoundButton, mMinHeight, mTag, mId);

View file

@ -361,6 +361,9 @@ public class FavouritesDbHelper {
} }
public boolean addFavourite(FavouritePoint p, boolean saveImmediately) { public boolean addFavourite(FavouritePoint p, boolean saveImmediately) {
if (Double.isNaN(p.getAltitude()) || p.getAltitude() == 0) {
p.initAltitude(context);
}
if (p.getName().isEmpty() && flatGroups.containsKey(p.getCategory())) { if (p.getName().isEmpty() && flatGroups.containsKey(p.getCategory())) {
return true; return true;
} }
@ -545,6 +548,7 @@ public class FavouritesDbHelper {
cancelAddressRequest(p); cancelAddressRequest(p);
p.setLatitude(lat); p.setLatitude(lat);
p.setLongitude(lon); p.setLongitude(lon);
p.initAltitude(context);
if (description != null) { if (description != null) {
p.setDescription(description); p.setDescription(description);
} }

View file

@ -59,7 +59,7 @@ public class OsmAndLocationSimulation {
boolean nightMode = app.getDaynightHelper().isNightModeForMapControls(); boolean nightMode = app.getDaynightHelper().isNightModeForMapControls();
int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme; int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme;
ApplicationMode appMode = app.getSettings().getApplicationMode(); ApplicationMode appMode = app.getSettings().getApplicationMode();
int selectedModeColor = ContextCompat.getColor(app, appMode.getIconColorInfo().getColor(nightMode)); int selectedModeColor = appMode.getProfileColor(nightMode);
AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(ma, themeRes)); AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(ma, themeRes));
builder.setTitle(R.string.animate_route); builder.setTitle(R.string.animate_route);

View file

@ -468,7 +468,7 @@ public abstract class OsmandPlugin {
FragmentManager fm = mapActivity.getSupportFragmentManager(); FragmentManager fm = mapActivity.getSupportFragmentManager();
Fragment fragment = fm.findFragmentByTag(fragmentData.tag); Fragment fragment = fm.findFragmentByTag(fragmentData.tag);
if (fragment != null) { if (fragment != null) {
fm.beginTransaction().remove(fragment).commit(); fm.beginTransaction().remove(fragment).commitAllowingStateLoss();
} }
} }
} }
@ -690,6 +690,10 @@ public abstract class OsmandPlugin {
return null; return null;
} }
public static <T extends OsmandPlugin> boolean isPluginEnabled(Class<T> clz) {
return getEnabledPlugin(clz) != null;
}
public static List<WorldRegion> getCustomDownloadRegions() { public static List<WorldRegion> getCustomDownloadRegions() {
List<WorldRegion> l = new ArrayList<>(); List<WorldRegion> l = new ArrayList<>();
for (OsmandPlugin plugin : getEnabledPlugins()) { for (OsmandPlugin plugin : getEnabledPlugins()) {

View file

@ -553,7 +553,7 @@ public class UiUtilities {
switch (type) { switch (type) {
case PROFILE_DEPENDENT: case PROFILE_DEPENDENT:
ApplicationMode appMode = app.getSettings().getApplicationMode(); ApplicationMode appMode = app.getSettings().getApplicationMode();
activeColor = ContextCompat.getColor(app, appMode.getIconColorInfo().getColor(nightMode)); activeColor = appMode.getProfileColor(nightMode);
break; break;
case TOOLBAR: case TOOLBAR:
activeColor = Color.WHITE; activeColor = Color.WHITE;

View file

@ -753,7 +753,7 @@ public class MapActivityActions implements DialogProvider {
optionsMenuHelper.addItem(new ItemBuilder().setLayout(R.layout.profile_list_item) optionsMenuHelper.addItem(new ItemBuilder().setLayout(R.layout.profile_list_item)
.setIcon(appMode.getIconRes()) .setIcon(appMode.getIconRes())
.setColor(appMode.getIconColorInfo().getColor(nightMode)) .setColor(appMode.getProfileColor(nightMode))
.setTag(tag) .setTag(tag)
.setTitle(appMode.toHumanString()) .setTitle(appMode.toHumanString())
.setDescription(modeDescription) .setDescription(modeDescription)
@ -770,7 +770,7 @@ public class MapActivityActions implements DialogProvider {
int activeColorPrimaryResId = nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light; int activeColorPrimaryResId = nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light;
optionsMenuHelper.addItem(new ItemBuilder().setLayout(R.layout.profile_list_item) optionsMenuHelper.addItem(new ItemBuilder().setLayout(R.layout.profile_list_item)
.setColor(activeColorPrimaryResId) .setColor(app, activeColorPrimaryResId)
.setTag(PROFILES_CONTROL_BUTTON_TAG) .setTag(PROFILES_CONTROL_BUTTON_TAG)
.setTitle(getString(R.string.shared_string_manage)) .setTitle(getString(R.string.shared_string_manage))
.setListener(new ItemClickListener() { .setListener(new ItemClickListener() {
@ -1083,7 +1083,7 @@ public class MapActivityActions implements DialogProvider {
.setId(DRAWER_SWITCH_PROFILE_ID) .setId(DRAWER_SWITCH_PROFILE_ID)
.setIcon(currentMode.getIconRes()) .setIcon(currentMode.getIconRes())
.setSecondaryIcon(icArrowResId) .setSecondaryIcon(icArrowResId)
.setColor(currentMode.getIconColorInfo().getColor(nightMode)) .setColor(currentMode.getProfileColor(nightMode))
.setTitle(currentMode.toHumanString()) .setTitle(currentMode.toHumanString())
.setDescription(modeDescription) .setDescription(modeDescription)
.setListener(new ItemClickListener() { .setListener(new ItemClickListener() {
@ -1097,7 +1097,7 @@ public class MapActivityActions implements DialogProvider {
.createItem()); .createItem());
optionsMenuHelper.addItem(new ItemBuilder().setLayout(R.layout.main_menu_drawer_btn_configure_profile) optionsMenuHelper.addItem(new ItemBuilder().setLayout(R.layout.main_menu_drawer_btn_configure_profile)
.setId(DRAWER_CONFIGURE_PROFILE_ID) .setId(DRAWER_CONFIGURE_PROFILE_ID)
.setColor(currentMode.getIconColorInfo().getColor(nightMode)) .setColor(currentMode.getProfileColor(nightMode))
.setTitle(getString(R.string.configure_profile)) .setTitle(getString(R.string.configure_profile))
.setListener(new ItemClickListener() { .setListener(new ItemClickListener() {
@Override @Override

View file

@ -437,7 +437,7 @@ public class MapActivityLayers {
} else { } else {
builder.setIcon(R.drawable.mx_user_defined); builder.setIcon(R.drawable.mx_user_defined);
} }
builder.setColor(ContextMenuItem.INVALID_ID); builder.setColor(activity, ContextMenuItem.INVALID_ID);
builder.setSkipPaintingWithoutColor(true); builder.setSkipPaintingWithoutColor(true);
adapter.addItem(builder.createItem()); adapter.addItem(builder.createItem());
} }
@ -495,7 +495,7 @@ public class MapActivityLayers {
OsmandApplication app = getApplication(); OsmandApplication app = getApplication();
boolean nightMode = isNightMode(app); boolean nightMode = isNightMode(app);
int themeRes = getThemeRes(app); int themeRes = getThemeRes(app);
int selectedModeColor = ContextCompat.getColor(app, settings.getApplicationMode().getIconColorInfo().getColor(nightMode)); int selectedModeColor = settings.getApplicationMode().getProfileColor(nightMode);
DialogListItemAdapter dialogAdapter = DialogListItemAdapter.createSingleChoiceAdapter( DialogListItemAdapter dialogAdapter = DialogListItemAdapter.createSingleChoiceAdapter(
items, nightMode, selectedItem, app, selectedModeColor, themeRes, new View.OnClickListener() { items, nightMode, selectedItem, app, selectedModeColor, themeRes, new View.OnClickListener() {
@Override @Override

View file

@ -120,13 +120,13 @@ public class AppModeDialog {
final View selection = tb.findViewById(R.id.selection); final View selection = tb.findViewById(R.id.selection);
ImageView iv = (ImageView) tb.findViewById(R.id.app_mode_icon); ImageView iv = (ImageView) tb.findViewById(R.id.app_mode_icon);
if (checked) { if (checked) {
iv.setImageDrawable(ctx.getUIUtilities().getIcon(mode.getIconRes(), mode.getIconColorInfo().getColor(nightMode))); iv.setImageDrawable(ctx.getUIUtilities().getPaintedIcon(mode.getIconRes(), mode.getProfileColor(nightMode)));
iv.setContentDescription(String.format("%s %s", mode.toHumanString(), ctx.getString(R.string.item_checked))); iv.setContentDescription(String.format("%s %s", mode.toHumanString(), ctx.getString(R.string.item_checked)));
selection.setBackgroundResource(mode.getIconColorInfo().getColor(nightMode)); selection.setBackgroundColor(mode.getProfileColor(nightMode));
selection.setVisibility(View.VISIBLE); selection.setVisibility(View.VISIBLE);
} else { } else {
if (useMapTheme) { if (useMapTheme) {
iv.setImageDrawable(ctx.getUIUtilities().getIcon(mode.getIconRes(), mode.getIconColorInfo().getColor(nightMode))); iv.setImageDrawable(ctx.getUIUtilities().getPaintedIcon(mode.getIconRes(), mode.getProfileColor(nightMode)));
iv.setBackgroundResource(AndroidUtils.resolveAttribute(themedCtx, android.R.attr.selectableItemBackground)); iv.setBackgroundResource(AndroidUtils.resolveAttribute(themedCtx, android.R.attr.selectableItemBackground));
} else { } else {
iv.setImageDrawable(ctx.getUIUtilities().getThemedIcon(mode.getIconRes())); iv.setImageDrawable(ctx.getUIUtilities().getThemedIcon(mode.getIconRes()));
@ -171,7 +171,7 @@ public class AppModeDialog {
final boolean checked = selected.contains(mode); final boolean checked = selected.contains(mode);
ImageView iv = (ImageView) tb.findViewById(R.id.app_mode_icon); ImageView iv = (ImageView) tb.findViewById(R.id.app_mode_icon);
ImageView selection = tb.findViewById(R.id.selection); ImageView selection = tb.findViewById(R.id.selection);
Drawable drawable = ctx.getUIUtilities().getIcon(mode.getIconRes(), mode.getIconColorInfo().getColor(nightMode)); Drawable drawable = ctx.getUIUtilities().getPaintedIcon(mode.getIconRes(), mode.getProfileColor(nightMode));
if (checked) { if (checked) {
iv.setImageDrawable(drawable); iv.setImageDrawable(drawable);
iv.setContentDescription(String.format("%s %s", mode.toHumanString(), ctx.getString(R.string.item_checked))); iv.setContentDescription(String.format("%s %s", mode.toHumanString(), ctx.getString(R.string.item_checked)));
@ -184,7 +184,7 @@ public class AppModeDialog {
} else { } else {
if (useMapTheme) { if (useMapTheme) {
if (Build.VERSION.SDK_INT >= 21) { if (Build.VERSION.SDK_INT >= 21) {
Drawable active = ctx.getUIUtilities().getIcon(mode.getIconRes(), mode.getIconColorInfo().getColor(nightMode)); Drawable active = ctx.getUIUtilities().getPaintedIcon(mode.getIconRes(), mode.getProfileColor(nightMode));
drawable = AndroidUtils.createPressedStateListDrawable(drawable, active); drawable = AndroidUtils.createPressedStateListDrawable(drawable, active);
} }
iv.setImageDrawable(drawable); iv.setImageDrawable(drawable);
@ -195,7 +195,7 @@ public class AppModeDialog {
AndroidUtils.setBackground(ctx, selection, nightMode, R.drawable.btn_border_pressed_trans_light, R.drawable.btn_border_pressed_trans_light); AndroidUtils.setBackground(ctx, selection, nightMode, R.drawable.btn_border_pressed_trans_light, R.drawable.btn_border_pressed_trans_light);
} }
} else { } else {
iv.setImageDrawable(ctx.getUIUtilities().getIcon(mode.getIconRes(), mode.getIconColorInfo().getColor(nightMode))); iv.setImageDrawable(ctx.getUIUtilities().getPaintedIcon(mode.getIconRes(), mode.getProfileColor(nightMode)));
} }
iv.setContentDescription(String.format("%s %s", mode.toHumanString(), ctx.getString(R.string.item_unchecked))); iv.setContentDescription(String.format("%s %s", mode.toHumanString(), ctx.getString(R.string.item_unchecked)));
} }
@ -232,7 +232,7 @@ public class AppModeDialog {
int metricsY = (int) ctx.getResources().getDimension(R.dimen.route_info_modes_height); int metricsY = (int) ctx.getResources().getDimension(R.dimen.route_info_modes_height);
View tb = layoutInflater.inflate(layoutId, null); View tb = layoutInflater.inflate(layoutId, null);
ImageView iv = (ImageView) tb.findViewById(R.id.app_mode_icon); ImageView iv = (ImageView) tb.findViewById(R.id.app_mode_icon);
iv.setImageDrawable(ctx.getUIUtilities().getIcon(mode.getIconRes(), mode.getIconColorInfo().getColor(isNightMode(ctx, useMapTheme)))); iv.setImageDrawable(ctx.getUIUtilities().getPaintedIcon(mode.getIconRes(), mode.getProfileColor(isNightMode(ctx, useMapTheme))));
iv.setContentDescription(mode.toHumanString()); iv.setContentDescription(mode.toHumanString());
// tb.setCompoundDrawablesWithIntrinsicBounds(null, ctx.getIconsCache().getIcon(mode.getIconId(), R.color.app_mode_icon_color), null, null); // tb.setCompoundDrawablesWithIntrinsicBounds(null, ctx.getIconsCache().getIcon(mode.getIconId(), R.color.app_mode_icon_color), null, null);
LayoutParams lp = new LinearLayout.LayoutParams(metricsX, metricsY); LayoutParams lp = new LinearLayout.LayoutParams(metricsX, metricsY);

View file

@ -121,7 +121,7 @@ public class StartGPSStatus extends OsmAndAction {
cb.setLayoutParams(lp); cb.setLayoutParams(lp);
cb.setPadding(dp8, 0, 0, 0); cb.setPadding(dp8, 0, 0, 0);
int textColorPrimary = ContextCompat.getColor(activity, isNightMode() ? R.color.text_color_primary_dark : R.color.text_color_primary_light); int textColorPrimary = ContextCompat.getColor(activity, isNightMode() ? R.color.text_color_primary_dark : R.color.text_color_primary_light);
int selectedModeColor = ContextCompat.getColor(activity, getSettings().getApplicationMode().getIconColorInfo().getColor(isNightMode())); int selectedModeColor = getSettings().getApplicationMode().getProfileColor(isNightMode());
cb.setTextColor(textColorPrimary); cb.setTextColor(textColorPrimary);
UiUtilities.setupCompoundButton(isNightMode(), selectedModeColor, cb); UiUtilities.setupCompoundButton(isNightMode(), selectedModeColor, cb);

View file

@ -678,7 +678,7 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) { public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) {
if (itemId == R.string.layer_recordings) { if (itemId == R.string.layer_recordings) {
SHOW_RECORDINGS.set(!SHOW_RECORDINGS.get()); SHOW_RECORDINGS.set(!SHOW_RECORDINGS.get());
adapter.getItem(pos).setColorRes(SHOW_RECORDINGS.get() ? adapter.getItem(pos).setColor(app, SHOW_RECORDINGS.get() ?
R.color.osmand_orange : ContextMenuItem.INVALID_ID); R.color.osmand_orange : ContextMenuItem.INVALID_ID);
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
updateLayers(mapView, mapActivity); updateLayers(mapView, mapActivity);
@ -690,7 +690,7 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
.setId(RECORDING_LAYER) .setId(RECORDING_LAYER)
.setSelected(SHOW_RECORDINGS.get()) .setSelected(SHOW_RECORDINGS.get())
.setIcon(R.drawable.ic_action_micro_dark) .setIcon(R.drawable.ic_action_micro_dark)
.setColor(SHOW_RECORDINGS.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setColor(mapActivity, SHOW_RECORDINGS.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID)
.setItemDeleteAction(makeDeleteAction(SHOW_RECORDINGS)) .setItemDeleteAction(makeDeleteAction(SHOW_RECORDINGS))
.setListener(listener).createItem()); .setListener(listener).createItem());
} }

View file

@ -10,6 +10,7 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.Window; import android.view.Window;
import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes; import androidx.annotation.ColorRes;
import androidx.annotation.DrawableRes; import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -91,6 +92,16 @@ public abstract class BottomSheetDialogFragment extends DialogFragment {
} }
} }
@Nullable
protected Drawable getPaintedIcon(@DrawableRes int drawableRes, @ColorInt int color) {
OsmandApplication app = getMyApplication();
if (app != null) {
return app.getUIUtilities().getPaintedIcon(drawableRes, color);
} else {
return null;
}
}
@Nullable @Nullable
protected Drawable getContentIcon(@DrawableRes int drawableRes) { protected Drawable getContentIcon(@DrawableRes int drawableRes) {
OsmandApplication app = getMyApplication(); OsmandApplication app = getMyApplication();

View file

@ -8,6 +8,7 @@ import android.view.ViewGroup;
import android.widget.CompoundButton; import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.CompoundButton.OnCheckedChangeListener;
import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes; import androidx.annotation.ColorRes;
import androidx.annotation.LayoutRes; import androidx.annotation.LayoutRes;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
@ -22,6 +23,7 @@ public class BottomSheetItemWithCompoundButton extends BottomSheetItemWithDescri
private ColorStateList buttonTintList; private ColorStateList buttonTintList;
private OnCheckedChangeListener onCheckedChangeListener; private OnCheckedChangeListener onCheckedChangeListener;
@ColorRes private int compoundButtonColorId; @ColorRes private int compoundButtonColorId;
@ColorInt private Integer compoundButtonColor;
private CompoundButton compoundButton; private CompoundButton compoundButton;
@ -80,6 +82,10 @@ public class BottomSheetItemWithCompoundButton extends BottomSheetItemWithDescri
this.compoundButtonColorId = compoundButtonColorId; this.compoundButtonColorId = compoundButtonColorId;
} }
public void setCompoundButtonColor(@ColorInt int compoundButtonColor) {
this.compoundButtonColor = compoundButtonColor;
}
public CompoundButton getCompoundButton() { public CompoundButton getCompoundButton() {
return compoundButton; return compoundButton;
} }
@ -91,7 +97,9 @@ public class BottomSheetItemWithCompoundButton extends BottomSheetItemWithDescri
if (compoundButton != null) { if (compoundButton != null) {
compoundButton.setChecked(checked); compoundButton.setChecked(checked);
compoundButton.setOnCheckedChangeListener(onCheckedChangeListener); compoundButton.setOnCheckedChangeListener(onCheckedChangeListener);
if (compoundButtonColorId != INVALID_ID) { if (compoundButtonColor != null) {
UiUtilities.setupCompoundButton(nightMode, compoundButtonColor, compoundButton);
} else if (compoundButtonColorId != INVALID_ID) {
UiUtilities.setupCompoundButton(nightMode, ContextCompat.getColor(context, compoundButtonColorId), compoundButton); UiUtilities.setupCompoundButton(nightMode, ContextCompat.getColor(context, compoundButtonColorId), compoundButton);
} else { } else {
CompoundButtonCompat.setButtonTintList(compoundButton, buttonTintList); CompoundButtonCompat.setButtonTintList(compoundButton, buttonTintList);
@ -105,6 +113,7 @@ public class BottomSheetItemWithCompoundButton extends BottomSheetItemWithDescri
protected ColorStateList buttonTintList; protected ColorStateList buttonTintList;
protected OnCheckedChangeListener onCheckedChangeListener; protected OnCheckedChangeListener onCheckedChangeListener;
@ColorRes protected int compoundButtonColorId = INVALID_ID; @ColorRes protected int compoundButtonColorId = INVALID_ID;
@ColorInt protected Integer compoundButtonColor = null;
public Builder setChecked(boolean checked) { public Builder setChecked(boolean checked) {
this.checked = checked; this.checked = checked;
@ -126,6 +135,11 @@ public class BottomSheetItemWithCompoundButton extends BottomSheetItemWithDescri
return this; return this;
} }
public Builder setCompoundButtonColor(@ColorInt int compoundButtonColor) {
this.compoundButtonColor = compoundButtonColor;
return this;
}
public BottomSheetItemWithCompoundButton create() { public BottomSheetItemWithCompoundButton create() {
return new BottomSheetItemWithCompoundButton(customView, return new BottomSheetItemWithCompoundButton(customView,
layoutId, layoutId,

View file

@ -1004,7 +1004,7 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, IRouteInfo
new TransactionBuilder(mapActivity.getSupportFragmentManager(), settings, mapActivity); new TransactionBuilder(mapActivity.getSupportFragmentManager(), settings, mapActivity);
builder.addFragmentsData(fragmentsData) builder.addFragmentsData(fragmentsData)
.addFragmentsData(OsmandPlugin.getPluginsCardsList()) .addFragmentsData(OsmandPlugin.getPluginsCardsList())
.getFragmentTransaction().commit(); .getFragmentTransaction().commitAllowingStateLoss();
} }
private void removeFragment(String tag) { private void removeFragment(String tag) {

View file

@ -172,7 +172,7 @@ public class ConfigureMapMenu {
final MapActivity activity, final int themeRes, final boolean nightMode) { final MapActivity activity, final int themeRes, final boolean nightMode) {
final OsmandApplication app = activity.getMyApplication(); final OsmandApplication app = activity.getMyApplication();
final OsmandSettings settings = app.getSettings(); final OsmandSettings settings = app.getSettings();
final int selectedProfileColorRes = settings.getApplicationMode().getIconColorInfo().getColor(nightMode); final int selectedProfileColor = settings.getApplicationMode().getProfileColor(nightMode);
MapLayerMenuListener l = new MapLayerMenuListener(activity, adapter); MapLayerMenuListener l = new MapLayerMenuListener(activity, adapter);
adapter.addItem(new ContextMenuItem.ItemBuilder() adapter.addItem(new ContextMenuItem.ItemBuilder()
.setId(SHOW_CATEGORY_ID) .setId(SHOW_CATEGORY_ID)
@ -184,7 +184,7 @@ public class ConfigureMapMenu {
.setId(FAVORITES_ID) .setId(FAVORITES_ID)
.setTitleId(R.string.shared_string_favorites, activity) .setTitleId(R.string.shared_string_favorites, activity)
.setSelected(settings.SHOW_FAVORITES.get()) .setSelected(settings.SHOW_FAVORITES.get())
.setColor(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setColor(app, selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID)
.setIcon(R.drawable.ic_action_favorite) .setIcon(R.drawable.ic_action_favorite)
.setItemDeleteAction(makeDeleteAction(settings.SHOW_FAVORITES)) .setItemDeleteAction(makeDeleteAction(settings.SHOW_FAVORITES))
.setListener(l) .setListener(l)
@ -196,7 +196,7 @@ public class ConfigureMapMenu {
.setTitleId(R.string.layer_poi, activity) .setTitleId(R.string.layer_poi, activity)
.setSelected(selected) .setSelected(selected)
.setDescription(app.getPoiFilters().getSelectedPoiFiltersName(wiki)) .setDescription(app.getPoiFilters().getSelectedPoiFiltersName(wiki))
.setColor(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setColor(app, selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID)
.setIcon(R.drawable.ic_action_info_dark) .setIcon(R.drawable.ic_action_info_dark)
.setSecondaryIcon(R.drawable.ic_action_additional_option) .setSecondaryIcon(R.drawable.ic_action_additional_option)
.setListener(l).createItem()); .setListener(l).createItem());
@ -205,7 +205,7 @@ public class ConfigureMapMenu {
.setId(POI_OVERLAY_LABELS_ID) .setId(POI_OVERLAY_LABELS_ID)
.setTitleId(R.string.layer_amenity_label, activity) .setTitleId(R.string.layer_amenity_label, activity)
.setSelected(settings.SHOW_POI_LABEL.get()) .setSelected(settings.SHOW_POI_LABEL.get())
.setColor(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setColor(app, selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID)
.setIcon(R.drawable.ic_action_text_dark) .setIcon(R.drawable.ic_action_text_dark)
.setItemDeleteAction(makeDeleteAction(settings.SHOW_POI_LABEL)) .setItemDeleteAction(makeDeleteAction(settings.SHOW_POI_LABEL))
.setListener(l).createItem()); .setListener(l).createItem());
@ -217,7 +217,7 @@ public class ConfigureMapMenu {
.setIcon(R.drawable.ic_action_transport_bus) .setIcon(R.drawable.ic_action_transport_bus)
.setSecondaryIcon(R.drawable.ic_action_additional_option) .setSecondaryIcon(R.drawable.ic_action_additional_option)
.setSelected(selected) .setSelected(selected)
.setColor(selected ? selectedProfileColorRes : ContextMenuItem.INVALID_ID) .setColor(selected ? selectedProfileColor : null)
.setListener(l).createItem()); .setListener(l).createItem());
selected = app.getSelectedGpxHelper().isShowingAnyGpxFiles(); selected = app.getSelectedGpxHelper().isShowingAnyGpxFiles();
@ -226,7 +226,7 @@ public class ConfigureMapMenu {
.setTitleId(R.string.layer_gpx_layer, activity) .setTitleId(R.string.layer_gpx_layer, activity)
.setSelected(app.getSelectedGpxHelper().isShowingAnyGpxFiles()) .setSelected(app.getSelectedGpxHelper().isShowingAnyGpxFiles())
.setDescription(app.getSelectedGpxHelper().getGpxDescription()) .setDescription(app.getSelectedGpxHelper().getGpxDescription())
.setColor(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setColor(app, selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID)
.setIcon(R.drawable.ic_action_polygom_dark) .setIcon(R.drawable.ic_action_polygom_dark)
.setSecondaryIcon(R.drawable.ic_action_additional_option) .setSecondaryIcon(R.drawable.ic_action_additional_option)
.setListener(l).createItem()); .setListener(l).createItem());
@ -236,7 +236,7 @@ public class ConfigureMapMenu {
.setId(MAP_MARKERS_ID) .setId(MAP_MARKERS_ID)
.setTitleId(R.string.map_markers, activity) .setTitleId(R.string.map_markers, activity)
.setSelected(selected) .setSelected(selected)
.setColor(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setColor(app, selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID)
.setIcon(R.drawable.ic_action_flag) .setIcon(R.drawable.ic_action_flag)
.setItemDeleteAction(makeDeleteAction(settings.SHOW_MAP_MARKERS)) .setItemDeleteAction(makeDeleteAction(settings.SHOW_MAP_MARKERS))
.setListener(l).createItem()); .setListener(l).createItem());
@ -267,8 +267,7 @@ public class ConfigureMapMenu {
final int themeRes, final boolean nightMode) { final int themeRes, final boolean nightMode) {
final OsmandApplication app = activity.getMyApplication(); final OsmandApplication app = activity.getMyApplication();
final OsmandSettings settings = app.getSettings(); final OsmandSettings settings = app.getSettings();
final int selectedProfileColorRes = settings.APPLICATION_MODE.get().getIconColorInfo().getColor(nightMode); final int selectedProfileColor = settings.APPLICATION_MODE.get().getProfileColor(nightMode);
final int selectedProfileColor = ContextCompat.getColor(app, selectedProfileColorRes);
adapter.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.map_widget_map_rendering, activity) adapter.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.map_widget_map_rendering, activity)
.setId(MAP_RENDERING_CATEGORY_ID) .setId(MAP_RENDERING_CATEGORY_ID)
@ -705,7 +704,6 @@ public class ConfigureMapMenu {
for (int i = 0; i < prefs.size(); i++) { for (int i = 0; i < prefs.size(); i++) {
prefs.get(i).set(false); prefs.get(i).set(false);
} }
adapter.getItem(pos).setColorRes(ContextMenuItem.INVALID_ID);
a.notifyDataSetInvalidated(); a.notifyDataSetInvalidated();
activity.refreshMapComplete(); activity.refreshMapComplete();
activity.getMapLayers().updateLayers(activity.getMapView()); activity.getMapLayers().updateLayers(activity.getMapView());
@ -739,7 +737,7 @@ public class ConfigureMapMenu {
} }
} }
} }
builder.setColor(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); builder.setColor(activity, selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID);
if (useDescription) { if (useDescription) {
final String descr = getDescription(prefs, includedPrefs); final String descr = getDescription(prefs, includedPrefs);
builder.setDescription(descr); builder.setDescription(descr);
@ -840,7 +838,7 @@ public class ConfigureMapMenu {
selected |= prefs.get(i).get(); selected |= prefs.get(i).get();
} }
adapter.getItem(pos).setSelected(selected); adapter.getItem(pos).setSelected(selected);
adapter.getItem(pos).setColorRes(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); adapter.getItem(pos).setColor(activity, selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID);
a.notifyDataSetInvalidated(); a.notifyDataSetInvalidated();
} }
}); });
@ -875,7 +873,7 @@ public class ConfigureMapMenu {
} else { } else {
adapter.getItem(pos).setSelected(selected); adapter.getItem(pos).setSelected(selected);
} }
adapter.getItem(pos).setColorRes(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); adapter.getItem(pos).setColor(activity, selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID);
} }
a.notifyDataSetInvalidated(); a.notifyDataSetInvalidated();
activity.refreshMapComplete(); activity.refreshMapComplete();

View file

@ -98,7 +98,7 @@ public class DetailsBottomSheet extends BasePreferenceBottomSheet {
@Override @Override
public void createMenuItems(Bundle savedInstanceState) { public void createMenuItems(Bundle savedInstanceState) {
int selectedProfileColorRes = app.getSettings().APPLICATION_MODE.get().getIconColorInfo().getColor(nightMode); int selectedProfileColor = app.getSettings().APPLICATION_MODE.get().getProfileColor(nightMode);
float spacing = getResources().getDimension(R.dimen.line_spacing_extra_description); float spacing = getResources().getDimension(R.dimen.line_spacing_extra_description);
LinearLayout linearLayout = new LinearLayout(app); LinearLayout linearLayout = new LinearLayout(app);
linearLayout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); linearLayout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
@ -139,7 +139,7 @@ public class DetailsBottomSheet extends BasePreferenceBottomSheet {
streetLightsNightPref.set(!onLeftClick); streetLightsNightPref.set(!onLeftClick);
} }
}) })
.setCompoundButtonColorId(selectedProfileColorRes) .setCompoundButtonColor(selectedProfileColor)
.setChecked(pref.get()) .setChecked(pref.get())
.setTitle(propertyName) .setTitle(propertyName)
.setIconHidden(true) .setIconHidden(true)
@ -160,7 +160,7 @@ public class DetailsBottomSheet extends BasePreferenceBottomSheet {
} else if (!STREET_LIGHTING_NIGHT.equals(property.getAttrName())) { } else if (!STREET_LIGHTING_NIGHT.equals(property.getAttrName())) {
final BottomSheetItemWithCompoundButton[] item = new BottomSheetItemWithCompoundButton[1]; final BottomSheetItemWithCompoundButton[] item = new BottomSheetItemWithCompoundButton[1];
item[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder() item[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder()
.setCompoundButtonColorId(selectedProfileColorRes) .setCompoundButtonColor(selectedProfileColor)
.setChecked(pref.get()) .setChecked(pref.get())
.setTitle(propertyName) .setTitle(propertyName)
.setIconHidden(true) .setIconHidden(true)
@ -217,7 +217,7 @@ public class DetailsBottomSheet extends BasePreferenceBottomSheet {
} }
if (adapter != null) { if (adapter != null) {
adapter.getItem(position).setSelected(checked); adapter.getItem(position).setSelected(checked);
adapter.getItem(position).setColorRes(checked ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); adapter.getItem(position).setColor(app, checked ? R.color.osmand_orange : ContextMenuItem.INVALID_ID);
adapter.getItem(position).setDescription(getString( adapter.getItem(position).setDescription(getString(
R.string.ltr_or_rtl_combine_via_slash, R.string.ltr_or_rtl_combine_via_slash,
String.valueOf(selected), String.valueOf(selected),

View file

@ -77,7 +77,7 @@ final class MapLayerMenuListener extends OnRowItemClick {
public boolean processResult(Boolean result) { public boolean processResult(Boolean result) {
if (item != null) { if (item != null) {
item.setSelected(result); item.setSelected(result);
item.setColorRes(result ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); item.setColor(mapActivity, result ? R.color.osmand_orange : ContextMenuItem.INVALID_ID);
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
} }
return true; return true;
@ -86,7 +86,7 @@ final class MapLayerMenuListener extends OnRowItemClick {
boolean selected = TransportLinesMenu.isShowLines(mapActivity.getMyApplication()); boolean selected = TransportLinesMenu.isShowLines(mapActivity.getMyApplication());
if (!selected && item != null) { if (!selected && item != null) {
item.setSelected(true); item.setSelected(true);
item.setColorRes(R.color.osmand_orange); item.setColor(mapActivity, R.color.osmand_orange);
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
} }
return false; return false;
@ -94,7 +94,7 @@ final class MapLayerMenuListener extends OnRowItemClick {
CompoundButton btn = (CompoundButton) view.findViewById(R.id.toggle_item); CompoundButton btn = (CompoundButton) view.findViewById(R.id.toggle_item);
if (btn != null && btn.getVisibility() == View.VISIBLE) { if (btn != null && btn.getVisibility() == View.VISIBLE) {
btn.setChecked(!btn.isChecked()); btn.setChecked(!btn.isChecked());
menuAdapter.getItem(pos).setColorRes(btn.isChecked() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); menuAdapter.getItem(pos).setColor(mapActivity, btn.isChecked() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID);
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
return false; return false;
} else { } else {
@ -110,7 +110,7 @@ final class MapLayerMenuListener extends OnRowItemClick {
final PoiFiltersHelper poiFiltersHelper = mapActivity.getMyApplication().getPoiFilters(); final PoiFiltersHelper poiFiltersHelper = mapActivity.getMyApplication().getPoiFilters();
final ContextMenuItem item = menuAdapter.getItem(pos); final ContextMenuItem item = menuAdapter.getItem(pos);
if (item.getSelected() != null) { if (item.getSelected() != null) {
item.setColorRes(isChecked ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); item.setColor(mapActivity, isChecked ? R.color.osmand_orange : ContextMenuItem.INVALID_ID);
} }
if (itemId == R.string.layer_poi) { if (itemId == R.string.layer_poi) {
PoiUIFilter wiki = poiFiltersHelper.getTopWikiPoiFilter(); PoiUIFilter wiki = poiFiltersHelper.getTopWikiPoiFilter();
@ -139,7 +139,7 @@ final class MapLayerMenuListener extends OnRowItemClick {
@Override @Override
public boolean processResult(Boolean result) { public boolean processResult(Boolean result) {
item.setSelected(result); item.setSelected(result);
item.setColorRes(result ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); item.setColor(mapActivity, result ? R.color.osmand_orange : ContextMenuItem.INVALID_ID);
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
return true; return true;
} }
@ -171,7 +171,7 @@ final class MapLayerMenuListener extends OnRowItemClick {
boolean selected = app.getSelectedGpxHelper().isShowingAnyGpxFiles(); boolean selected = app.getSelectedGpxHelper().isShowingAnyGpxFiles();
item.setSelected(selected); item.setSelected(selected);
item.setDescription(app.getSelectedGpxHelper().getGpxDescription()); item.setDescription(app.getSelectedGpxHelper().getGpxDescription());
item.setColorRes(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); item.setColor(mapActivity, selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID);
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
} }
}); });
@ -189,7 +189,7 @@ final class MapLayerMenuListener extends OnRowItemClick {
boolean selected = pf.isShowingAnyPoi(wiki); boolean selected = pf.isShowingAnyPoi(wiki);
item.setSelected(selected); item.setSelected(selected);
item.setDescription(pf.getSelectedPoiFiltersName(wiki)); item.setDescription(pf.getSelectedPoiFiltersName(wiki));
item.setColorRes(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); item.setColor(mapActivity, selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID);
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
} }
}; };

View file

@ -174,8 +174,8 @@ public class SelectMapViewQuickActionsBottomSheet extends MenuBottomSheetDialogF
if (appMode != null) { if (appMode != null) {
boolean selected = key.equals(selectedItem); boolean selected = key.equals(selectedItem);
int iconId = appMode.getIconRes(); int iconId = appMode.getIconRes();
int colorId = appMode.getIconColorInfo().getColor(nightMode); int color = appMode.getProfileColor(nightMode);
Drawable icon = getIcon(iconId, colorId); Drawable icon = getPaintedIcon(iconId, color);
String translatedName = appMode.toHumanString(); String translatedName = appMode.toHumanString();
createItemRow(selected, counter, icon, translatedName, key); createItemRow(selected, counter, icon, translatedName, key);
counter++; counter++;

View file

@ -516,13 +516,13 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement
.setTitleId(R.string.shared_string_refresh, getContext()) .setTitleId(R.string.shared_string_refresh, getContext())
.setIcon(R.drawable.ic_action_refresh_dark) .setIcon(R.drawable.ic_action_refresh_dark)
.setListener(listener) .setListener(listener)
.setColor(iconColorResId) .setColor(getContext(), iconColorResId)
.createItem()); .createItem());
optionsMenuAdapter.addItem(new ContextMenuItem.ItemBuilder() optionsMenuAdapter.addItem(new ContextMenuItem.ItemBuilder()
.setTitleId(R.string.shared_string_delete, getContext()) .setTitleId(R.string.shared_string_delete, getContext())
.setIcon(R.drawable.ic_action_delete_dark) .setIcon(R.drawable.ic_action_delete_dark)
.setListener(listener) .setListener(listener)
.setColor(iconColorResId) .setColor(getContext(), iconColorResId)
.createItem()); .createItem());
optionsMenuAdapter.addItem(new ContextMenuItem.ItemBuilder() optionsMenuAdapter.addItem(new ContextMenuItem.ItemBuilder()
.setTitleId(R.string.local_index_mi_backup, getContext()) .setTitleId(R.string.local_index_mi_backup, getContext())
@ -554,7 +554,7 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement
MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_ALWAYS); MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
} }
if (contextMenuItem.getIcon() != -1) { if (contextMenuItem.getIcon() != -1) {
Drawable icMenuItem = getMyApplication().getUIUtilities().getIcon(contextMenuItem.getIcon(), contextMenuItem.getColorRes()); Drawable icMenuItem = getMyApplication().getUIUtilities().getPaintedIcon(contextMenuItem.getIcon(), contextMenuItem.getColor());
item.setIcon(icMenuItem); item.setIcon(icMenuItem);
} }

View file

@ -6,6 +6,7 @@ import android.content.Intent;
import android.database.Cursor; import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.AsyncTask.Status;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.provider.OpenableColumns; import android.provider.OpenableColumns;
@ -25,6 +26,8 @@ import net.osmand.PlatformUtil;
import net.osmand.data.FavouritePoint; import net.osmand.data.FavouritePoint;
import net.osmand.data.FavouritePoint.BackgroundType; import net.osmand.data.FavouritePoint.BackgroundType;
import net.osmand.plus.AppInitializer; import net.osmand.plus.AppInitializer;
import net.osmand.plus.AppInitializer.AppInitializeListener;
import net.osmand.plus.AppInitializer.InitEvents;
import net.osmand.plus.GPXDatabase.GpxDataItem; import net.osmand.plus.GPXDatabase.GpxDataItem;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
@ -212,7 +215,7 @@ public class ImportHelper {
public static String getNameFromContentUri(OsmandApplication app, Uri contentUri) { public static String getNameFromContentUri(OsmandApplication app, Uri contentUri) {
try { try {
String name; String name;
Cursor returnCursor = app.getContentResolver().query(contentUri, new String[] {OpenableColumns.DISPLAY_NAME}, null, null, null); Cursor returnCursor = app.getContentResolver().query(contentUri, new String[]{OpenableColumns.DISPLAY_NAME}, null, null, null);
if (returnCursor != null && returnCursor.moveToFirst()) { if (returnCursor != null && returnCursor.moveToFirst()) {
int columnIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); int columnIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
if (columnIndex != -1) { if (columnIndex != -1) {
@ -687,7 +690,7 @@ public class ImportHelper {
} else { } else {
fpCat = p.category; fpCat = p.category;
} }
FavouritePoint point = new FavouritePoint(p.lat, p.lon, p.name, fpCat); FavouritePoint point = new FavouritePoint(p.lat, p.lon, p.name, fpCat, p.ele, 0);
if (p.desc != null) { if (p.desc != null) {
point.setDescription(p.desc); point.setDescription(p.desc);
} }
@ -707,15 +710,17 @@ public class ImportHelper {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private <P> void executeImportTask(final AsyncTask<P, ?, ?> importTask, final P... requests) { private <P> void executeImportTask(final AsyncTask<P, ?, ?> importTask, final P... requests) {
if (app.isApplicationInitializing()) { if (app.isApplicationInitializing()) {
app.getAppInitializer().addListener(new AppInitializer.AppInitializeListener() { app.getAppInitializer().addListener(new AppInitializeListener() {
@Override @Override
public void onProgress(AppInitializer init, AppInitializer.InitEvents event) { public void onProgress(AppInitializer init, InitEvents event) {
} }
@Override @Override
public void onFinish(AppInitializer init) { public void onFinish(AppInitializer init) {
if (importTask.getStatus() == Status.PENDING) {
importTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, requests); importTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, requests);
} }
}
}); });
} else { } else {
importTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, requests); importTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, requests);

View file

@ -1036,6 +1036,8 @@ public class MapContextMenu extends MenuTitleController implements StateChangedL
title = ""; title = "";
} }
String originObjectName = ""; String originObjectName = "";
double altitude = 0;
long timestamp = System.currentTimeMillis();
Object object = getObject(); Object object = getObject();
if (object != null) { if (object != null) {
if (object instanceof Amenity) { if (object instanceof Amenity) {
@ -1043,10 +1045,13 @@ public class MapContextMenu extends MenuTitleController implements StateChangedL
} else if (object instanceof TransportStop) { } else if (object instanceof TransportStop) {
originObjectName = ((TransportStop) object).toStringEn(); originObjectName = ((TransportStop) object).toStringEn();
} }
if (object instanceof WptPt) {
altitude = ((WptPt) object).ele;
}
} }
FavoritePointEditor favoritePointEditor = getFavoritePointEditor(); FavoritePointEditor favoritePointEditor = getFavoritePointEditor();
if (favoritePointEditor != null) { if (favoritePointEditor != null) {
favoritePointEditor.add(getLatLon(), title, getStreetStr(), originObjectName); favoritePointEditor.add(getLatLon(), title, getStreetStr(), originObjectName, altitude, timestamp);
} }
} }
}); });
@ -1074,7 +1079,8 @@ public class MapContextMenu extends MenuTitleController implements StateChangedL
for (OsmandMapLayer layer : mapActivity.getMapView().getLayers()) { for (OsmandMapLayer layer : mapActivity.getMapView().getLayers()) {
layer.populateObjectContextMenu(latLon, getObject(), menuAdapter, mapActivity); layer.populateObjectContextMenu(latLon, getObject(), menuAdapter, mapActivity);
} }
mapActivity.getMapActions().addActionsToAdapter(configure ? 0 : latLon.getLatitude(), configure ? 0 : latLon.getLongitude(), menuAdapter, configure ? null : getObject(), configure); } mapActivity.getMapActions().addActionsToAdapter(configure ? 0 : latLon.getLatitude(), configure ? 0 : latLon.getLongitude(), menuAdapter, configure ? null : getObject(), configure);
}
return menuAdapter; return menuAdapter;
} }

View file

@ -27,7 +27,7 @@ public class FavoritePointEditor extends PointEditor {
return favorite; return favorite;
} }
public void add(LatLon latLon, String title, String address, String originObjectName) { public void add(LatLon latLon, String title, String address, String originObjectName, double altitude, long timestamp) {
MapActivity mapActivity = getMapActivity(); MapActivity mapActivity = getMapActivity();
if (latLon == null || mapActivity == null) { if (latLon == null || mapActivity == null) {
return; return;
@ -37,7 +37,7 @@ public class FavoritePointEditor extends PointEditor {
if (!Algorithms.isEmpty(lastCategory) && !app.getFavorites().groupExists(lastCategory)) { if (!Algorithms.isEmpty(lastCategory) && !app.getFavorites().groupExists(lastCategory)) {
lastCategory = ""; lastCategory = "";
} }
favorite = new FavouritePoint(latLon.getLatitude(), latLon.getLongitude(), title, lastCategory); favorite = new FavouritePoint(latLon.getLatitude(), latLon.getLongitude(), title, lastCategory, altitude, timestamp);
favorite.setDescription(""); favorite.setDescription("");
favorite.setAddress(address.isEmpty() ? title : address); favorite.setAddress(address.isEmpty() ? title : address);
favorite.setOriginObjectName(originObjectName); favorite.setOriginObjectName(originObjectName);
@ -64,7 +64,6 @@ public class FavoritePointEditor extends PointEditor {
favorite.setDescription(""); favorite.setDescription("");
favorite.setAddress(""); favorite.setAddress("");
favorite.setOriginObjectName(originObjectName); favorite.setOriginObjectName(originObjectName);
FavoritePointEditorFragmentNew.showAutoFillInstance(mapActivity, autoFill); FavoritePointEditorFragmentNew.showAutoFillInstance(mapActivity, autoFill);
} }

View file

@ -190,7 +190,7 @@ public class FavoritePointEditorFragment extends PointEditorFragment {
final FavouritePoint favorite = getFavorite(); final FavouritePoint favorite = getFavorite();
if (favorite != null) { if (favorite != null) {
final FavouritePoint point = new FavouritePoint(favorite.getLatitude(), favorite.getLongitude(), final FavouritePoint point = new FavouritePoint(favorite.getLatitude(), favorite.getLongitude(),
getNameTextValue(), getCategoryTextValue()); getNameTextValue(), getCategoryTextValue(), favorite.getAltitude(), favorite.getTimestamp());
point.setDescription(getDescriptionTextValue()); point.setDescription(getDescriptionTextValue());
point.setAddress(getAddressTextValue()); point.setAddress(getAddressTextValue());
AlertDialog.Builder builder = FavouritesDbHelper.checkDuplicates(point, helper, getMapActivity()); AlertDialog.Builder builder = FavouritesDbHelper.checkDuplicates(point, helper, getMapActivity());
@ -198,7 +198,7 @@ public class FavoritePointEditorFragment extends PointEditorFragment {
if (favorite.getName().equals(point.getName()) && if (favorite.getName().equals(point.getName()) &&
favorite.getCategory().equals(point.getCategory()) && favorite.getCategory().equals(point.getCategory()) &&
Algorithms.stringsEqual(favorite.getDescription(), point.getDescription()) && Algorithms.stringsEqual(favorite.getDescription(), point.getDescription()) &&
Algorithms.stringsEqual(favorite.getAddress(),point.getAddress())) { Algorithms.stringsEqual(favorite.getAddress(), point.getAddress())) {
if (needDismiss) { if (needDismiss) {
dismiss(false); dismiss(false);
} }
@ -209,7 +209,7 @@ public class FavoritePointEditorFragment extends PointEditorFragment {
builder.setPositiveButton(R.string.shared_string_ok, new DialogInterface.OnClickListener() { builder.setPositiveButton(R.string.shared_string_ok, new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
doSave(favorite, point.getName(), point.getCategory(), point.getDescription(),point.getAddress(), needDismiss); doSave(favorite, point.getName(), point.getCategory(), point.getDescription(), point.getAddress(), needDismiss);
} }
}); });
builder.create().show(); builder.create().show();
@ -225,9 +225,9 @@ public class FavoritePointEditorFragment extends PointEditorFragment {
FavoritePointEditor editor = getFavoritePointEditor(); FavoritePointEditor editor = getFavoritePointEditor();
if (editor != null && helper != null) { if (editor != null && helper != null) {
if (editor.isNew()) { if (editor.isNew()) {
doAddFavorite(name, category, description,address); doAddFavorite(name, category, description, address);
} else { } else {
helper.editFavouriteName(favorite, name, category, description,address); helper.editFavouriteName(favorite, name, category, description, address);
} }
} }
MapActivity mapActivity = getMapActivity(); MapActivity mapActivity = getMapActivity();

View file

@ -75,6 +75,9 @@ public class FavoritePointEditorFragmentNew extends PointEditorFragmentNew {
FavouritesDbHelper helper = getHelper(); FavouritesDbHelper helper = getHelper();
if (editor != null && helper != null) { if (editor != null && helper != null) {
FavouritePoint favorite = editor.getFavorite(); FavouritePoint favorite = editor.getFavorite();
if (favorite == null && savedInstanceState != null) {
favorite = (FavouritePoint) savedInstanceState.getSerializable(FavoriteDialogs.KEY_FAVORITE);
}
this.favorite = favorite; this.favorite = favorite;
this.group = helper.getGroup(favorite); this.group = helper.getGroup(favorite);
this.color = favorite.getColor(); this.color = favorite.getColor();
@ -109,6 +112,12 @@ public class FavoritePointEditorFragmentNew extends PointEditorFragmentNew {
return view; return view;
} }
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable(FavoriteDialogs.KEY_FAVORITE, getFavorite());
}
private void replacePressed() { private void replacePressed() {
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putSerializable(FavoriteDialogs.KEY_FAVORITE, getFavorite()); args.putSerializable(FavoriteDialogs.KEY_FAVORITE, getFavorite());
@ -242,7 +251,7 @@ public class FavoritePointEditorFragmentNew extends PointEditorFragmentNew {
final FavouritePoint favorite = getFavorite(); final FavouritePoint favorite = getFavorite();
if (favorite != null) { if (favorite != null) {
final FavouritePoint point = new FavouritePoint(favorite.getLatitude(), favorite.getLongitude(), final FavouritePoint point = new FavouritePoint(favorite.getLatitude(), favorite.getLongitude(),
getNameTextValue(), getCategoryTextValue()); getNameTextValue(), getCategoryTextValue(), favorite.getAltitude(), favorite.getTimestamp());
point.setDescription(isDescriptionAvailable() ? getDescriptionTextValue() : null); point.setDescription(isDescriptionAvailable() ? getDescriptionTextValue() : null);
point.setAddress(isAddressAvailable() ? getAddressTextValue() : null); point.setAddress(isAddressAvailable() ? getAddressTextValue() : null);
point.setColor(color); point.setColor(color);
@ -258,7 +267,7 @@ public class FavoritePointEditorFragmentNew extends PointEditorFragmentNew {
final FavouritePoint favorite = getFavorite(); final FavouritePoint favorite = getFavorite();
if (favorite != null) { if (favorite != null) {
final FavouritePoint point = new FavouritePoint(favorite.getLatitude(), favorite.getLongitude(), final FavouritePoint point = new FavouritePoint(favorite.getLatitude(), favorite.getLongitude(),
getNameTextValue(), getCategoryTextValue()); getNameTextValue(), getCategoryTextValue(), favorite.getAltitude(), favorite.getTimestamp());
point.setDescription(isDescriptionAvailable() ? getDescriptionTextValue() : null); point.setDescription(isDescriptionAvailable() ? getDescriptionTextValue() : null);
point.setAddress(isAddressAvailable() ? getAddressTextValue() : null); point.setAddress(isAddressAvailable() ? getAddressTextValue() : null);
point.setColor(color); point.setColor(color);

View file

@ -474,7 +474,7 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment implemen
if (!ColorDialogs.isPaletteColor(customColor)) { if (!ColorDialogs.isPaletteColor(customColor)) {
colors.add(customColor); colors.add(customColor);
} }
colorsCard = new ColorsCard(mapActivity, selectedColor, this, colors); colorsCard = new ColorsCard(mapActivity, selectedColor, this, colors, app.getSettings().CUSTOM_TRACK_COLORS, null);
colorsCard.setListener(this); colorsCard.setListener(this);
LinearLayout selectColor = view.findViewById(R.id.select_color); LinearLayout selectColor = view.findViewById(R.id.select_color);
selectColor.addView(colorsCard.build(view.getContext())); selectColor.addView(colorsCard.build(view.getContext()));

View file

@ -61,8 +61,7 @@ public class MapillaryFiltersFragment extends BaseOsmAndFragment {
final int backgroundColor = ContextCompat.getColor(getActivity(), final int backgroundColor = ContextCompat.getColor(getActivity(),
nightMode ? R.color.activity_background_color_dark : R.color.activity_background_color_light); nightMode ? R.color.activity_background_color_dark : R.color.activity_background_color_light);
final DateFormat dateFormat = SimpleDateFormat.getDateInstance(DateFormat.MEDIUM); final DateFormat dateFormat = SimpleDateFormat.getDateInstance(DateFormat.MEDIUM);
final int currentModeColorRes = getMyApplication().getSettings().getApplicationMode().getIconColorInfo().getColor(nightMode); final int currentModeColor = getMyApplication().getSettings().getApplicationMode().getProfileColor(nightMode);
final int currentModeColor = ContextCompat.getColor(getActivity(), currentModeColorRes);
final View view = View.inflate(new ContextThemeWrapper(getContext(), themeRes), R.layout.fragment_mapillary_filters, null); final View view = View.inflate(new ContextThemeWrapper(getContext(), themeRes), R.layout.fragment_mapillary_filters, null);
view.findViewById(R.id.mapillary_filters_linear_layout).setBackgroundColor(backgroundColor); view.findViewById(R.id.mapillary_filters_linear_layout).setBackgroundColor(backgroundColor);
@ -71,17 +70,17 @@ public class MapillaryFiltersFragment extends BaseOsmAndFragment {
final View toggleRow = view.findViewById(R.id.toggle_row); final View toggleRow = view.findViewById(R.id.toggle_row);
final boolean selected = settings.SHOW_MAPILLARY.get(); final boolean selected = settings.SHOW_MAPILLARY.get();
final int toggleActionStringId = selected ? R.string.shared_string_on : R.string.shared_string_off; final int toggleActionStringId = selected ? R.string.shared_string_on : R.string.shared_string_off;
int toggleIconColorId; int toggleIconColor;
int toggleIconId; int toggleIconId;
if (selected) { if (selected) {
toggleIconId = R.drawable.ic_action_view; toggleIconId = R.drawable.ic_action_view;
toggleIconColorId = currentModeColorRes; toggleIconColor = currentModeColor;
} else { } else {
toggleIconId = R.drawable.ic_action_hide; toggleIconId = R.drawable.ic_action_hide;
toggleIconColorId = nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light; toggleIconColor = ContextCompat.getColor(getContext(), nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light);
} }
((AppCompatTextView) toggleRow.findViewById(R.id.toggle_row_title)).setText(toggleActionStringId); ((AppCompatTextView) toggleRow.findViewById(R.id.toggle_row_title)).setText(toggleActionStringId);
final Drawable drawable = getIcon(toggleIconId, toggleIconColorId); final Drawable drawable = getPaintedContentIcon(toggleIconId, toggleIconColor);
((AppCompatImageView) toggleRow.findViewById(R.id.toggle_row_icon)).setImageDrawable(drawable); ((AppCompatImageView) toggleRow.findViewById(R.id.toggle_row_icon)).setImageDrawable(drawable);
final CompoundButton toggle = (CompoundButton) toggleRow.findViewById(R.id.toggle_row_toggle); final CompoundButton toggle = (CompoundButton) toggleRow.findViewById(R.id.toggle_row_toggle);
toggle.setOnCheckedChangeListener(null); toggle.setOnCheckedChangeListener(null);

View file

@ -185,7 +185,7 @@ public class MapillaryPlugin extends OsmandPlugin {
ContextMenuItem item = adapter.getItem(pos); ContextMenuItem item = adapter.getItem(pos);
if (item != null) { if (item != null) {
item.setSelected(settings.SHOW_MAPILLARY.get()); item.setSelected(settings.SHOW_MAPILLARY.get());
item.setColorRes(settings.SHOW_MAPILLARY.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); item.setColor(app, settings.SHOW_MAPILLARY.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID);
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
} }
} }
@ -201,7 +201,7 @@ public class MapillaryPlugin extends OsmandPlugin {
.setTitleId(R.string.street_level_imagery, mapActivity) .setTitleId(R.string.street_level_imagery, mapActivity)
.setDescription("Mapillary") .setDescription("Mapillary")
.setSelected(settings.SHOW_MAPILLARY.get()) .setSelected(settings.SHOW_MAPILLARY.get())
.setColor(settings.SHOW_MAPILLARY.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setColor(app, settings.SHOW_MAPILLARY.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID)
.setIcon(R.drawable.ic_action_mapillary) .setIcon(R.drawable.ic_action_mapillary)
.setSecondaryIcon(R.drawable.ic_action_additional_option) .setSecondaryIcon(R.drawable.ic_action_additional_option)
.setItemDeleteAction(makeDeleteAction(settings.SHOW_MAPILLARY)) .setItemDeleteAction(makeDeleteAction(settings.SHOW_MAPILLARY))

View file

@ -99,8 +99,7 @@ public class InputZoomLevelsBottomSheet extends MenuBottomSheetDialogFragment {
final TextView maxZoomValue = sliderView.findViewById(R.id.zoom_value_max); final TextView maxZoomValue = sliderView.findViewById(R.id.zoom_value_max);
maxZoomValue.setText(String.valueOf(maxZoom)); maxZoomValue.setText(String.valueOf(maxZoom));
RangeSlider slider = sliderView.findViewById(R.id.zoom_slider); RangeSlider slider = sliderView.findViewById(R.id.zoom_slider);
int colorProfileRes = app.getSettings().getApplicationMode().getIconColorInfo().getColor(nightMode); int colorProfile = app.getSettings().getApplicationMode().getProfileColor(nightMode);
int colorProfile = ContextCompat.getColor(app, colorProfileRes);
UiUtilities.setupSlider(slider, nightMode, colorProfile, true); UiUtilities.setupSlider(slider, nightMode, colorProfile, true);
slider.setValueFrom(SLIDER_FROM); slider.setValueFrom(SLIDER_FROM);
slider.setValueTo(SLIDER_TO); slider.setValueTo(SLIDER_TO);

View file

@ -1350,7 +1350,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
snapToRoadBtn.setVisibility(View.VISIBLE); snapToRoadBtn.setVisibility(View.VISIBLE);
profileWithConfig.setVisibility(View.GONE); profileWithConfig.setVisibility(View.GONE);
} else { } else {
icon = getIcon(appMode.getIconRes(), appMode.getIconColorInfo().getColor(nightMode)); icon = getPaintedContentIcon(appMode.getIconRes(), appMode.getProfileColor(nightMode));
snapToRoadBtn.setVisibility(View.GONE); snapToRoadBtn.setVisibility(View.GONE);
profileWithConfig.setVisibility(View.VISIBLE); profileWithConfig.setVisibility(View.VISIBLE);
} }

View file

@ -55,7 +55,7 @@ public class OptionsBottomSheetDialogFragment extends MenuBottomSheetDialogFragm
icon = getContentIcon(R.drawable.ic_action_split_interval); icon = getContentIcon(R.drawable.ic_action_split_interval);
} else { } else {
description = routeAppMode.toHumanString(); description = routeAppMode.toHumanString();
icon = getIcon(routeAppMode.getIconRes(), routeAppMode.getIconColorInfo().getColor(nightMode)); icon = getPaintedIcon(routeAppMode.getIconRes(), routeAppMode.getProfileColor(nightMode));
} }
} else { } else {
description = getString(R.string.shared_string_undefined); description = getString(R.string.shared_string_undefined);

View file

@ -49,7 +49,7 @@ public class ProfileCard extends BaseCard {
for (int i = 0; i < modes.size(); i++) { for (int i = 0; i < modes.size(); i++) {
ApplicationMode mode = modes.get(i); ApplicationMode mode = modes.get(i);
LinearLayout container = view.findViewById(R.id.content_container); LinearLayout container = view.findViewById(R.id.content_container);
Drawable icon = app.getUIUtilities().getIcon(mode.getIconRes(), mode.getIconColorInfo().getColor(nightMode)); Drawable icon = app.getUIUtilities().getPaintedIcon(mode.getIconRes(), mode.getProfileColor(nightMode));
String title = mode.toHumanString(); String title = mode.toHumanString();
View.OnClickListener onClickListener = new View.OnClickListener() { View.OnClickListener onClickListener = new View.OnClickListener() {
@Override @Override

View file

@ -117,7 +117,7 @@ public class RouteBetweenPointsBottomSheetDialogFragment extends BottomSheetBeha
for (int i = 0; i < modes.size(); i++) { for (int i = 0; i < modes.size(); i++) {
ApplicationMode mode = modes.get(i); ApplicationMode mode = modes.get(i);
if (!"public_transport".equals(mode.getRoutingProfile())) { if (!"public_transport".equals(mode.getRoutingProfile())) {
icon = app.getUIUtilities().getIcon(mode.getIconRes(), mode.getIconColorInfo().getColor(nightMode)); icon = app.getUIUtilities().getPaintedIcon(mode.getIconRes(), mode.getProfileColor(nightMode));
addProfileView(navigationType, onClickListener, i, icon, mode.toHumanString(), mode.equals(appMode)); addProfileView(navigationType, onClickListener, i, icon, mode.toHumanString(), mode.equals(appMode));
} }
} }

View file

@ -403,7 +403,7 @@ public class SelectedPointBottomSheetDialogFragment extends MenuBottomSheetDialo
if (MeasurementEditingContext.DEFAULT_APP_MODE.equals(routeAppMode)) { if (MeasurementEditingContext.DEFAULT_APP_MODE.equals(routeAppMode)) {
icon = getContentIcon(R.drawable.ic_action_split_interval); icon = getContentIcon(R.drawable.ic_action_split_interval);
} else { } else {
icon = getIcon(routeAppMode.getIconRes(), routeAppMode.getIconColorInfo().getColor(nightMode)); icon = getPaintedIcon(routeAppMode.getIconRes(), routeAppMode.getProfileColor(nightMode));
} }
return icon; return icon;
} }

View file

@ -106,7 +106,7 @@ public class SnapToRoadBottomSheetDialogFragment extends BottomSheetDialogFragme
for (int i = 0; i < modes.size(); i++) { for (int i = 0; i < modes.size(); i++) {
ApplicationMode mode = modes.get(i); ApplicationMode mode = modes.get(i);
Drawable icon = app.getUIUtilities().getIcon(mode.getIconRes(), mode.getIconColorInfo().getColor(nightMode)); Drawable icon = app.getUIUtilities().getPaintedIcon(mode.getIconRes(), mode.getProfileColor(nightMode));
addProfileView(container, onClickListener, i, icon, mode.toHumanString()); addProfileView(container, onClickListener, i, icon, mode.toHumanString());
} }

View file

@ -560,7 +560,7 @@ public class OsmandMonitoringPlugin extends OsmandPlugin {
ApplicationMode appMode = app.getSettings().getApplicationMode(); ApplicationMode appMode = app.getSettings().getApplicationMode();
int textColorPrimary = ContextCompat.getColor(app, nightMode ? R.color.text_color_primary_dark : R.color.text_color_primary_light); int textColorPrimary = ContextCompat.getColor(app, nightMode ? R.color.text_color_primary_dark : R.color.text_color_primary_light);
int textColorSecondary = ContextCompat.getColor(app, nightMode ? R.color.text_color_secondary_dark : R.color.text_color_secondary_light); int textColorSecondary = ContextCompat.getColor(app, nightMode ? R.color.text_color_secondary_dark : R.color.text_color_secondary_light);
int selectedModeColor = ContextCompat.getColor(uiCtx, appMode.getIconColorInfo().getColor(nightMode)); int selectedModeColor = appMode.getProfileColor(nightMode);
LinearLayout ll = new LinearLayout(uiCtx); LinearLayout ll = new LinearLayout(uiCtx);
final int dp24 = AndroidUtils.dpToPx(uiCtx, 24f); final int dp24 = AndroidUtils.dpToPx(uiCtx, 24f);
final int dp8 = AndroidUtils.dpToPx(uiCtx, 8f); final int dp8 = AndroidUtils.dpToPx(uiCtx, 8f);

View file

@ -116,8 +116,7 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment {
container = itemView.findViewById(R.id.always_ask_and_range_slider_container); container = itemView.findViewById(R.id.always_ask_and_range_slider_container);
RangeSlider intervalSlider = itemView.findViewById(R.id.interval_slider); RangeSlider intervalSlider = itemView.findViewById(R.id.interval_slider);
intervalSlider.setValueTo(secondsLength + minutesLength - 1); intervalSlider.setValueTo(secondsLength + minutesLength - 1);
int currentModeColorRes = app.getSettings().getApplicationMode().getIconColorInfo().getColor(nightMode); int currentModeColor = app.getSettings().getApplicationMode().getProfileColor(nightMode);
int currentModeColor = ContextCompat.getColor(app, currentModeColorRes);
UiUtilities.setupSlider(intervalSlider, nightMode, currentModeColor, true); UiUtilities.setupSlider(intervalSlider, nightMode, currentModeColor, true);
container.setVisibility(View.GONE); container.setVisibility(View.GONE);
intervalSlider.addOnChangeListener(new RangeSlider.OnChangeListener() { intervalSlider.addOnChangeListener(new RangeSlider.OnChangeListener() {

View file

@ -1005,6 +1005,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
} }
} }
}); });
notifyDataSetChanged();
} }
public Set<GpxInfo> getSelectedGpx() { public Set<GpxInfo> getSelectedGpx() {

View file

@ -121,7 +121,7 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment
final ApplicationMode mode = app.getSettings().getApplicationMode(); final ApplicationMode mode = app.getSettings().getApplicationMode();
final BottomSheetItemWithCompoundButton[] showOnMapItem = new BottomSheetItemWithCompoundButton[1]; final BottomSheetItemWithCompoundButton[] showOnMapItem = new BottomSheetItemWithCompoundButton[1];
showOnMapItem[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder() showOnMapItem[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder()
.setCompoundButtonColorId(mode.getIconColorInfo().getColor(nightMode)) .setCompoundButtonColor(mode.getProfileColor(nightMode))
.setChecked(checked) .setChecked(checked)
.setTitle(getString(R.string.shared_string_show_on_map)) .setTitle(getString(R.string.shared_string_show_on_map))
.setCustomView(getCustomButtonView(app, mode, checked, nightMode)) .setCustomView(getCustomButtonView(app, mode, checked, nightMode))

View file

@ -1,36 +0,0 @@
package net.osmand.plus.onlinerouting;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.plus.onlinerouting.engine.EngineType;
import net.osmand.plus.onlinerouting.engine.GraphhopperEngine;
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
import net.osmand.plus.onlinerouting.engine.OrsEngine;
import net.osmand.plus.onlinerouting.engine.OsrmEngine;
import java.util.Map;
public class OnlineRoutingFactory {
public static OnlineRoutingEngine createEngine(@NonNull EngineType type) {
return createEngine(type, null);
}
@NonNull
public static OnlineRoutingEngine createEngine(@NonNull EngineType type,
@Nullable Map<String, String> params) {
switch (type) {
case GRAPHHOPPER:
return new GraphhopperEngine(params);
case OSRM:
return new OsrmEngine(params);
case ORS:
return new OrsEngine(params);
default:
throw new IllegalArgumentException(
"Online routing type {" + type.name() + "} not supported");
}
}
}

View file

@ -18,14 +18,20 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipInputStream;
import static net.osmand.util.Algorithms.GZIP_FILE_SIGNATURE;
import static net.osmand.util.Algorithms.ZIP_FILE_SIGNATURE;
import static net.osmand.util.Algorithms.isEmpty; import static net.osmand.util.Algorithms.isEmpty;
public class OnlineRoutingHelper { public class OnlineRoutingHelper {
@ -88,7 +94,7 @@ public class OnlineRoutingHelper {
boolean leftSideNavigation) throws IOException, JSONException { boolean leftSideNavigation) throws IOException, JSONException {
String url = engine.getFullUrl(path); String url = engine.getFullUrl(path);
String content = makeRequest(url); String content = makeRequest(url);
return engine.parseServerResponse(content, app, leftSideNavigation); return engine.parseResponse(content, app, leftSideNavigation);
} }
@NonNull @NonNull
@ -98,7 +104,7 @@ public class OnlineRoutingHelper {
StringBuilder content = new StringBuilder(); StringBuilder content = new StringBuilder();
BufferedReader reader; BufferedReader reader;
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); reader = new BufferedReader(new InputStreamReader(getInputStream(connection)));
} else { } else {
reader = new BufferedReader(new InputStreamReader(connection.getErrorStream())); reader = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
} }
@ -113,6 +119,18 @@ public class OnlineRoutingHelper {
return content.toString(); return content.toString();
} }
private InputStream getInputStream(@NonNull HttpURLConnection connection) throws IOException {
ByteArrayInputStream localIS = Algorithms.createByteArrayIS(connection.getInputStream());
if (Algorithms.checkFileSignature(localIS, ZIP_FILE_SIGNATURE)) {
ZipInputStream zipIS = new ZipInputStream(localIS);
zipIS.getNextEntry(); // set position to reading for the first item
return zipIS;
} else if (Algorithms.checkFileSignature(localIS, GZIP_FILE_SIGNATURE)) {
return new GZIPInputStream(localIS);
}
return localIS;
}
public void saveEngine(@NonNull OnlineRoutingEngine engine) { public void saveEngine(@NonNull OnlineRoutingEngine engine) {
deleteInaccessibleParameters(engine); deleteInaccessibleParameters(engine);
String key = createEngineKeyIfNeeded(engine); String key = createEngineKeyIfNeeded(engine);

View file

@ -7,8 +7,8 @@ import androidx.annotation.NonNull;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import net.osmand.plus.onlinerouting.engine.EngineType;
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine; import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
import net.osmand.plus.onlinerouting.engine.EngineType;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import org.json.JSONArray; import org.json.JSONArray;
@ -60,10 +60,10 @@ public class OnlineRoutingUtils {
for (int i = 0; i < itemsJson.length(); i++) { for (int i = 0; i < itemsJson.length(); i++) {
JSONObject object = itemsJson.getJSONObject(i); JSONObject object = itemsJson.getJSONObject(i);
if (object.has(TYPE) && object.has(PARAMS)) { if (object.has(TYPE) && object.has(PARAMS)) {
EngineType type = EngineType.getTypeByName(object.getString(TYPE)); OnlineRoutingEngine type = EngineType.getTypeByName(object.getString(TYPE));
String paramsString = object.getString(PARAMS); String paramsString = object.getString(PARAMS);
HashMap<String, String> params = gson.fromJson(paramsString, typeToken); HashMap<String, String> params = gson.fromJson(paramsString, typeToken);
OnlineRoutingEngine engine = OnlineRoutingFactory.createEngine(type, params); OnlineRoutingEngine engine = type.newInstance(params);
if (!Algorithms.isEmpty(engine.getStringKey())) { if (!Algorithms.isEmpty(engine.getStringKey())) {
engines.add(engine); engines.add(engine);
} }
@ -82,7 +82,7 @@ public class OnlineRoutingUtils {
continue; continue;
} }
JSONObject jsonObject = new JSONObject(); JSONObject jsonObject = new JSONObject();
jsonObject.put(TYPE, engine.getType().name()); jsonObject.put(TYPE, engine.getTypeName());
jsonObject.put(PARAMS, gson.toJson(engine.getParams(), type)); jsonObject.put(PARAMS, gson.toJson(engine.getParams(), type));
jsonArray.put(jsonObject); jsonArray.put(jsonObject);
} }

View file

@ -6,6 +6,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.StringRes; import androidx.annotation.StringRes;
public class VehicleType { public class VehicleType {
private final String key; private final String key;
@StringRes @StringRes
private final int titleId; private final int titleId;

View file

@ -1,34 +1,38 @@
package net.osmand.plus.onlinerouting.engine; package net.osmand.plus.onlinerouting.engine;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
public enum EngineType { public class EngineType {
GRAPHHOPPER("Graphhopper"),
OSRM("OSRM"),
ORS("Openroute Service");
private final String title; public final static OnlineRoutingEngine GRAPHHOPPER_TYPE = new GraphhopperEngine(null);
public final static OnlineRoutingEngine OSRM_TYPE = new OsrmEngine(null);
public final static OnlineRoutingEngine ORS_TYPE = new OrsEngine(null);
public final static OnlineRoutingEngine GPX_TYPE = new GpxEngine(null);
EngineType(String title) { private static OnlineRoutingEngine[] enginesTypes;
this.title = title;
public static OnlineRoutingEngine[] values() {
if (enginesTypes == null) {
enginesTypes = new OnlineRoutingEngine[]{
GRAPHHOPPER_TYPE,
OSRM_TYPE,
ORS_TYPE,
GPX_TYPE
};
} }
return enginesTypes;
public String getTitle() {
return title;
} }
@NonNull @NonNull
public static EngineType getTypeByName(@Nullable String name) { public static OnlineRoutingEngine getTypeByName(@NonNull String typeName) {
if (!Algorithms.isEmpty(name)) { for (OnlineRoutingEngine type : values()) {
for (EngineType type : values()) { if (Algorithms.objectEquals(type.getTypeName(), typeName)) {
if (type.name().equals(name)) {
return type; return type;
} }
} }
}
return values()[0]; return values()[0];
} }
} }

View file

@ -0,0 +1,107 @@
package net.osmand.plus.onlinerouting.engine;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.GPXUtilities;
import net.osmand.GPXUtilities.GPXFile;
import net.osmand.data.LatLon;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.onlinerouting.EngineParameter;
import net.osmand.plus.onlinerouting.VehicleType;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static net.osmand.plus.onlinerouting.engine.EngineType.GPX_TYPE;
public class GpxEngine extends OnlineRoutingEngine {
public GpxEngine(@Nullable Map<String, String> params) {
super(params);
}
@NonNull
@Override
public OnlineRoutingEngine getType() {
return GPX_TYPE;
}
@Override
@NonNull
public String getTitle() {
return "GPX";
}
@NonNull
@Override
public String getTypeName() {
return "GPX";
}
@Override
protected void makeFullUrl(@NonNull StringBuilder sb,
@NonNull List<LatLon> path) {
for (int i = 0; i < path.size(); i++) {
LatLon point = path.get(i);
sb.append(point.getLongitude()).append(',').append(point.getLatitude());
if (i < path.size() - 1) {
sb.append(';');
}
}
}
@NonNull
@Override
public String getStandardUrl() {
return "";
}
@Override
protected void collectAllowedVehicles(@NonNull List<VehicleType> vehicles) {
}
@Override
protected void collectAllowedParameters(@NonNull Set<EngineParameter> params) {
params.add(EngineParameter.KEY);
params.add(EngineParameter.CUSTOM_NAME);
params.add(EngineParameter.NAME_INDEX);
params.add(EngineParameter.CUSTOM_URL);
}
@Override
public OnlineRoutingEngine newInstance(Map<String, String> params) {
return new GpxEngine(params);
}
@Override
@Nullable
public OnlineRoutingResponse parseResponse(@NonNull String content,
@NonNull OsmandApplication app,
boolean leftSideNavigation) {
GPXFile gpxFile = parseGpx(content);
return gpxFile != null ? new OnlineRoutingResponse(parseGpx(content)) : null;
}
@Override
public boolean isResultOk(@NonNull StringBuilder errorMessage,
@NonNull String content) {
return parseGpx(content) != null;
}
private GPXFile parseGpx(@NonNull String content) {
InputStream gpxStream;
try {
gpxStream = new ByteArrayInputStream(content.getBytes("UTF-8"));
return GPXUtilities.loadGPXFile(gpxStream);
} catch (UnsupportedEncodingException e) {
LOG.debug("Error when parsing GPX from server response: " + e.getMessage());
}
return null;
}
}

View file

@ -20,10 +20,12 @@ import org.json.JSONObject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import static net.osmand.plus.onlinerouting.engine.EngineType.GRAPHHOPPER_TYPE;
import static net.osmand.util.Algorithms.isEmpty; import static net.osmand.util.Algorithms.isEmpty;
public class GraphhopperEngine extends OnlineRoutingEngine { public class GraphhopperEngine extends JsonOnlineRoutingEngine {
public GraphhopperEngine(@Nullable Map<String, String> params) { public GraphhopperEngine(@Nullable Map<String, String> params) {
super(params); super(params);
@ -31,8 +33,20 @@ public class GraphhopperEngine extends OnlineRoutingEngine {
@NonNull @NonNull
@Override @Override
public EngineType getType() { public OnlineRoutingEngine getType() {
return EngineType.GRAPHHOPPER; return GRAPHHOPPER_TYPE;
}
@Override
@NonNull
public String getTitle() {
return "Graphhopper";
}
@NonNull
@Override
public String getTypeName() {
return "GRAPHHOPPER";
} }
@NonNull @NonNull
@ -42,8 +56,18 @@ public class GraphhopperEngine extends OnlineRoutingEngine {
} }
@Override @Override
protected void collectAllowedParameters() { protected void collectAllowedParameters(@NonNull Set<EngineParameter> params) {
allowParameters(EngineParameter.API_KEY); params.add(EngineParameter.KEY);
params.add(EngineParameter.VEHICLE_KEY);
params.add(EngineParameter.CUSTOM_NAME);
params.add(EngineParameter.NAME_INDEX);
params.add(EngineParameter.CUSTOM_URL);
params.add(EngineParameter.API_KEY);
}
@Override
public OnlineRoutingEngine newInstance(Map<String, String> params) {
return new GraphhopperEngine(params);
} }
@Override @Override
@ -82,8 +106,7 @@ public class GraphhopperEngine extends OnlineRoutingEngine {
} }
@Nullable @Nullable
@Override protected OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root,
public OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root,
@NonNull OsmandApplication app, @NonNull OsmandApplication app,
boolean leftSideNavigation) throws JSONException { boolean leftSideNavigation) throws JSONException {
String encoded = root.getString("points"); String encoded = root.getString("points");
@ -223,4 +246,5 @@ public class GraphhopperEngine extends OnlineRoutingEngine {
protected String getRootArrayKey() { protected String getRootArrayKey() {
return "paths"; return "paths";
} }
} }

View file

@ -0,0 +1,82 @@
package net.osmand.plus.onlinerouting.engine;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.GPXUtilities.WptPt;
import net.osmand.Location;
import net.osmand.data.LatLon;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.routing.RouteProvider;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static net.osmand.util.Algorithms.isEmpty;
public abstract class JsonOnlineRoutingEngine extends OnlineRoutingEngine {
public JsonOnlineRoutingEngine(@Nullable Map<String, String> params) {
super(params);
}
@Nullable
public OnlineRoutingResponse parseResponse(@NonNull String content,
@NonNull OsmandApplication app,
boolean leftSideNavigation) throws JSONException {
JSONObject root = parseRootResponseObject(content);
return root != null ? parseServerResponse(root, app, leftSideNavigation) : null;
}
@Nullable
protected JSONObject parseRootResponseObject(@NonNull String content) throws JSONException {
JSONObject fullJSON = new JSONObject(content);
String key = getRootArrayKey();
JSONArray array = null;
if (fullJSON.has(key)) {
array = fullJSON.getJSONArray(key);
}
return array != null && array.length() > 0 ? array.getJSONObject(0) : null;
}
public boolean isResultOk(@NonNull StringBuilder errorMessage,
@NonNull String content) throws JSONException {
JSONObject obj = new JSONObject(content);
String messageKey = getErrorMessageKey();
if (obj.has(messageKey)) {
String message = obj.getString(messageKey);
errorMessage.append(message);
}
return obj.has(getRootArrayKey());
}
@Nullable
protected abstract OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root,
@NonNull OsmandApplication app,
boolean leftSideNavigation) throws JSONException;
@NonNull
protected abstract String getRootArrayKey();
@NonNull
protected abstract String getErrorMessageKey();
@NonNull
protected static List<Location> convertRouteToLocationsList(@NonNull List<LatLon> route) {
List<Location> result = new ArrayList<>();
if (!isEmpty(route)) {
for (LatLon pt : route) {
WptPt wpt = new WptPt();
wpt.lat = pt.getLatitude();
wpt.lon = pt.getLongitude();
result.add(RouteProvider.createLocation(wpt));
}
}
return result;
}
}

View file

@ -5,24 +5,21 @@ import android.content.Context;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import net.osmand.GPXUtilities.WptPt; import net.osmand.GPXUtilities.GPXFile;
import net.osmand.Location; import net.osmand.Location;
import net.osmand.PlatformUtil;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.EngineParameter;
import net.osmand.plus.onlinerouting.OnlineRoutingFactory;
import net.osmand.plus.onlinerouting.VehicleType; import net.osmand.plus.onlinerouting.VehicleType;
import net.osmand.plus.routing.RouteDirectionInfo; import net.osmand.plus.routing.RouteDirectionInfo;
import net.osmand.plus.routing.RouteProvider;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import org.json.JSONArray; import org.apache.commons.logging.Log;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -34,6 +31,8 @@ import static net.osmand.util.Algorithms.isEmpty;
public abstract class OnlineRoutingEngine implements Cloneable { public abstract class OnlineRoutingEngine implements Cloneable {
protected static final Log LOG = PlatformUtil.getLog(OnlineRoutingEngine.class);
public final static String ONLINE_ROUTING_ENGINE_PREFIX = "online_routing_engine_"; public final static String ONLINE_ROUTING_ENGINE_PREFIX = "online_routing_engine_";
public final static VehicleType CUSTOM_VEHICLE = new VehicleType("", R.string.shared_string_custom); public final static VehicleType CUSTOM_VEHICLE = new VehicleType("", R.string.shared_string_custom);
@ -46,11 +45,17 @@ public abstract class OnlineRoutingEngine implements Cloneable {
this.params.putAll(params); this.params.putAll(params);
} }
collectAllowedVehiclesInternal(); collectAllowedVehiclesInternal();
collectAllowedParametersInternal(); collectAllowedParameters(allowedParameters);
} }
@NonNull @NonNull
public abstract EngineType getType(); public abstract OnlineRoutingEngine getType();
@NonNull
public abstract String getTitle();
@NonNull
public abstract String getTypeName();
@Nullable @Nullable
public String getStringKey() { public String getStringKey() {
@ -100,45 +105,13 @@ public abstract class OnlineRoutingEngine implements Cloneable {
@NonNull @NonNull
public abstract String getStandardUrl(); public abstract String getStandardUrl();
public OnlineRoutingResponse parseServerResponse(@NonNull String content,
@NonNull OsmandApplication app,
boolean leftSideNavigation) throws JSONException {
JSONObject root = parseRootResponseObject(content);
return root != null ? parseServerResponse(root, app, leftSideNavigation) : null;
}
@Nullable @Nullable
protected abstract OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, public abstract OnlineRoutingResponse parseResponse(@NonNull String content,
@NonNull OsmandApplication app, @NonNull OsmandApplication app,
boolean leftSideNavigation) throws JSONException; boolean leftSideNavigation) throws JSONException;
@Nullable public abstract boolean isResultOk(@NonNull StringBuilder errorMessage,
protected JSONObject parseRootResponseObject(@NonNull String content) throws JSONException { @NonNull String content) throws JSONException;
JSONObject fullJSON = new JSONObject(content);
String responseArrayKey = getRootArrayKey();
JSONArray array = null;
if (fullJSON.has(responseArrayKey)) {
array = fullJSON.getJSONArray(responseArrayKey);
}
return array != null && array.length() > 0 ? array.getJSONObject(0) : null;
}
@NonNull
protected abstract String getRootArrayKey();
@NonNull
protected List<Location> convertRouteToLocationsList(@NonNull List<LatLon> route) {
List<Location> result = new ArrayList<>();
if (!isEmpty(route)) {
for (LatLon pt : route) {
WptPt wpt = new WptPt();
wpt.lat = pt.getLatitude();
wpt.lon = pt.getLongitude();
result.add(RouteProvider.createLocation(wpt));
}
}
return result;
}
@NonNull @NonNull
public Map<String, String> getParams() { public Map<String, String> getParams() {
@ -171,23 +144,12 @@ public abstract class OnlineRoutingEngine implements Cloneable {
return Collections.unmodifiableList(allowedVehicles); return Collections.unmodifiableList(allowedVehicles);
} }
private void collectAllowedParametersInternal() { protected abstract void collectAllowedParameters(@NonNull Set<EngineParameter> params);
allowedParameters.clear();
allowParameters(EngineParameter.KEY, EngineParameter.VEHICLE_KEY,
EngineParameter.CUSTOM_NAME, EngineParameter.NAME_INDEX, EngineParameter.CUSTOM_URL);
collectAllowedParameters();
}
protected abstract void collectAllowedParameters();
public boolean isParameterAllowed(EngineParameter key) { public boolean isParameterAllowed(EngineParameter key) {
return allowedParameters.contains(key); return allowedParameters.contains(key);
} }
protected void allowParameters(@NonNull EngineParameter... allowedParams) {
allowedParameters.addAll(Arrays.asList(allowedParams));
}
@Nullable @Nullable
private String getSelectedVehicleName(@NonNull Context ctx) { private String getSelectedVehicleName(@NonNull Context ctx) {
String key = get(EngineParameter.VEHICLE_KEY); String key = get(EngineParameter.VEHICLE_KEY);
@ -216,24 +178,10 @@ public abstract class OnlineRoutingEngine implements Cloneable {
return CUSTOM_VEHICLE; return CUSTOM_VEHICLE;
} }
public boolean checkServerResponse(@NonNull StringBuilder errorMessage,
@NonNull String content) throws JSONException {
JSONObject obj = new JSONObject(content);
String messageKey = getErrorMessageKey();
if (obj.has(messageKey)) {
String message = obj.getString(messageKey);
errorMessage.append(message);
}
return obj.has(getRootArrayKey());
}
@NonNull
protected abstract String getErrorMessageKey();
@NonNull @NonNull
@Override @Override
public Object clone() { public Object clone() {
return OnlineRoutingFactory.createEngine(getType(), getParams()); return newInstance(getParams());
} }
@Override @Override
@ -246,20 +194,30 @@ public abstract class OnlineRoutingEngine implements Cloneable {
return Algorithms.objectEquals(getParams(), engine.getParams()); return Algorithms.objectEquals(getParams(), engine.getParams());
} }
public abstract OnlineRoutingEngine newInstance(Map<String, String> params);
@NonNull @NonNull
public static String generateKey() { public static String generateKey() {
return ONLINE_ROUTING_ENGINE_PREFIX + System.currentTimeMillis(); return ONLINE_ROUTING_ENGINE_PREFIX + System.currentTimeMillis();
} }
public static class OnlineRoutingResponse { public static class OnlineRoutingResponse {
private List<Location> route; private List<Location> route;
private List<RouteDirectionInfo> directions; private List<RouteDirectionInfo> directions;
private GPXFile gpxFile;
// constructor for JSON responses
public OnlineRoutingResponse(List<Location> route, List<RouteDirectionInfo> directions) { public OnlineRoutingResponse(List<Location> route, List<RouteDirectionInfo> directions) {
this.route = route; this.route = route;
this.directions = directions; this.directions = directions;
} }
// constructor for GPX responses
public OnlineRoutingResponse(GPXFile gpxFile) {
this.gpxFile = gpxFile;
}
public List<Location> getRoute() { public List<Location> getRoute() {
return route; return route;
} }
@ -267,5 +225,10 @@ public abstract class OnlineRoutingEngine implements Cloneable {
public List<RouteDirectionInfo> getDirections() { public List<RouteDirectionInfo> getDirections() {
return directions; return directions;
} }
public GPXFile getGpxFile() {
return gpxFile;
} }
}
} }

View file

@ -17,10 +17,12 @@ import org.json.JSONObject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import static net.osmand.plus.onlinerouting.engine.EngineType.ORS_TYPE;
import static net.osmand.util.Algorithms.isEmpty; import static net.osmand.util.Algorithms.isEmpty;
public class OrsEngine extends OnlineRoutingEngine { public class OrsEngine extends JsonOnlineRoutingEngine {
public OrsEngine(@Nullable Map<String, String> params) { public OrsEngine(@Nullable Map<String, String> params) {
super(params); super(params);
@ -28,8 +30,20 @@ public class OrsEngine extends OnlineRoutingEngine {
@NonNull @NonNull
@Override @Override
public EngineType getType() { public OnlineRoutingEngine getType() {
return EngineType.ORS; return ORS_TYPE;
}
@Override
@NonNull
public String getTitle() {
return "Openroute Service";
}
@NonNull
@Override
public String getTypeName() {
return "ORS";
} }
@NonNull @NonNull
@ -39,8 +53,18 @@ public class OrsEngine extends OnlineRoutingEngine {
} }
@Override @Override
protected void collectAllowedParameters() { protected void collectAllowedParameters(@NonNull Set<EngineParameter> params) {
allowParameters(EngineParameter.API_KEY); params.add(EngineParameter.KEY);
params.add(EngineParameter.VEHICLE_KEY);
params.add(EngineParameter.CUSTOM_NAME);
params.add(EngineParameter.NAME_INDEX);
params.add(EngineParameter.CUSTOM_URL);
params.add(EngineParameter.API_KEY);
}
@Override
public OnlineRoutingEngine newInstance(Map<String, String> params) {
return new OrsEngine(params);
} }
@Override @Override
@ -109,4 +133,5 @@ public class OrsEngine extends OnlineRoutingEngine {
protected String getRootArrayKey() { protected String getRootArrayKey() {
return "features"; return "features";
} }
} }

View file

@ -22,20 +22,34 @@ import org.json.JSONObject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import static net.osmand.plus.onlinerouting.engine.EngineType.OSRM_TYPE;
import static net.osmand.util.Algorithms.isEmpty; import static net.osmand.util.Algorithms.isEmpty;
import static net.osmand.util.Algorithms.objectEquals; import static net.osmand.util.Algorithms.objectEquals;
public class OsrmEngine extends OnlineRoutingEngine { public class OsrmEngine extends JsonOnlineRoutingEngine {
public OsrmEngine(@Nullable Map<String, String> params) { public OsrmEngine(@Nullable Map<String, String> params) {
super(params); super(params);
} }
@Override @Override
public @NonNull @NonNull
EngineType getType() { public OnlineRoutingEngine getType() {
return EngineType.OSRM; return OSRM_TYPE;
}
@Override
@NonNull
public String getTitle() {
return "OSRM";
}
@NonNull
@Override
public String getTypeName() {
return "OSRM";
} }
@NonNull @NonNull
@ -45,7 +59,17 @@ public class OsrmEngine extends OnlineRoutingEngine {
} }
@Override @Override
protected void collectAllowedParameters() { protected void collectAllowedParameters(@NonNull Set<EngineParameter> params) {
params.add(EngineParameter.KEY);
params.add(EngineParameter.VEHICLE_KEY);
params.add(EngineParameter.CUSTOM_NAME);
params.add(EngineParameter.NAME_INDEX);
params.add(EngineParameter.CUSTOM_URL);
}
@Override
public OnlineRoutingEngine newInstance(Map<String, String> params) {
return new OsrmEngine(params);
} }
@Override @Override
@ -76,7 +100,7 @@ public class OsrmEngine extends OnlineRoutingEngine {
@Nullable @Nullable
@Override @Override
public OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, protected OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root,
@NonNull OsmandApplication app, @NonNull OsmandApplication app,
boolean leftSideNavigation) throws JSONException { boolean leftSideNavigation) throws JSONException {
String encodedPoints = root.getString("geometry"); String encodedPoints = root.getString("geometry");
@ -225,13 +249,14 @@ public class OsrmEngine extends OnlineRoutingEngine {
@NonNull @NonNull
@Override @Override
protected String getErrorMessageKey() { protected String getRootArrayKey() {
return "message"; return "routes";
} }
@NonNull @NonNull
@Override @Override
protected String getRootArrayKey() { protected String getErrorMessageKey() {
return "routes"; return "message";
} }
} }

View file

@ -78,7 +78,7 @@ public class OnlineRoutingCard extends BaseCard {
bottomDivider = view.findViewById(R.id.bottom_divider); bottomDivider = view.findViewById(R.id.bottom_divider);
button = view.findViewById(R.id.button); button = view.findViewById(R.id.button);
int activeColor = ContextCompat.getColor(app, appMode.getIconColorInfo().getColor(nightMode)); int activeColor = appMode.getProfileColor(nightMode);
textFieldBoxes.setPrimaryColor(activeColor); textFieldBoxes.setPrimaryColor(activeColor);
textFieldBoxes.setGravityFloatingLabel(Gravity.START); textFieldBoxes.setGravityFloatingLabel(Gravity.START);

View file

@ -39,12 +39,11 @@ import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.BaseOsmAndFragment; import net.osmand.plus.base.BaseOsmAndFragment;
import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionItem; import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionItem;
import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.EngineParameter;
import net.osmand.plus.onlinerouting.OnlineRoutingFactory;
import net.osmand.plus.onlinerouting.OnlineRoutingHelper; import net.osmand.plus.onlinerouting.OnlineRoutingHelper;
import net.osmand.plus.onlinerouting.OnlineRoutingUtils; import net.osmand.plus.onlinerouting.OnlineRoutingUtils;
import net.osmand.plus.onlinerouting.VehicleType; import net.osmand.plus.onlinerouting.VehicleType;
import net.osmand.plus.onlinerouting.engine.EngineType;
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine; import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
import net.osmand.plus.onlinerouting.engine.EngineType;
import net.osmand.plus.onlinerouting.ui.OnlineRoutingCard.OnTextChangedListener; import net.osmand.plus.onlinerouting.ui.OnlineRoutingCard.OnTextChangedListener;
import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.routepreparationmenu.cards.BaseCard;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
@ -54,7 +53,9 @@ import org.json.JSONException;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import static net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine.CUSTOM_VEHICLE; import static net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine.CUSTOM_VEHICLE;
@ -201,15 +202,15 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
typeCard = new OnlineRoutingCard(mapActivity, isNightMode(), appMode); typeCard = new OnlineRoutingCard(mapActivity, isNightMode(), appMode);
typeCard.build(mapActivity); typeCard.build(mapActivity);
typeCard.setHeaderTitle(getString(R.string.shared_string_type)); typeCard.setHeaderTitle(getString(R.string.shared_string_type));
List<HorizontalSelectionItem> serverItems = new ArrayList<>(); List<HorizontalSelectionItem> typeItems = new ArrayList<>();
for (EngineType server : EngineType.values()) { for (OnlineRoutingEngine type : EngineType.values()) {
serverItems.add(new HorizontalSelectionItem(server.getTitle(), server)); typeItems.add(new HorizontalSelectionItem(type.getTitle(), type));
} }
typeCard.setSelectionMenu(serverItems, engine.getType().getTitle(), typeCard.setSelectionMenu(typeItems, engine.getType().getTitle(),
new CallbackWithObject<HorizontalSelectionItem>() { new CallbackWithObject<HorizontalSelectionItem>() {
@Override @Override
public boolean processResult(HorizontalSelectionItem result) { public boolean processResult(HorizontalSelectionItem result) {
EngineType type = (EngineType) result.getObject(); OnlineRoutingEngine type = (OnlineRoutingEngine) result.getObject();
if (engine.getType() != type) { if (engine.getType() != type) {
changeEngineType(type); changeEngineType(type);
return true; return true;
@ -366,9 +367,9 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
}); });
} }
private void changeEngineType(EngineType type) { private void changeEngineType(OnlineRoutingEngine type) {
OnlineRoutingEngine tmp = (OnlineRoutingEngine) engine.clone(); OnlineRoutingEngine tmp = (OnlineRoutingEngine) engine.clone();
engine = OnlineRoutingFactory.createEngine(type, tmp.getParams()); engine = type.newInstance(tmp.getParams());
// after changing the type, select the vehicle // after changing the type, select the vehicle
// with the same name that was selected before // with the same name that was selected before
@ -462,7 +463,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
boolean resultOk = false; boolean resultOk = false;
try { try {
String response = helper.makeRequest(exampleCard.getEditedText()); String response = helper.makeRequest(exampleCard.getEditedText());
resultOk = requestedEngine.checkServerResponse(errorMessage, response); resultOk = requestedEngine.isResultOk(errorMessage, response);
} catch (IOException | JSONException e) { } catch (IOException | JSONException e) {
errorMessage.append(e.toString()); errorMessage.append(e.toString());
} }
@ -514,6 +515,12 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
} else { } else {
apiKeyCard.hide(); apiKeyCard.hide();
} }
if (engine.isParameterAllowed(EngineParameter.VEHICLE_KEY)) {
vehicleCard.show();
} else {
vehicleCard.hide();
}
} else if (vehicleCard.equals(card)) { } else if (vehicleCard.equals(card)) {
VehicleType vt = engine.getSelectedVehicleType(); VehicleType vt = engine.getSelectedVehicleType();
@ -609,7 +616,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
} }
private void saveState(@NonNull Bundle outState) { private void saveState(@NonNull Bundle outState) {
outState.putString(ENGINE_TYPE_KEY, engine.getType().name()); outState.putString(ENGINE_TYPE_KEY, engine.getTypeName());
for (EngineParameter key : EngineParameter.values()) { for (EngineParameter key : EngineParameter.values()) {
String value = engine.get(key); String value = engine.get(key);
if (value != null) { if (value != null) {
@ -626,14 +633,15 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
editedEngineKey = savedState.getString(EngineParameter.KEY.name()); editedEngineKey = savedState.getString(EngineParameter.KEY.name());
initEngine = createInitStateEngine(); initEngine = createInitStateEngine();
String typeKey = savedState.getString(ENGINE_TYPE_KEY); String typeKey = savedState.getString(ENGINE_TYPE_KEY);
EngineType type = EngineType.getTypeByName(typeKey); OnlineRoutingEngine type = EngineType.getTypeByName(typeKey);
engine = OnlineRoutingFactory.createEngine(type); Map<String, String> params = new HashMap<>();
for (EngineParameter key : EngineParameter.values()) { for (EngineParameter key : EngineParameter.values()) {
String value = savedState.getString(key.name()); String value = savedState.getString(key.name());
if (value != null) { if (value != null) {
engine.put(key, value); params.put(key.name(), value);
} }
} }
engine = type.newInstance(params);
customVehicleKey = savedState.getString(ENGINE_CUSTOM_VEHICLE_KEY); customVehicleKey = savedState.getString(ENGINE_CUSTOM_VEHICLE_KEY);
selectedLocation = ExampleLocation.valueOf(savedState.getString(EXAMPLE_LOCATION_KEY)); selectedLocation = ExampleLocation.valueOf(savedState.getString(EXAMPLE_LOCATION_KEY));
appMode = ApplicationMode.valueOfStringKey(savedState.getString(APP_MODE_KEY), null); appMode = ApplicationMode.valueOfStringKey(savedState.getString(APP_MODE_KEY), null);
@ -656,7 +664,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
if (editedEngine != null) { if (editedEngine != null) {
engine = (OnlineRoutingEngine) editedEngine.clone(); engine = (OnlineRoutingEngine) editedEngine.clone();
} else { } else {
engine = OnlineRoutingFactory.createEngine(EngineType.values()[0]); engine = EngineType.values()[0].newInstance(null);
String vehicle = engine.getAllowedVehicles().get(0).getKey(); String vehicle = engine.getAllowedVehicles().get(0).getKey();
engine.put(EngineParameter.VEHICLE_KEY, vehicle); engine.put(EngineParameter.VEHICLE_KEY, vehicle);
if (editedEngineKey != null) { if (editedEngineKey != null) {

View file

@ -324,7 +324,7 @@ public class OsmEditingPlugin extends OsmandPlugin {
.setTitleId(R.string.layer_osm_bugs, mapActivity) .setTitleId(R.string.layer_osm_bugs, mapActivity)
.setSelected(settings.SHOW_OSM_BUGS.get()) .setSelected(settings.SHOW_OSM_BUGS.get())
.setIcon(R.drawable.ic_action_osm_note) .setIcon(R.drawable.ic_action_osm_note)
.setColor(settings.SHOW_OSM_BUGS.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setColor(app, settings.SHOW_OSM_BUGS.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID)
.setSecondaryIcon(R.drawable.ic_action_additional_option) .setSecondaryIcon(R.drawable.ic_action_additional_option)
.setListener(new ContextMenuAdapter.OnRowItemClick() { .setListener(new ContextMenuAdapter.OnRowItemClick() {
@ -343,7 +343,7 @@ public class OsmEditingPlugin extends OsmandPlugin {
if (itemId == R.string.layer_osm_bugs) { if (itemId == R.string.layer_osm_bugs) {
OsmandPreference<Boolean> showOsmBugs = settings.SHOW_OSM_BUGS; OsmandPreference<Boolean> showOsmBugs = settings.SHOW_OSM_BUGS;
showOsmBugs.set(isChecked); showOsmBugs.set(isChecked);
adapter.getItem(pos).setColorRes(showOsmBugs.get() ? adapter.getItem(pos).setColor(app, showOsmBugs.get() ?
R.color.osmand_orange : ContextMenuItem.INVALID_ID); R.color.osmand_orange : ContextMenuItem.INVALID_ID);
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
updateLayers(mapActivity.getMapView(), mapActivity); updateLayers(mapActivity.getMapView(), mapActivity);
@ -359,14 +359,14 @@ public class OsmEditingPlugin extends OsmandPlugin {
.setTitleId(R.string.layer_osm_edits, mapActivity) .setTitleId(R.string.layer_osm_edits, mapActivity)
.setSelected(settings.SHOW_OSM_EDITS.get()) .setSelected(settings.SHOW_OSM_EDITS.get())
.setIcon(R.drawable.ic_action_openstreetmap_logo) .setIcon(R.drawable.ic_action_openstreetmap_logo)
.setColor(settings.SHOW_OSM_EDITS.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setColor(app, settings.SHOW_OSM_EDITS.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID)
.setListener(new ContextMenuAdapter.OnRowItemClick() { .setListener(new ContextMenuAdapter.OnRowItemClick() {
@Override @Override
public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) { public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) {
if (itemId == R.string.layer_osm_edits) { if (itemId == R.string.layer_osm_edits) {
OsmandPreference<Boolean> showOsmEdits = settings.SHOW_OSM_EDITS; OsmandPreference<Boolean> showOsmEdits = settings.SHOW_OSM_EDITS;
showOsmEdits.set(isChecked); showOsmEdits.set(isChecked);
adapter.getItem(pos).setColorRes(showOsmEdits.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); adapter.getItem(pos).setColor(app, showOsmEdits.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID);
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
updateLayers(mapActivity.getMapView(), mapActivity); updateLayers(mapActivity.getMapView(), mapActivity);
} }
@ -404,7 +404,7 @@ public class OsmEditingPlugin extends OsmandPlugin {
final AvailableGPXFragment f = ((AvailableGPXFragment) fragment); final AvailableGPXFragment f = ((AvailableGPXFragment) fragment);
optionsMenuAdapter.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.local_index_mi_upload_gpx, activity) optionsMenuAdapter.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.local_index_mi_upload_gpx, activity)
.setIcon(R.drawable.ic_action_export) .setIcon(R.drawable.ic_action_export)
.setColor(R.color.color_white) .setColor(app, R.color.color_white)
.setListener(new ItemClickListener() { .setListener(new ItemClickListener() {
@Override @Override

View file

@ -46,7 +46,7 @@ public class OsmNotesMenu {
final boolean nightMode = isNightMode(app); final boolean nightMode = isNightMode(app);
final int themeRes = getThemeRes(app); final int themeRes = getThemeRes(app);
final int selectedModeColor = ContextCompat.getColor(app, settings.getApplicationMode().getIconColorInfo().getColor(nightMode)); final int selectedModeColor = settings.getApplicationMode().getProfileColor(nightMode);
final int osmNotesStringId = R.string.layer_osm_bugs; final int osmNotesStringId = R.string.layer_osm_bugs;
final int showZoomLevelStringId = R.string.show_from_zoom_level; final int showZoomLevelStringId = R.string.show_from_zoom_level;
@ -110,7 +110,7 @@ public class OsmNotesMenu {
.setTitleId(osmNotesStringId, mapActivity) .setTitleId(osmNotesStringId, mapActivity)
.setDescription(mapActivity.getString(R.string.switch_osm_notes_visibility_desc)) .setDescription(mapActivity.getString(R.string.switch_osm_notes_visibility_desc))
.setIcon(R.drawable.ic_action_osm_note) .setIcon(R.drawable.ic_action_osm_note)
.setColor(toggleIconColorId) .setColor(app, toggleIconColorId)
.setListener(l) .setListener(l)
.setSelected(showOsmBugs) .setSelected(showOsmBugs)
.createItem()); .createItem());

View file

@ -310,13 +310,12 @@ public class RearrangePoiFiltersFragment extends DialogFragment implements Selec
ImageView profileIcon = (ImageView) view.findViewById(R.id.profile_icon); ImageView profileIcon = (ImageView) view.findViewById(R.id.profile_icon);
if (profileIcon != null) { if (profileIcon != null) {
int iconRes = selectedAppMode.getIconRes(); int iconRes = selectedAppMode.getIconRes();
int iconColor = selectedAppMode.getIconColorInfo().getColor(nightMode); profileIcon.setImageDrawable(uiUtilities.getPaintedIcon(iconRes, selectedAppMode.getProfileColor(nightMode)));
profileIcon.setImageDrawable(uiUtilities.getPaintedIcon(iconRes, iconColor));
} }
View profileButton = view.findViewById(R.id.profile_button); View profileButton = view.findViewById(R.id.profile_button);
if (profileButton != null) { if (profileButton != null) {
int iconColor = getSelectedAppMode().getIconColorInfo().getColor(nightMode); int iconColor = getSelectedAppMode().getProfileColor(nightMode);
int bgColor = ContextCompat.getColor(app, nightMode ? int bgColor = ContextCompat.getColor(app, nightMode ?
R.color.divider_color_dark : R.color.active_buttons_and_links_text_light); R.color.divider_color_dark : R.color.active_buttons_and_links_text_light);
int selectedColor = UiUtilities.getColorWithAlpha(iconColor, 0.3f); int selectedColor = UiUtilities.getColorWithAlpha(iconColor, 0.3f);

View file

@ -67,7 +67,7 @@ public class AppProfileArrayAdapter extends ArrayAdapter<ProfileDataObject> {
Drawable iconDrawable; Drawable iconDrawable;
boolean lightContent = app.getSettings().isLightContent(); boolean lightContent = app.getSettings().isLightContent();
if (mode.isSelected()) { if (mode.isSelected()) {
iconDrawable = app.getUIUtilities().getIcon(mode.getIconRes(), mode.getIconColor(!lightContent)); iconDrawable = app.getUIUtilities().getPaintedIcon(mode.getIconRes(), mode.getIconColor(!lightContent));
} else { } else {
iconDrawable = app.getUIUtilities().getIcon(mode.getIconRes(), lightContent); iconDrawable = app.getUIUtilities().getIcon(mode.getIconRes(), lightContent);
} }

View file

@ -6,10 +6,12 @@ import android.view.ViewGroup;
import android.widget.CompoundButton; import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.CompoundButton.OnCheckedChangeListener;
import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes; import androidx.annotation.ColorRes;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.view.ContextThemeWrapper; import androidx.appcompat.view.ContextThemeWrapper;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
@ -35,8 +37,8 @@ public class ConfigureProfileMenuAdapter extends AbstractProfileMenuAdapter<Conf
@Nullable @Nullable
private ProfileSelectedListener profileSelectedListener; private ProfileSelectedListener profileSelectedListener;
private final OsmandApplication app; private final OsmandApplication app;
@ColorRes @ColorInt
private int selectedIconColorRes; private int selectedIconColor;
private boolean bottomButton; private boolean bottomButton;
private String bottomButtonText; private String bottomButtonText;
private static final String BUTTON_ITEM = "button_item"; private static final String BUTTON_ITEM = "button_item";
@ -54,9 +56,10 @@ public class ConfigureProfileMenuAdapter extends AbstractProfileMenuAdapter<Conf
this.bottomButton = !Algorithms.isEmpty(bottomButtonText); this.bottomButton = !Algorithms.isEmpty(bottomButtonText);
this.bottomButtonText = bottomButtonText; this.bottomButtonText = bottomButtonText;
this.nightMode = nightMode; this.nightMode = nightMode;
selectedIconColorRes = nightMode int selectedIconColorRes = nightMode
? R.color.active_color_primary_dark ? R.color.active_color_primary_dark
: R.color.active_color_primary_light; : R.color.active_color_primary_light;
selectedIconColor = ContextCompat.getColor(app, selectedIconColorRes);
} }
public List<Object> getItems() { public List<Object> getItems() {
@ -137,9 +140,9 @@ public class ConfigureProfileMenuAdapter extends AbstractProfileMenuAdapter<Conf
if (iconRes == 0 || iconRes == -1) { if (iconRes == 0 || iconRes == -1) {
iconRes = R.drawable.ic_action_world_globe; iconRes = R.drawable.ic_action_world_globe;
} }
selectedIconColorRes = mode.getIconColorInfo().getColor(nightMode); selectedIconColor = mode.getProfileColor(nightMode);
if (selectedItems.contains(mode)) { if (selectedItems.contains(mode)) {
holder.icon.setImageDrawable(app.getUIUtilities().getIcon(iconRes, selectedIconColorRes)); holder.icon.setImageDrawable(app.getUIUtilities().getPaintedIcon(iconRes, selectedIconColor));
} else { } else {
holder.icon.setImageDrawable(app.getUIUtilities().getIcon(iconRes, R.color.profile_icon_color_inactive)); holder.icon.setImageDrawable(app.getUIUtilities().getIcon(iconRes, R.color.profile_icon_color_inactive));
} }

View file

@ -14,6 +14,7 @@ import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
@ -241,7 +242,7 @@ public class EditProfilesFragment extends BaseOsmAndFragment {
order = mode.getOrder(); order = mode.getOrder();
} }
profiles.add(new EditProfileDataObject(modeKey, mode.toHumanString(), ProfileDataUtils.getAppModeDescription(getContext(), mode), profiles.add(new EditProfileDataObject(modeKey, mode.toHumanString(), ProfileDataUtils.getAppModeDescription(getContext(), mode),
mode.getIconRes(), false, mode.isCustomProfile(), deleted, mode.getIconColorInfo(), order)); mode.getIconRes(), false, mode.isCustomProfile(), deleted, mode.getProfileColor(false), mode.getProfileColor(true), order));
} }
} }
Collections.sort(profiles, new Comparator<EditProfileDataObject>() { Collections.sort(profiles, new Comparator<EditProfileDataObject>() {
@ -274,8 +275,9 @@ public class EditProfilesFragment extends BaseOsmAndFragment {
private boolean deleted; private boolean deleted;
private boolean customProfile; private boolean customProfile;
EditProfileDataObject(String stringKey, String name, String descr, int iconRes, boolean isSelected, boolean customProfile, boolean deleted, ProfileIconColors iconColor, int order) { EditProfileDataObject(String stringKey, String name, String descr, int iconRes, boolean isSelected,
super(name, descr, stringKey, iconRes, isSelected, iconColor); boolean customProfile, boolean deleted, @ColorInt int iconColorLight, @ColorInt int iconColorDark, int order) {
super(name, descr, stringKey, iconRes, isSelected, iconColorLight, iconColorDark);
this.customProfile = customProfile; this.customProfile = customProfile;
this.deleted = deleted; this.deleted = deleted;
this.order = order; this.order = order;
@ -365,10 +367,9 @@ public class EditProfilesFragment extends BaseOsmAndFragment {
if (iconRes == 0 || iconRes == -1) { if (iconRes == 0 || iconRes == -1) {
iconRes = R.drawable.ic_action_world_globe; iconRes = R.drawable.ic_action_world_globe;
} }
int profileColorResId = mode.getIconColor(nightMode); int colorNoAlpha = mode.getIconColor(nightMode);
int colorNoAlpha = ContextCompat.getColor(app, profileColorResId);
profileViewHolder.icon.setImageDrawable(uiUtilities.getIcon(iconRes, profileColorResId)); profileViewHolder.icon.setImageDrawable(uiUtilities.getPaintedIcon(iconRes, colorNoAlpha));
//set up cell color //set up cell color
Drawable drawable = UiUtilities.getColoredSelectableDrawable(app, colorNoAlpha, 0.3f); Drawable drawable = UiUtilities.getColoredSelectableDrawable(app, colorNoAlpha, 0.3f);

View file

@ -12,7 +12,7 @@ public class OnlineRoutingEngineDataObject extends ProfileDataObject {
String description, String description,
String stringKey, String stringKey,
int order) { int order) {
super(name, description, stringKey, R.drawable.ic_world_globe_dark, false, null); super(name, description, stringKey, R.drawable.ic_world_globe_dark, false, null, null);
this.order = order; this.order = order;
} }

View file

@ -1,5 +1,6 @@
package net.osmand.plus.profiles; package net.osmand.plus.profiles;
import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes; import androidx.annotation.ColorRes;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -12,15 +13,20 @@ public class ProfileDataObject implements Comparable<ProfileDataObject> {
private String stringKey; private String stringKey;
private boolean isSelected; private boolean isSelected;
private boolean isEnabled; private boolean isEnabled;
private ProfileIconColors iconColor; @ColorInt
private Integer iconColorLight;
@ColorInt
private Integer iconColorDark;
public ProfileDataObject(String name, String description, String stringKey, int iconRes, boolean isSelected, ProfileIconColors iconColor) { public ProfileDataObject(String name, String description, String stringKey, int iconRes, boolean isSelected,
@ColorInt Integer iconColorLight, @ColorInt Integer iconColorDark) {
this.name = name; this.name = name;
this.iconRes = iconRes; this.iconRes = iconRes;
this.description = description; this.description = description;
this.isSelected = isSelected; this.isSelected = isSelected;
this.stringKey = stringKey; this.stringKey = stringKey;
this.iconColor = iconColor; this.iconColorLight = iconColorLight;
this.iconColorDark = iconColorDark;
} }
public String getName() { public String getName() {
@ -55,8 +61,9 @@ public class ProfileDataObject implements Comparable<ProfileDataObject> {
return stringKey; return stringKey;
} }
@ColorRes public int getIconColor(boolean isNightMode) { @ColorInt
return iconColor.getColor(isNightMode); public int getIconColor(boolean isNightMode) {
return isNightMode ? iconColorDark : iconColorLight;
} }
@Override @Override

View file

@ -33,7 +33,7 @@ public class ProfileDataUtils {
description = getAppModeDescription(app, mode); description = getAppModeDescription(app, mode);
} }
profiles.add(new ProfileDataObject(mode.toHumanString(), description, profiles.add(new ProfileDataObject(mode.toHumanString(), description,
mode.getStringKey(), mode.getIconRes(), false, mode.getIconColorInfo())); mode.getStringKey(), mode.getIconRes(), false, mode.getProfileColor(false), mode.getProfileColor(true)));
} }
return profiles; return profiles;
} }

View file

@ -31,6 +31,7 @@ public enum ProfileIconColors {
return name; return name;
} }
@ColorRes
public int getColor(boolean nightMode) { public int getColor(boolean nightMode) {
return nightMode ? nightColor : dayColor; return nightMode ? nightColor : dayColor;
} }

View file

@ -11,7 +11,7 @@ public class RoutingProfileDataObject extends ProfileDataObject {
private String fileName; private String fileName;
public RoutingProfileDataObject(String stringKey, String name, String descr, int iconRes, boolean isSelected, String fileName) { public RoutingProfileDataObject(String stringKey, String name, String descr, int iconRes, boolean isSelected, String fileName) {
super(name, descr, stringKey, iconRes, isSelected, null); super(name, descr, stringKey, iconRes, isSelected, null, null);
this.fileName = fileName; this.fileName = fileName;
} }

View file

@ -67,10 +67,9 @@ public class SelectCopyProfilesMenuAdapter extends AbstractProfileMenuAdapter<Se
if (iconRes == 0 || iconRes == -1) { if (iconRes == 0 || iconRes == -1) {
iconRes = R.drawable.ic_action_world_globe; iconRes = R.drawable.ic_action_world_globe;
} }
int iconColor = appMode.getIconColorInfo().getColor(nightMode); int colorNoAlpha = appMode.getProfileColor(nightMode);
holder.icon.setImageDrawable(app.getUIUtilities().getIcon(iconRes, iconColor));
int colorNoAlpha = ContextCompat.getColor(app, iconColor); holder.icon.setImageDrawable(app.getUIUtilities().getPaintedIcon(iconRes, colorNoAlpha));
Drawable drawable = UiUtilities.getColoredSelectableDrawable(app, colorNoAlpha, 0.3f); Drawable drawable = UiUtilities.getColoredSelectableDrawable(app, colorNoAlpha, 0.3f);
if (selected) { if (selected) {

View file

@ -77,11 +77,12 @@ public class SelectMultipleProfilesBottomSheet extends BasePreferenceBottomSheet
View itemView = UiUtilities.getInflater(app, nightMode) View itemView = UiUtilities.getInflater(app, nightMode)
.inflate(R.layout.bottom_sheet_item_with_descr_and_checkbox_56dp, null); .inflate(R.layout.bottom_sheet_item_with_descr_and_checkbox_56dp, null);
int profileColorId = profile.getIconColor(nightMode); int profileColor = profile.getIconColor(nightMode);
int activeColorId = nightMode ? int activeColorId = nightMode ?
R.color.active_color_primary_dark : R.color.active_color_primary_light; R.color.active_color_primary_dark : R.color.active_color_primary_light;
int disableColorId = nightMode ? int disableColorId = nightMode ?
R.color.icon_color_default_dark : R.color.icon_color_default_light; R.color.icon_color_default_dark : R.color.icon_color_default_light;
int disableColor = ContextCompat.getColor(app, disableColorId);
boolean enable = profile.isEnabled(); boolean enable = profile.isEnabled();
TextView tvTitle = itemView.findViewById(R.id.title); TextView tvTitle = itemView.findViewById(R.id.title);
@ -97,8 +98,8 @@ public class SelectMultipleProfilesBottomSheet extends BasePreferenceBottomSheet
tvDescription.setTextColor(ContextCompat.getColor(app, disableColorId)); tvDescription.setTextColor(ContextCompat.getColor(app, disableColorId));
} }
Drawable drawableIcon = app.getUIUtilities().getIcon( Drawable drawableIcon = app.getUIUtilities().getPaintedIcon(
profile.getIconRes(), enable ? profileColorId : disableColorId); profile.getIconRes(), enable ? profileColor : disableColor);
ivIcon.setImageDrawable(drawableIcon); ivIcon.setImageDrawable(drawableIcon);
UiUtilities.setupCompoundButton(nightMode, ContextCompat.getColor(app, UiUtilities.setupCompoundButton(nightMode, ContextCompat.getColor(app,
enable ? activeColorId : disableColorId), compoundButton); enable ? activeColorId : disableColorId), compoundButton);

View file

@ -254,12 +254,13 @@ public class SelectProfileBottomSheet extends BasePreferenceBottomSheet {
boolean isSelected = setupSelected && Algorithms.objectEquals(profile.getStringKey(), selectedItemKey); boolean isSelected = setupSelected && Algorithms.objectEquals(profile.getStringKey(), selectedItemKey);
int iconColor; int iconColor;
if (dialogMode == DialogMode.NAVIGATION_PROFILE) { if (dialogMode == DialogMode.NAVIGATION_PROFILE) {
iconColor = isSelected ? activeColorResId : iconDefaultColorResId; int iconColorResId = isSelected ? activeColorResId : iconDefaultColorResId;
iconColor = ContextCompat.getColor(app, iconColorResId);
} else { } else {
iconColor = profile.getIconColor(nightMode); iconColor = profile.getIconColor(nightMode);
} }
Drawable drawableIcon = app.getUIUtilities().getIcon(profile.getIconRes(), iconColor); Drawable drawableIcon = app.getUIUtilities().getPaintedIcon(profile.getIconRes(), iconColor);
ivIcon.setImageDrawable(drawableIcon); ivIcon.setImageDrawable(drawableIcon);
compoundButton.setChecked(isSelected); compoundButton.setChecked(isSelected);
UiUtilities.setupCompoundButton(compoundButton, nightMode, UiUtilities.CompoundButtonType.GLOBAL); UiUtilities.setupCompoundButton(compoundButton, nightMode, UiUtilities.CompoundButtonType.GLOBAL);

View file

@ -6,19 +6,12 @@ import android.graphics.drawable.LayerDrawable;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.annotation.ColorRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.view.ContextThemeWrapper;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -26,6 +19,13 @@ import org.apache.commons.logging.Log;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.view.ContextThemeWrapper;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
public class SelectProfileMenuAdapter extends AbstractProfileMenuAdapter<SelectProfileMenuAdapter.SelectProfileViewHolder> { public class SelectProfileMenuAdapter extends AbstractProfileMenuAdapter<SelectProfileMenuAdapter.SelectProfileViewHolder> {
private static final Log LOG = PlatformUtil.getLog(SelectProfileMenuAdapter.class); private static final Log LOG = PlatformUtil.getLog(SelectProfileMenuAdapter.class);
@ -33,8 +33,8 @@ public class SelectProfileMenuAdapter extends AbstractProfileMenuAdapter<SelectP
private List<Object> items = new ArrayList<>(); private List<Object> items = new ArrayList<>();
private final OsmandApplication app; private final OsmandApplication app;
private ApplicationMode appMode; private ApplicationMode appMode;
@ColorRes @ColorInt
private int selectedIconColorRes; private int selectedIconColor;
private boolean bottomButton; private boolean bottomButton;
private String bottomButtonText; private String bottomButtonText;
private static final String BUTTON_ITEM = "button_item"; private static final String BUTTON_ITEM = "button_item";
@ -53,9 +53,8 @@ public class SelectProfileMenuAdapter extends AbstractProfileMenuAdapter<SelectP
this.bottomButton = !Algorithms.isEmpty(bottomButtonText); this.bottomButton = !Algorithms.isEmpty(bottomButtonText);
this.bottomButtonText = bottomButtonText; this.bottomButtonText = bottomButtonText;
this.nightMode = nightMode; this.nightMode = nightMode;
selectedIconColorRes = nightMode int selectedIconColorRes = nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light;
? R.color.active_color_primary_dark selectedIconColor = ContextCompat.getColor(app, selectedIconColorRes);
: R.color.active_color_primary_light;
} }
public List<Object> getItems() { public List<Object> getItems() {
@ -100,11 +99,10 @@ public class SelectProfileMenuAdapter extends AbstractProfileMenuAdapter<SelectP
holder.title.setText(item.toHumanString()); holder.title.setText(item.toHumanString());
holder.descr.setText(ProfileDataUtils.getAppModeDescription(app, item)); holder.descr.setText(ProfileDataUtils.getAppModeDescription(app, item));
int profileColorResId = item.getIconColorInfo().getColor(nightMode); int colorNoAlpha = item.getProfileColor(nightMode);
holder.icon.setImageDrawable(app.getUIUtilities().getIcon(profileColorResId, selectedIconColorRes)); holder.icon.setImageDrawable(app.getUIUtilities().getPaintedIcon(item.getIconRes(), colorNoAlpha));
//set up cell color //set up cell color
int colorNoAlpha = ContextCompat.getColor(app, profileColorResId);
boolean selectedMode = appMode == item; boolean selectedMode = appMode == item;
Drawable drawable = UiUtilities.getColoredSelectableDrawable(app, colorNoAlpha, 0.3f); Drawable drawable = UiUtilities.getColoredSelectableDrawable(app, colorNoAlpha, 0.3f);
@ -146,8 +144,8 @@ public class SelectProfileMenuAdapter extends AbstractProfileMenuAdapter<SelectP
if (iconRes == 0 || iconRes == -1) { if (iconRes == 0 || iconRes == -1) {
iconRes = R.drawable.ic_action_world_globe; iconRes = R.drawable.ic_action_world_globe;
} }
selectedIconColorRes = mode.getIconColorInfo().getColor(nightMode); selectedIconColor = mode.getProfileColor(nightMode);
holder.icon.setImageDrawable(app.getUIUtilities().getIcon(iconRes, selectedIconColorRes)); holder.icon.setImageDrawable(app.getUIUtilities().getPaintedIcon(iconRes, selectedIconColor));
} }
class SelectProfileViewHolder extends ProfileAbstractViewHolder { class SelectProfileViewHolder extends ProfileAbstractViewHolder {

View file

@ -372,8 +372,7 @@ public class QuickActionListFragment extends BaseOsmAndFragment
private void updateToolbarSwitch(final boolean isChecked) { private void updateToolbarSwitch(final boolean isChecked) {
OsmandApplication app = requireMyApplication(); OsmandApplication app = requireMyApplication();
ApplicationMode appMode = app.getSettings().getApplicationMode(); ApplicationMode appMode = app.getSettings().getApplicationMode();
int profileColor = appMode.getIconColorInfo().getColor(nightMode); int color = isChecked ? appMode.getProfileColor(nightMode) : ContextCompat.getColor(app, R.color.preference_top_switch_off);
int color = ContextCompat.getColor(app, isChecked ? profileColor : R.color.preference_top_switch_off);
AndroidUtils.setBackground(toolbarSwitchContainer, new ColorDrawable(color)); AndroidUtils.setBackground(toolbarSwitchContainer, new ColorDrawable(color));
SwitchCompat switchView = toolbarSwitchContainer.findViewById(R.id.switchWidget); SwitchCompat switchView = toolbarSwitchContainer.findViewById(R.id.switchWidget);

View file

@ -12,10 +12,12 @@ import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes; import androidx.annotation.ColorRes;
import androidx.annotation.DrawableRes; import androidx.annotation.DrawableRes;
import androidx.annotation.StringRes; import androidx.annotation.StringRes;
import androidx.appcompat.widget.SwitchCompat; import androidx.appcompat.widget.SwitchCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -161,8 +163,8 @@ public abstract class SwitchableAction<T> extends QuickAction {
OsmandApplication app = (OsmandApplication) context.getApplicationContext(); OsmandApplication app = (OsmandApplication) context.getApplicationContext();
Drawable icon = app.getUIUtilities().getIcon( Drawable icon = app.getUIUtilities().getPaintedIcon(
getItemIconRes(app, item), getItemIconColorRes(app, item)); getItemIconRes(app, item), getItemIconColor(app, item));
holder.icon.setImageDrawable(icon); holder.icon.setImageDrawable(icon);
holder.title.setText(getItemName(context, item)); holder.title.setText(getItemName(context, item));
@ -310,10 +312,11 @@ public abstract class SwitchableAction<T> extends QuickAction {
return R.drawable.ic_map; return R.drawable.ic_map;
} }
@ColorRes @ColorInt
protected int getItemIconColorRes(OsmandApplication app, T item) { protected int getItemIconColor(OsmandApplication app, T item) {
boolean nightMode = !app.getSettings().isLightContent(); boolean nightMode = !app.getSettings().isLightContent();
return nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light; int colorRes = nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light;
return ContextCompat.getColor(app, colorRes);
} }
protected abstract protected abstract

View file

@ -353,7 +353,6 @@ public class ShowHidePoiAction extends QuickAction {
builder.setIcon(R.drawable.mx_user_defined); builder.setIcon(R.drawable.mx_user_defined);
} }
builder.setColor(ContextMenuItem.INVALID_ID);
builder.setSkipPaintingWithoutColor(true); builder.setSkipPaintingWithoutColor(true);
adapter.addItem(builder.createItem()); adapter.addItem(builder.createItem());
} }

View file

@ -5,6 +5,7 @@ import android.text.TextUtils;
import android.view.View; import android.view.View;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.ColorInt;
import androidx.appcompat.widget.SwitchCompat; import androidx.appcompat.widget.SwitchCompat;
import com.google.gson.Gson; import com.google.gson.Gson;
@ -182,13 +183,14 @@ public class SwitchProfileAction extends SwitchableAction<String> {
} }
@Override @Override
protected int getItemIconColorRes(OsmandApplication app, String item) { @ColorInt
protected int getItemIconColor(OsmandApplication app, String item) {
ApplicationMode appMode = getModeForKey(item); ApplicationMode appMode = getModeForKey(item);
if (appMode != null) { if (appMode != null) {
boolean nightMode = !app.getSettings().isLightContent(); boolean nightMode = !app.getSettings().isLightContent();
return appMode.getIconColorInfo().getColor(nightMode); return appMode.getProfileColor(nightMode);
} }
return super.getItemIconColorRes(app, item); return super.getItemIconColor(app, item);
} }
@Override @Override

View file

@ -13,7 +13,6 @@ import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
@ -325,7 +324,7 @@ public class OsmandRasterMapsPlugin extends OsmandPlugin {
: mapActivity.getString(R.string.shared_string_none); : mapActivity.getString(R.string.shared_string_none);
item.setDescription(overlayMapDescr); item.setDescription(overlayMapDescr);
item.setSelected(hasOverlayDescription); item.setSelected(hasOverlayDescription);
item.setColorRes(hasOverlayDescription ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); item.setColor(app, hasOverlayDescription ? R.color.osmand_orange : ContextMenuItem.INVALID_ID);
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
} }
} }
@ -350,7 +349,7 @@ public class OsmandRasterMapsPlugin extends OsmandPlugin {
item.setDescription(underlayMapDescr); item.setDescription(underlayMapDescr);
item.setSelected(hasUnderlayDescription); item.setSelected(hasUnderlayDescription);
item.setColorRes(hasUnderlayDescription ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); item.setColor(app, hasUnderlayDescription ? R.color.osmand_orange : ContextMenuItem.INVALID_ID);
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
@ -383,7 +382,7 @@ public class OsmandRasterMapsPlugin extends OsmandPlugin {
.setId(OVERLAY_MAP) .setId(OVERLAY_MAP)
.setDescription(overlayMapDescr) .setDescription(overlayMapDescr)
.setSelected(hasOverlayDescription) .setSelected(hasOverlayDescription)
.setColor(hasOverlayDescription ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setColor(app, hasOverlayDescription ? R.color.osmand_orange : ContextMenuItem.INVALID_ID)
.setIcon(R.drawable.ic_layer_top) .setIcon(R.drawable.ic_layer_top)
.setSecondaryIcon(R.drawable.ic_action_additional_option) .setSecondaryIcon(R.drawable.ic_action_additional_option)
.setListener(listener) .setListener(listener)
@ -399,7 +398,7 @@ public class OsmandRasterMapsPlugin extends OsmandPlugin {
.setId(UNDERLAY_MAP) .setId(UNDERLAY_MAP)
.setDescription(underlayMapDescr) .setDescription(underlayMapDescr)
.setSelected(hasUnderlayDescription) .setSelected(hasUnderlayDescription)
.setColor(hasUnderlayDescription ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setColor(app, hasUnderlayDescription ? R.color.osmand_orange : ContextMenuItem.INVALID_ID)
.setIcon(R.drawable.ic_layer_bottom) .setIcon(R.drawable.ic_layer_bottom)
.setSecondaryIcon(R.drawable.ic_action_additional_option) .setSecondaryIcon(R.drawable.ic_action_additional_option)
.setListener(listener) .setListener(listener)
@ -485,7 +484,7 @@ public class OsmandRasterMapsPlugin extends OsmandPlugin {
final boolean[] selected = new boolean[downloaded.size()]; final boolean[] selected = new boolean[downloaded.size()];
boolean nightMode = isNightMode(activity); boolean nightMode = isNightMode(activity);
int themeResId = getThemeRes(activity); int themeResId = getThemeRes(activity);
int selectedProfileColor = ContextCompat.getColor(app, app.getSettings().getApplicationMode().getIconColorInfo().getColor(nightMode)); int selectedProfileColor = app.getSettings().getApplicationMode().getProfileColor(nightMode);
DialogListItemAdapter dialogAdapter = DialogListItemAdapter.createMultiChoiceAdapter(names, nightMode, selected, app, DialogListItemAdapter dialogAdapter = DialogListItemAdapter.createMultiChoiceAdapter(names, nightMode, selected, app,
selectedProfileColor, themeResId, new View.OnClickListener() { selectedProfileColor, themeResId, new View.OnClickListener() {
@Override @Override

View file

@ -11,6 +11,7 @@ import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes; import androidx.annotation.ColorRes;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -64,8 +65,8 @@ public class AvoidRoadsBottomSheetDialogFragment extends MenuBottomSheetDialogFr
private List<BottomSheetItemWithCompoundButton> compoundButtons = new ArrayList<>(); private List<BottomSheetItemWithCompoundButton> compoundButtons = new ArrayList<>();
private boolean hideImpassableRoads; private boolean hideImpassableRoads;
@ColorRes @ColorInt
private int compoundButtonColorId = INVALID_ID; private Integer compoundButtonColor = null;
private ApplicationMode appMode; private ApplicationMode appMode;
public void setHideImpassableRoads(boolean hideImpassableRoads) { public void setHideImpassableRoads(boolean hideImpassableRoads) {
@ -236,7 +237,7 @@ public class AvoidRoadsBottomSheetDialogFragment extends MenuBottomSheetDialogFr
final BottomSheetItemWithCompoundButton[] item = new BottomSheetItemWithCompoundButton[1]; final BottomSheetItemWithCompoundButton[] item = new BottomSheetItemWithCompoundButton[1];
item[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder() item[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder()
.setCompoundButtonColorId(compoundButtonColorId) .setCompoundButtonColor(compoundButtonColor)
.setChecked(selected) .setChecked(selected)
.setTitle(parameterName) .setTitle(parameterName)
.setLayoutId(R.layout.bottom_sheet_item_with_switch_no_icon) .setLayoutId(R.layout.bottom_sheet_item_with_switch_no_icon)
@ -254,8 +255,8 @@ public class AvoidRoadsBottomSheetDialogFragment extends MenuBottomSheetDialogFr
} }
} }
public void setCompoundButtonColorId(@ColorRes int compoundButtonColorId) { public void setCompoundButtonColor(@ColorInt int compoundButtonColor) {
this.compoundButtonColorId = compoundButtonColorId; this.compoundButtonColor = compoundButtonColor;
} }
@Override @Override

View file

@ -11,6 +11,7 @@ import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes; import androidx.annotation.ColorRes;
import androidx.appcompat.widget.SwitchCompat; import androidx.appcompat.widget.SwitchCompat;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
@ -84,8 +85,8 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment {
private RoutingHelper routingHelper; private RoutingHelper routingHelper;
private RoutingOptionsHelper routingOptionsHelper; private RoutingOptionsHelper routingOptionsHelper;
private ApplicationMode applicationMode; private ApplicationMode applicationMode;
@ColorRes @ColorInt
private int selectedModeColorId; private int selectedModeColor;
private boolean currentMuteState; private boolean currentMuteState;
private boolean currentUseHeightState; private boolean currentUseHeightState;
private MapActivity mapActivity; private MapActivity mapActivity;
@ -149,7 +150,7 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment {
if (dialogMode == null) { if (dialogMode == null) {
dialogMode = DialogMode.DIRECTIONS; dialogMode = DialogMode.DIRECTIONS;
} }
selectedModeColorId = applicationMode.getIconColorInfo().getColor(nightMode); selectedModeColor = applicationMode.getProfileColor(nightMode);
voiceMuteChangeListener = new StateChangedListener<Boolean>() { voiceMuteChangeListener = new StateChangedListener<Boolean>() {
@Override @Override
public void stateChanged(Boolean change) { public void stateChanged(Boolean change) {
@ -271,7 +272,6 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment {
private BaseBottomSheetItem createMuteSoundItem(final LocalRoutingParameter optionsItem) { private BaseBottomSheetItem createMuteSoundItem(final LocalRoutingParameter optionsItem) {
boolean active = !routingHelper.getVoiceRouter().isMuteForMode(applicationMode); boolean active = !routingHelper.getVoiceRouter().isMuteForMode(applicationMode);
int selectedModeColor = ContextCompat.getColor(app, selectedModeColorId);
final View itemView = UiUtilities.getInflater(app, nightMode).inflate( final View itemView = UiUtilities.getInflater(app, nightMode).inflate(
R.layout.bottom_sheet_item_with_descr_switch_and_additional_button_56dp, null, false); R.layout.bottom_sheet_item_with_descr_switch_and_additional_button_56dp, null, false);
final ImageView icon = itemView.findViewById(R.id.icon); final ImageView icon = itemView.findViewById(R.id.icon);
@ -310,7 +310,7 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment {
Drawable drawable = app.getUIUtilities().getIcon(R.drawable.ic_action_settings, Drawable drawable = app.getUIUtilities().getIcon(R.drawable.ic_action_settings,
nightMode ? R.color.route_info_control_icon_color_dark : R.color.route_info_control_icon_color_light); nightMode ? R.color.route_info_control_icon_color_dark : R.color.route_info_control_icon_color_light);
if (Build.VERSION.SDK_INT >= 21) { if (Build.VERSION.SDK_INT >= 21) {
Drawable activeDrawable = app.getUIUtilities().getIcon(R.drawable.ic_action_settings, selectedModeColorId); Drawable activeDrawable = app.getUIUtilities().getPaintedIcon(R.drawable.ic_action_settings, selectedModeColor);
drawable = AndroidUtils.createPressedStateListDrawable(drawable, activeDrawable); drawable = AndroidUtils.createPressedStateListDrawable(drawable, activeDrawable);
} }
voicePromptsBtnImage.setImageDrawable(drawable); voicePromptsBtnImage.setImageDrawable(drawable);
@ -358,7 +358,7 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment {
item[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder() item[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder()
.setChecked(!active) .setChecked(!active)
.setCompoundButtonColorId(selectedModeColorId) .setCompoundButtonColor(selectedModeColor)
.setDescription(getElevationDescription(parameter)) .setDescription(getElevationDescription(parameter))
.setIcon(getContentIcon(active ? parameter.getActiveIconId() : parameter.getDisabledIconId())) .setIcon(getContentIcon(active ? parameter.getActiveIconId() : parameter.getDisabledIconId()))
.setTitle(getString(R.string.routing_attr_height_obstacles_name)) .setTitle(getString(R.string.routing_attr_height_obstacles_name))
@ -387,7 +387,7 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment {
private BaseBottomSheetItem createTimeConditionalRoutingItem(final LocalRoutingParameter optionsItem) { private BaseBottomSheetItem createTimeConditionalRoutingItem(final LocalRoutingParameter optionsItem) {
final BottomSheetItemWithCompoundButton[] timeConditionalRoutingItem = new BottomSheetItemWithCompoundButton[1]; final BottomSheetItemWithCompoundButton[] timeConditionalRoutingItem = new BottomSheetItemWithCompoundButton[1];
timeConditionalRoutingItem[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder() timeConditionalRoutingItem[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder()
.setCompoundButtonColorId(selectedModeColorId) .setCompoundButtonColor(selectedModeColor)
.setChecked(settings.ENABLE_TIME_CONDITIONAL_ROUTING.getModeValue(applicationMode)) .setChecked(settings.ENABLE_TIME_CONDITIONAL_ROUTING.getModeValue(applicationMode))
.setIcon(getContentIcon((optionsItem.getActiveIconId()))) .setIcon(getContentIcon((optionsItem.getActiveIconId())))
.setTitle(getString(R.string.temporary_conditional_routing)) .setTitle(getString(R.string.temporary_conditional_routing))
@ -433,7 +433,7 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment {
private BaseBottomSheetItem createRouteSimulationItem(final LocalRoutingParameter optionsItem) { private BaseBottomSheetItem createRouteSimulationItem(final LocalRoutingParameter optionsItem) {
final BottomSheetItemWithCompoundButton[] simulateNavigationItem = new BottomSheetItemWithCompoundButton[1]; final BottomSheetItemWithCompoundButton[] simulateNavigationItem = new BottomSheetItemWithCompoundButton[1];
simulateNavigationItem[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder() simulateNavigationItem[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder()
.setCompoundButtonColorId(selectedModeColorId) .setCompoundButtonColor(selectedModeColor)
.setChecked(settings.simulateNavigation) .setChecked(settings.simulateNavigation)
.setIcon(getContentIcon(R.drawable.ic_action_start_navigation)) .setIcon(getContentIcon(R.drawable.ic_action_start_navigation))
.setTitle(getString(R.string.simulate_navigation)) .setTitle(getString(R.string.simulate_navigation))
@ -470,7 +470,7 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment {
routingOptionsHelper.addNewRouteMenuParameter(applicationMode, optionsItem); routingOptionsHelper.addNewRouteMenuParameter(applicationMode, optionsItem);
AvoidRoadsBottomSheetDialogFragment avoidRoadsFragment = new AvoidRoadsBottomSheetDialogFragment(); AvoidRoadsBottomSheetDialogFragment avoidRoadsFragment = new AvoidRoadsBottomSheetDialogFragment();
avoidRoadsFragment.setTargetFragment(RouteOptionsBottomSheet.this, AvoidRoadsBottomSheetDialogFragment.REQUEST_CODE); avoidRoadsFragment.setTargetFragment(RouteOptionsBottomSheet.this, AvoidRoadsBottomSheetDialogFragment.REQUEST_CODE);
avoidRoadsFragment.setCompoundButtonColorId(selectedModeColorId); avoidRoadsFragment.setCompoundButtonColor(selectedModeColor);
avoidRoadsFragment.setApplicationMode(applicationMode); avoidRoadsFragment.setApplicationMode(applicationMode);
avoidRoadsFragment.show(mapActivity.getSupportFragmentManager(), AvoidRoadsBottomSheetDialogFragment.TAG); avoidRoadsFragment.show(mapActivity.getSupportFragmentManager(), AvoidRoadsBottomSheetDialogFragment.TAG);
updateMenu(); updateMenu();
@ -492,7 +492,7 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment {
AvoidRoadsBottomSheetDialogFragment avoidRoadsFragment = new AvoidRoadsBottomSheetDialogFragment(); AvoidRoadsBottomSheetDialogFragment avoidRoadsFragment = new AvoidRoadsBottomSheetDialogFragment();
avoidRoadsFragment.setHideImpassableRoads(true); avoidRoadsFragment.setHideImpassableRoads(true);
avoidRoadsFragment.setTargetFragment(RouteOptionsBottomSheet.this, AvoidRoadsBottomSheetDialogFragment.REQUEST_CODE); avoidRoadsFragment.setTargetFragment(RouteOptionsBottomSheet.this, AvoidRoadsBottomSheetDialogFragment.REQUEST_CODE);
avoidRoadsFragment.setCompoundButtonColorId(selectedModeColorId); avoidRoadsFragment.setCompoundButtonColor(selectedModeColor);
avoidRoadsFragment.show(mapActivity.getSupportFragmentManager(), AvoidRoadsBottomSheetDialogFragment.TAG); avoidRoadsFragment.show(mapActivity.getSupportFragmentManager(), AvoidRoadsBottomSheetDialogFragment.TAG);
updateMenu(); updateMenu();
} }
@ -565,7 +565,7 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment {
if (parameter != null) { if (parameter != null) {
final BottomSheetItemWithCompoundButton[] item = new BottomSheetItemWithCompoundButton[1]; final BottomSheetItemWithCompoundButton[] item = new BottomSheetItemWithCompoundButton[1];
BottomSheetItemWithCompoundButton.Builder builder = new BottomSheetItemWithCompoundButton.Builder(); BottomSheetItemWithCompoundButton.Builder builder = new BottomSheetItemWithCompoundButton.Builder();
builder.setCompoundButtonColorId(selectedModeColorId); builder.setCompoundButtonColor(selectedModeColor);
int iconId = -1; int iconId = -1;
if (parameter.routingParameter != null || parameter instanceof RoutingOptionsHelper.OtherLocalRoutingParameter) { if (parameter.routingParameter != null || parameter instanceof RoutingOptionsHelper.OtherLocalRoutingParameter) {
builder.setTitle(parameter.getText(mapActivity)); builder.setTitle(parameter.getText(mapActivity));

View file

@ -153,7 +153,7 @@ public class RoutingOptionsHelper {
Context themedContext = UiUtilities.getThemedContext(mapActivity, nightMode); Context themedContext = UiUtilities.getThemedContext(mapActivity, nightMode);
int themeRes = getThemeRes(app); int themeRes = getThemeRes(app);
ApplicationMode selectedAppMode = app.getRoutingHelper().getAppMode(); ApplicationMode selectedAppMode = app.getRoutingHelper().getAppMode();
int selectedModeColor = ContextCompat.getColor(app, selectedAppMode.getIconColorInfo().getColor(nightMode)); int selectedModeColor = selectedAppMode.getProfileColor(nightMode);
DialogListItemAdapter dialogAdapter = DialogListItemAdapter.createSingleChoiceAdapter( DialogListItemAdapter dialogAdapter = DialogListItemAdapter.createSingleChoiceAdapter(
entries, nightMode, selected, app, selectedModeColor, themeRes, new View.OnClickListener() { entries, nightMode, selected, app, selectedModeColor, themeRes, new View.OnClickListener() {
@Override @Override
@ -334,7 +334,7 @@ public class RoutingOptionsHelper {
final boolean nightMode = isNightMode(app); final boolean nightMode = isNightMode(app);
Context themedContext = UiUtilities.getThemedContext(mapActivity, nightMode); Context themedContext = UiUtilities.getThemedContext(mapActivity, nightMode);
ApplicationMode selectedAppMode = app.getRoutingHelper().getAppMode(); ApplicationMode selectedAppMode = app.getRoutingHelper().getAppMode();
final int selectedModeColor = ContextCompat.getColor(app, selectedAppMode.getIconColorInfo().getColor(nightMode)); final int selectedModeColor = selectedAppMode.getProfileColor(nightMode);
AlertDialog.Builder builder = new AlertDialog.Builder(themedContext); AlertDialog.Builder builder = new AlertDialog.Builder(themedContext);
final int layout = R.layout.list_menu_item_native_singlechoice; final int layout = R.layout.list_menu_item_native_singlechoice;

View file

@ -356,7 +356,7 @@ public class ShowAlongTheRouteBottomSheet extends MenuBottomSheetDialogFragment
} }
} }
}); });
int selectedProfileColor = ContextCompat.getColor(app, getAppMode().getIconColorInfo().getColor(isNightMode(app))); int selectedProfileColor = getAppMode().getProfileColor(isNightMode(app));
UiUtilities.setupCompoundButton(nightMode, selectedProfileColor, compoundButton); UiUtilities.setupCompoundButton(nightMode, selectedProfileColor, compoundButton);
convertView.setOnClickListener(new View.OnClickListener() { convertView.setOnClickListener(new View.OnClickListener() {
@ -516,7 +516,7 @@ public class ShowAlongTheRouteBottomSheet extends MenuBottomSheetDialogFragment
selected = i; selected = i;
} }
} }
int selectedProfileColor = ContextCompat.getColor(app, getAppMode().getIconColorInfo().getColor(nightMode)); int selectedProfileColor = getAppMode().getProfileColor(nightMode);
DialogListItemAdapter dialogAdapter = DialogListItemAdapter.createSingleChoiceAdapter( DialogListItemAdapter dialogAdapter = DialogListItemAdapter.createSingleChoiceAdapter(
names, nightMode, selected, app, selectedProfileColor, themeRes, new View.OnClickListener() { names, nightMode, selected, app, selectedProfileColor, themeRes, new View.OnClickListener() {
@Override @Override

View file

@ -1228,16 +1228,28 @@ public class RouteProvider {
} }
private RouteCalculationResult findOnlineRoute(RouteCalculationParams params) throws IOException, JSONException { private RouteCalculationResult findOnlineRoute(RouteCalculationParams params) throws IOException, JSONException {
OnlineRoutingHelper helper = params.ctx.getOnlineRoutingHelper(); OsmandApplication app = params.ctx;
String stringKey = params.mode.getRoutingProfile(); OnlineRoutingHelper helper = app.getOnlineRoutingHelper();
OsmandSettings settings = app.getSettings();
String engineKey = params.mode.getRoutingProfile();
OnlineRoutingResponse response = OnlineRoutingResponse response =
helper.calculateRouteOnline(stringKey, getPathFromParams(params), params.leftSide); helper.calculateRouteOnline(engineKey, getPathFromParams(params), params.leftSide);
if (response != null) { if (response != null) {
params.intermediates = null; if (response.getGpxFile() != null) {
return new RouteCalculationResult(response.getRoute(), response.getDirections(), params, null, false); GPXRouteParamsBuilder builder = new GPXRouteParamsBuilder(response.getGpxFile(), settings);
} else { params.gpxRoute = builder.build(app);
return new RouteCalculationResult("Route is empty"); return calculateGpxRoute(params);
} }
List<Location> route = response.getRoute();
List<RouteDirectionInfo> directions = response.getDirections();
if (!Algorithms.isEmpty(route) && !Algorithms.isEmpty(directions)) {
params.intermediates = null;
return new RouteCalculationResult(route, directions, params, null, false);
}
}
return new RouteCalculationResult("Route is empty");
} }
private static List<LatLon> getPathFromParams(RouteCalculationParams params) { private static List<LatLon> getPathFromParams(RouteCalculationParams params) {

View file

@ -1,6 +1,8 @@
package net.osmand.plus.settings.backend; package net.osmand.plus.settings.backend;
import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes; import androidx.annotation.DrawableRes;
import androidx.core.content.ContextCompat;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
@ -469,6 +471,15 @@ public class ApplicationMode {
return app.getSettings().LOCATION_ICON.getModeValue(this); return app.getSettings().LOCATION_ICON.getModeValue(this);
} }
@ColorInt
public int getProfileColor(boolean nightMode) {
Integer customProfileColor = getCustomIconColor();
if (customProfileColor != null) {
return customProfileColor;
}
return ContextCompat.getColor(app, getIconColorInfo().getColor(nightMode));
}
public void setLocationIcon(LocationIcon locationIcon) { public void setLocationIcon(LocationIcon locationIcon) {
if (locationIcon != null) { if (locationIcon != null) {
app.getSettings().LOCATION_ICON.setModeValue(this, locationIcon); app.getSettings().LOCATION_ICON.setModeValue(this, locationIcon);
@ -485,6 +496,28 @@ public class ApplicationMode {
} }
} }
public List<String> getCustomIconColors() {
return app.getSettings().CUSTOM_ICON_COLORS.getStringsListForProfile(this);
}
public void setCustomIconColors(List<String> customColors) {
app.getSettings().CUSTOM_ICON_COLORS.setModeValues(this, customColors);
}
public Integer getCustomIconColor() {
try {
String customColor = app.getSettings().CUSTOM_ICON_COLOR.getModeValue(this);
return Algorithms.isEmpty(customColor) ? null : Algorithms.parseColor(customColor);
} catch (IllegalArgumentException e) {
return null;
}
}
public void setCustomIconColor(Integer customIconColor) {
String valueToSave = customIconColor == null ? null : Algorithms.colorToString(customIconColor);
app.getSettings().CUSTOM_ICON_COLOR.setModeValue(this, valueToSave);
}
public int getOrder() { public int getOrder() {
return app.getSettings().APP_MODE_ORDER.getModeValue(this); return app.getSettings().APP_MODE_ORDER.getModeValue(this);
} }
@ -582,6 +615,7 @@ public class ApplicationMode {
mode.setRoutingProfile(builder.routingProfile); mode.setRoutingProfile(builder.routingProfile);
mode.setRouteService(builder.routeService); mode.setRouteService(builder.routeService);
mode.setIconColor(builder.iconColor); mode.setIconColor(builder.iconColor);
mode.setCustomIconColor(builder.customIconColor);
mode.setLocationIcon(builder.locationIcon); mode.setLocationIcon(builder.locationIcon);
mode.setNavigationIcon(builder.navigationIcon); mode.setNavigationIcon(builder.navigationIcon);
mode.setOrder(builder.order); mode.setOrder(builder.order);
@ -604,6 +638,7 @@ public class ApplicationMode {
builder.setUserProfileName(modeBean.userProfileName); builder.setUserProfileName(modeBean.userProfileName);
builder.setIconResName(modeBean.iconName); builder.setIconResName(modeBean.iconName);
builder.setIconColor(modeBean.iconColor); builder.setIconColor(modeBean.iconColor);
builder.setCustomIconColor(modeBean.customIconColor);
builder.setRoutingProfile(modeBean.routingProfile); builder.setRoutingProfile(modeBean.routingProfile);
builder.setRouteService(modeBean.routeService); builder.setRouteService(modeBean.routeService);
builder.setLocationIcon(modeBean.locIcon); builder.setLocationIcon(modeBean.locIcon);
@ -623,6 +658,7 @@ public class ApplicationMode {
mb.stringKey = stringKey; mb.stringKey = stringKey;
mb.userProfileName = getUserProfileName(); mb.userProfileName = getUserProfileName();
mb.iconColor = getIconColorInfo(); mb.iconColor = getIconColorInfo();
mb.customIconColor = getCustomIconColor();
mb.iconName = getIconName(); mb.iconName = getIconName();
mb.parent = parentAppMode != null ? parentAppMode.getStringKey() : null; mb.parent = parentAppMode != null ? parentAppMode.getStringKey() : null;
mb.routeService = getRouteService(); mb.routeService = getRouteService();
@ -699,6 +735,7 @@ public class ApplicationMode {
private String routingProfile; private String routingProfile;
private String iconResName; private String iconResName;
private ProfileIconColors iconColor; private ProfileIconColors iconColor;
private Integer customIconColor;
private LocationIcon locationIcon; private LocationIcon locationIcon;
private NavigationIcon navigationIcon; private NavigationIcon navigationIcon;
private int order = -1; private int order = -1;
@ -722,6 +759,7 @@ public class ApplicationMode {
applicationMode.setRouteService(routeService); applicationMode.setRouteService(routeService);
applicationMode.setRoutingProfile(routingProfile); applicationMode.setRoutingProfile(routingProfile);
applicationMode.setIconResName(iconResName); applicationMode.setIconResName(iconResName);
applicationMode.setCustomIconColor(customIconColor);
applicationMode.setIconColor(iconColor); applicationMode.setIconColor(iconColor);
applicationMode.setLocationIcon(locationIcon); applicationMode.setLocationIcon(locationIcon);
applicationMode.setNavigationIcon(navigationIcon); applicationMode.setNavigationIcon(navigationIcon);
@ -770,6 +808,11 @@ public class ApplicationMode {
return this; return this;
} }
public ApplicationModeBuilder setCustomIconColor(Integer customIconColor) {
this.customIconColor = customIconColor;
return this;
}
public ApplicationModeBuilder setOrder(int order) { public ApplicationModeBuilder setOrder(int order) {
this.order = order; this.order = order;
return this; return this;
@ -798,6 +841,8 @@ public class ApplicationMode {
@Expose @Expose
public ProfileIconColors iconColor = ProfileIconColors.DEFAULT; public ProfileIconColors iconColor = ProfileIconColors.DEFAULT;
@Expose @Expose
public Integer customIconColor = null;
@Expose
public String routingProfile = null; public String routingProfile = null;
@Expose @Expose
public RouteService routeService = RouteService.OSMAND; public RouteService routeService = RouteService.OSMAND;

View file

@ -983,6 +983,10 @@ public class OsmandSettings {
public final CommonPreference<ProfileIconColors> ICON_COLOR = new EnumStringPreference<>(this, public final CommonPreference<ProfileIconColors> ICON_COLOR = new EnumStringPreference<>(this,
"app_mode_icon_color", ProfileIconColors.DEFAULT, ProfileIconColors.values()).makeProfile().cache(); "app_mode_icon_color", ProfileIconColors.DEFAULT, ProfileIconColors.values()).makeProfile().cache();
public final ListStringPreference CUSTOM_ICON_COLORS = (ListStringPreference) new ListStringPreference(this, "custom_icon_colors", null, ",").makeProfile().cache();
public final CommonPreference<String> CUSTOM_ICON_COLOR = new StringPreference(this, "custom_icon_color", null).makeProfile().cache();
public final CommonPreference<String> USER_PROFILE_NAME = new StringPreference(this, "user_profile_name", "").makeProfile().cache(); public final CommonPreference<String> USER_PROFILE_NAME = new StringPreference(this, "user_profile_name", "").makeProfile().cache();
public final CommonPreference<String> PARENT_APP_MODE = new StringPreference(this, "parent_app_mode", null).makeProfile().cache(); public final CommonPreference<String> PARENT_APP_MODE = new StringPreference(this, "parent_app_mode", null).makeProfile().cache();

View file

@ -301,6 +301,7 @@ public class ProfileSettingsItem extends OsmandSettingsItem {
OsmandSettings settings = app.getSettings(); OsmandSettings settings = app.getSettings();
return new String[] { return new String[] {
settings.ICON_COLOR.getId(), settings.ICON_COLOR.getId(),
settings.CUSTOM_ICON_COLOR.getId(),
settings.ICON_RES_NAME.getId(), settings.ICON_RES_NAME.getId(),
settings.PARENT_APP_MODE.getId(), settings.PARENT_APP_MODE.getId(),
settings.ROUTING_PROFILE.getId(), settings.ROUTING_PROFILE.getId(),

View file

@ -171,7 +171,7 @@ public class AnnouncementTimeBottomSheet extends BasePreferenceBottomSheet
} }
private void setProfileColorToSeekBar() { private void setProfileColorToSeekBar() {
int color = ContextCompat.getColor(app, getAppMode().getIconColorInfo().getColor(nightMode)); int color = getAppMode().getProfileColor(nightMode);
LayerDrawable seekBarProgressLayer = LayerDrawable seekBarProgressLayer =
(LayerDrawable) ContextCompat.getDrawable(app, R.drawable.seekbar_progress_announcement_time); (LayerDrawable) ContextCompat.getDrawable(app, R.drawable.seekbar_progress_announcement_time);

View file

@ -66,7 +66,7 @@ public class BooleanPreferenceBottomSheet extends BasePreferenceBottomSheet {
? getString(R.string.shared_string_disabled) : summaryOff.toString(); ? getString(R.string.shared_string_disabled) : summaryOff.toString();
final int activeColor = AndroidUtils.resolveAttribute(themedCtx, R.attr.active_color_basic); final int activeColor = AndroidUtils.resolveAttribute(themedCtx, R.attr.active_color_basic);
final int disabledColor = AndroidUtils.resolveAttribute(themedCtx, android.R.attr.textColorSecondary); final int disabledColor = AndroidUtils.resolveAttribute(themedCtx, android.R.attr.textColorSecondary);
boolean checked = pref.getModeValue(getAppMode()); boolean checked = switchPreference.isChecked();
final BottomSheetItemWithCompoundButton[] preferenceBtn = new BottomSheetItemWithCompoundButton[1]; final BottomSheetItemWithCompoundButton[] preferenceBtn = new BottomSheetItemWithCompoundButton[1];
preferenceBtn[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder() preferenceBtn[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder()
@ -77,7 +77,7 @@ public class BooleanPreferenceBottomSheet extends BasePreferenceBottomSheet {
.setOnClickListener(new View.OnClickListener() { .setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
boolean newValue = !pref.getModeValue(getAppMode()); boolean newValue = !switchPreference.isChecked();
Fragment targetFragment = getTargetFragment(); Fragment targetFragment = getTargetFragment();
if (targetFragment instanceof OnConfirmPreferenceChange) { if (targetFragment instanceof OnConfirmPreferenceChange) {
ApplyQueryType applyQueryType = getApplyQueryType(); ApplyQueryType applyQueryType = getApplyQueryType();
@ -103,7 +103,7 @@ public class BooleanPreferenceBottomSheet extends BasePreferenceBottomSheet {
}) })
.create(); .create();
if (isProfileDependent()) { if (isProfileDependent()) {
preferenceBtn[0].setCompoundButtonColorId(getAppMode().getIconColorInfo().getColor(nightMode)); preferenceBtn[0].setCompoundButtonColor(getAppMode().getProfileColor(nightMode));
} }
items.add(preferenceBtn[0]); items.add(preferenceBtn[0]);
@ -133,8 +133,7 @@ public class BooleanPreferenceBottomSheet extends BasePreferenceBottomSheet {
Context themedCtx = UiUtilities.getThemedContext(app, nightMode); Context themedCtx = UiUtilities.getThemedContext(app, nightMode);
View buttonView = customView.findViewById(R.id.button_container); View buttonView = customView.findViewById(R.id.button_container);
int colorRes = mode.getIconColorInfo().getColor(nightMode); int color = checked ? mode.getProfileColor(nightMode) : AndroidUtils.getColorFromAttr(themedCtx, R.attr.divider_color_basic);
int color = checked ? ContextCompat.getColor(themedCtx, colorRes) : AndroidUtils.getColorFromAttr(themedCtx, R.attr.divider_color_basic);
int bgColor = UiUtilities.getColorWithAlpha(color, checked ? 0.1f : 0.5f); int bgColor = UiUtilities.getColorWithAlpha(color, checked ? 0.1f : 0.5f);
int selectedColor = UiUtilities.getColorWithAlpha(color, checked ? 0.3f : 0.5f); int selectedColor = UiUtilities.getColorWithAlpha(color, checked ? 0.3f : 0.5f);

View file

@ -5,6 +5,7 @@ import android.os.Bundle;
import android.view.View; import android.view.View;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
@ -65,6 +66,7 @@ public class ElevationDateBottomSheet extends MenuBottomSheetDialogFragment {
private int checkedColor; private int checkedColor;
private int uncheckedColor; private int uncheckedColor;
private int disabledColor; private int disabledColor;
@ColorInt
private int appModeColor; private int appModeColor;
@Override @Override
@ -101,7 +103,7 @@ public class ElevationDateBottomSheet extends MenuBottomSheetDialogFragment {
on = getString(R.string.shared_string_enabled); on = getString(R.string.shared_string_enabled);
off = getString(R.string.shared_string_disabled); off = getString(R.string.shared_string_disabled);
appModeColor = appMode.getIconColorInfo().getColor(nightMode); appModeColor = appMode.getProfileColor(nightMode);
activeColor = AndroidUtils.resolveAttribute(themedCtx, R.attr.active_color_basic); activeColor = AndroidUtils.resolveAttribute(themedCtx, R.attr.active_color_basic);
disabledColor = AndroidUtils.resolveAttribute(themedCtx, android.R.attr.textColorSecondary); disabledColor = AndroidUtils.resolveAttribute(themedCtx, android.R.attr.textColorSecondary);
checkedColor = (nightMode ? app.getResources().getColor(R.color.text_color_primary_dark) : app.getResources().getColor(R.color.text_color_primary_light)); checkedColor = (nightMode ? app.getResources().getColor(R.color.text_color_primary_dark) : app.getResources().getColor(R.color.text_color_primary_light));
@ -122,7 +124,7 @@ public class ElevationDateBottomSheet extends MenuBottomSheetDialogFragment {
private void createUseHeightButton(Context context) { private void createUseHeightButton(Context context) {
boolean checked = useHeightPref.getModeValue(appMode); boolean checked = useHeightPref.getModeValue(appMode);
useHeightButton = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder() useHeightButton = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder()
.setCompoundButtonColorId(appModeColor) .setCompoundButtonColor(appModeColor)
.setChecked(checked) .setChecked(checked)
.setTitle(checked ? on : off) .setTitle(checked ? on : off)
.setTitleColorId(checked ? activeColor : disabledColor) .setTitleColorId(checked ? activeColor : disabledColor)

View file

@ -89,7 +89,7 @@ public class MultiSelectPreferencesBottomSheet extends BasePreferenceBottomSheet
.setTag(prefId) .setTag(prefId)
.create(); .create();
if (isProfileDependent()) { if (isProfileDependent()) {
item[0].setCompoundButtonColorId(getAppMode().getIconColorInfo().getColor(nightMode)); item[0].setCompoundButtonColor(getAppMode().getProfileColor(nightMode));
} }
items.add(item[0]); items.add(item[0]);
} }

View file

@ -84,8 +84,7 @@ public class RecalculateRouteInDeviationBottomSheet extends BooleanPreferenceBot
entryValues = new Float[]{9.1f, 18.3f, 30.5f, 45.7f, 91.5f, 183.0f, 482.0f, 965.0f, 1609.0f}; entryValues = new Float[]{9.1f, 18.3f, 30.5f, 45.7f, 91.5f, 183.0f, 482.0f, 965.0f, 1609.0f};
} }
final int appModeColorId = appMode.getIconColorInfo().getColor(nightMode); final int appModeColor = appMode.getProfileColor(nightMode);
final int appModeColor = ContextCompat.getColor(themedCtx, appModeColorId);
final int activeColor = AndroidUtils.resolveAttribute(themedCtx, R.attr.active_color_basic); final int activeColor = AndroidUtils.resolveAttribute(themedCtx, R.attr.active_color_basic);
final int disabledColor = AndroidUtils.resolveAttribute(themedCtx, android.R.attr.textColorSecondary); final int disabledColor = AndroidUtils.resolveAttribute(themedCtx, android.R.attr.textColorSecondary);
@ -108,7 +107,7 @@ public class RecalculateRouteInDeviationBottomSheet extends BooleanPreferenceBot
final BottomSheetItemWithCompoundButton[] preferenceBtn = new BottomSheetItemWithCompoundButton[1]; final BottomSheetItemWithCompoundButton[] preferenceBtn = new BottomSheetItemWithCompoundButton[1];
preferenceBtn[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder() preferenceBtn[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder()
.setChecked(enabled) .setChecked(enabled)
.setCompoundButtonColorId(appModeColorId) .setCompoundButtonColor(appModeColor)
.setTitle(enabled ? on : off) .setTitle(enabled ? on : off)
.setTitleColorId(enabled ? activeColor : disabledColor) .setTitleColorId(enabled ? activeColor : disabledColor)
.setCustomView(getCustomButtonView(app, getAppMode(), enabled, nightMode)) .setCustomView(getCustomButtonView(app, getAppMode(), enabled, nightMode))

View file

@ -38,18 +38,17 @@ public class ResetProfilePrefsBottomSheet extends BasePreferenceBottomSheet {
String title = getString(customProfile ? R.string.restore_all_profile_settings : R.string.reset_all_profile_settings); String title = getString(customProfile ? R.string.restore_all_profile_settings : R.string.reset_all_profile_settings);
items.add(new TitleItem(title)); items.add(new TitleItem(title));
int profileColor = mode.getIconColorInfo().getColor(nightMode); int colorNoAlpha = mode.getProfileColor(nightMode);
int colorNoAlpha = ContextCompat.getColor(ctx, profileColor);
Drawable backgroundIcon = UiUtilities.getColoredSelectableDrawable(ctx, colorNoAlpha, 0.3f); Drawable backgroundIcon = UiUtilities.getColoredSelectableDrawable(ctx, colorNoAlpha, 0.3f);
Drawable[] layers = {new ColorDrawable(UiUtilities.getColorWithAlpha(colorNoAlpha, 0.10f)), backgroundIcon}; Drawable[] layers = {new ColorDrawable(UiUtilities.getColorWithAlpha(colorNoAlpha, 0.10f)), backgroundIcon};
BaseBottomSheetItem profileItem = new BottomSheetItemWithCompoundButton.Builder() BaseBottomSheetItem profileItem = new BottomSheetItemWithCompoundButton.Builder()
.setChecked(true) .setChecked(true)
.setCompoundButtonColorId(profileColor) .setCompoundButtonColor(colorNoAlpha)
.setButtonTintList(ColorStateList.valueOf(getResolvedColor(profileColor))) .setButtonTintList(ColorStateList.valueOf(colorNoAlpha))
.setDescription(ProfileDataUtils.getAppModeDescription(ctx, mode)) .setDescription(ProfileDataUtils.getAppModeDescription(ctx, mode))
.setIcon(getIcon(mode.getIconRes(), profileColor)) .setIcon(getPaintedIcon(mode.getIconRes(), colorNoAlpha))
.setTitle(mode.toHumanString()) .setTitle(mode.toHumanString())
.setBackground(new LayerDrawable(layers)) .setBackground(new LayerDrawable(layers))
.setLayoutId(R.layout.preference_profile_item_with_radio_btn) .setLayoutId(R.layout.preference_profile_item_with_radio_btn)

View file

@ -6,6 +6,7 @@ import android.view.View;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
@ -69,8 +70,11 @@ public class SingleSelectPreferenceBottomSheet extends BasePreferenceBottomSheet
final BaseBottomSheetItem[] preferenceItem = new BottomSheetItemWithCompoundButton[1]; final BaseBottomSheetItem[] preferenceItem = new BottomSheetItemWithCompoundButton[1];
preferenceItem[0] = new BottomSheetItemWithCompoundButton.Builder() preferenceItem[0] = new BottomSheetItemWithCompoundButton.Builder()
.setChecked(i == selectedEntryIndex) .setChecked(i == selectedEntryIndex)
.setButtonTintList(AndroidUtils.createCheckedColorStateList(ctx, R.color.icon_color_default_light, .setButtonTintList(AndroidUtils.createCheckedColorIntStateList(
isProfileDependent() ? getAppMode().getIconColorInfo().getColor(nightMode) : getActiveColorId())) ContextCompat.getColor(ctx,R.color.icon_color_default_light),
isProfileDependent() ?
getAppMode().getProfileColor(nightMode) :
ContextCompat.getColor(ctx, getActiveColorId())))
.setTitle(entries[i]) .setTitle(entries[i])
.setTag(i) .setTag(i)
.setLayoutId(R.layout.bottom_sheet_item_with_radio_btn_left) .setLayoutId(R.layout.bottom_sheet_item_with_radio_btn_left)

View file

@ -118,8 +118,7 @@ public class WakeTimeBottomSheet extends BasePreferenceBottomSheet {
} }
}); });
int appModeColorId = getAppMode().getIconColorInfo().getColor(nightMode); int appModeColor = getAppMode().getProfileColor(nightMode);
int appModeColor = ContextCompat.getColor(themedCtx, appModeColorId);
UiUtilities.setupSlider(slider, nightMode, appModeColor, true); UiUtilities.setupSlider(slider, nightMode, appModeColor, true);
items.add(new BaseBottomSheetItem.Builder() items.add(new BaseBottomSheetItem.Builder()

View file

@ -680,12 +680,9 @@ public abstract class BaseSettingsFragment extends PreferenceFragmentCompat impl
@ColorInt @ColorInt
protected int getActiveProfileColor() { protected int getActiveProfileColor() {
return ContextCompat.getColor(app, getActiveProfileColorRes()); return isProfileDependent() ?
} getSelectedAppMode().getProfileColor(isNightMode()) :
ContextCompat.getColor(app, nightMode ? R.color.icon_color_active_dark : R.color.icon_color_active_light);
@ColorRes
protected int getActiveProfileColorRes() {
return isProfileDependent() ? getSelectedAppMode().getIconColorInfo().getColor(isNightMode()) : R.color.icon_color_active_light;
} }
@ColorRes @ColorRes
@ -801,7 +798,7 @@ public abstract class BaseSettingsFragment extends PreferenceFragmentCompat impl
protected Drawable getActiveIcon(@DrawableRes int id) { protected Drawable getActiveIcon(@DrawableRes int id) {
UiUtilities cache = getIconsCache(); UiUtilities cache = getIconsCache();
return cache != null ? cache.getIcon(id, getActiveProfileColorRes()) : null; return cache != null ? cache.getPaintedIcon(id, getActiveProfileColor()) : null;
} }
protected Drawable getIcon(@DrawableRes int id, @ColorRes int colorId) { protected Drawable getIcon(@DrawableRes int id, @ColorRes int colorId) {
@ -829,7 +826,8 @@ public abstract class BaseSettingsFragment extends PreferenceFragmentCompat impl
Drawable icon = AndroidUtils.createEnabledStateListDrawable(disabled, enabled); Drawable icon = AndroidUtils.createEnabledStateListDrawable(disabled, enabled);
if (Build.VERSION.SDK_INT < 21) { if (Build.VERSION.SDK_INT < 21) {
ColorStateList colorStateList = AndroidUtils.createEnabledColorStateList(app, R.color.icon_color_default_light, getActiveProfileColorRes()); int defaultColor = ContextCompat.getColor(app, nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light);
ColorStateList colorStateList = AndroidUtils.createEnabledColorIntStateList(defaultColor, getActiveProfileColor());
icon = DrawableCompat.wrap(icon); icon = DrawableCompat.wrap(icon);
DrawableCompat.setTintList(icon, colorStateList); DrawableCompat.setTintList(icon, colorStateList);
return icon; return icon;

View file

@ -6,9 +6,6 @@ import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.IndexConstants; import net.osmand.IndexConstants;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
@ -33,12 +30,16 @@ import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.ApplicationMode.ApplicationModeBean; import net.osmand.plus.settings.backend.ApplicationMode.ApplicationModeBean;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import static net.osmand.plus.settings.backend.backup.FileSettingsItem.FileSubtype; import static net.osmand.plus.settings.backend.backup.FileSettingsItem.FileSubtype;
public class DuplicatesSettingsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { public class DuplicatesSettingsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
@ -121,7 +122,10 @@ public class DuplicatesSettingsAdapter extends RecyclerView.Adapter<RecyclerView
} }
int profileIconRes = AndroidUtils.getDrawableId(app, modeBean.iconName); int profileIconRes = AndroidUtils.getDrawableId(app, modeBean.iconName);
ProfileIconColors iconColor = modeBean.iconColor; ProfileIconColors iconColor = modeBean.iconColor;
itemHolder.icon.setImageDrawable(uiUtilities.getIcon(profileIconRes, iconColor.getColor(nightMode))); Integer customIconColor = modeBean.customIconColor;
int actualIconColor = customIconColor != null ?
customIconColor : ContextCompat.getColor(app, iconColor.getColor(nightMode));
itemHolder.icon.setImageDrawable(uiUtilities.getPaintedIcon(profileIconRes, actualIconColor));
} else if (currentItem instanceof QuickAction) { } else if (currentItem instanceof QuickAction) {
QuickAction action = (QuickAction) currentItem; QuickAction action = (QuickAction) currentItem;
itemHolder.title.setText(action.getName(app)); itemHolder.title.setText(action.getName(app));

Some files were not shown because too many files have changed in this diff Show more