Merge branch 'master' into gpx_context_menu_description
# Conflicts: # OsmAnd/res/menu/track_menu_bottom_navigation.xml # OsmAnd/res/values/strings.xml # OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java
This commit is contained in:
commit
a8406fda7d
37 changed files with 1401 additions and 295 deletions
|
@ -2,6 +2,7 @@ package net.osmand.aidlapi;
|
||||||
|
|
||||||
import net.osmand.aidlapi.map.ALatLon;
|
import net.osmand.aidlapi.map.ALatLon;
|
||||||
import net.osmand.aidlapi.map.SetMapLocationParams;
|
import net.osmand.aidlapi.map.SetMapLocationParams;
|
||||||
|
import net.osmand.aidlapi.map.SetLocationParams;
|
||||||
|
|
||||||
import net.osmand.aidlapi.favorite.group.AFavoriteGroup;
|
import net.osmand.aidlapi.favorite.group.AFavoriteGroup;
|
||||||
import net.osmand.aidlapi.favorite.group.AddFavoriteGroupParams;
|
import net.osmand.aidlapi.favorite.group.AddFavoriteGroupParams;
|
||||||
|
@ -901,4 +902,6 @@ interface IOsmAndAidlInterface {
|
||||||
boolean addRoadBlock(in AddBlockedRoadParams params);
|
boolean addRoadBlock(in AddBlockedRoadParams params);
|
||||||
|
|
||||||
boolean removeRoadBlock(in RemoveBlockedRoadParams params);
|
boolean removeRoadBlock(in RemoveBlockedRoadParams params);
|
||||||
|
|
||||||
|
boolean setLocation(in SetLocationParams params);
|
||||||
}
|
}
|
3
OsmAnd-api/src/net/osmand/aidlapi/map/ALocation.aidl
Normal file
3
OsmAnd-api/src/net/osmand/aidlapi/map/ALocation.aidl
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
package net.osmand.aidlapi.map;
|
||||||
|
|
||||||
|
parcelable ALocation;
|
208
OsmAnd-api/src/net/osmand/aidlapi/map/ALocation.java
Normal file
208
OsmAnd-api/src/net/osmand/aidlapi/map/ALocation.java
Normal file
|
@ -0,0 +1,208 @@
|
||||||
|
package net.osmand.aidlapi.map;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
import net.osmand.aidlapi.AidlParams;
|
||||||
|
|
||||||
|
public class ALocation extends AidlParams {
|
||||||
|
|
||||||
|
private double latitude = 0.0;
|
||||||
|
private double longitude = 0.0;
|
||||||
|
private long time = 0;
|
||||||
|
private boolean hasAltitude = false;
|
||||||
|
private double altitude = 0.0f;
|
||||||
|
private boolean hasSpeed = false;
|
||||||
|
private float speed = 0.0f;
|
||||||
|
private boolean hasBearing = false;
|
||||||
|
private float bearing = 0.0f;
|
||||||
|
private boolean hasAccuracy = false;
|
||||||
|
private float accuracy = 0.0f;
|
||||||
|
private boolean hasVerticalAccuracy = false;
|
||||||
|
private float verticalAccuracy = 0.0f;
|
||||||
|
|
||||||
|
private ALocation() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ALocation(Parcel in) {
|
||||||
|
readFromParcel(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Parcelable.Creator<ALocation> CREATOR = new Parcelable.Creator<ALocation>() {
|
||||||
|
@Override
|
||||||
|
public ALocation createFromParcel(Parcel in) {
|
||||||
|
return new ALocation(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ALocation[] newArray(int size) {
|
||||||
|
return new ALocation[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public double getLatitude() {
|
||||||
|
return latitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getLongitude() {
|
||||||
|
return longitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTime() {
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasAltitude() {
|
||||||
|
return hasAltitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getAltitude() {
|
||||||
|
return altitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasSpeed() {
|
||||||
|
return hasSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getSpeed() {
|
||||||
|
return speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasBearing() {
|
||||||
|
return hasBearing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getBearing() {
|
||||||
|
return bearing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasAccuracy() {
|
||||||
|
return hasAccuracy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getAccuracy() {
|
||||||
|
return accuracy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasVerticalAccuracy() {
|
||||||
|
return hasVerticalAccuracy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getVerticalAccuracy() {
|
||||||
|
return verticalAccuracy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void writeToBundle(Bundle bundle) {
|
||||||
|
bundle.putDouble("latitude", latitude);
|
||||||
|
bundle.putDouble("longitude", longitude);
|
||||||
|
bundle.putLong("time", time);
|
||||||
|
bundle.putBoolean("hasAltitude", hasAltitude);
|
||||||
|
bundle.putDouble("altitude", altitude);
|
||||||
|
bundle.putBoolean("hasSpeed", hasSpeed);
|
||||||
|
bundle.putFloat("speed", speed);
|
||||||
|
bundle.putBoolean("hasBearing", hasBearing);
|
||||||
|
bundle.putFloat("bearing", bearing);
|
||||||
|
bundle.putBoolean("hasAccuracy", hasAccuracy);
|
||||||
|
bundle.putFloat("accuracy", accuracy);
|
||||||
|
bundle.putBoolean("hasVerticalAccuracy", hasVerticalAccuracy);
|
||||||
|
bundle.putFloat("verticalAccuracy", verticalAccuracy);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void readFromBundle(Bundle bundle) {
|
||||||
|
latitude = bundle.getDouble("latitude");
|
||||||
|
longitude = bundle.getDouble("longitude");
|
||||||
|
time = bundle.getLong("time");
|
||||||
|
hasAltitude = bundle.getBoolean("hasAltitude");
|
||||||
|
altitude = bundle.getDouble("altitude");
|
||||||
|
hasSpeed = bundle.getBoolean("hasSpeed");
|
||||||
|
speed = bundle.getFloat("speed");
|
||||||
|
hasBearing = bundle.getBoolean("hasBearing");
|
||||||
|
bearing = bundle.getFloat("bearing");
|
||||||
|
hasAccuracy = bundle.getBoolean("hasAccuracy");
|
||||||
|
accuracy = bundle.getFloat("accuracy");
|
||||||
|
hasVerticalAccuracy = bundle.getBoolean("hasVerticalAccuracy");
|
||||||
|
verticalAccuracy = bundle.getFloat("verticalAccuracy");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder builder() {
|
||||||
|
return new ALocation().new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Builder {
|
||||||
|
|
||||||
|
private Builder() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setLatitude(double latitude) {
|
||||||
|
ALocation.this.latitude = latitude;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setLongitude(double longitude) {
|
||||||
|
ALocation.this.longitude = longitude;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setTime(long time) {
|
||||||
|
ALocation.this.time = time;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder hasAltitude(boolean hasAltitude) {
|
||||||
|
ALocation.this.hasAltitude = hasAltitude;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setAltitude(float altitude) {
|
||||||
|
ALocation.this.altitude = altitude;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder hasSpeed(boolean hasSpeed) {
|
||||||
|
ALocation.this.hasSpeed = hasSpeed;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setSpeed(float speed) {
|
||||||
|
ALocation.this.speed = speed;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder hasBearing(boolean hasBearing) {
|
||||||
|
ALocation.this.hasBearing = hasBearing;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setBearing(float bearing) {
|
||||||
|
ALocation.this.bearing = bearing;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder hasAccuracy(boolean hasAccuracy) {
|
||||||
|
ALocation.this.hasAccuracy = hasAccuracy;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setAccuracy(float accuracy) {
|
||||||
|
ALocation.this.accuracy = accuracy;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder hasVerticalAccuracy(boolean hasVerticalAccuracy) {
|
||||||
|
ALocation.this.hasVerticalAccuracy = hasVerticalAccuracy;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setVerticalAccuracy(float verticalAccuracy) {
|
||||||
|
ALocation.this.verticalAccuracy = verticalAccuracy;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ALocation build() {
|
||||||
|
return ALocation.this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
package net.osmand.aidlapi.map;
|
||||||
|
|
||||||
|
parcelable SetLocationParams;
|
54
OsmAnd-api/src/net/osmand/aidlapi/map/SetLocationParams.java
Normal file
54
OsmAnd-api/src/net/osmand/aidlapi/map/SetLocationParams.java
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
package net.osmand.aidlapi.map;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Parcel;
|
||||||
|
|
||||||
|
import net.osmand.aidlapi.AidlParams;
|
||||||
|
|
||||||
|
public class SetLocationParams extends AidlParams {
|
||||||
|
|
||||||
|
private ALocation location;
|
||||||
|
private long timeToNotUseOtherGPS;
|
||||||
|
|
||||||
|
public SetLocationParams(ALocation location, long timeToNotUseOtherGPS) {
|
||||||
|
this.location = location;
|
||||||
|
this.timeToNotUseOtherGPS = timeToNotUseOtherGPS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SetLocationParams(Parcel in) {
|
||||||
|
readFromParcel(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<SetLocationParams> CREATOR = new Creator<SetLocationParams>() {
|
||||||
|
@Override
|
||||||
|
public SetLocationParams createFromParcel(Parcel in) {
|
||||||
|
return new SetLocationParams(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SetLocationParams[] newArray(int size) {
|
||||||
|
return new SetLocationParams[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public ALocation getLocation() {
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTimeToNotUseOtherGPS() {
|
||||||
|
return timeToNotUseOtherGPS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToBundle(Bundle bundle) {
|
||||||
|
bundle.putParcelable("location", location);
|
||||||
|
bundle.putLong("timeToNotUseOtherGPS", timeToNotUseOtherGPS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void readFromBundle(Bundle bundle) {
|
||||||
|
bundle.setClassLoader(ALocation.class.getClassLoader());
|
||||||
|
location = bundle.getParcelable("location");
|
||||||
|
timeToNotUseOtherGPS = bundle.getLong("timeToNotUseOtherGPS");
|
||||||
|
}
|
||||||
|
}
|
|
@ -1216,7 +1216,13 @@ public class RouteResultPreparation {
|
||||||
TurnType t = TurnType.getExitTurn(exit, 0, leftSide);
|
TurnType t = TurnType.getExitTurn(exit, 0, leftSide);
|
||||||
// usually covers more than expected
|
// usually covers more than expected
|
||||||
float turnAngleBasedOnOutRoads = (float) MapUtils.degreesDiff(last.getBearingBegin(), prev.getBearingEnd());
|
float turnAngleBasedOnOutRoads = (float) MapUtils.degreesDiff(last.getBearingBegin(), prev.getBearingEnd());
|
||||||
float turnAngleBasedOnCircle = (float) -MapUtils.degreesDiff(firstRoundabout.getBearingBegin(), lastRoundabout.getBearingEnd() + 180);
|
// Angle based on circle method tries
|
||||||
|
// 1. to calculate antinormal to roundabout circle on roundabout entrance and
|
||||||
|
// 2. normal to roundabout circle on roundabout exit
|
||||||
|
// 3. calculate angle difference
|
||||||
|
// This method doesn't work if you go from S to N touching only 1 point of roundabout,
|
||||||
|
// but it is very important to identify very sharp or very large angle to understand did you pass whole roundabout or small entrance
|
||||||
|
float turnAngleBasedOnCircle = (float) MapUtils.degreesDiff(firstRoundabout.getBearingBegin(), lastRoundabout.getBearingEnd() + 180);
|
||||||
if (Math.abs(turnAngleBasedOnOutRoads) > 120) {
|
if (Math.abs(turnAngleBasedOnOutRoads) > 120) {
|
||||||
// correctly identify if angle is +- 180, so we approach from left or right side
|
// correctly identify if angle is +- 180, so we approach from left or right side
|
||||||
t.setTurnAngle(turnAngleBasedOnCircle) ;
|
t.setTurnAngle(turnAngleBasedOnCircle) ;
|
||||||
|
|
|
@ -1,19 +1,15 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<item android:id="@android:id/background">
|
<item android:id="@+id/background">
|
||||||
<shape android:shape="rectangle" >
|
<shape android:shape="rectangle">
|
||||||
<solid
|
<solid android:color="#4d007eb3" />
|
||||||
android:color="#4d007eb3" />
|
<corners android:radius="30dp" />
|
||||||
<corners android:radius="30dp" />
|
</shape>
|
||||||
</shape>
|
</item>
|
||||||
</item>
|
<item android:id="@+id/progress">
|
||||||
<item android:id="@android:id/progress">
|
<shape android:shape="rectangle">
|
||||||
<clip>
|
<solid android:color="@color/color_white" />
|
||||||
<shape android:shape="rectangle" >
|
<corners android:radius="30dp" />
|
||||||
<solid
|
</shape>
|
||||||
android:color="@color/profile_icon_color_blue_light" />
|
</item>
|
||||||
<corners android:radius="30dp" />
|
|
||||||
</shape>
|
|
||||||
</clip>
|
|
||||||
</item>
|
|
||||||
</layer-list>
|
</layer-list>
|
|
@ -1,12 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
<item>
|
<item android:id="@+id/thump">
|
||||||
<shape android:shape="oval">
|
<shape android:shape="oval">
|
||||||
<size
|
<size
|
||||||
android:height="12dp"
|
android:width="12dp"
|
||||||
android:width="12dp" />
|
android:height="12dp" />
|
||||||
<solid android:color="@color/profile_icon_color_blue_light" />
|
<solid android:color="@color/profile_icon_color_blue_light" />
|
||||||
</shape>
|
</shape>
|
||||||
</item>
|
</item>
|
||||||
</layer-list>
|
</layer-list>
|
|
@ -27,6 +27,7 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="@dimen/content_padding"
|
android:layout_marginStart="@dimen/content_padding"
|
||||||
android:layout_marginLeft="@dimen/content_padding"
|
android:layout_marginLeft="@dimen/content_padding"
|
||||||
|
android:layout_marginTop="@dimen/content_padding_half"
|
||||||
android:layout_marginEnd="@dimen/content_padding"
|
android:layout_marginEnd="@dimen/content_padding"
|
||||||
android:layout_marginRight="@dimen/content_padding"
|
android:layout_marginRight="@dimen/content_padding"
|
||||||
android:lineSpacingMultiplier="1.1"
|
android:lineSpacingMultiplier="1.1"
|
||||||
|
@ -70,8 +71,6 @@
|
||||||
android:maxHeight="2dp"
|
android:maxHeight="2dp"
|
||||||
android:paddingTop="11dp"
|
android:paddingTop="11dp"
|
||||||
android:paddingBottom="11dp"
|
android:paddingBottom="11dp"
|
||||||
android:progressDrawable="@drawable/seekbar_progress_announcement_time"
|
|
||||||
android:thumb="@drawable/seekbar_thumb_announcement_time"
|
|
||||||
osmand:tickMark="@drawable/seekbar_tickmark_announcement_time"
|
osmand:tickMark="@drawable/seekbar_tickmark_announcement_time"
|
||||||
tools:max="3"
|
tools:max="3"
|
||||||
tools:progress="1" />
|
tools:progress="1" />
|
||||||
|
|
104
OsmAnd/res/layout/gpx_overview_fragment.xml
Normal file
104
OsmAnd/res/layout/gpx_overview_fragment.xml
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recycler_overview"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="@dimen/content_padding_small_half"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
tools:itemCount="4"
|
||||||
|
tools:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
|
tools:listitem="@layout/item_gpx_stat_block" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/content_padding"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingTop="@dimen/dash_margin"
|
||||||
|
android:paddingBottom="@dimen/dash_margin">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/direction"
|
||||||
|
android:layout_width="@dimen/context_menu_transport_icon_size"
|
||||||
|
android:layout_height="@dimen/context_menu_transport_icon_size"
|
||||||
|
osmand:srcCompat="@drawable/ic_direction_arrow" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/distance"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/content_padding_small_half"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding_small_half"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textColor="?android:textColorSecondary"
|
||||||
|
android:textSize="@dimen/default_desc_text_size"
|
||||||
|
tools:text="300 km" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/content_padding"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding"
|
||||||
|
android:layout_marginTop="@dimen/content_padding_half"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding"
|
||||||
|
android:layout_marginRight="@dimen/content_padding"
|
||||||
|
android:layout_marginBottom="@dimen/content_padding"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:weightSum="4">
|
||||||
|
<!-- todo stretch buttons correctly -->
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/show_button"
|
||||||
|
layout="@layout/item_gpx_action"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:layout_width="@dimen/content_padding_half"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/appearance_button"
|
||||||
|
layout="@layout/item_gpx_action"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:layout_width="@dimen/content_padding_half"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/edit_button"
|
||||||
|
layout="@layout/item_gpx_action"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:layout_width="@dimen/content_padding_half"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/directions_button"
|
||||||
|
layout="@layout/item_gpx_action"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
21
OsmAnd/res/layout/item_gpx_action.xml
Normal file
21
OsmAnd/res/layout/item_gpx_action.xml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/filled"
|
||||||
|
android:layout_width="@dimen/fab_recycler_view_padding_bottom"
|
||||||
|
android:layout_height="@dimen/setting_list_item_small_height"
|
||||||
|
tools:alpha="0.1"
|
||||||
|
tools:srcCompat="@drawable/bg_topbar_shield_exit_ref" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/image"
|
||||||
|
android:layout_width="@dimen/standard_icon_size"
|
||||||
|
android:layout_height="@dimen/standard_icon_size"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
tools:srcCompat="@drawable/ic_action_hide" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
44
OsmAnd/res/layout/item_gpx_stat_block.xml
Normal file
44
OsmAnd/res/layout/item_gpx_stat_block.xml
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/value"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@null"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
|
android:textSize="@dimen/default_desc_text_size"
|
||||||
|
osmand:typeface="@string/font_roboto_medium"
|
||||||
|
tools:text="700 km" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/image"
|
||||||
|
android:layout_width="@dimen/context_menu_transport_icon_size"
|
||||||
|
android:layout_height="@dimen/context_menu_transport_icon_size"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginStart="@dimen/context_menu_first_line_top_margin"
|
||||||
|
android:layout_marginLeft="@dimen/context_menu_first_line_top_margin"
|
||||||
|
tools:src="@drawable/ic_action_track_16" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@null"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
|
android:textSize="@dimen/default_desc_text_size"
|
||||||
|
tools:text="@string/distance" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -1,9 +1,8 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="?attr/list_background_color"
|
android:background="?attr/list_background_color">
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:id="@+id/appbar"
|
android:id="@+id/appbar"
|
||||||
|
@ -15,21 +14,41 @@
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
<ScrollView
|
<ScrollView
|
||||||
|
android:id="@+id/segments_scroll"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1">
|
android:layout_marginBottom="@dimen/dialog_button_ex_height">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/segments_container"
|
android:id="@+id/segments_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical" />
|
android:orientation="vertical"
|
||||||
|
android:paddingTop="@dimen/dialog_button_ex_height"
|
||||||
|
android:paddingBottom="@dimen/context_menu_buttons_bottom_height" />
|
||||||
|
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
||||||
<include
|
<LinearLayout
|
||||||
layout="@layout/bottom_buttons"
|
android:id="@+id/control_buttons"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/dialog_button_ex_height" />
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
</LinearLayout>
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/buttons_shadow"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="8dp"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:background="@drawable/shadow" />
|
||||||
|
|
||||||
|
<include
|
||||||
|
layout="@layout/bottom_buttons"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/dialog_button_ex_height"
|
||||||
|
android:layout_gravity="bottom" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</FrameLayout>
|
|
@ -164,36 +164,4 @@
|
||||||
tools:visibility="visible"
|
tools:visibility="visible"
|
||||||
android:visibility="gone" />
|
android:visibility="gone" />
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/result_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/setting_list_item_group_height"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
tools:visibility="visible"
|
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:id="@+id/result_icon"
|
|
||||||
android:layout_width="@dimen/standard_icon_size"
|
|
||||||
android:layout_height="@dimen/standard_icon_size"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:layout_marginRight="@dimen/content_padding"
|
|
||||||
android:layout_marginLeft="@dimen/content_padding"
|
|
||||||
android:tint="?attr/default_icon_color"
|
|
||||||
tools:src="@drawable/ic_action_gdirections_dark" />
|
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
|
||||||
android:id="@+id/result_text"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="start|center_vertical"
|
|
||||||
android:letterSpacing="@dimen/description_letter_spacing"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
|
||||||
android:textSize="@dimen/default_list_text_size"
|
|
||||||
osmand:typeface="@string/font_roboto_regular"
|
|
||||||
tools:text="OK" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
|
@ -43,12 +43,13 @@
|
||||||
android:paddingStart="@dimen/context_menu_padding_margin_default"
|
android:paddingStart="@dimen/context_menu_padding_margin_default"
|
||||||
android:paddingLeft="@dimen/context_menu_padding_margin_default"
|
android:paddingLeft="@dimen/context_menu_padding_margin_default"
|
||||||
android:paddingEnd="@dimen/context_menu_padding_margin_default"
|
android:paddingEnd="@dimen/context_menu_padding_margin_default"
|
||||||
android:paddingRight="@dimen/context_menu_padding_margin_default">
|
android:paddingRight="@dimen/context_menu_padding_margin_default"
|
||||||
|
android:paddingBottom="@dimen/context_menu_direction_margin">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="@dimen/context_menu_first_line_top_margin"
|
android:layout_marginTop="@dimen/context_menu_second_line_top_margin"
|
||||||
android:layout_marginEnd="@dimen/context_menu_padding_margin_default"
|
android:layout_marginEnd="@dimen/context_menu_padding_margin_default"
|
||||||
android:layout_marginRight="@dimen/context_menu_padding_margin_default"
|
android:layout_marginRight="@dimen/context_menu_padding_margin_default"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
|
@ -71,7 +72,8 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
tools:text="@string/amenity_type_finance" />
|
android:visibility="gone"
|
||||||
|
tools:text="@string/amenity_type_finance" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@ -79,7 +81,7 @@
|
||||||
android:id="@+id/icon_view"
|
android:id="@+id/icon_view"
|
||||||
android:layout_width="@dimen/map_widget_icon"
|
android:layout_width="@dimen/map_widget_icon"
|
||||||
android:layout_height="@dimen/map_widget_icon"
|
android:layout_height="@dimen/map_widget_icon"
|
||||||
android:layout_marginTop="@dimen/context_menu_padding_margin_default"
|
android:layout_marginTop="@dimen/context_menu_second_line_top_margin"
|
||||||
android:tint="?attr/default_icon_color"
|
android:tint="?attr/default_icon_color"
|
||||||
osmand:srcCompat="@drawable/ic_action_polygom_dark" />
|
osmand:srcCompat="@drawable/ic_action_polygom_dark" />
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
android:id="@+id/action_track"
|
android:id="@+id/action_track"
|
||||||
android:icon="@drawable/ic_action_polygom_dark"
|
android:icon="@drawable/ic_action_polygom_dark"
|
||||||
android:title="@string/shared_string_gpx_track" />
|
android:title="@string/shared_string_gpx_track" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_points"
|
android:id="@+id/action_points"
|
||||||
android:icon="@drawable/ic_action_waypoint"
|
android:icon="@drawable/ic_action_waypoint"
|
||||||
|
|
|
@ -3675,4 +3675,7 @@
|
||||||
<string name="poi_liaison_filter">اتصال</string>
|
<string name="poi_liaison_filter">اتصال</string>
|
||||||
<string name="poi_consulate_filter">قنصلية</string>
|
<string name="poi_consulate_filter">قنصلية</string>
|
||||||
<string name="poi_embassy_filter">سفارة</string>
|
<string name="poi_embassy_filter">سفارة</string>
|
||||||
|
<string name="poi_wildlife_crossing_bat_tunnel">نفق خفافيش</string>
|
||||||
|
<string name="poi_wildlife_crossing_bat_bridge">جسر خفافيش</string>
|
||||||
|
<string name="poi_wildlife_crossing">معبر الحيوانات البرية</string>
|
||||||
</resources>
|
</resources>
|
|
@ -3989,4 +3989,15 @@
|
||||||
<string name="routing_engine_vehicle_type_cycling_road">Ŝosea biciklado</string>
|
<string name="routing_engine_vehicle_type_cycling_road">Ŝosea biciklado</string>
|
||||||
<string name="routing_engine_vehicle_type_cycling_regular">Kutima biciklado</string>
|
<string name="routing_engine_vehicle_type_cycling_regular">Kutima biciklado</string>
|
||||||
<string name="routing_engine_vehicle_type_hgv">Peza kamiono</string>
|
<string name="routing_engine_vehicle_type_hgv">Peza kamiono</string>
|
||||||
|
<string name="shared_string_sec">s</string>
|
||||||
|
<string name="announcement_time_passing">Pasado</string>
|
||||||
|
<string name="announcement_time_approach">Alproksimiĝado</string>
|
||||||
|
<string name="announcement_time_prepare_long">Longa preparado</string>
|
||||||
|
<string name="announcement_time_prepare">Preparado</string>
|
||||||
|
<string name="announcement_time_off_route">Devojiĝo de kurso</string>
|
||||||
|
<string name="announcement_time_arrive">Atingo al celo</string>
|
||||||
|
<string name="shared_string_turn">Turno</string>
|
||||||
|
<string name="announcement_time_intervals">Interspacoj distancaj kaj tempaj</string>
|
||||||
|
<string name="announcement_time_descr">Tempo de anonco de diversaj voĉaj sciigoj dependas de ilia specoj, nuna naviga kaj implicita naviga rapido.</string>
|
||||||
|
<string name="announcement_time_title">Tempo de anonco</string>
|
||||||
</resources>
|
</resources>
|
|
@ -3961,7 +3961,7 @@
|
||||||
<string name="announcement_time_prepare">Préparation</string>
|
<string name="announcement_time_prepare">Préparation</string>
|
||||||
<string name="announcement_time_prepare_long">Longue préparation</string>
|
<string name="announcement_time_prepare_long">Longue préparation</string>
|
||||||
<string name="announcement_time_arrive">Arrivé à destination</string>
|
<string name="announcement_time_arrive">Arrivé à destination</string>
|
||||||
<string name="shared_string_turn">Tourner</string>
|
<string name="shared_string_turn">Bifurcation</string>
|
||||||
<string name="show_track_on_map">Afficher la trace sur la carte</string>
|
<string name="show_track_on_map">Afficher la trace sur la carte</string>
|
||||||
<string name="routing_engine_vehicle_type_scooter">Trottinette</string>
|
<string name="routing_engine_vehicle_type_scooter">Trottinette</string>
|
||||||
<string name="routing_engine_vehicle_type_small_truck">Camionnette</string>
|
<string name="routing_engine_vehicle_type_small_truck">Camionnette</string>
|
||||||
|
@ -3979,5 +3979,15 @@
|
||||||
<string name="routing_engine_vehicle_type_mtb">VTT</string>
|
<string name="routing_engine_vehicle_type_mtb">VTT</string>
|
||||||
<string name="message_server_error">Erreur serveur : %1$s</string>
|
<string name="message_server_error">Erreur serveur : %1$s</string>
|
||||||
<string name="message_name_is_already_exists">Ce nom existe déjà</string>
|
<string name="message_name_is_already_exists">Ce nom existe déjà</string>
|
||||||
<string name="routing_engine_vehicle_type_hgv">Poids lourds</string>
|
<string name="routing_engine_vehicle_type_hgv">Poids lourd</string>
|
||||||
|
<string name="announcement_time_passing">Durée</string>
|
||||||
|
<string name="analyze_by_intervals">Analyser par intervalles (fractionner)</string>
|
||||||
|
<string name="announcement_time_intervals">Intervalles de temps et de distance</string>
|
||||||
|
<string name="announcement_time_descr">Le délai d\'annonce des alertes vocales dépend du type d\'annonce, de la vitesse actuelle et du type de navigation.</string>
|
||||||
|
<string name="announcement_time_title">Délai de l\'annonce</string>
|
||||||
|
<string name="announcement_time_off_route">Hors de l\'itinéraire prévu</string>
|
||||||
|
<string name="routing_engine_vehicle_type_cycling_road">Vélo de route</string>
|
||||||
|
<string name="routing_engine_vehicle_type_cycling_mountain">Vélo tout terrain</string>
|
||||||
|
<string name="routing_engine_vehicle_type_cycling_electric">Vélo électrique</string>
|
||||||
|
<string name="routing_engine_vehicle_type_cycling_regular">Vélo</string>
|
||||||
</resources>
|
</resources>
|
|
@ -3881,4 +3881,42 @@
|
||||||
<string name="upload_to_openstreetmap">Last opp til OpenStreetMap</string>
|
<string name="upload_to_openstreetmap">Last opp til OpenStreetMap</string>
|
||||||
<string name="rename_track">Gi spor nytt navn</string>
|
<string name="rename_track">Gi spor nytt navn</string>
|
||||||
<string name="change_folder">Endre mappe</string>
|
<string name="change_folder">Endre mappe</string>
|
||||||
|
<string name="select_data_to_export">Velg data å eksportere til filen.</string>
|
||||||
|
<string name="export_not_enough_space_descr">Din enhet har kun %1$s ledig. Frigjør litt plass eller velg bort noen elementer fra eksporten.</string>
|
||||||
|
<string name="select_groups_for_import">ffffffffff|</string>
|
||||||
|
<string name="reverse_all_points">Reverser alle punkter</string>
|
||||||
|
<string name="routing_engine_vehicle_type_small_truck">Liten lastebil</string>
|
||||||
|
<string name="routing_engine_vehicle_type_truck">Lastebil</string>
|
||||||
|
<string name="cannot_upload_image">Kan ikke laste opp bilde. Prøv igjen senere.</string>
|
||||||
|
<string name="approximate_file_size">Omtrentlig filstørrelse</string>
|
||||||
|
<string name="export_not_enough_space">Det er ikke nok plass</string>
|
||||||
|
<string name="select_items_for_import">Velg elementer å importere.</string>
|
||||||
|
<string name="add_online_routing_engine">Legg til nettbasert rutingsmotor</string>
|
||||||
|
<string name="edit_online_routing_engine">Rediger nettbasert rutingsmotor</string>
|
||||||
|
<string name="shared_string_subtype">Undertype</string>
|
||||||
|
<string name="shared_string_enter_param">Skriv inn parameter</string>
|
||||||
|
<string name="keep_it_empty_if_not">La den stå tom hvis ikke</string>
|
||||||
|
<string name="online_routing_example_hint">Nettadresse med alle parametre vil se slik ut:</string>
|
||||||
|
<string name="online_routing_engine">Nettbasert rutingsmotor</string>
|
||||||
|
<string name="online_routing_engines">Nettbaserte rutingsmotorer</string>
|
||||||
|
<string name="announcement_time_prepare_long">Lang forberedelse</string>
|
||||||
|
<string name="announcement_time_prepare">Forberedelse</string>
|
||||||
|
<string name="announcement_time_arrive">Ankom målet</string>
|
||||||
|
<string name="shared_string_turn">Sving</string>
|
||||||
|
<string name="announcement_time_intervals">Tid og avstansintervaller</string>
|
||||||
|
<string name="announcement_time_descr">kunngjøringstid for forskjellige stemmeforespørsler avhenger av forespørselstype, nåværende navigasjonshastighet og forvalgt navigasjonshastighet.</string>
|
||||||
|
<string name="routing_engine_vehicle_type_hiking">Turgåing</string>
|
||||||
|
<string name="routing_engine_vehicle_type_walking">Fotgjengeri</string>
|
||||||
|
<string name="shared_string_sec">sek</string>
|
||||||
|
<string name="announcement_time_title">Kunngjøringstid</string>
|
||||||
|
<string name="start_recording">Start opptak</string>
|
||||||
|
<string name="show_track_on_map">Vis spor på kart</string>
|
||||||
|
<string name="routing_engine_vehicle_type_wheelchair">Rullestol</string>
|
||||||
|
<string name="routing_engine_vehicle_type_cycling_electric">El-sykkel</string>
|
||||||
|
<string name="routing_engine_vehicle_type_cycling_mountain">Terrengsykkel</string>
|
||||||
|
<string name="routing_engine_vehicle_type_racingbike">Temposykkel</string>
|
||||||
|
<string name="routing_engine_vehicle_type_cycling_road">Landeveissykling</string>
|
||||||
|
<string name="routing_engine_vehicle_type_cycling_regular">Vanlig sykling</string>
|
||||||
|
<string name="message_server_error">Tjenerfeil: %1$s</string>
|
||||||
|
<string name="message_name_is_already_exists">Navnet finnes allerede</string>
|
||||||
</resources>
|
</resources>
|
|
@ -3974,9 +3974,9 @@
|
||||||
<string name="announcement_time_prepare_long">Długie przygotowanie</string>
|
<string name="announcement_time_prepare_long">Długie przygotowanie</string>
|
||||||
<string name="announcement_time_prepare">Przygotuj</string>
|
<string name="announcement_time_prepare">Przygotuj</string>
|
||||||
<string name="announcement_time_off_route">Poza trasą</string>
|
<string name="announcement_time_off_route">Poza trasą</string>
|
||||||
<string name="announcement_time_arrive">Przyjedź do miejsca docelowego</string>
|
<string name="announcement_time_arrive">Dotarłeś do miejsca docelowego</string>
|
||||||
<string name="shared_string_turn">Zakręt</string>
|
<string name="shared_string_turn">Zakręt</string>
|
||||||
<string name="announcement_time_intervals">Odstępy czasowe i odległościowe</string>
|
<string name="announcement_time_intervals">Przedziały czasu i dystansu</string>
|
||||||
<string name="announcement_time_descr">Czas ogłaszania różnych komunikatów głosowych zależy od rodzaju komunikatu, aktualnej prędkości nawigacji i domyślnej prędkości nawigacji.</string>
|
<string name="announcement_time_descr">Czas ogłaszania różnych komunikatów głosowych zależy od rodzaju komunikatu, aktualnej prędkości nawigacji i domyślnej prędkości nawigacji.</string>
|
||||||
<string name="announcement_time_title">Czas ogłoszenia</string>
|
<string name="announcement_time_title">Czas ogłoszenia</string>
|
||||||
<string name="start_recording">Rozpocznij nagrywanie</string>
|
<string name="start_recording">Rozpocznij nagrywanie</string>
|
||||||
|
@ -3996,4 +3996,6 @@
|
||||||
<string name="routing_engine_vehicle_type_mtb">MTB</string>
|
<string name="routing_engine_vehicle_type_mtb">MTB</string>
|
||||||
<string name="message_server_error">Błąd serwera: %1$s</string>
|
<string name="message_server_error">Błąd serwera: %1$s</string>
|
||||||
<string name="message_name_is_already_exists">Taka nazwa już istnieje</string>
|
<string name="message_name_is_already_exists">Taka nazwa już istnieje</string>
|
||||||
|
<string name="online_routing_engine">Silnik wyznaczania tras online</string>
|
||||||
|
<string name="online_routing_engines">Silniki wyznaczania tras online</string>
|
||||||
</resources>
|
</resources>
|
|
@ -274,6 +274,7 @@
|
||||||
<color name="gpx_chart_green_label">#197d2a</color>
|
<color name="gpx_chart_green_label">#197d2a</color>
|
||||||
|
|
||||||
<color name="gpx_split_segment_icon_color">#b3b3b3</color>
|
<color name="gpx_split_segment_icon_color">#b3b3b3</color>
|
||||||
|
<color name="gpx_pale_green">#87CC70</color>
|
||||||
|
|
||||||
<color name="map_background_color_light">#fafafa</color>
|
<color name="map_background_color_light">#fafafa</color>
|
||||||
<color name="map_background_color_dark">#101821</color>
|
<color name="map_background_color_dark">#101821</color>
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
<string name="context_menu_edit_descr">Edit description</string>
|
<string name="context_menu_edit_descr">Edit description</string>
|
||||||
<string name="context_menu_read_full">Read full</string>
|
<string name="context_menu_read_full">Read full</string>
|
||||||
|
<string name="delete_online_routing_engine">Delete this online routing engine?</string>
|
||||||
<string name="message_name_is_already_exists">The name is already exists</string>
|
<string name="message_name_is_already_exists">The name is already exists</string>
|
||||||
<string name="message_server_error">Server error: %1$s</string>
|
<string name="message_server_error">Server error: %1$s</string>
|
||||||
<string name="routing_engine_vehicle_type_mtb">MTB</string>
|
<string name="routing_engine_vehicle_type_mtb">MTB</string>
|
||||||
|
|
|
@ -89,7 +89,7 @@
|
||||||
<net.osmand.plus.settings.preferences.ListPreferenceEx
|
<net.osmand.plus.settings.preferences.ListPreferenceEx
|
||||||
android:key="arrival_distance_factor"
|
android:key="arrival_distance_factor"
|
||||||
android:layout="@layout/preference_with_descr"
|
android:layout="@layout/preference_with_descr"
|
||||||
android:title="@string/arrival_distance" />
|
android:title="@string/announcement_time_title" />
|
||||||
|
|
||||||
<Preference
|
<Preference
|
||||||
android:layout="@layout/simple_divider_item"
|
android:layout="@layout/simple_divider_item"
|
||||||
|
|
|
@ -43,6 +43,7 @@ import net.osmand.aidl.tiles.ASqliteDbFile;
|
||||||
import net.osmand.aidlapi.customization.AProfile;
|
import net.osmand.aidlapi.customization.AProfile;
|
||||||
import net.osmand.aidlapi.info.AppInfoParams;
|
import net.osmand.aidlapi.info.AppInfoParams;
|
||||||
import net.osmand.aidlapi.map.ALatLon;
|
import net.osmand.aidlapi.map.ALatLon;
|
||||||
|
import net.osmand.aidlapi.map.ALocation;
|
||||||
import net.osmand.aidlapi.navigation.ABlockedRoad;
|
import net.osmand.aidlapi.navigation.ABlockedRoad;
|
||||||
import net.osmand.data.FavouritePoint;
|
import net.osmand.data.FavouritePoint;
|
||||||
import net.osmand.data.LatLon;
|
import net.osmand.data.LatLon;
|
||||||
|
@ -167,11 +168,14 @@ public class OsmandAidlApi {
|
||||||
|
|
||||||
private static final String AIDL_REFRESH_MAP = "aidl_refresh_map";
|
private static final String AIDL_REFRESH_MAP = "aidl_refresh_map";
|
||||||
private static final String AIDL_SET_MAP_LOCATION = "aidl_set_map_location";
|
private static final String AIDL_SET_MAP_LOCATION = "aidl_set_map_location";
|
||||||
|
private static final String AIDL_SET_LOCATION = "aidl_set_location";
|
||||||
private static final String AIDL_LATITUDE = "aidl_latitude";
|
private static final String AIDL_LATITUDE = "aidl_latitude";
|
||||||
private static final String AIDL_LONGITUDE = "aidl_longitude";
|
private static final String AIDL_LONGITUDE = "aidl_longitude";
|
||||||
private static final String AIDL_ZOOM = "aidl_zoom";
|
private static final String AIDL_ZOOM = "aidl_zoom";
|
||||||
private static final String AIDL_ROTATION = "aidl_rotation";
|
private static final String AIDL_ROTATION = "aidl_rotation";
|
||||||
private static final String AIDL_ANIMATED = "aidl_animated";
|
private static final String AIDL_ANIMATED = "aidl_animated";
|
||||||
|
private static final String AIDL_LOCATION = "aidl_location";
|
||||||
|
private static final String AIDL_TIME_TO_NOT_USE_OTHER_GPS = "aidl_time_to_not_use_other_gps";
|
||||||
|
|
||||||
private static final String AIDL_START_NAME = "aidl_start_name";
|
private static final String AIDL_START_NAME = "aidl_start_name";
|
||||||
private static final String AIDL_START_LAT = "aidl_start_lat";
|
private static final String AIDL_START_LAT = "aidl_start_lat";
|
||||||
|
@ -263,6 +267,7 @@ public class OsmandAidlApi {
|
||||||
registerHideSqliteDbFileReceiver(mapActivity);
|
registerHideSqliteDbFileReceiver(mapActivity);
|
||||||
registerExecuteQuickActionReceiver(mapActivity);
|
registerExecuteQuickActionReceiver(mapActivity);
|
||||||
registerLockStateReceiver(mapActivity);
|
registerLockStateReceiver(mapActivity);
|
||||||
|
registerSetLocationReceiver(mapActivity);
|
||||||
initOsmandTelegram();
|
initOsmandTelegram();
|
||||||
app.getAppCustomization().addListener(mapActivity);
|
app.getAppCustomization().addListener(mapActivity);
|
||||||
this.mapActivity = mapActivity;
|
this.mapActivity = mapActivity;
|
||||||
|
@ -903,6 +908,42 @@ public class OsmandAidlApi {
|
||||||
registerReceiver(lockStateReceiver, mapActivity, AIDL_LOCK_STATE);
|
registerReceiver(lockStateReceiver, mapActivity, AIDL_LOCK_STATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void registerSetLocationReceiver(MapActivity mapActivity) {
|
||||||
|
BroadcastReceiver setLocationReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
String packName = intent.getStringExtra(AIDL_PACKAGE_NAME);
|
||||||
|
ALocation aLocation = intent.getParcelableExtra(AIDL_LOCATION);
|
||||||
|
long timeToNotUseOtherGPS = intent.getLongExtra(AIDL_TIME_TO_NOT_USE_OTHER_GPS, 0);
|
||||||
|
|
||||||
|
if (!Algorithms.isEmpty(packName) && aLocation != null
|
||||||
|
&& !Double.isNaN(aLocation.getLatitude()) && !Double.isNaN(aLocation.getLongitude())) {
|
||||||
|
Location location = new Location(packName);
|
||||||
|
location.setLatitude(aLocation.getLatitude());
|
||||||
|
location.setLongitude(aLocation.getLongitude());
|
||||||
|
location.setTime(aLocation.getTime());
|
||||||
|
if (aLocation.hasAltitude()) {
|
||||||
|
location.setAltitude(aLocation.getAltitude());
|
||||||
|
}
|
||||||
|
if (aLocation.hasSpeed()) {
|
||||||
|
location.setSpeed(aLocation.getSpeed());
|
||||||
|
}
|
||||||
|
if (aLocation.hasBearing()) {
|
||||||
|
location.setBearing(aLocation.getBearing());
|
||||||
|
}
|
||||||
|
if (aLocation.hasAccuracy()) {
|
||||||
|
location.setAccuracy(aLocation.getAccuracy());
|
||||||
|
}
|
||||||
|
if (aLocation.hasVerticalAccuracy()) {
|
||||||
|
location.setVerticalAccuracy(aLocation.getVerticalAccuracy());
|
||||||
|
}
|
||||||
|
app.getLocationProvider().setCustomLocation(location, timeToNotUseOtherGPS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
registerReceiver(setLocationReceiver, mapActivity, AIDL_SET_LOCATION);
|
||||||
|
}
|
||||||
|
|
||||||
public void registerMapLayers(@NonNull MapActivity mapActivity) {
|
public void registerMapLayers(@NonNull MapActivity mapActivity) {
|
||||||
for (ConnectedApp connectedApp : connectedApps.values()) {
|
for (ConnectedApp connectedApp : connectedApps.values()) {
|
||||||
connectedApp.registerMapLayers(mapActivity);
|
connectedApp.registerMapLayers(mapActivity);
|
||||||
|
@ -2405,6 +2446,16 @@ public class OsmandAidlApi {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean setLocation(String packName, ALocation location, long timeToNotUseOtherGPS) {
|
||||||
|
Intent intent = new Intent();
|
||||||
|
intent.setAction(AIDL_SET_LOCATION);
|
||||||
|
intent.putExtra(AIDL_LOCATION, location);
|
||||||
|
intent.putExtra(AIDL_PACKAGE_NAME, packName);
|
||||||
|
intent.putExtra(AIDL_TIME_TO_NOT_USE_OTHER_GPS, timeToNotUseOtherGPS);
|
||||||
|
app.sendBroadcast(intent);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private static class FileCopyInfo {
|
private static class FileCopyInfo {
|
||||||
long startTime;
|
long startTime;
|
||||||
long lastAccessTime;
|
long lastAccessTime;
|
||||||
|
|
|
@ -53,6 +53,7 @@ import net.osmand.aidlapi.gpx.StopGpxRecordingParams;
|
||||||
import net.osmand.aidlapi.info.AppInfoParams;
|
import net.osmand.aidlapi.info.AppInfoParams;
|
||||||
import net.osmand.aidlapi.lock.SetLockStateParams;
|
import net.osmand.aidlapi.lock.SetLockStateParams;
|
||||||
import net.osmand.aidlapi.map.ALatLon;
|
import net.osmand.aidlapi.map.ALatLon;
|
||||||
|
import net.osmand.aidlapi.map.SetLocationParams;
|
||||||
import net.osmand.aidlapi.map.SetMapLocationParams;
|
import net.osmand.aidlapi.map.SetMapLocationParams;
|
||||||
import net.osmand.aidlapi.maplayer.AddMapLayerParams;
|
import net.osmand.aidlapi.maplayer.AddMapLayerParams;
|
||||||
import net.osmand.aidlapi.maplayer.RemoveMapLayerParams;
|
import net.osmand.aidlapi.maplayer.RemoveMapLayerParams;
|
||||||
|
@ -1443,6 +1444,20 @@ public class OsmandAidlServiceV2 extends Service implements AidlCallbackListener
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setLocation(SetLocationParams params) {
|
||||||
|
try {
|
||||||
|
if (params != null) {
|
||||||
|
OsmandAidlApi api = getApi("setLocation");
|
||||||
|
String packName = getCallingAppPackName();
|
||||||
|
return api != null && api.setLocation(packName, params.getLocation(), params.getTimeToNotUseOtherGPS());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
handleException(e);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private void setCustomization(OsmandAidlApi api, CustomizationInfoParams params) {
|
private void setCustomization(OsmandAidlApi api, CustomizationInfoParams params) {
|
||||||
|
|
|
@ -45,6 +45,7 @@ import net.osmand.plus.routing.RoutingHelper;
|
||||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||||
import net.osmand.router.RouteSegmentResult;
|
import net.osmand.router.RouteSegmentResult;
|
||||||
|
import net.osmand.util.Algorithms;
|
||||||
import net.osmand.util.MapUtils;
|
import net.osmand.util.MapUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -93,7 +94,9 @@ public class OsmAndLocationProvider implements SensorEventListener {
|
||||||
private SimulationProvider simulatePosition = null;
|
private SimulationProvider simulatePosition = null;
|
||||||
|
|
||||||
private long cachedLocationTimeFix = 0;
|
private long cachedLocationTimeFix = 0;
|
||||||
|
private long timeToNotUseOtherGPS = 0;
|
||||||
private net.osmand.Location cachedLocation;
|
private net.osmand.Location cachedLocation;
|
||||||
|
private net.osmand.Location customLocation;
|
||||||
|
|
||||||
private boolean sensorRegistered = false;
|
private boolean sensorRegistered = false;
|
||||||
private float[] mGravs = new float[3];
|
private float[] mGravs = new float[3];
|
||||||
|
@ -726,8 +729,21 @@ public class OsmAndLocationProvider implements SensorEventListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setCustomLocation(net.osmand.Location location, long ignoreLocationsTime) {
|
||||||
|
timeToNotUseOtherGPS = System.currentTimeMillis() + ignoreLocationsTime;
|
||||||
|
customLocation = location;
|
||||||
|
setLocation(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean shouldIgnoreLocation(net.osmand.Location location) {
|
||||||
|
if (customLocation != null && timeToNotUseOtherGPS >= System.currentTimeMillis()) {
|
||||||
|
return location == null || !Algorithms.stringsEqual(customLocation.getProvider(), location.getProvider());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public void setLocationFromService(net.osmand.Location location) {
|
public void setLocationFromService(net.osmand.Location location) {
|
||||||
if (locationSimulation.isRouteAnimating()) {
|
if (locationSimulation.isRouteAnimating() || shouldIgnoreLocation(location)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (location != null) {
|
if (location != null) {
|
||||||
|
@ -746,7 +762,11 @@ public class OsmAndLocationProvider implements SensorEventListener {
|
||||||
setLocation(location);
|
setLocation(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setLocation(net.osmand.Location location) { if (location == null) {
|
private void setLocation(net.osmand.Location location) {
|
||||||
|
if (shouldIgnoreLocation(location)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (location == null) {
|
||||||
updateGPSInfo(null);
|
updateGPSInfo(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ import net.osmand.plus.UiUtilities;
|
||||||
import net.osmand.plus.helpers.AndroidUiHelper;
|
import net.osmand.plus.helpers.AndroidUiHelper;
|
||||||
import net.osmand.plus.helpers.GpxUiHelper;
|
import net.osmand.plus.helpers.GpxUiHelper;
|
||||||
import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetAxisType;
|
import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetAxisType;
|
||||||
|
import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType;
|
||||||
import net.osmand.plus.helpers.GpxUiHelper.LineGraphType;
|
import net.osmand.plus.helpers.GpxUiHelper.LineGraphType;
|
||||||
import net.osmand.plus.helpers.GpxUiHelper.OrderedLineDataSet;
|
import net.osmand.plus.helpers.GpxUiHelper.OrderedLineDataSet;
|
||||||
import net.osmand.plus.track.TrackDisplayHelper;
|
import net.osmand.plus.track.TrackDisplayHelper;
|
||||||
|
@ -687,8 +688,50 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid
|
||||||
}
|
}
|
||||||
|
|
||||||
void openAnalyzeOnMap(GPXTabItemType tabType) {
|
void openAnalyzeOnMap(GPXTabItemType tabType) {
|
||||||
List<ILineDataSet> ds = getDataSets(null, tabType, null, null);
|
List<ILineDataSet> dataSets = getDataSets(null, tabType, null, null);
|
||||||
actionsListener.openAnalyzeOnMap(gpxItem, ds, tabType);
|
prepareGpxItemChartTypes(gpxItem, dataSets);
|
||||||
|
actionsListener.openAnalyzeOnMap(gpxItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void prepareGpxItemChartTypes(GpxDisplayItem gpxItem, List<ILineDataSet> dataSets) {
|
||||||
|
WptPt wpt = null;
|
||||||
|
gpxItem.chartTypes = null;
|
||||||
|
if (dataSets != null && dataSets.size() > 0) {
|
||||||
|
gpxItem.chartTypes = new GPXDataSetType[dataSets.size()];
|
||||||
|
for (int i = 0; i < dataSets.size(); i++) {
|
||||||
|
OrderedLineDataSet orderedDataSet = (OrderedLineDataSet) dataSets.get(i);
|
||||||
|
gpxItem.chartTypes[i] = orderedDataSet.getDataSetType();
|
||||||
|
}
|
||||||
|
if (gpxItem.chartHighlightPos != -1) {
|
||||||
|
TrkSegment segment = null;
|
||||||
|
for (Track t : gpxItem.group.getGpx().tracks) {
|
||||||
|
for (TrkSegment s : t.segments) {
|
||||||
|
if (s.points.size() > 0 && s.points.get(0).equals(gpxItem.analysis.locationStart)) {
|
||||||
|
segment = s;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (segment != null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (segment != null) {
|
||||||
|
OrderedLineDataSet dataSet = (OrderedLineDataSet) dataSets.get(0);
|
||||||
|
float distance = gpxItem.chartHighlightPos * dataSet.getDivX();
|
||||||
|
for (WptPt p : segment.points) {
|
||||||
|
if (p.distance >= distance) {
|
||||||
|
wpt = p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (wpt != null) {
|
||||||
|
gpxItem.locationOnMap = wpt;
|
||||||
|
} else {
|
||||||
|
gpxItem.locationOnMap = gpxItem.locationStart;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void openSplitIntervalScreen() {
|
private void openSplitIntervalScreen() {
|
||||||
|
|
|
@ -2,13 +2,9 @@ package net.osmand.plus.myplaces;
|
||||||
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
|
|
||||||
|
|
||||||
import net.osmand.GPXUtilities.TrkSegment;
|
import net.osmand.GPXUtilities.TrkSegment;
|
||||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
|
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface SegmentActionsListener {
|
public interface SegmentActionsListener {
|
||||||
|
|
||||||
void updateContent();
|
void updateContent();
|
||||||
|
@ -23,5 +19,5 @@ public interface SegmentActionsListener {
|
||||||
|
|
||||||
void showOptionsPopupMenu(View view, TrkSegment trkSegment, boolean confirmDeletion);
|
void showOptionsPopupMenu(View view, TrkSegment trkSegment, boolean confirmDeletion);
|
||||||
|
|
||||||
void openAnalyzeOnMap(GpxDisplayItem gpxItem, List<ILineDataSet> dataSets, GPXTabItemType tabType);
|
void openAnalyzeOnMap(GpxDisplayItem gpxItem);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,16 +22,11 @@ import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
|
||||||
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
|
|
||||||
|
|
||||||
import net.osmand.AndroidUtils;
|
import net.osmand.AndroidUtils;
|
||||||
import net.osmand.FileUtils;
|
import net.osmand.FileUtils;
|
||||||
import net.osmand.FileUtils.RenameCallback;
|
import net.osmand.FileUtils.RenameCallback;
|
||||||
import net.osmand.GPXUtilities.GPXFile;
|
import net.osmand.GPXUtilities.GPXFile;
|
||||||
import net.osmand.GPXUtilities.Track;
|
|
||||||
import net.osmand.GPXUtilities.TrkSegment;
|
import net.osmand.GPXUtilities.TrkSegment;
|
||||||
import net.osmand.GPXUtilities.WptPt;
|
|
||||||
import net.osmand.data.LatLon;
|
|
||||||
import net.osmand.data.PointDescription;
|
import net.osmand.data.PointDescription;
|
||||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup;
|
import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup;
|
||||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
|
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
|
||||||
|
@ -43,8 +38,6 @@ import net.osmand.plus.activities.MapActivity;
|
||||||
import net.osmand.plus.activities.TrackActivity;
|
import net.osmand.plus.activities.TrackActivity;
|
||||||
import net.osmand.plus.base.OsmAndListFragment;
|
import net.osmand.plus.base.OsmAndListFragment;
|
||||||
import net.osmand.plus.helpers.GpxUiHelper;
|
import net.osmand.plus.helpers.GpxUiHelper;
|
||||||
import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType;
|
|
||||||
import net.osmand.plus.helpers.GpxUiHelper.OrderedLineDataSet;
|
|
||||||
import net.osmand.plus.myplaces.TrackBitmapDrawer.TrackBitmapDrawerListener;
|
import net.osmand.plus.myplaces.TrackBitmapDrawer.TrackBitmapDrawerListener;
|
||||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||||
import net.osmand.plus.track.SaveGpxAsyncTask;
|
import net.osmand.plus.track.SaveGpxAsyncTask;
|
||||||
|
@ -299,55 +292,9 @@ public class TrackSegmentFragment extends OsmAndListFragment implements TrackBit
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void openAnalyzeOnMap(GpxDisplayItem gpxItem, List<ILineDataSet> dataSets, GPXTabItemType tabType) {
|
public void openAnalyzeOnMap(GpxDisplayItem gpxItem) {
|
||||||
LatLon location = null;
|
|
||||||
WptPt wpt = null;
|
|
||||||
gpxItem.chartTypes = null;
|
|
||||||
if (dataSets != null && dataSets.size() > 0) {
|
|
||||||
gpxItem.chartTypes = new GPXDataSetType[dataSets.size()];
|
|
||||||
for (int i = 0; i < dataSets.size(); i++) {
|
|
||||||
OrderedLineDataSet orderedDataSet = (OrderedLineDataSet) dataSets.get(i);
|
|
||||||
gpxItem.chartTypes[i] = orderedDataSet.getDataSetType();
|
|
||||||
}
|
|
||||||
if (gpxItem.chartHighlightPos != -1) {
|
|
||||||
TrkSegment segment = null;
|
|
||||||
for (Track t : gpxItem.group.getGpx().tracks) {
|
|
||||||
for (TrkSegment s : t.segments) {
|
|
||||||
if (s.points.size() > 0 && s.points.get(0).equals(gpxItem.analysis.locationStart)) {
|
|
||||||
segment = s;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (segment != null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (segment != null) {
|
|
||||||
OrderedLineDataSet dataSet = (OrderedLineDataSet) dataSets.get(0);
|
|
||||||
float distance = gpxItem.chartHighlightPos * dataSet.getDivX();
|
|
||||||
for (WptPt p : segment.points) {
|
|
||||||
if (p.distance >= distance) {
|
|
||||||
wpt = p;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (wpt != null) {
|
|
||||||
location = new LatLon(wpt.lat, wpt.lon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (location == null) {
|
|
||||||
location = new LatLon(gpxItem.locationStart.lat, gpxItem.locationStart.lon);
|
|
||||||
}
|
|
||||||
if (wpt != null) {
|
|
||||||
gpxItem.locationOnMap = wpt;
|
|
||||||
} else {
|
|
||||||
gpxItem.locationOnMap = gpxItem.locationStart;
|
|
||||||
}
|
|
||||||
|
|
||||||
OsmandSettings settings = app.getSettings();
|
OsmandSettings settings = app.getSettings();
|
||||||
settings.setMapLocationToShow(location.getLatitude(), location.getLongitude(),
|
settings.setMapLocationToShow(gpxItem.locationOnMap.lat, gpxItem.locationOnMap.lon,
|
||||||
settings.getLastKnownMapZoom(),
|
settings.getLastKnownMapZoom(),
|
||||||
new PointDescription(PointDescription.POINT_TYPE_WPT, gpxItem.name),
|
new PointDescription(PointDescription.POINT_TYPE_WPT, gpxItem.name),
|
||||||
false,
|
false,
|
||||||
|
|
|
@ -25,8 +25,6 @@ import net.osmand.plus.helpers.AndroidUiHelper;
|
||||||
import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter;
|
import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter;
|
||||||
import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionAdapterListener;
|
import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionAdapterListener;
|
||||||
import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionItem;
|
import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionItem;
|
||||||
import net.osmand.plus.onlinerouting.VehicleType;
|
|
||||||
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
|
|
||||||
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;
|
||||||
import net.osmand.plus.widgets.OsmandTextFieldBoxes;
|
import net.osmand.plus.widgets.OsmandTextFieldBoxes;
|
||||||
|
@ -123,8 +121,8 @@ public class OnlineRoutingCard extends BaseCard {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSelectionMenu(@NonNull List<HorizontalSelectionItem> items,
|
public void setSelectionMenu(@NonNull List<HorizontalSelectionItem> items,
|
||||||
@NonNull String selectedItemTitle,
|
@NonNull String selectedItemTitle,
|
||||||
@NonNull final CallbackWithObject<HorizontalSelectionItem> callback) {
|
@NonNull final CallbackWithObject<HorizontalSelectionItem> callback) {
|
||||||
showElements(rvSelectionMenu);
|
showElements(rvSelectionMenu);
|
||||||
rvSelectionMenu.setLayoutManager(
|
rvSelectionMenu.setLayoutManager(
|
||||||
new LinearLayoutManager(app, RecyclerView.HORIZONTAL, false));
|
new LinearLayoutManager(app, RecyclerView.HORIZONTAL, false));
|
||||||
|
@ -137,23 +135,15 @@ public class OnlineRoutingCard extends BaseCard {
|
||||||
if (callback.processResult(item)) {
|
if (callback.processResult(item)) {
|
||||||
adapter.setSelectedItem(item);
|
adapter.setSelectedItem(item);
|
||||||
}
|
}
|
||||||
Object obj = item.getObject();
|
|
||||||
updateBottomMarginSelectionMenu(obj);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Object item = adapter.getItemByTitle(selectedItemTitle).getObject();
|
|
||||||
updateBottomMarginSelectionMenu(item);
|
|
||||||
rvSelectionMenu.setAdapter(adapter);
|
rvSelectionMenu.setAdapter(adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateBottomMarginSelectionMenu(Object item) {
|
private void updateBottomMarginSelectionMenu() {
|
||||||
if (item instanceof VehicleType) {
|
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) rvSelectionMenu.getLayoutParams();
|
||||||
VehicleType vt = (VehicleType) item;
|
int contentPadding = app.getResources().getDimensionPixelSize(R.dimen.content_padding);
|
||||||
boolean hasPadding = vt.equals(OnlineRoutingEngine.CUSTOM_VEHICLE);
|
params.bottomMargin = isVisibleViewsBelowSelectionMenu() ? contentPadding : 0;
|
||||||
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) rvSelectionMenu.getLayoutParams();
|
|
||||||
int contentPadding = app.getResources().getDimensionPixelSize(R.dimen.content_padding);
|
|
||||||
params.bottomMargin = hasPadding ? contentPadding : 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDescription(@NonNull String description) {
|
public void setDescription(@NonNull String description) {
|
||||||
|
@ -166,6 +156,10 @@ public class OnlineRoutingCard extends BaseCard {
|
||||||
textFieldBoxes.setLabelText(labelText);
|
textFieldBoxes.setLabelText(labelText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void hideFieldBoxLabel() {
|
||||||
|
textFieldBoxes.makeCompactPadding();
|
||||||
|
}
|
||||||
|
|
||||||
public void setFieldBoxHelperText(@NonNull String helperText) {
|
public void setFieldBoxHelperText(@NonNull String helperText) {
|
||||||
showElements(fieldBoxContainer, tvHelperText);
|
showElements(fieldBoxContainer, tvHelperText);
|
||||||
fieldBoxHelperTextShowed = true;
|
fieldBoxHelperTextShowed = true;
|
||||||
|
@ -202,7 +196,7 @@ public class OnlineRoutingCard extends BaseCard {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setButton(@NonNull String title,
|
public void setButton(@NonNull String title,
|
||||||
@NonNull OnClickListener listener) {
|
@NonNull OnClickListener listener) {
|
||||||
showElements(button);
|
showElements(button);
|
||||||
button.setOnClickListener(listener);
|
button.setOnClickListener(listener);
|
||||||
UiUtilities.setupDialogButton(nightMode, button, DialogButtonType.PRIMARY, title);
|
UiUtilities.setupDialogButton(nightMode, button, DialogButtonType.PRIMARY, title);
|
||||||
|
@ -226,10 +220,20 @@ public class OnlineRoutingCard extends BaseCard {
|
||||||
|
|
||||||
private void showElements(View... views) {
|
private void showElements(View... views) {
|
||||||
AndroidUiHelper.setVisibility(View.VISIBLE, views);
|
AndroidUiHelper.setVisibility(View.VISIBLE, views);
|
||||||
|
updateBottomMarginSelectionMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void hideElements(View... views) {
|
private void hideElements(View... views) {
|
||||||
AndroidUiHelper.setVisibility(View.GONE, views);
|
AndroidUiHelper.setVisibility(View.GONE, views);
|
||||||
|
updateBottomMarginSelectionMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isVisibleViewsBelowSelectionMenu() {
|
||||||
|
return isVisible(tvDescription) || isVisible(fieldBoxContainer) || isVisible(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isVisible(View view) {
|
||||||
|
return view.getVisibility() == View.VISIBLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnTextChangedListener(@Nullable OnTextChangedListener onTextChangedListener) {
|
public void setOnTextChangedListener(@Nullable OnTextChangedListener onTextChangedListener) {
|
||||||
|
|
|
@ -12,8 +12,8 @@ import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.ViewTreeObserver;
|
|
||||||
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
|
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
|
||||||
|
import android.view.ViewTreeObserver.OnScrollChangedListener;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.ScrollView;
|
import android.widget.ScrollView;
|
||||||
|
@ -23,6 +23,7 @@ import androidx.activity.OnBackPressedCallback;
|
||||||
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.appcompat.widget.AppCompatImageView;
|
||||||
import androidx.appcompat.widget.Toolbar;
|
import androidx.appcompat.widget.Toolbar;
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
@ -42,9 +43,9 @@ 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.ui.OnlineRoutingCard.OnTextChangedListener;
|
|
||||||
import net.osmand.plus.onlinerouting.engine.EngineType;
|
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.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;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
@ -82,7 +83,9 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
||||||
private View testResultsContainer;
|
private View testResultsContainer;
|
||||||
private View saveButton;
|
private View saveButton;
|
||||||
private ScrollView scrollView;
|
private ScrollView scrollView;
|
||||||
|
private AppCompatImageView buttonsShadow;
|
||||||
private OnGlobalLayoutListener onGlobalLayout;
|
private OnGlobalLayoutListener onGlobalLayout;
|
||||||
|
private OnScrollChangedListener onScroll;
|
||||||
private boolean isKeyboardShown = false;
|
private boolean isKeyboardShown = false;
|
||||||
|
|
||||||
private OnlineRoutingEngine engine;
|
private OnlineRoutingEngine engine;
|
||||||
|
@ -112,7 +115,6 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||||
|
@ -121,7 +123,8 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
||||||
view = getInflater().inflate(
|
view = getInflater().inflate(
|
||||||
R.layout.online_routing_engine_fragment, container, false);
|
R.layout.online_routing_engine_fragment, container, false);
|
||||||
segmentsContainer = (ViewGroup) view.findViewById(R.id.segments_container);
|
segmentsContainer = (ViewGroup) view.findViewById(R.id.segments_container);
|
||||||
scrollView = (ScrollView) segmentsContainer.getParent();
|
scrollView = (ScrollView) view.findViewById(R.id.segments_scroll);
|
||||||
|
buttonsShadow = (AppCompatImageView) view.findViewById(R.id.buttons_shadow);
|
||||||
if (Build.VERSION.SDK_INT >= 21) {
|
if (Build.VERSION.SDK_INT >= 21) {
|
||||||
AndroidUtils.addStatusBarPadding21v(getContext(), view);
|
AndroidUtils.addStatusBarPadding21v(getContext(), view);
|
||||||
}
|
}
|
||||||
|
@ -138,67 +141,9 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
||||||
generateUniqueNameIfNeeded();
|
generateUniqueNameIfNeeded();
|
||||||
updateCardViews(nameCard, typeCard, vehicleCard, exampleCard);
|
updateCardViews(nameCard, typeCard, vehicleCard, exampleCard);
|
||||||
|
|
||||||
scrollView.setOnTouchListener(new View.OnTouchListener() {
|
showShadowBelowButtons();
|
||||||
int scrollViewY = 0;
|
showButtonsAboveKeyboard();
|
||||||
|
hideKeyboardOnScroll();
|
||||||
@Override
|
|
||||||
public boolean onTouch(View v, MotionEvent event) {
|
|
||||||
int y = scrollView.getScrollY();
|
|
||||||
if (isKeyboardShown && scrollViewY != y) {
|
|
||||||
scrollViewY = y;
|
|
||||||
View focus = mapActivity.getCurrentFocus();
|
|
||||||
if (focus != null) {
|
|
||||||
AndroidUtils.hideSoftKeyboard(mapActivity, focus);
|
|
||||||
focus.clearFocus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
onGlobalLayout = new ViewTreeObserver.OnGlobalLayoutListener() {
|
|
||||||
private int layoutHeightPrevious;
|
|
||||||
private int layoutHeightMin;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onGlobalLayout() {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
|
||||||
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
|
||||||
} else {
|
|
||||||
view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
Rect visibleDisplayFrame = new Rect();
|
|
||||||
view.getWindowVisibleDisplayFrame(visibleDisplayFrame);
|
|
||||||
int layoutHeight = visibleDisplayFrame.bottom;
|
|
||||||
|
|
||||||
if (layoutHeight < layoutHeightPrevious) {
|
|
||||||
isKeyboardShown = true;
|
|
||||||
layoutHeightMin = layoutHeight;
|
|
||||||
} else {
|
|
||||||
isKeyboardShown = layoutHeight == layoutHeightMin;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (layoutHeight != layoutHeightPrevious) {
|
|
||||||
FrameLayout.LayoutParams rootViewLayout = (FrameLayout.LayoutParams) view.getLayoutParams();
|
|
||||||
rootViewLayout.height = layoutHeight;
|
|
||||||
view.requestLayout();
|
|
||||||
layoutHeightPrevious = layoutHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
view.post(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
view.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayout);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
|
||||||
view.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayout);
|
|
||||||
}
|
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
@ -223,8 +168,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
||||||
actionBtn.setOnClickListener(new OnClickListener() {
|
actionBtn.setOnClickListener(new OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
onDeleteEngine();
|
delete(mapActivity);
|
||||||
dismiss();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -359,6 +303,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
||||||
exampleCard = new OnlineRoutingCard(mapActivity, isNightMode(), appMode);
|
exampleCard = new OnlineRoutingCard(mapActivity, isNightMode(), appMode);
|
||||||
exampleCard.build(mapActivity);
|
exampleCard.build(mapActivity);
|
||||||
exampleCard.setHeaderTitle(getString(R.string.shared_string_example));
|
exampleCard.setHeaderTitle(getString(R.string.shared_string_example));
|
||||||
|
exampleCard.hideFieldBoxLabel();
|
||||||
List<HorizontalSelectionItem> locationItems = new ArrayList<>();
|
List<HorizontalSelectionItem> locationItems = new ArrayList<>();
|
||||||
for (ExampleLocation location : ExampleLocation.values()) {
|
for (ExampleLocation location : ExampleLocation.values()) {
|
||||||
locationItems.add(new HorizontalSelectionItem(location.getName(), location));
|
locationItems.add(new HorizontalSelectionItem(location.getName(), location));
|
||||||
|
@ -390,7 +335,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
||||||
private void setupResultsContainer() {
|
private void setupResultsContainer() {
|
||||||
testResultsContainer = getInflater().inflate(
|
testResultsContainer = getInflater().inflate(
|
||||||
R.layout.bottom_sheet_item_with_descr_64dp, segmentsContainer, false);
|
R.layout.bottom_sheet_item_with_descr_64dp, segmentsContainer, false);
|
||||||
testResultsContainer.setVisibility(View.INVISIBLE);
|
testResultsContainer.setVisibility(View.GONE);
|
||||||
segmentsContainer.addView(testResultsContainer);
|
segmentsContainer.addView(testResultsContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -480,6 +425,22 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
||||||
helper.deleteEngine(engine);
|
helper.deleteEngine(engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void delete(Activity activity) {
|
||||||
|
if (engine != null) {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(UiUtilities.getThemedContext(activity, isNightMode()));
|
||||||
|
builder.setMessage(getString(R.string.delete_online_routing_engine));
|
||||||
|
builder.setNegativeButton(R.string.shared_string_no, null);
|
||||||
|
builder.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
onDeleteEngine();
|
||||||
|
dismiss();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
builder.create().show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isEditingMode() {
|
private boolean isEditingMode() {
|
||||||
return editedEngineKey != null;
|
return editedEngineKey != null;
|
||||||
}
|
}
|
||||||
|
@ -511,8 +472,8 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showTestResults(final boolean resultOk,
|
private void showTestResults(final boolean resultOk,
|
||||||
final @NonNull String message,
|
final @NonNull String message,
|
||||||
final @NonNull ExampleLocation location) {
|
final @NonNull ExampleLocation location) {
|
||||||
app.runInUIThread(new Runnable() {
|
app.runInUIThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -528,6 +489,12 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
||||||
tvTitle.setText(String.format(getString(R.string.message_server_error), message));
|
tvTitle.setText(String.format(getString(R.string.message_server_error), message));
|
||||||
}
|
}
|
||||||
tvDescription.setText(location.getName());
|
tvDescription.setText(location.getName());
|
||||||
|
scrollView.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
scrollView.scrollTo(0, scrollView.getChildAt(0).getBottom());
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -567,6 +534,10 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
||||||
public void showExitDialog() {
|
public void showExitDialog() {
|
||||||
View focus = view.findFocus();
|
View focus = view.findFocus();
|
||||||
AndroidUtils.hideSoftKeyboard(mapActivity, focus);
|
AndroidUtils.hideSoftKeyboard(mapActivity, focus);
|
||||||
|
if (hasNameDuplicate(initEngine)) {
|
||||||
|
List<OnlineRoutingEngine> cachedEngines = helper.getEnginesExceptMentionedKeys(editedEngineKey);
|
||||||
|
OnlineRoutingUtils.generateUniqueName(app, initEngine, cachedEngines);
|
||||||
|
}
|
||||||
if (!engine.equals(initEngine)) {
|
if (!engine.equals(initEngine)) {
|
||||||
AlertDialog.Builder dismissDialog = createWarningDialog(mapActivity,
|
AlertDialog.Builder dismissDialog = createWarningDialog(mapActivity,
|
||||||
R.string.shared_string_dismiss, R.string.exit_without_saving, R.string.shared_string_cancel);
|
R.string.shared_string_dismiss, R.string.exit_without_saving, R.string.shared_string_cancel);
|
||||||
|
@ -627,11 +598,8 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
||||||
@Override
|
@Override
|
||||||
public void onDestroyView() {
|
public void onDestroyView() {
|
||||||
super.onDestroyView();
|
super.onDestroyView();
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
removeOnGlobalLayoutListener();
|
||||||
view.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayout);
|
removeOnScrollListener();
|
||||||
} else {
|
|
||||||
view.getViewTreeObserver().removeGlobalOnLayoutListener(onGlobalLayout);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -699,8 +667,8 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void showInstance(@NonNull FragmentActivity activity,
|
public static void showInstance(@NonNull FragmentActivity activity,
|
||||||
@NonNull ApplicationMode appMode,
|
@NonNull ApplicationMode appMode,
|
||||||
@Nullable String editedEngineKey) {
|
@Nullable String editedEngineKey) {
|
||||||
FragmentManager fm = activity.getSupportFragmentManager();
|
FragmentManager fm = activity.getSupportFragmentManager();
|
||||||
if (!fm.isStateSaved() && fm.findFragmentByTag(OnlineRoutingEngineFragment.TAG) == null) {
|
if (!fm.isStateSaved() && fm.findFragmentByTag(OnlineRoutingEngineFragment.TAG) == null) {
|
||||||
OnlineRoutingEngineFragment fragment = new OnlineRoutingEngineFragment();
|
OnlineRoutingEngineFragment fragment = new OnlineRoutingEngineFragment();
|
||||||
|
@ -711,4 +679,122 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
||||||
.addToBackStack(TAG).commitAllowingStateLoss();
|
.addToBackStack(TAG).commitAllowingStateLoss();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
|
private void hideKeyboardOnScroll() {
|
||||||
|
scrollView.setOnTouchListener(new View.OnTouchListener() {
|
||||||
|
int scrollViewY = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouch(View v, MotionEvent event) {
|
||||||
|
int y = scrollView.getScrollY();
|
||||||
|
if (isKeyboardShown && scrollViewY != y) {
|
||||||
|
scrollViewY = y;
|
||||||
|
View focus = mapActivity.getCurrentFocus();
|
||||||
|
if (focus != null) {
|
||||||
|
AndroidUtils.hideSoftKeyboard(mapActivity, focus);
|
||||||
|
focus.clearFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showShadowBelowButtons() {
|
||||||
|
scrollView.getViewTreeObserver().addOnScrollChangedListener(getShowShadowOnScrollListener());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showButtonsAboveKeyboard() {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||||
|
view.getViewTreeObserver().addOnGlobalLayoutListener(getShowButtonsOnGlobalListener());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private OnScrollChangedListener getShowShadowOnScrollListener() {
|
||||||
|
if (onScroll == null) {
|
||||||
|
onScroll = new OnScrollChangedListener() {
|
||||||
|
@Override
|
||||||
|
public void onScrollChanged() {
|
||||||
|
boolean scrollToBottomAvailable = scrollView.canScrollVertically(1);
|
||||||
|
if (scrollToBottomAvailable) {
|
||||||
|
showShadowButton();
|
||||||
|
} else {
|
||||||
|
hideShadowButton();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return onScroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
private OnGlobalLayoutListener getShowButtonsOnGlobalListener() {
|
||||||
|
if (onGlobalLayout == null) {
|
||||||
|
onGlobalLayout = new OnGlobalLayoutListener() {
|
||||||
|
private int layoutHeightPrevious;
|
||||||
|
private int layoutHeightMin;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onGlobalLayout() {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||||
|
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||||
|
} else {
|
||||||
|
view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Rect visibleDisplayFrame = new Rect();
|
||||||
|
view.getWindowVisibleDisplayFrame(visibleDisplayFrame);
|
||||||
|
int layoutHeight = visibleDisplayFrame.bottom;
|
||||||
|
|
||||||
|
if (layoutHeight < layoutHeightPrevious) {
|
||||||
|
isKeyboardShown = true;
|
||||||
|
layoutHeightMin = layoutHeight;
|
||||||
|
} else {
|
||||||
|
isKeyboardShown = layoutHeight == layoutHeightMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layoutHeight != layoutHeightPrevious) {
|
||||||
|
FrameLayout.LayoutParams rootViewLayout = (FrameLayout.LayoutParams) view.getLayoutParams();
|
||||||
|
rootViewLayout.height = layoutHeight;
|
||||||
|
view.requestLayout();
|
||||||
|
layoutHeightPrevious = layoutHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
view.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
view.getViewTreeObserver().addOnGlobalLayoutListener(getShowButtonsOnGlobalListener());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return onGlobalLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeOnScrollListener() {
|
||||||
|
scrollView.getViewTreeObserver().removeOnScrollChangedListener(getShowShadowOnScrollListener());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeOnGlobalLayoutListener() {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||||
|
view.getViewTreeObserver().removeOnGlobalLayoutListener(getShowButtonsOnGlobalListener());
|
||||||
|
} else {
|
||||||
|
view.getViewTreeObserver().removeGlobalOnLayoutListener(getShowButtonsOnGlobalListener());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showShadowButton() {
|
||||||
|
buttonsShadow.setVisibility(View.VISIBLE);
|
||||||
|
buttonsShadow.animate()
|
||||||
|
.alpha(0.8f)
|
||||||
|
.setDuration(200)
|
||||||
|
.setListener(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hideShadowButton() {
|
||||||
|
buttonsShadow.animate()
|
||||||
|
.alpha(0f)
|
||||||
|
.setDuration(200);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,18 @@
|
||||||
package net.osmand.plus.settings.bottomsheets;
|
package net.osmand.plus.settings.bottomsheets;
|
||||||
|
|
||||||
|
import android.graphics.drawable.ClipDrawable;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.graphics.drawable.GradientDrawable;
|
||||||
|
import android.graphics.drawable.LayerDrawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.view.Gravity;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.SeekBar;
|
import android.widget.SeekBar;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
@ -133,6 +139,7 @@ public class AnnouncementTimeBottomSheet extends BasePreferenceBottomSheet
|
||||||
ivArrow = rootView.findViewById(R.id.iv_arrow);
|
ivArrow = rootView.findViewById(R.id.iv_arrow);
|
||||||
tvIntervalsDescr = rootView.findViewById(R.id.tv_interval_descr);
|
tvIntervalsDescr = rootView.findViewById(R.id.tv_interval_descr);
|
||||||
|
|
||||||
|
setProfileColorToSeekBar();
|
||||||
seekBarArrival.setOnSeekBarChangeListener(this);
|
seekBarArrival.setOnSeekBarChangeListener(this);
|
||||||
seekBarArrival.setProgress(selectedEntryIndex);
|
seekBarArrival.setProgress(selectedEntryIndex);
|
||||||
seekBarArrival.setMax(listPreference.getEntries().length - 1);
|
seekBarArrival.setMax(listPreference.getEntries().length - 1);
|
||||||
|
@ -163,6 +170,31 @@ public class AnnouncementTimeBottomSheet extends BasePreferenceBottomSheet
|
||||||
AndroidUiHelper.updateVisibility(tvIntervalsDescr, !collapsed);
|
AndroidUiHelper.updateVisibility(tvIntervalsDescr, !collapsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setProfileColorToSeekBar() {
|
||||||
|
int color = ContextCompat.getColor(app, getAppMode().getIconColorInfo().getColor(nightMode));
|
||||||
|
|
||||||
|
LayerDrawable seekBarProgressLayer =
|
||||||
|
(LayerDrawable) ContextCompat.getDrawable(app, R.drawable.seekbar_progress_announcement_time);
|
||||||
|
|
||||||
|
GradientDrawable background = (GradientDrawable) seekBarProgressLayer.findDrawableByLayerId(R.id.background);
|
||||||
|
background.setColor(color);
|
||||||
|
background.setAlpha(70);
|
||||||
|
|
||||||
|
GradientDrawable progress = (GradientDrawable) seekBarProgressLayer.findDrawableByLayerId(R.id.progress);
|
||||||
|
progress.setColor(color);
|
||||||
|
Drawable clippedProgress = new ClipDrawable(progress, Gravity.CENTER_VERTICAL | Gravity.START, 1);
|
||||||
|
|
||||||
|
seekBarArrival.setProgressDrawable(new LayerDrawable(new Drawable[] {
|
||||||
|
background, clippedProgress
|
||||||
|
}));
|
||||||
|
|
||||||
|
LayerDrawable seekBarThumpLayer =
|
||||||
|
(LayerDrawable) ContextCompat.getDrawable(app, R.drawable.seekbar_thumb_announcement_time);
|
||||||
|
GradientDrawable thump = (GradientDrawable) seekBarThumpLayer.findDrawableByLayerId(R.id.thump);
|
||||||
|
thump.setColor(color);
|
||||||
|
seekBarArrival.setThumb(thump);
|
||||||
|
}
|
||||||
|
|
||||||
public static void showInstance(@NonNull FragmentManager fm, String prefKey, Fragment target,
|
public static void showInstance(@NonNull FragmentManager fm, String prefKey, Fragment target,
|
||||||
@Nullable ApplicationMode appMode, boolean usedOnMap) {
|
@Nullable ApplicationMode appMode, boolean usedOnMap) {
|
||||||
try {
|
try {
|
||||||
|
|
339
OsmAnd/src/net/osmand/plus/track/OverviewCard.java
Normal file
339
OsmAnd/src/net/osmand/plus/track/OverviewCard.java
Normal file
|
@ -0,0 +1,339 @@
|
||||||
|
package net.osmand.plus.track;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.ColorRes;
|
||||||
|
import androidx.annotation.DrawableRes;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.widget.AppCompatImageView;
|
||||||
|
import androidx.recyclerview.widget.DefaultItemAnimator;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView.ItemDecoration;
|
||||||
|
|
||||||
|
import net.osmand.GPXUtilities.GPXFile;
|
||||||
|
import net.osmand.GPXUtilities.GPXTrackAnalysis;
|
||||||
|
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
|
||||||
|
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType;
|
||||||
|
import net.osmand.plus.OsmAndFormatter;
|
||||||
|
import net.osmand.plus.R;
|
||||||
|
import net.osmand.plus.activities.MapActivity;
|
||||||
|
import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType;
|
||||||
|
import net.osmand.plus.myplaces.SegmentActionsListener;
|
||||||
|
import net.osmand.plus.routepreparationmenu.cards.BaseCard;
|
||||||
|
import net.osmand.plus.widgets.TextViewEx;
|
||||||
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static net.osmand.plus.myplaces.TrackActivityFragmentAdapter.isGpxFileSelected;
|
||||||
|
import static net.osmand.plus.track.OptionsCard.APPEARANCE_BUTTON_INDEX;
|
||||||
|
import static net.osmand.plus.track.OptionsCard.DIRECTIONS_BUTTON_INDEX;
|
||||||
|
import static net.osmand.plus.track.OptionsCard.EDIT_BUTTON_INDEX;
|
||||||
|
import static net.osmand.plus.track.OptionsCard.SHOW_ON_MAP_BUTTON_INDEX;
|
||||||
|
|
||||||
|
public class OverviewCard extends BaseCard {
|
||||||
|
|
||||||
|
private RecyclerView rvOverview;
|
||||||
|
private View showButton;
|
||||||
|
private View appearanceButton;
|
||||||
|
private View editButton;
|
||||||
|
private View directionsButton;
|
||||||
|
|
||||||
|
private final TrackDisplayHelper displayHelper;
|
||||||
|
private final GPXFile gpxFile;
|
||||||
|
private final GpxDisplayItemType[] filterTypes = new GpxDisplayItemType[] {GpxDisplayItemType.TRACK_SEGMENT};
|
||||||
|
private final SegmentActionsListener listener;
|
||||||
|
|
||||||
|
public OverviewCard(@NonNull MapActivity mapActivity, @NonNull TrackDisplayHelper displayHelper,
|
||||||
|
@NonNull SegmentActionsListener listener) {
|
||||||
|
super(mapActivity);
|
||||||
|
this.displayHelper = displayHelper;
|
||||||
|
this.gpxFile = displayHelper.getGpx();
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCardLayoutId() {
|
||||||
|
return R.layout.gpx_overview_fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateContent() {
|
||||||
|
int iconColorDef = R.color.icon_color_active_light;
|
||||||
|
int iconColorPres = R.color.active_buttons_and_links_text_dark;
|
||||||
|
boolean fileAvailable = gpxFile.path != null && !gpxFile.showCurrentTrack;
|
||||||
|
|
||||||
|
showButton = view.findViewById(R.id.show_button);
|
||||||
|
appearanceButton = view.findViewById(R.id.appearance_button);
|
||||||
|
editButton = view.findViewById(R.id.edit_button);
|
||||||
|
directionsButton = view.findViewById(R.id.directions_button);
|
||||||
|
rvOverview = view.findViewById(R.id.recycler_overview);
|
||||||
|
|
||||||
|
initShowButton(iconColorDef, iconColorPres);
|
||||||
|
initAppearanceButton(iconColorDef, iconColorPres);
|
||||||
|
if (fileAvailable) {
|
||||||
|
initEditButton(iconColorDef, iconColorPres);
|
||||||
|
initDirectionsButton(iconColorDef, iconColorPres);
|
||||||
|
}
|
||||||
|
initStatBlocks();
|
||||||
|
}
|
||||||
|
|
||||||
|
void initStatBlocks() {
|
||||||
|
GpxDisplayItem gpxItem = TrackDisplayHelper.flatten(displayHelper.getOriginalGroups(filterTypes)).get(0);
|
||||||
|
GPXTrackAnalysis analysis = gpxItem.analysis;
|
||||||
|
boolean joinSegments = displayHelper.isJoinSegments();
|
||||||
|
float totalDistance = !joinSegments && gpxItem.isGeneralTrack() ? analysis.totalDistanceWithoutGaps : analysis.totalDistance;
|
||||||
|
float timeSpan = !joinSegments && gpxItem.isGeneralTrack() ? analysis.timeSpanWithoutGaps : analysis.timeSpan;
|
||||||
|
String asc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationUp, app);
|
||||||
|
String desc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationDown, app);
|
||||||
|
String avg = OsmAndFormatter.getFormattedSpeed(analysis.avgSpeed, app);
|
||||||
|
String max = OsmAndFormatter.getFormattedSpeed(analysis.maxSpeed, app);
|
||||||
|
|
||||||
|
StatBlock sDistance = new StatBlock(app.getString(R.string.distance), OsmAndFormatter.getFormattedDistance(totalDistance, app),
|
||||||
|
R.drawable.ic_action_track_16, R.color.icon_color_default_light, GPXDataSetType.ALTITUDE, GPXDataSetType.SPEED);
|
||||||
|
StatBlock sAscent = new StatBlock(app.getString(R.string.altitude_ascent), asc,
|
||||||
|
R.drawable.ic_action_arrow_up_16, R.color.gpx_chart_red, GPXDataSetType.SLOPE, null);
|
||||||
|
StatBlock sDescent = new StatBlock(app.getString(R.string.altitude_descent), desc,
|
||||||
|
R.drawable.ic_action_arrow_down_16, R.color.gpx_pale_green, GPXDataSetType.ALTITUDE, GPXDataSetType.SLOPE);
|
||||||
|
StatBlock sAvSpeed = new StatBlock(app.getString(R.string.average_speed), avg,
|
||||||
|
R.drawable.ic_action_speed_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null);
|
||||||
|
StatBlock sMaxSpeed = new StatBlock(app.getString(R.string.max_speed), max,
|
||||||
|
R.drawable.ic_action_max_speed_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null);
|
||||||
|
StatBlock sTimeSpan = new StatBlock(app.getString(R.string.shared_string_time_span),
|
||||||
|
Algorithms.formatDuration((int) (timeSpan / 1000), app.accessibilityEnabled()),
|
||||||
|
R.drawable.ic_action_time_span_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null);
|
||||||
|
|
||||||
|
LinearLayoutManager llManager = new LinearLayoutManager(app);
|
||||||
|
llManager.setOrientation(LinearLayoutManager.HORIZONTAL);
|
||||||
|
rvOverview.setLayoutManager(llManager);
|
||||||
|
rvOverview.setItemAnimator(new DefaultItemAnimator());
|
||||||
|
List<StatBlock> items = Arrays.asList(sDistance, sAscent, sDescent, sAvSpeed, sMaxSpeed, sTimeSpan);
|
||||||
|
final StatBlockAdapter siAdapter = new StatBlockAdapter(items);
|
||||||
|
rvOverview.setAdapter(siAdapter);
|
||||||
|
rvOverview.addItemDecoration(new HorizontalDividerDecoration(app));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initShowButton(final int iconColorDef, final int iconColorPres) {
|
||||||
|
final AppCompatImageView image = showButton.findViewById(R.id.image);
|
||||||
|
final AppCompatImageView filled = showButton.findViewById(R.id.filled);
|
||||||
|
final int iconShowResId = R.drawable.ic_action_view;
|
||||||
|
final int iconHideResId = R.drawable.ic_action_hide;
|
||||||
|
final boolean[] gpxFileSelected = {isGpxFileSelected(app, gpxFile)};
|
||||||
|
filled.setImageResource(R.drawable.bg_topbar_shield_exit_ref);
|
||||||
|
filled.setAlpha(gpxFileSelected[0] ? 1f : 0.1f);
|
||||||
|
setImageDrawable(image, gpxFileSelected[0] ? iconShowResId : iconHideResId,
|
||||||
|
gpxFileSelected[0] ? iconColorPres : iconColorDef);
|
||||||
|
showButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
gpxFileSelected[0] = !gpxFileSelected[0];
|
||||||
|
filled.setAlpha(gpxFileSelected[0] ? 1f : 0.1f);
|
||||||
|
setImageDrawable(image, gpxFileSelected[0] ? iconShowResId : iconHideResId,
|
||||||
|
gpxFileSelected[0] ? iconColorPres : iconColorDef);
|
||||||
|
CardListener listener = getListener();
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onCardButtonPressed(OverviewCard.this, SHOW_ON_MAP_BUTTON_INDEX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initAppearanceButton(int iconColorDef, int iconColorPres) {
|
||||||
|
initButton(appearanceButton, APPEARANCE_BUTTON_INDEX, R.drawable.ic_action_appearance, iconColorDef, iconColorPres);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initEditButton(int iconColorDef, int iconColorPres) {
|
||||||
|
initButton(editButton, EDIT_BUTTON_INDEX, R.drawable.ic_action_edit_dark, iconColorDef, iconColorPres);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initDirectionsButton(int iconColorDef, int iconColorPres) {
|
||||||
|
initButton(directionsButton, DIRECTIONS_BUTTON_INDEX, R.drawable.ic_action_gdirections_dark, iconColorDef, iconColorPres);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initButton(View item, final int buttonIndex, int iconResId, int iconColorDef, int iconColorPres) {
|
||||||
|
final AppCompatImageView image = item.findViewById(R.id.image);
|
||||||
|
final AppCompatImageView filled = item.findViewById(R.id.filled);
|
||||||
|
filled.setImageResource(R.drawable.bg_topbar_shield_exit_ref);
|
||||||
|
filled.setAlpha(0.1f);
|
||||||
|
setImageDrawable(image, iconResId, iconColorDef);
|
||||||
|
setOnTouchItem(item, image, filled, iconResId, iconColorDef, iconColorPres);
|
||||||
|
item.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
CardListener listener = getListener();
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onCardButtonPressed(OverviewCard.this, buttonIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setImageDrawable(ImageView iv, @DrawableRes int resId, @ColorRes int color) {
|
||||||
|
Drawable icon = app.getUIUtilities().getIcon(resId, color);
|
||||||
|
iv.setImageDrawable(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setOnTouchItem(View item, final ImageView image, final ImageView filled, @DrawableRes final int resId, @ColorRes final int colorDef, @ColorRes final int colorPres) {
|
||||||
|
item.setOnTouchListener(new View.OnTouchListener() {
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
|
@Override
|
||||||
|
public boolean onTouch(View v, MotionEvent event) {
|
||||||
|
switch (event.getAction()) {
|
||||||
|
case MotionEvent.ACTION_DOWN: {
|
||||||
|
filled.setAlpha(1f);
|
||||||
|
setImageDrawable(image, resId, colorPres);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
case MotionEvent.ACTION_CANCEL: {
|
||||||
|
filled.setAlpha(0.1f);
|
||||||
|
setImageDrawable(image, resId, colorDef);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private class StatBlockAdapter extends RecyclerView.Adapter<StatBlockViewHolder> {
|
||||||
|
|
||||||
|
private final List<StatBlock> statBlocks;
|
||||||
|
|
||||||
|
public StatBlockAdapter(List<StatBlock> StatBlocks) {
|
||||||
|
this.statBlocks = StatBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return statBlocks.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public StatBlockViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
|
View itemView = LayoutInflater.from(parent.getContext())
|
||||||
|
.inflate(R.layout.item_gpx_stat_block, parent, false);
|
||||||
|
return new StatBlockViewHolder(itemView);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(StatBlockViewHolder holder, int position) {
|
||||||
|
final StatBlock item = statBlocks.get(position);
|
||||||
|
|
||||||
|
holder.valueText.setText(item.value);
|
||||||
|
holder.titleText.setText(item.title);
|
||||||
|
holder.valueText.setTextColor(app.getResources().getColor(R.color.active_color_primary_light));
|
||||||
|
holder.titleText.setTextColor(app.getResources().getColor(R.color.text_color_secondary_light));
|
||||||
|
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
GpxDisplayItem gpxItem = TrackDisplayHelper.flatten(displayHelper.getOriginalGroups(filterTypes)).get(0);
|
||||||
|
if (gpxItem != null && gpxItem.analysis != null) {
|
||||||
|
ArrayList<GPXDataSetType> list = new ArrayList<>();
|
||||||
|
if (item.firstType != null) {
|
||||||
|
list.add(item.firstType);
|
||||||
|
}
|
||||||
|
if (item.secondType != null) {
|
||||||
|
list.add(item.secondType);
|
||||||
|
}
|
||||||
|
if (list.size() > 0) {
|
||||||
|
gpxItem.chartTypes = list.toArray(new GPXDataSetType[0]);
|
||||||
|
}
|
||||||
|
gpxItem.locationOnMap = gpxItem.locationStart;
|
||||||
|
|
||||||
|
listener.openAnalyzeOnMap(gpxItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setImageDrawable(holder.imageView, item.imageResId, item.imageColorId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class StatBlockViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
|
private final TextViewEx valueText;
|
||||||
|
private final TextView titleText;
|
||||||
|
private final AppCompatImageView imageView;
|
||||||
|
|
||||||
|
StatBlockViewHolder(View view) {
|
||||||
|
super(view);
|
||||||
|
valueText = view.findViewById(R.id.value);
|
||||||
|
titleText = view.findViewById(R.id.title);
|
||||||
|
imageView = view.findViewById(R.id.image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class HorizontalDividerDecoration extends ItemDecoration {
|
||||||
|
|
||||||
|
private final Drawable divider;
|
||||||
|
private final int marginV;
|
||||||
|
private final int marginH;
|
||||||
|
|
||||||
|
public HorizontalDividerDecoration(Context context) {
|
||||||
|
int[] ATTRS = new int[] {android.R.attr.listDivider};
|
||||||
|
final TypedArray ta = context.obtainStyledAttributes(ATTRS);
|
||||||
|
divider = ta.getDrawable(0);
|
||||||
|
// DrawableCompat.setTint(divider, context.getResources().getColor(R.color.divider_color_light)); //todo change drawable color
|
||||||
|
ta.recycle();
|
||||||
|
marginV = context.getResources().getDimensionPixelSize(R.dimen.map_small_button_margin);
|
||||||
|
marginH = context.getResources().getDimensionPixelSize(R.dimen.content_padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
|
||||||
|
drawHorizontal(c, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawHorizontal(Canvas c, RecyclerView parent) {
|
||||||
|
for (int i = 0; i < parent.getChildCount(); i++) {
|
||||||
|
final View child = parent.getChildAt(i);
|
||||||
|
final int left = child.getRight() - divider.getIntrinsicWidth() + marginH;
|
||||||
|
final int right = left + divider.getIntrinsicHeight();
|
||||||
|
final int top = child.getTop() + marginV;
|
||||||
|
final int bottom = child.getBottom() - marginV;
|
||||||
|
divider.setBounds(left, top, right, bottom);
|
||||||
|
divider.draw(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getItemOffsets(Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
|
||||||
|
outRect.set(marginH - divider.getIntrinsicWidth(), marginV, marginH + divider.getIntrinsicWidth(), marginV);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class StatBlock {
|
||||||
|
|
||||||
|
private final String title;
|
||||||
|
private final String value;
|
||||||
|
private final int imageResId;
|
||||||
|
private final int imageColorId;
|
||||||
|
private final GPXDataSetType firstType;
|
||||||
|
private final GPXDataSetType secondType;
|
||||||
|
|
||||||
|
public StatBlock(String title, String value, @DrawableRes int imageResId, @ColorRes int imageColorId,
|
||||||
|
GPXDataSetType firstType, GPXDataSetType secondType) {
|
||||||
|
this.title = title;
|
||||||
|
this.value = value;
|
||||||
|
this.imageResId = imageResId;
|
||||||
|
this.imageColorId = imageColorId;
|
||||||
|
this.firstType = firstType;
|
||||||
|
this.secondType = secondType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,6 +25,7 @@ import net.osmand.GPXUtilities.GPXFile;
|
||||||
import net.osmand.GPXUtilities.Track;
|
import net.osmand.GPXUtilities.Track;
|
||||||
import net.osmand.GPXUtilities.TrkSegment;
|
import net.osmand.GPXUtilities.TrkSegment;
|
||||||
import net.osmand.GPXUtilities.WptPt;
|
import net.osmand.GPXUtilities.WptPt;
|
||||||
|
import net.osmand.Location;
|
||||||
import net.osmand.PlatformUtil;
|
import net.osmand.PlatformUtil;
|
||||||
import net.osmand.data.LatLon;
|
import net.osmand.data.LatLon;
|
||||||
import net.osmand.data.QuadRect;
|
import net.osmand.data.QuadRect;
|
||||||
|
@ -34,10 +35,13 @@ import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup;
|
||||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
|
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
|
||||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType;
|
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType;
|
||||||
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
||||||
|
import net.osmand.plus.OsmAndLocationProvider.OsmAndCompassListener;
|
||||||
|
import net.osmand.plus.OsmAndLocationProvider.OsmAndLocationListener;
|
||||||
import net.osmand.plus.OsmandApplication;
|
import net.osmand.plus.OsmandApplication;
|
||||||
import net.osmand.plus.OsmandPlugin;
|
import net.osmand.plus.OsmandPlugin;
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
import net.osmand.plus.UiUtilities;
|
import net.osmand.plus.UiUtilities;
|
||||||
|
import net.osmand.plus.UiUtilities.UpdateLocationViewCache;
|
||||||
import net.osmand.plus.activities.MapActivity;
|
import net.osmand.plus.activities.MapActivity;
|
||||||
import net.osmand.plus.activities.MapActivityActions;
|
import net.osmand.plus.activities.MapActivityActions;
|
||||||
import net.osmand.plus.base.ContextMenuFragment;
|
import net.osmand.plus.base.ContextMenuFragment;
|
||||||
|
@ -46,6 +50,7 @@ import net.osmand.plus.helpers.AndroidUiHelper;
|
||||||
import net.osmand.plus.helpers.GpxUiHelper;
|
import net.osmand.plus.helpers.GpxUiHelper;
|
||||||
import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType;
|
import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType;
|
||||||
import net.osmand.plus.helpers.GpxUiHelper.OrderedLineDataSet;
|
import net.osmand.plus.helpers.GpxUiHelper.OrderedLineDataSet;
|
||||||
|
import net.osmand.plus.mapcontextmenu.MapContextMenu;
|
||||||
import net.osmand.plus.mapcontextmenu.controllers.SelectedGpxMenuController.OpenGpxDetailsTask;
|
import net.osmand.plus.mapcontextmenu.controllers.SelectedGpxMenuController.OpenGpxDetailsTask;
|
||||||
import net.osmand.plus.mapcontextmenu.other.TrackChartPoints;
|
import net.osmand.plus.mapcontextmenu.other.TrackChartPoints;
|
||||||
import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu;
|
import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu;
|
||||||
|
@ -65,6 +70,7 @@ import net.osmand.plus.routepreparationmenu.cards.BaseCard.CardListener;
|
||||||
import net.osmand.plus.track.SaveGpxAsyncTask.SaveGpxListener;
|
import net.osmand.plus.track.SaveGpxAsyncTask.SaveGpxListener;
|
||||||
import net.osmand.plus.widgets.IconPopupMenu;
|
import net.osmand.plus.widgets.IconPopupMenu;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
import net.osmand.util.MapUtils;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
|
@ -96,7 +102,7 @@ import static net.osmand.plus.track.OptionsCard.SHOW_ON_MAP_BUTTON_INDEX;
|
||||||
import static net.osmand.plus.track.OptionsCard.UPLOAD_OSM_BUTTON_INDEX;
|
import static net.osmand.plus.track.OptionsCard.UPLOAD_OSM_BUTTON_INDEX;
|
||||||
|
|
||||||
public class TrackMenuFragment extends ContextMenuScrollFragment implements CardListener,
|
public class TrackMenuFragment extends ContextMenuScrollFragment implements CardListener,
|
||||||
SegmentActionsListener, RenameCallback, OnTrackFileMoveListener {
|
SegmentActionsListener, RenameCallback, OnTrackFileMoveListener, OsmAndLocationListener, OsmAndCompassListener {
|
||||||
|
|
||||||
public static final String TAG = TrackMenuFragment.class.getName();
|
public static final String TAG = TrackMenuFragment.class.getName();
|
||||||
private static final Log log = PlatformUtil.getLog(TrackMenuFragment.class);
|
private static final Log log = PlatformUtil.getLog(TrackMenuFragment.class);
|
||||||
|
@ -113,10 +119,16 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
private SegmentsCard segmentsCard;
|
private SegmentsCard segmentsCard;
|
||||||
private OptionsCard optionsCard;
|
private OptionsCard optionsCard;
|
||||||
private DescriptionCard descriptionCard;
|
private DescriptionCard descriptionCard;
|
||||||
|
private OverviewCard overviewCard;
|
||||||
|
|
||||||
private TrackChartPoints trackChartPoints;
|
private TrackChartPoints trackChartPoints;
|
||||||
|
|
||||||
private int menuTitleHeight;
|
private int menuTitleHeight;
|
||||||
|
private String gpxTitle;
|
||||||
|
private UpdateLocationViewCache updateLocationViewCache;
|
||||||
|
private Location lastLocation = null;
|
||||||
|
private Float heading;
|
||||||
|
private boolean locationUpdateStarted;
|
||||||
|
|
||||||
public enum TrackMenuType {
|
public enum TrackMenuType {
|
||||||
OVERVIEW(R.id.action_overview, R.string.shared_string_overview),
|
OVERVIEW(R.id.action_overview, R.string.shared_string_overview),
|
||||||
|
@ -162,6 +174,11 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
return MenuState.HEADER_ONLY | MenuState.HALF_SCREEN | MenuState.FULL_SCREEN;
|
return MenuState.HEADER_ONLY | MenuState.HALF_SCREEN | MenuState.FULL_SCREEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getInitialMenuState() {
|
||||||
|
return MenuState.HEADER_ONLY;
|
||||||
|
}
|
||||||
|
|
||||||
public TrackDisplayHelper getDisplayHelper() {
|
public TrackDisplayHelper getDisplayHelper() {
|
||||||
return displayHelper;
|
return displayHelper;
|
||||||
}
|
}
|
||||||
|
@ -186,6 +203,8 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(gpxFilePath);
|
selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(gpxFilePath);
|
||||||
}
|
}
|
||||||
displayHelper.setGpx(selectedGpxFile.getGpxFile());
|
displayHelper.setGpx(selectedGpxFile.getGpxFile());
|
||||||
|
String fileName = Algorithms.getFileWithoutDirs(getGpx().path);
|
||||||
|
gpxTitle = GpxUiHelper.getGpxTitle(fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,9 +220,12 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
routeMenuTopShadowAll = view.findViewById(R.id.route_menu_top_shadow_all);
|
routeMenuTopShadowAll = view.findViewById(R.id.route_menu_top_shadow_all);
|
||||||
headerTitle = view.findViewById(R.id.title);
|
headerTitle = view.findViewById(R.id.title);
|
||||||
headerIcon = view.findViewById(R.id.icon_view);
|
headerIcon = view.findViewById(R.id.icon_view);
|
||||||
|
updateLocationViewCache = app.getUIUtilities().getUpdateLocationViewCache();
|
||||||
|
|
||||||
if (isPortrait()) {
|
if (isPortrait()) {
|
||||||
updateCardsLayout();
|
AndroidUiHelper.updateVisibility(getTopShadow(), true);
|
||||||
|
AndroidUtils.setBackground(view.getContext(), getBottomContainer(), isNightMode(),
|
||||||
|
R.color.list_background_color_light, R.color.list_background_color_dark);
|
||||||
} else {
|
} else {
|
||||||
int widthNoShadow = getLandscapeNoShadowWidth();
|
int widthNoShadow = getLandscapeNoShadowWidth();
|
||||||
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(widthNoShadow, ViewGroup.LayoutParams.WRAP_CONTENT);
|
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(widthNoShadow, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
|
@ -220,14 +242,32 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setHeaderTitle(String text, boolean iconVisibility) {
|
||||||
|
headerTitle.setText(text);
|
||||||
|
AndroidUiHelper.updateVisibility(headerIcon, iconVisibility);
|
||||||
|
}
|
||||||
|
|
||||||
private void updateHeader() {
|
private void updateHeader() {
|
||||||
if (menuType == TrackMenuType.OPTIONS) {
|
ViewGroup headerContainer = (ViewGroup) routeMenuTopShadowAll;
|
||||||
headerTitle.setText(menuType.titleId);
|
if (menuType == TrackMenuType.OVERVIEW) {
|
||||||
AndroidUiHelper.updateVisibility(headerIcon, false);
|
setHeaderTitle(gpxTitle, true);
|
||||||
|
if (overviewCard != null && overviewCard.getView() != null) {
|
||||||
|
ViewGroup parent = ((ViewGroup) overviewCard.getView().getParent());
|
||||||
|
if (parent != null) {
|
||||||
|
parent.removeView(overviewCard.getView());
|
||||||
|
}
|
||||||
|
headerContainer.addView(overviewCard.getView());
|
||||||
|
} else {
|
||||||
|
overviewCard = new OverviewCard(getMapActivity(), displayHelper, this);
|
||||||
|
overviewCard.setListener(this);
|
||||||
|
headerContainer.addView(overviewCard.build(getMapActivity()));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
String fileName = Algorithms.getFileWithoutDirs(getGpx().path);
|
if (overviewCard != null && overviewCard.getView() != null) {
|
||||||
headerTitle.setText(GpxUiHelper.getGpxTitle(fileName));
|
headerContainer.removeView(overviewCard.getView());
|
||||||
AndroidUiHelper.updateVisibility(headerIcon, true);
|
}
|
||||||
|
boolean isOptions = menuType == TrackMenuType.OPTIONS;
|
||||||
|
setHeaderTitle(isOptions ? app.getString(menuType.titleId) : gpxTitle, !isOptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,6 +360,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
mapActivity.getMapLayers().getGpxLayer().setTrackChartPoints(trackChartPoints);
|
mapActivity.getMapLayers().getGpxLayer().setTrackChartPoints(trackChartPoints);
|
||||||
}
|
}
|
||||||
updateHeader();
|
updateHeader();
|
||||||
|
startLocationUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -329,6 +370,67 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
if (mapActivity != null) {
|
if (mapActivity != null) {
|
||||||
mapActivity.getMapLayers().getGpxLayer().setTrackChartPoints(null);
|
mapActivity.getMapLayers().getGpxLayer().setTrackChartPoints(null);
|
||||||
}
|
}
|
||||||
|
stopLocationUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateLocation(Location location) {
|
||||||
|
if (!MapUtils.areLatLonEqual(lastLocation, location)) {
|
||||||
|
lastLocation = location;
|
||||||
|
updateLocationUi();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateCompassValue(float value) {
|
||||||
|
// 99 in next line used to one-time initialize arrows (with reference vs. fixed-north direction)
|
||||||
|
// on non-compass devices
|
||||||
|
float lastHeading = heading != null ? heading : 99;
|
||||||
|
heading = value;
|
||||||
|
if (Math.abs(MapUtils.degreesDiff(lastHeading, heading)) > 5) {
|
||||||
|
updateLocationUi();
|
||||||
|
} else {
|
||||||
|
heading = lastHeading;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateLocationUi() {
|
||||||
|
app.runInUIThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
updateDistanceDirection();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateDistanceDirection() {
|
||||||
|
MapActivity mapActivity = getMapActivity();
|
||||||
|
View view = overviewCard.getView();
|
||||||
|
if (mapActivity != null && view != null) {
|
||||||
|
MapContextMenu menu = mapActivity.getContextMenu();
|
||||||
|
TextView distanceText = (TextView) view.findViewById(R.id.distance);
|
||||||
|
ImageView direction = (ImageView) view.findViewById(R.id.direction);
|
||||||
|
app.getUIUtilities().updateLocationView(updateLocationViewCache, direction, distanceText, menu.getLatLon());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startLocationUpdate() {
|
||||||
|
OsmandApplication app = getMyApplication();
|
||||||
|
if (app != null && !locationUpdateStarted) {
|
||||||
|
locationUpdateStarted = true;
|
||||||
|
app.getLocationProvider().addCompassListener(this);
|
||||||
|
app.getLocationProvider().addLocationListener(this);
|
||||||
|
updateLocationUi();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopLocationUpdate() {
|
||||||
|
OsmandApplication app = getMyApplication();
|
||||||
|
if (app != null && locationUpdateStarted) {
|
||||||
|
locationUpdateStarted = false;
|
||||||
|
app.getLocationProvider().removeLocationListener(this);
|
||||||
|
app.getLocationProvider().removeCompassListener(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -429,7 +531,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
if (mapActivity == null) {
|
if (mapActivity == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (card instanceof OptionsCard) {
|
if (card instanceof OptionsCard || card instanceof OverviewCard) {
|
||||||
final GPXFile gpxFile = getGpx();
|
final GPXFile gpxFile = getGpx();
|
||||||
if (buttonIndex == SHOW_ON_MAP_BUTTON_INDEX) {
|
if (buttonIndex == SHOW_ON_MAP_BUTTON_INDEX) {
|
||||||
boolean gpxFileSelected = !isGpxFileSelected(app, gpxFile);
|
boolean gpxFileSelected = !isGpxFileSelected(app, gpxFile);
|
||||||
|
@ -561,7 +663,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateCardsLayout() {
|
/*private void updateCardsLayout() {
|
||||||
View mainView = getMainView();
|
View mainView = getMainView();
|
||||||
if (mainView != null) {
|
if (mainView != null) {
|
||||||
View topShadow = getTopShadow();
|
View topShadow = getTopShadow();
|
||||||
|
@ -574,7 +676,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
AndroidUtils.setBackground(mainView.getContext(), bottomContainer, isNightMode(), R.color.list_background_color_light, R.color.list_background_color_dark);
|
AndroidUtils.setBackground(mainView.getContext(), bottomContainer, isNightMode(), R.color.list_background_color_light, R.color.list_background_color_dark);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
private void setupButtons(View view) {
|
private void setupButtons(View view) {
|
||||||
ColorStateList navColorStateList = AndroidUtils.createBottomNavColorStateList(getContext(), isNightMode());
|
ColorStateList navColorStateList = AndroidUtils.createBottomNavColorStateList(getContext(), isNightMode());
|
||||||
|
@ -647,46 +749,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void openAnalyzeOnMap(GpxDisplayItem gpxItem, List<ILineDataSet> dataSets, GPXTabItemType tabType) {
|
public void openAnalyzeOnMap(GpxDisplayItem gpxItem) {
|
||||||
WptPt wpt = null;
|
|
||||||
gpxItem.chartTypes = null;
|
|
||||||
if (dataSets != null && dataSets.size() > 0) {
|
|
||||||
gpxItem.chartTypes = new GPXDataSetType[dataSets.size()];
|
|
||||||
for (int i = 0; i < dataSets.size(); i++) {
|
|
||||||
OrderedLineDataSet orderedDataSet = (OrderedLineDataSet) dataSets.get(i);
|
|
||||||
gpxItem.chartTypes[i] = orderedDataSet.getDataSetType();
|
|
||||||
}
|
|
||||||
if (gpxItem.chartHighlightPos != -1) {
|
|
||||||
TrkSegment segment = null;
|
|
||||||
for (Track t : gpxItem.group.getGpx().tracks) {
|
|
||||||
for (TrkSegment s : t.segments) {
|
|
||||||
if (s.points.size() > 0 && s.points.get(0).equals(gpxItem.analysis.locationStart)) {
|
|
||||||
segment = s;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (segment != null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (segment != null) {
|
|
||||||
OrderedLineDataSet dataSet = (OrderedLineDataSet) dataSets.get(0);
|
|
||||||
float distance = gpxItem.chartHighlightPos * dataSet.getDivX();
|
|
||||||
for (WptPt p : segment.points) {
|
|
||||||
if (p.distance >= distance) {
|
|
||||||
wpt = p;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (wpt != null) {
|
|
||||||
gpxItem.locationOnMap = wpt;
|
|
||||||
} else {
|
|
||||||
gpxItem.locationOnMap = gpxItem.locationStart;
|
|
||||||
}
|
|
||||||
|
|
||||||
TrackDetailsMenu trackDetailsMenu = getMapActivity().getTrackDetailsMenu();
|
TrackDetailsMenu trackDetailsMenu = getMapActivity().getTrackDetailsMenu();
|
||||||
trackDetailsMenu.setGpxItem(gpxItem);
|
trackDetailsMenu.setGpxItem(gpxItem);
|
||||||
trackDetailsMenu.show();
|
trackDetailsMenu.show();
|
||||||
|
@ -805,7 +868,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putString(TRACK_FILE_NAME, path);
|
args.putString(TRACK_FILE_NAME, path);
|
||||||
args.putBoolean(CURRENT_RECORDING, showCurrentTrack);
|
args.putBoolean(CURRENT_RECORDING, showCurrentTrack);
|
||||||
args.putInt(ContextMenuFragment.MENU_STATE_KEY, MenuState.HALF_SCREEN);
|
args.putInt(ContextMenuFragment.MENU_STATE_KEY, MenuState.HEADER_ONLY);
|
||||||
|
|
||||||
TrackMenuFragment fragment = new TrackMenuFragment();
|
TrackMenuFragment fragment = new TrackMenuFragment();
|
||||||
fragment.setArguments(args);
|
fragment.setArguments(args);
|
||||||
|
|
|
@ -2,6 +2,9 @@ package net.osmand.plus.widgets;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import net.osmand.plus.R;
|
||||||
|
|
||||||
import studio.carbonylgroup.textfieldboxes.TextFieldBoxes;
|
import studio.carbonylgroup.textfieldboxes.TextFieldBoxes;
|
||||||
|
|
||||||
|
@ -19,4 +22,11 @@ public class OsmandTextFieldBoxes extends TextFieldBoxes {
|
||||||
super(context, attrs, defStyleAttr);
|
super(context, attrs, defStyleAttr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void makeCompactPadding() {
|
||||||
|
floatingLabel.setVisibility(View.GONE);
|
||||||
|
labelSpace.setVisibility(View.GONE);
|
||||||
|
labelSpaceBelow.setVisibility(View.GONE);
|
||||||
|
int paddingH = getResources().getDimensionPixelSize(R.dimen.route_info_card_details_margin);
|
||||||
|
inputLayout.setPadding(0, paddingH, 0, paddingH);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,7 +130,7 @@ public class TravelObfHelper implements TravelHelper {
|
||||||
@Nullable
|
@Nullable
|
||||||
private TravelArticle cacheTravelArticles(File file, Amenity amenity, String lang, boolean readPoints) {
|
private TravelArticle cacheTravelArticles(File file, Amenity amenity, String lang, boolean readPoints) {
|
||||||
TravelArticle article = null;
|
TravelArticle article = null;
|
||||||
Map<String, TravelArticle> articles = readArticles(file, amenity, readPoints);
|
Map<String, TravelArticle> articles = readArticles(file, amenity, false);
|
||||||
if (!Algorithms.isEmpty(articles)) {
|
if (!Algorithms.isEmpty(articles)) {
|
||||||
TravelArticleIdentifier newArticleId = articles.values().iterator().next().generateIdentifier();
|
TravelArticleIdentifier newArticleId = articles.values().iterator().next().generateIdentifier();
|
||||||
cachedArticles.put(newArticleId, articles);
|
cachedArticles.put(newArticleId, articles);
|
||||||
|
@ -404,6 +404,9 @@ public class TravelObfHelper implements TravelHelper {
|
||||||
Map<String, WikivoyageSearchResult> headerObjs = new HashMap<>();
|
Map<String, WikivoyageSearchResult> headerObjs = new HashMap<>();
|
||||||
if (parts != null && parts.length > 0) {
|
if (parts != null && parts.length > 0) {
|
||||||
headers.addAll(Arrays.asList(parts));
|
headers.addAll(Arrays.asList(parts));
|
||||||
|
if (!Algorithms.isEmpty(article.isParentOf)) {
|
||||||
|
headers.add(title);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String header : headers) {
|
for (String header : headers) {
|
||||||
|
@ -533,8 +536,7 @@ public class TravelObfHelper implements TravelHelper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean publish(Amenity amenity) {
|
public boolean publish(Amenity amenity) {
|
||||||
if (Algorithms.stringsEqual(articleId.routeId, Algorithms.emptyIfNull(amenity.getTagContent(Amenity.ROUTE_ID, null)))
|
if (Algorithms.stringsEqual(articleId.routeId, Algorithms.emptyIfNull(amenity.getTagContent(Amenity.ROUTE_ID, null))) || isDbArticle) {
|
||||||
&& Algorithms.stringsEqual(articleId.routeSource, Algorithms.emptyIfNull(amenity.getTagContent(Amenity.ROUTE_SOURCE, null))) || isDbArticle) {
|
|
||||||
amenities.add(amenity);
|
amenities.add(amenity);
|
||||||
done = true;
|
done = true;
|
||||||
}
|
}
|
||||||
|
@ -549,7 +551,7 @@ public class TravelObfHelper implements TravelHelper {
|
||||||
|
|
||||||
if (!Double.isNaN(articleId.lat)) {
|
if (!Double.isNaN(articleId.lat)) {
|
||||||
req.setBBoxRadius(articleId.lat, articleId.lon, ARTICLE_SEARCH_RADIUS);
|
req.setBBoxRadius(articleId.lat, articleId.lon, ARTICLE_SEARCH_RADIUS);
|
||||||
if (!Algorithms.isEmpty(articleId.routeId)) {
|
if (!Algorithms.isEmpty(articleId.title)) {
|
||||||
reader.searchPoiByName(req);
|
reader.searchPoiByName(req);
|
||||||
} else {
|
} else {
|
||||||
reader.searchPoi(req);
|
reader.searchPoi(req);
|
||||||
|
|
Loading…
Reference in a new issue