commit
16708b9eef
69 changed files with 4243 additions and 1507 deletions
|
@ -449,6 +449,10 @@ public class GPXUtilities {
|
||||||
public String getArticleLang() {
|
public String getArticleLang() {
|
||||||
return getExtensionsToRead().get("article_lang");
|
return getExtensionsToRead().get("article_lang");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return getExtensionsToRead().get("desc");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Author extends GPXExtensions {
|
public static class Author extends GPXExtensions {
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class NetworkUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String sendPostDataRequest(String urlText, InputStream data) {
|
public static String sendPostDataRequest(String urlText, String formName, String fileName, InputStream data) {
|
||||||
try {
|
try {
|
||||||
log.info("POST : " + urlText);
|
log.info("POST : " + urlText);
|
||||||
HttpURLConnection conn = getHttpURLConnection(urlText);
|
HttpURLConnection conn = getHttpURLConnection(urlText);
|
||||||
|
@ -69,7 +69,7 @@ public class NetworkUtils {
|
||||||
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
|
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
|
||||||
OutputStream ous = conn.getOutputStream();
|
OutputStream ous = conn.getOutputStream();
|
||||||
ous.write(("--" + BOUNDARY + "\r\n").getBytes());
|
ous.write(("--" + BOUNDARY + "\r\n").getBytes());
|
||||||
ous.write(("content-disposition: form-data; name=\"" + "file" + "\"; filename=\"" + "image1" + "\"\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$
|
ous.write(("Content-Disposition: form-data; name=\"" + formName + "\"; filename=\"" + fileName + "\"\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
ous.write(("Content-Type: application/octet-stream\r\n\r\n").getBytes()); //$NON-NLS-1$
|
ous.write(("Content-Type: application/octet-stream\r\n\r\n").getBytes()); //$NON-NLS-1$
|
||||||
Algorithms.streamCopy(data, ous);
|
Algorithms.streamCopy(data, ous);
|
||||||
ous.write(("\r\n--" + BOUNDARY + "--\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$
|
ous.write(("\r\n--" + BOUNDARY + "--\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
|
|
@ -1222,7 +1222,7 @@ public class RouteResultPreparation {
|
||||||
// 3. calculate angle difference
|
// 3. calculate angle difference
|
||||||
// This method doesn't work if you go from S to N touching only 1 point of roundabout,
|
// 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
|
// 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);
|
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) ;
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
<string name="osmand_unlimited">OsmAnd Unlimited</string>
|
<string name="osmand_unlimited">OsmAnd Unlimited</string>
|
||||||
<string name="markers">Markers</string>
|
<string name="markers">Markers</string>
|
||||||
<string name="opr_base_url">https://test.openplacereviews.org/</string>
|
<string name="opr_base_url">https://test.openplacereviews.org/</string>
|
||||||
|
<string name="dev_opr_base_url">https://test.openplacereviews.org/</string>
|
||||||
<string name="osm_oauth_developer_key">v8G8r9NLJZGMV4he5lwbQlz620FNVARKjI9Bm5UJ</string>
|
<string name="osm_oauth_developer_key">v8G8r9NLJZGMV4he5lwbQlz620FNVARKjI9Bm5UJ</string>
|
||||||
<string name="osm_oauth_developer_secret">jDvM95Ne1Bq2BDTmIfB6b3ZMxvdK87WGfp6DC07J</string>
|
<string name="osm_oauth_developer_secret">jDvM95Ne1Bq2BDTmIfB6b3ZMxvdK87WGfp6DC07J</string>
|
||||||
<string name="osm_oauth_consumer_key">Ti2qq3fo4i4Wmuox3SiWRIGq3obZisBHnxmcM05y</string>
|
<string name="osm_oauth_consumer_key">Ti2qq3fo4i4Wmuox3SiWRIGq3obZisBHnxmcM05y</string>
|
||||||
|
|
7
OsmAnd/res/drawable/btn_border_active.xml
Normal file
7
OsmAnd/res/drawable/btn_border_active.xml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
|
||||||
|
<corners android:radius="4dp" />
|
||||||
|
<solid android:color="?attr/switch_button_active" />
|
||||||
|
</shape>
|
17
OsmAnd/res/drawable/ic_action_user_account_16.xml
Normal file
17
OsmAnd/res/drawable/ic_action_user_account_16.xml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="16dp"
|
||||||
|
android:height="16dp"
|
||||||
|
android:viewportWidth="16"
|
||||||
|
android:viewportHeight="16">
|
||||||
|
<path
|
||||||
|
android:pathData="M15,8C15,11.866 11.866,15 8,15C4.134,15 1,11.866 1,8C1,4.134 4.134,1 8,1C11.866,1 15,4.134 15,8Z"
|
||||||
|
android:strokeAlpha="0.2"
|
||||||
|
android:fillColor="#727272"
|
||||||
|
android:fillAlpha="0.2"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M4.2594,11.3179C4.5408,10.7297 5.0357,10.2524 5.6667,10C7.1567,9.3614 8.8433,9.3614 10.3334,10C10.9644,10.2524 11.4592,10.7297 11.7406,11.3179C10.8247,12.3498 9.4883,13 8,13C6.5117,13 5.1753,12.3498 4.2594,11.3179Z"
|
||||||
|
android:fillColor="#727272"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M10,6C10,7.1046 9.1046,8 8,8C6.8955,8 6,7.1046 6,6C6,4.8954 6.8955,4 8,4C9.1046,4 10,4.8954 10,6Z"
|
||||||
|
android:fillColor="#727272"/>
|
||||||
|
</vector>
|
|
@ -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="@android:id/progress">
|
<item android:id="@+id/progress">
|
||||||
<clip>
|
|
||||||
<shape android:shape="rectangle">
|
<shape android:shape="rectangle">
|
||||||
<solid
|
<solid android:color="@color/color_white" />
|
||||||
android:color="@color/profile_icon_color_blue_light" />
|
|
||||||
<corners android:radius="30dp" />
|
<corners android:radius="30dp" />
|
||||||
</shape>
|
</shape>
|
||||||
</clip>
|
|
||||||
</item>
|
</item>
|
||||||
</layer-list>
|
</layer-list>
|
|
@ -1,11 +1,12 @@
|
||||||
|
<?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>
|
||||||
|
|
|
@ -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" />
|
||||||
|
|
85
OsmAnd/res/layout/dialog_edit_gpx_description.xml
Normal file
85
OsmAnd/res/layout/dialog_edit_gpx_description.xml
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:background="?attr/card_and_list_background_basic"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
xmlns:osmand="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/action_bar_height"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/btn_close"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginStart="@dimen/card_padding"
|
||||||
|
android:layout_marginLeft="@dimen/card_padding"
|
||||||
|
android:padding="@dimen/context_menu_padding_margin_small"
|
||||||
|
android:paddingStart="@dimen/context_menu_padding_margin_small"
|
||||||
|
android:paddingEnd="@dimen/context_menu_padding_margin_small">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:layout_width="@dimen/favorites_icon_size_small"
|
||||||
|
android:layout_height="@dimen/favorites_icon_size_small"
|
||||||
|
android:tint="?attr/default_icon_color"
|
||||||
|
osmand:srcCompat="@drawable/ic_action_close" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="@dimen/card_content_padding_large"
|
||||||
|
android:layout_marginStart="@dimen/card_content_padding_large"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:text="@string/context_menu_edit_descr"
|
||||||
|
android:textColor="?attr/searchbar_text"
|
||||||
|
android:textSize="@dimen/dialog_header_text_size"
|
||||||
|
osmand:typeface="@string/font_roboto_medium" />
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/btn_save"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginRight="@dimen/content_padding_half"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding_half"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:background="@drawable/btn_border_active"
|
||||||
|
android:paddingStart="@dimen/content_padding"
|
||||||
|
android:paddingLeft="@dimen/content_padding"
|
||||||
|
android:paddingTop="@dimen/content_padding_half"
|
||||||
|
android:paddingRight="@dimen/content_padding"
|
||||||
|
android:paddingEnd="@dimen/content_padding"
|
||||||
|
android:paddingBottom="@dimen/content_padding_half"
|
||||||
|
android:text="@string/shared_string_save"
|
||||||
|
android:textColor="?attr/active_color_basic"
|
||||||
|
android:textSize="@dimen/default_desc_text_size"
|
||||||
|
osmand:typeface="@string/font_roboto_medium" />
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="?attr/divider_color" />
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.EditTextEx
|
||||||
|
android:id="@+id/description"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="@dimen/content_padding"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding"
|
||||||
|
android:layout_marginRight="@dimen/content_padding"
|
||||||
|
android:background="?attr/card_and_list_background_basic"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
|
android:textSize="@dimen/default_list_text_size"
|
||||||
|
osmand:typeface="@string/font_roboto_regular"
|
||||||
|
tools:text="Amsterdam is the Netherlands' capital and financial, cultural and creative centre with more than 850,000 inhabitants. Amsterdam is known for the canals that criss-cross the city, its impressive architecture and more than 1,500 bridges. The city has a heritage dating back to the Dutch Golden Age in the 17th century as well as a diverse art scene and a bustling nightlife." />
|
||||||
|
|
||||||
|
</LinearLayout>
|
105
OsmAnd/res/layout/dialog_read_gpx_description.xml
Normal file
105
OsmAnd/res/layout/dialog_read_gpx_description.xml
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/root"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:background="?attr/list_background_color">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/pstsTabBackground">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.Toolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/action_bar_height"
|
||||||
|
app:titleTextColor="?attr/list_background_color" />
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/ll"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:background="?attr/list_background_color">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/main_image"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
tools:visibility="visible"
|
||||||
|
tools:src="@drawable/img_help_announcement_time_day"/>
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.WebViewEx
|
||||||
|
android:id="@+id/content"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="@dimen/content_padding"
|
||||||
|
android:layout_marginStart="@dimen/content_padding"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding"
|
||||||
|
android:background="@color/color_transparent" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/divider"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="?attr/divider_color"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible"/>
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/btn_edit"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding"
|
||||||
|
android:layout_marginStart="@dimen/content_padding"
|
||||||
|
android:layout_marginTop="@dimen/context_menu_padding_margin_small"
|
||||||
|
android:layout_marginBottom="@dimen/context_menu_padding_margin_small"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:padding="@dimen/context_menu_padding_margin_small"
|
||||||
|
android:paddingStart="@dimen/context_menu_padding_margin_small"
|
||||||
|
android:paddingEnd="@dimen/context_menu_padding_margin_small"
|
||||||
|
android:drawablePadding="@dimen/list_content_padding_large"
|
||||||
|
osmand:drawableLeftCompat="@drawable/ic_action_edit_dark"
|
||||||
|
osmand:drawableStartCompat="@drawable/ic_action_edit_dark"
|
||||||
|
osmand:drawableTint="?attr/active_color_basic"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:text="@string/shared_string_edit"
|
||||||
|
android:textColor="?attr/active_color_basic"
|
||||||
|
android:textSize="@dimen/default_list_text_size"
|
||||||
|
osmand:typeface="@string/font_roboto_medium"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/bottom_empty_space"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/card_row_min_height"
|
||||||
|
android:foreground="@drawable/bg_contextmenu_shadow"
|
||||||
|
android:foregroundGravity="top|fill_horizontal"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible">
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="?attr/activity_background_basic" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
</LinearLayout>
|
121
OsmAnd/res/layout/gpx_description_preview_card.xml
Normal file
121
OsmAnd/res/layout/gpx_description_preview_card.xml
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
<?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="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:background="?attr/list_background_color">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/activity_background_basic">
|
||||||
|
|
||||||
|
<include layout="@layout/list_item_divider" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/content_padding"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding"
|
||||||
|
android:layout_marginTop="@dimen/content_padding_small"
|
||||||
|
android:layout_marginRight="@dimen/content_padding"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding"
|
||||||
|
android:text="@string/shared_string_description"
|
||||||
|
android:textColor="?android:textColorSecondary"
|
||||||
|
android:textSize="@dimen/default_desc_text_size"
|
||||||
|
osmand:typeface="@string/font_roboto_medium" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/main_image"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/content_padding_small"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
tools:visibility="visible"
|
||||||
|
tools:src="@drawable/img_help_announcement_time_day"/>
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/description"
|
||||||
|
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/context_menu_padding_margin_small"
|
||||||
|
android:layout_marginRight="@dimen/content_padding"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding"
|
||||||
|
android:textColor="?android:textColorPrimary"
|
||||||
|
android:textSize="@dimen/default_list_text_size"
|
||||||
|
android:lineSpacingMultiplier="1.1"
|
||||||
|
osmand:typeface="@string/font_roboto_regular"
|
||||||
|
tools:text="Amsterdam is the Netherlands' capital and financial, cultural and creative centre with more than 850,000 inhabitants. Amsterdam is known for the canals that criss-cross the city, its impressive architecture and more than 1,500 bridges. The city has a heritage dating back to the Dutch Golden Age in the 17th century as well as a diverse art scene and a bustling nightlife."/>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/context_menu_padding_margin_small"
|
||||||
|
android:layout_marginBottom="@dimen/context_menu_padding_margin_small"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/btn_read_full"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/context_menu_padding_margin_small"
|
||||||
|
android:layout_marginLeft="@dimen/context_menu_padding_margin_small"
|
||||||
|
android:layout_gravity="start"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:paddingStart="@dimen/bottom_sheet_content_padding_small"
|
||||||
|
android:paddingLeft="@dimen/bottom_sheet_content_padding_small"
|
||||||
|
android:paddingTop="@dimen/bottom_sheet_content_padding_small"
|
||||||
|
android:paddingRight="@dimen/bottom_sheet_content_padding_small"
|
||||||
|
android:paddingEnd="@dimen/bottom_sheet_content_padding_small"
|
||||||
|
android:paddingBottom="@dimen/bottom_sheet_content_padding_small"
|
||||||
|
android:drawablePadding="@dimen/bottom_sheet_content_padding_small"
|
||||||
|
osmand:drawableStartCompat="@drawable/ic_action_read_article"
|
||||||
|
osmand:drawableLeftCompat="@drawable/ic_action_read_article"
|
||||||
|
osmand:drawableTint="?attr/wikivoyage_active_color"
|
||||||
|
android:text="@string/context_menu_read_full"
|
||||||
|
android:textColor="?attr/wikivoyage_active_color"
|
||||||
|
android:textSize="@dimen/default_desc_text_size"
|
||||||
|
osmand:typeface="@string/font_roboto_medium" />
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/btn_edit"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginRight="@dimen/context_menu_padding_margin_small"
|
||||||
|
android:layout_marginEnd="@dimen/context_menu_padding_margin_small"
|
||||||
|
android:layout_gravity="end"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:padding="@dimen/bottom_sheet_content_padding_small"
|
||||||
|
android:paddingStart="@dimen/bottom_sheet_content_padding_small"
|
||||||
|
android:paddingEnd="@dimen/bottom_sheet_content_padding_small"
|
||||||
|
android:drawablePadding="@dimen/bottom_sheet_content_padding_small"
|
||||||
|
osmand:drawableRightCompat="@drawable/ic_action_edit_dark"
|
||||||
|
osmand:drawableEndCompat="@drawable/ic_action_edit_dark"
|
||||||
|
osmand:drawableTint="?attr/wikivoyage_active_color"
|
||||||
|
android:text="@string/shared_string_edit"
|
||||||
|
android:textColor="?attr/wikivoyage_active_color"
|
||||||
|
android:textSize="@dimen/default_desc_text_size"
|
||||||
|
osmand:typeface="@string/font_roboto_medium" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/activity_background_basic">
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/shadow"
|
||||||
|
layout="@layout/card_bottom_divider" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -2,20 +2,15 @@
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="?attr/bg_color">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/bg_color"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<com.github.mikephil.charting.charts.LineChart
|
<com.github.mikephil.charting.charts.LineChart
|
||||||
android:id="@+id/chart"
|
android:id="@+id/chart"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="150dp"
|
android:layout_height="@dimen/list_item_description_width"
|
||||||
android:layout_gravity="center_vertical" />
|
android:layout_gravity="center_vertical" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
@ -32,14 +27,14 @@
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
|
android:paddingStart="@dimen/content_padding"
|
||||||
android:paddingLeft="@dimen/content_padding"
|
android:paddingLeft="@dimen/content_padding"
|
||||||
|
android:paddingEnd="@dimen/content_padding"
|
||||||
android:paddingRight="@dimen/content_padding"
|
android:paddingRight="@dimen/content_padding"
|
||||||
android:text="@string/join_segments"
|
android:text="@string/join_segments"
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
android:textSize="@dimen/default_list_text_size"
|
android:textSize="@dimen/default_list_text_size"
|
||||||
osmand:typeface="@string/font_roboto_regular"
|
osmand:typeface="@string/font_roboto_regular" />
|
||||||
android:paddingStart="@dimen/content_padding"
|
|
||||||
android:paddingEnd="@dimen/content_padding" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.SwitchCompat
|
<androidx.appcompat.widget.SwitchCompat
|
||||||
android:id="@+id/gpx_join_gaps_switch"
|
android:id="@+id/gpx_join_gaps_switch"
|
||||||
|
@ -49,10 +44,10 @@
|
||||||
android:clickable="false"
|
android:clickable="false"
|
||||||
android:focusable="false"
|
android:focusable="false"
|
||||||
android:focusableInTouchMode="false"
|
android:focusableInTouchMode="false"
|
||||||
|
android:paddingStart="@dimen/content_padding"
|
||||||
android:paddingLeft="@dimen/content_padding"
|
android:paddingLeft="@dimen/content_padding"
|
||||||
android:paddingRight="@dimen/content_padding"
|
|
||||||
android:paddingEnd="@dimen/content_padding"
|
android:paddingEnd="@dimen/content_padding"
|
||||||
android:paddingStart="@dimen/content_padding" />
|
android:paddingRight="@dimen/content_padding" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@ -61,99 +56,99 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:paddingTop="13dp"
|
android:paddingTop="@dimen/context_menu_first_line_top_margin"
|
||||||
android:paddingBottom="11dp">
|
android:paddingBottom="@dimen/content_padding_small">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/content_padding"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding_small"
|
||||||
|
android:layout_marginRight="@dimen/content_padding_small"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:layout_height="wrap_content"
|
android:orientation="horizontal">
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingLeft="16dp"
|
|
||||||
android:paddingStart="16dp">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:id="@+id/average_icon"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="5dp"
|
|
||||||
osmand:srcCompat="@drawable/ic_action_altitude_average"/>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:layout_weight="1"
|
||||||
android:layout_marginLeft="18dp"
|
android:orientation="vertical">
|
||||||
android:layout_marginStart="18dp">
|
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
|
||||||
android:id="@+id/average_text"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@null"
|
|
||||||
tools:text="40 m"
|
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
|
||||||
osmand:typeface="@string/font_roboto_medium"
|
|
||||||
android:textSize="@dimen/default_desc_text_size"/>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/average_desc"
|
android:id="@+id/average_desc"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@null"
|
android:background="@null"
|
||||||
android:layout_marginTop="3dp"
|
|
||||||
android:text="@string/average_altitude"
|
android:text="@string/average_altitude"
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
android:textSize="@dimen/default_sub_text_size"/>
|
android:textSize="@dimen/default_desc_text_size" />
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/average_text"
|
||||||
|
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="40 m" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/average_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="@dimen/poi_icon_size"
|
||||||
|
android:layout_marginTop="@dimen/subHeaderPadding"
|
||||||
|
osmand:srcCompat="@drawable/ic_action_altitude_average" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/content_padding_small"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding_small"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding"
|
||||||
|
android:layout_marginRight="@dimen/content_padding"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal">
|
||||||
android:paddingLeft="16dp"
|
|
||||||
android:paddingStart="16dp">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:id="@+id/range_icon"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="5dp"
|
|
||||||
osmand:srcCompat="@drawable/ic_action_altitude_average"/>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:layout_weight="1"
|
||||||
android:layout_marginLeft="18dp"
|
android:orientation="vertical">
|
||||||
android:layout_marginStart="18dp">
|
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
|
||||||
android:id="@+id/range_text"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@null"
|
|
||||||
tools:text="30m - 53m"
|
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
|
||||||
osmand:typeface="@string/font_roboto_medium"
|
|
||||||
android:textSize="@dimen/default_desc_text_size"/>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/range_desc"
|
android:id="@+id/range_desc"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@null"
|
android:background="@null"
|
||||||
android:layout_marginTop="3dp"
|
|
||||||
android:text="@string/altitude_range"
|
android:text="@string/altitude_range"
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
android:textSize="@dimen/default_sub_text_size"/>
|
android:textSize="@dimen/default_desc_text_size" />
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/range_text"
|
||||||
|
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="30m - 53m" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/range_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="@dimen/poi_icon_size"
|
||||||
|
android:layout_marginTop="@dimen/subHeaderPadding"
|
||||||
|
osmand:srcCompat="@drawable/ic_action_altitude_average" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -164,140 +159,115 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingLeft="16dp"
|
|
||||||
android:paddingRight="8dp"
|
|
||||||
android:paddingStart="16dp"
|
|
||||||
android:paddingEnd="8dp">
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="1dp"
|
android:layout_height="1dp"
|
||||||
|
android:layout_marginStart="@dimen/content_padding_small"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding_small"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding_small"
|
||||||
|
android:layout_marginRight="@dimen/content_padding_small"
|
||||||
android:background="?attr/dashboard_divider" />
|
android:background="?attr/dashboard_divider" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingLeft="8dp"
|
|
||||||
android:paddingRight="16dp"
|
|
||||||
android:paddingStart="8dp"
|
|
||||||
android:paddingEnd="16dp">
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="1dp"
|
|
||||||
android:background="?attr/dashboard_divider"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/ascent_descent"
|
android:id="@+id/ascent_descent"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:paddingTop="13dp"
|
android:paddingTop="@dimen/context_menu_first_line_top_margin"
|
||||||
android:paddingBottom="11dp">
|
android:paddingBottom="@dimen/content_padding_small">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/content_padding"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding_small"
|
||||||
|
android:layout_marginRight="@dimen/content_padding_small"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:layout_height="wrap_content"
|
android:orientation="horizontal">
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingLeft="16dp"
|
|
||||||
android:paddingStart="16dp">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:id="@+id/ascent_icon"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="5dp"
|
|
||||||
osmand:srcCompat="@drawable/ic_action_altitude_ascent"/>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:layout_weight="1"
|
||||||
android:layout_marginLeft="18dp"
|
android:orientation="vertical">
|
||||||
android:layout_marginStart="18dp">
|
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
|
||||||
android:id="@+id/ascent_text"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@null"
|
|
||||||
tools:text="174"
|
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
|
||||||
osmand:typeface="@string/font_roboto_medium"
|
|
||||||
android:textSize="@dimen/default_desc_text_size"/>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/ascent_desc"
|
android:id="@+id/ascent_desc"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@null"
|
android:background="@null"
|
||||||
android:layout_marginTop="3dp"
|
|
||||||
android:text="@string/altitude_ascent"
|
android:text="@string/altitude_ascent"
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
android:textSize="@dimen/default_sub_text_size"/>
|
android:textSize="@dimen/default_desc_text_size" />
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/ascent_text"
|
||||||
|
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="174" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/ascent_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="@dimen/poi_icon_size"
|
||||||
|
android:layout_marginTop="@dimen/subHeaderPadding"
|
||||||
|
osmand:srcCompat="@drawable/ic_action_altitude_ascent" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/content_padding"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding_small"
|
||||||
|
android:layout_marginRight="@dimen/content_padding_small"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal">
|
||||||
android:paddingLeft="16dp"
|
|
||||||
android:paddingStart="16dp">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:id="@+id/descent_icon"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="5dp"
|
|
||||||
osmand:srcCompat="@drawable/ic_action_altitude_descent"/>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:layout_weight="1"
|
||||||
android:layout_marginLeft="18dp"
|
android:orientation="vertical">
|
||||||
android:layout_marginStart="18dp">
|
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
|
||||||
android:id="@+id/descent_text"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@null"
|
|
||||||
tools:text="164"
|
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
|
||||||
osmand:typeface="@string/font_roboto_medium"
|
|
||||||
android:textSize="@dimen/default_desc_text_size"/>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/descent_desc"
|
android:id="@+id/descent_desc"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@null"
|
android:background="@null"
|
||||||
android:layout_marginTop="3dp"
|
|
||||||
android:text="@string/altitude_descent"
|
android:text="@string/altitude_descent"
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
android:textSize="@dimen/default_sub_text_size"/>
|
android:textSize="@dimen/default_desc_text_size" />
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/descent_text"
|
||||||
|
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="164" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/descent_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="@dimen/poi_icon_size"
|
||||||
|
android:layout_marginTop="@dimen/subHeaderPadding"
|
||||||
|
osmand:srcCompat="@drawable/ic_action_altitude_descent" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -311,57 +281,40 @@
|
||||||
android:id="@+id/details_view"
|
android:id="@+id/details_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="48dp"
|
android:layout_height="48dp"
|
||||||
android:orientation="horizontal"
|
android:gravity="center"
|
||||||
android:gravity="center">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:visibility="gone"
|
|
||||||
tools:visibility="visible"
|
|
||||||
android:id="@+id/overflow_menu"
|
|
||||||
android:background="@null"
|
|
||||||
android:paddingRight="16dp"
|
|
||||||
android:paddingLeft="16dp"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:src="@drawable/ic_overflow_menu_dark"
|
|
||||||
android:paddingStart="16dp"
|
|
||||||
android:paddingEnd="16dp" />
|
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
android:background="?attr/selectableItemBackground"
|
|
||||||
android:id="@+id/split_interval"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:paddingLeft="16dp"
|
|
||||||
android:paddingRight="16dp"
|
|
||||||
android:gravity="start|center_vertical"
|
|
||||||
android:textColor="?attr/color_dialog_buttons"
|
|
||||||
android:textSize="@dimen/default_sub_text_size"
|
|
||||||
osmand:textAllCapsCompat="true"
|
|
||||||
osmand:typeface="@string/font_roboto_medium"
|
|
||||||
android:text="@string/gpx_split_interval"
|
|
||||||
android:paddingEnd="16dp"
|
|
||||||
android:paddingStart="16dp" />
|
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
|
||||||
android:background="?attr/selectableItemBackground"
|
|
||||||
android:id="@+id/analyze_on_map"
|
android:id="@+id/analyze_on_map"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:paddingLeft="16dp"
|
android:layout_weight="1"
|
||||||
android:paddingRight="16dp"
|
android:background="?attr/selectableItemBackground"
|
||||||
android:gravity="end|center_vertical"
|
android:gravity="start|center_vertical"
|
||||||
android:textColor="?attr/color_dialog_buttons"
|
android:paddingStart="@dimen/content_padding"
|
||||||
android:textSize="@dimen/default_sub_text_size"
|
android:paddingLeft="@dimen/content_padding"
|
||||||
osmand:textAllCapsCompat="true"
|
android:paddingEnd="@dimen/content_padding"
|
||||||
osmand:typeface="@string/font_roboto_medium"
|
android:paddingRight="@dimen/content_padding"
|
||||||
android:text="@string/analyze_on_map"
|
android:text="@string/analyze_on_map"
|
||||||
android:paddingEnd="16dp"
|
android:textColor="?attr/color_dialog_buttons"
|
||||||
android:paddingStart="16dp" />
|
android:textSize="@dimen/default_list_text_size"
|
||||||
|
osmand:typeface="@string/font_roboto_regular" />
|
||||||
</LinearLayout>
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/overflow_menu"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:gravity="end|center_vertical"
|
||||||
|
android:paddingStart="@dimen/content_padding"
|
||||||
|
android:paddingLeft="@dimen/content_padding"
|
||||||
|
android:paddingEnd="@dimen/content_padding"
|
||||||
|
android:paddingRight="@dimen/content_padding"
|
||||||
|
android:text="@string/shared_string_options"
|
||||||
|
android:textColor="?attr/color_dialog_buttons"
|
||||||
|
android:textSize="@dimen/default_list_text_size"
|
||||||
|
osmand:typeface="@string/font_roboto_regular" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
|
@ -2,20 +2,15 @@
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="?attr/bg_color">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/bg_color"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<com.github.mikephil.charting.charts.LineChart
|
<com.github.mikephil.charting.charts.LineChart
|
||||||
android:id="@+id/chart"
|
android:id="@+id/chart"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="150dp"
|
android:layout_height="@dimen/list_item_description_width"
|
||||||
android:layout_gravity="center_vertical" />
|
android:layout_gravity="center_vertical" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
@ -32,14 +27,14 @@
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
|
android:paddingStart="@dimen/content_padding"
|
||||||
android:paddingLeft="@dimen/content_padding"
|
android:paddingLeft="@dimen/content_padding"
|
||||||
|
android:paddingEnd="@dimen/content_padding"
|
||||||
android:paddingRight="@dimen/content_padding"
|
android:paddingRight="@dimen/content_padding"
|
||||||
android:text="@string/join_segments"
|
android:text="@string/join_segments"
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
android:textSize="@dimen/default_list_text_size"
|
android:textSize="@dimen/default_list_text_size"
|
||||||
osmand:typeface="@string/font_roboto_regular"
|
osmand:typeface="@string/font_roboto_regular" />
|
||||||
android:paddingStart="@dimen/content_padding"
|
|
||||||
android:paddingEnd="@dimen/content_padding" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.SwitchCompat
|
<androidx.appcompat.widget.SwitchCompat
|
||||||
android:id="@+id/gpx_join_gaps_switch"
|
android:id="@+id/gpx_join_gaps_switch"
|
||||||
|
@ -49,10 +44,10 @@
|
||||||
android:clickable="false"
|
android:clickable="false"
|
||||||
android:focusable="false"
|
android:focusable="false"
|
||||||
android:focusableInTouchMode="false"
|
android:focusableInTouchMode="false"
|
||||||
android:paddingLeft="@dimen/content_padding"
|
|
||||||
android:paddingRight="@dimen/content_padding"
|
|
||||||
android:paddingStart="@dimen/content_padding"
|
android:paddingStart="@dimen/content_padding"
|
||||||
android:paddingEnd="@dimen/content_padding" />
|
android:paddingLeft="@dimen/content_padding"
|
||||||
|
android:paddingEnd="@dimen/content_padding"
|
||||||
|
android:paddingRight="@dimen/content_padding" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@ -61,99 +56,99 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:paddingTop="13dp"
|
android:paddingTop="@dimen/context_menu_first_line_top_margin"
|
||||||
android:paddingBottom="11dp">
|
android:paddingBottom="@dimen/content_padding">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/content_padding"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding_small"
|
||||||
|
android:layout_marginRight="@dimen/content_padding_small"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:layout_height="wrap_content"
|
android:orientation="horizontal">
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingLeft="16dp"
|
|
||||||
android:paddingStart="16dp">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:id="@+id/distance_icon"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="5dp"
|
|
||||||
osmand:srcCompat="@drawable/ic_action_polygom_dark"/>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:layout_weight="1"
|
||||||
android:layout_marginLeft="18dp"
|
android:orientation="vertical">
|
||||||
android:layout_marginStart="18dp">
|
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
|
||||||
android:id="@+id/distance_text"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@null"
|
|
||||||
tools:text="40 km"
|
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
|
||||||
osmand:typeface="@string/font_roboto_medium"
|
|
||||||
android:textSize="@dimen/default_desc_text_size"/>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/distance_desc"
|
android:id="@+id/distance_desc"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@null"
|
android:background="@null"
|
||||||
android:layout_marginTop="3dp"
|
|
||||||
android:text="@string/distance"
|
android:text="@string/distance"
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
android:textSize="@dimen/default_sub_text_size"/>
|
android:textSize="@dimen/default_desc_text_size" />
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/distance_text"
|
||||||
|
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="40 km" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/distance_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="@dimen/poi_icon_size"
|
||||||
|
android:layout_marginTop="@dimen/subHeaderPadding"
|
||||||
|
osmand:srcCompat="@drawable/ic_action_distance_16" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/content_padding"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding_small"
|
||||||
|
android:layout_marginRight="@dimen/content_padding_small"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal">
|
||||||
android:paddingLeft="16dp"
|
|
||||||
android:paddingStart="16dp">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:id="@+id/duration_icon"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="5dp"
|
|
||||||
osmand:srcCompat="@drawable/ic_action_time_start"/>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:layout_weight="1"
|
||||||
android:layout_marginLeft="18dp"
|
android:orientation="vertical">
|
||||||
android:layout_marginStart="18dp">
|
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
|
||||||
android:id="@+id/duration_text"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@null"
|
|
||||||
tools:text="3:32:44"
|
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
|
||||||
osmand:typeface="@string/font_roboto_medium"
|
|
||||||
android:textSize="@dimen/default_desc_text_size"/>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/duration_desc"
|
android:id="@+id/duration_desc"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@null"
|
android:background="@null"
|
||||||
android:layout_marginTop="3dp"
|
|
||||||
android:text="@string/shared_string_time_span"
|
android:text="@string/shared_string_time_span"
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
android:textSize="@dimen/default_sub_text_size"/>
|
android:textSize="@dimen/default_desc_text_size" />
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/duration_text"
|
||||||
|
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="3:32:44" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/duration_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="@dimen/poi_icon_size"
|
||||||
|
android:layout_marginTop="@dimen/subHeaderPadding"
|
||||||
|
osmand:srcCompat="@drawable/ic_action_time_span_16" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -164,158 +159,133 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingLeft="@dimen/content_padding"
|
|
||||||
android:paddingRight="@dimen/content_padding_half"
|
|
||||||
android:paddingStart="@dimen/content_padding"
|
|
||||||
android:paddingEnd="@dimen/content_padding_half">
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="1dp"
|
android:layout_height="1dp"
|
||||||
|
android:layout_marginStart="@dimen/content_padding_small"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding_small"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding_small"
|
||||||
|
android:layout_marginRight="@dimen/content_padding_small"
|
||||||
android:background="?attr/dashboard_divider" />
|
android:background="?attr/dashboard_divider" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingLeft="@dimen/content_padding_half"
|
|
||||||
android:paddingRight="@dimen/content_padding"
|
|
||||||
android:paddingEnd="@dimen/content_padding"
|
|
||||||
android:paddingStart="@dimen/content_padding_half">
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="1dp"
|
|
||||||
android:background="?attr/dashboard_divider"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/start_end_time"
|
android:id="@+id/start_end_time"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:paddingTop="13dp"
|
android:paddingTop="@dimen/context_menu_first_line_top_margin"
|
||||||
android:paddingBottom="11dp">
|
android:paddingBottom="@dimen/content_padding_small">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/content_padding"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding_small"
|
||||||
|
android:layout_marginRight="@dimen/content_padding_small"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:layout_height="wrap_content"
|
android:orientation="horizontal">
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingLeft="@dimen/content_padding"
|
|
||||||
android:paddingStart="@dimen/content_padding">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:id="@+id/start_time_icon"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="5dp"
|
|
||||||
osmand:srcCompat="@drawable/ic_action_time_start"/>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:layout_weight="1"
|
||||||
android:layout_marginLeft="18dp"
|
android:orientation="vertical">
|
||||||
android:layout_marginStart="18dp">
|
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
|
||||||
android:id="@+id/start_time_text"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@null"
|
|
||||||
tools:text="15:04:58"
|
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
|
||||||
osmand:typeface="@string/font_roboto_medium"
|
|
||||||
android:textSize="@dimen/default_desc_text_size"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/start_date_text"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@null"
|
|
||||||
tools:text="Aug 8, 2016"
|
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
|
||||||
android:textSize="@dimen/default_desc_text_size"/>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/start_time_desc"
|
android:id="@+id/start_time_desc"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@null"
|
android:background="@null"
|
||||||
android:layout_marginTop="@dimen/content_padding_half"
|
|
||||||
android:text="@string/shared_string_start_time"
|
android:text="@string/shared_string_start_time"
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
android:textSize="@dimen/default_sub_text_size"/>
|
android:textSize="@dimen/default_desc_text_size" />
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/start_time_text"
|
||||||
|
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="15:04:58" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/start_date_text"
|
||||||
|
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="Aug 8, 2016" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/start_time_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="@dimen/poi_icon_size"
|
||||||
|
android:layout_marginTop="@dimen/subHeaderPadding"
|
||||||
|
osmand:srcCompat="@drawable/ic_action_time_start_16" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/content_padding"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding_small"
|
||||||
|
android:layout_marginRight="@dimen/content_padding_small"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal">
|
||||||
android:paddingLeft="@dimen/content_padding"
|
|
||||||
android:paddingStart="@dimen/content_padding">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:id="@+id/end_time_icon"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="5dp"
|
|
||||||
osmand:srcCompat="@drawable/ic_action_time_start"/>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:layout_weight="1"
|
||||||
android:layout_marginLeft="18dp"
|
android:orientation="vertical">
|
||||||
android:layout_marginStart="18dp">
|
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
|
||||||
android:id="@+id/end_time_text"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@null"
|
|
||||||
tools:text="20:58:00"
|
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
|
||||||
osmand:typeface="@string/font_roboto_medium"
|
|
||||||
android:textSize="@dimen/default_desc_text_size"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/end_date_text"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@null"
|
|
||||||
tools:text="Aug 8, 2016"
|
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
|
||||||
android:textSize="@dimen/default_desc_text_size"/>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/end_time_desc"
|
android:id="@+id/end_time_desc"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@null"
|
android:background="@null"
|
||||||
android:layout_marginTop="@dimen/content_padding_half"
|
|
||||||
android:text="@string/shared_string_end_time"
|
android:text="@string/shared_string_end_time"
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
android:textSize="@dimen/default_sub_text_size"/>
|
android:textSize="@dimen/default_desc_text_size" />
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/end_time_text"
|
||||||
|
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="20:58:00" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/end_date_text"
|
||||||
|
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="Aug 8, 2016" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/end_time_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="@dimen/poi_icon_size"
|
||||||
|
android:layout_marginTop="@dimen/subHeaderPadding"
|
||||||
|
osmand:srcCompat="@drawable/ic_action_time_end_16" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -329,57 +299,40 @@
|
||||||
android:id="@+id/details_view"
|
android:id="@+id/details_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="48dp"
|
android:layout_height="48dp"
|
||||||
android:orientation="horizontal"
|
android:gravity="center"
|
||||||
android:gravity="center">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:visibility="gone"
|
|
||||||
tools:visibility="visible"
|
|
||||||
android:id="@+id/overflow_menu"
|
|
||||||
android:background="@null"
|
|
||||||
android:paddingRight="@dimen/content_padding"
|
|
||||||
android:paddingLeft="@dimen/content_padding"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:src="@drawable/ic_overflow_menu_dark"
|
|
||||||
android:paddingStart="@dimen/content_padding"
|
|
||||||
android:paddingEnd="@dimen/content_padding" />
|
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
android:background="?attr/selectableItemBackground"
|
|
||||||
android:id="@+id/split_interval"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:paddingLeft="@dimen/content_padding"
|
|
||||||
android:paddingRight="@dimen/content_padding"
|
|
||||||
android:gravity="start|center_vertical"
|
|
||||||
android:textColor="?attr/color_dialog_buttons"
|
|
||||||
android:textSize="@dimen/default_sub_text_size"
|
|
||||||
osmand:textAllCapsCompat="true"
|
|
||||||
osmand:typeface="@string/font_roboto_medium"
|
|
||||||
android:text="@string/gpx_split_interval"
|
|
||||||
android:paddingEnd="@dimen/content_padding"
|
|
||||||
android:paddingStart="@dimen/content_padding" />
|
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
|
||||||
android:background="?attr/selectableItemBackground"
|
|
||||||
android:id="@+id/analyze_on_map"
|
android:id="@+id/analyze_on_map"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:gravity="start|center_vertical"
|
||||||
|
android:paddingStart="@dimen/content_padding"
|
||||||
android:paddingLeft="@dimen/content_padding"
|
android:paddingLeft="@dimen/content_padding"
|
||||||
android:paddingRight="@dimen/content_padding"
|
|
||||||
android:gravity="end|center_vertical"
|
|
||||||
android:textColor="?attr/color_dialog_buttons"
|
|
||||||
android:textSize="@dimen/default_sub_text_size"
|
|
||||||
osmand:textAllCapsCompat="true"
|
|
||||||
osmand:typeface="@string/font_roboto_medium"
|
|
||||||
android:text="@string/analyze_on_map"
|
|
||||||
android:paddingEnd="@dimen/content_padding"
|
android:paddingEnd="@dimen/content_padding"
|
||||||
android:paddingStart="@dimen/content_padding" />
|
android:paddingRight="@dimen/content_padding"
|
||||||
|
android:text="@string/analyze_on_map"
|
||||||
</LinearLayout>
|
android:textColor="?attr/color_dialog_buttons"
|
||||||
|
android:textSize="@dimen/default_list_text_size"
|
||||||
|
osmand:typeface="@string/font_roboto_regular" />
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/overflow_menu"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:gravity="end|center_vertical"
|
||||||
|
android:paddingStart="@dimen/content_padding"
|
||||||
|
android:paddingLeft="@dimen/content_padding"
|
||||||
|
android:paddingEnd="@dimen/content_padding"
|
||||||
|
android:paddingRight="@dimen/content_padding"
|
||||||
|
android:text="@string/shared_string_options"
|
||||||
|
android:textColor="?attr/color_dialog_buttons"
|
||||||
|
android:textSize="@dimen/default_list_text_size"
|
||||||
|
osmand:typeface="@string/font_roboto_regular" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
|
@ -2,14 +2,9 @@
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="?attr/bg_color">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/bg_color"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<com.github.mikephil.charting.charts.LineChart
|
<com.github.mikephil.charting.charts.LineChart
|
||||||
|
@ -32,14 +27,14 @@
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
|
android:paddingStart="@dimen/content_padding"
|
||||||
android:paddingLeft="@dimen/content_padding"
|
android:paddingLeft="@dimen/content_padding"
|
||||||
|
android:paddingEnd="@dimen/content_padding"
|
||||||
android:paddingRight="@dimen/content_padding"
|
android:paddingRight="@dimen/content_padding"
|
||||||
android:text="@string/join_segments"
|
android:text="@string/join_segments"
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
android:textSize="@dimen/default_list_text_size"
|
android:textSize="@dimen/default_list_text_size"
|
||||||
osmand:typeface="@string/font_roboto_regular"
|
osmand:typeface="@string/font_roboto_regular" />
|
||||||
android:paddingStart="@dimen/content_padding"
|
|
||||||
android:paddingEnd="@dimen/content_padding" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.SwitchCompat
|
<androidx.appcompat.widget.SwitchCompat
|
||||||
android:id="@+id/gpx_join_gaps_switch"
|
android:id="@+id/gpx_join_gaps_switch"
|
||||||
|
@ -49,10 +44,10 @@
|
||||||
android:clickable="false"
|
android:clickable="false"
|
||||||
android:focusable="false"
|
android:focusable="false"
|
||||||
android:focusableInTouchMode="false"
|
android:focusableInTouchMode="false"
|
||||||
android:paddingLeft="@dimen/content_padding"
|
|
||||||
android:paddingRight="@dimen/content_padding"
|
|
||||||
android:paddingStart="@dimen/content_padding"
|
android:paddingStart="@dimen/content_padding"
|
||||||
android:paddingEnd="@dimen/content_padding" />
|
android:paddingLeft="@dimen/content_padding"
|
||||||
|
android:paddingEnd="@dimen/content_padding"
|
||||||
|
android:paddingRight="@dimen/content_padding" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@ -66,94 +61,94 @@
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/content_padding"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding_small"
|
||||||
|
android:layout_marginRight="@dimen/content_padding_small"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:layout_height="wrap_content"
|
android:orientation="horizontal">
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingLeft="@dimen/content_padding"
|
|
||||||
android:paddingStart="@dimen/content_padding">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:id="@+id/average_icon"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="5dp"
|
|
||||||
osmand:srcCompat="@drawable/ic_action_speed"/>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:layout_weight="1"
|
||||||
android:layout_marginLeft="18dp"
|
android:orientation="vertical">
|
||||||
android:layout_marginStart="18dp">
|
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
|
||||||
android:id="@+id/average_text"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@null"
|
|
||||||
tools:text="6.8 km/h"
|
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
|
||||||
osmand:typeface="@string/font_roboto_medium"
|
|
||||||
android:textSize="@dimen/default_desc_text_size"/>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/average_desc"
|
android:id="@+id/average_desc"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@null"
|
android:background="@null"
|
||||||
android:layout_marginTop="3dp"
|
|
||||||
android:text="@string/average_speed"
|
android:text="@string/average_speed"
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
android:textSize="@dimen/default_sub_text_size"/>
|
android:textSize="@dimen/default_desc_text_size" />
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/average_text"
|
||||||
|
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="6.8 km/h" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/average_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="@dimen/poi_icon_size"
|
||||||
|
android:layout_marginTop="2dp"
|
||||||
|
osmand:srcCompat="@drawable/ic_action_speed" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/content_padding_small"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding_small"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding"
|
||||||
|
android:layout_marginRight="@dimen/content_padding"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal">
|
||||||
android:paddingLeft="@dimen/content_padding"
|
|
||||||
android:paddingStart="@dimen/content_padding">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:id="@+id/max_icon"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="5dp"
|
|
||||||
osmand:srcCompat="@drawable/ic_action_max_speed"/>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:layout_weight="1"
|
||||||
android:layout_marginLeft="18dp"
|
android:orientation="vertical">
|
||||||
android:layout_marginStart="18dp">
|
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
|
||||||
android:id="@+id/max_text"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@null"
|
|
||||||
tools:text="31.3 km/h"
|
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
|
||||||
osmand:typeface="@string/font_roboto_medium"
|
|
||||||
android:textSize="@dimen/default_desc_text_size"/>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/max_desc"
|
android:id="@+id/max_desc"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@null"
|
android:background="@null"
|
||||||
android:layout_marginTop="3dp"
|
|
||||||
android:text="@string/max_speed"
|
android:text="@string/max_speed"
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
android:textSize="@dimen/default_sub_text_size"/>
|
android:textSize="@dimen/default_desc_text_size" />
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/max_text"
|
||||||
|
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="31.3 km/h" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/max_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="@dimen/poi_icon_size"
|
||||||
|
android:layout_marginTop="2dp"
|
||||||
|
osmand:srcCompat="@drawable/ic_action_max_speed_16" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -164,41 +159,17 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingLeft="@dimen/content_padding"
|
|
||||||
android:paddingRight="@dimen/content_padding_half"
|
|
||||||
android:paddingStart="@dimen/content_padding"
|
|
||||||
android:paddingEnd="@dimen/content_padding_half">
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="1dp"
|
android:layout_height="1dp"
|
||||||
|
android:layout_marginStart="@dimen/content_padding_small"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding_small"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding_small"
|
||||||
|
android:layout_marginRight="@dimen/content_padding_small"
|
||||||
android:background="?attr/dashboard_divider" />
|
android:background="?attr/dashboard_divider" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingLeft="@dimen/content_padding_half"
|
|
||||||
android:paddingRight="@dimen/content_padding"
|
|
||||||
android:paddingEnd="@dimen/content_padding"
|
|
||||||
android:paddingStart="@dimen/content_padding_half">
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="1dp"
|
|
||||||
android:background="?attr/dashboard_divider"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/time_distance"
|
android:id="@+id/time_distance"
|
||||||
|
@ -210,94 +181,95 @@
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/content_padding"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding_small"
|
||||||
|
android:layout_marginRight="@dimen/content_padding_small"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:layout_height="wrap_content"
|
android:orientation="horizontal">
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingLeft="@dimen/content_padding"
|
|
||||||
android:paddingStart="@dimen/content_padding">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:id="@+id/time_moving_icon"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="5dp"
|
|
||||||
osmand:srcCompat="@drawable/ic_action_time_span"/>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:layout_weight="1"
|
||||||
android:layout_marginLeft="18dp"
|
android:orientation="vertical">
|
||||||
android:layout_marginStart="18dp">
|
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
|
||||||
android:id="@+id/time_moving_text"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@null"
|
|
||||||
tools:text="174"
|
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
|
||||||
osmand:typeface="@string/font_roboto_medium"
|
|
||||||
android:textSize="@dimen/default_desc_text_size"/>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/time_moving_desc"
|
android:id="@+id/time_moving_desc"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@null"
|
android:background="@null"
|
||||||
android:layout_marginTop="3dp"
|
|
||||||
android:text="@string/shared_string_time_moving"
|
android:text="@string/shared_string_time_moving"
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
android:textSize="@dimen/default_sub_text_size"/>
|
android:textSize="@dimen/default_desc_text_size" />
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/time_moving_text"
|
||||||
|
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="174" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/time_moving_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="@dimen/poi_icon_size"
|
||||||
|
android:layout_marginTop="2dp"
|
||||||
|
osmand:srcCompat="@drawable/ic_action_time_span" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/content_padding"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding_small"
|
||||||
|
android:layout_marginRight="@dimen/content_padding_small"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal">
|
||||||
android:paddingLeft="@dimen/content_padding"
|
|
||||||
android:paddingStart="@dimen/content_padding">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:id="@+id/distance_icon"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="5dp"
|
|
||||||
osmand:srcCompat="@drawable/ic_action_polygom_dark"/>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:layout_weight="1"
|
||||||
android:layout_marginLeft="18dp"
|
android:orientation="vertical">
|
||||||
android:layout_marginStart="18dp">
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/distance_desc"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="3dp"
|
||||||
|
android:background="@null"
|
||||||
|
android:text="@string/distance_moving"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
|
android:textSize="@dimen/default_desc_text_size" />
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
android:id="@+id/distance_text"
|
android:id="@+id/distance_text"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@null"
|
android:background="@null"
|
||||||
tools:text="42 km"
|
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
|
android:textSize="@dimen/default_desc_text_size"
|
||||||
osmand:typeface="@string/font_roboto_medium"
|
osmand:typeface="@string/font_roboto_medium"
|
||||||
android:textSize="@dimen/default_desc_text_size"/>
|
tools:text="42 km" />
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/distance_desc"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@null"
|
|
||||||
android:layout_marginTop="3dp"
|
|
||||||
android:text="@string/distance_moving"
|
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
|
||||||
android:textSize="@dimen/default_sub_text_size"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/distance_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="@dimen/poi_icon_size"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
osmand:srcCompat="@drawable/ic_action_polygom_dark" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -311,57 +283,40 @@
|
||||||
android:id="@+id/details_view"
|
android:id="@+id/details_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="48dp"
|
android:layout_height="48dp"
|
||||||
android:orientation="horizontal"
|
android:gravity="center"
|
||||||
android:gravity="center">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:visibility="gone"
|
|
||||||
tools:visibility="visible"
|
|
||||||
android:id="@+id/overflow_menu"
|
|
||||||
android:background="@null"
|
|
||||||
android:paddingRight="@dimen/content_padding"
|
|
||||||
android:paddingLeft="@dimen/content_padding"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:src="@drawable/ic_overflow_menu_dark"
|
|
||||||
android:paddingStart="@dimen/content_padding"
|
|
||||||
android:paddingEnd="@dimen/content_padding" />
|
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
android:background="?attr/selectableItemBackground"
|
|
||||||
android:id="@+id/split_interval"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:paddingLeft="@dimen/content_padding"
|
|
||||||
android:paddingRight="@dimen/content_padding"
|
|
||||||
android:gravity="start|center_vertical"
|
|
||||||
android:textColor="?attr/color_dialog_buttons"
|
|
||||||
android:textSize="@dimen/default_sub_text_size"
|
|
||||||
osmand:textAllCapsCompat="true"
|
|
||||||
osmand:typeface="@string/font_roboto_medium"
|
|
||||||
android:text="@string/gpx_split_interval"
|
|
||||||
android:paddingStart="@dimen/content_padding"
|
|
||||||
android:paddingEnd="@dimen/content_padding" />
|
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
|
||||||
android:background="?attr/selectableItemBackground"
|
|
||||||
android:id="@+id/analyze_on_map"
|
android:id="@+id/analyze_on_map"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:paddingLeft="@dimen/content_padding"
|
android:layout_weight="1"
|
||||||
android:paddingRight="@dimen/content_padding"
|
android:background="?attr/selectableItemBackground"
|
||||||
android:gravity="end|center_vertical"
|
android:gravity="start|center_vertical"
|
||||||
android:textColor="?attr/color_dialog_buttons"
|
|
||||||
android:textSize="@dimen/default_sub_text_size"
|
|
||||||
osmand:textAllCapsCompat="true"
|
|
||||||
osmand:typeface="@string/font_roboto_medium"
|
|
||||||
android:text="@string/analyze_on_map"
|
|
||||||
android:paddingStart="@dimen/content_padding"
|
android:paddingStart="@dimen/content_padding"
|
||||||
android:paddingEnd="@dimen/content_padding" />
|
android:paddingLeft="@dimen/content_padding"
|
||||||
|
android:paddingEnd="@dimen/content_padding"
|
||||||
</LinearLayout>
|
android:paddingRight="@dimen/content_padding"
|
||||||
|
android:text="@string/analyze_on_map"
|
||||||
|
android:textColor="?attr/color_dialog_buttons"
|
||||||
|
android:textSize="@dimen/default_list_text_size"
|
||||||
|
osmand:typeface="@string/font_roboto_regular" />
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/overflow_menu"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:gravity="end|center_vertical"
|
||||||
|
android:paddingStart="@dimen/content_padding"
|
||||||
|
android:paddingLeft="@dimen/content_padding"
|
||||||
|
android:paddingEnd="@dimen/content_padding"
|
||||||
|
android:paddingRight="@dimen/content_padding"
|
||||||
|
android:text="@string/shared_string_options"
|
||||||
|
android:textColor="?attr/color_dialog_buttons"
|
||||||
|
android:textSize="@dimen/default_list_text_size"
|
||||||
|
osmand:typeface="@string/font_roboto_regular" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
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>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/control_buttons"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<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
|
<include
|
||||||
layout="@layout/bottom_buttons"
|
layout="@layout/bottom_buttons"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/dialog_button_ex_height" />
|
android:layout_height="@dimen/dialog_button_ex_height"
|
||||||
|
android:layout_gravity="bottom" />
|
||||||
|
|
||||||
</LinearLayout>
|
</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>
|
|
@ -1,6 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/search_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="56dp"
|
android:layout_height="56dp"
|
||||||
android:focusableInTouchMode="true"
|
android:focusableInTouchMode="true"
|
||||||
|
|
|
@ -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,6 +72,7 @@
|
||||||
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"
|
||||||
|
android:visibility="gone"
|
||||||
tools:text="@string/amenity_type_finance" />
|
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" />
|
||||||
|
|
||||||
|
@ -116,6 +118,79 @@
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:id="@+id/context_menu_toolbar_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:alpha="0">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.Toolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/actionModeBackground"
|
||||||
|
android:minHeight="@dimen/toolbar_height"
|
||||||
|
android:padding="0dp"
|
||||||
|
osmand:contentInsetEnd="0dp"
|
||||||
|
osmand:contentInsetLeft="0dp"
|
||||||
|
osmand:contentInsetRight="0dp"
|
||||||
|
osmand:contentInsetStart="0dp"
|
||||||
|
osmand:theme="@style/ThemeOverlay.AppCompat.ActionBar">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:minHeight="@dimen/toolbar_height">
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/close_button"
|
||||||
|
style="@style/Widget.AppCompat.Toolbar.Button.Navigation"
|
||||||
|
android:layout_width="@dimen/toolbar_height"
|
||||||
|
android:layout_height="@dimen/toolbar_height"
|
||||||
|
android:contentDescription="@string/access_shared_string_navigate_up"
|
||||||
|
osmand:srcCompat="@drawable/ic_arrow_back" />
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/toolbar_title"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/content_padding"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding"
|
||||||
|
android:layout_marginRight="@dimen/content_padding"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:letterSpacing="@dimen/text_button_letter_spacing"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:textColor="?attr/app_bar_primary_item_color"
|
||||||
|
android:textSize="@dimen/dialog_header_text_size"
|
||||||
|
osmand:typeface="@string/font_roboto_medium"
|
||||||
|
tools:text="@string/routing_settings_2" />
|
||||||
|
|
||||||
|
<include
|
||||||
|
layout="@layout/search_text_layout"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/search_button"
|
||||||
|
style="@style/Widget.AppCompat.Toolbar.Button.Navigation"
|
||||||
|
android:layout_width="@dimen/toolbar_height"
|
||||||
|
android:layout_height="@dimen/toolbar_height"
|
||||||
|
android:contentDescription="@string/access_shared_string_navigate_up"
|
||||||
|
android:visibility="gone"
|
||||||
|
osmand:srcCompat="@drawable/ic_action_search_dark" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</androidx.appcompat.widget.Toolbar>
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
<com.google.android.material.bottomnavigation.BottomNavigationView
|
<com.google.android.material.bottomnavigation.BottomNavigationView
|
||||||
android:id="@+id/bottom_navigation"
|
android:id="@+id/bottom_navigation"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
21
OsmAnd/res/layout/track_points_card.xml
Normal file
21
OsmAnd/res/layout/track_points_card.xml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<ExpandableListView
|
||||||
|
android:id="@android:id/list"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginStart="0dp"
|
||||||
|
android:layout_marginLeft="0dp"
|
||||||
|
android:layout_marginTop="0dp"
|
||||||
|
android:layout_marginEnd="0dp"
|
||||||
|
android:layout_marginRight="0dp"
|
||||||
|
android:divider="@null"
|
||||||
|
android:dividerHeight="0dp"
|
||||||
|
android:drawSelectorOnTop="false"
|
||||||
|
android:groupIndicator="@android:color/transparent" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
8
OsmAnd/res/menu/edit_description_menu.xml
Normal file
8
OsmAnd/res/menu/edit_description_menu.xml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:osmand="http://schemas.android.com/apk/res-auto">
|
||||||
|
<item android:id="@+id/action_edit"
|
||||||
|
android:icon="@drawable/ic_action_edit_dark"
|
||||||
|
osmand:showAsAction="always"
|
||||||
|
android:title="@string/shared_string_edit"/>
|
||||||
|
</menu>
|
|
@ -1,14 +1,16 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<!-- <item-->
|
|
||||||
<!-- android:id="@+id/action_overview"-->
|
<item
|
||||||
<!-- android:icon="@drawable/ic_action_trail_overview"-->
|
android:id="@+id/action_overview"
|
||||||
<!-- android:title="@string/shared_string_overview" />-->
|
android:icon="@drawable/ic_action_trail_overview"
|
||||||
|
android:title="@string/shared_string_overview" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
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"
|
||||||
|
|
|
@ -9,4 +9,9 @@
|
||||||
android:id="@+id/action_delete"
|
android:id="@+id/action_delete"
|
||||||
android:icon="@drawable/ic_action_remove_dark"
|
android:icon="@drawable/ic_action_remove_dark"
|
||||||
android:title="@string/shared_string_delete"/>
|
android:title="@string/shared_string_delete"/>
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/split_interval"
|
||||||
|
android:icon="@drawable/ic_action_split_interval"
|
||||||
|
android:title="@string/gpx_split_interval"/>
|
||||||
</menu>
|
</menu>
|
|
@ -141,6 +141,7 @@
|
||||||
<attr name="bg_dash_line" format="reference"/>
|
<attr name="bg_dash_line" format="reference"/>
|
||||||
<attr name="text_input_background" format="reference"/>
|
<attr name="text_input_background" format="reference"/>
|
||||||
<attr name="image_help_announcement_time" format="reference"/>
|
<attr name="image_help_announcement_time" format="reference"/>
|
||||||
|
<attr name="switch_button_active" format="reference" />
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
|
|
||||||
<declare-styleable name="PagerSlidingTabStrip">
|
<declare-styleable name="PagerSlidingTabStrip">
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -12,6 +12,12 @@
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
<string name="copy_to_map_favorites">Copy to favorites</string>
|
||||||
|
<string name="copy_to_map_markers">Copy to map markers</string>
|
||||||
|
<string name="delete_waypoints">Delete waypoints</string>
|
||||||
|
<string name="context_menu_edit_descr">Edit description</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>
|
||||||
|
|
|
@ -248,6 +248,7 @@
|
||||||
<item name="radioButtonStyle">@style/RadioButtonStyle</item>
|
<item name="radioButtonStyle">@style/RadioButtonStyle</item>
|
||||||
<item name="text_input_background">@color/text_input_background_light</item>
|
<item name="text_input_background">@color/text_input_background_light</item>
|
||||||
<item name="image_help_announcement_time">@drawable/img_help_announcement_time_day</item>
|
<item name="image_help_announcement_time">@drawable/img_help_announcement_time_day</item>
|
||||||
|
<item name="switch_button_active">@color/switch_button_active_light</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="ToolbarStyle" parent="@style/Widget.AppCompat.Toolbar">
|
<style name="ToolbarStyle" parent="@style/Widget.AppCompat.Toolbar">
|
||||||
|
@ -545,6 +546,7 @@
|
||||||
<item name="radioButtonStyle">@style/RadioButtonStyle</item>
|
<item name="radioButtonStyle">@style/RadioButtonStyle</item>
|
||||||
<item name="text_input_background">@color/text_input_background_dark</item>
|
<item name="text_input_background">@color/text_input_background_dark</item>
|
||||||
<item name="image_help_announcement_time">@drawable/img_help_announcement_time_night</item>
|
<item name="image_help_announcement_time">@drawable/img_help_announcement_time_night</item>
|
||||||
|
<item name="switch_button_active">@color/switch_button_active_dark</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="FreeVersionBanner" parent="OsmandDarkTheme">
|
<style name="FreeVersionBanner" parent="OsmandDarkTheme">
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package net.osmand;
|
package net.osmand;
|
||||||
|
|
||||||
|
import android.os.AsyncTask;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
@ -8,6 +9,8 @@ import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
|
||||||
|
import net.osmand.GPXUtilities.GPXFile;
|
||||||
|
import net.osmand.GPXUtilities.Metadata;
|
||||||
import net.osmand.plus.GpxSelectionHelper;
|
import net.osmand.plus.GpxSelectionHelper;
|
||||||
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
||||||
import net.osmand.plus.OsmandApplication;
|
import net.osmand.plus.OsmandApplication;
|
||||||
|
@ -109,6 +112,8 @@ public class FileUtils {
|
||||||
selected.getGpxFile().path = dest.getAbsolutePath();
|
selected.getGpxFile().path = dest.getAbsolutePath();
|
||||||
helper.updateSelectedGpxFile(selected);
|
helper.updateSelectedGpxFile(selected);
|
||||||
}
|
}
|
||||||
|
RenameGpxAsyncTask renameGpxAsyncTask = new RenameGpxAsyncTask(app, dest);
|
||||||
|
renameGpxAsyncTask.execute();
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -196,4 +201,34 @@ public class FileUtils {
|
||||||
public interface RenameCallback {
|
public interface RenameCallback {
|
||||||
void renamedTo(File file);
|
void renamedTo(File file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class RenameGpxAsyncTask extends AsyncTask<Void, Void, Exception> {
|
||||||
|
|
||||||
|
private OsmandApplication app;
|
||||||
|
private File file;
|
||||||
|
|
||||||
|
private RenameGpxAsyncTask(@NonNull OsmandApplication app, @NonNull File file) {
|
||||||
|
this.app = app;
|
||||||
|
this.file = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Exception doInBackground(Void... voids) {
|
||||||
|
GpxSelectionHelper helper = app.getSelectedGpxHelper();
|
||||||
|
SelectedGpxFile selected = helper.getSelectedFileByPath(file.getAbsolutePath());
|
||||||
|
|
||||||
|
GPXFile gpxFile;
|
||||||
|
if (selected != null && selected.getGpxFile() != null) {
|
||||||
|
gpxFile = selected.getGpxFile();
|
||||||
|
} else {
|
||||||
|
gpxFile = GPXUtilities.loadGPXFile(file);
|
||||||
|
}
|
||||||
|
if (gpxFile.metadata == null) {
|
||||||
|
gpxFile.metadata = new Metadata();
|
||||||
|
}
|
||||||
|
gpxFile.metadata.name = Algorithms.getFileNameWithoutExtension(file.getName());
|
||||||
|
|
||||||
|
return GPXUtilities.writeGpxFile(file, gpxFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,10 +45,12 @@ import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
public class GpxSelectionHelper {
|
public class GpxSelectionHelper {
|
||||||
|
|
||||||
|
@ -60,6 +62,7 @@ public class GpxSelectionHelper {
|
||||||
private static final String BACKUPMODIFIEDTIME = "backupTime";
|
private static final String BACKUPMODIFIEDTIME = "backupTime";
|
||||||
private static final String COLOR = "color";
|
private static final String COLOR = "color";
|
||||||
private static final String SELECTED_BY_USER = "selected_by_user";
|
private static final String SELECTED_BY_USER = "selected_by_user";
|
||||||
|
private static final String HIDDEN_GROUPS = "hidden_groups";
|
||||||
|
|
||||||
private OsmandApplication app;
|
private OsmandApplication app;
|
||||||
private SavingTrackHelper savingTrackHelper;
|
private SavingTrackHelper savingTrackHelper;
|
||||||
|
@ -577,7 +580,10 @@ public class GpxSelectionHelper {
|
||||||
} else if (obj.has(BACKUP)) {
|
} else if (obj.has(BACKUP)) {
|
||||||
selectedGpxFilesBackUp.put(gpx, gpx.modifiedTime);
|
selectedGpxFilesBackUp.put(gpx, gpx.modifiedTime);
|
||||||
} else {
|
} else {
|
||||||
selectGpxFile(gpx, true, false, true, selectedByUser, false);
|
SelectedGpxFile file = selectGpxFile(gpx, true, false, true, selectedByUser, false);
|
||||||
|
if (obj.has(HIDDEN_GROUPS)) {
|
||||||
|
readHiddenGroups(file, obj.getString(HIDDEN_GROUPS));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
gpx.addGeneralTrack();
|
gpx.addGeneralTrack();
|
||||||
} else if (obj.has(CURRENT_TRACK)) {
|
} else if (obj.has(CURRENT_TRACK)) {
|
||||||
|
@ -598,6 +604,33 @@ public class GpxSelectionHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String saveHiddenGroups(SelectedGpxFile selectedGpxFile) {
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
Iterator<String> it = selectedGpxFile.hiddenGroups.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
String name = it.next();
|
||||||
|
stringBuilder.append(name != null ? name : " ");
|
||||||
|
if (it.hasNext()) {
|
||||||
|
stringBuilder.append(",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stringBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readHiddenGroups(SelectedGpxFile selectedGpxFile, String text) {
|
||||||
|
StringTokenizer toks = new StringTokenizer(text, ",");
|
||||||
|
Set<String> res = new HashSet<>();
|
||||||
|
while (toks.hasMoreTokens()) {
|
||||||
|
String token = toks.nextToken();
|
||||||
|
if (!Algorithms.isBlank(token)) {
|
||||||
|
res.add(token);
|
||||||
|
} else {
|
||||||
|
res.add(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
selectedGpxFile.hiddenGroups = res;
|
||||||
|
}
|
||||||
|
|
||||||
private int parseColor(String color) {
|
private int parseColor(String color) {
|
||||||
try {
|
try {
|
||||||
return Algorithms.isEmpty(color) ? 0 : Algorithms.parseColor(color);
|
return Algorithms.isEmpty(color) ? 0 : Algorithms.parseColor(color);
|
||||||
|
@ -619,6 +652,7 @@ public class GpxSelectionHelper {
|
||||||
if (s.gpxFile.getColor(0) != 0) {
|
if (s.gpxFile.getColor(0) != 0) {
|
||||||
obj.put(COLOR, Algorithms.colorToString(s.gpxFile.getColor(0)));
|
obj.put(COLOR, Algorithms.colorToString(s.gpxFile.getColor(0)));
|
||||||
}
|
}
|
||||||
|
obj.put(HIDDEN_GROUPS, saveHiddenGroups(s));
|
||||||
}
|
}
|
||||||
obj.put(SELECTED_BY_USER, s.selectedByUser);
|
obj.put(SELECTED_BY_USER, s.selectedByUser);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
|
@ -765,6 +799,7 @@ public class GpxSelectionHelper {
|
||||||
private GPXFile gpxFile;
|
private GPXFile gpxFile;
|
||||||
private GPXTrackAnalysis trackAnalysis;
|
private GPXTrackAnalysis trackAnalysis;
|
||||||
|
|
||||||
|
private Set<String> hiddenGroups = new HashSet<>();
|
||||||
private List<TrkSegment> processedPointsToDisplay = new ArrayList<>();
|
private List<TrkSegment> processedPointsToDisplay = new ArrayList<>();
|
||||||
private List<GpxDisplayGroup> displayGroups;
|
private List<GpxDisplayGroup> displayGroups;
|
||||||
|
|
||||||
|
@ -832,6 +867,18 @@ public class GpxSelectionHelper {
|
||||||
return processedPointsToDisplay;
|
return processedPointsToDisplay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<String> getHiddenGroups() {
|
||||||
|
return Collections.unmodifiableSet(hiddenGroups);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addHiddenGroups(String group) {
|
||||||
|
hiddenGroups.add(group);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeHiddenGroups(String group) {
|
||||||
|
hiddenGroups.remove(group);
|
||||||
|
}
|
||||||
|
|
||||||
public GPXFile getGpxFile() {
|
public GPXFile getGpxFile() {
|
||||||
return gpxFile;
|
return gpxFile;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,8 @@ public class RenameFileBottomSheet extends MenuBottomSheetDialogFragment {
|
||||||
file = new File(path);
|
file = new File(path);
|
||||||
}
|
}
|
||||||
selectedFileName = savedInstanceState.getString(SELECTED_FILE_NAME_KEY);
|
selectedFileName = savedInstanceState.getString(SELECTED_FILE_NAME_KEY);
|
||||||
|
} else {
|
||||||
|
selectedFileName = Algorithms.getFileNameWithoutExtension(file);
|
||||||
}
|
}
|
||||||
items.add(new TitleItem(getString(R.string.shared_string_rename)));
|
items.add(new TitleItem(getString(R.string.shared_string_rename)));
|
||||||
|
|
||||||
|
@ -74,7 +76,7 @@ public class RenameFileBottomSheet extends MenuBottomSheetDialogFragment {
|
||||||
nameTextBox.setDefaultHintTextColor(colorStateList);
|
nameTextBox.setDefaultHintTextColor(colorStateList);
|
||||||
|
|
||||||
editText = view.findViewById(R.id.name_edit_text);
|
editText = view.findViewById(R.id.name_edit_text);
|
||||||
editText.setText(selectedFileName != null ? selectedFileName : Algorithms.getFileNameWithoutExtension(file));
|
editText.setText(selectedFileName);
|
||||||
editText.addTextChangedListener(new TextWatcher() {
|
editText.addTextChangedListener(new TextWatcher() {
|
||||||
@Override
|
@Override
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
@ -127,12 +129,13 @@ public class RenameFileBottomSheet extends MenuBottomSheetDialogFragment {
|
||||||
File dest;
|
File dest;
|
||||||
int index = file.getName().lastIndexOf('.');
|
int index = file.getName().lastIndexOf('.');
|
||||||
String ext = index == -1 ? "" : file.getName().substring(index);
|
String ext = index == -1 ? "" : file.getName().substring(index);
|
||||||
|
String newName = Algorithms.getFileNameWithoutExtension(selectedFileName);
|
||||||
if (SQLiteTileSource.EXT.equals(ext)) {
|
if (SQLiteTileSource.EXT.equals(ext)) {
|
||||||
dest = renameSQLiteFile(app, file, selectedFileName + ext, null);
|
dest = renameSQLiteFile(app, file, newName + ext, null);
|
||||||
} else if (IndexConstants.GPX_FILE_EXT.equals(ext)) {
|
} else if (IndexConstants.GPX_FILE_EXT.equals(ext)) {
|
||||||
dest = renameGpxFile(app, file, selectedFileName + ext, false, null);
|
dest = renameGpxFile(app, file, newName + ext, false, null);
|
||||||
} else {
|
} else {
|
||||||
dest = renameFile(app, file, selectedFileName + ext, false, null);
|
dest = renameFile(app, file, newName + ext, false, null);
|
||||||
}
|
}
|
||||||
if (dest != null) {
|
if (dest != null) {
|
||||||
Fragment fragment = getTargetFragment();
|
Fragment fragment = getTargetFragment();
|
||||||
|
|
|
@ -9,6 +9,7 @@ import android.content.res.ColorStateList;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Matrix;
|
||||||
import android.graphics.PorterDuff;
|
import android.graphics.PorterDuff;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.graphics.drawable.GradientDrawable;
|
import android.graphics.drawable.GradientDrawable;
|
||||||
|
@ -98,6 +99,7 @@ import static net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCa
|
||||||
public class MenuBuilder {
|
public class MenuBuilder {
|
||||||
|
|
||||||
private static final int PICK_IMAGE = 1231;
|
private static final int PICK_IMAGE = 1231;
|
||||||
|
private static final int MAX_IMAGE_LENGTH = 2048;
|
||||||
private static final Log LOG = PlatformUtil.getLog(MenuBuilder.class);
|
private static final Log LOG = PlatformUtil.getLog(MenuBuilder.class);
|
||||||
public static final float SHADOW_HEIGHT_TOP_DP = 17f;
|
public static final float SHADOW_HEIGHT_TOP_DP = 17f;
|
||||||
public static final int TITLE_LIMIT = 60;
|
public static final int TITLE_LIMIT = 60;
|
||||||
|
@ -505,10 +507,11 @@ public class MenuBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void uploadImageToPlace(InputStream image) {
|
private void uploadImageToPlace(InputStream image) {
|
||||||
InputStream serverData = new ByteArrayInputStream(compressImage(image));
|
InputStream serverData = new ByteArrayInputStream(compressImageToJpeg(image));
|
||||||
final String baseUrl = OPRConstants.getBaseUrl(app);
|
final String baseUrl = OPRConstants.getBaseUrl(app);
|
||||||
|
// all these should be constant
|
||||||
String url = baseUrl + "api/ipfs/image";
|
String url = baseUrl + "api/ipfs/image";
|
||||||
String response = NetworkUtils.sendPostDataRequest(url, serverData);
|
String response = NetworkUtils.sendPostDataRequest(url, "file", "compressed.jpeg", serverData);
|
||||||
if (response != null) {
|
if (response != null) {
|
||||||
int res = 0;
|
int res = 0;
|
||||||
try {
|
try {
|
||||||
|
@ -571,11 +574,27 @@ public class MenuBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] compressImage(InputStream image) {
|
private byte[] compressImageToJpeg(InputStream image) {
|
||||||
BufferedInputStream bufferedInputStream = new BufferedInputStream(image);
|
BufferedInputStream bufferedInputStream = new BufferedInputStream(image);
|
||||||
Bitmap bmp = BitmapFactory.decodeStream(bufferedInputStream);
|
Bitmap bmp = BitmapFactory.decodeStream(bufferedInputStream);
|
||||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||||
bmp.compress(Bitmap.CompressFormat.PNG, 70, os);
|
int h = bmp.getHeight();
|
||||||
|
int w = bmp.getWidth();
|
||||||
|
boolean scale = false;
|
||||||
|
while (w > MAX_IMAGE_LENGTH || h > MAX_IMAGE_LENGTH) {
|
||||||
|
w = w / 2;
|
||||||
|
h = h / 2;
|
||||||
|
scale = true;
|
||||||
|
}
|
||||||
|
if (scale) {
|
||||||
|
Matrix matrix = new Matrix();
|
||||||
|
matrix.postScale(w, h);
|
||||||
|
Bitmap resizedBitmap = Bitmap.createBitmap(
|
||||||
|
bmp, 0, 0, w, h, matrix, false);
|
||||||
|
bmp.recycle();
|
||||||
|
bmp = resizedBitmap;
|
||||||
|
}
|
||||||
|
bmp.compress(Bitmap.CompressFormat.JPEG, 90, os);
|
||||||
return os.toByteArray();
|
return os.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,14 +15,14 @@ import java.io.File;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
class DeletePointsTask extends AsyncTask<Void, Void, Void> {
|
public class DeletePointsTask extends AsyncTask<Void, Void, Void> {
|
||||||
|
|
||||||
private OsmandApplication app;
|
private OsmandApplication app;
|
||||||
private GPXFile gpx;
|
private GPXFile gpx;
|
||||||
private Set<GpxDisplayItem> selectedItems;
|
private Set<GpxDisplayItem> selectedItems;
|
||||||
private WeakReference<OnPointsDeleteListener> listenerRef;
|
private WeakReference<OnPointsDeleteListener> listenerRef;
|
||||||
|
|
||||||
DeletePointsTask(OsmandApplication app, GPXFile gpxFile, Set<GpxDisplayItem> selectedItems, OnPointsDeleteListener listener) {
|
public DeletePointsTask(OsmandApplication app, GPXFile gpxFile, Set<GpxDisplayItem> selectedItems, OnPointsDeleteListener listener) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
this.gpx = gpxFile;
|
this.gpx = gpxFile;
|
||||||
this.selectedItems = selectedItems;
|
this.selectedItems = selectedItems;
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
package net.osmand.plus.myplaces;
|
package net.osmand.plus.myplaces;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
|
import android.graphics.Typeface;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.ContextThemeWrapper;
|
import android.view.ContextThemeWrapper;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.View.OnClickListener;
|
||||||
import android.view.ViewGroup.LayoutParams;
|
import android.view.ViewGroup.LayoutParams;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
|
@ -17,56 +18,127 @@ import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.appcompat.widget.ListPopupWindow;
|
import androidx.appcompat.widget.ListPopupWindow;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.fragment.app.FragmentActivity;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
|
||||||
import net.osmand.AndroidUtils;
|
import net.osmand.AndroidUtils;
|
||||||
import net.osmand.GPXUtilities;
|
import net.osmand.GPXUtilities;
|
||||||
import net.osmand.GPXUtilities.GPXFile;
|
import net.osmand.GPXUtilities.GPXFile;
|
||||||
import net.osmand.GPXUtilities.WptPt;
|
import net.osmand.GPXUtilities.WptPt;
|
||||||
|
import net.osmand.data.FavouritePoint;
|
||||||
|
import net.osmand.plus.FavouritesDbHelper;
|
||||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup;
|
import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup;
|
||||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
|
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
|
||||||
import net.osmand.plus.mapmarkers.MapMarkersHelper;
|
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType;
|
||||||
import net.osmand.plus.mapmarkers.MapMarkersGroup;
|
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
||||||
import net.osmand.plus.OsmandApplication;
|
import net.osmand.plus.OsmandApplication;
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
|
import net.osmand.plus.UiUtilities;
|
||||||
import net.osmand.plus.activities.EditFavoriteGroupDialogFragment.FavoriteColorAdapter;
|
import net.osmand.plus.activities.EditFavoriteGroupDialogFragment.FavoriteColorAdapter;
|
||||||
|
import net.osmand.plus.activities.MapActivity;
|
||||||
import net.osmand.plus.activities.SavingTrackHelper;
|
import net.osmand.plus.activities.SavingTrackHelper;
|
||||||
import net.osmand.plus.activities.TrackActivity;
|
import net.osmand.plus.activities.TrackActivity;
|
||||||
import net.osmand.plus.base.MenuBottomSheetDialogFragment;
|
import net.osmand.plus.base.MenuBottomSheetDialogFragment;
|
||||||
import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
|
import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
|
||||||
|
import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithCompoundButton;
|
||||||
import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
|
import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
|
||||||
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
|
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
|
||||||
import net.osmand.plus.helpers.AndroidUiHelper;
|
import net.osmand.plus.helpers.AndroidUiHelper;
|
||||||
|
import net.osmand.plus.helpers.FontCache;
|
||||||
|
import net.osmand.plus.mapmarkers.MapMarkersGroup;
|
||||||
|
import net.osmand.plus.mapmarkers.MapMarkersHelper;
|
||||||
|
import net.osmand.plus.measurementtool.OptionsDividerItem;
|
||||||
|
import net.osmand.plus.myplaces.DeletePointsTask.OnPointsDeleteListener;
|
||||||
|
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||||
|
import net.osmand.plus.track.TrackMenuFragment;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static net.osmand.plus.settings.bottomsheets.BooleanPreferenceBottomSheet.getCustomButtonView;
|
||||||
|
import static net.osmand.plus.settings.bottomsheets.BooleanPreferenceBottomSheet.updateCustomButtonView;
|
||||||
|
|
||||||
|
public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment implements OnPointsDeleteListener {
|
||||||
|
|
||||||
public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment {
|
|
||||||
public static final String TAG = EditTrackGroupDialogFragment.class.getSimpleName();
|
public static final String TAG = EditTrackGroupDialogFragment.class.getSimpleName();
|
||||||
|
|
||||||
|
private OsmandApplication app;
|
||||||
|
|
||||||
private GpxDisplayGroup group;
|
private GpxDisplayGroup group;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createMenuItems(Bundle savedInstanceState) {
|
public void createMenuItems(Bundle savedInstanceState) {
|
||||||
final OsmandApplication app = getMyApplication();
|
app = requiredMyApplication();
|
||||||
if (group == null) {
|
if (group == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
items.add(new TitleItem(getCategoryName(app, group.getName())));
|
items.add(new TitleItem(getCategoryName(app, group.getName())));
|
||||||
|
|
||||||
BaseBottomSheetItem editNameItem = new SimpleBottomSheetItem.Builder()
|
SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(group.getGpx().path);
|
||||||
.setIcon(getContentIcon(R.drawable.ic_action_edit_dark))
|
if (group.getType() == GpxDisplayItemType.TRACK_POINTS && selectedGpxFile != null) {
|
||||||
.setTitle(getString(R.string.edit_name))
|
items.add(createShowOnMapItem(selectedGpxFile));
|
||||||
.setLayoutId(R.layout.bottom_sheet_item_simple)
|
}
|
||||||
|
items.add(createEditNameItem());
|
||||||
|
items.add(new OptionsDividerItem(app));
|
||||||
|
|
||||||
|
// items.add(createCopyToMarkersItem());
|
||||||
|
items.add(createCopyToFavoritesItem());
|
||||||
|
items.add(new OptionsDividerItem(app));
|
||||||
|
|
||||||
|
items.add(createDeleteGroupItem());
|
||||||
|
}
|
||||||
|
|
||||||
|
private BaseBottomSheetItem createShowOnMapItem(final SelectedGpxFile selectedGpxFile) {
|
||||||
|
final String name = Algorithms.isEmpty(group.getName()) ? null : group.getName();
|
||||||
|
boolean checked = !selectedGpxFile.getHiddenGroups().contains(name);
|
||||||
|
final ApplicationMode mode = app.getSettings().getApplicationMode();
|
||||||
|
final BottomSheetItemWithCompoundButton[] showOnMapItem = new BottomSheetItemWithCompoundButton[1];
|
||||||
|
showOnMapItem[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder()
|
||||||
|
.setCompoundButtonColorId(mode.getIconColorInfo().getColor(nightMode))
|
||||||
|
.setChecked(checked)
|
||||||
|
.setTitle(getString(R.string.shared_string_show_on_map))
|
||||||
|
.setCustomView(getCustomButtonView(app, mode, checked, nightMode))
|
||||||
.setOnClickListener(new View.OnClickListener() {
|
.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
Activity activity = getActivity();
|
boolean checked = !showOnMapItem[0].isChecked();
|
||||||
|
if (checked) {
|
||||||
|
selectedGpxFile.removeHiddenGroups(name);
|
||||||
|
} else {
|
||||||
|
selectedGpxFile.addHiddenGroups(name);
|
||||||
|
}
|
||||||
|
app.getSelectedGpxHelper().updateSelectedGpxFile(selectedGpxFile);
|
||||||
|
|
||||||
|
showOnMapItem[0].setChecked(checked);
|
||||||
|
updateCustomButtonView(app, mode, v, checked, nightMode);
|
||||||
|
|
||||||
|
FragmentActivity activity = getActivity();
|
||||||
|
if (activity instanceof MapActivity) {
|
||||||
|
((MapActivity) activity).refreshMap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.create();
|
||||||
|
return showOnMapItem[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
private BaseBottomSheetItem createEditNameItem() {
|
||||||
|
return new SimpleBottomSheetItem.Builder()
|
||||||
|
.setIcon(getContentIcon(R.drawable.ic_action_name_field))
|
||||||
|
.setTitle(getString(R.string.shared_string_rename))
|
||||||
|
.setLayoutId(R.layout.bottom_sheet_item_simple)
|
||||||
|
.setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp)
|
||||||
|
.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
final FragmentActivity activity = getActivity();
|
||||||
if (activity != null) {
|
if (activity != null) {
|
||||||
AlertDialog.Builder b = new AlertDialog.Builder(activity);
|
AlertDialog.Builder b = new AlertDialog.Builder(activity);
|
||||||
b.setTitle(R.string.favorite_group_name);
|
b.setTitle(R.string.favorite_group_name);
|
||||||
|
@ -86,12 +158,9 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment
|
||||||
String name = nameEditText.getText().toString();
|
String name = nameEditText.getText().toString();
|
||||||
boolean nameChanged = !Algorithms.objectEquals(group.getName(), name);
|
boolean nameChanged = !Algorithms.objectEquals(group.getName(), name);
|
||||||
if (nameChanged) {
|
if (nameChanged) {
|
||||||
TrackActivity trackActivity = getTrackActivity();
|
new UpdateGpxCategoryTask(activity, group, name)
|
||||||
if (trackActivity != null) {
|
|
||||||
new UpdateGpxCategoryTask(trackActivity, group, name)
|
|
||||||
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
dismiss();
|
dismiss();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -100,20 +169,118 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.create();
|
.create();
|
||||||
items.add(editNameItem);
|
}
|
||||||
|
|
||||||
|
private BaseBottomSheetItem createCopyToMarkersItem() {
|
||||||
|
return new SimpleBottomSheetItem.Builder()
|
||||||
|
.setIcon(getContentIcon(R.drawable.ic_action_copy))
|
||||||
|
.setTitle(getString(R.string.copy_to_map_markers))
|
||||||
|
.setLayoutId(R.layout.bottom_sheet_item_simple)
|
||||||
|
.setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp)
|
||||||
|
.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
// MapMarkersHelper markersHelper = app.getMapMarkersHelper();
|
||||||
|
// MapMarkersGroup markersGroup = markersHelper.getMarkersGroup(group);
|
||||||
|
// if (markersGroup != null) {
|
||||||
|
// markersHelper.removeMarkersGroup(markersGroup);
|
||||||
|
// } else {
|
||||||
|
// markersHelper.addOrEnableGroup(group);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
private BaseBottomSheetItem createCopyToFavoritesItem() {
|
||||||
|
return new SimpleBottomSheetItem.Builder()
|
||||||
|
.setIcon(getContentIcon(R.drawable.ic_action_copy))
|
||||||
|
.setTitle(getString(R.string.copy_to_map_favorites))
|
||||||
|
.setLayoutId(R.layout.bottom_sheet_item_simple)
|
||||||
|
.setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp)
|
||||||
|
.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
saveGroupToFavorites();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveGroupToFavorites() {
|
||||||
|
FragmentActivity activity = getActivity();
|
||||||
|
if (activity != null) {
|
||||||
|
AlertDialog.Builder b = new AlertDialog.Builder(activity);
|
||||||
|
final EditText editText = new EditText(activity);
|
||||||
|
String name = group.getModifiableList().iterator().next().group.getName();
|
||||||
|
if (name.indexOf('\n') > 0) {
|
||||||
|
name = name.substring(0, name.indexOf('\n'));
|
||||||
|
}
|
||||||
|
editText.setText(name);
|
||||||
|
int leftMargin = AndroidUtils.dpToPx(activity, 16f);
|
||||||
|
int topMargin = AndroidUtils.dpToPx(activity, 8f);
|
||||||
|
editText.setPadding(leftMargin, topMargin, leftMargin, topMargin);
|
||||||
|
b.setTitle(R.string.save_as_favorites_points);
|
||||||
|
b.setView(editText);
|
||||||
|
b.setPositiveButton(R.string.shared_string_save, new DialogInterface.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
String category = editText.getText().toString();
|
||||||
|
FavouritesDbHelper favouritesDbHelper = app.getFavorites();
|
||||||
|
for (GpxDisplayItem item : group.getModifiableList()) {
|
||||||
|
if (item.locationStart != null) {
|
||||||
|
FavouritePoint fp = FavouritePoint.fromWpt(item.locationStart, app, category);
|
||||||
|
if (!Algorithms.isEmpty(item.description)) {
|
||||||
|
fp.setDescription(item.description);
|
||||||
|
}
|
||||||
|
favouritesDbHelper.addFavourite(fp, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
favouritesDbHelper.saveCurrentPointsIntoFile();
|
||||||
|
dismiss();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
b.setNegativeButton(R.string.shared_string_cancel, null);
|
||||||
|
b.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private BaseBottomSheetItem createDeleteGroupItem() {
|
||||||
|
String delete = app.getString(R.string.shared_string_delete);
|
||||||
|
Typeface typeface = FontCache.getRobotoMedium(app);
|
||||||
|
return new SimpleBottomSheetItem.Builder()
|
||||||
|
.setTitleColorId(R.color.color_osm_edit_delete)
|
||||||
|
.setIcon(getIcon(R.drawable.ic_action_delete_dark, R.color.color_osm_edit_delete))
|
||||||
|
.setTitle(UiUtilities.createCustomFontSpannable(typeface, delete, delete))
|
||||||
|
.setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp)
|
||||||
|
.setOnClickListener(new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
deleteGroupItems();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteGroupItems() {
|
||||||
|
Set<GpxDisplayItem> items = new HashSet<>(group.getModifiableList());
|
||||||
|
new DeletePointsTask(app, group.getGpx(), items, this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BaseBottomSheetItem createChangeColorItem() {
|
||||||
final int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme;
|
final int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme;
|
||||||
final View changeColorView = View.inflate(new ContextThemeWrapper(getContext(), themeRes),
|
final View changeColorView = View.inflate(new ContextThemeWrapper(getContext(), themeRes),
|
||||||
R.layout.change_fav_color, null);
|
R.layout.change_fav_color, null);
|
||||||
((ImageView) changeColorView.findViewById(R.id.change_color_icon))
|
((ImageView) changeColorView.findViewById(R.id.change_color_icon))
|
||||||
.setImageDrawable(getContentIcon(R.drawable.ic_action_appearance));
|
.setImageDrawable(getContentIcon(R.drawable.ic_action_appearance));
|
||||||
updateColorView((ImageView) changeColorView.findViewById(R.id.colorImage));
|
updateColorView((ImageView) changeColorView.findViewById(R.id.colorImage));
|
||||||
BaseBottomSheetItem changeColorItem = new BaseBottomSheetItem.Builder()
|
return new BaseBottomSheetItem.Builder()
|
||||||
.setCustomView(changeColorView)
|
.setCustomView(changeColorView)
|
||||||
.setOnClickListener(new View.OnClickListener() {
|
.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
Activity activity = getActivity();
|
final FragmentActivity activity = getActivity();
|
||||||
if (activity != null) {
|
if (activity != null) {
|
||||||
final ListPopupWindow popup = new ListPopupWindow(activity);
|
final ListPopupWindow popup = new ListPopupWindow(activity);
|
||||||
popup.setAnchorView(v);
|
popup.setAnchorView(v);
|
||||||
|
@ -135,13 +302,10 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment
|
||||||
Integer color = colorAdapter.getItem(position);
|
Integer color = colorAdapter.getItem(position);
|
||||||
if (color != null) {
|
if (color != null) {
|
||||||
if (color != group.getColor()) {
|
if (color != group.getColor()) {
|
||||||
TrackActivity trackActivity = getTrackActivity();
|
new UpdateGpxCategoryTask(activity, group, color)
|
||||||
if (trackActivity != null) {
|
|
||||||
new UpdateGpxCategoryTask(trackActivity, group, color)
|
|
||||||
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
popup.dismiss();
|
popup.dismiss();
|
||||||
dismiss();
|
dismiss();
|
||||||
}
|
}
|
||||||
|
@ -151,8 +315,6 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.create();
|
.create();
|
||||||
items.add(changeColorItem);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -163,15 +325,6 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private TrackActivity getTrackActivity() {
|
|
||||||
Activity activity = getActivity();
|
|
||||||
if (activity != null && activity instanceof TrackActivity) {
|
|
||||||
return (TrackActivity) activity;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String getCategoryName(@NonNull Context ctx, String category) {
|
private static String getCategoryName(@NonNull Context ctx, String category) {
|
||||||
return Algorithms.isEmpty(category) ? ctx.getString(R.string.shared_string_waypoints) : category;
|
return Algorithms.isEmpty(category) ? ctx.getString(R.string.shared_string_waypoints) : category;
|
||||||
}
|
}
|
||||||
|
@ -181,24 +334,38 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment
|
||||||
if (color == 0) {
|
if (color == 0) {
|
||||||
colorImageView.setImageDrawable(getContentIcon(R.drawable.ic_action_circle));
|
colorImageView.setImageDrawable(getContentIcon(R.drawable.ic_action_circle));
|
||||||
} else {
|
} else {
|
||||||
colorImageView.setImageDrawable(getMyApplication().getUIUtilities().getPaintedIcon(R.drawable.ic_action_circle, color));
|
colorImageView.setImageDrawable(app.getUIUtilities().getPaintedIcon(R.drawable.ic_action_circle, color));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void showInstance(FragmentManager fragmentManager, GpxDisplayGroup group) {
|
public static void showInstance(FragmentManager fragmentManager, GpxDisplayGroup group, Fragment target) {
|
||||||
EditTrackGroupDialogFragment f = (EditTrackGroupDialogFragment) fragmentManager
|
if (!fragmentManager.isStateSaved() && fragmentManager.findFragmentByTag(TAG) == null) {
|
||||||
.findFragmentByTag(EditTrackGroupDialogFragment.TAG);
|
EditTrackGroupDialogFragment fragment = new EditTrackGroupDialogFragment();
|
||||||
if (f == null ) {
|
fragment.group = group;
|
||||||
f = new EditTrackGroupDialogFragment();
|
fragment.setRetainInstance(true);
|
||||||
f.group = group;
|
fragment.setTargetFragment(target, 0);
|
||||||
f.show(fragmentManager, EditTrackGroupDialogFragment.TAG);
|
fragment.show(fragmentManager, TAG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPointsDeletionStarted() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPointsDeleted() {
|
||||||
|
Fragment fragment = getTargetFragment();
|
||||||
|
if (fragment instanceof TrackMenuFragment) {
|
||||||
|
((TrackMenuFragment) fragment).updateContent();
|
||||||
|
}
|
||||||
|
dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
private static class UpdateGpxCategoryTask extends AsyncTask<Void, Void, Void> {
|
private static class UpdateGpxCategoryTask extends AsyncTask<Void, Void, Void> {
|
||||||
|
|
||||||
private OsmandApplication app;
|
private OsmandApplication app;
|
||||||
private WeakReference<TrackActivity> activityRef;
|
private WeakReference<FragmentActivity> activityRef;
|
||||||
|
|
||||||
private GpxDisplayGroup group;
|
private GpxDisplayGroup group;
|
||||||
|
|
||||||
|
@ -208,20 +375,20 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment
|
||||||
private ProgressDialog progressDialog;
|
private ProgressDialog progressDialog;
|
||||||
private boolean wasUpdated = false;
|
private boolean wasUpdated = false;
|
||||||
|
|
||||||
private UpdateGpxCategoryTask(@NonNull TrackActivity activity, @NonNull GpxDisplayGroup group) {
|
private UpdateGpxCategoryTask(@NonNull FragmentActivity activity, @NonNull GpxDisplayGroup group) {
|
||||||
this.app = (OsmandApplication) activity.getApplication();
|
this.app = (OsmandApplication) activity.getApplication();
|
||||||
activityRef = new WeakReference<>(activity);
|
activityRef = new WeakReference<>(activity);
|
||||||
|
|
||||||
this.group = group;
|
this.group = group;
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateGpxCategoryTask(@NonNull TrackActivity activity, @NonNull GpxDisplayGroup group,
|
UpdateGpxCategoryTask(@NonNull FragmentActivity activity, @NonNull GpxDisplayGroup group,
|
||||||
@NonNull String newCategory) {
|
@NonNull String newCategory) {
|
||||||
this(activity, group);
|
this(activity, group);
|
||||||
this.newCategory = newCategory;
|
this.newCategory = newCategory;
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateGpxCategoryTask(@NonNull TrackActivity activity, @NonNull GpxDisplayGroup group,
|
UpdateGpxCategoryTask(@NonNull FragmentActivity activity, @NonNull GpxDisplayGroup group,
|
||||||
@NonNull Integer newColor) {
|
@NonNull Integer newColor) {
|
||||||
this(activity, group);
|
this(activity, group);
|
||||||
this.newColor = newColor;
|
this.newColor = newColor;
|
||||||
|
@ -229,7 +396,7 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPreExecute() {
|
protected void onPreExecute() {
|
||||||
TrackActivity activity = activityRef.get();
|
FragmentActivity activity = activityRef.get();
|
||||||
if (activity != null) {
|
if (activity != null) {
|
||||||
progressDialog = new ProgressDialog(activity);
|
progressDialog = new ProgressDialog(activity);
|
||||||
progressDialog.setTitle(EditTrackGroupDialogFragment.getCategoryName(app, group.getName()));
|
progressDialog.setTitle(EditTrackGroupDialogFragment.getCategoryName(app, group.getName()));
|
||||||
|
@ -293,9 +460,15 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment
|
||||||
progressDialog.dismiss();
|
progressDialog.dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackActivity activity = activityRef.get();
|
FragmentActivity activity = activityRef.get();
|
||||||
if (activity != null) {
|
if (activity instanceof TrackActivity) {
|
||||||
activity.loadGpx();
|
((TrackActivity) activity).loadGpx();
|
||||||
|
} else if (activity instanceof MapActivity) {
|
||||||
|
MapActivity mapActivity = (MapActivity) activity;
|
||||||
|
TrackMenuFragment fragment = mapActivity.getTrackMenuFragment();
|
||||||
|
if (fragment != null) {
|
||||||
|
fragment.updateContent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -275,17 +276,7 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid
|
||||||
openAnalyzeOnMap(GPXTabItemType.GPX_TAB_ITEM_SPEED);
|
openAnalyzeOnMap(GPXTabItemType.GPX_TAB_ITEM_SPEED);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (gpxFile.showCurrentTrack) {
|
TextView overflowMenu = view.findViewById(R.id.overflow_menu);
|
||||||
view.findViewById(R.id.split_interval).setVisibility(View.GONE);
|
|
||||||
} else {
|
|
||||||
view.findViewById(R.id.split_interval).setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View view) {
|
|
||||||
openSplitIntervalScreen();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
ImageView overflowMenu = view.findViewById(R.id.overflow_menu);
|
|
||||||
if (!gpxItem.group.getTrack().generalTrack) {
|
if (!gpxItem.group.getTrack().generalTrack) {
|
||||||
setupOptionsPopupMenu(overflowMenu, false);
|
setupOptionsPopupMenu(overflowMenu, false);
|
||||||
} else {
|
} else {
|
||||||
|
@ -293,13 +284,12 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupOptionsPopupMenu(ImageView overflowMenu, final boolean confirmDeletion) {
|
private void setupOptionsPopupMenu(TextView overflowMenu, final boolean confirmDeletion) {
|
||||||
overflowMenu.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_overflow_menu_white));
|
|
||||||
overflowMenu.setVisibility(View.VISIBLE);
|
overflowMenu.setVisibility(View.VISIBLE);
|
||||||
overflowMenu.setOnClickListener(new View.OnClickListener() {
|
overflowMenu.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
actionsListener.showOptionsPopupMenu(view, getTrkSegment(), confirmDeletion);
|
actionsListener.showOptionsPopupMenu(view, getTrkSegment(), confirmDeletion, gpxItem);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -359,17 +349,7 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid
|
||||||
openAnalyzeOnMap(GPXTabItemType.GPX_TAB_ITEM_ALTITUDE);
|
openAnalyzeOnMap(GPXTabItemType.GPX_TAB_ITEM_ALTITUDE);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (gpxFile.showCurrentTrack) {
|
TextView overflowMenu = view.findViewById(R.id.overflow_menu);
|
||||||
view.findViewById(R.id.split_interval).setVisibility(View.GONE);
|
|
||||||
} else {
|
|
||||||
view.findViewById(R.id.split_interval).setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View view) {
|
|
||||||
openSplitIntervalScreen();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
ImageView overflowMenu = view.findViewById(R.id.overflow_menu);
|
|
||||||
if (!gpxItem.group.getTrack().generalTrack) {
|
if (!gpxItem.group.getTrack().generalTrack) {
|
||||||
setupOptionsPopupMenu(overflowMenu, false);
|
setupOptionsPopupMenu(overflowMenu, false);
|
||||||
} else {
|
} else {
|
||||||
|
@ -436,17 +416,7 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid
|
||||||
openAnalyzeOnMap(GPXTabItemType.GPX_TAB_ITEM_GENERAL);
|
openAnalyzeOnMap(GPXTabItemType.GPX_TAB_ITEM_GENERAL);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (gpxFile.showCurrentTrack) {
|
TextView overflowMenu = view.findViewById(R.id.overflow_menu);
|
||||||
view.findViewById(R.id.split_interval).setVisibility(View.GONE);
|
|
||||||
} else {
|
|
||||||
view.findViewById(R.id.split_interval).setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View view) {
|
|
||||||
openSplitIntervalScreen();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
ImageView overflowMenu = view.findViewById(R.id.overflow_menu);
|
|
||||||
if (!gpxItem.group.getTrack().generalTrack) {
|
if (!gpxItem.group.getTrack().generalTrack) {
|
||||||
setupOptionsPopupMenu(overflowMenu, true);
|
setupOptionsPopupMenu(overflowMenu, true);
|
||||||
} else {
|
} else {
|
||||||
|
@ -687,8 +657,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();
|
||||||
|
@ -21,7 +17,7 @@ public interface SegmentActionsListener {
|
||||||
|
|
||||||
void openSplitInterval(GpxDisplayItem gpxItem, TrkSegment trkSegment);
|
void openSplitInterval(GpxDisplayItem gpxItem, TrkSegment trkSegment);
|
||||||
|
|
||||||
void showOptionsPopupMenu(View view, TrkSegment trkSegment, boolean confirmDeletion);
|
void showOptionsPopupMenu(View view, TrkSegment trkSegment, boolean confirmDeletion, GpxDisplayItem gpxItem);
|
||||||
|
|
||||||
void openAnalyzeOnMap(GpxDisplayItem gpxItem, List<ILineDataSet> dataSets, GPXTabItemType tabType);
|
void openAnalyzeOnMap(GpxDisplayItem gpxItem);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,6 @@ import com.squareup.picasso.Picasso;
|
||||||
import com.squareup.picasso.RequestCreator;
|
import com.squareup.picasso.RequestCreator;
|
||||||
|
|
||||||
import net.osmand.AndroidUtils;
|
import net.osmand.AndroidUtils;
|
||||||
import net.osmand.GPXUtilities;
|
|
||||||
import net.osmand.GPXUtilities.GPXFile;
|
import net.osmand.GPXUtilities.GPXFile;
|
||||||
import net.osmand.GPXUtilities.Metadata;
|
import net.osmand.GPXUtilities.Metadata;
|
||||||
import net.osmand.GPXUtilities.WptPt;
|
import net.osmand.GPXUtilities.WptPt;
|
||||||
|
@ -409,7 +408,7 @@ public class TrackActivityFragmentAdapter implements TrackBitmapDrawerListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private String getMetadataImageLink(@NonNull Metadata metadata) {
|
public static String getMetadataImageLink(@NonNull Metadata metadata) {
|
||||||
String link = metadata.link;
|
String link = metadata.link;
|
||||||
if (!TextUtils.isEmpty(link)) {
|
if (!TextUtils.isEmpty(link)) {
|
||||||
String lowerCaseLink = link.toLowerCase();
|
String lowerCaseLink = link.toLowerCase();
|
||||||
|
|
|
@ -1007,7 +1007,7 @@ public class TrackPointFragment extends OsmandExpandableListFragment implements
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
FragmentActivity activity = getActivity();
|
FragmentActivity activity = getActivity();
|
||||||
if (activity != null) {
|
if (activity != null) {
|
||||||
EditTrackGroupDialogFragment.showInstance(activity.getSupportFragmentManager(), group);
|
EditTrackGroupDialogFragment.showInstance(activity.getSupportFragmentManager(), group, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -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,
|
||||||
|
@ -357,14 +304,19 @@ public class TrackSegmentFragment extends OsmAndListFragment implements TrackBit
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void showOptionsPopupMenu(View view, final TrkSegment segment, final boolean confirmDeletion) {
|
public void showOptionsPopupMenu(View view, final TrkSegment segment, final boolean confirmDeletion, final GpxDisplayItem gpxItem) {
|
||||||
FragmentActivity activity = getActivity();
|
FragmentActivity activity = getActivity();
|
||||||
if (activity != null) {
|
if (activity != null) {
|
||||||
optionsPopupMenu = new IconPopupMenu(activity, view.findViewById(R.id.overflow_menu));
|
IconPopupMenu optionsPopupMenu = new IconPopupMenu(activity, view.findViewById(R.id.overflow_menu));
|
||||||
Menu menu = optionsPopupMenu.getMenu();
|
final Menu menu = optionsPopupMenu.getMenu();
|
||||||
optionsPopupMenu.getMenuInflater().inflate(R.menu.track_segment_menu, menu);
|
optionsPopupMenu.getMenuInflater().inflate(R.menu.track_segment_menu, menu);
|
||||||
menu.findItem(R.id.action_edit).setIcon(app.getUIUtilities().getThemedIcon(R.drawable.ic_action_edit_dark));
|
menu.findItem(R.id.action_edit).setIcon(app.getUIUtilities().getThemedIcon(R.drawable.ic_action_edit_dark));
|
||||||
menu.findItem(R.id.action_delete).setIcon(app.getUIUtilities().getThemedIcon(R.drawable.ic_action_remove_dark));
|
menu.findItem(R.id.action_delete).setIcon(app.getUIUtilities().getThemedIcon(R.drawable.ic_action_remove_dark));
|
||||||
|
if (displayHelper.getGpx().showCurrentTrack) {
|
||||||
|
menu.findItem(R.id.split_interval).setVisible(false);
|
||||||
|
} else {
|
||||||
|
menu.findItem(R.id.split_interval).setIcon(app.getUIUtilities().getThemedIcon(R.drawable.ic_action_split_interval));
|
||||||
|
}
|
||||||
optionsPopupMenu.setOnMenuItemClickListener(new IconPopupMenu.OnMenuItemClickListener() {
|
optionsPopupMenu.setOnMenuItemClickListener(new IconPopupMenu.OnMenuItemClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onMenuItemClick(MenuItem item) {
|
public boolean onMenuItemClick(MenuItem item) {
|
||||||
|
@ -389,6 +341,8 @@ public class TrackSegmentFragment extends OsmAndListFragment implements TrackBit
|
||||||
builder.show();
|
builder.show();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
} else if (i == R.id.split_interval) {
|
||||||
|
openSplitInterval(gpxItem, segment);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@ import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static net.osmand.util.Algorithms.isEmpty;
|
||||||
|
|
||||||
public class OnlineRoutingHelper {
|
public class OnlineRoutingHelper {
|
||||||
|
|
||||||
private static final Log LOG = PlatformUtil.getLog(OnlineRoutingHelper.class);
|
private static final Log LOG = PlatformUtil.getLog(OnlineRoutingHelper.class);
|
||||||
|
@ -71,12 +73,21 @@ public class OnlineRoutingHelper {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@Nullable
|
||||||
public List<LatLon> calculateRouteOnline(@NonNull OnlineRoutingEngine engine,
|
public OnlineRoutingResponse calculateRouteOnline(@Nullable String stringKey,
|
||||||
@NonNull List<LatLon> path) throws IOException, JSONException {
|
@NonNull List<LatLon> path,
|
||||||
|
boolean leftSideNavigation) throws IOException, JSONException {
|
||||||
|
OnlineRoutingEngine engine = getEngineByKey(stringKey);
|
||||||
|
return engine != null ? calculateRouteOnline(engine, path, leftSideNavigation) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public OnlineRoutingResponse calculateRouteOnline(@NonNull OnlineRoutingEngine engine,
|
||||||
|
@NonNull List<LatLon> path,
|
||||||
|
boolean leftSideNavigation) throws IOException, JSONException {
|
||||||
String url = engine.getFullUrl(path);
|
String url = engine.getFullUrl(path);
|
||||||
String content = makeRequest(url);
|
String content = makeRequest(url);
|
||||||
return engine.parseServerResponse(content);
|
return engine.parseServerResponse(content, leftSideNavigation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
|
@ -131,7 +142,7 @@ public class OnlineRoutingHelper {
|
||||||
@NonNull
|
@NonNull
|
||||||
private String createEngineKeyIfNeeded(@NonNull OnlineRoutingEngine engine) {
|
private String createEngineKeyIfNeeded(@NonNull OnlineRoutingEngine engine) {
|
||||||
String key = engine.get(EngineParameter.KEY);
|
String key = engine.get(EngineParameter.KEY);
|
||||||
if (Algorithms.isEmpty(key)) {
|
if (isEmpty(key)) {
|
||||||
key = OnlineRoutingEngine.generateKey();
|
key = OnlineRoutingEngine.generateKey();
|
||||||
engine.put(EngineParameter.KEY, key);
|
engine.put(EngineParameter.KEY, key);
|
||||||
}
|
}
|
||||||
|
@ -151,7 +162,7 @@ public class OnlineRoutingHelper {
|
||||||
private List<OnlineRoutingEngine> readFromSettings() {
|
private List<OnlineRoutingEngine> readFromSettings() {
|
||||||
List<OnlineRoutingEngine> engines = new ArrayList<>();
|
List<OnlineRoutingEngine> engines = new ArrayList<>();
|
||||||
String jsonString = settings.ONLINE_ROUTING_ENGINES.get();
|
String jsonString = settings.ONLINE_ROUTING_ENGINES.get();
|
||||||
if (!Algorithms.isEmpty(jsonString)) {
|
if (!isEmpty(jsonString)) {
|
||||||
try {
|
try {
|
||||||
JSONObject json = new JSONObject(jsonString);
|
JSONObject json = new JSONObject(jsonString);
|
||||||
OnlineRoutingUtils.readFromJson(json, engines);
|
OnlineRoutingUtils.readFromJson(json, engines);
|
||||||
|
@ -163,7 +174,7 @@ public class OnlineRoutingHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveCacheToSettings() {
|
private void saveCacheToSettings() {
|
||||||
if (!Algorithms.isEmpty(cachedEngines)) {
|
if (!isEmpty(cachedEngines)) {
|
||||||
try {
|
try {
|
||||||
JSONObject json = new JSONObject();
|
JSONObject json = new JSONObject();
|
||||||
OnlineRoutingUtils.writeToJson(json, getEngines());
|
OnlineRoutingUtils.writeToJson(json, getEngines());
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
package net.osmand.plus.onlinerouting;
|
||||||
|
|
||||||
|
import net.osmand.Location;
|
||||||
|
import net.osmand.plus.routing.RouteDirectionInfo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class OnlineRoutingResponse {
|
||||||
|
private List<Location> route;
|
||||||
|
private List<RouteDirectionInfo> directions;
|
||||||
|
|
||||||
|
public OnlineRoutingResponse(List<Location> route, List<RouteDirectionInfo> directions) {
|
||||||
|
this.route = route;
|
||||||
|
this.directions = directions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Location> getRoute() {
|
||||||
|
return route;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<RouteDirectionInfo> getDirections() {
|
||||||
|
return directions;
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,15 +3,21 @@ package net.osmand.plus.onlinerouting.engine;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import net.osmand.Location;
|
||||||
import net.osmand.data.LatLon;
|
import net.osmand.data.LatLon;
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
import net.osmand.plus.onlinerouting.EngineParameter;
|
import net.osmand.plus.onlinerouting.EngineParameter;
|
||||||
|
import net.osmand.plus.onlinerouting.OnlineRoutingResponse;
|
||||||
import net.osmand.plus.onlinerouting.VehicleType;
|
import net.osmand.plus.onlinerouting.VehicleType;
|
||||||
|
import net.osmand.plus.routing.RouteDirectionInfo;
|
||||||
|
import net.osmand.router.TurnType;
|
||||||
import net.osmand.util.GeoPolylineParserUtil;
|
import net.osmand.util.GeoPolylineParserUtil;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -23,8 +29,9 @@ public class GraphhopperEngine extends OnlineRoutingEngine {
|
||||||
super(params);
|
super(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public @NonNull EngineType getType() {
|
public EngineType getType() {
|
||||||
return EngineType.GRAPHHOPPER;
|
return EngineType.GRAPHHOPPER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,15 +78,49 @@ public class GraphhopperEngine extends OnlineRoutingEngine {
|
||||||
if (!isEmpty(apiKey)) {
|
if (!isEmpty(apiKey)) {
|
||||||
sb.append('&').append("key=").append(apiKey);
|
sb.append('&').append("key=").append(apiKey);
|
||||||
}
|
}
|
||||||
|
sb.append('&').append("details=").append("lanes");
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public List<LatLon> parseServerResponse(@NonNull String content) throws JSONException {
|
public OnlineRoutingResponse parseServerResponse(@NonNull String content,
|
||||||
|
boolean leftSideNavigation) throws JSONException {
|
||||||
JSONObject obj = new JSONObject(content);
|
JSONObject obj = new JSONObject(content);
|
||||||
return GeoPolylineParserUtil.parse(
|
JSONObject root = obj.getJSONArray("paths").getJSONObject(0);
|
||||||
obj.getJSONArray("paths").getJSONObject(0).getString("points"),
|
|
||||||
GeoPolylineParserUtil.PRECISION_5);
|
String encoded = root.getString("points");
|
||||||
|
List<LatLon> points = GeoPolylineParserUtil.parse(encoded, GeoPolylineParserUtil.PRECISION_5);
|
||||||
|
if (isEmpty(points)) return null;
|
||||||
|
List<Location> route = convertRouteToLocationsList(points);
|
||||||
|
|
||||||
|
JSONArray instructions = root.getJSONArray("instructions");
|
||||||
|
List<RouteDirectionInfo> directions = new ArrayList<>();
|
||||||
|
for (int i = 0; i < instructions.length(); i++) {
|
||||||
|
JSONObject item = instructions.getJSONObject(i);
|
||||||
|
int sign = Integer.parseInt(item.getString("sign"));
|
||||||
|
int distance = (int) Math.round(Double.parseDouble(item.getString("distance")));
|
||||||
|
String description = item.getString("text");
|
||||||
|
String streetName = item.getString("street_name");
|
||||||
|
int timeInSeconds = (int) Math.round(Integer.parseInt(item.getString("time")) / 1000f);
|
||||||
|
JSONArray interval = item.getJSONArray("interval");
|
||||||
|
int startPointOffset = interval.getInt(0);
|
||||||
|
int endPointOffset = interval.getInt(1);
|
||||||
|
|
||||||
|
float averageSpeed = (float) distance / timeInSeconds;
|
||||||
|
TurnType turnType = identifyTurnType(sign, leftSideNavigation);
|
||||||
|
// TODO turnType.setTurnAngle()
|
||||||
|
|
||||||
|
RouteDirectionInfo direction = new RouteDirectionInfo(averageSpeed, turnType);
|
||||||
|
direction.routePointOffset = startPointOffset;
|
||||||
|
if (turnType != null && turnType.isRoundAbout()) {
|
||||||
|
direction.routeEndPointOffset = endPointOffset;
|
||||||
|
}
|
||||||
|
direction.setDescriptionRoute(description);
|
||||||
|
direction.setStreetName(streetName);
|
||||||
|
direction.setDistance(distance);
|
||||||
|
directions.add(direction);
|
||||||
|
}
|
||||||
|
return new OnlineRoutingResponse(route, directions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -92,4 +133,82 @@ public class GraphhopperEngine extends OnlineRoutingEngine {
|
||||||
}
|
}
|
||||||
return obj.has("paths");
|
return obj.has("paths");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param sign - a number which specifies the turn type to show (Graphhopper API value)
|
||||||
|
* @return a TurnType object defined in OsmAnd which is equivalent to a value from the Graphhopper API
|
||||||
|
*
|
||||||
|
* For future compatibility it is important that all clients
|
||||||
|
* are able to handle also unknown instruction sign numbers
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public static TurnType identifyTurnType(int sign, boolean leftSide) {
|
||||||
|
int id = INVALID_ID;
|
||||||
|
|
||||||
|
if (sign == -98) {
|
||||||
|
// an U-turn without the knowledge
|
||||||
|
// if it is a right or left U-turn
|
||||||
|
id = TurnType.TU;
|
||||||
|
|
||||||
|
} else if (sign == -8) {
|
||||||
|
// a left U-turn
|
||||||
|
leftSide = false;
|
||||||
|
id = TurnType.TU;
|
||||||
|
|
||||||
|
} else if (sign == -7) {
|
||||||
|
// keep left
|
||||||
|
id = TurnType.KL;
|
||||||
|
|
||||||
|
} else if (sign == -6) {
|
||||||
|
// not yet used: leave roundabout
|
||||||
|
|
||||||
|
} else if (sign == -3) {
|
||||||
|
// turn sharp left
|
||||||
|
id = TurnType.TSHL;
|
||||||
|
|
||||||
|
} else if (sign == -2) {
|
||||||
|
// turn left
|
||||||
|
id = TurnType.TL;
|
||||||
|
|
||||||
|
} else if (sign == -1) {
|
||||||
|
// turn slight left
|
||||||
|
id = TurnType.TSLL;
|
||||||
|
|
||||||
|
} else if (sign == 0) {
|
||||||
|
// continue on street
|
||||||
|
id = TurnType.C;
|
||||||
|
|
||||||
|
} else if (sign == 1) {
|
||||||
|
// turn slight right
|
||||||
|
id = TurnType.TSLR;
|
||||||
|
|
||||||
|
} else if (sign == 2) {
|
||||||
|
// turn right
|
||||||
|
id = TurnType.TR;
|
||||||
|
|
||||||
|
} else if (sign == 3) {
|
||||||
|
// turn sharp right
|
||||||
|
id = TurnType.TSHR;
|
||||||
|
|
||||||
|
} else if (sign == 4) {
|
||||||
|
// the finish instruction before the last point
|
||||||
|
|
||||||
|
} else if (sign == 5) {
|
||||||
|
// the instruction before a via point
|
||||||
|
|
||||||
|
} else if (sign == 6) {
|
||||||
|
// the instruction before entering a roundabout
|
||||||
|
id = TurnType.RNDB;
|
||||||
|
|
||||||
|
} else if (sign == 7) {
|
||||||
|
// keep right
|
||||||
|
id = TurnType.KR;
|
||||||
|
|
||||||
|
} else if (sign == 8) {
|
||||||
|
// a right U-turn
|
||||||
|
id = TurnType.TRU;
|
||||||
|
}
|
||||||
|
|
||||||
|
return id != INVALID_ID ? TurnType.valueOf(id, leftSide) : null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,11 +5,15 @@ import android.content.Context;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import net.osmand.GPXUtilities.WptPt;
|
||||||
|
import net.osmand.Location;
|
||||||
import net.osmand.data.LatLon;
|
import net.osmand.data.LatLon;
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
import net.osmand.plus.onlinerouting.EngineParameter;
|
import net.osmand.plus.onlinerouting.EngineParameter;
|
||||||
import net.osmand.plus.onlinerouting.OnlineRoutingFactory;
|
import net.osmand.plus.onlinerouting.OnlineRoutingFactory;
|
||||||
|
import net.osmand.plus.onlinerouting.OnlineRoutingResponse;
|
||||||
import net.osmand.plus.onlinerouting.VehicleType;
|
import net.osmand.plus.onlinerouting.VehicleType;
|
||||||
|
import net.osmand.plus.routing.RouteProvider;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
|
@ -28,7 +32,8 @@ import static net.osmand.util.Algorithms.isEmpty;
|
||||||
public abstract class OnlineRoutingEngine implements Cloneable {
|
public abstract class OnlineRoutingEngine implements Cloneable {
|
||||||
|
|
||||||
public final static String ONLINE_ROUTING_ENGINE_PREFIX = "online_routing_engine_";
|
public final static String ONLINE_ROUTING_ENGINE_PREFIX = "online_routing_engine_";
|
||||||
public static final VehicleType CUSTOM_VEHICLE = new VehicleType("", R.string.shared_string_custom);
|
public final static VehicleType CUSTOM_VEHICLE = new VehicleType("", R.string.shared_string_custom);
|
||||||
|
public final static int INVALID_ID = -1;
|
||||||
|
|
||||||
private final Map<String, String> params = new HashMap<>();
|
private final Map<String, String> params = new HashMap<>();
|
||||||
private final List<VehicleType> allowedVehicles = new ArrayList<>();
|
private final List<VehicleType> allowedVehicles = new ArrayList<>();
|
||||||
|
@ -71,15 +76,6 @@ public abstract class OnlineRoutingEngine implements Cloneable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public String getBaseUrl() {
|
|
||||||
String customUrl = get(EngineParameter.CUSTOM_URL);
|
|
||||||
if (isEmpty(customUrl)) {
|
|
||||||
return getStandardUrl();
|
|
||||||
}
|
|
||||||
return customUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public String getFullUrl(@NonNull List<LatLon> path) {
|
public String getFullUrl(@NonNull List<LatLon> path) {
|
||||||
StringBuilder sb = new StringBuilder(getBaseUrl());
|
StringBuilder sb = new StringBuilder(getBaseUrl());
|
||||||
|
@ -91,11 +87,35 @@ public abstract class OnlineRoutingEngine implements Cloneable {
|
||||||
@NonNull List<LatLon> path);
|
@NonNull List<LatLon> path);
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public abstract List<LatLon> parseServerResponse(@NonNull String content) throws JSONException;
|
public String getBaseUrl() {
|
||||||
|
String customUrl = get(EngineParameter.CUSTOM_URL);
|
||||||
|
if (isEmpty(customUrl)) {
|
||||||
|
return getStandardUrl();
|
||||||
|
}
|
||||||
|
return customUrl;
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public abstract String getStandardUrl();
|
public abstract String getStandardUrl();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public abstract OnlineRoutingResponse parseServerResponse(@NonNull String content,
|
||||||
|
boolean leftSideNavigation) throws JSONException;
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
protected List<Location> convertRouteToLocationsList(@NonNull List<LatLon> route) {
|
||||||
|
List<Location> result = new ArrayList<>();
|
||||||
|
if (!isEmpty(route)) {
|
||||||
|
for (LatLon pt : route) {
|
||||||
|
WptPt wpt = new WptPt();
|
||||||
|
wpt.lat = pt.getLatitude();
|
||||||
|
wpt.lon = pt.getLongitude();
|
||||||
|
result.add(RouteProvider.createLocation(wpt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public Map<String, String> getParams() {
|
public Map<String, String> getParams() {
|
||||||
return params;
|
return params;
|
||||||
|
|
|
@ -3,9 +3,11 @@ package net.osmand.plus.onlinerouting.engine;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import net.osmand.Location;
|
||||||
import net.osmand.data.LatLon;
|
import net.osmand.data.LatLon;
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
import net.osmand.plus.onlinerouting.EngineParameter;
|
import net.osmand.plus.onlinerouting.EngineParameter;
|
||||||
|
import net.osmand.plus.onlinerouting.OnlineRoutingResponse;
|
||||||
import net.osmand.plus.onlinerouting.VehicleType;
|
import net.osmand.plus.onlinerouting.VehicleType;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
|
@ -24,8 +26,9 @@ public class OrsEngine extends OnlineRoutingEngine {
|
||||||
super(params);
|
super(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public @NonNull EngineType getType() {
|
public EngineType getType() {
|
||||||
return EngineType.ORS;
|
return EngineType.ORS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,20 +78,25 @@ public class OrsEngine extends OnlineRoutingEngine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public List<LatLon> parseServerResponse(@NonNull String content) throws JSONException {
|
public OnlineRoutingResponse parseServerResponse(@NonNull String content,
|
||||||
|
boolean leftSideNavigation) throws JSONException {
|
||||||
JSONObject obj = new JSONObject(content);
|
JSONObject obj = new JSONObject(content);
|
||||||
JSONArray array = obj.getJSONArray("features").getJSONObject(0)
|
JSONArray array = obj.getJSONArray("features").getJSONObject(0)
|
||||||
.getJSONObject("geometry").getJSONArray("coordinates");
|
.getJSONObject("geometry").getJSONArray("coordinates");
|
||||||
List<LatLon> track = new ArrayList<>();
|
List<LatLon> points = new ArrayList<>();
|
||||||
for (int i = 0; i < array.length(); i++) {
|
for (int i = 0; i < array.length(); i++) {
|
||||||
JSONArray point = array.getJSONArray(i);
|
JSONArray point = array.getJSONArray(i);
|
||||||
double lon = Double.parseDouble(point.getString(0));
|
double lon = Double.parseDouble(point.getString(0));
|
||||||
double lat = Double.parseDouble(point.getString(1));
|
double lat = Double.parseDouble(point.getString(1));
|
||||||
track.add(new LatLon(lat, lon));
|
points.add(new LatLon(lat, lon));
|
||||||
}
|
}
|
||||||
return track;
|
if (!isEmpty(points)) {
|
||||||
|
List<Location> route = convertRouteToLocationsList(points);
|
||||||
|
new OnlineRoutingResponse(route, null);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -3,9 +3,11 @@ package net.osmand.plus.onlinerouting.engine;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import net.osmand.Location;
|
||||||
import net.osmand.data.LatLon;
|
import net.osmand.data.LatLon;
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
import net.osmand.plus.onlinerouting.EngineParameter;
|
import net.osmand.plus.onlinerouting.EngineParameter;
|
||||||
|
import net.osmand.plus.onlinerouting.OnlineRoutingResponse;
|
||||||
import net.osmand.plus.onlinerouting.VehicleType;
|
import net.osmand.plus.onlinerouting.VehicleType;
|
||||||
import net.osmand.util.GeoPolylineParserUtil;
|
import net.osmand.util.GeoPolylineParserUtil;
|
||||||
|
|
||||||
|
@ -24,7 +26,8 @@ public class OsrmEngine extends OnlineRoutingEngine {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull EngineType getType() {
|
public @NonNull
|
||||||
|
EngineType getType() {
|
||||||
return EngineType.OSRM;
|
return EngineType.OSRM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +38,8 @@ public class OsrmEngine extends OnlineRoutingEngine {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void collectAllowedParameters() { }
|
protected void collectAllowedParameters() {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void collectAllowedVehicles(@NonNull List<VehicleType> vehicles) {
|
protected void collectAllowedVehicles(@NonNull List<VehicleType> vehicles) {
|
||||||
|
@ -60,15 +64,21 @@ public class OsrmEngine extends OnlineRoutingEngine {
|
||||||
}
|
}
|
||||||
sb.append('?');
|
sb.append('?');
|
||||||
sb.append("overview=full");
|
sb.append("overview=full");
|
||||||
|
sb.append('&').append("steps=true");
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public List<LatLon> parseServerResponse(@NonNull String content) throws JSONException {
|
public OnlineRoutingResponse parseServerResponse(@NonNull String content,
|
||||||
|
boolean leftSideNavigation) throws JSONException {
|
||||||
JSONObject obj = new JSONObject(content);
|
JSONObject obj = new JSONObject(content);
|
||||||
return GeoPolylineParserUtil.parse(
|
String encoded = obj.getJSONArray("routes").getJSONObject(0).getString("geometry");
|
||||||
obj.getJSONArray("routes").getJSONObject(0).getString("geometry"),
|
List<LatLon> points = GeoPolylineParserUtil.parse(encoded, GeoPolylineParserUtil.PRECISION_5);
|
||||||
GeoPolylineParserUtil.PRECISION_5);
|
if (!isEmpty(points)) {
|
||||||
|
List<Location> route = convertRouteToLocationsList(points);
|
||||||
|
return new OnlineRoutingResponse(route, null);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -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) {
|
|
||||||
VehicleType vt = (VehicleType) item;
|
|
||||||
boolean hasPadding = vt.equals(OnlineRoutingEngine.CUSTOM_VEHICLE);
|
|
||||||
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) rvSelectionMenu.getLayoutParams();
|
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) rvSelectionMenu.getLayoutParams();
|
||||||
int contentPadding = app.getResources().getDimensionPixelSize(R.dimen.content_padding);
|
int contentPadding = app.getResources().getDimensionPixelSize(R.dimen.content_padding);
|
||||||
params.bottomMargin = hasPadding ? contentPadding : 0;
|
params.bottomMargin = isVisibleViewsBelowSelectionMenu() ? 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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,14 +111,14 @@ public class OpenstreetmapPoint extends OsmPoint {
|
||||||
boolean res = this.getName() != null && this.getName().equals(otherPoint.getName());
|
boolean res = this.getName() != null && this.getName().equals(otherPoint.getName());
|
||||||
LatLon thisLatLon = new LatLon(this.getLatitude(), this.getLongitude());
|
LatLon thisLatLon = new LatLon(this.getLatitude(), this.getLongitude());
|
||||||
LatLon otherLatLon = new LatLon(otherPoint.getLatitude(), otherPoint.getLongitude());
|
LatLon otherLatLon = new LatLon(otherPoint.getLatitude(), otherPoint.getLongitude());
|
||||||
res = res || thisLatLon.equals(otherLatLon);
|
res = res && thisLatLon.equals(otherLatLon);
|
||||||
if (getType() != null)
|
if (getType() != null)
|
||||||
res = res || getType().equals(otherPoint.getType());
|
res = res && getType().equals(otherPoint.getType());
|
||||||
if (getSubtype() != null)
|
if (getSubtype() != null)
|
||||||
res = res || getSubtype().equals(otherPoint.getSubtype());
|
res = res && getSubtype().equals(otherPoint.getSubtype());
|
||||||
if (getTagsString() != null)
|
if (getTagsString() != null)
|
||||||
res = res || getTagsString().equals(otherPoint.getTagsString());
|
res = res && getTagsString().equals(otherPoint.getTagsString());
|
||||||
res = res || getId() == otherPoint.getId();
|
res = res && getId() == otherPoint.getId();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,9 @@ public class OsmNotesPoint extends OsmPoint {
|
||||||
LatLon thisPos = new LatLon(latitude, longitude);
|
LatLon thisPos = new LatLon(latitude, longitude);
|
||||||
LatLon thatPos = new LatLon(that.latitude, that.longitude);
|
LatLon thatPos = new LatLon(that.latitude, that.longitude);
|
||||||
boolean res = thisPos.equals(thatPos);
|
boolean res = thisPos.equals(thatPos);
|
||||||
res = res || text != null && text.equals(that.text);
|
if (text != null) {
|
||||||
|
res = res && text.equals(that.text);
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -711,7 +711,7 @@ public class RouteCalculationResult {
|
||||||
if (directions != null && directions.size() > 1) {
|
if (directions != null && directions.size() > 1) {
|
||||||
for (int i = 1; i < directions.size();) {
|
for (int i = 1; i < directions.size();) {
|
||||||
RouteDirectionInfo r = directions.get(i);
|
RouteDirectionInfo r = directions.get(i);
|
||||||
if (r.getTurnType().getValue() == TurnType.C) {
|
if (r.getTurnType() != null && r.getTurnType().getValue() == TurnType.C) {
|
||||||
RouteDirectionInfo prev = directions.get(i - 1);
|
RouteDirectionInfo prev = directions.get(i - 1);
|
||||||
prev.setAverageSpeed((prev.distance + r.distance)
|
prev.setAverageSpeed((prev.distance + r.distance)
|
||||||
/ (prev.distance / prev.getAverageSpeed() + r.distance / r.getAverageSpeed()));
|
/ (prev.distance / prev.getAverageSpeed() + r.distance / r.getAverageSpeed()));
|
||||||
|
|
|
@ -21,7 +21,7 @@ import net.osmand.data.LocationPoint;
|
||||||
import net.osmand.data.WptLocationPoint;
|
import net.osmand.data.WptLocationPoint;
|
||||||
import net.osmand.plus.OsmandApplication;
|
import net.osmand.plus.OsmandApplication;
|
||||||
import net.osmand.plus.onlinerouting.OnlineRoutingHelper;
|
import net.osmand.plus.onlinerouting.OnlineRoutingHelper;
|
||||||
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
|
import net.osmand.plus.onlinerouting.OnlineRoutingResponse;
|
||||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||||
import net.osmand.plus.settings.backend.CommonPreference;
|
import net.osmand.plus.settings.backend.CommonPreference;
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
|
@ -326,7 +326,7 @@ public class RouteProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Location createLocation(WptPt pt){
|
public static Location createLocation(WptPt pt){
|
||||||
Location loc = new Location("OsmandRouteProvider");
|
Location loc = new Location("OsmandRouteProvider");
|
||||||
loc.setLatitude(pt.lat);
|
loc.setLatitude(pt.lat);
|
||||||
loc.setLongitude(pt.lon);
|
loc.setLongitude(pt.lon);
|
||||||
|
@ -1202,27 +1202,17 @@ public class RouteProvider {
|
||||||
private RouteCalculationResult findOnlineRoute(RouteCalculationParams params) throws IOException, JSONException {
|
private RouteCalculationResult findOnlineRoute(RouteCalculationParams params) throws IOException, JSONException {
|
||||||
OnlineRoutingHelper helper = params.ctx.getOnlineRoutingHelper();
|
OnlineRoutingHelper helper = params.ctx.getOnlineRoutingHelper();
|
||||||
String stringKey = params.mode.getRoutingProfile();
|
String stringKey = params.mode.getRoutingProfile();
|
||||||
OnlineRoutingEngine engine = helper.getEngineByKey(stringKey);
|
OnlineRoutingResponse response =
|
||||||
List<LatLon> route = null;
|
helper.calculateRouteOnline(stringKey, getPathFromParams(params), params.leftSide);
|
||||||
if (engine != null) {
|
if (response != null) {
|
||||||
route = helper.calculateRouteOnline(engine, getFullPathFromParams(params));
|
|
||||||
}
|
|
||||||
if (!Algorithms.isEmpty(route)) {
|
|
||||||
List<Location> res = new ArrayList<>();
|
|
||||||
for (LatLon pt : route) {
|
|
||||||
WptPt wpt = new WptPt();
|
|
||||||
wpt.lat = pt.getLatitude();
|
|
||||||
wpt.lon = pt.getLongitude();
|
|
||||||
res.add(createLocation(wpt));
|
|
||||||
}
|
|
||||||
params.intermediates = null;
|
params.intermediates = null;
|
||||||
return new RouteCalculationResult(res, null, params, null, true);
|
return new RouteCalculationResult(response.getRoute(), response.getDirections(), params, null, true);
|
||||||
} else {
|
} else {
|
||||||
return new RouteCalculationResult("Route is empty");
|
return new RouteCalculationResult("Route is empty");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<LatLon> getFullPathFromParams(RouteCalculationParams params) {
|
private static List<LatLon> getPathFromParams(RouteCalculationParams params) {
|
||||||
List<LatLon> points = new ArrayList<>();
|
List<LatLon> points = new ArrayList<>();
|
||||||
points.add(new LatLon(params.start.getLatitude(), params.start.getLongitude()));
|
points.add(new LatLon(params.start.getLatitude(), params.start.getLongitude()));
|
||||||
if (Algorithms.isEmpty(params.intermediates)) {
|
if (Algorithms.isEmpty(params.intermediates)) {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -122,14 +122,14 @@ public class BooleanPreferenceBottomSheet extends BasePreferenceBottomSheet {
|
||||||
return R.string.shared_string_close;
|
return R.string.shared_string_close;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static View getCustomButtonView(OsmandApplication app, ApplicationMode mode, boolean checked, boolean nightMode) {
|
public static View getCustomButtonView(OsmandApplication app, ApplicationMode mode, boolean checked, boolean nightMode) {
|
||||||
View customView = UiUtilities.getInflater(app, nightMode).inflate(R.layout.bottom_sheet_item_preference_switch, null);
|
View customView = UiUtilities.getInflater(app, nightMode).inflate(R.layout.bottom_sheet_item_preference_switch, null);
|
||||||
updateCustomButtonView(app, mode, customView, checked, nightMode);
|
updateCustomButtonView(app, mode, customView, checked, nightMode);
|
||||||
|
|
||||||
return customView;
|
return customView;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void updateCustomButtonView(OsmandApplication app, ApplicationMode mode, View customView, boolean checked, boolean nightMode) {
|
public static void updateCustomButtonView(OsmandApplication app, ApplicationMode mode, View customView, boolean checked, boolean nightMode) {
|
||||||
Context themedCtx = UiUtilities.getThemedContext(app, nightMode);
|
Context themedCtx = UiUtilities.getThemedContext(app, nightMode);
|
||||||
View buttonView = customView.findViewById(R.id.button_container);
|
View buttonView = customView.findViewById(R.id.button_container);
|
||||||
|
|
||||||
|
|
102
OsmAnd/src/net/osmand/plus/track/DescriptionCard.java
Normal file
102
OsmAnd/src/net/osmand/plus/track/DescriptionCard.java
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
package net.osmand.plus.track;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.widget.AppCompatImageView;
|
||||||
|
|
||||||
|
import com.squareup.picasso.Callback;
|
||||||
|
import com.squareup.picasso.Picasso;
|
||||||
|
import com.squareup.picasso.RequestCreator;
|
||||||
|
|
||||||
|
import net.osmand.GPXUtilities.GPXFile;
|
||||||
|
import net.osmand.PicassoUtils;
|
||||||
|
import net.osmand.plus.R;
|
||||||
|
import net.osmand.plus.activities.MapActivity;
|
||||||
|
import net.osmand.plus.helpers.AndroidUiHelper;
|
||||||
|
import net.osmand.plus.routepreparationmenu.cards.BaseCard;
|
||||||
|
import net.osmand.plus.widgets.TextViewEx;
|
||||||
|
import net.osmand.plus.wikipedia.WikiArticleHelper;
|
||||||
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
|
import static net.osmand.plus.myplaces.TrackActivityFragmentAdapter.getMetadataImageLink;
|
||||||
|
|
||||||
|
public class DescriptionCard extends BaseCard {
|
||||||
|
|
||||||
|
private final GPXFile gpxFile;
|
||||||
|
|
||||||
|
public DescriptionCard(@NonNull MapActivity mapActivity, @NonNull GPXFile gpxFile) {
|
||||||
|
super(mapActivity);
|
||||||
|
this.gpxFile = gpxFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCardLayoutId() {
|
||||||
|
return R.layout.gpx_description_preview_card;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateContent() {
|
||||||
|
if (gpxFile.metadata == null || gpxFile.metadata.getDescription() == null) {
|
||||||
|
AndroidUiHelper.updateVisibility(view, false);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
AndroidUiHelper.updateVisibility(view, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
final String title = gpxFile.metadata.getArticleTitle();
|
||||||
|
final String imageUrl = getMetadataImageLink(gpxFile.metadata);
|
||||||
|
final String descriptionHtml = gpxFile.metadata.getDescription();
|
||||||
|
|
||||||
|
setupImage(imageUrl);
|
||||||
|
|
||||||
|
TextViewEx tvDescription = view.findViewById(R.id.description);
|
||||||
|
tvDescription.setText(getFirstParagraph(descriptionHtml));
|
||||||
|
|
||||||
|
TextViewEx readBtn = view.findViewById(R.id.btn_read_full);
|
||||||
|
readBtn.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
GpxReadDescriptionDialogFragment.showInstance(mapActivity, title, imageUrl, descriptionHtml);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
TextViewEx editBtn = view.findViewById(R.id.btn_edit);
|
||||||
|
editBtn.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
GpxEditDescriptionDialogFragment.showInstance(mapActivity, descriptionHtml, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getFirstParagraph(String descriptionHtml) {
|
||||||
|
if (descriptionHtml != null) {
|
||||||
|
String firstParagraph = WikiArticleHelper.getPartialContent(descriptionHtml);
|
||||||
|
if (!Algorithms.isEmpty(firstParagraph)) {
|
||||||
|
return firstParagraph;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return descriptionHtml;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupImage(final String imageUrl) {
|
||||||
|
if (imageUrl == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final PicassoUtils picasso = PicassoUtils.getPicasso(app);
|
||||||
|
RequestCreator rc = Picasso.get().load(imageUrl);
|
||||||
|
final AppCompatImageView image = view.findViewById(R.id.main_image);
|
||||||
|
rc.into(image, new Callback() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess() {
|
||||||
|
picasso.setResultLoaded(imageUrl, true);
|
||||||
|
AndroidUiHelper.updateVisibility(image, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Exception e) {
|
||||||
|
picasso.setResultLoaded(imageUrl, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,131 @@
|
||||||
|
package net.osmand.plus.track;
|
||||||
|
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.fragment.app.FragmentActivity;
|
||||||
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
|
||||||
|
import net.osmand.GPXUtilities.GPXFile;
|
||||||
|
import net.osmand.PlatformUtil;
|
||||||
|
import net.osmand.plus.OsmandApplication;
|
||||||
|
import net.osmand.plus.R;
|
||||||
|
import net.osmand.plus.UiUtilities;
|
||||||
|
import net.osmand.plus.activities.MapActivity;
|
||||||
|
import net.osmand.plus.base.BaseOsmAndDialogFragment;
|
||||||
|
import net.osmand.plus.track.SaveGpxAsyncTask.SaveGpxListener;
|
||||||
|
import net.osmand.plus.widgets.EditTextEx;
|
||||||
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public class GpxEditDescriptionDialogFragment extends BaseOsmAndDialogFragment {
|
||||||
|
|
||||||
|
public static final String TAG = GpxEditDescriptionDialogFragment.class.getSimpleName();
|
||||||
|
private static final Log log = PlatformUtil.getLog(GpxEditDescriptionDialogFragment.class);
|
||||||
|
|
||||||
|
private static final String CONTENT_KEY = "content_key";
|
||||||
|
|
||||||
|
private EditTextEx editableHtml;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||||
|
OsmandApplication app = getMyApplication();
|
||||||
|
boolean nightMode = app.getDaynightHelper().isNightModeForMapControls();
|
||||||
|
LayoutInflater themedInflater = UiUtilities.getInflater(requireContext(), nightMode);
|
||||||
|
View view = themedInflater.inflate(R.layout.dialog_edit_gpx_description, container, false);
|
||||||
|
|
||||||
|
editableHtml = view.findViewById(R.id.description);
|
||||||
|
|
||||||
|
view.findViewById(R.id.btn_close).setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
dismiss();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
view.findViewById(R.id.btn_save).setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Editable editable = editableHtml.getText();
|
||||||
|
if (!Algorithms.isEmpty(editable) && !saveGpx(editable.toString())) {
|
||||||
|
dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Bundle args = getArguments();
|
||||||
|
if (args != null) {
|
||||||
|
String html = args.getString(CONTENT_KEY);
|
||||||
|
if (html != null) {
|
||||||
|
editableHtml.setText(html);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean saveGpx(final String html) {
|
||||||
|
MapActivity mapActivity = getMapActivity();
|
||||||
|
if (mapActivity == null || mapActivity.getTrackMenuFragment() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
TrackMenuFragment trackMenuFragment = mapActivity.getTrackMenuFragment();
|
||||||
|
|
||||||
|
GPXFile gpx = trackMenuFragment.getGpx();
|
||||||
|
gpx.metadata.getExtensionsToWrite().put("desc", html);
|
||||||
|
|
||||||
|
File file = trackMenuFragment.getDisplayHelper().getFile();
|
||||||
|
new SaveGpxAsyncTask(file, gpx, new SaveGpxListener() {
|
||||||
|
@Override
|
||||||
|
public void gpxSavingStarted() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void gpxSavingFinished(Exception errorMessage) {
|
||||||
|
if (errorMessage != null) {
|
||||||
|
log.error(errorMessage);
|
||||||
|
}
|
||||||
|
MapActivity mapActivity = getMapActivity();
|
||||||
|
if (mapActivity != null && mapActivity.getTrackMenuFragment() != null) {
|
||||||
|
TrackMenuFragment trackMenuFragment = mapActivity.getTrackMenuFragment();
|
||||||
|
trackMenuFragment.updateContent();
|
||||||
|
}
|
||||||
|
Fragment target = getTargetFragment();
|
||||||
|
if (target instanceof GpxReadDescriptionDialogFragment) {
|
||||||
|
((GpxReadDescriptionDialogFragment) target).updateContent(html);
|
||||||
|
}
|
||||||
|
dismiss();
|
||||||
|
}
|
||||||
|
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private MapActivity getMapActivity() {
|
||||||
|
return (MapActivity) getActivity();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void showInstance(@NonNull FragmentActivity activity, @NonNull String description, @Nullable Fragment target) {
|
||||||
|
FragmentManager fragmentManager = activity.getSupportFragmentManager();
|
||||||
|
if (!fragmentManager.isStateSaved()) {
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putString(CONTENT_KEY, description);
|
||||||
|
|
||||||
|
GpxEditDescriptionDialogFragment fragment = new GpxEditDescriptionDialogFragment();
|
||||||
|
fragment.setArguments(args);
|
||||||
|
fragment.setTargetFragment(target, 0);
|
||||||
|
fragment.show(fragmentManager, GpxEditDescriptionDialogFragment.TAG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,251 @@
|
||||||
|
package net.osmand.plus.track;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Base64;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.webkit.WebSettings;
|
||||||
|
import android.webkit.WebView;
|
||||||
|
import android.webkit.WebViewClient;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.widget.AppCompatImageView;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.fragment.app.FragmentActivity;
|
||||||
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
|
||||||
|
import com.squareup.picasso.Callback;
|
||||||
|
import com.squareup.picasso.Picasso;
|
||||||
|
import com.squareup.picasso.RequestCreator;
|
||||||
|
|
||||||
|
import net.osmand.AndroidUtils;
|
||||||
|
import net.osmand.PicassoUtils;
|
||||||
|
import net.osmand.plus.OsmandApplication;
|
||||||
|
import net.osmand.plus.R;
|
||||||
|
import net.osmand.plus.UiUtilities;
|
||||||
|
import net.osmand.plus.base.BaseOsmAndDialogFragment;
|
||||||
|
import net.osmand.plus.helpers.AndroidUiHelper;
|
||||||
|
import net.osmand.plus.widgets.TextViewEx;
|
||||||
|
import net.osmand.plus.widgets.WebViewEx;
|
||||||
|
import net.osmand.plus.wikivoyage.WikivoyageUtils;
|
||||||
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
|
public class GpxReadDescriptionDialogFragment extends BaseOsmAndDialogFragment {
|
||||||
|
|
||||||
|
public static final String TAG = GpxReadDescriptionDialogFragment.class.getSimpleName();
|
||||||
|
|
||||||
|
private static final String TITLE_KEY = "title_key";
|
||||||
|
private static final String IMAGE_URL_KEY = "image_url_key";
|
||||||
|
private static final String CONTENT_KEY = "content_key";
|
||||||
|
private static final int EDIT_ID = 1;
|
||||||
|
|
||||||
|
private WebViewEx webView;
|
||||||
|
|
||||||
|
private String title;
|
||||||
|
private String imageUrl;
|
||||||
|
private String contentHtml;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
Bundle args = getArguments();
|
||||||
|
if (savedInstanceState != null) {
|
||||||
|
readBundle(savedInstanceState);
|
||||||
|
} else if (args != null) {
|
||||||
|
readBundle(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readBundle(Bundle bundle) {
|
||||||
|
title = bundle.getString(TITLE_KEY);
|
||||||
|
imageUrl = bundle.getString(IMAGE_URL_KEY);
|
||||||
|
contentHtml = bundle.getString(CONTENT_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||||
|
OsmandApplication app = getMyApplication();
|
||||||
|
boolean nightMode = app.getDaynightHelper().isNightModeForMapControls();
|
||||||
|
LayoutInflater themedInflater = UiUtilities.getInflater(requireContext(), nightMode);
|
||||||
|
View view = themedInflater.inflate(R.layout.dialog_read_gpx_description, container, false);
|
||||||
|
|
||||||
|
setupToolbar(view);
|
||||||
|
setupImage(view);
|
||||||
|
setupWebView(view);
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
loadWebviewData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||||
|
if (item.getItemId() == EDIT_ID) {
|
||||||
|
FragmentActivity activity = getActivity();
|
||||||
|
if (activity != null) {
|
||||||
|
GpxEditDescriptionDialogFragment.showInstance(activity, contentHtml, this);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
|
||||||
|
menu.clear();
|
||||||
|
OsmandApplication app = getMyApplication();
|
||||||
|
int color = AndroidUtils.resolveAttribute(app, R.attr.pstsTextColor);
|
||||||
|
MenuItem menuItem = menu.add(0, EDIT_ID, 0, app.getString(R.string.shared_string_edit));
|
||||||
|
menuItem.setIcon(getIcon(R.drawable.ic_action_edit_dark, color));
|
||||||
|
menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onMenuItemClick(MenuItem item) {
|
||||||
|
return onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||||
|
super.onSaveInstanceState(outState);
|
||||||
|
outState.putString(TITLE_KEY, title);
|
||||||
|
outState.putString(IMAGE_URL_KEY, imageUrl);
|
||||||
|
outState.putString(CONTENT_KEY, contentHtml);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupToolbar(View view) {
|
||||||
|
Toolbar toolbar = view.findViewById(R.id.toolbar);
|
||||||
|
getMyActivity().setSupportActionBar(toolbar);
|
||||||
|
setHasOptionsMenu(true);
|
||||||
|
toolbar.setClickable(true);
|
||||||
|
|
||||||
|
Context ctx = getMyActivity();
|
||||||
|
int iconColor = AndroidUtils.resolveAttribute(ctx, R.attr.pstsTextColor);
|
||||||
|
Drawable icBack = getMyApplication().getUIUtilities().getIcon(R.drawable.ic_arrow_back, iconColor);
|
||||||
|
toolbar.setNavigationIcon(icBack);
|
||||||
|
toolbar.setNavigationContentDescription(R.string.access_shared_string_navigate_up);
|
||||||
|
|
||||||
|
if (!Algorithms.isEmpty(title)) {
|
||||||
|
toolbar.setTitle(title);
|
||||||
|
int titleColor = AndroidUtils.resolveAttribute(ctx, R.attr.pstsTextColor);
|
||||||
|
toolbar.setTitleTextColor(ContextCompat.getColor(ctx, titleColor));
|
||||||
|
}
|
||||||
|
|
||||||
|
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(final View v) {
|
||||||
|
dismiss();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupImage(View view) {
|
||||||
|
if (imageUrl == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final OsmandApplication app = getMyApplication();
|
||||||
|
final PicassoUtils picasso = PicassoUtils.getPicasso(app);
|
||||||
|
final AppCompatImageView image = view.findViewById(R.id.main_image);
|
||||||
|
RequestCreator rc = Picasso.get().load(imageUrl);
|
||||||
|
WikivoyageUtils.setupNetworkPolicy(app.getSettings(), rc);
|
||||||
|
|
||||||
|
rc.into(image, new Callback() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess() {
|
||||||
|
picasso.setResultLoaded(imageUrl, true);
|
||||||
|
AndroidUiHelper.updateVisibility(image, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Exception e) {
|
||||||
|
picasso.setResultLoaded(imageUrl, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupWebView(final View view) {
|
||||||
|
webView = view.findViewById(R.id.content);
|
||||||
|
webView.setScrollbarFadingEnabled(true);
|
||||||
|
webView.setVerticalScrollBarEnabled(false);
|
||||||
|
webView.setBackgroundColor(Color.TRANSPARENT);
|
||||||
|
webView.setLayerType(WebView.LAYER_TYPE_HARDWARE, null);
|
||||||
|
webView.getSettings().setTextZoom((int) (getResources().getConfiguration().fontScale * 100f));
|
||||||
|
webView.getSettings().setDomStorageEnabled(true);
|
||||||
|
webView.getSettings().setLoadWithOverviewMode(true);
|
||||||
|
webView.getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH);
|
||||||
|
webView.setWebViewClient(new WebViewClient() {
|
||||||
|
@Override
|
||||||
|
public void onPageCommitVisible(WebView webView, String url) {
|
||||||
|
super.onPageCommitVisible(webView, url);
|
||||||
|
setupDependentViews(view);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
loadWebviewData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateContent(String content) {
|
||||||
|
contentHtml = content;
|
||||||
|
loadWebviewData();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadWebviewData() {
|
||||||
|
String content = contentHtml;
|
||||||
|
if (content != null) {
|
||||||
|
content = isNightMode(false) ? getColoredContent(content) : content;
|
||||||
|
String encoded = Base64.encodeToString(content.getBytes(), Base64.NO_PADDING);
|
||||||
|
webView.loadData(encoded, "text/html", "base64");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupDependentViews(final View view) {
|
||||||
|
TextViewEx readBtn = view.findViewById(R.id.btn_edit);
|
||||||
|
readBtn.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
FragmentActivity activity = getActivity();
|
||||||
|
if (activity != null) {
|
||||||
|
GpxEditDescriptionDialogFragment.showInstance(activity, contentHtml, GpxReadDescriptionDialogFragment.this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
AndroidUiHelper.setVisibility(View.VISIBLE,
|
||||||
|
readBtn, view.findViewById(R.id.divider), view.findViewById(R.id.bottom_empty_space));
|
||||||
|
int backgroundColor = isNightMode(false) ?
|
||||||
|
R.color.activity_background_color_dark : R.color.activity_background_color_light;
|
||||||
|
view.findViewById(R.id.root).setBackgroundResource(backgroundColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getColoredContent(String content) {
|
||||||
|
return "<body style=\"color:white;\">\n" + content + "</body>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void showInstance(@NonNull FragmentActivity activity, @NonNull String title, @NonNull String imageUrl, @NonNull String description) {
|
||||||
|
FragmentManager fragmentManager = activity.getSupportFragmentManager();
|
||||||
|
if (!fragmentManager.isStateSaved()) {
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putString(TITLE_KEY, title);
|
||||||
|
args.putString(IMAGE_URL_KEY, imageUrl);
|
||||||
|
args.putString(CONTENT_KEY, description);
|
||||||
|
|
||||||
|
GpxReadDescriptionDialogFragment fragment = new GpxReadDescriptionDialogFragment();
|
||||||
|
fragment.setArguments(args);
|
||||||
|
fragment.show(fragmentManager, GpxReadDescriptionDialogFragment.TAG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,7 +22,6 @@ public class SegmentsCard extends BaseCard {
|
||||||
|
|
||||||
private TrackDisplayHelper displayHelper;
|
private TrackDisplayHelper displayHelper;
|
||||||
private GpxDisplayItemType[] filterTypes = new GpxDisplayItemType[] {GpxDisplayItemType.TRACK_SEGMENT};
|
private GpxDisplayItemType[] filterTypes = new GpxDisplayItemType[] {GpxDisplayItemType.TRACK_SEGMENT};
|
||||||
private SegmentGPXAdapter adapter;
|
|
||||||
private SegmentActionsListener listener;
|
private SegmentActionsListener listener;
|
||||||
|
|
||||||
public SegmentsCard(@NonNull MapActivity mapActivity, @NonNull TrackDisplayHelper displayHelper,
|
public SegmentsCard(@NonNull MapActivity mapActivity, @NonNull TrackDisplayHelper displayHelper,
|
||||||
|
|
|
@ -112,10 +112,16 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public float getMiddleStateKoef() {
|
public float getMiddleStateKoef() {
|
||||||
return 0.5f;
|
return 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getInitialMenuState() {
|
||||||
|
return MenuState.HALF_SCREEN;
|
||||||
|
}
|
||||||
|
|
||||||
public TrackDrawInfo getTrackDrawInfo() {
|
public TrackDrawInfo getTrackDrawInfo() {
|
||||||
return trackDrawInfo;
|
return trackDrawInfo;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,9 @@
|
||||||
package net.osmand.plus.track;
|
package net.osmand.plus.track;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import net.osmand.GPXUtilities.GPXFile;
|
import net.osmand.GPXUtilities.GPXFile;
|
||||||
import net.osmand.GPXUtilities.WptPt;
|
|
||||||
import net.osmand.data.LatLon;
|
|
||||||
import net.osmand.data.PointDescription;
|
|
||||||
import net.osmand.data.QuadRect;
|
import net.osmand.data.QuadRect;
|
||||||
import net.osmand.plus.GPXDatabase.GpxDataItem;
|
import net.osmand.plus.GPXDatabase.GpxDataItem;
|
||||||
import net.osmand.plus.GpxSelectionHelper;
|
import net.osmand.plus.GpxSelectionHelper;
|
||||||
|
@ -17,10 +12,6 @@ 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.OsmandApplication;
|
import net.osmand.plus.OsmandApplication;
|
||||||
import net.osmand.plus.R;
|
|
||||||
import net.osmand.plus.activities.MapActivity;
|
|
||||||
import net.osmand.plus.measurementtool.GpxData;
|
|
||||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -163,21 +154,4 @@ public class TrackDisplayHelper {
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addNewGpxData(Activity activity) {
|
|
||||||
GPXFile gpxFile = getGpx();
|
|
||||||
GpxData gpxData = new GpxData(gpxFile);
|
|
||||||
WptPt pointToShow = gpxFile != null ? gpxFile.findPointToShow() : null;
|
|
||||||
if (pointToShow != null) {
|
|
||||||
LatLon location = new LatLon(pointToShow.getLatitude(), pointToShow.getLongitude());
|
|
||||||
final OsmandSettings settings = app.getSettings();
|
|
||||||
settings.setMapLocationToShow(location.getLatitude(), location.getLongitude(),
|
|
||||||
settings.getLastKnownMapZoom(),
|
|
||||||
new PointDescription(PointDescription.POINT_TYPE_WPT, activity.getString(R.string.add_line)),
|
|
||||||
false,
|
|
||||||
gpxData
|
|
||||||
);
|
|
||||||
MapActivity.launchMapActivityMoveToTop(activity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,27 @@
|
||||||
package net.osmand.plus.track;
|
package net.osmand.plus.track;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.AnimatorListenerAdapter;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.res.ColorStateList;
|
import android.content.res.ColorStateList;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.TextWatcher;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.View.OnClickListener;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.view.animation.DecelerateInterpolator;
|
||||||
|
import android.widget.EditText;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes;
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.StringRes;
|
import androidx.annotation.StringRes;
|
||||||
|
@ -23,18 +29,17 @@ 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 com.google.android.material.bottomnavigation.BottomNavigationView;
|
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
||||||
|
|
||||||
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.Location;
|
||||||
import net.osmand.PlatformUtil;
|
import net.osmand.PlatformUtil;
|
||||||
import net.osmand.data.LatLon;
|
import net.osmand.data.LatLon;
|
||||||
|
import net.osmand.data.PointDescription;
|
||||||
import net.osmand.data.QuadRect;
|
import net.osmand.data.QuadRect;
|
||||||
import net.osmand.data.RotatedTileBox;
|
import net.osmand.data.RotatedTileBox;
|
||||||
import net.osmand.plus.GpxDbHelper;
|
import net.osmand.plus.GpxDbHelper;
|
||||||
|
@ -42,18 +47,20 @@ 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;
|
||||||
import net.osmand.plus.base.ContextMenuScrollFragment;
|
import net.osmand.plus.base.ContextMenuScrollFragment;
|
||||||
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.GPXDataSetType;
|
import net.osmand.plus.mapcontextmenu.MapContextMenu;
|
||||||
import net.osmand.plus.helpers.GpxUiHelper.OrderedLineDataSet;
|
|
||||||
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;
|
||||||
|
@ -61,7 +68,7 @@ import net.osmand.plus.measurementtool.GpxData;
|
||||||
import net.osmand.plus.measurementtool.MeasurementEditingContext;
|
import net.osmand.plus.measurementtool.MeasurementEditingContext;
|
||||||
import net.osmand.plus.measurementtool.MeasurementToolFragment;
|
import net.osmand.plus.measurementtool.MeasurementToolFragment;
|
||||||
import net.osmand.plus.myplaces.AvailableGPXFragment.GpxInfo;
|
import net.osmand.plus.myplaces.AvailableGPXFragment.GpxInfo;
|
||||||
import net.osmand.plus.myplaces.GPXTabItemType;
|
import net.osmand.plus.myplaces.DeletePointsTask.OnPointsDeleteListener;
|
||||||
import net.osmand.plus.myplaces.MoveGpxFileBottomSheet;
|
import net.osmand.plus.myplaces.MoveGpxFileBottomSheet;
|
||||||
import net.osmand.plus.myplaces.MoveGpxFileBottomSheet.OnTrackFileMoveListener;
|
import net.osmand.plus.myplaces.MoveGpxFileBottomSheet.OnTrackFileMoveListener;
|
||||||
import net.osmand.plus.myplaces.SegmentActionsListener;
|
import net.osmand.plus.myplaces.SegmentActionsListener;
|
||||||
|
@ -71,8 +78,10 @@ import net.osmand.plus.osmedit.OsmEditingPlugin;
|
||||||
import net.osmand.plus.routepreparationmenu.cards.BaseCard;
|
import net.osmand.plus.routepreparationmenu.cards.BaseCard;
|
||||||
import net.osmand.plus.routepreparationmenu.cards.BaseCard.CardListener;
|
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.views.AddGpxPointBottomSheetHelper.NewGpxPoint;
|
||||||
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;
|
||||||
|
|
||||||
|
@ -94,9 +103,12 @@ import static net.osmand.plus.track.OptionsCard.RENAME_BUTTON_INDEX;
|
||||||
import static net.osmand.plus.track.OptionsCard.SHARE_BUTTON_INDEX;
|
import static net.osmand.plus.track.OptionsCard.SHARE_BUTTON_INDEX;
|
||||||
import static net.osmand.plus.track.OptionsCard.SHOW_ON_MAP_BUTTON_INDEX;
|
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;
|
||||||
|
import static net.osmand.plus.track.TrackPointsCard.ADD_WAYPOINT_INDEX;
|
||||||
|
import static net.osmand.plus.track.TrackPointsCard.DELETE_WAYPOINTS_INDEX;
|
||||||
|
|
||||||
public class TrackMenuFragment extends ContextMenuScrollFragment implements CardListener,
|
public class TrackMenuFragment extends ContextMenuScrollFragment implements CardListener,
|
||||||
SegmentActionsListener, RenameCallback, OnTrackFileMoveListener {
|
SegmentActionsListener, RenameCallback, OnTrackFileMoveListener, OnPointsDeleteListener,
|
||||||
|
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);
|
||||||
|
@ -105,29 +117,46 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
private TrackDisplayHelper displayHelper;
|
private TrackDisplayHelper displayHelper;
|
||||||
private SelectedGpxFile selectedGpxFile;
|
private SelectedGpxFile selectedGpxFile;
|
||||||
|
|
||||||
private View routeMenuTopShadowAll;
|
private TrackMenuType menuType = TrackMenuType.OVERVIEW;
|
||||||
private TextView headerTitle;
|
|
||||||
private ImageView headerIcon;
|
|
||||||
private BottomNavigationView bottomNav;
|
|
||||||
private TrackMenuType menuType = TrackMenuType.TRACK;
|
|
||||||
private SegmentsCard segmentsCard;
|
private SegmentsCard segmentsCard;
|
||||||
private OptionsCard optionsCard;
|
private OptionsCard optionsCard;
|
||||||
|
private DescriptionCard descriptionCard;
|
||||||
|
private OverviewCard overviewCard;
|
||||||
|
private TrackPointsCard pointsCard;
|
||||||
|
|
||||||
|
private TextView headerTitle;
|
||||||
|
private ImageView headerIcon;
|
||||||
|
private View toolbarContainer;
|
||||||
|
private View searchContainer;
|
||||||
|
private ImageView searchButton;
|
||||||
|
private EditText searchEditText;
|
||||||
|
private TextView toolbarTextView;
|
||||||
|
private View routeMenuTopShadowAll;
|
||||||
|
private BottomNavigationView bottomNav;
|
||||||
|
|
||||||
|
private String gpxTitle;
|
||||||
private TrackChartPoints trackChartPoints;
|
private TrackChartPoints trackChartPoints;
|
||||||
|
|
||||||
|
private Float heading;
|
||||||
|
private Location lastLocation;
|
||||||
|
private UpdateLocationViewCache updateLocationViewCache;
|
||||||
|
private boolean locationUpdateStarted;
|
||||||
|
|
||||||
private int menuTitleHeight;
|
private int menuTitleHeight;
|
||||||
|
private int toolbarHeightPx;
|
||||||
|
|
||||||
public enum TrackMenuType {
|
public enum TrackMenuType {
|
||||||
|
OVERVIEW(R.id.action_overview, R.string.shared_string_overview),
|
||||||
TRACK(R.id.action_track, R.string.shared_string_gpx_tracks),
|
TRACK(R.id.action_track, R.string.shared_string_gpx_tracks),
|
||||||
POINTS(R.id.action_points, R.string.shared_string_gpx_points),
|
POINTS(R.id.action_points, R.string.shared_string_gpx_points),
|
||||||
OPTIONS(R.id.action_options, R.string.shared_string_options);
|
OPTIONS(R.id.action_options, R.string.shared_string_options);
|
||||||
|
|
||||||
TrackMenuType(@DrawableRes int iconId, @StringRes int titleId) {
|
TrackMenuType(int menuItemId, @StringRes int titleId) {
|
||||||
this.iconId = iconId;
|
this.menuItemId = menuItemId;
|
||||||
this.titleId = titleId;
|
this.titleId = titleId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final int iconId;
|
public final int menuItemId;
|
||||||
public final int titleId;
|
public final int titleId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +177,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getToolbarHeight() {
|
public int getToolbarHeight() {
|
||||||
return 0;
|
return toolbarHeightPx;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getMiddleStateKoef() {
|
public float getMiddleStateKoef() {
|
||||||
|
@ -160,6 +189,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;
|
||||||
}
|
}
|
||||||
|
@ -170,6 +204,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
app = requireMyApplication();
|
app = requireMyApplication();
|
||||||
GpxDbHelper gpxDbHelper = app.getGpxDbHelper();
|
GpxDbHelper gpxDbHelper = app.getGpxDbHelper();
|
||||||
displayHelper = new TrackDisplayHelper(app);
|
displayHelper = new TrackDisplayHelper(app);
|
||||||
|
updateLocationViewCache = app.getUIUtilities().getUpdateLocationViewCache();
|
||||||
|
|
||||||
Bundle arguments = getArguments();
|
Bundle arguments = getArguments();
|
||||||
if (arguments != null) {
|
if (arguments != null) {
|
||||||
|
@ -184,7 +219,10 @@ 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);
|
||||||
}
|
}
|
||||||
|
toolbarHeightPx = getResources().getDimensionPixelSize(R.dimen.dashboard_map_toolbar);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GPXFile getGpx() {
|
public GPXFile getGpx() {
|
||||||
|
@ -199,9 +237,13 @@ 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);
|
||||||
|
toolbarContainer = view.findViewById(R.id.context_menu_toolbar_container);
|
||||||
|
toolbarTextView = view.findViewById(R.id.toolbar_title);
|
||||||
|
searchButton = view.findViewById(R.id.search_button);
|
||||||
|
searchContainer = view.findViewById(R.id.search_container);
|
||||||
|
|
||||||
if (isPortrait()) {
|
if (isPortrait()) {
|
||||||
updateCardsLayout();
|
AndroidUiHelper.updateVisibility(getTopShadow(), true);
|
||||||
} 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);
|
||||||
|
@ -210,6 +252,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
}
|
}
|
||||||
|
|
||||||
setupCards();
|
setupCards();
|
||||||
|
setupToolbar();
|
||||||
updateHeader();
|
updateHeader();
|
||||||
setupButtons(view);
|
setupButtons(view);
|
||||||
enterTrackAppearanceMode();
|
enterTrackAppearanceMode();
|
||||||
|
@ -218,15 +261,101 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateHeader() {
|
private void setHeaderTitle(String text, boolean iconVisibility) {
|
||||||
if (menuType == TrackMenuType.OPTIONS) {
|
headerTitle.setText(text);
|
||||||
headerTitle.setText(menuType.titleId);
|
AndroidUiHelper.updateVisibility(headerIcon, iconVisibility);
|
||||||
AndroidUiHelper.updateVisibility(headerIcon, false);
|
|
||||||
} else {
|
|
||||||
String fileName = Algorithms.getFileWithoutDirs(getGpx().path);
|
|
||||||
headerTitle.setText(GpxUiHelper.getGpxTitle(fileName));
|
|
||||||
AndroidUiHelper.updateVisibility(headerIcon, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateHeader() {
|
||||||
|
ViewGroup headerContainer = (ViewGroup) routeMenuTopShadowAll;
|
||||||
|
if (menuType == TrackMenuType.OVERVIEW) {
|
||||||
|
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 {
|
||||||
|
if (overviewCard != null && overviewCard.getView() != null) {
|
||||||
|
headerContainer.removeView(overviewCard.getView());
|
||||||
|
}
|
||||||
|
boolean isOptions = menuType == TrackMenuType.OPTIONS;
|
||||||
|
setHeaderTitle(isOptions ? app.getString(menuType.titleId) : gpxTitle, !isOptions);
|
||||||
|
}
|
||||||
|
if (menuType == TrackMenuType.POINTS) {
|
||||||
|
AndroidUiHelper.updateVisibility(searchButton, true);
|
||||||
|
} else {
|
||||||
|
AndroidUiHelper.updateVisibility(toolbarTextView, true);
|
||||||
|
AndroidUiHelper.updateVisibility(searchButton, false);
|
||||||
|
AndroidUiHelper.updateVisibility(searchContainer, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupToolbar() {
|
||||||
|
toolbarTextView.setText(gpxTitle);
|
||||||
|
|
||||||
|
ImageView closeButton = toolbarContainer.findViewById(R.id.close_button);
|
||||||
|
closeButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if (menuType == TrackMenuType.POINTS) {
|
||||||
|
AndroidUiHelper.updateVisibility(toolbarTextView, true);
|
||||||
|
AndroidUiHelper.updateVisibility(searchButton, true);
|
||||||
|
AndroidUiHelper.updateVisibility(searchContainer, false);
|
||||||
|
}
|
||||||
|
openMenuHeaderOnly();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
closeButton.setImageResource(AndroidUtils.getNavigationIconResId(toolbarContainer.getContext()));
|
||||||
|
|
||||||
|
searchButton.setOnClickListener(new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
AndroidUiHelper.updateVisibility(searchContainer, true);
|
||||||
|
AndroidUiHelper.updateVisibility(searchButton, false);
|
||||||
|
AndroidUiHelper.updateVisibility(toolbarTextView, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
searchEditText = toolbarContainer.findViewById(R.id.searchEditText);
|
||||||
|
searchEditText.setHint(R.string.search_poi_filter);
|
||||||
|
searchEditText.addTextChangedListener(
|
||||||
|
new TextWatcher() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
if (pointsCard != null) {
|
||||||
|
pointsCard.filter(s.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
ImageView clearButton = toolbarContainer.findViewById(R.id.clearButton);
|
||||||
|
clearButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if (!Algorithms.isEmpty(searchEditText.getText())) {
|
||||||
|
searchEditText.setText("");
|
||||||
|
searchEditText.setSelection(0);
|
||||||
|
}
|
||||||
|
if (pointsCard != null) {
|
||||||
|
pointsCard.updateContent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupCards() {
|
private void setupCards() {
|
||||||
|
@ -258,6 +387,29 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
optionsCard.setListener(this);
|
optionsCard.setListener(this);
|
||||||
cardsContainer.addView(optionsCard.build(mapActivity));
|
cardsContainer.addView(optionsCard.build(mapActivity));
|
||||||
}
|
}
|
||||||
|
} else if (menuType == TrackMenuType.OVERVIEW) {
|
||||||
|
if (descriptionCard != null && descriptionCard.getView() != null) {
|
||||||
|
ViewGroup parent = ((ViewGroup) descriptionCard.getView().getParent());
|
||||||
|
if (parent != null) {
|
||||||
|
parent.removeView(descriptionCard.getView());
|
||||||
|
}
|
||||||
|
cardsContainer.addView(descriptionCard.getView());
|
||||||
|
} else {
|
||||||
|
descriptionCard = new DescriptionCard(getMapActivity(), displayHelper.getGpx());
|
||||||
|
cardsContainer.addView(descriptionCard.build(mapActivity));
|
||||||
|
}
|
||||||
|
} else if (menuType == TrackMenuType.POINTS) {
|
||||||
|
if (pointsCard != null && pointsCard.getView() != null) {
|
||||||
|
ViewGroup parent = (ViewGroup) pointsCard.getView().getParent();
|
||||||
|
if (parent != null) {
|
||||||
|
parent.removeAllViews();
|
||||||
|
}
|
||||||
|
cardsContainer.addView(pointsCard.getView());
|
||||||
|
} else {
|
||||||
|
pointsCard = new TrackPointsCard(mapActivity, displayHelper);
|
||||||
|
pointsCard.setListener(this);
|
||||||
|
cardsContainer.addView(pointsCard.build(mapActivity));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -273,12 +425,14 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
protected void setViewY(int y, boolean animated, boolean adjustMapPos) {
|
protected void setViewY(int y, boolean animated, boolean adjustMapPos) {
|
||||||
super.setViewY(y, animated, adjustMapPos);
|
super.setViewY(y, animated, adjustMapPos);
|
||||||
updateStatusBarColor();
|
updateStatusBarColor();
|
||||||
|
updateToolbar(y, animated);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateMainViewLayout(int posY) {
|
protected void updateMainViewLayout(int posY) {
|
||||||
super.updateMainViewLayout(posY);
|
super.updateMainViewLayout(posY);
|
||||||
updateStatusBarColor();
|
updateStatusBarColor();
|
||||||
|
updateToolbar(posY, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -306,6 +460,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
if (mapActivity != null && trackChartPoints != null) {
|
if (mapActivity != null && trackChartPoints != null) {
|
||||||
mapActivity.getMapLayers().getGpxLayer().setTrackChartPoints(trackChartPoints);
|
mapActivity.getMapLayers().getGpxLayer().setTrackChartPoints(trackChartPoints);
|
||||||
}
|
}
|
||||||
|
startLocationUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -315,6 +470,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
|
||||||
|
@ -377,7 +593,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
if (Build.VERSION.SDK_INT >= 23 && !nightMode) {
|
if (Build.VERSION.SDK_INT >= 23 && !nightMode) {
|
||||||
view.setSystemUiVisibility(view.getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
view.setSystemUiVisibility(view.getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
||||||
}
|
}
|
||||||
return nightMode ? R.color.divider_color_dark : R.color.divider_color_light;
|
return nightMode ? R.color.status_bar_color_dark : R.color.status_bar_color_light;
|
||||||
} else {
|
} else {
|
||||||
if (Build.VERSION.SDK_INT >= 23 && !nightMode) {
|
if (Build.VERSION.SDK_INT >= 23 && !nightMode) {
|
||||||
view.setSystemUiVisibility(view.getSystemUiVisibility() & ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
view.setSystemUiVisibility(view.getSystemUiVisibility() & ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
||||||
|
@ -415,8 +631,8 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
if (mapActivity == null) {
|
if (mapActivity == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (card instanceof OptionsCard) {
|
|
||||||
final GPXFile gpxFile = getGpx();
|
final GPXFile gpxFile = getGpx();
|
||||||
|
if (card instanceof OptionsCard || card instanceof OverviewCard) {
|
||||||
if (buttonIndex == SHOW_ON_MAP_BUTTON_INDEX) {
|
if (buttonIndex == SHOW_ON_MAP_BUTTON_INDEX) {
|
||||||
boolean gpxFileSelected = !isGpxFileSelected(app, gpxFile);
|
boolean gpxFileSelected = !isGpxFileSelected(app, gpxFile);
|
||||||
app.getSelectedGpxHelper().selectGpxFile(gpxFile, gpxFileSelected, false);
|
app.getSelectedGpxHelper().selectGpxFile(gpxFile, gpxFileSelected, false);
|
||||||
|
@ -508,6 +724,25 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
});
|
});
|
||||||
builder.show();
|
builder.show();
|
||||||
}
|
}
|
||||||
|
} else if (card instanceof TrackPointsCard) {
|
||||||
|
if (buttonIndex == ADD_WAYPOINT_INDEX) {
|
||||||
|
PointDescription pointDescription = new PointDescription(PointDescription.POINT_TYPE_WPT, app.getString(R.string.add_waypoint));
|
||||||
|
QuadRect rect = displayHelper.getRect();
|
||||||
|
NewGpxPoint newGpxPoint = new NewGpxPoint(gpxFile, pointDescription, rect);
|
||||||
|
|
||||||
|
mapActivity.getMapView().fitRectToMap(rect.left, rect.right, rect.top, rect.bottom,
|
||||||
|
(int) rect.width(), (int) rect.height(), 0);
|
||||||
|
mapActivity.getMapLayers().getContextMenuLayer().enterAddGpxPointMode(newGpxPoint);
|
||||||
|
|
||||||
|
hide();
|
||||||
|
} else if (buttonIndex == DELETE_WAYPOINTS_INDEX) {
|
||||||
|
TrackPointsCard pointsCard = (TrackPointsCard) card;
|
||||||
|
if (pointsCard.isSelectionMode()) {
|
||||||
|
pointsCard.deleteItemsAction();
|
||||||
|
} else {
|
||||||
|
pointsCard.setSelectionMode(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,6 +755,34 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateToolbar(int y, boolean animated) {
|
||||||
|
final MapActivity mapActivity = getMapActivity();
|
||||||
|
if (mapActivity != null) {
|
||||||
|
if (toolbarContainer != null && isPortrait()) {
|
||||||
|
if (animated) {
|
||||||
|
final float toolbarAlpha = getToolbarAlpha(y);
|
||||||
|
if (toolbarAlpha > 0) {
|
||||||
|
updateVisibility(toolbarContainer, true);
|
||||||
|
}
|
||||||
|
toolbarContainer.animate().alpha(toolbarAlpha)
|
||||||
|
.setDuration(ContextMenuFragment.ANIMATION_DURATION)
|
||||||
|
.setInterpolator(new DecelerateInterpolator())
|
||||||
|
.setListener(new AnimatorListenerAdapter() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(Animator animation) {
|
||||||
|
updateVisibility(toolbarContainer, toolbarAlpha);
|
||||||
|
mapActivity.updateStatusBarColor();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.start();
|
||||||
|
} else {
|
||||||
|
updateToolbarVisibility(toolbarContainer, y);
|
||||||
|
mapActivity.updateStatusBarColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onHeaderClick() {
|
protected void onHeaderClick() {
|
||||||
adjustMapPosition(getViewY());
|
adjustMapPosition(getViewY());
|
||||||
|
@ -547,32 +810,17 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateCardsLayout() {
|
|
||||||
View mainView = getMainView();
|
|
||||||
if (mainView != null) {
|
|
||||||
View topShadow = getTopShadow();
|
|
||||||
FrameLayout bottomContainer = getBottomContainer();
|
|
||||||
if (getCurrentMenuState() == MenuState.HEADER_ONLY) {
|
|
||||||
topShadow.setVisibility(View.INVISIBLE);
|
|
||||||
bottomContainer.setBackgroundDrawable(null);
|
|
||||||
} else {
|
|
||||||
topShadow.setVisibility(View.VISIBLE);
|
|
||||||
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());
|
||||||
BottomNavigationView bottomNav = view.findViewById(R.id.bottom_navigation);
|
BottomNavigationView bottomNav = view.findViewById(R.id.bottom_navigation);
|
||||||
bottomNav.setItemIconTintList(navColorStateList);
|
bottomNav.setItemIconTintList(navColorStateList);
|
||||||
bottomNav.setItemTextColor(navColorStateList);
|
bottomNav.setItemTextColor(navColorStateList);
|
||||||
bottomNav.setSelectedItemId(R.id.action_track);
|
bottomNav.setSelectedItemId(R.id.action_overview);
|
||||||
bottomNav.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
|
bottomNav.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
|
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
|
||||||
for (TrackMenuType type : TrackMenuType.values()) {
|
for (TrackMenuType type : TrackMenuType.values()) {
|
||||||
if (type.iconId == item.getItemId()) {
|
if (type.menuItemId == item.getItemId()) {
|
||||||
menuType = type;
|
menuType = type;
|
||||||
setupCards();
|
setupCards();
|
||||||
updateHeader();
|
updateHeader();
|
||||||
|
@ -592,6 +840,12 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
if (optionsCard != null) {
|
if (optionsCard != null) {
|
||||||
optionsCard.updateContent();
|
optionsCard.updateContent();
|
||||||
}
|
}
|
||||||
|
if (descriptionCard != null) {
|
||||||
|
descriptionCard.updateContent();
|
||||||
|
}
|
||||||
|
if (pointsCard != null) {
|
||||||
|
pointsCard.updateContent();
|
||||||
|
}
|
||||||
setupCards();
|
setupCards();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -605,6 +859,18 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPointsDeletionStarted() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPointsDeleted() {
|
||||||
|
if (pointsCard != null) {
|
||||||
|
pointsCard.onPointsDeleted();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPointSelected(TrkSegment segment, double lat, double lon) {
|
public void onPointSelected(TrkSegment segment, double lat, double lon) {
|
||||||
if (trackChartPoints == null) {
|
if (trackChartPoints == null) {
|
||||||
|
@ -630,54 +896,15 @@ 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();
|
||||||
close();
|
hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void showOptionsPopupMenu(View view, final TrkSegment segment, final boolean confirmDeletion) {
|
public void showOptionsPopupMenu(View view, final TrkSegment segment, final boolean confirmDeletion, final GpxDisplayItem gpxItem) {
|
||||||
FragmentActivity activity = getActivity();
|
FragmentActivity activity = getActivity();
|
||||||
if (activity != null) {
|
if (activity != null) {
|
||||||
IconPopupMenu optionsPopupMenu = new IconPopupMenu(activity, view.findViewById(R.id.overflow_menu));
|
IconPopupMenu optionsPopupMenu = new IconPopupMenu(activity, view.findViewById(R.id.overflow_menu));
|
||||||
|
@ -685,6 +912,11 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
optionsPopupMenu.getMenuInflater().inflate(R.menu.track_segment_menu, menu);
|
optionsPopupMenu.getMenuInflater().inflate(R.menu.track_segment_menu, menu);
|
||||||
menu.findItem(R.id.action_edit).setIcon(app.getUIUtilities().getThemedIcon(R.drawable.ic_action_edit_dark));
|
menu.findItem(R.id.action_edit).setIcon(app.getUIUtilities().getThemedIcon(R.drawable.ic_action_edit_dark));
|
||||||
menu.findItem(R.id.action_delete).setIcon(app.getUIUtilities().getThemedIcon(R.drawable.ic_action_remove_dark));
|
menu.findItem(R.id.action_delete).setIcon(app.getUIUtilities().getThemedIcon(R.drawable.ic_action_remove_dark));
|
||||||
|
if (getGpx().showCurrentTrack) {
|
||||||
|
menu.findItem(R.id.split_interval).setVisible(false);
|
||||||
|
} else {
|
||||||
|
menu.findItem(R.id.split_interval).setIcon(app.getUIUtilities().getThemedIcon(R.drawable.ic_action_split_interval));
|
||||||
|
}
|
||||||
optionsPopupMenu.setOnMenuItemClickListener(new IconPopupMenu.OnMenuItemClickListener() {
|
optionsPopupMenu.setOnMenuItemClickListener(new IconPopupMenu.OnMenuItemClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onMenuItemClick(MenuItem item) {
|
public boolean onMenuItemClick(MenuItem item) {
|
||||||
|
@ -709,6 +941,8 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
builder.show();
|
builder.show();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
} else if (i == R.id.split_interval) {
|
||||||
|
openSplitInterval(gpxItem, segment);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -720,7 +954,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
private void editSegment(TrkSegment segment) {
|
private void editSegment(TrkSegment segment) {
|
||||||
GPXFile gpxFile = getGpx();
|
GPXFile gpxFile = getGpx();
|
||||||
openPlanRoute(new GpxData(gpxFile));
|
openPlanRoute(new GpxData(gpxFile));
|
||||||
close();
|
hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void openPlanRoute(GpxData gpxData) {
|
public void openPlanRoute(GpxData gpxData) {
|
||||||
|
@ -771,12 +1005,24 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void close() {
|
private void hide() {
|
||||||
try {
|
try {
|
||||||
MapActivity mapActivity = getMapActivity();
|
MapActivity mapActivity = getMapActivity();
|
||||||
if (mapActivity != null) {
|
if (mapActivity != null) {
|
||||||
FragmentManager fragmentManager = mapActivity.getSupportFragmentManager();
|
FragmentManager fragmentManager = mapActivity.getSupportFragmentManager();
|
||||||
fragmentManager.beginTransaction().remove(this).commitAllowingStateLoss();
|
fragmentManager.beginTransaction().hide(this).commit();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void show() {
|
||||||
|
try {
|
||||||
|
MapActivity mapActivity = getMapActivity();
|
||||||
|
if (mapActivity != null) {
|
||||||
|
FragmentManager fragmentManager = mapActivity.getSupportFragmentManager();
|
||||||
|
fragmentManager.beginTransaction().show(this).commit();
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e);
|
log.error(e);
|
||||||
|
@ -788,7 +1034,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);
|
||||||
|
@ -796,7 +1042,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
||||||
|
|
||||||
mapActivity.getSupportFragmentManager()
|
mapActivity.getSupportFragmentManager()
|
||||||
.beginTransaction()
|
.beginTransaction()
|
||||||
.replace(R.id.fragmentContainer, fragment, fragment.getFragmentTag())
|
.replace(R.id.fragmentContainer, fragment, TAG)
|
||||||
.addToBackStack(fragment.getFragmentTag())
|
.addToBackStack(fragment.getFragmentTag())
|
||||||
.commitAllowingStateLoss();
|
.commitAllowingStateLoss();
|
||||||
return true;
|
return true;
|
||||||
|
|
639
OsmAnd/src/net/osmand/plus/track/TrackPointsCard.java
Normal file
639
OsmAnd/src/net/osmand/plus/track/TrackPointsCard.java
Normal file
|
@ -0,0 +1,639 @@
|
||||||
|
package net.osmand.plus.track;
|
||||||
|
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.text.SpannableStringBuilder;
|
||||||
|
import android.text.Spanned;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.text.style.ForegroundColorSpan;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.View.OnClickListener;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.CheckBox;
|
||||||
|
import android.widget.ExpandableListView;
|
||||||
|
import android.widget.ExpandableListView.OnChildClickListener;
|
||||||
|
import android.widget.Filter;
|
||||||
|
import android.widget.Filterable;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
|
import net.osmand.AndroidUtils;
|
||||||
|
import net.osmand.Collator;
|
||||||
|
import net.osmand.GPXUtilities.WptPt;
|
||||||
|
import net.osmand.OsmAndCollator;
|
||||||
|
import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup;
|
||||||
|
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
|
||||||
|
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType;
|
||||||
|
import net.osmand.plus.R;
|
||||||
|
import net.osmand.plus.UiUtilities;
|
||||||
|
import net.osmand.plus.activities.MapActivity;
|
||||||
|
import net.osmand.plus.activities.OsmandBaseExpandableListAdapter;
|
||||||
|
import net.osmand.plus.base.PointImageDrawable;
|
||||||
|
import net.osmand.plus.helpers.AndroidUiHelper;
|
||||||
|
import net.osmand.plus.myplaces.DeletePointsTask;
|
||||||
|
import net.osmand.plus.myplaces.DeletePointsTask.OnPointsDeleteListener;
|
||||||
|
import net.osmand.plus.myplaces.EditTrackGroupDialogFragment;
|
||||||
|
import net.osmand.plus.routepreparationmenu.cards.BaseCard;
|
||||||
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class TrackPointsCard extends BaseCard implements OnChildClickListener, OnPointsDeleteListener {
|
||||||
|
|
||||||
|
public static final int ADD_WAYPOINT_INDEX = 0;
|
||||||
|
public static final int DELETE_WAYPOINTS_INDEX = 1;
|
||||||
|
|
||||||
|
private final TrackDisplayHelper displayHelper;
|
||||||
|
private final GpxDisplayItemType[] filterTypes = new GpxDisplayItemType[] {GpxDisplayItemType.TRACK_POINTS, GpxDisplayItemType.TRACK_ROUTE_POINTS};
|
||||||
|
|
||||||
|
private final Set<Integer> selectedGroups = new LinkedHashSet<>();
|
||||||
|
private final LinkedHashMap<GpxDisplayItemType, Set<GpxDisplayItem>> selectedItems = new LinkedHashMap<>();
|
||||||
|
private boolean selectionMode;
|
||||||
|
|
||||||
|
private final PointGPXAdapter adapter;
|
||||||
|
private ExpandableListView listView;
|
||||||
|
|
||||||
|
public TrackPointsCard(@NonNull MapActivity mapActivity, @NonNull TrackDisplayHelper displayHelper) {
|
||||||
|
super(mapActivity);
|
||||||
|
this.displayHelper = displayHelper;
|
||||||
|
adapter = new PointGPXAdapter();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSelectionMode() {
|
||||||
|
return selectionMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSelectionMode(boolean selectionMode) {
|
||||||
|
this.selectionMode = selectionMode;
|
||||||
|
adapter.notifyDataSetInvalidated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCardLayoutId() {
|
||||||
|
return R.layout.track_points_card;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateContent() {
|
||||||
|
listView = view.findViewById(android.R.id.list);
|
||||||
|
listView.setOnChildClickListener(this);
|
||||||
|
|
||||||
|
adapter.setFilterResults(null);
|
||||||
|
adapter.synchronizeGroups(getOriginalGroups());
|
||||||
|
if (listView.getAdapter() == null) {
|
||||||
|
listView.setAdapter(adapter);
|
||||||
|
}
|
||||||
|
if (!adapter.isEmpty() && listView.getFooterViewsCount() == 0) {
|
||||||
|
LayoutInflater inflater = UiUtilities.getInflater(mapActivity, nightMode);
|
||||||
|
listView.addFooterView(inflater.inflate(R.layout.list_shadow_footer, listView, false));
|
||||||
|
addActions(inflater);
|
||||||
|
}
|
||||||
|
expandAllGroups();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addActions(LayoutInflater inflater) {
|
||||||
|
View view = inflater.inflate(R.layout.preference_category_with_descr, listView, false);
|
||||||
|
TextView title = view.findViewById(android.R.id.title);
|
||||||
|
title.setText(R.string.shared_string_actions);
|
||||||
|
|
||||||
|
AndroidUiHelper.updateVisibility(view.findViewById(android.R.id.icon), false);
|
||||||
|
AndroidUiHelper.updateVisibility(view.findViewById(android.R.id.summary), false);
|
||||||
|
listView.addFooterView(view);
|
||||||
|
|
||||||
|
addWaypointAction(inflater);
|
||||||
|
deleteWaypointAction(inflater);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addWaypointAction(LayoutInflater inflater) {
|
||||||
|
View view = inflater.inflate(R.layout.preference_button, listView, false);
|
||||||
|
TextView addWaypointTitle = view.findViewById(android.R.id.title);
|
||||||
|
ImageView addWaypointIcon = view.findViewById(android.R.id.icon);
|
||||||
|
|
||||||
|
addWaypointTitle.setText(R.string.add_waypoint);
|
||||||
|
addWaypointIcon.setImageDrawable(getContentIcon(R.drawable.ic_action_name_field));
|
||||||
|
|
||||||
|
AndroidUiHelper.updateVisibility(view.findViewById(R.id.divider), true);
|
||||||
|
|
||||||
|
view.setOnClickListener(new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
CardListener listener = getListener();
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onCardButtonPressed(TrackPointsCard.this, ADD_WAYPOINT_INDEX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
listView.addFooterView(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteWaypointAction(LayoutInflater inflater) {
|
||||||
|
View view = inflater.inflate(R.layout.preference_button, listView, false);
|
||||||
|
TextView deleteWaypointsTitle = view.findViewById(android.R.id.title);
|
||||||
|
ImageView deleteWaypointsIcon = view.findViewById(android.R.id.icon);
|
||||||
|
|
||||||
|
deleteWaypointsTitle.setText(R.string.delete_waypoints);
|
||||||
|
deleteWaypointsIcon.setImageDrawable(getColoredIcon(R.drawable.ic_action_delete_dark, R.color.color_osm_edit_delete));
|
||||||
|
|
||||||
|
view.setOnClickListener(new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
CardListener listener = getListener();
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onCardButtonPressed(TrackPointsCard.this, DELETE_WAYPOINTS_INDEX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
listView.addFooterView(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void expandAllGroups() {
|
||||||
|
for (int i = 0; i < adapter.getGroupCount(); i++) {
|
||||||
|
listView.expandGroup(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<GpxDisplayGroup> getOriginalGroups() {
|
||||||
|
return displayHelper.getOriginalGroups(filterTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteItemsAction() {
|
||||||
|
int size = getSelectedItemsCount();
|
||||||
|
if (size > 0) {
|
||||||
|
AlertDialog.Builder b = new AlertDialog.Builder(mapActivity);
|
||||||
|
b.setMessage(app.getString(R.string.points_delete_multiple, size));
|
||||||
|
b.setPositiveButton(R.string.shared_string_delete, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
deleteItems();
|
||||||
|
setSelectionMode(false);
|
||||||
|
adapter.notifyDataSetInvalidated();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
b.setNegativeButton(R.string.shared_string_cancel, null);
|
||||||
|
b.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteItems() {
|
||||||
|
new DeletePointsTask(app, displayHelper.getGpx(), getSelectedItems(), this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<GpxDisplayItem> getSelectedItems() {
|
||||||
|
Set<GpxDisplayItem> result = new LinkedHashSet<>();
|
||||||
|
for (Set<GpxDisplayItem> set : selectedItems.values()) {
|
||||||
|
if (set != null) {
|
||||||
|
result.addAll(set);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateSelectionMode() {
|
||||||
|
int size = getSelectedItemsCount();
|
||||||
|
app.showToastMessage(size + " " + app.getString(R.string.shared_string_selected_lowercase));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getSelectedItemsCount() {
|
||||||
|
int count = 0;
|
||||||
|
for (Set<GpxDisplayItem> set : selectedItems.values()) {
|
||||||
|
if (set != null) {
|
||||||
|
count += set.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPointsDeletionStarted() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPointsDeleted() {
|
||||||
|
selectedItems.clear();
|
||||||
|
selectedGroups.clear();
|
||||||
|
adapter.synchronizeGroups(getOriginalGroups());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void filter(String text) {
|
||||||
|
adapter.getFilter().filter(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class PointGPXAdapter extends OsmandBaseExpandableListAdapter implements Filterable {
|
||||||
|
|
||||||
|
private final List<GpxDisplayGroup> groups = new ArrayList<>();
|
||||||
|
private final Map<GpxDisplayGroup, List<GpxDisplayItem>> itemGroups = new LinkedHashMap<>();
|
||||||
|
private final Comparator<String> comparator;
|
||||||
|
private Filter pointsFilter;
|
||||||
|
private Set<?> filteredItems;
|
||||||
|
|
||||||
|
PointGPXAdapter() {
|
||||||
|
final Collator collator = OsmAndCollator.primaryCollator();
|
||||||
|
comparator = new Comparator<String>() {
|
||||||
|
@Override
|
||||||
|
public int compare(String s1, String s2) {
|
||||||
|
return collator.compare(s1, s2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void synchronizeGroups(@NonNull List<GpxDisplayGroup> displayGroups) {
|
||||||
|
groups.clear();
|
||||||
|
itemGroups.clear();
|
||||||
|
Set<?> filtered = filteredItems;
|
||||||
|
Collections.sort(displayGroups, new Comparator<GpxDisplayGroup>() {
|
||||||
|
@Override
|
||||||
|
public int compare(GpxDisplayGroup g1, GpxDisplayGroup g2) {
|
||||||
|
int i1 = g1.getType().ordinal();
|
||||||
|
int i2 = g2.getType().ordinal();
|
||||||
|
return i1 < i2 ? -1 : (i1 == i2 ? 0 : 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
List<GpxDisplayGroup> trackPointsGroups = new ArrayList<>();
|
||||||
|
List<GpxDisplayGroup> routePointsGroups = new ArrayList<>();
|
||||||
|
for (GpxDisplayGroup group : displayGroups) {
|
||||||
|
if (group.getType() == GpxDisplayItemType.TRACK_POINTS) {
|
||||||
|
trackPointsGroups.add(group);
|
||||||
|
} else if (group.getType() == GpxDisplayItemType.TRACK_ROUTE_POINTS) {
|
||||||
|
routePointsGroups.add(group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
processDisplayGroups(trackPointsGroups, filtered);
|
||||||
|
processDisplayGroups(routePointsGroups, filtered);
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processDisplayGroups(List<GpxDisplayGroup> displayGroups, Set<?> filteredItems) {
|
||||||
|
for (int i = 0; i < displayGroups.size(); i++) {
|
||||||
|
GpxDisplayGroup group = displayGroups.get(i);
|
||||||
|
if (group.getModifiableList().isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Map<String, List<GpxDisplayItem>> itemsMap = collectItemsByCategory(group, i);
|
||||||
|
if (filteredItems != null) {
|
||||||
|
itemsMap = filterItems(itemsMap, filteredItems);
|
||||||
|
}
|
||||||
|
if (!Algorithms.isEmpty(itemsMap)) {
|
||||||
|
setCollectedItems(group, itemsMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, List<GpxDisplayItem>> collectItemsByCategory(GpxDisplayGroup group, int index) {
|
||||||
|
Map<String, List<GpxDisplayItem>> itemsMap = new HashMap<>();
|
||||||
|
|
||||||
|
for (GpxDisplayItem item : group.getModifiableList()) {
|
||||||
|
String category;
|
||||||
|
if (item.locationStart != null) {
|
||||||
|
if (group.getType() == GpxDisplayItemType.TRACK_POINTS) {
|
||||||
|
category = item.locationStart.category;
|
||||||
|
if (Algorithms.isEmpty(category)) {
|
||||||
|
category = "";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
category = app.getString(R.string.route_points) + " " + (index + 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
category = "";
|
||||||
|
}
|
||||||
|
List<GpxDisplayItem> items = itemsMap.get(category);
|
||||||
|
if (items == null) {
|
||||||
|
items = new ArrayList<>();
|
||||||
|
itemsMap.put(category, items);
|
||||||
|
}
|
||||||
|
items.add(item);
|
||||||
|
}
|
||||||
|
return itemsMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, List<GpxDisplayItem>> filterItems(Map<String, List<GpxDisplayItem>> itemsMap, Set<?> filteredItems) {
|
||||||
|
Map<String, List<GpxDisplayItem>> itemsMapFiltered = new HashMap<>();
|
||||||
|
for (Entry<String, List<GpxDisplayItem>> e : itemsMap.entrySet()) {
|
||||||
|
String category = e.getKey();
|
||||||
|
List<GpxDisplayItem> items = e.getValue();
|
||||||
|
if (filteredItems.contains(category)) {
|
||||||
|
itemsMapFiltered.put(category, items);
|
||||||
|
} else {
|
||||||
|
for (GpxDisplayItem i : items) {
|
||||||
|
if (filteredItems.contains(i)) {
|
||||||
|
List<GpxDisplayItem> itemsFiltered = itemsMapFiltered.get(category);
|
||||||
|
if (itemsFiltered == null) {
|
||||||
|
itemsFiltered = new ArrayList<>();
|
||||||
|
itemsMapFiltered.put(category, itemsFiltered);
|
||||||
|
}
|
||||||
|
itemsFiltered.add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return itemsMapFiltered;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setCollectedItems(GpxDisplayGroup group, Map<String, List<GpxDisplayItem>> itemsMap) {
|
||||||
|
List<String> categories = new ArrayList<>(itemsMap.keySet());
|
||||||
|
Collections.sort(categories, comparator);
|
||||||
|
for (String category : categories) {
|
||||||
|
List<GpxDisplayItem> values = itemsMap.get(category);
|
||||||
|
GpxDisplayGroup headerGroup = group.cloneInstance();
|
||||||
|
headerGroup.setName(category);
|
||||||
|
for (GpxDisplayItem i : values) {
|
||||||
|
if (i.locationStart != null && i.locationStart.getColor() != 0) {
|
||||||
|
headerGroup.setColor(i.locationStart.getColor(group.getColor()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<GpxDisplayItem> headerGroupItems = headerGroup.getModifiableList();
|
||||||
|
headerGroupItems.clear();
|
||||||
|
headerGroupItems.addAll(values);
|
||||||
|
itemGroups.put(headerGroup, values);
|
||||||
|
this.groups.add(headerGroup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getGroupCount() {
|
||||||
|
return groups.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GpxDisplayGroup getGroup(int groupPosition) {
|
||||||
|
return groups.get(groupPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getGroupId(int groupPosition) {
|
||||||
|
return groupPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getChildrenCount(int groupPosition) {
|
||||||
|
return itemGroups.get(groups.get(groupPosition)).size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GpxDisplayItem getChild(int groupPosition, int childPosition) {
|
||||||
|
return itemGroups.get(groups.get(groupPosition)).get(childPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getChildId(int groupPosition, int childPosition) {
|
||||||
|
return groupPosition * 10000 + childPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isChildSelectable(int groupPosition, int childPosition) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasStableIds() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
|
||||||
|
final GpxDisplayGroup group = getGroup(groupPosition);
|
||||||
|
View row = convertView;
|
||||||
|
if (row == null) {
|
||||||
|
LayoutInflater inflater = LayoutInflater.from(view.getContext());
|
||||||
|
row = inflater.inflate(R.layout.wpt_list_item, parent, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
row.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if (listView.isGroupExpanded(groupPosition)) {
|
||||||
|
listView.collapseGroup(groupPosition);
|
||||||
|
} else {
|
||||||
|
listView.expandGroup(groupPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
String categoryName = group.getName();
|
||||||
|
if (TextUtils.isEmpty(categoryName)) {
|
||||||
|
categoryName = app.getString(R.string.shared_string_gpx_points);
|
||||||
|
}
|
||||||
|
SpannableStringBuilder text = new SpannableStringBuilder(categoryName)
|
||||||
|
.append(" – ")
|
||||||
|
.append(String.valueOf(getChildrenCount(groupPosition)));
|
||||||
|
text.setSpan(new ForegroundColorSpan(AndroidUtils.getColorFromAttr(view.getContext(), R.attr.wikivoyage_primary_text_color)),
|
||||||
|
0, categoryName.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
text.setSpan(new ForegroundColorSpan(ContextCompat.getColor(app, R.color.wikivoyage_secondary_text)),
|
||||||
|
categoryName.length() + 1, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
|
||||||
|
TextView title = row.findViewById(R.id.label);
|
||||||
|
title.setText(text);
|
||||||
|
|
||||||
|
ImageView icon = row.findViewById(R.id.icon);
|
||||||
|
icon.setImageDrawable(getContentIcon(R.drawable.ic_action_folder));
|
||||||
|
|
||||||
|
boolean expanded = listView.isGroupExpanded(groupPosition);
|
||||||
|
ImageView expandImage = row.findViewById(R.id.expand_image);
|
||||||
|
expandImage.setImageDrawable(getContentIcon(expanded ? R.drawable.ic_action_arrow_up : R.drawable.ic_action_arrow_down));
|
||||||
|
|
||||||
|
final CheckBox checkBox = (CheckBox) row.findViewById(R.id.toggle_item);
|
||||||
|
if (selectionMode) {
|
||||||
|
checkBox.setChecked(selectedGroups.contains(groupPosition));
|
||||||
|
checkBox.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
List<GpxDisplayItem> items = itemGroups.get(group);
|
||||||
|
setGroupSelection(items, groupPosition, checkBox.isChecked());
|
||||||
|
adapter.notifyDataSetInvalidated();
|
||||||
|
updateSelectionMode();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
AndroidUiHelper.updateVisibility(checkBox, true);
|
||||||
|
} else {
|
||||||
|
AndroidUiHelper.updateVisibility(checkBox, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageView options = (ImageView) row.findViewById(R.id.options);
|
||||||
|
options.setImageDrawable(getContentIcon(R.drawable.ic_overflow_menu_white));
|
||||||
|
options.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
EditTrackGroupDialogFragment.showInstance(mapActivity.getSupportFragmentManager(),
|
||||||
|
group, mapActivity.getTrackMenuFragment());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
AndroidUiHelper.updateVisibility(expandImage, true);
|
||||||
|
AndroidUiHelper.updateVisibility(row.findViewById(R.id.divider), true);
|
||||||
|
AndroidUiHelper.updateVisibility(row.findViewById(R.id.description), false);
|
||||||
|
AndroidUiHelper.updateVisibility(row.findViewById(R.id.list_divider), false);
|
||||||
|
AndroidUiHelper.updateVisibility(row.findViewById(R.id.group_divider), true);
|
||||||
|
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
|
||||||
|
View row = convertView;
|
||||||
|
if (row == null) {
|
||||||
|
LayoutInflater inflater = LayoutInflater.from(view.getContext());
|
||||||
|
row = inflater.inflate(R.layout.wpt_list_item, parent, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
final GpxDisplayGroup group = getGroup(groupPosition);
|
||||||
|
final GpxDisplayItem gpxItem = getChild(groupPosition, childPosition);
|
||||||
|
|
||||||
|
TextView title = row.findViewById(R.id.label);
|
||||||
|
title.setText(gpxItem.name);
|
||||||
|
|
||||||
|
TextView description = row.findViewById(R.id.description);
|
||||||
|
if (!Algorithms.isEmpty(gpxItem.description)) {
|
||||||
|
description.setText(gpxItem.description);
|
||||||
|
AndroidUiHelper.updateVisibility(description, true);
|
||||||
|
} else {
|
||||||
|
AndroidUiHelper.updateVisibility(description, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
final CheckBox checkBox = (CheckBox) row.findViewById(R.id.toggle_item);
|
||||||
|
if (selectionMode) {
|
||||||
|
checkBox.setVisibility(View.VISIBLE);
|
||||||
|
checkBox.setChecked(selectedItems.get(group.getType()) != null && selectedItems.get(group.getType()).contains(gpxItem));
|
||||||
|
checkBox.setOnClickListener(new View.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if (checkBox.isChecked()) {
|
||||||
|
Set<GpxDisplayItem> set = selectedItems.get(group.getType());
|
||||||
|
if (set != null) {
|
||||||
|
set.add(gpxItem);
|
||||||
|
} else {
|
||||||
|
set = new LinkedHashSet<>();
|
||||||
|
set.add(gpxItem);
|
||||||
|
selectedItems.put(group.getType(), set);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Set<GpxDisplayItem> set = selectedItems.get(group.getType());
|
||||||
|
if (set != null) {
|
||||||
|
set.remove(gpxItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateSelectionMode();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
AndroidUiHelper.updateVisibility(checkBox, true);
|
||||||
|
AndroidUiHelper.updateVisibility(row.findViewById(R.id.icon), false);
|
||||||
|
} else {
|
||||||
|
ImageView icon = row.findViewById(R.id.icon);
|
||||||
|
if (GpxDisplayItemType.TRACK_POINTS == group.getType()) {
|
||||||
|
WptPt wpt = gpxItem.locationStart;
|
||||||
|
int groupColor = wpt.getColor(group.getColor());
|
||||||
|
if (groupColor == 0) {
|
||||||
|
groupColor = ContextCompat.getColor(app, R.color.gpx_color_point);
|
||||||
|
}
|
||||||
|
icon.setImageDrawable(PointImageDrawable.getFromWpt(app, groupColor, false, wpt));
|
||||||
|
} else {
|
||||||
|
icon.setImageDrawable(getContentIcon(R.drawable.ic_action_marker_dark));
|
||||||
|
}
|
||||||
|
AndroidUiHelper.updateVisibility(icon, true);
|
||||||
|
AndroidUiHelper.updateVisibility(checkBox, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
AndroidUiHelper.updateVisibility(row.findViewById(R.id.divider), false);
|
||||||
|
AndroidUiHelper.updateVisibility(row.findViewById(R.id.options), false);
|
||||||
|
AndroidUiHelper.updateVisibility(row.findViewById(R.id.list_divider), true);
|
||||||
|
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setGroupSelection(List<GpxDisplayItem> items, int groupPosition, boolean select) {
|
||||||
|
GpxDisplayGroup group = groups.get(groupPosition);
|
||||||
|
if (select) {
|
||||||
|
selectedGroups.add(groupPosition);
|
||||||
|
if (items != null) {
|
||||||
|
Set<GpxDisplayItem> set = selectedItems.get(group.getType());
|
||||||
|
if (set != null) {
|
||||||
|
set.addAll(items);
|
||||||
|
} else {
|
||||||
|
set = new LinkedHashSet<>(items);
|
||||||
|
selectedItems.put(group.getType(), set);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
selectedGroups.remove(groupPosition);
|
||||||
|
selectedItems.remove(group.getType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Filter getFilter() {
|
||||||
|
if (pointsFilter == null) {
|
||||||
|
pointsFilter = new PointsFilter();
|
||||||
|
}
|
||||||
|
return pointsFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFilterResults(Set<?> values) {
|
||||||
|
this.filteredItems = values;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PointsFilter extends Filter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected FilterResults performFiltering(CharSequence constraint) {
|
||||||
|
FilterResults results = new FilterResults();
|
||||||
|
if (constraint == null || constraint.length() == 0) {
|
||||||
|
results.values = null;
|
||||||
|
results.count = 1;
|
||||||
|
} else {
|
||||||
|
Set<Object> filter = new HashSet<>();
|
||||||
|
String cs = constraint.toString().toLowerCase();
|
||||||
|
List<GpxDisplayGroup> groups = getOriginalGroups();
|
||||||
|
if (groups != null) {
|
||||||
|
for (GpxDisplayGroup g : groups) {
|
||||||
|
for (GpxDisplayItem i : g.getModifiableList()) {
|
||||||
|
if (i.name.toLowerCase().contains(cs)) {
|
||||||
|
filter.add(i);
|
||||||
|
} else if (i.locationStart != null && !TextUtils.isEmpty(i.locationStart.category)
|
||||||
|
&& i.locationStart.category.toLowerCase().contains(cs)) {
|
||||||
|
filter.add(i.locationStart.category);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
results.values = filter;
|
||||||
|
results.count = filter.size();
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void publishResults(CharSequence constraint, FilterResults results) {
|
||||||
|
synchronized (adapter) {
|
||||||
|
adapter.setFilterResults((Set<?>) results.values);
|
||||||
|
List<GpxDisplayGroup> groups = getOriginalGroups();
|
||||||
|
if (groups != null) {
|
||||||
|
adapter.synchronizeGroups(groups);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
adapter.notifyDataSetChanged();
|
||||||
|
expandAllGroups();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,19 +6,20 @@ import android.view.View;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import net.osmand.GPXUtilities.GPXFile;
|
||||||
import net.osmand.data.LatLon;
|
import net.osmand.data.LatLon;
|
||||||
import net.osmand.data.PointDescription;
|
import net.osmand.data.PointDescription;
|
||||||
import net.osmand.data.QuadRect;
|
import net.osmand.data.QuadRect;
|
||||||
import net.osmand.data.RotatedTileBox;
|
import net.osmand.data.RotatedTileBox;
|
||||||
import net.osmand.GPXUtilities.GPXFile;
|
|
||||||
import net.osmand.plus.UiUtilities;
|
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
|
import net.osmand.plus.UiUtilities;
|
||||||
import net.osmand.plus.activities.MapActivity;
|
import net.osmand.plus.activities.MapActivity;
|
||||||
import net.osmand.plus.activities.TrackActivity;
|
import net.osmand.plus.activities.TrackActivity;
|
||||||
import net.osmand.plus.mapcontextmenu.MapContextMenu;
|
import net.osmand.plus.mapcontextmenu.MapContextMenu;
|
||||||
import net.osmand.plus.mapcontextmenu.editors.RtePtEditor;
|
import net.osmand.plus.mapcontextmenu.editors.RtePtEditor;
|
||||||
import net.osmand.plus.mapcontextmenu.editors.WptPtEditor;
|
import net.osmand.plus.mapcontextmenu.editors.WptPtEditor;
|
||||||
import net.osmand.plus.mapcontextmenu.editors.WptPtEditor.OnDismissListener;
|
import net.osmand.plus.mapcontextmenu.editors.WptPtEditor.OnDismissListener;
|
||||||
|
import net.osmand.plus.track.TrackMenuFragment;
|
||||||
import net.osmand.plus.views.layers.ContextMenuLayer;
|
import net.osmand.plus.views.layers.ContextMenuLayer;
|
||||||
|
|
||||||
public class AddGpxPointBottomSheetHelper implements OnDismissListener {
|
public class AddGpxPointBottomSheetHelper implements OnDismissListener {
|
||||||
|
@ -73,7 +74,7 @@ public class AddGpxPointBottomSheetHelper implements OnDismissListener {
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
hide();
|
hide();
|
||||||
contextMenuLayer.cancelAddGpxPoint();
|
contextMenuLayer.cancelAddGpxPoint();
|
||||||
openTrackActivity();
|
onClose();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -140,8 +141,17 @@ public class AddGpxPointBottomSheetHelper implements OnDismissListener {
|
||||||
if (contextMenu.isVisible() && contextMenu.isClosable()) {
|
if (contextMenu.isVisible() && contextMenu.isClosable()) {
|
||||||
contextMenu.close();
|
contextMenu.close();
|
||||||
}
|
}
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onClose() {
|
||||||
|
TrackMenuFragment fragment = mapActivity.getTrackMenuFragment();
|
||||||
|
if (fragment != null) {
|
||||||
|
fragment.show();
|
||||||
|
} else {
|
||||||
openTrackActivity();
|
openTrackActivity();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void openTrackActivity() {
|
private void openTrackActivity() {
|
||||||
Intent newIntent = new Intent(mapActivity, mapActivity.getMyApplication().getAppCustomization().getTrackActivity());
|
Intent newIntent = new Intent(mapActivity, mapActivity.getMyApplication().getAppCustomization().getTrackActivity());
|
||||||
|
|
|
@ -574,7 +574,6 @@ public class ContextMenuLayer extends OsmandMapLayer {
|
||||||
public void cancelAddGpxPoint() {
|
public void cancelAddGpxPoint() {
|
||||||
cancelApplyingNewMarkerPosition = true;
|
cancelApplyingNewMarkerPosition = true;
|
||||||
quitAddGpxPoint();
|
quitAddGpxPoint();
|
||||||
activity.getContextMenu().show();
|
|
||||||
applyingMarkerLatLon = null;
|
applyingMarkerLatLon = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -516,7 +516,7 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
|
||||||
for (WptPt wpt : getListStarPoints(g)) {
|
for (WptPt wpt : getListStarPoints(g)) {
|
||||||
if (wpt.lat >= latLonBounds.bottom && wpt.lat <= latLonBounds.top
|
if (wpt.lat >= latLonBounds.bottom && wpt.lat <= latLonBounds.top
|
||||||
&& wpt.lon >= latLonBounds.left && wpt.lon <= latLonBounds.right
|
&& wpt.lon >= latLonBounds.left && wpt.lon <= latLonBounds.right
|
||||||
&& wpt != contextMenuLayer.getMoveableObject()) {
|
&& wpt != contextMenuLayer.getMoveableObject() && !isPointHidden(g, wpt)) {
|
||||||
pointFileMap.put(wpt, g);
|
pointFileMap.put(wpt, g);
|
||||||
MapMarker marker = null;
|
MapMarker marker = null;
|
||||||
if (synced) {
|
if (synced) {
|
||||||
|
@ -777,6 +777,14 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
|
||||||
return g.getGpxFile().getPoints();
|
return g.getGpxFile().getPoints();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isPointHidden(SelectedGpxFile selectedGpxFile, WptPt point) {
|
||||||
|
if (!Algorithms.isEmpty(selectedGpxFile.getHiddenGroups())) {
|
||||||
|
return selectedGpxFile.getHiddenGroups().contains(point.category);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private boolean calculateBelongs(int ex, int ey, int objx, int objy, int radius) {
|
private boolean calculateBelongs(int ex, int ey, int objx, int objy, int radius) {
|
||||||
return (Math.abs(objx - ex) <= radius && Math.abs(objy - ey) <= radius);
|
return (Math.abs(objx - ex) <= radius && Math.abs(objy - ey) <= radius);
|
||||||
}
|
}
|
||||||
|
@ -790,6 +798,9 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
|
||||||
List<WptPt> pts = getListStarPoints(g);
|
List<WptPt> pts = getListStarPoints(g);
|
||||||
// int fcolor = g.getColor() == 0 ? clr : g.getColor();
|
// int fcolor = g.getColor() == 0 ? clr : g.getColor();
|
||||||
for (WptPt n : pts) {
|
for (WptPt n : pts) {
|
||||||
|
if (isPointHidden(g, n)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
int x = (int) tb.getPixXFromLatLon(n.lat, n.lon);
|
int x = (int) tb.getPixXFromLatLon(n.lat, n.lon);
|
||||||
int y = (int) tb.getPixYFromLatLon(n.lat, n.lon);
|
int y = (int) tb.getPixYFromLatLon(n.lat, n.lon);
|
||||||
if (calculateBelongs(ex, ey, x, y, r)) {
|
if (calculateBelongs(ex, ey, x, y, r)) {
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue