Merge remote-tracking branch 'origin/master'

This commit is contained in:
Weblate 2017-08-22 18:45:50 +02:00
commit e6d87e13fb
86 changed files with 6590 additions and 743 deletions

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<nine-patch android:src="@drawable/bg_shadow_bottomsheet_sides"/>
</item>
<item>
<shape>
<solid android:color="@color/bg_color_dark"/>
</shape>
</item>
</layer-list>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<nine-patch android:src="@drawable/bg_shadow_bottomsheet_sides"/>
</item>
<item>
<shape>
<solid android:color="@color/bg_color_light"/>
</shape>
</item>
</layer-list>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<nine-patch android:src="@drawable/bg_shadow_bottomsheet_topsides"/>
</item>
<item>
<shape>
<solid android:color="@color/bg_color_dark"/>
</shape>
</item>
</layer-list>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<nine-patch android:src="@drawable/bg_shadow_bottomsheet_topsides"/>
</item>
<item>
<shape>
<solid android:color="@color/bg_color_light"/>
</shape>
</item>
</layer-list>

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid android:color="@color/bg_color_dark" />
<stroke android:color="@color/map_widget_blue_pressed" android:width="1dp"/>
<corners android:radius="@dimen/map_button_rect_rad" />
</shape>
</item>
<item android:state_enabled="false">
<shape android:shape="rectangle">
<solid android:color="@color/bg_color_dark" />
<stroke android:color="@color/searchbar_tab_inactive_light" android:width="1dp"/>
<corners android:radius="@dimen/map_button_rect_rad" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid android:color="@color/bg_color_dark" />
<stroke android:color="@color/map_widget_blue" android:width="1dp"/>
<corners android:radius="@dimen/map_button_rect_rad" />
</shape>
</item>
</selector>

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid android:color="@color/bg_color_light" />
<stroke android:color="@color/map_widget_blue_pressed" android:width="1dp"/>
<corners android:radius="@dimen/map_button_rect_rad" />
</shape>
</item>
<item android:state_enabled="false">
<shape android:shape="rectangle">
<solid android:color="@color/bg_color_light" />
<stroke android:color="@color/searchbar_tab_inactive_light" android:width="1dp"/>
<corners android:radius="@dimen/map_button_rect_rad" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid android:color="@color/bg_color_light" />
<stroke android:color="@color/map_widget_blue" android:width="1dp"/>
<corners android:radius="@dimen/map_button_rect_rad" />
</shape>
</item>
</selector>

View file

@ -0,0 +1,58 @@
<?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:id="@android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:layout_marginTop="@dimen/my_places_empty_state_image_margin_top"
android:layout_marginBottom="@dimen/my_places_empty_state_image_margin_bottom"
android:adjustViewBounds="true"
android:layout_marginLeft="@dimen/my_places_empty_state_image_margin_left"
android:layout_marginStart="@dimen/my_places_empty_state_image_margin_left"
android:id="@+id/empty_state_image_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
tools:src="@drawable/ic_empty_state_favorites_night_result"/>
<LinearLayout
android:clipToPadding="false"
android:paddingLeft="@dimen/my_places_empty_state_text_button_padding_left"
android:paddingStart="@dimen/my_places_empty_state_text_button_padding_left"
android:paddingRight="@dimen/my_places_empty_state_text_button_padding_right"
android:paddingEnd="@dimen/my_places_empty_state_text_button_padding_right"
android:paddingTop="@dimen/my_places_empty_state_text_button_padding_top"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical">
<net.osmand.plus.widgets.TextViewEx
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/my_places_empty_state_text_interval"
android:background="@null"
android:text="@string/empty_state_favourites"
android:textColor="?android:attr/textColorPrimary"
android:textSize="@dimen/my_places_empty_state_text_size"
osmand:typeface="@string/font_roboto_medium"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@null"
android:text="@string/empty_state_favourites_desc"
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/my_places_empty_state_text_desc_size"/>
<Button
android:id="@+id/import_button"
style="@style/DialogActionButton"
android:layout_marginTop="@dimen/my_places_empty_state_button_margin_top"
android:text="@string/shared_string_import"/>
</LinearLayout>
</LinearLayout>

View file

@ -0,0 +1,58 @@
<?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:id="@android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:layout_marginTop="@dimen/my_places_empty_state_image_margin_top"
android:layout_marginBottom="@dimen/my_places_empty_state_image_margin_bottom"
android:adjustViewBounds="true"
android:layout_marginLeft="@dimen/my_places_empty_state_image_margin_left"
android:layout_marginStart="@dimen/my_places_empty_state_image_margin_left"
android:id="@+id/empty_state_image_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
tools:src="@drawable/ic_empty_state_trip_night_result"/>
<LinearLayout
android:clipToPadding="false"
android:paddingLeft="@dimen/my_places_empty_state_text_button_padding_left"
android:paddingStart="@dimen/my_places_empty_state_text_button_padding_left"
android:paddingRight="@dimen/my_places_empty_state_text_button_padding_right"
android:paddingEnd="@dimen/my_places_empty_state_text_button_padding_right"
android:paddingTop="@dimen/my_places_empty_state_text_button_padding_top"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical">
<net.osmand.plus.widgets.TextViewEx
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/my_places_empty_state_text_interval"
android:background="@null"
android:text="@string/empty_state_my_tracks"
android:textColor="?android:attr/textColorPrimary"
android:textSize="@dimen/my_places_empty_state_text_size"
osmand:typeface="@string/font_roboto_medium"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@null"
android:text="@string/empty_state_my_tracks_desc"
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/my_places_empty_state_text_desc_size"/>
<Button
android:id="@+id/import_button"
style="@style/DialogActionButton"
android:layout_marginTop="@dimen/my_places_empty_state_button_margin_top"
android:text="@string/shared_string_import"/>
</LinearLayout>
</LinearLayout>

View file

@ -0,0 +1,345 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
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:background="@color/color_transparent"
android:clickable="true">
<LinearLayout
android:id="@+id/main_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:clickable="true"
android:orientation="vertical"
tools:background="@drawable/bg_bottom_menu_dark">
<ProgressBar
android:id="@+id/snap_to_road_progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="0dp"
android:visibility="gone"
tools:visibility="visible"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="@+id/up_down_row"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.45"
android:background="?attr/selectableItemBackground"
android:paddingBottom="14dp"
android:paddingTop="14dp">
<ImageView
android:id="@+id/main_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginEnd="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginStart="16dp"
android:background="@null"
tools:src="@drawable/ic_action_ruler"/>
<ImageView
android:id="@+id/up_down_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginEnd="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginStart="16dp"
android:background="@null"
tools:src="@drawable/ic_action_arrow_down"/>
<TextView
android:id="@+id/measurement_distance_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="4dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="4dp"
android:layout_marginStart="8dp"
android:layout_toEndOf="@id/main_icon"
android:layout_toRightOf="@id/main_icon"
android:textAppearance="@style/TextAppearance.ListItemTitle"
tools:text="724 m,"/>
<TextView
android:id="@+id/measurement_points_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/measurement_distance_text_view"
android:layout_toRightOf="@id/measurement_distance_text_view"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_list_text_size"
tools:text="points: 3"/>
<TextView
android:id="@+id/distance_to_center_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/measurement_points_text_view"
android:layout_toLeftOf="@id/up_down_button"
android:layout_toRightOf="@id/measurement_points_text_view"
android:layout_toStartOf="@id/up_down_button"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_list_text_size"
tools:text=" 700 m"/>
<TextView
android:id="@+id/move_point_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="4dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="4dp"
android:layout_marginStart="8dp"
android:layout_toEndOf="@id/main_icon"
android:layout_toRightOf="@id/main_icon"
android:text="@string/move_point"
android:textAppearance="@style/TextAppearance.ListItemTitle"
android:visibility="gone"/>
<TextView
android:id="@+id/add_point_after_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="4dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="4dp"
android:layout_marginStart="8dp"
android:layout_toEndOf="@id/main_icon"
android:layout_toRightOf="@id/main_icon"
android:text="@string/add_point_after"
android:textAppearance="@style/TextAppearance.ListItemTitle"
android:visibility="gone"/>
<TextView
android:id="@+id/add_point_before_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="4dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="4dp"
android:layout_marginStart="8dp"
android:layout_toEndOf="@id/main_icon"
android:layout_toRightOf="@id/main_icon"
android:text="@string/add_point_before"
android:textAppearance="@style/TextAppearance.ListItemTitle"
android:visibility="gone"/>
</RelativeLayout>
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="?attr/dashboard_divider"/>
<LinearLayout
android:id="@+id/measure_mode_controls"
android:layout_width="0dp"
android:layout_height="52dp"
android:layout_weight="0.55">
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/options_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:gravity="center_vertical"
android:maxLines="1"
android:paddingEnd="12dp"
android:paddingLeft="16dp"
android:paddingRight="12dp"
android:paddingStart="16dp"
android:text="@string/shared_string_options"
android:textColor="?attr/color_dialog_buttons"
osmand:textAllCapsCompat="true"
osmand:typeface="@string/font_roboto_medium"/>
</FrameLayout>
<ImageButton
android:id="@+id/undo_point_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:paddingBottom="14dp"
android:paddingEnd="12dp"
android:paddingLeft="16dp"
android:paddingRight="12dp"
android:paddingStart="16dp"
android:paddingTop="14dp"
tools:src="@drawable/ic_action_undo_dark"/>
<ImageButton
android:id="@+id/redo_point_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:paddingBottom="14dp"
android:paddingEnd="16dp"
android:paddingLeft="12dp"
android:paddingRight="16dp"
android:paddingStart="12dp"
android:paddingTop="14dp"
tools:src="@drawable/ic_action_redo_dark"/>
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<Button
android:id="@+id/add_point_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:background="@drawable/btn_round_blue"
android:drawableLeft="@drawable/ic_action_plus"
android:maxLines="1"
android:minHeight="36dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:text="@string/shared_string_add"
android:textColor="@color/color_white"/>
</FrameLayout>
</LinearLayout>
<RelativeLayout
android:id="@+id/move_point_controls"
android:layout_width="0dp"
android:layout_height="52dp"
android:layout_weight="0.6"
android:visibility="gone">
<Button
android:id="@+id/apply_move_point_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:background="@drawable/btn_round_blue"
android:minHeight="36dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:text="@string/shared_string_apply"
android:textColor="@color/color_white"/>
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/cancel_move_point_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:gravity="center_vertical"
android:paddingEnd="12dp"
android:paddingLeft="16dp"
android:paddingRight="12dp"
android:paddingStart="16dp"
android:text="@string/shared_string_cancel"
android:textColor="?attr/color_dialog_buttons"
osmand:textAllCapsCompat="true"
osmand:typeface="@string/font_roboto_medium"/>
</RelativeLayout>
<LinearLayout
android:id="@+id/add_point_before_after_controls"
android:layout_width="0dp"
android:layout_height="52dp"
android:layout_weight="0.6"
android:gravity="center_vertical"
android:orientation="horizontal"
android:visibility="gone">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/cancel_point_before_after_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:gravity="center_vertical"
android:paddingEnd="12dp"
android:paddingLeft="16dp"
android:paddingRight="12dp"
android:paddingStart="16dp"
android:text="@string/shared_string_cancel"
android:textColor="?attr/color_dialog_buttons"
osmand:textAllCapsCompat="true"
osmand:typeface="@string/font_roboto_medium"/>
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
<Button
android:id="@+id/apply_point_before_after_point_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:background="?attr/btn_round_border"
android:minHeight="36dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:text="@string/shared_string_apply"
android:textColor="?attr/color_dialog_buttons"/>
<Button
android:id="@+id/add_point_before_after_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:background="@drawable/btn_round_blue"
android:drawableLeft="@drawable/ic_action_plus"
android:minHeight="36dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:text="@string/shared_string_add"
android:textColor="@color/color_white"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</FrameLayout>

View file

@ -94,6 +94,15 @@
android:background="@drawable/btn_round" android:background="@drawable/btn_round"
android:contentDescription="@string/layer_route" android:contentDescription="@string/layer_route"
tools:src="@drawable/ic_action_test_light"/> tools:src="@drawable/ic_action_test_light"/>
<ImageButton
android:id="@+id/snap_to_road_image_button"
android:layout_width="@dimen/map_button_size"
android:layout_height="@dimen/map_button_size"
android:layout_gravity="bottom"
android:background="@drawable/btn_circle"
android:visibility="gone"
tools:src="@drawable/ic_action_test_light"/>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
</FrameLayout> </FrameLayout>
@ -268,4 +277,9 @@
android:layout_gravity="bottom|left" android:layout_gravity="bottom|left"
tools:visibility="visible"/> tools:visibility="visible"/>
<FrameLayout
android:id="@+id/bottomFragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout> </LinearLayout>

View file

@ -3,6 +3,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:osmand="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"> android:orientation="vertical">
<FrameLayout <FrameLayout
@ -457,6 +458,35 @@
android:contentDescription="@string/shared_string_close" android:contentDescription="@string/shared_string_close"
android:src="@drawable/ic_action_remove_dark"/> android:src="@drawable/ic_action_remove_dark"/>
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/widget_top_bar_save"
android:layout_width="wrap_content"
android:layout_height="56dp"
android:background="@null"
android:ellipsize="end"
android:gravity="center_vertical"
android:lines="1"
android:paddingRight="16dp"
android:paddingEnd="16dp"
android:textAllCaps="true"
android:singleLine="true"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_desc_text_size"
android:contentDescription="@string/shared_string_save"
android:text="@string/shared_string_save"
tools:visibility="visible"
android:visibility="gone"
osmand:typeface="@string/font_roboto_medium"/>
<android.support.v7.widget.SwitchCompat
android:id="@+id/widget_top_bar_switch"
android:layout_width="wrap_content"
android:layout_height="56dp"
android:paddingEnd="16dp"
android:paddingRight="16dp"
android:visibility="gone"
tools:visibility="visible"/>
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout

View file

@ -1,8 +1,9 @@
<?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"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:background="?attr/ctx_menu_info_view_bg"
android:orientation="vertical">
<ExpandableListView <ExpandableListView
android:id="@android:id/list" android:id="@android:id/list"
@ -17,4 +18,7 @@
android:drawSelectorOnTop="false" android:drawSelectorOnTop="false"
android:groupIndicator="@android:color/transparent"/> android:groupIndicator="@android:color/transparent"/>
<include layout="@layout/empty_state_my_tracks"
android:id="@android:id/empty"/>
</LinearLayout> </LinearLayout>

View file

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:osmand="http://schemas.android.com/apk/res-auto"
android:id="@android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<ImageView
android:id="@+id/empty_state_image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/my_places_empty_state_image_margin_bottom"
android:layout_marginTop="@dimen/my_places_empty_state_image_margin_top"
tools:src="@drawable/ic_empty_state_favorites_night_result"/>
<net.osmand.plus.widgets.TextViewEx
osmand:typeface="@string/font_roboto_medium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/my_places_empty_state_text_interval"
android:background="@null"
android:text="@string/empty_state_favourites"
android:textColor="?android:attr/textColorPrimary"
android:textSize="@dimen/my_places_empty_state_text_size"/>
<TextView
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@null"
android:layout_marginLeft="@dimen/my_places_empty_state_text_desc_margin"
android:layout_marginRight="@dimen/my_places_empty_state_text_desc_margin"
android:text="@string/empty_state_favourites_desc"
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/my_places_empty_state_text_desc_size"/>
<Button
android:id="@+id/import_button"
style="@style/DialogActionButton"
android:layout_marginTop="@dimen/my_places_empty_state_button_margin_top"
android:text="@string/shared_string_import"/>
</LinearLayout>

View file

@ -0,0 +1,46 @@
<?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:visibility="gone"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<ImageView
android:id="@+id/empty_state_image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/my_places_empty_state_image_margin_bottom"
android:layout_marginTop="@dimen/my_places_empty_state_image_margin_top"
tools:src="@drawable/ic_empty_state_trip_night_result"/>
<net.osmand.plus.widgets.TextViewEx
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/my_places_empty_state_text_interval"
android:background="@null"
android:text="@string/empty_state_my_tracks"
android:textColor="?android:attr/textColorPrimary"
android:textSize="@dimen/my_places_empty_state_text_size"
osmand:typeface="@string/font_roboto_medium"/>
<TextView
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@null"
android:layout_marginLeft="@dimen/my_places_empty_state_text_desc_margin"
android:layout_marginRight="@dimen/my_places_empty_state_text_desc_margin"
android:text="@string/empty_state_my_tracks_desc"
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/my_places_empty_state_text_desc_size"/>
<Button
android:id="@+id/import_button"
style="@style/DialogActionButton"
android:layout_marginTop="@dimen/my_places_empty_state_button_margin_top"
android:text="@string/shared_string_import"/>
</LinearLayout>

View file

@ -1,9 +1,10 @@
<?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"
android:id="@+id/MainLayout" android:id="@+id/MainLayout"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical"> android:orientation="vertical"
android:background="?attr/ctx_menu_info_view_bg">
<ExpandableListView <ExpandableListView
android:id="@android:id/list" android:id="@android:id/list"
@ -16,6 +17,9 @@
android:divider="@null" android:divider="@null"
android:dividerHeight="0dp" android:dividerHeight="0dp"
android:drawSelectorOnTop="false" android:drawSelectorOnTop="false"
android:groupIndicator="@android:color/transparent" /> android:groupIndicator="@android:color/transparent"/>
<include layout="@layout/empty_state_favourites"
android:id="@android:id/empty"/>
</LinearLayout> </LinearLayout>

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout <FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android" 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" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -16,14 +17,25 @@
android:clickable="true" android:clickable="true"
android:orientation="vertical"> android:orientation="vertical">
<RelativeLayout <ProgressBar
android:id="@+id/snap_to_road_progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:minHeight="0dp"
android:visibility="gone"
tools:visibility="visible"/>
<RelativeLayout
android:id="@+id/up_down_row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:paddingBottom="12dp" android:paddingBottom="12dp"
android:paddingTop="12dp"> android:paddingTop="12dp">
<ImageView <ImageView
android:id="@+id/ruler_icon" android:id="@+id/main_icon"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
@ -36,16 +48,18 @@
android:background="@null" android:background="@null"
tools:src="@drawable/ic_action_ruler"/> tools:src="@drawable/ic_action_ruler"/>
<ImageButton <ImageView
android:id="@+id/up_down_button" android:id="@+id/up_down_button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:layout_marginEnd="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginStart="16dp"
android:background="@null" android:background="@null"
android:paddingEnd="16dp"
android:paddingStart="16dp"
tools:src="@drawable/ic_action_arrow_down"/> tools:src="@drawable/ic_action_arrow_down"/>
<TextView <TextView
@ -57,8 +71,8 @@
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_marginRight="4dp" android:layout_marginRight="4dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:layout_toEndOf="@id/ruler_icon" android:layout_toEndOf="@id/main_icon"
android:layout_toRightOf="@id/ruler_icon" android:layout_toRightOf="@id/main_icon"
android:textAppearance="@style/TextAppearance.ListItemTitle" android:textAppearance="@style/TextAppearance.ListItemTitle"
tools:text="724 m,"/> tools:text="724 m,"/>
@ -68,12 +82,68 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:layout_toEndOf="@id/measurement_distance_text_view" android:layout_toEndOf="@id/measurement_distance_text_view"
android:layout_toLeftOf="@id/up_down_button"
android:layout_toRightOf="@id/measurement_distance_text_view" android:layout_toRightOf="@id/measurement_distance_text_view"
android:layout_toStartOf="@id/up_down_button"
android:textColor="?android:textColorSecondary" android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_list_text_size" android:textSize="@dimen/default_list_text_size"
tools:text="points: 3"/> tools:text="points: 3"/>
<TextView
android:id="@+id/distance_to_center_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/measurement_points_text_view"
android:layout_toLeftOf="@id/up_down_button"
android:layout_toRightOf="@id/measurement_points_text_view"
android:layout_toStartOf="@id/up_down_button"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_list_text_size"
tools:text=" 700 m"/>
<TextView
android:id="@+id/move_point_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="4dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="4dp"
android:layout_marginStart="8dp"
android:layout_toEndOf="@id/main_icon"
android:layout_toRightOf="@id/main_icon"
android:text="@string/move_point"
android:textAppearance="@style/TextAppearance.ListItemTitle"
android:visibility="gone"/>
<TextView
android:id="@+id/add_point_after_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="4dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="4dp"
android:layout_marginStart="8dp"
android:layout_toEndOf="@id/main_icon"
android:layout_toRightOf="@id/main_icon"
android:text="@string/add_point_after"
android:textAppearance="@style/TextAppearance.ListItemTitle"
android:visibility="gone"/>
<TextView
android:id="@+id/add_point_before_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="4dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="4dp"
android:layout_marginStart="8dp"
android:layout_toEndOf="@id/main_icon"
android:layout_toRightOf="@id/main_icon"
android:text="@string/add_point_before"
android:textAppearance="@style/TextAppearance.ListItemTitle"
android:visibility="gone"/>
</RelativeLayout> </RelativeLayout>
<View <View
@ -81,58 +151,118 @@
android:layout_height="1dp" android:layout_height="1dp"
android:background="?attr/dashboard_divider"/> android:background="?attr/dashboard_divider"/>
<LinearLayout <FrameLayout
android:id="@+id/points_list_container" android:id="@+id/points_list_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="220dp" android:layout_height="220dp"
android:background="@color/ctx_menu_info_view_bg_dark" android:background="@color/ctx_menu_info_view_bg_dark"
android:orientation="vertical"
android:visibility="gone"> android:visibility="gone">
<android.support.v7.widget.RecyclerView
android:id="@+id/measure_points_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<include layout="@layout/card_bottom_divider"/> <include layout="@layout/card_bottom_divider"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/points_recycler_view"
android:layout_width="match_parent"
android:layout_height="215dp"/>
<ImageView <ImageView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="5dp"
android:layout_gravity="bottom"
android:alpha="0.5"
android:scaleType="fitXY" android:scaleType="fitXY"
android:src="@drawable/bg_shadow_onmap"/> android:src="@drawable/bg_shadow_onmap"/>
</LinearLayout> </FrameLayout>
<RelativeLayout <LinearLayout
android:id="@+id/measure_mode_controls"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="52dp">
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/options_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:ellipsize="end"
android:gravity="center_vertical"
android:maxLines="1"
android:paddingEnd="12dp"
android:paddingLeft="16dp"
android:paddingRight="12dp"
android:paddingStart="16dp"
android:text="@string/shared_string_options"
android:textColor="?attr/color_dialog_buttons"
osmand:textAllCapsCompat="true"
osmand:typeface="@string/font_roboto_medium"/>
</FrameLayout>
<ImageButton <ImageButton
android:id="@+id/undo_point_button" android:id="@+id/undo_point_button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true" android:background="?attr/selectableItemBackground"
android:layout_alignParentStart="true" android:paddingBottom="14dp"
android:layout_centerVertical="true" android:paddingEnd="12dp"
android:background="@null" android:paddingLeft="16dp"
android:paddingEnd="16dp" android:paddingRight="12dp"
android:paddingStart="16dp" android:paddingStart="16dp"
android:paddingTop="14dp"
tools:src="@drawable/ic_action_undo_dark"/> tools:src="@drawable/ic_action_undo_dark"/>
<ImageButton <ImageButton
android:id="@+id/redo_point_button" android:id="@+id/redo_point_button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerVertical="true" android:background="?attr/selectableItemBackground"
android:layout_toEndOf="@id/undo_point_button" android:paddingBottom="14dp"
android:layout_toRightOf="@id/undo_point_button" android:paddingEnd="16dp"
android:background="@null" android:paddingLeft="12dp"
android:paddingEnd="8dp" android:paddingRight="16dp"
android:paddingStart="8dp" android:paddingStart="12dp"
android:paddingTop="14dp"
tools:src="@drawable/ic_action_redo_dark"/> tools:src="@drawable/ic_action_redo_dark"/>
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<Button
android:id="@+id/add_point_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:background="@drawable/btn_round_blue"
android:drawableLeft="@drawable/ic_action_plus"
android:ellipsize="end"
android:maxLines="1"
android:minHeight="36dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:text="@string/shared_string_add"
android:textColor="@color/color_white"/>
</FrameLayout>
</LinearLayout>
<RelativeLayout
android:id="@+id/move_point_controls"
android:layout_width="match_parent"
android:layout_height="52dp"
android:visibility="gone">
<Button <Button
android:id="@+id/add_point_button" android:id="@+id/apply_move_point_button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
@ -143,13 +273,87 @@
android:layout_marginRight="8dp" android:layout_marginRight="8dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:background="@drawable/btn_round_blue" android:background="@drawable/btn_round_blue"
android:minHeight="36dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:text="@string/shared_string_apply"
android:textColor="@color/color_white"/>
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/cancel_move_point_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:gravity="center_vertical"
android:paddingEnd="12dp"
android:paddingLeft="16dp"
android:paddingRight="12dp"
android:paddingStart="16dp"
android:text="@string/shared_string_cancel"
android:textColor="?attr/color_dialog_buttons"
osmand:textAllCapsCompat="true"
osmand:typeface="@string/font_roboto_medium"/>
</RelativeLayout>
<LinearLayout
android:id="@+id/add_point_before_after_controls"
android:layout_width="match_parent"
android:layout_height="52dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:visibility="gone">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/cancel_point_before_after_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:gravity="center_vertical"
android:paddingEnd="12dp"
android:paddingLeft="16dp"
android:paddingRight="12dp"
android:paddingStart="16dp"
android:text="@string/shared_string_cancel"
android:textColor="?attr/color_dialog_buttons"
osmand:textAllCapsCompat="true"
osmand:typeface="@string/font_roboto_medium"/>
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
<Button
android:id="@+id/apply_point_before_after_point_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:background="?attr/btn_round_border"
android:minHeight="36dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:text="@string/shared_string_apply"
android:textColor="?attr/color_dialog_buttons"/>
<Button
android:id="@+id/add_point_before_after_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:background="@drawable/btn_round_blue"
android:drawableLeft="@drawable/ic_action_plus" android:drawableLeft="@drawable/ic_action_plus"
android:minHeight="36dp" android:minHeight="36dp"
android:paddingLeft="8dp" android:paddingLeft="8dp"
android:paddingRight="8dp" android:paddingRight="8dp"
android:text="@string/shared_string_add" android:text="@string/shared_string_add"
android:textColor="@color/color_white"/> android:textColor="@color/color_white"/>
</RelativeLayout> </LinearLayout>
</LinearLayout> </LinearLayout>

View file

@ -0,0 +1,269 @@
<?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:background="?attr/bg_color"
android:orientation="vertical">
<ScrollView
android:id="@+id/measure_options_scroll_view"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="8dp">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/options_title"
android:layout_width="match_parent"
android:layout_height="52dp"
android:gravity="center_vertical"
android:paddingEnd="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingStart="16dp"
android:text="@string/shared_string_options"
android:textAppearance="@style/TextAppearance.ListItemTitle"
osmand:typeface="@string/font_roboto_medium"/>
<RelativeLayout
android:id="@+id/snap_to_road_row"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="?attr/selectableItemBackground"
android:minHeight="48dp"
android:paddingEnd="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingStart="16dp">
<ImageView
android:id="@+id/snap_to_road_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
tools:src="@drawable/ic_action_snap_to_road"/>
<android.support.v7.widget.SwitchCompat
android:id="@+id/snap_to_road_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:background="@null"
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/snap_to_road_icon"
android:layout_toLeftOf="@id/snap_to_road_switch"
android:layout_toRightOf="@id/snap_to_road_icon"
android:layout_toStartOf="@id/snap_to_road_switch"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="@string/snap_to_road"
android:textAppearance="@style/TextAppearance.ListItemTitle"/>
<TextView
android:id="@+id/snap_to_road_enabled_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/shared_string_enabled"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"
android:visibility="gone"
tools:visibility="visible"/>
</LinearLayout>
</RelativeLayout>
<View
android:layout_width="wrap_content"
android:layout_height="1dp"
android:layout_marginBottom="8dp"
android:layout_marginLeft="64dp"
android:layout_marginStart="64dp"
android:layout_marginTop="7dp"
android:background="?attr/dashboard_divider"/>
<RelativeLayout
android:id="@+id/save_as_new_segment_row"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="?attr/selectableItemBackground"
android:minHeight="48dp"
android:paddingEnd="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingStart="16dp"
android:visibility="gone">
<ImageView
android:id="@+id/save_as_new_segment_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
tools:src="@drawable/ic_action_polygom_dark"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/save_as_new_segment_icon"
android:layout_toRightOf="@id/save_as_new_segment_icon"
android:maxLines="1"
android:text="@string/shared_string_save"
android:textAppearance="@style/TextAppearance.ListItemTitle"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/save_as_new_track_row"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="?attr/selectableItemBackground"
android:minHeight="48dp"
android:paddingEnd="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingStart="16dp">
<ImageView
android:id="@+id/save_as_new_track_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
tools:src="@drawable/ic_action_polygom_dark"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/save_as_new_track_icon"
android:layout_toRightOf="@id/save_as_new_track_icon"
android:maxLines="1"
android:text="@string/shared_string_save_as_gpx"
android:textAppearance="@style/TextAppearance.ListItemTitle"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/add_to_the_track_row"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="?attr/selectableItemBackground"
android:minHeight="48dp"
android:paddingEnd="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingStart="16dp">
<ImageView
android:id="@+id/add_to_the_track_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
tools:src="@drawable/ic_action_split_interval"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/add_to_the_track_icon"
android:layout_toRightOf="@id/add_to_the_track_icon"
android:maxLines="1"
android:text="@string/add_segment_to_the_track"
android:textAppearance="@style/TextAppearance.ListItemTitle"/>
</RelativeLayout>
<View
android:layout_width="wrap_content"
android:layout_height="1dp"
android:layout_marginBottom="8dp"
android:layout_marginLeft="64dp"
android:layout_marginStart="64dp"
android:layout_marginTop="7dp"
android:background="?attr/dashboard_divider"/>
<RelativeLayout
android:id="@+id/clear_all_row"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="?attr/selectableItemBackground"
android:minHeight="48dp"
android:paddingEnd="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingStart="16dp">
<ImageView
android:id="@+id/clear_all_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
tools:src="@drawable/ic_action_reset_to_default_dark"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/clear_all_icon"
android:layout_toRightOf="@id/clear_all_icon"
android:maxLines="1"
android:text="@string/shared_string_clear_all"
android:textAppearance="@style/TextAppearance.ListItemTitle"/>
</RelativeLayout>
</LinearLayout>
</ScrollView>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dashboard_divider"/>
<FrameLayout
android:id="@+id/cancel_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measure_distance_bottom_sheet_cancel_button_height"
android:background="?attr/selectableItemBackground">
<TextView
android:id="@+id/cancel_row_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/shared_string_close"
android:textAllCaps="true"
android:textColor="?attr/color_dialog_buttons"
android:textSize="14sp"
android:textStyle="bold"/>
</FrameLayout>
</LinearLayout>

View file

@ -0,0 +1,206 @@
<?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:background="?attr/bg_color"
android:orientation="vertical">
<ScrollView
android:id="@+id/save_as_new_track_scroll_view"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="8dp">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/save_as_new_track_title"
android:layout_width="match_parent"
android:layout_height="52dp"
android:gravity="center_vertical"
android:paddingEnd="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingStart="16dp"
android:text="@string/shared_string_save_as_gpx"
android:textAppearance="@style/TextAppearance.ListItemTitle"
osmand:typeface="@string/font_roboto_medium"/>
<TextView
android:layout_width="match_parent"
android:layout_height="44dp"
android:paddingEnd="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingStart="16dp"
android:text="@string/measurement_tool_save_as_new_track_descr"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"/>
<LinearLayout
android:id="@+id/images_row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="8dp"
android:layout_marginStart="16dp"
android:layout_weight="1">
<ImageView
android:id="@+id/route_point_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:adjustViewBounds="true"
android:foreground="?attr/selectableItemBackground"
tools:src="@drawable/img_help_trip_route_points_night"/>
<TextView
android:id="@+id/route_point_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/route_point_image"
android:layout_alignStart="@id/route_point_image"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:layout_marginTop="8dp"
android:text="@string/route_point"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_split_segments_sub"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="16dp"
android:layout_marginStart="8dp"
android:layout_weight="1">
<ImageView
android:id="@+id/line_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:adjustViewBounds="true"
android:foreground="?attr/selectableItemBackground"
tools:src="@drawable/img_help_trip_track_night"/>
<TextView
android:id="@+id/line_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/line_image"
android:layout_alignStart="@id/line_image"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:layout_marginTop="8dp"
android:text="@string/line"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_split_segments_sub"/>
</RelativeLayout>
</LinearLayout>
<RelativeLayout
android:id="@+id/save_as_route_point_row"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="?attr/selectableItemBackground"
android:minHeight="48dp"
android:paddingEnd="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingStart="16dp">
<ImageView
android:id="@+id/route_point_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
tools:src="@drawable/ic_action_route_points"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/route_point_icon"
android:layout_toRightOf="@id/route_point_icon"
android:maxLines="1"
android:text="@string/save_as_route_point"
android:textAppearance="@style/TextAppearance.ListItemTitle"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/save_as_line_row"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="?attr/selectableItemBackground"
android:minHeight="48dp"
android:paddingEnd="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingStart="16dp">
<ImageView
android:id="@+id/line_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
tools:src="@drawable/ic_action_split_interval"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/line_icon"
android:layout_toRightOf="@id/line_icon"
android:maxLines="1"
android:text="@string/save_as_line"
android:textAppearance="@style/TextAppearance.ListItemTitle"/>
</RelativeLayout>
</LinearLayout>
</ScrollView>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dashboard_divider"/>
<FrameLayout
android:id="@+id/cancel_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measure_distance_bottom_sheet_cancel_button_height"
android:background="?attr/selectableItemBackground">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/shared_string_cancel"
android:textAllCaps="true"
android:textColor="?attr/color_dialog_buttons"
android:textSize="14sp"
android:textStyle="bold"/>
</FrameLayout>
</LinearLayout>

View file

@ -0,0 +1,234 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/bg_color"
android:orientation="vertical">
<ScrollView
android:id="@+id/selected_point_options_scroll_view"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="8dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="56dp"
android:minHeight="56dp"
android:paddingEnd="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingStart="16dp">
<ImageView
android:id="@+id/selected_point_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
tools:src="@drawable/ic_action_measure_point"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_toEndOf="@id/selected_point_icon"
android:layout_toRightOf="@id/selected_point_icon"
android:gravity="center_vertical"
android:orientation="vertical">
<TextView
android:id="@+id/selected_point_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.ListItemTitle"
tools:text="Point 2"/>
<TextView
android:id="@+id/selected_point_distance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.ListItemTitle"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_list_text_size"
tools:text="386 m"/>
</LinearLayout>
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginBottom="8dp"
android:background="?attr/dashboard_divider"/>
<RelativeLayout
android:id="@+id/move_point_row"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="?attr/selectableItemBackground"
android:minHeight="48dp"
android:paddingEnd="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingStart="16dp">
<ImageView
android:id="@+id/move_point_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
tools:src="@drawable/ic_action_move_point"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/move_point_icon"
android:layout_toRightOf="@id/move_point_icon"
android:maxLines="1"
android:text="@string/shared_string_move"
android:textAppearance="@style/TextAppearance.ListItemTitle"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/delete_point_row"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="?attr/selectableItemBackground"
android:minHeight="48dp"
android:paddingEnd="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingStart="16dp">
<ImageView
android:id="@+id/delete_point_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
tools:src="@drawable/ic_action_remove_dark"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/delete_point_icon"
android:layout_toRightOf="@id/delete_point_icon"
android:maxLines="1"
android:text="@string/shared_string_delete"
android:textAppearance="@style/TextAppearance.ListItemTitle"/>
</RelativeLayout>
<View
android:layout_width="wrap_content"
android:layout_height="1dp"
android:layout_marginBottom="8dp"
android:layout_marginLeft="64dp"
android:layout_marginStart="64dp"
android:layout_marginTop="7dp"
android:background="?attr/dashboard_divider"/>
<RelativeLayout
android:id="@+id/add_point_after_row"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="?attr/selectableItemBackground"
android:minHeight="48dp"
android:paddingEnd="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingStart="16dp">
<ImageView
android:id="@+id/add_point_after_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
tools:src="@drawable/ic_action_addpoint_above"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/add_point_after_icon"
android:layout_toRightOf="@id/add_point_after_icon"
android:maxLines="1"
android:text="@string/add_point_after"
android:textAppearance="@style/TextAppearance.ListItemTitle"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/add_point_before_row"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="?attr/selectableItemBackground"
android:minHeight="48dp"
android:paddingEnd="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingStart="16dp">
<ImageView
android:id="@+id/add_point_before_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
tools:src="@drawable/ic_action_addpoint_below"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/add_point_before_icon"
android:layout_toRightOf="@id/add_point_before_icon"
android:maxLines="1"
android:text="@string/add_point_before"
android:textAppearance="@style/TextAppearance.ListItemTitle"/>
</RelativeLayout>
</LinearLayout>
</ScrollView>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dashboard_divider"/>
<FrameLayout
android:id="@+id/cancel_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measure_distance_bottom_sheet_cancel_button_height"
android:background="?attr/selectableItemBackground">
<TextView
android:id="@+id/cancel_row_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/shared_string_close"
android:textAllCaps="true"
android:textColor="?attr/color_dialog_buttons"
android:textSize="14sp"
android:textStyle="bold"/>
</FrameLayout>
</LinearLayout>

View file

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_bottom_menu_dark">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/bg_color"
android:orientation="vertical">
<LinearLayout
android:id="@+id/navigation_types_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="8dp">
<TextView
android:id="@+id/choose_navigation_title"
android:layout_width="match_parent"
android:layout_height="52dp"
android:gravity="center_vertical"
android:paddingEnd="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingStart="16dp"
android:text="@string/choose_navigation_type"
android:textAppearance="@style/TextAppearance.ListItemTitle"/>
<TextView
android:layout_width="match_parent"
android:layout_height="44dp"
android:paddingEnd="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingStart="16dp"
android:text="@string/measurement_tool_snap_to_road_descr"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dashboard_divider"/>
<FrameLayout
android:id="@+id/cancel_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measure_distance_bottom_sheet_cancel_button_height"
android:background="?attr/selectableItemBackground">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/shared_string_cancel"
android:textAllCaps="true"
android:textColor="?attr/color_dialog_buttons"
android:textSize="14sp"
android:textStyle="bold"/>
</FrameLayout>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>

View file

@ -264,6 +264,17 @@
android:orientation="horizontal" android:orientation="horizontal"
android:gravity="center"> android:gravity="center">
<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"/>
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:id="@+id/split_interval" android:id="@+id/split_interval"

View file

@ -282,6 +282,17 @@
android:orientation="horizontal" android:orientation="horizontal"
android:gravity="center"> android:gravity="center">
<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"/>
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:id="@+id/split_interval" android:id="@+id/split_interval"

View file

@ -264,6 +264,17 @@
android:orientation="horizontal" android:orientation="horizontal"
android:gravity="center"> android:gravity="center">
<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"/>
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:id="@+id/split_interval" android:id="@+id/split_interval"

View file

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="?attr/selectableItemBackground"
android:minHeight="48dp"
android:paddingEnd="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingStart="16dp">
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
tools:src="@drawable/ic_action_car_dark"/>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/icon"
android:layout_toRightOf="@id/icon"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.ListItemTitle"
tools:text="@string/rendering_value_car_name"/>
</RelativeLayout>

View file

@ -126,6 +126,15 @@
android:contentDescription="@string/layer_route" android:contentDescription="@string/layer_route"
tools:src="@drawable/ic_action_test_light"/> tools:src="@drawable/ic_action_test_light"/>
<ImageButton
android:id="@+id/snap_to_road_image_button"
android:layout_width="@dimen/map_button_size"
android:layout_height="@dimen/map_button_size"
android:layout_gravity="bottom"
android:background="@drawable/btn_circle"
android:visibility="gone"
tools:src="@drawable/ic_action_test_light"/>
<FrameLayout <FrameLayout
android:id="@+id/map_ruler_layout" android:id="@+id/map_ruler_layout"
android:layout_width="@dimen/map_ruler_width" android:layout_width="@dimen/map_ruler_width"

View file

@ -3,6 +3,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:osmand="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"> android:orientation="vertical">
<!-- TOP ROW --> <!-- TOP ROW -->
@ -234,6 +235,35 @@
android:contentDescription="@string/shared_string_close" android:contentDescription="@string/shared_string_close"
android:src="@drawable/ic_action_remove_dark"/> android:src="@drawable/ic_action_remove_dark"/>
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/widget_top_bar_save"
android:layout_width="wrap_content"
android:layout_height="56dp"
android:background="@null"
android:ellipsize="end"
android:gravity="center_vertical"
android:lines="1"
android:paddingRight="16dp"
android:paddingEnd="16dp"
android:textAllCaps="true"
android:singleLine="true"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_desc_text_size"
android:contentDescription="@string/shared_string_save"
android:text="@string/shared_string_save"
tools:visibility="visible"
android:visibility="gone"
osmand:typeface="@string/font_roboto_medium"/>
<android.support.v7.widget.SwitchCompat
android:id="@+id/widget_top_bar_switch"
android:layout_width="wrap_content"
android:layout_height="56dp"
android:paddingEnd="16dp"
android:paddingRight="16dp"
android:visibility="gone"
tools:visibility="visible"/>
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout

View file

@ -0,0 +1,126 @@
<?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="match_parent"
android:layout_height="48dp"
android:descendantFocusability="blocksDescendants">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground">
<android.support.v7.widget.AppCompatImageView
android:id="@+id/measure_point_reorder_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:paddingBottom="12dp"
android:paddingEnd="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingStart="16dp"
android:paddingTop="12dp"
android:tint="?attr/secondary_icon_color"
tools:src="@drawable/ic_action_reorder"/>
<android.support.v7.widget.AppCompatImageView
android:id="@+id/measure_point_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_toEndOf="@id/measure_point_reorder_icon"
android:layout_toRightOf="@id/measure_point_reorder_icon"
tools:src="@drawable/ic_action_measure_point"/>
<ImageButton
android:id="@+id/measure_point_remove_image_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="?attr/selectableItemBackground"
android:focusableInTouchMode="true"
android:paddingBottom="12dp"
android:paddingEnd="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingStart="16dp"
android:paddingTop="12dp"
tools:src="@drawable/ic_action_remove_dark"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@+id/measure_point_icon"
android:layout_toLeftOf="@id/measure_point_remove_image_button"
android:layout_toRightOf="@+id/measure_point_icon"
android:layout_toStartOf="@id/measure_point_remove_image_button"
android:orientation="vertical">
<android.support.v7.widget.AppCompatTextView
android:id="@+id/measure_point_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_desc_text_size"
tools:text="@string/plugin_distance_point"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.AppCompatTextView
android:maxLines="1"
android:id="@+id/measure_point_descr"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_sub_text_size"
tools:text="@string/shared_string_control_start"/>
<android.support.v7.widget.AppCompatTextView
android:maxLines="1"
android:id="@+id/measure_point_ele"
android:layout_toEndOf="@id/measure_point_descr"
android:layout_toRightOf="@id/measure_point_descr"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_sub_text_size"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
tools:text="Altitude: 345 m"/>
<android.support.v7.widget.AppCompatTextView
android:maxLines="1"
android:id="@+id/measure_point_speed"
android:layout_toEndOf="@id/measure_point_ele"
android:layout_toRightOf="@id/measure_point_ele"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_sub_text_size"
tools:text="Speed: 45 km/h"/>
</RelativeLayout>
</LinearLayout>
<View
android:id="@+id/points_divider"
android:layout_width="wrap_content"
android:layout_height="1dp"
android:layout_alignParentBottom="true"
android:layout_toEndOf="@+id/measure_point_reorder_icon"
android:layout_toRightOf="@+id/measure_point_reorder_icon"
android:background="?attr/dashboard_divider"/>
</RelativeLayout>
</FrameLayout>

View file

@ -1,72 +1,66 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:osmand="http://schemas.android.com/apk/res-auto"
android:id="@+id/MainLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
<ExpandableListView xmlns:osmand="http://schemas.android.com/apk/res-auto">
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
android:layout_marginTop="0dp"
android:divider="@null"
android:dividerHeight="0dp"
android:drawSelectorOnTop="false"
android:groupIndicator="@android:color/transparent"/>
<android.support.design.widget.FloatingActionButton <android.support.design.widget.FloatingActionButton
android:id="@+id/menu_fab" android:id="@+id/menu_fab"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_margin="16dp"
android:contentDescription="@string/quick_action_new_action" android:contentDescription="@string/quick_action_new_action"
android:src="@drawable/ic_action_plus" android:src="@drawable/ic_action_plus"
app:backgroundTint="@color/dashboard_blue" app:backgroundTint="@color/dashboard_blue"
app:fabSize="normal"/> app:fabSize="normal"
app:useCompatPadding="true"/>
<android.support.design.widget.FloatingActionButton <android.support.design.widget.FloatingActionButton
android:id="@+id/waypoint_fab" android:id="@+id/waypoint_fab"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_above="@id/menu_fab" android:layout_above="@id/menu_fab"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_marginRight="24dp" android:layout_marginBottom="-16dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:contentDescription="@string/quick_action_new_action" android:contentDescription="@string/quick_action_new_action"
android:src="@drawable/ic_action_marker_dark" android:src="@drawable/ic_action_marker_dark"
android:visibility="gone" android:visibility="gone"
app:backgroundTint="@color/dashboard_blue" app:backgroundTint="@color/fab_green"
app:fabSize="mini" app:fabSize="mini"
app:useCompatPadding="true"
tools:visibility="visible"/> tools:visibility="visible"/>
<FrameLayout <FrameLayout
android:id="@+id/waypoint_text_layout" android:id="@+id/waypoint_text_layout"
android:layout_toLeftOf="@id/waypoint_fab"
android:layout_toStartOf="@id/waypoint_fab"
android:layout_above="@id/menu_fab"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="40dp" android:layout_height="40dp"
android:layout_marginRight="16dp" android:layout_alignBottom="@id/waypoint_fab"
android:layout_marginEnd="16dp" android:layout_marginBottom="16dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_toLeftOf="@id/waypoint_fab"
android:layout_toStartOf="@id/waypoint_fab"
android:visibility="gone" android:visibility="gone"
tools:visibility="visible"> tools:visibility="visible">
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
android:textColor="?android:attr/textColorPrimary"
osmand:typeface="@string/font_roboto_medium"
android:layout_gravity="center_vertical"
android:id="@+id/waypoint_text" android:id="@+id/waypoint_text"
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:background="?attr/bg_card"
android:gravity="center_vertical" android:gravity="center_vertical"
android:text="@string/add_waypoint"/> android:padding="8dp"
android:text="@string/add_waypoint"
android:textColor="?android:attr/textColorPrimary"
osmand:typeface="@string/font_roboto_medium"/>
</FrameLayout> </FrameLayout>
@ -75,38 +69,89 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_above="@id/waypoint_fab" android:layout_above="@id/waypoint_fab"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_marginBottom="16dp" android:layout_marginBottom="-16dp"
android:layout_marginRight="24dp" android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:contentDescription="@string/quick_action_new_action" android:contentDescription="@string/quick_action_new_action"
android:src="@drawable/ic_action_markers_dark" android:src="@drawable/ic_action_markers_dark"
android:visibility="gone" android:visibility="gone"
app:backgroundTint="@color/dashboard_blue" app:backgroundTint="@color/fab_green"
app:fabSize="mini" app:fabSize="mini"
app:useCompatPadding="true"
tools:visibility="visible"/> tools:visibility="visible"/>
<FrameLayout <FrameLayout
android:id="@+id/route_text_layout" android:id="@+id/route_text_layout"
android:layout_toLeftOf="@id/route_fab"
android:layout_toStartOf="@id/route_fab"
android:layout_above="@id/waypoint_fab"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="40dp" android:layout_height="40dp"
android:layout_alignBottom="@id/route_fab"
android:layout_marginBottom="16dp" android:layout_marginBottom="16dp"
android:layout_marginRight="16dp" android:layout_marginEnd="8dp"
android:layout_marginEnd="16dp" android:layout_marginRight="8dp"
android:layout_toLeftOf="@id/route_fab"
android:layout_toStartOf="@id/route_fab"
android:visibility="gone" android:visibility="gone"
tools:visibility="visible"> tools:visibility="visible">
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
android:textColor="?android:attr/textColorPrimary"
osmand:typeface="@string/font_roboto_medium"
android:layout_gravity="center_vertical"
android:id="@+id/route_text" android:id="@+id/route_text"
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:background="?attr/bg_card"
android:gravity="center_vertical" android:gravity="center_vertical"
android:text="@string/add_route_point"/> android:padding="8dp"
android:text="@string/add_route_points"
android:textColor="?android:attr/textColorPrimary"
osmand:typeface="@string/font_roboto_medium"/>
</FrameLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/line_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/route_fab"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="-16dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:contentDescription="@string/quick_action_new_action"
android:src="@drawable/ic_action_polygom_dark"
android:visibility="gone"
app:backgroundTint="@color/fab_green"
app:fabSize="mini"
app:useCompatPadding="true"
tools:visibility="visible"/>
<FrameLayout
android:id="@+id/line_text_layout"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_above="@id/route_fab"
android:layout_alignBottom="@id/line_fab"
android:layout_marginBottom="16dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_toLeftOf="@id/line_fab"
android:layout_toStartOf="@id/line_fab"
android:visibility="gone"
tools:visibility="visible">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/line_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="?attr/bg_card"
android:gravity="center_vertical"
android:padding="8dp"
android:text="@string/add_line"
android:textColor="?android:attr/textColorPrimary"
osmand:typeface="@string/font_roboto_medium"/>
</FrameLayout> </FrameLayout>

View file

@ -10,6 +10,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:inputType="text"/> android:inputType="text"/>
@ -19,6 +21,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:text="@string/file_with_name_already_exists" android:text="@string/file_with_name_already_exists"

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/MainLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ExpandableListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
android:layout_marginTop="0dp"
android:divider="@null"
android:dividerHeight="0dp"
android:drawSelectorOnTop="false"
android:groupIndicator="@android:color/transparent"/>
<View
android:id="@+id/overlay_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white_80_transparent"
android:visibility="gone"/>
<include layout="@layout/my_places_fabs"/>
</RelativeLayout>

View file

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
android:layout_marginTop="0dp"/>
<View
android:id="@+id/overlay_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white_80_transparent"
android:visibility="gone"/>
<include layout="@layout/my_places_fabs"/>
</RelativeLayout>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_save_as_gpx"
android:icon="@drawable/ic_action_polygom_dark"
android:title="@string/shared_string_save_as_gpx"/>
<item
android:id="@+id/action_clear_all"
android:icon="@drawable/ic_action_reset_to_default_dark"
android:title="@string/shared_string_clear_all"/>
</menu>

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_edit"
android:icon="@drawable/ic_action_edit_dark"
android:title="@string/shared_string_edit"/>
<item
android:id="@+id/action_delete"
android:icon="@drawable/ic_action_remove_dark"
android:title="@string/shared_string_delete"/>
</menu>

View file

@ -4,4 +4,7 @@
<dimen name="splash_screen_logo_top">24dp</dimen> <dimen name="splash_screen_logo_top">24dp</dimen>
<dimen name="splash_screen_text_bottom">48dp</dimen> <dimen name="splash_screen_text_bottom">48dp</dimen>
<dimen name="my_places_empty_state_image_margin_top">39dp</dimen>
<dimen name="my_places_empty_state_image_margin_bottom">39dp</dimen>
</resources> </resources>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="my_places_empty_state_image_margin_top">59dp</dimen>
<dimen name="my_places_empty_state_image_margin_bottom">59dp</dimen>
</resources>

View file

@ -78,5 +78,17 @@
<dimen name="default_split_segments_overview">15sp</dimen> <dimen name="default_split_segments_overview">15sp</dimen>
<dimen name="default_split_segments_data">15sp</dimen> <dimen name="default_split_segments_data">15sp</dimen>
<dimen name="default_split_segments_sub">12sp</dimen> <dimen name="default_split_segments_sub">12sp</dimen>
<dimen name="my_places_empty_state_image_margin_top">63dp</dimen>
<dimen name="my_places_empty_state_image_margin_bottom">45dp</dimen>
<dimen name="my_places_empty_state_text_interval">12dp</dimen>
<dimen name="my_places_empty_state_button_margin_top">30dp</dimen>
<dimen name="my_places_empty_state_text_size">20sp</dimen>
<dimen name="my_places_empty_state_text_desc_size">18sp</dimen>
<dimen name="my_places_empty_state_text_desc_margin">68dp</dimen>
<dimen name="my_places_empty_state_image_margin_left">138dp</dimen>
<dimen name="my_places_empty_state_text_button_padding_left">72dp</dimen>
<dimen name="my_places_empty_state_text_button_padding_right">90dp</dimen>
<dimen name="my_places_empty_state_text_button_padding_top">96dp</dimen>
</resources> </resources>

View file

@ -2,4 +2,6 @@
<resources> <resources>
<dimen name="splash_screen_logo_top">300dp</dimen> <dimen name="splash_screen_logo_top">300dp</dimen>
<dimen name="splash_screen_text_bottom">200dp</dimen> <dimen name="splash_screen_text_bottom">200dp</dimen>
<dimen name="measurement_tool_select_radius">48dp</dimen>
</resources> </resources>

View file

@ -16,6 +16,7 @@
<attr name="expandable_list_item_background" format="color"/> <attr name="expandable_list_item_background" format="color"/>
<attr name="expandable_list_background" format="color"/> <attr name="expandable_list_background" format="color"/>
<attr name="bg_color" format="reference" /> <attr name="bg_color" format="reference" />
<attr name="btn_round_border" format="reference" />
<attr name="bg_card" format="reference" /> <attr name="bg_card" format="reference" />
<attr name="context_menu_card" format="reference" /> <attr name="context_menu_card" format="reference" />
<attr name="ctx_menu_card_btn" format="reference" /> <attr name="ctx_menu_card_btn" format="reference" />

View file

@ -257,4 +257,6 @@
<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>
<color name="fab_green">#46bd2a</color>
</resources> </resources>

View file

@ -143,4 +143,21 @@
<dimen name="splash_screen_logo_top">150dp</dimen> <dimen name="splash_screen_logo_top">150dp</dimen>
<dimen name="splash_screen_text_bottom">128dp</dimen> <dimen name="splash_screen_text_bottom">128dp</dimen>
<dimen name="my_places_empty_state_image_margin_top">42dp</dimen>
<dimen name="my_places_empty_state_image_margin_bottom">30dp</dimen>
<dimen name="my_places_empty_state_text_interval">8dp</dimen>
<dimen name="my_places_empty_state_button_margin_top">20dp</dimen>
<dimen name="my_places_empty_state_text_size">18sp</dimen>
<dimen name="my_places_empty_state_text_desc_size">16sp</dimen>
<dimen name="my_places_empty_state_text_desc_margin">45dp</dimen>
<dimen name="my_places_empty_state_image_margin_left">92dp</dimen>
<dimen name="my_places_empty_state_text_button_padding_left">48dp</dimen>
<dimen name="my_places_empty_state_text_button_padding_right">60dp</dimen>
<dimen name="my_places_empty_state_text_button_padding_top">64dp</dimen>
<dimen name="measure_distance_bottom_sheet_cancel_button_height">48dp</dimen>
<dimen name="landscape_bottom_sheet_dialog_fragment_width">360dp</dimen>
<dimen name="measurement_tool_select_radius">20dp</dimen>
</resources> </resources>

View file

@ -9,6 +9,19 @@
3. All your modified/created strings are in the top of the file (to make easier find what\'s translated). 3. All your modified/created strings are in the top of the file (to make easier find what\'s translated).
PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy
--> -->
<string name="measurement_tool_altitude">Altitude: %1$s</string>
<string name="measurement_tool_speed">Speed: %1$s</string>
<string name="line">Line</string>
<string name="save_as_route_point">Save as Route Point</string>
<string name="save_as_line">Save as line</string>
<string name="route_point">Route point</string>
<string name="edit_line">Edit Line</string>
<string name="add_point_before">Add point before</string>
<string name="add_point_after">Add point after</string>
<string name="shared_string_options">Options</string>
<string name="measurement_tool_snap_to_road_descr">OsmAnd will add additional points, depending on the navigation type.</string>
<string name="measurement_tool_save_as_new_track_descr">You can save points either as route points or as a line.</string>
<string name="choose_navigation_type">Choose navigation type</string>
<string name="none_point_error">Please add at least one point.</string> <string name="none_point_error">Please add at least one point.</string>
<string name="enter_gpx_name">GPX file name:</string> <string name="enter_gpx_name">GPX file name:</string>
<string name="show_on_map_after_saving">Show on map after saving</string> <string name="show_on_map_after_saving">Show on map after saving</string>
@ -790,7 +803,7 @@
<string name="shared_string_clear">Clear</string> <string name="shared_string_clear">Clear</string>
<string name="shared_string_clear_all">Clear all</string> <string name="shared_string_clear_all">Clear all</string>
<string name="shared_string_save">Save</string> <string name="shared_string_save">Save</string>
<string name="shared_string_save_as_gpx">Save as GPX track</string> <string name="shared_string_save_as_gpx">Save as new Track</string>
<string name="shared_string_rename">Rename</string> <string name="shared_string_rename">Rename</string>
<string name="shared_string_delete">Delete</string> <string name="shared_string_delete">Delete</string>
<string name="shared_string_delete_all">Delete all</string> <string name="shared_string_delete_all">Delete all</string>
@ -2663,10 +2676,19 @@
<string name="shared_string_action_name">Action name</string> <string name="shared_string_action_name">Action name</string>
<string name="mappilary_no_internet_desc">You need internet to view photos from Mapillary</string> <string name="mappilary_no_internet_desc">You need internet to view photos from Mapillary</string>
<string name="retry">Retry</string> <string name="retry">Retry</string>
<string name="add_route_point">Add Route Point</string> <string name="add_route_points">Add Route Points</string>
<string name="add_waypoint">Add Waypoint</string> <string name="add_waypoint">Add Waypoint</string>
<string name="add_line">Add Line</string>
<string name="save_gpx_waypoint">Save GPX Waypoint</string> <string name="save_gpx_waypoint">Save GPX Waypoint</string>
<string name="save_route_point">Save Route Point</string> <string name="save_route_point">Save Route Point</string>
<string name="waypoint_one">Waypoint 1</string> <string name="waypoint_one">Waypoint 1</string>
<string name="route_point_one">Route Point 1</string> <string name="route_point_one">Route Point 1</string>
<string name="empty_state_my_tracks">Add and Record Tracks</string>
<string name="empty_state_my_tracks_desc">Record or import tracks to view</string>
<string name="empty_state_favourites">Add Favorites</string>
<string name="empty_state_favourites_desc">Add favorites on map or import them from filesystem</string>
<string name="import_track">Import track</string>
<string name="import_track_desc">File %1$s does not contain waypoints, import it as a track?</string>
<string name="move_point">Move Point</string>
<string name="add_segment_to_the_track">Add to a track</string>
</resources> </resources>

View file

@ -109,6 +109,7 @@
<item name="actionModeBackground">@color/actionbar_light_color</item> <item name="actionModeBackground">@color/actionbar_light_color</item>
<item name="actionBarStyle">@style/Widget.Styled.ActionBarLight</item> <item name="actionBarStyle">@style/Widget.Styled.ActionBarLight</item>
<item name="bg_color">@color/bg_color_light</item> <item name="bg_color">@color/bg_color_light</item>
<item name="btn_round_border">@drawable/btn_round_border_light</item>
<item name="bg_card">@drawable/bg_card_light</item> <item name="bg_card">@drawable/bg_card_light</item>
<item name="context_menu_card">@drawable/context_menu_card_light</item> <item name="context_menu_card">@drawable/context_menu_card_light</item>
<item name="bg_map_context_menu">@drawable/bg_map_context_menu_light</item> <item name="bg_map_context_menu">@drawable/bg_map_context_menu_light</item>
@ -282,6 +283,7 @@
<item name="actionModeBackground">@color/actionbar_dark_color</item> <item name="actionModeBackground">@color/actionbar_dark_color</item>
<item name="actionBarStyle">@style/Widget.Styled.ActionBarDark</item> <item name="actionBarStyle">@style/Widget.Styled.ActionBarDark</item>
<item name="bg_color">@color/bg_color_dark</item> <item name="bg_color">@color/bg_color_dark</item>
<item name="btn_round_border">@drawable/btn_round_border_dark</item>
<item name="bg_card">@drawable/bg_card_dark</item> <item name="bg_card">@drawable/bg_card_dark</item>
<item name="context_menu_card">@drawable/context_menu_card_dark</item> <item name="context_menu_card">@drawable/context_menu_card_dark</item>
<item name="bg_map_context_menu">@drawable/bg_map_context_menu_dark</item> <item name="bg_map_context_menu">@drawable/bg_map_context_menu_dark</item>

View file

@ -172,6 +172,27 @@ public class AndroidUtils {
return result; return result;
} }
public static int getNavBarHeight(Context ctx) {
if (!hasNavBar(ctx)) {
return 0;
}
boolean landscape = ctx.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
boolean isSmartphone = ctx.getResources().getConfiguration().smallestScreenWidthDp < 600;
if (isSmartphone && landscape) {
return 0;
}
int id = ctx.getResources().getIdentifier(landscape ? "navigation_bar_height_landscape" : "navigation_bar_height", "dimen", "android");
if (id > 0) {
return ctx.getResources().getDimensionPixelSize(id);
}
return 0;
}
public static boolean hasNavBar(Context ctx) {
int id = ctx.getResources().getIdentifier("config_showNavigationBar", "bool", "android");
return id > 0 && ctx.getResources().getBoolean(id);
}
public static int getScreenHeight(Activity activity) { public static int getScreenHeight(Activity activity) {
DisplayMetrics dm = new DisplayMetrics(); DisplayMetrics dm = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(dm); activity.getWindowManager().getDefaultDisplay().getMetrics(dm);

View file

@ -6,6 +6,7 @@ import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Paint; import android.graphics.Paint;
import android.support.annotation.ColorInt; import android.support.annotation.ColorInt;
import android.text.TextUtils;
import net.osmand.Location; import net.osmand.Location;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
@ -247,6 +248,7 @@ public class GPXUtilities {
public String name = null; public String name = null;
public String desc = null; public String desc = null;
public List<TrkSegment> segments = new ArrayList<>(); public List<TrkSegment> segments = new ArrayList<>();
public boolean generalTrack = false;
} }
@ -772,6 +774,7 @@ public class GPXUtilities {
track.segments = new ArrayList<>(); track.segments = new ArrayList<>();
track.segments.add(generalSegment); track.segments.add(generalSegment);
generalTrack = track; generalTrack = track;
track.generalTrack = true;
} }
return generalTrack; return generalTrack;
} }
@ -823,6 +826,14 @@ public class GPXUtilities {
return g; return g;
} }
public List<WptPt> getRoutePoints() {
List<WptPt> points = new ArrayList<>();
for (int i = 0; i < routes.size(); i++) {
Route rt = routes.get(i);
points.addAll(rt.points);
}
return points;
}
public boolean hasRtePt() { public boolean hasRtePt() {
for (Route r : routes) { for (Route r : routes) {
@ -880,7 +891,7 @@ public class GPXUtilities {
if (routes.size() == 0) { if (routes.size() == 0) {
routes.add(new Route()); routes.add(new Route());
} }
Route currentRoute = routes.get(routes.size() -1); Route currentRoute = routes.get(routes.size() - 1);
currentRoute.points.add(pt); currentRoute.points.add(pt);
modifiedTime = System.currentTimeMillis(); modifiedTime = System.currentTimeMillis();
@ -888,6 +899,64 @@ public class GPXUtilities {
return pt; return pt;
} }
public void addTrkSegment(List<WptPt> points) {
removeGeneralTrackIfExists();
TrkSegment segment = new TrkSegment();
segment.points.addAll(points);
if (tracks.size() == 0) {
tracks.add(new Track());
}
Track lastTrack = tracks.get(tracks.size() - 1);
lastTrack.segments.add(segment);
modifiedTime = System.currentTimeMillis();
}
public boolean replaceSegment(TrkSegment oldSegment, TrkSegment newSegment) {
removeGeneralTrackIfExists();
for (int i = 0; i < tracks.size(); i++) {
Track currentTrack = tracks.get(i);
for (int j = 0; j < currentTrack.segments.size(); j++) {
int segmentIndex = currentTrack.segments.indexOf(oldSegment);
if (segmentIndex != -1) {
currentTrack.segments.remove(segmentIndex);
currentTrack.segments.add(segmentIndex, newSegment);
addGeneralTrack();
modifiedTime = System.currentTimeMillis();
return true;
}
}
}
addGeneralTrack();
return false;
}
public void addRoutePoints(List<WptPt> points) {
if (routes.size() == 0) {
Route route = new Route();
routes.add(route);
}
Route lastRoute = routes.get(routes.size() - 1);
lastRoute.points.addAll(points);
modifiedTime = System.currentTimeMillis();
}
public void replaceRoutePoints(List<WptPt> points) {
routes.clear();
routes.add(new Route());
Route currentRoute = routes.get(routes.size() - 1);
currentRoute.points.addAll(points);
modifiedTime = System.currentTimeMillis();
}
public void updateWptPt(WptPt pt, double lat, double lon, long time, String description, String name, String category, int color) { public void updateWptPt(WptPt pt, double lat, double lon, long time, String description, String name, String category, int color) {
int index = points.indexOf(pt); int index = points.indexOf(pt);
@ -910,6 +979,32 @@ public class GPXUtilities {
modifiedTime = System.currentTimeMillis(); modifiedTime = System.currentTimeMillis();
} }
private void removeGeneralTrackIfExists() {
Track generalTrack = getGeneralTrack();
if (generalTrack != null) {
tracks.remove(generalTrack);
this.generalTrack = null;
this.generalSegment = null;
}
}
public boolean removeTrkSegment(TrkSegment segment) {
removeGeneralTrackIfExists();
for (int i = 0; i < tracks.size(); i++) {
Track currentTrack = tracks.get(i);
for (int j = 0; j < currentTrack.segments.size(); j++) {
if (currentTrack.segments.remove(segment)) {
addGeneralTrack();
modifiedTime = System.currentTimeMillis();
return true;
}
}
}
addGeneralTrack();
return false;
}
public boolean deleteWptPt(WptPt pt) { public boolean deleteWptPt(WptPt pt) {
modifiedTime = System.currentTimeMillis(); modifiedTime = System.currentTimeMillis();
return points.remove(pt); return points.remove(pt);
@ -1014,6 +1109,19 @@ public class GPXUtilities {
} }
return count; return count;
} }
public List<String> getWaypointCategories() {
List<String> categories = new ArrayList<>();
for (WptPt pt : points) {
String category = pt.category;
if (!TextUtils.isEmpty(category)) {
if (!categories.contains(category)) {
categories.add(category);
}
}
}
return categories;
}
} }
public static String asString(GPXFile file, OsmandApplication ctx) { public static String asString(GPXFile file, OsmandApplication ctx) {

View file

@ -1244,7 +1244,9 @@ public class OsmandSettings {
// this value string is synchronized with settings_pref.xml preference name // this value string is synchronized with settings_pref.xml preference name
public static final int CENTER_CONSTANT = 0; public static final int CENTER_CONSTANT = 0;
public static final int BOTTOM_CONSTANT = 1; public static final int BOTTOM_CONSTANT = 1;
public static final int MIDDLE_CONSTANT = 2; public static final int MIDDLE_BOTTOM_CONSTANT = 2;
public static final int MIDDLE_TOP_CONSTANT = 3;
public static final int LANDSCAPE_MIDDLE_RIGHT_CONSTANT = 4;
public final CommonPreference<Boolean> CENTER_POSITION_ON_MAP = new BooleanPreference("center_position_on_map", false).makeProfile(); public final CommonPreference<Boolean> CENTER_POSITION_ON_MAP = new BooleanPreference("center_position_on_map", false).makeProfile();
// this value string is synchronized with settings_pref.xml preference name // this value string is synchronized with settings_pref.xml preference name

View file

@ -21,6 +21,7 @@ import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.ExpandableListView; import android.widget.ExpandableListView;
import android.widget.Filter; import android.widget.Filter;
@ -71,11 +72,13 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment {
public static final int SHARE_ID = 4; public static final int SHARE_ID = 4;
public static final int SELECT_MAP_MARKERS_ID = 5; public static final int SELECT_MAP_MARKERS_ID = 5;
public static final int SELECT_MAP_MARKERS_ACTION_MODE_ID = 6; public static final int SELECT_MAP_MARKERS_ACTION_MODE_ID = 6;
public static final int IMPORT_FAVOURITES_ID = 7;
public static final String GROUP_EXPANDED_POSTFIX = "_group_expanded"; public static final String GROUP_EXPANDED_POSTFIX = "_group_expanded";
private FavouritesAdapter favouritesAdapter = new FavouritesAdapter(); private FavouritesAdapter favouritesAdapter = new FavouritesAdapter();
private FavouritesDbHelper helper; private FavouritesDbHelper helper;
private OsmandApplication app;
private boolean selectionMode = false; private boolean selectionMode = false;
private Set<FavouritePoint> favoritesSelected = new LinkedHashSet<>(); private Set<FavouritePoint> favoritesSelected = new LinkedHashSet<>();
private Set<FavoriteGroup> groupsToDelete = new LinkedHashSet<>(); private Set<FavoriteGroup> groupsToDelete = new LinkedHashSet<>();
@ -88,6 +91,7 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment {
@Override @Override
public void onAttach(Context context) { public void onAttach(Context context) {
super.onAttach(context); super.onAttach(context);
this.app = (OsmandApplication) getActivity().getApplication();
helper = getMyApplication().getFavorites(); helper = getMyApplication().getFavorites();
favouritesAdapter.synchronizeGroups(); favouritesAdapter.synchronizeGroups();
@ -156,6 +160,17 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment {
footerView = inflater.inflate(R.layout.list_shadow_footer, null, false); footerView = inflater.inflate(R.layout.list_shadow_footer, null, false);
listView.addFooterView(footerView); listView.addFooterView(footerView);
} }
View emptyView = view.findViewById(android.R.id.empty);
ImageView emptyImageView = (ImageView) emptyView.findViewById(R.id.empty_state_image_view);
emptyImageView.setImageResource(app.getSettings().isLightContent() ? R.drawable.ic_empty_state_favorites_day_result : R.drawable.ic_empty_state_favorites_night_result);
Button importButton = (Button) emptyView.findViewById(R.id.import_button);
importButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
importFavourites();
}
});
listView.setEmptyView(emptyView);
listView.setAdapter(favouritesAdapter); listView.setAdapter(favouritesAdapter);
setListView(listView); setListView(listView);
setHasOptionsMenu(true); setHasOptionsMenu(true);
@ -237,6 +252,9 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment {
} else if (item.getItemId() == DELETE_ACTION_ID) { } else if (item.getItemId() == DELETE_ACTION_ID) {
deleteFavoritesAction(); deleteFavoritesAction();
return true; return true;
} else if (item.getItemId() == IMPORT_FAVOURITES_ID) {
importFavourites();
return true;
} else { } else {
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
@ -268,6 +286,8 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment {
if (!MenuItemCompat.isActionViewExpanded(mi)) { if (!MenuItemCompat.isActionViewExpanded(mi)) {
createMenuItem(menu, IMPORT_FAVOURITES_ID, R.string.shared_string_add_to_favorites, R.drawable.ic_action_plus,
R.drawable.ic_action_plus, MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
createMenuItem(menu, SHARE_ID, R.string.shared_string_share, R.drawable.ic_action_gshare_dark, createMenuItem(menu, SHARE_ID, R.string.shared_string_share, R.drawable.ic_action_gshare_dark,
R.drawable.ic_action_gshare_dark, MenuItemCompat.SHOW_AS_ACTION_ALWAYS); R.drawable.ic_action_gshare_dark, MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
if (getSettings().USE_MAP_MARKERS.get()) { if (getSettings().USE_MAP_MARKERS.get()) {
@ -467,6 +487,10 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment {
} }
} }
private void importFavourites() {
((FavoritesActivity) getActivity()).importFavourites();
}
public void shareFavorites(final FavoriteGroup group) { public void shareFavorites(final FavoriteGroup group) {
final AsyncTask<Void, Void, Void> exportTask = new AsyncTask<Void, Void, Void>() { final AsyncTask<Void, Void, Void> exportTask = new AsyncTask<Void, Void, Void>() {

View file

@ -96,6 +96,7 @@ import net.osmand.plus.mapcontextmenu.other.MapRouteInfoMenu;
import net.osmand.plus.mapcontextmenu.other.MapRouteInfoMenuFragment; import net.osmand.plus.mapcontextmenu.other.MapRouteInfoMenuFragment;
import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu; import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu;
import net.osmand.plus.measurementtool.MeasurementToolFragment; import net.osmand.plus.measurementtool.MeasurementToolFragment;
import net.osmand.plus.measurementtool.NewGpxData;
import net.osmand.plus.render.RendererRegistry; import net.osmand.plus.render.RendererRegistry;
import net.osmand.plus.resources.ResourceManager; import net.osmand.plus.resources.ResourceManager;
import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.routing.RoutingHelper;
@ -501,13 +502,16 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
} }
} }
if (getMeasurementToolFragment() != null) { if (getMeasurementToolFragment() != null) {
getMeasurementToolFragment().showQuitDialog(); getMeasurementToolFragment().quit(true);
return; return;
} }
if (mapContextMenu.isVisible() && mapContextMenu.isClosable()) { if (mapContextMenu.isVisible() && mapContextMenu.isClosable()) {
mapContextMenu.close(); mapContextMenu.close();
return; return;
} }
if (getMapLayers().getContextMenuLayer().isInAddGpxPointMode()) {
quitAddGpxPointMode();
}
if (prevActivityIntent != null && getSupportFragmentManager().getBackStackEntryCount() == 0) { if (prevActivityIntent != null && getSupportFragmentManager().getBackStackEntryCount() == 0) {
prevActivityIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); prevActivityIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
LatLon loc = getMapLocation(); LatLon loc = getMapLocation();
@ -527,6 +531,11 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
} }
private void quitAddGpxPointMode() {
getMapLayers().getContextMenuLayer().getAddGpxPointBottomSheetHelper().hide();
getMapLayers().getContextMenuLayer().quitAddGpxPoint();
}
@Override @Override
protected void onRestart() { protected void onRestart() {
super.onRestart(); super.onRestart();
@ -928,7 +937,14 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
mapView.fitRectToMap(qr.left, qr.right, qr.top, qr.bottom, (int) qr.width(), (int) qr.height(), 0); mapView.fitRectToMap(qr.left, qr.right, qr.top, qr.bottom, (int) qr.width(), (int) qr.height(), 0);
} else if (toShow instanceof NewGpxPoint) { } else if (toShow instanceof NewGpxPoint) {
NewGpxPoint newGpxPoint = (NewGpxPoint) toShow; NewGpxPoint newGpxPoint = (NewGpxPoint) toShow;
QuadRect qr = newGpxPoint.getRect();
mapView.fitRectToMap(qr.left, qr.right, qr.top, qr.bottom, (int) qr.width(), (int) qr.height(), 0);
getMapLayers().getContextMenuLayer().enterAddGpxPointMode(newGpxPoint); getMapLayers().getContextMenuLayer().enterAddGpxPointMode(newGpxPoint);
} else if (toShow instanceof NewGpxData) {
NewGpxData newGpxData = (NewGpxData) toShow;
QuadRect qr = newGpxData.getRect();
mapView.fitRectToMap(qr.left, qr.right, qr.top, qr.bottom, (int) qr.width(), (int) qr.height(), 0);
MeasurementToolFragment.showInstance(getSupportFragmentManager(), newGpxData);
} else { } else {
mapContextMenu.show(latLonToShow, mapLabelToShow, toShow); mapContextMenu.show(latLonToShow, mapLabelToShow, toShow);
} }

View file

@ -764,12 +764,7 @@ public class MapActivityActions implements DialogProvider {
.setListener(new ContextMenuAdapter.ItemClickListener() { .setListener(new ContextMenuAdapter.ItemClickListener() {
@Override @Override
public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> adapter, int itemId, int position, boolean isChecked) { public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> adapter, int itemId, int position, boolean isChecked) {
MeasurementToolFragment fragment = new MeasurementToolFragment(); MeasurementToolFragment.showInstance(mapActivity.getSupportFragmentManager(), null);
mapActivity.getSupportFragmentManager()
.beginTransaction()
.add(R.id.bottomFragmentContainer, fragment, MeasurementToolFragment.TAG)
.addToBackStack(MeasurementToolFragment.TAG)
.commitAllowingStateLoss();
return true; return true;
} }
}).createItem()); }).createItem());

View file

@ -13,19 +13,27 @@ import android.view.MenuItem;
import android.view.View; import android.view.View;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
import net.osmand.data.QuadRect;
import net.osmand.plus.GPXDatabase.GpxDataItem; import net.osmand.plus.GPXDatabase.GpxDataItem;
import net.osmand.plus.GPXUtilities; import net.osmand.plus.GPXUtilities;
import net.osmand.plus.GPXUtilities.TrkSegment;
import net.osmand.plus.GPXUtilities.GPXFile; import net.osmand.plus.GPXUtilities.GPXFile;
import net.osmand.plus.GPXUtilities.WptPt;
import net.osmand.plus.GpxSelectionHelper; import net.osmand.plus.GpxSelectionHelper;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup; import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup;
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
import net.osmand.plus.OsmAndAppCustomization; import net.osmand.plus.OsmAndAppCustomization;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.measurementtool.NewGpxData;
import net.osmand.plus.myplaces.FavoritesActivity; import net.osmand.plus.myplaces.FavoritesActivity;
import net.osmand.plus.myplaces.SplitSegmentFragment; import net.osmand.plus.myplaces.SplitSegmentFragment;
import net.osmand.plus.myplaces.TrackPointFragment; import net.osmand.plus.myplaces.TrackPointFragment;
import net.osmand.plus.myplaces.TrackSegmentFragment; import net.osmand.plus.myplaces.TrackSegmentFragment;
import net.osmand.plus.views.AddGpxPointBottomSheetHelper.NewGpxPoint;
import net.osmand.plus.views.controls.PagerSlidingTabStrip; import net.osmand.plus.views.controls.PagerSlidingTabStrip;
import java.io.File; import java.io.File;
@ -37,8 +45,10 @@ public class TrackActivity extends TabActivity {
public static final String TRACK_FILE_NAME = "TRACK_FILE_NAME"; public static final String TRACK_FILE_NAME = "TRACK_FILE_NAME";
public static final String OPEN_POINTS_TAB = "OPEN_POINTS_TAB"; public static final String OPEN_POINTS_TAB = "OPEN_POINTS_TAB";
public static final String OPEN_TRACKS_LIST = "OPEN_TRACKS_LIST";
public static final String CURRENT_RECORDING = "CURRENT_RECORDING"; public static final String CURRENT_RECORDING = "CURRENT_RECORDING";
protected List<WeakReference<Fragment>> fragList = new ArrayList<>(); protected List<WeakReference<Fragment>> fragList = new ArrayList<>();
private OsmandApplication app;
protected PagerSlidingTabStrip slidingTabLayout; protected PagerSlidingTabStrip slidingTabLayout;
private File file = null; private File file = null;
private GPXFile gpxFile; private GPXFile gpxFile;
@ -48,7 +58,8 @@ public class TrackActivity extends TabActivity {
private List<GpxDisplayGroup> displayGroups; private List<GpxDisplayGroup> displayGroups;
private List<GpxDisplayGroup> originalGroups = new ArrayList<>(); private List<GpxDisplayGroup> originalGroups = new ArrayList<>();
private boolean stopped = false; private boolean stopped = false;
public boolean openPointsTab = false; private boolean openPointsTab = false;
private boolean openTracksList = false;
public PagerSlidingTabStrip getSlidingTabLayout() { public PagerSlidingTabStrip getSlidingTabLayout() {
return slidingTabLayout; return slidingTabLayout;
@ -56,7 +67,8 @@ public class TrackActivity extends TabActivity {
@Override @Override
public void onCreate(Bundle icicle) { public void onCreate(Bundle icicle) {
((OsmandApplication) getApplication()).applyTheme(this); this.app = getMyApplication();
app.applyTheme(this);
super.onCreate(icicle); super.onCreate(icicle);
Intent intent = getIntent(); Intent intent = getIntent();
if (intent == null || (!intent.hasExtra(TRACK_FILE_NAME) && if (intent == null || (!intent.hasExtra(TRACK_FILE_NAME) &&
@ -80,9 +92,109 @@ public class TrackActivity extends TabActivity {
if (intent.hasExtra(OPEN_POINTS_TAB)) { if (intent.hasExtra(OPEN_POINTS_TAB)) {
openPointsTab = true; openPointsTab = true;
} }
if (intent.hasExtra(OPEN_TRACKS_LIST)) {
openTracksList = true;
}
setContentView(R.layout.tab_content); setContentView(R.layout.tab_content);
} }
public void addPoint(PointDescription pointDescription) {
Intent currentIntent = getIntent();
if (currentIntent != null) {
currentIntent.putExtra(TrackActivity.OPEN_POINTS_TAB, true);
}
final OsmandSettings settings = app.getSettings();
GPXFile gpx = getGpx();
LatLon location = settings.getLastKnownMapLocation();
QuadRect rect = getRect();
NewGpxPoint newGpxPoint = new NewGpxPoint(gpx, pointDescription, rect);
if (gpx != null && location != null) {
settings.setMapLocationToShow(location.getLatitude(), location.getLongitude(),
settings.getLastKnownMapZoom(),
pointDescription,
false,
newGpxPoint);
MapActivity.launchMapActivityMoveToTop(this);
}
}
public void addNewGpxData(NewGpxData.ActionType actionType) {
addNewGpxData(actionType, null);
}
public void addNewGpxData(NewGpxData.ActionType actionType, TrkSegment segment) {
GPXFile gpxFile = getGpx();
QuadRect rect = getRect();
NewGpxData newGpxData = new NewGpxData(gpxFile, rect, actionType, segment);
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, getString(R.string.add_line)),
false,
newGpxData
);
MapActivity.launchMapActivityMoveToTop(this);
}
}
public QuadRect getRect() {
double left = 0, right = 0;
double top = 0, bottom = 0;
if (getGpx() != null) {
for (GPXUtilities.Track track : getGpx().tracks) {
for (GPXUtilities.TrkSegment segment : track.segments) {
for (WptPt p : segment.points) {
if (left == 0 && right == 0) {
left = p.getLongitude();
right = p.getLongitude();
top = p.getLatitude();
bottom = p.getLatitude();
} else {
left = Math.min(left, p.getLongitude());
right = Math.max(right, p.getLongitude());
top = Math.max(top, p.getLatitude());
bottom = Math.min(bottom, p.getLatitude());
}
}
}
}
for (WptPt p : getGpx().points) {
if (left == 0 && right == 0) {
left = p.getLongitude();
right = p.getLongitude();
top = p.getLatitude();
bottom = p.getLatitude();
} else {
left = Math.min(left, p.getLongitude());
right = Math.max(right, p.getLongitude());
top = Math.max(top, p.getLatitude());
bottom = Math.min(bottom, p.getLatitude());
}
}
for (GPXUtilities.Route route : getGpx().routes) {
for (WptPt p : route.points) {
if (left == 0 && right == 0) {
left = p.getLongitude();
right = p.getLongitude();
top = p.getLatitude();
bottom = p.getLatitude();
} else {
left = Math.min(left, p.getLongitude());
right = Math.max(right, p.getLongitude());
top = Math.max(top, p.getLatitude());
bottom = Math.min(bottom, p.getLatitude());
}
}
}
}
return new QuadRect(left, top, right, bottom);
}
protected void setGpxDataItem(GpxDataItem gpxDataItem) { protected void setGpxDataItem(GpxDataItem gpxDataItem) {
this.gpxDataItem = gpxDataItem; this.gpxDataItem = gpxDataItem;
} }
@ -253,7 +365,7 @@ public class TrackActivity extends TabActivity {
return true; return true;
} }
} }
if (getIntent().hasExtra(MapActivity.INTENT_KEY_PARENT_MAP_ACTIVITY)) { if (getIntent().hasExtra(MapActivity.INTENT_KEY_PARENT_MAP_ACTIVITY) || openTracksList) {
OsmAndAppCustomization appCustomization = getMyApplication().getAppCustomization(); OsmAndAppCustomization appCustomization = getMyApplication().getAppCustomization();
final Intent favorites = new Intent(this, appCustomization.getFavoritesActivity()); final Intent favorites = new Intent(this, appCustomization.getFavoritesActivity());
getMyApplication().getSettings().FAVORITES_TAB.set(FavoritesActivity.GPX_TAB); getMyApplication().getSettings().FAVORITES_TAB.set(FavoritesActivity.GPX_TAB);
@ -286,6 +398,13 @@ public class TrackActivity extends TabActivity {
return; return;
} }
} }
if (openTracksList) {
OsmAndAppCustomization appCustomization = getMyApplication().getAppCustomization();
final Intent favorites = new Intent(this, appCustomization.getFavoritesActivity());
getMyApplication().getSettings().FAVORITES_TAB.set(FavoritesActivity.GPX_TAB);
favorites.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(favorites);
}
super.onBackPressed(); super.onBackPressed();
} }

View file

@ -21,6 +21,7 @@ import net.osmand.plus.GPXUtilities.GPXFile;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.myplaces.FavoritesActivity;
import net.osmand.plus.views.OsmandMapTileView; import net.osmand.plus.views.OsmandMapTileView;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
@ -88,6 +89,21 @@ public class GpxImportHelper {
return false; return false;
} }
public void handleFavouritesImport(Uri uri) {
String scheme = uri.getScheme();
boolean isFileIntent = "file".equals(scheme);
boolean isContentIntent = "content".equals(scheme);
boolean isOsmandSubdir = isSubDirectory(app.getAppPath(IndexConstants.GPX_INDEX_DIR), new File(uri.getPath()));
final boolean saveFile = !isFileIntent || !isOsmandSubdir;
String fileName = "";
if (isFileIntent) {
fileName = new File(uri.getPath()).getName();
} else if (isContentIntent) {
fileName = getNameFromContentUri(uri);
}
handleFavouritesImport(uri, fileName, saveFile, false, true);
}
public void handleFileImport(final Uri intentUri, final String fileName, final boolean useImportDir) { public void handleFileImport(final Uri intentUri, final String fileName, final boolean useImportDir) {
final boolean isFileIntent = "file".equals(intentUri.getScheme()); final boolean isFileIntent = "file".equals(intentUri.getScheme());
final boolean isOsmandSubdir = isSubDirectory(app.getAppPath(IndexConstants.GPX_INDEX_DIR), new File(intentUri.getPath())); final boolean isOsmandSubdir = isSubDirectory(app.getAppPath(IndexConstants.GPX_INDEX_DIR), new File(intentUri.getPath()));
@ -99,7 +115,7 @@ public class GpxImportHelper {
} else if (fileName != null && fileName.endsWith(KMZ_SUFFIX)) { } else if (fileName != null && fileName.endsWith(KMZ_SUFFIX)) {
handleKmzImport(intentUri, fileName, saveFile, useImportDir); handleKmzImport(intentUri, fileName, saveFile, useImportDir);
} else { } else {
handleFavouritesImport(intentUri, fileName, saveFile, useImportDir); handleFavouritesImport(intentUri, fileName, saveFile, useImportDir, false);
} }
} }
@ -155,12 +171,12 @@ public class GpxImportHelper {
@Override @Override
protected void onPostExecute(GPXFile result) { protected void onPostExecute(GPXFile result) {
progress.dismiss(); progress.dismiss();
handleResult(result, fileName, save, useImportDir); handleResult(result, fileName, save, useImportDir, false);
} }
}.execute(); }.execute();
} }
private void handleFavouritesImport(final Uri gpxFile, final String fileName, final boolean save, final boolean useImportDir) { private void handleFavouritesImport(final Uri gpxFile, final String fileName, final boolean save, final boolean useImportDir, final boolean forceImportFavourites) {
new AsyncTask<Void, Void, GPXFile>() { new AsyncTask<Void, Void, GPXFile>() {
ProgressDialog progress = null; ProgressDialog progress = null;
@ -193,12 +209,12 @@ public class GpxImportHelper {
@Override @Override
protected void onPostExecute(final GPXFile result) { protected void onPostExecute(final GPXFile result) {
progress.dismiss(); progress.dismiss();
importFavourites(result, fileName, save, useImportDir); importFavourites(result, fileName, save, useImportDir, forceImportFavourites);
} }
}.execute(); }.execute();
} }
private void importFavoritesImpl(final GPXFile gpxFile) { private void importFavoritesImpl(final GPXFile gpxFile, final String fileName, final boolean forceImportFavourites) {
new AsyncTask<Void, Void, GPXFile>() { new AsyncTask<Void, Void, GPXFile>() {
ProgressDialog progress = null; ProgressDialog progress = null;
@ -209,7 +225,7 @@ public class GpxImportHelper {
@Override @Override
protected GPXFile doInBackground(Void... nothing) { protected GPXFile doInBackground(Void... nothing) {
final List<FavouritePoint> favourites = asFavourites(gpxFile.points); final List<FavouritePoint> favourites = asFavourites(gpxFile.points, fileName, forceImportFavourites);
final FavouritesDbHelper favoritesHelper = app.getFavorites(); final FavouritesDbHelper favoritesHelper = app.getFavorites();
for (final FavouritePoint favourite : favourites) { for (final FavouritePoint favourite : favourites) {
favoritesHelper.deleteFavourite(favourite, false); favoritesHelper.deleteFavourite(favourite, false);
@ -225,6 +241,8 @@ public class GpxImportHelper {
progress.dismiss(); progress.dismiss();
Toast.makeText(activity, R.string.fav_imported_sucessfully, Toast.LENGTH_LONG).show(); Toast.makeText(activity, R.string.fav_imported_sucessfully, Toast.LENGTH_LONG).show();
final Intent newIntent = new Intent(activity, app.getAppCustomization().getFavoritesActivity()); final Intent newIntent = new Intent(activity, app.getAppCustomization().getFavoritesActivity());
newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
newIntent.putExtra(FavoritesActivity.OPEN_FAVOURITES_TAB, true);
activity.startActivity(newIntent); activity.startActivity(newIntent);
} }
}.execute(); }.execute();
@ -277,7 +295,7 @@ public class GpxImportHelper {
@Override @Override
protected void onPostExecute(GPXFile result) { protected void onPostExecute(GPXFile result) {
progress.dismiss(); progress.dismiss();
handleResult(result, name, save, useImportDir); handleResult(result, name, save, useImportDir, false);
} }
}.execute(); }.execute();
@ -322,13 +340,13 @@ public class GpxImportHelper {
@Override @Override
protected void onPostExecute(GPXFile result) { protected void onPostExecute(GPXFile result) {
progress.dismiss(); progress.dismiss();
handleResult(result, name, save, useImportDir); handleResult(result, name, save, useImportDir, false);
} }
}.execute(); }.execute();
} }
private void handleResult(final GPXFile result, final String name, final boolean save, private void handleResult(final GPXFile result, final String name, final boolean save,
final boolean useImportDir) { final boolean useImportDir, boolean forceImportFavourites) {
if (result != null) { if (result != null) {
if (result.warning != null) { if (result.warning != null) {
Toast.makeText(activity, result.warning, Toast.LENGTH_LONG).show(); Toast.makeText(activity, result.warning, Toast.LENGTH_LONG).show();
@ -372,6 +390,12 @@ public class GpxImportHelper {
}) })
.show(); .show();
} }
if (forceImportFavourites) {
final Intent newIntent = new Intent(activity, app.getAppCustomization().getFavoritesActivity());
newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
newIntent.putExtra(FavoritesActivity.OPEN_MY_PLACES_TAB, true);
activity.startActivity(newIntent);
}
} }
private String saveImport(final GPXFile gpxFile, final String fileName, final boolean useImportDir) { private String saveImport(final GPXFile gpxFile, final String fileName, final boolean useImportDir) {
@ -467,38 +491,76 @@ public class GpxImportHelper {
} }
private void importFavourites(final GPXFile gpxFile, final String fileName, final boolean save, private void importFavourites(final GPXFile gpxFile, final String fileName, final boolean save,
final boolean useImportDir) { final boolean useImportDir, final boolean forceImportFavourites) {
if (gpxFile == null || gpxFile.points == null || gpxFile.points.size() == 0) { if (gpxFile == null || gpxFile.points == null || gpxFile.points.size() == 0) {
handleResult(gpxFile, fileName, save, useImportDir); if (forceImportFavourites) {
return; final DialogInterface.OnClickListener importAsTrackListener = new DialogInterface.OnClickListener() {
} @Override
final DialogInterface.OnClickListener importFavouritesListener = new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) {
@Override switch (which) {
public void onClick(DialogInterface dialog, int which) { case DialogInterface.BUTTON_POSITIVE:
switch (which) { handleResult(gpxFile, fileName, save, useImportDir, true);
case DialogInterface.BUTTON_POSITIVE: break;
importFavoritesImpl(gpxFile); case DialogInterface.BUTTON_NEGATIVE:
break; dialog.dismiss();
case DialogInterface.BUTTON_NEGATIVE: break;
handleResult(gpxFile, fileName, save, useImportDir); }
break; }
} };
}
};
new AlertDialog.Builder(activity) new AlertDialog.Builder(activity)
.setTitle(R.string.shared_string_import2osmand) .setTitle(R.string.import_track)
.setMessage(R.string.import_file_favourites) .setMessage(activity.getString(R.string.import_track_desc, fileName))
.setPositiveButton(R.string.shared_string_import, importFavouritesListener) .setPositiveButton(R.string.shared_string_import, importAsTrackListener)
.setNegativeButton(R.string.shared_string_save, importFavouritesListener) .setNegativeButton(R.string.shared_string_cancel, importAsTrackListener)
.show(); .show();
return;
} else {
handleResult(gpxFile, fileName, save, useImportDir, false);
return;
}
}
if (forceImportFavourites) {
importFavoritesImpl(gpxFile, fileName, true);
} else {
final DialogInterface.OnClickListener importFavouritesListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
importFavoritesImpl(gpxFile, fileName, false);
break;
case DialogInterface.BUTTON_NEGATIVE:
handleResult(gpxFile, fileName, save, useImportDir, false);
break;
}
}
};
new AlertDialog.Builder(activity)
.setTitle(R.string.shared_string_import2osmand)
.setMessage(R.string.import_file_favourites)
.setPositiveButton(R.string.shared_string_import, importFavouritesListener)
.setNegativeButton(R.string.shared_string_save, importFavouritesListener)
.show();
}
} }
private List<FavouritePoint> asFavourites(final List<GPXUtilities.WptPt> wptPts) { private List<FavouritePoint> asFavourites(final List<GPXUtilities.WptPt> wptPts, String fileName, boolean forceImportFavourites) {
final List<FavouritePoint> favourites = new ArrayList<>(); final List<FavouritePoint> favourites = new ArrayList<>();
for (GPXUtilities.WptPt p : wptPts) { for (GPXUtilities.WptPt p : wptPts) {
if (p.name != null) { if (p.name != null) {
final String fpCat = (p.category != null) ? p.category : ""; final String fpCat;
if (p.category == null) {
if (forceImportFavourites) {
fpCat = fileName;
} else {
fpCat = "";
}
} else {
fpCat = p.category;
}
final FavouritePoint fp = new FavouritePoint(p.lat, p.lon, p.name, fpCat); final FavouritePoint fp = new FavouritePoint(p.lat, p.lon, p.name, fpCat);
if (p.desc != null) { if (p.desc != null) {
fp.setDescription(p.desc); fp.setDescription(p.desc);

View file

@ -3,7 +3,6 @@ package net.osmand.plus.mapcontextmenu.builders.cards.dialogs;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import net.osmand.plus.OsmandSettings; import net.osmand.plus.OsmandSettings;
@ -12,8 +11,6 @@ import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.mapillary.MapillaryImageDialog; import net.osmand.plus.mapillary.MapillaryImageDialog;
import net.osmand.plus.views.OsmandMapTileView; import net.osmand.plus.views.OsmandMapTileView;
import java.util.List;
public abstract class ContextMenuCardDialog { public abstract class ContextMenuCardDialog {
private MapActivity mapActivity; private MapActivity mapActivity;
@ -109,9 +106,9 @@ public abstract class ContextMenuCardDialog {
private void shiftMapPosition() { private void shiftMapPosition() {
OsmandMapTileView mapView = mapActivity.getMapView(); OsmandMapTileView mapView = mapActivity.getMapView();
if (AndroidUiHelper.isOrientationPortrait(mapActivity)) { if (AndroidUiHelper.isOrientationPortrait(mapActivity)) {
if (mapView.getMapPosition() != OsmandSettings.MIDDLE_CONSTANT) { if (mapView.getMapPosition() != OsmandSettings.MIDDLE_BOTTOM_CONSTANT) {
prevMapPosition = mapView.getMapPosition(); prevMapPosition = mapView.getMapPosition();
mapView.setMapPosition(OsmandSettings.MIDDLE_CONSTANT); mapView.setMapPosition(OsmandSettings.MIDDLE_BOTTOM_CONSTANT);
} }
} else { } else {
mapView.setMapPositionX(1); mapView.setMapPositionX(1);

View file

@ -118,7 +118,7 @@ public abstract class PointEditorFragment extends Fragment {
public boolean onTouch(final View v, MotionEvent event) { public boolean onTouch(final View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) { if (event.getAction() == MotionEvent.ACTION_UP) {
DialogFragment dialogFragment = DialogFragment dialogFragment =
SelectCategoryDialogFragment.createInstance(getEditor().getFragmentTag()); createSelectCategoryDialog();
dialogFragment.show(getChildFragmentManager(), SelectCategoryDialogFragment.TAG); dialogFragment.show(getChildFragmentManager(), SelectCategoryDialogFragment.TAG);
return true; return true;
} }
@ -176,6 +176,10 @@ public abstract class PointEditorFragment extends Fragment {
return view; return view;
} }
protected DialogFragment createSelectCategoryDialog() {
return SelectCategoryDialogFragment.createInstance(getEditor().getFragmentTag());
}
public Drawable getRowIcon(int iconId) { public Drawable getRowIcon(int iconId) {
IconsCache iconsCache = getMyApplication().getIconsCache(); IconsCache iconsCache = getMyApplication().getIconsCache();
return iconsCache.getIcon(iconId, return iconsCache.getIcon(iconId,

View file

@ -1,5 +1,7 @@
package net.osmand.plus.mapcontextmenu.editors; package net.osmand.plus.mapcontextmenu.editors;
import android.support.v4.app.DialogFragment;
import net.osmand.plus.GPXUtilities; import net.osmand.plus.GPXUtilities;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
@ -16,6 +18,11 @@ public class RtePtEditorFragment extends WptPtEditorFragment {
return getMapActivity().getResources().getString(R.string.save_route_point); return getMapActivity().getResources().getString(R.string.save_route_point);
} }
@Override
protected DialogFragment createSelectCategoryDialog() {
return SelectCategoryDialogFragment.createInstance(getEditor().getFragmentTag());
}
public static void showInstance(final MapActivity mapActivity) { public static void showInstance(final MapActivity mapActivity) {
RtePtEditor editor = mapActivity.getContextMenu().getRtePtPointEditor(); RtePtEditor editor = mapActivity.getContextMenu().getRtePtPointEditor();
//int slideInAnim = editor.getSlideInAnimation(); //int slideInAnim = editor.getSlideInAnimation();

View file

@ -15,6 +15,7 @@ import android.widget.Button;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import net.osmand.plus.FavouritesDbHelper; import net.osmand.plus.FavouritesDbHelper;
import net.osmand.plus.GPXUtilities.GPXFile;
import net.osmand.plus.IconsCache; import net.osmand.plus.IconsCache;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
@ -40,6 +41,15 @@ public class SelectCategoryDialogFragment extends DialogFragment {
private String editorTag; private String editorTag;
private CategorySelectionListener selectionListener; private CategorySelectionListener selectionListener;
private GPXFile gpxFile;
public void setGpxFile(GPXFile gpxFile) {
this.gpxFile = gpxFile;
}
public GPXFile getGpxFile() {
return gpxFile;
}
@NonNull @NonNull
@Override @Override
@ -58,36 +68,16 @@ public class SelectCategoryDialogFragment extends DialogFragment {
LinearLayout ll = (LinearLayout) v.findViewById(R.id.list_container); LinearLayout ll = (LinearLayout) v.findViewById(R.id.list_container);
final FavouritesDbHelper helper = ((OsmandApplication) getActivity().getApplication()).getFavorites(); final FavouritesDbHelper helper = ((OsmandApplication) getActivity().getApplication()).getFavorites();
List<FavouritesDbHelper.FavoriteGroup> gs = helper.getFavoriteGroups(); if (gpxFile != null) {
for (final FavouritesDbHelper.FavoriteGroup category : gs) { List<String> categories = gpxFile.getWaypointCategories();
View itemView = getActivity().getLayoutInflater().inflate(R.layout.favorite_category_dialog_item, null); for (final String category : categories) {
Button button = (Button)itemView.findViewById(R.id.button); addCategory(ll, category, 0);
if (category.color != 0) { }
button.setCompoundDrawablesWithIntrinsicBounds(getIcon(getActivity(), R.drawable.ic_action_folder, category.color), null, null, null); } else {
} else { List<FavouritesDbHelper.FavoriteGroup> gs = helper.getFavoriteGroups();
button.setCompoundDrawablesWithIntrinsicBounds(getIcon(getActivity(), R.drawable.ic_action_folder, getResources().getColor(R.color.color_favorite)), null, null, null); for (final FavouritesDbHelper.FavoriteGroup category : gs) {
addCategory(ll, category.name, category.color);
} }
button.setCompoundDrawablePadding(dpToPx(15f));
String name = category.name.length() == 0 ? getString(R.string.shared_string_favorites) : category.name;
button.setText(name);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
PointEditor editor = ((MapActivity) getActivity()).getContextMenu().getPointEditor(editorTag);
if (editor != null) {
editor.setCategory(category.name);
}
if (selectionListener != null) {
selectionListener.onCategorySelected(category.name, category.color);
}
dismiss();
}
});
ll.addView(itemView);
} }
View itemView = getActivity().getLayoutInflater().inflate(R.layout.favorite_category_dialog_item, null); View itemView = getActivity().getLayoutInflater().inflate(R.layout.favorite_category_dialog_item, null);
Button button = (Button)itemView.findViewById(R.id.button); Button button = (Button)itemView.findViewById(R.id.button);
@ -111,6 +101,40 @@ public class SelectCategoryDialogFragment extends DialogFragment {
return builder.create(); return builder.create();
} }
private void addCategory(LinearLayout ll, final String categoryName, final int categoryColor) {
View itemView = getActivity().getLayoutInflater().inflate(R.layout.favorite_category_dialog_item, null);
Button button = (Button)itemView.findViewById(R.id.button);
if (categoryColor != 0) {
button.setCompoundDrawablesWithIntrinsicBounds(getIcon(getActivity(), R.drawable.ic_action_folder, categoryColor), null, null, null);
} else {
button.setCompoundDrawablesWithIntrinsicBounds(getIcon(getActivity(), R.drawable.ic_action_folder, getResources().getColor(R.color.color_favorite)), null, null, null);
}
button.setCompoundDrawablePadding(dpToPx(15f));
String name = categoryName.length() == 0 ? getString(R.string.shared_string_favorites) : categoryName;
button.setText(name);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
PointEditor editor = ((MapActivity) getActivity()).getContextMenu().getPointEditor(editorTag);
if (editor != null) {
editor.setCategory(categoryName);
if (gpxFile != null && editor instanceof WptPtEditor) {
((WptPtEditor) editor).getWptPt().category = categoryName;
}
}
if (selectionListener != null) {
selectionListener.onCategorySelected(categoryName, categoryColor);
}
dismiss();
}
});
ll.addView(itemView);
}
public static SelectCategoryDialogFragment createInstance(String editorTag) { public static SelectCategoryDialogFragment createInstance(String editorTag) {
SelectCategoryDialogFragment fragment = new SelectCategoryDialogFragment(); SelectCategoryDialogFragment fragment = new SelectCategoryDialogFragment();
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();

View file

@ -7,6 +7,7 @@ import android.graphics.drawable.Drawable;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.view.View; import android.view.View;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
@ -47,6 +48,16 @@ public class WptPtEditorFragment extends PointEditorFragment {
defaultColor = getResources().getColor(R.color.gpx_color_point); defaultColor = getResources().getColor(R.color.gpx_color_point);
} }
@Override
protected DialogFragment createSelectCategoryDialog() {
SelectCategoryDialogFragment selectCategoryDialogFragment = SelectCategoryDialogFragment.createInstance(getEditor().getFragmentTag());
GPXFile gpx = editor.getGpxFile();
if (gpx != null) {
selectCategoryDialogFragment.setGpxFile(gpx);
}
return selectCategoryDialogFragment;
}
protected void assignEditor() { protected void assignEditor() {
editor = getMapActivity().getContextMenu().getWptPtPointEditor(); editor = getMapActivity().getContextMenu().getWptPtPointEditor();
} }

View file

@ -0,0 +1,86 @@
package net.osmand.plus.measurementtool;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout.LayoutParams;
import net.osmand.AndroidUtils;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
public class MeasurePointsListFragment extends Fragment {
public static final String TAG = "MeasurePointsListFragment";
private RecyclerView rv;
private int height;
private int width;
private FrameLayout parent;
private FrameLayout mainView;
public void setRecyclerView(RecyclerView rv) {
this.rv = rv;
}
public void setHeight(int height) {
this.height = height;
}
public void setWidth(int width) {
this.width = width;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
final MapActivity mapActivity = (MapActivity) getActivity();
if (rv == null) {
return null;
}
final boolean nightMode = mapActivity.getMyApplication().getDaynightHelper().isNightModeForMapControls();
final int backgroundColor = ContextCompat.getColor(getActivity(),
nightMode ? R.color.ctx_menu_info_view_bg_dark : R.color.ctx_menu_info_view_bg_light);
final TypedValue typedValueAttr = new TypedValue();
getActivity().getTheme().resolveAttribute(R.attr.left_menu_view_bg, typedValueAttr, true);
parent = new FrameLayout(mapActivity);
parent.setLayoutParams(new LayoutParams(width + AndroidUtils.dpToPx(getActivity(), 16), height));
parent.setBackgroundResource(typedValueAttr.resourceId);
mainView = new FrameLayout(mapActivity);
mainView.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
mainView.setBackgroundColor(backgroundColor);
ImageView shadow = new ImageView(mapActivity);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.BOTTOM;
shadow.setLayoutParams(params);
shadow.setScaleType(ImageView.ScaleType.FIT_XY);
shadow.setImageResource(R.drawable.bg_shadow_onmap);
mainView.addView(rv);
mainView.addView(shadow);
parent.addView(mainView);
return parent;
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (parent != null && mainView != null) {
parent.removeAllViews();
mainView.removeAllViews();
}
}
}

View file

@ -7,6 +7,7 @@ import android.graphics.Paint;
import android.graphics.Path; import android.graphics.Path;
import android.graphics.PointF; import android.graphics.PointF;
import net.osmand.AndroidUtils;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.data.PointDescription; import net.osmand.data.PointDescription;
import net.osmand.data.QuadPoint; import net.osmand.data.QuadPoint;
@ -28,18 +29,32 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
private OsmandMapTileView view; private OsmandMapTileView view;
private boolean inMeasurementMode; private boolean inMeasurementMode;
private LinkedList<WptPt> measurementPoints = new LinkedList<>(); private boolean inMovePointMode;
private LinkedList<WptPt> cacheMeasurementPoints = new LinkedList<>(); private boolean inAddPointAfterMode;
private boolean inAddPointBeforeMode;
private List<WptPt> measurementPoints = new LinkedList<>();
private List<WptPt> snappedToRoadPoints = new LinkedList<>();
private Bitmap centerIconDay; private Bitmap centerIconDay;
private Bitmap centerIconNight; private Bitmap centerIconNight;
private Bitmap pointIcon; private Bitmap pointIcon;
private Bitmap applyingPointIcon;
private Paint bitmapPaint; private Paint bitmapPaint;
private RenderingLineAttributes lineAttrs = new RenderingLineAttributes("rulerLine"); private final RenderingLineAttributes lineAttrs = new RenderingLineAttributes("measureDistanceLine");
private Path path = new Path(); private final Path path = new Path();
private int marginX; private int marginPointIconX;
private int marginY; private int marginPointIconY;
private TIntArrayList tx = new TIntArrayList(); private int marginApplyingPointIconX;
private TIntArrayList ty = new TIntArrayList(); private int marginApplyingPointIconY;
private final TIntArrayList tx = new TIntArrayList();
private final TIntArrayList ty = new TIntArrayList();
private OnMeasureDistanceToCenter measureDistanceToCenterListener;
private OnSingleTapListener singleTapListener;
private OnEnterMovePointModeListener enterMovePointModeListener;
private int selectedPointPos = -1;
private WptPt selectedCachedPoint;
private LatLon pressedPointLatLon;
private boolean overlapped;
private int pointsToDraw = 50;
@Override @Override
public void initLayer(OsmandMapTileView view) { public void initLayer(OsmandMapTileView view) {
@ -47,31 +62,83 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
centerIconDay = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_ruler_center_day); centerIconDay = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_ruler_center_day);
centerIconNight = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_ruler_center_night); centerIconNight = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_ruler_center_night);
pointIcon = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_pedestrian_location); pointIcon = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_measure_point_day);
applyingPointIcon = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_measure_point_move_day);
bitmapPaint = new Paint(); bitmapPaint = new Paint();
bitmapPaint.setAntiAlias(true); bitmapPaint.setAntiAlias(true);
bitmapPaint.setDither(true); bitmapPaint.setDither(true);
bitmapPaint.setFilterBitmap(true); bitmapPaint.setFilterBitmap(true);
marginY = pointIcon.getHeight() / 2; marginPointIconY = pointIcon.getHeight() / 2;
marginX = pointIcon.getWidth() / 2; marginPointIconX = pointIcon.getWidth() / 2;
marginApplyingPointIconY = applyingPointIcon.getHeight() / 2;
marginApplyingPointIconX = applyingPointIcon.getWidth() / 2;
}
void setOnSingleTapListener(OnSingleTapListener listener) {
this.singleTapListener = listener;
}
void setOnEnterMovePointModeListener(OnEnterMovePointModeListener listener) {
this.enterMovePointModeListener = listener;
}
void setOnMeasureDistanceToCenterListener(OnMeasureDistanceToCenter listener) {
this.measureDistanceToCenterListener = listener;
}
void setSelectedPointPos(int pos) {
selectedPointPos = pos;
}
void setSelectedCachedPoint(WptPt selectedCachedPoint) {
this.selectedCachedPoint = selectedCachedPoint;
}
WptPt getSelectedCachedPoint() {
return selectedCachedPoint;
}
int getSelectedPointPos() {
return selectedPointPos;
} }
public boolean isInMeasurementMode() { public boolean isInMeasurementMode() {
return inMeasurementMode; return inMeasurementMode;
} }
boolean isInMovePointMode() {
return inMovePointMode;
}
boolean isInAddPointAfterMode() {
return inAddPointAfterMode;
}
boolean isInAddPointBeforeMode() {
return inAddPointBeforeMode;
}
void setInMeasurementMode(boolean inMeasurementMode) { void setInMeasurementMode(boolean inMeasurementMode) {
this.inMeasurementMode = inMeasurementMode; this.inMeasurementMode = inMeasurementMode;
} }
int getPointsCount() { public List<WptPt> getMeasurementPoints() {
return measurementPoints.size(); return measurementPoints;
} }
public LinkedList<WptPt> getMeasurementPoints() { void setMeasurementPoints(List<WptPt> points) {
return measurementPoints; measurementPoints = points;
}
public List<WptPt> getSnappedToRoadPoints() {
return snappedToRoadPoints;
}
public void setSnappedToRoadPoints(List<WptPt> snappedToRoadPoints) {
this.snappedToRoadPoints = snappedToRoadPoints;
} }
String getDistanceSt() { String getDistanceSt() {
@ -85,50 +152,223 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
return OsmAndFormatter.getFormattedDistance(dist, view.getApplication()); return OsmAndFormatter.getFormattedDistance(dist, view.getApplication());
} }
void clearPoints() { @Override
measurementPoints.clear(); public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
cacheMeasurementPoints.clear(); if (singleTapListener != null) {
view.refreshMap(); if (inMeasurementMode && !inMovePointMode && !inAddPointAfterMode && !inAddPointBeforeMode) {
if (overlapped) {
clearSelection();
} else {
selectPoint(point.x, point.y, true);
}
if (selectedPointPos == -1) {
pressedPointLatLon = tileBox.getLatLonFromPixel(point.x, point.y);
singleTapListener.onAddPoint();
}
}
}
return false;
}
void clearSelection() {
selectedPointPos = -1;
selectedCachedPoint = null;
}
@Override
public boolean onLongPressEvent(PointF point, RotatedTileBox tileBox) {
if (inMeasurementMode) {
if (!overlapped && !inMovePointMode && !inAddPointAfterMode && !inAddPointBeforeMode && measurementPoints.size() > 0) {
selectPoint(point.x, point.y, false);
if (selectedCachedPoint != null && selectedPointPos != -1) {
enterMovingPointMode();
if (inMeasurementMode && inMovePointMode && enterMovePointModeListener != null) {
enterMovePointModeListener.onEnterMovePointMode();
}
}
}
}
return false;
}
void enterMovingPointMode() {
inMovePointMode = true;
moveMapToPoint(selectedPointPos);
}
void enterAddingPointAfterMode() {
inAddPointAfterMode = true;
moveMapToPoint(selectedPointPos);
}
void enterAddingPointBeforeMode() {
inAddPointBeforeMode = true;
moveMapToPoint(selectedPointPos);
}
private void selectPoint(double x, double y, boolean singleTap) {
clearSelection();
RotatedTileBox tb = view.getCurrentRotatedTileBox();
double lowestDistance = view.getResources().getDimension(R.dimen.measurement_tool_select_radius);
for (int i = 0; i < measurementPoints.size(); i++) {
WptPt pt = measurementPoints.get(i);
if (tb.containsLatLon(pt.getLatitude(), pt.getLongitude())) {
double xDiff = tb.getPixXFromLonNoRot(pt.getLongitude()) - x;
double yDiff = tb.getPixYFromLatNoRot(pt.getLatitude()) - y;
double distToPoint = Math.sqrt(Math.pow(xDiff, 2) + Math.pow(yDiff, 2));
if (distToPoint < lowestDistance) {
lowestDistance = distToPoint;
selectedCachedPoint = new WptPt(pt);
selectedPointPos = i;
}
}
}
if (singleTap && singleTapListener != null) {
singleTapListener.onSelectPoint(selectedPointPos, selectedCachedPoint);
}
}
void selectPoint(int position) {
clearSelection();
selectedCachedPoint = new WptPt(measurementPoints.get(position));
selectedPointPos = position;
if (singleTapListener != null) {
singleTapListener.onSelectPoint(selectedPointPos, selectedCachedPoint);
}
} }
@Override @Override
public void onDraw(Canvas canvas, RotatedTileBox tb, DrawSettings settings) { public void onDraw(Canvas canvas, RotatedTileBox tb, DrawSettings settings) {
if (inMeasurementMode) { if (inMeasurementMode) {
lineAttrs.updatePaints(view, settings, tb); lineAttrs.updatePaints(view, settings, tb);
drawCenterIcon(canvas, tb, tb.getCenterPixelPoint(), settings.isNightMode()); if (!inMovePointMode && !inAddPointAfterMode && !inAddPointBeforeMode) {
drawCenterIcon(canvas, tb, tb.getCenterPixelPoint(), settings.isNightMode());
if (measureDistanceToCenterListener != null) {
float distance = 0;
if (measurementPoints.size() > 0) {
WptPt lastPoint = measurementPoints.get(measurementPoints.size() - 1);
LatLon centerLatLon = tb.getCenterLatLon();
distance = (float) MapUtils.getDistance(lastPoint.lat, lastPoint.lon, centerLatLon.getLatitude(), centerLatLon.getLongitude());
}
measureDistanceToCenterListener.onMeasure(distance);
}
}
if (measurementPoints.size() > 0) { List<WptPt> drawPoints;
if (snappedToRoadPoints.size() > 0) {
drawPoints = snappedToRoadPoints;
} else {
drawPoints = measurementPoints;
}
if (drawPoints.size() > 0) {
path.reset(); path.reset();
tx.reset(); tx.reset();
ty.reset(); ty.reset();
for (int i = 0; i < drawPoints.size(); i++) {
WptPt pt = drawPoints.get(i);
int locX;
int locY;
if (selectedPointPos == i && (inMovePointMode || inAddPointAfterMode || inAddPointBeforeMode)) {
locX = tb.getCenterPixelX();
locY = tb.getCenterPixelY();
} else {
locX = tb.getPixXFromLonNoRot(pt.lon);
locY = tb.getPixYFromLatNoRot(pt.lat);
}
if (inAddPointAfterMode) {
int previousLocX = tb.getPixXFromLonNoRot(pt.lon);
int previousLocY = tb.getPixYFromLatNoRot(pt.lat);
if (i == 0) {
path.moveTo(previousLocX, previousLocY);
} else {
path.lineTo(previousLocX, previousLocY);
}
tx.add(previousLocX);
ty.add(previousLocY);
path.lineTo(locX, locY);
tx.add(locX);
ty.add(locY);
} else if (inAddPointBeforeMode) {
if (i == 0) {
path.moveTo(locX, locY);
} else {
path.lineTo(locX, locY);
}
tx.add(locX);
ty.add(locY);
int followingLocX = tb.getPixXFromLonNoRot(pt.lon);
int followingLocY = tb.getPixYFromLatNoRot(pt.lat);
path.lineTo(followingLocX, followingLocY);
tx.add(followingLocX);
ty.add(followingLocY);
} else {
if (i == 0) {
path.moveTo(locX, locY);
} else {
path.lineTo(locX, locY);
}
tx.add(locX);
ty.add(locY);
}
}
if (!inMovePointMode && !inAddPointAfterMode && !inAddPointBeforeMode) {
path.lineTo(tb.getCenterPixelX(), tb.getCenterPixelY());
tx.add(tb.getCenterPixelX());
ty.add(tb.getCenterPixelY());
}
calculatePath(tb, tx, ty, path);
canvas.drawPath(path, lineAttrs.paint);
overlapped = false;
int drawn = 0;
for (int i = 0; i < measurementPoints.size(); i++) { for (int i = 0; i < measurementPoints.size(); i++) {
WptPt pt = measurementPoints.get(i); WptPt pt = measurementPoints.get(i);
int locX = tb.getPixXFromLonNoRot(pt.lon); int locX = tb.getPixXFromLonNoRot(pt.lon);
int locY = tb.getPixYFromLatNoRot(pt.lat); int locY = tb.getPixYFromLatNoRot(pt.lat);
if (i == 0) { if (locX >= 0 && locX <= tb.getPixWidth() && locY >= 0 && locY <= tb.getPixHeight()) {
path.moveTo(locX, locY); if (!(inMovePointMode && i == selectedPointPos)) {
} else { drawn++;
path.lineTo(locX, locY); if (drawn > pointsToDraw) {
overlapped = true;
break;
}
}
} }
tx.add(locX);
ty.add(locY);
} }
path.lineTo(tb.getCenterPixelX(), tb.getCenterPixelY()); if (!overlapped) {
tx.add(tb.getCenterPixelX()); for (int i = 0; i < measurementPoints.size(); i++) {
ty.add(tb.getCenterPixelY()); WptPt pt = measurementPoints.get(i);
calculatePath(tb, tx, ty, path);
canvas.drawPath(path, lineAttrs.paint);
for (WptPt pt : measurementPoints) {
if (tb.containsLatLon(pt.lat, pt.lon)) {
int locX = tb.getPixXFromLonNoRot(pt.lon); int locX = tb.getPixXFromLonNoRot(pt.lon);
int locY = tb.getPixYFromLatNoRot(pt.lat); int locY = tb.getPixYFromLatNoRot(pt.lat);
canvas.drawBitmap(pointIcon, locX - marginX, locY - marginY, bitmapPaint); if (locX >= 0 && locX <= tb.getPixWidth() && locY >= 0 && locY <= tb.getPixHeight()) {
if (!(inMovePointMode && i == selectedPointPos)) {
canvas.drawBitmap(pointIcon, locX - marginPointIconX, locY - marginPointIconY, bitmapPaint);
}
}
} }
} }
if (inAddPointAfterMode || inAddPointBeforeMode || inMovePointMode) {
int locX = tb.getCenterPixelX();
int locY = tb.getCenterPixelY();
canvas.drawBitmap(applyingPointIcon, locX - marginApplyingPointIconX, locY - marginApplyingPointIconY, bitmapPaint);
}
} }
} }
} }
void exitMovePointMode() {
inMovePointMode = false;
}
void exitAddPointAfterMode() {
inAddPointAfterMode = false;
}
void exitAddPointBeforeMode() {
inAddPointBeforeMode = false;
}
private void drawCenterIcon(Canvas canvas, RotatedTileBox tb, QuadPoint center, boolean nightMode) { private void drawCenterIcon(Canvas canvas, RotatedTileBox tb, QuadPoint center, boolean nightMode) {
canvas.rotate(-tb.getRotate(), center.x, center.y); canvas.rotate(-tb.getRotate(), center.x, center.y);
if (nightMode) { if (nightMode) {
@ -141,37 +381,59 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
canvas.rotate(tb.getRotate(), center.x, center.y); canvas.rotate(tb.getRotate(), center.x, center.y);
} }
void addPointOnClick() { public WptPt addCenterPoint(int position) {
RotatedTileBox tb = view.getCurrentRotatedTileBox(); RotatedTileBox tb = view.getCurrentRotatedTileBox();
LatLon l = tb.getLatLonFromPixel(tb.getCenterPixelX(), tb.getCenterPixelY()); LatLon l = tb.getLatLonFromPixel(tb.getCenterPixelX(), tb.getCenterPixelY());
WptPt pt = new WptPt(); WptPt pt = new WptPt();
pt.lat = l.getLatitude(); pt.lat = l.getLatitude();
pt.lon = l.getLongitude(); pt.lon = l.getLongitude();
if (measurementPoints.size() > 0) { boolean allowed = measurementPoints.size() == 0 || !measurementPoints.get(measurementPoints.size() - 1).equals(pt);
if (!measurementPoints.get(measurementPoints.size() - 1).equals(pt)) { if (allowed) {
measurementPoints.add(pt); measurementPoints.add(position, pt);
} return pt;
} else {
measurementPoints.add(pt);
} }
cacheMeasurementPoints = new LinkedList<>(measurementPoints); return null;
view.refreshMap();
} }
boolean undoPointOnClick() { public WptPt addPoint(int position) {
measurementPoints.remove(measurementPoints.size() - 1); if (pressedPointLatLon != null) {
WptPt pt = new WptPt();
pt.lat = pressedPointLatLon.getLatitude();
pt.lon = pressedPointLatLon.getLongitude();
pressedPointLatLon = null;
boolean allowed = measurementPoints.size() == 0 || !measurementPoints.get(measurementPoints.size() - 1).equals(pt);
if (allowed) {
measurementPoints.add(position, pt);
moveMapToPoint(position);
return pt;
}
}
return null;
}
WptPt getMovedPointToApply() {
RotatedTileBox tb = view.getCurrentRotatedTileBox();
LatLon latLon = tb.getCenterLatLon();
WptPt pt = measurementPoints.get(selectedPointPos);
pt.lat = latLon.getLatitude();
pt.lon = latLon.getLongitude();
return pt;
}
public void moveMapToPoint(int pos) {
if (measurementPoints.size() > 0) { if (measurementPoints.size() > 0) {
WptPt pt = measurementPoints.get(measurementPoints.size() - 1); if (pos >= measurementPoints.size()) {
pos = measurementPoints.size() - 1;
} else if (pos < 0) {
pos = 0;
}
WptPt pt = measurementPoints.get(pos);
view.getAnimatedDraggingThread().startMoving(pt.getLatitude(), pt.getLongitude(), view.getZoom(), true); view.getAnimatedDraggingThread().startMoving(pt.getLatitude(), pt.getLongitude(), view.getZoom(), true);
} }
return measurementPoints.size() > 0;
} }
boolean redoPointOnClick() { public void refreshMap() {
WptPt pt = cacheMeasurementPoints.get(measurementPoints.size()); view.refreshMap();
measurementPoints.add(pt);
view.getAnimatedDraggingThread().startMoving(pt.getLatitude(), pt.getLongitude(), view.getZoom(), true);
return cacheMeasurementPoints.size() > measurementPoints.size();
} }
@Override @Override
@ -213,4 +475,19 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
public boolean isObjectClickable(Object o) { public boolean isObjectClickable(Object o) {
return !isInMeasurementMode(); return !isInMeasurementMode();
} }
interface OnSingleTapListener {
void onAddPoint();
void onSelectPoint(int selectedPointPos, WptPt selectedCachedPoint);
}
interface OnEnterMovePointModeListener {
void onEnterMovePointMode();
}
interface OnMeasureDistanceToCenter {
void onMeasure(float distance);
}
} }

View file

@ -0,0 +1,36 @@
package net.osmand.plus.measurementtool;
import net.osmand.data.QuadRect;
import net.osmand.plus.GPXUtilities;
public class NewGpxData {
public enum ActionType { ADD_SEGMENT, ADD_ROUTE_POINTS, EDIT_SEGMENT }
private GPXUtilities.GPXFile gpxFile;
private GPXUtilities.TrkSegment trkSegment;
private QuadRect rect;
private ActionType actionType;
public NewGpxData(GPXUtilities.GPXFile gpxFile, QuadRect rect, ActionType actionType, GPXUtilities.TrkSegment trkSegment) {
this.gpxFile = gpxFile;
this.rect = rect;
this.actionType = actionType;
this.trkSegment = trkSegment;
}
public GPXUtilities.GPXFile getGpxFile() {
return gpxFile;
}
public QuadRect getRect() {
return rect;
}
public ActionType getActionType() {
return actionType;
}
public GPXUtilities.TrkSegment getTrkSegment() {
return trkSegment;
}
}

View file

@ -0,0 +1,206 @@
package net.osmand.plus.measurementtool;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.DrawableRes;
import android.support.annotation.Nullable;
import android.support.v7.widget.SwitchCompat;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import net.osmand.AndroidUtils;
import net.osmand.plus.R;
import net.osmand.plus.base.BottomSheetDialogFragment;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.widgets.TextViewEx;
public class OptionsBottomSheetDialogFragment extends BottomSheetDialogFragment {
public final static String TAG = "OptionsBottomSheetDialogFragment";
private OptionsFragmentListener listener;
private boolean addLineMode;
private boolean portrait;
private boolean nightMode;
private boolean snapToRoadEnabled;
public void setListener(OptionsFragmentListener listener) {
this.listener = listener;
}
public void setAddLineMode(boolean addLineMode) {
this.addLineMode = addLineMode;
}
public void setSnapToRoadEnabled(boolean snapToRoadEnabled) {
this.snapToRoadEnabled = snapToRoadEnabled;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
nightMode = getMyApplication().getDaynightHelper().isNightModeForMapControls();
portrait = AndroidUiHelper.isOrientationPortrait(getActivity());
final int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme;
final View mainView = View.inflate(new ContextThemeWrapper(getContext(), themeRes), R.layout.fragment_options_bottom_sheet_dialog, null);
if (portrait) {
AndroidUtils.setBackground(getActivity(), mainView, nightMode, R.drawable.bg_bottom_menu_light, R.drawable.bg_bottom_menu_dark);
}
if (nightMode) {
((TextViewEx) mainView.findViewById(R.id.options_title)).setTextColor(getResources().getColor(R.color.ctx_menu_info_text_dark));
}
if (snapToRoadEnabled) {
mainView.findViewById(R.id.snap_to_road_enabled_text_view).setVisibility(View.VISIBLE);
((SwitchCompat) mainView.findViewById(R.id.snap_to_road_switch)).setChecked(true);
}
((ImageView) mainView.findViewById(R.id.snap_to_road_icon)).setImageDrawable(snapToRoadEnabled
? getActiveIcon(R.drawable.ic_action_snap_to_road)
: getContentIcon(R.drawable.ic_action_snap_to_road));
((ImageView) mainView.findViewById(R.id.clear_all_icon)).setImageDrawable(getContentIcon(R.drawable.ic_action_reset_to_default_dark));
if (!addLineMode) {
((ImageView) mainView.findViewById(R.id.save_as_new_track_icon)).setImageDrawable(getContentIcon(R.drawable.ic_action_polygom_dark));
((ImageView) mainView.findViewById(R.id.add_to_the_track_icon)).setImageDrawable(getContentIcon(R.drawable.ic_action_split_interval));
} else {
mainView.findViewById(R.id.save_as_new_track_row).setVisibility(View.GONE);
mainView.findViewById(R.id.add_to_the_track_row).setVisibility(View.GONE);
mainView.findViewById(R.id.save_as_new_segment_row).setVisibility(View.VISIBLE);
((ImageView) mainView.findViewById(R.id.save_as_new_segment_icon)).setImageDrawable(getContentIcon(R.drawable.ic_action_polygom_dark));
}
mainView.findViewById(R.id.snap_to_road_row).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (listener != null) {
listener.snapToRoadOnCLick();
}
dismiss();
}
});
mainView.findViewById(R.id.clear_all_row).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (listener != null) {
listener.clearAllOnClick();
}
dismiss();
}
});
if (!addLineMode) {
mainView.findViewById(R.id.save_as_new_track_row).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (listener != null) {
listener.saveAsNewTrackOnClick();
}
dismiss();
}
});
mainView.findViewById(R.id.add_to_the_track_row).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (listener != null) {
listener.addToTheTrackOnClick();
}
dismiss();
}
});
} else {
mainView.findViewById(R.id.save_as_new_segment_row).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (listener != null) {
listener.addToGpxOnClick();
}
dismiss();
}
});
}
mainView.findViewById(R.id.cancel_row).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dismiss();
}
});
final int screenHeight = AndroidUtils.getScreenHeight(getActivity());
final int statusBarHeight = AndroidUtils.getStatusBarHeight(getActivity());
final int navBarHeight = AndroidUtils.getNavBarHeight(getActivity());
mainView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
final View scrollView = mainView.findViewById(R.id.measure_options_scroll_view);
int scrollViewHeight = scrollView.getHeight();
int dividerHeight = AndroidUtils.dpToPx(getContext(), 1);
int cancelButtonHeight = getContext().getResources().getDimensionPixelSize(R.dimen.measure_distance_bottom_sheet_cancel_button_height);
int spaceForScrollView = screenHeight - statusBarHeight - navBarHeight - dividerHeight - cancelButtonHeight;
if (scrollViewHeight > spaceForScrollView) {
scrollView.getLayoutParams().height = spaceForScrollView;
scrollView.requestLayout();
}
if (!portrait) {
if (screenHeight - statusBarHeight - mainView.getHeight()
>= AndroidUtils.dpToPx(getActivity(), 8)) {
AndroidUtils.setBackground(getActivity(), mainView, nightMode,
R.drawable.bg_bottom_sheet_topsides_landscape_light, R.drawable.bg_bottom_sheet_topsides_landscape_dark);
} else {
AndroidUtils.setBackground(getActivity(), mainView, nightMode,
R.drawable.bg_bottom_sheet_sides_landscape_light, R.drawable.bg_bottom_sheet_sides_landscape_dark);
}
}
ViewTreeObserver obs = mainView.getViewTreeObserver();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
obs.removeOnGlobalLayoutListener(this);
} else {
obs.removeGlobalOnLayoutListener(this);
}
}
});
return mainView;
}
@Override
public void onStart() {
super.onStart();
if (!portrait) {
final Window window = getDialog().getWindow();
WindowManager.LayoutParams params = window.getAttributes();
params.width = getActivity().getResources().getDimensionPixelSize(R.dimen.landscape_bottom_sheet_dialog_fragment_width);
window.setAttributes(params);
}
}
@Override
protected Drawable getContentIcon(@DrawableRes int id) {
return getIcon(id, nightMode ? R.color.ctx_menu_info_text_dark : R.color.on_map_icon_color);
}
private Drawable getActiveIcon(@DrawableRes int id) {
return getIcon(id, nightMode ? R.color.osmand_orange : R.color.color_myloc_distance);
}
interface OptionsFragmentListener {
void snapToRoadOnCLick();
void addToGpxOnClick();
void saveAsNewTrackOnClick();
void addToTheTrackOnClick();
void clearAllOnClick();
}
}

View file

@ -0,0 +1,178 @@
package net.osmand.plus.measurementtool;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.DrawableRes;
import android.support.annotation.Nullable;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;
import net.osmand.AndroidUtils;
import net.osmand.plus.R;
import net.osmand.plus.Version;
import net.osmand.plus.base.BottomSheetDialogFragment;
import net.osmand.plus.helpers.AndroidUiHelper;
public class SaveAsNewTrackBottomSheetDialogFragment extends BottomSheetDialogFragment {
public final static String TAG = "SaveAsNewTrackBottomSheetDialogFragment";
private SaveAsNewTrackFragmentListener listener;
private boolean nightMode;
private boolean portrait;
public void setListener(SaveAsNewTrackFragmentListener listener) {
this.listener = listener;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
nightMode = getMyApplication().getDaynightHelper().isNightModeForMapControls();
portrait = AndroidUiHelper.isOrientationPortrait(getActivity());
final int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme;
final View mainView = View.inflate(new ContextThemeWrapper(getContext(), themeRes), R.layout.fragment_save_as_new_track_bottom_sheet_dialog, container);
if (portrait) {
AndroidUtils.setBackground(getActivity(), mainView, nightMode, R.drawable.bg_bottom_menu_light, R.drawable.bg_bottom_menu_dark);
}
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
mainView.findViewById(R.id.images_row).setVisibility(View.GONE);
} else {
final ImageView routePointImage = (ImageView) mainView.findViewById(R.id.route_point_image);
ImageView lineImage = (ImageView) mainView.findViewById(R.id.line_image);
if (nightMode) {
routePointImage.setImageResource(R.drawable.img_help_trip_route_points_night);
lineImage.setImageResource(R.drawable.img_help_trip_track_night);
} else {
routePointImage.setImageResource(R.drawable.img_help_trip_route_points_day);
lineImage.setImageResource(R.drawable.img_help_trip_track_day);
}
mainView.findViewById(R.id.line_text).setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return false;
}
});
lineImage.setOnClickListener(saveAsLineOnClickListener);
mainView.findViewById(R.id.route_point_text).setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return false;
}
});
routePointImage.setOnClickListener(saveAsRoutePointOnClickListener);
}
if (nightMode) {
((TextView) mainView.findViewById(R.id.save_as_new_track_title)).setTextColor(getResources().getColor(R.color.ctx_menu_info_text_dark));
}
((ImageView) mainView.findViewById(R.id.route_point_icon)).setImageDrawable(getContentIcon(R.drawable.ic_action_route_points));
((ImageView) mainView.findViewById(R.id.line_icon)).setImageDrawable(getContentIcon(R.drawable.ic_action_split_interval));
mainView.findViewById(R.id.save_as_line_row).setOnClickListener(saveAsLineOnClickListener);
mainView.findViewById(R.id.save_as_route_point_row).setOnClickListener(saveAsRoutePointOnClickListener);
mainView.findViewById(R.id.cancel_row).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dismiss();
}
});
final int screenHeight = AndroidUtils.getScreenHeight(getActivity());
final int statusBarHeight = AndroidUtils.getStatusBarHeight(getActivity());
final int navBarHeight = AndroidUtils.getNavBarHeight(getActivity());
mainView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
final View scrollView = mainView.findViewById(R.id.save_as_new_track_scroll_view);
int scrollViewHeight = scrollView.getHeight();
int dividerHeight = AndroidUtils.dpToPx(getContext(), 1);
int cancelButtonHeight = getContext().getResources().getDimensionPixelSize(R.dimen.measure_distance_bottom_sheet_cancel_button_height);
int spaceForScrollView = screenHeight - statusBarHeight - navBarHeight - dividerHeight - cancelButtonHeight;
if (scrollViewHeight > spaceForScrollView) {
scrollView.getLayoutParams().height = spaceForScrollView;
scrollView.requestLayout();
}
if (!portrait) {
if (screenHeight - statusBarHeight - mainView.getHeight()
>= AndroidUtils.dpToPx(getActivity(), 8)) {
AndroidUtils.setBackground(getActivity(), mainView, nightMode,
R.drawable.bg_bottom_sheet_topsides_landscape_light, R.drawable.bg_bottom_sheet_topsides_landscape_dark);
} else {
AndroidUtils.setBackground(getActivity(), mainView, nightMode,
R.drawable.bg_bottom_sheet_sides_landscape_light, R.drawable.bg_bottom_sheet_sides_landscape_dark);
}
}
ViewTreeObserver obs = mainView.getViewTreeObserver();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
obs.removeOnGlobalLayoutListener(this);
} else {
obs.removeGlobalOnLayoutListener(this);
}
}
});
return mainView;
}
@Override
public void onStart() {
super.onStart();
if (!portrait) {
final Window window = getDialog().getWindow();
WindowManager.LayoutParams params = window.getAttributes();
params.width = getActivity().getResources().getDimensionPixelSize(R.dimen.landscape_bottom_sheet_dialog_fragment_width);
window.setAttributes(params);
}
}
@Override
protected Drawable getContentIcon(@DrawableRes int id) {
return getIcon(id, nightMode ? R.color.ctx_menu_info_text_dark : R.color.on_map_icon_color);
}
private View.OnClickListener saveAsLineOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
if (listener != null) {
listener.saveAsLineOnClick();
}
dismiss();
}
};
private View.OnClickListener saveAsRoutePointOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
if (listener != null) {
listener.saveAsRoutePointOnClick();
}
dismiss();
}
};
interface SaveAsNewTrackFragmentListener {
void saveAsRoutePointOnClick();
void saveAsLineOnClick();
}
}

View file

@ -0,0 +1,227 @@
package net.osmand.plus.measurementtool;
import android.content.DialogInterface;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.DrawableRes;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;
import net.osmand.AndroidUtils;
import net.osmand.plus.GPXUtilities.WptPt;
import net.osmand.plus.IconsCache;
import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.TrackActivity;
import net.osmand.plus.base.BottomSheetDialogFragment;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.util.MapUtils;
import java.util.List;
public class SelectedPointBottomSheetDialogFragment extends BottomSheetDialogFragment {
public final static String TAG = "SelectedPointBottomSheetDialogFragment";
private SelectedPointFragmentListener listener;
private boolean nightMode;
private boolean portrait;
private NewGpxData.ActionType actionType;
public void setListener(SelectedPointFragmentListener listener) {
this.listener = listener;
}
public void setActionType(NewGpxData.ActionType actionType) {
this.actionType = actionType;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final MapActivity mapActivity = (MapActivity) getActivity();
nightMode = getMyApplication().getDaynightHelper().isNightModeForMapControls();
portrait = AndroidUiHelper.isOrientationPortrait(mapActivity);
final IconsCache iconsCache = mapActivity.getMyApplication().getIconsCache();
final MeasurementToolLayer measurementLayer = mapActivity.getMapLayers().getMeasurementToolLayer();
final int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme;
final View mainView = View.inflate(new ContextThemeWrapper(getContext(), themeRes), R.layout.fragment_selected_menu_bottom_sheet_dialog, null);
if (portrait) {
AndroidUtils.setBackground(getActivity(), mainView, nightMode, R.drawable.bg_bottom_menu_light, R.drawable.bg_bottom_menu_dark);
}
int color = nightMode ? R.color.osmand_orange : R.color.color_myloc_distance;
((ImageView) mainView.findViewById(R.id.selected_point_icon)).setImageDrawable(iconsCache.getIcon(R.drawable.ic_action_measure_point, color));
((ImageView) mainView.findViewById(R.id.move_point_icon)).setImageDrawable(getContentIcon(R.drawable.ic_action_move_point));
((ImageView) mainView.findViewById(R.id.delete_point_icon)).setImageDrawable(getContentIcon(R.drawable.ic_action_remove_dark));
((ImageView) mainView.findViewById(R.id.add_point_after_icon)).setImageDrawable(getContentIcon(R.drawable.ic_action_addpoint_above));
((ImageView) mainView.findViewById(R.id.add_point_before_icon)).setImageDrawable(getContentIcon(R.drawable.ic_action_addpoint_below));
mainView.findViewById(R.id.move_point_row).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (listener != null) {
listener.moveOnClick();
}
dismiss();
}
});
mainView.findViewById(R.id.delete_point_row).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (listener != null) {
listener.deleteOnClick();
}
dismiss();
}
});
mainView.findViewById(R.id.add_point_after_row).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (listener != null) {
listener.addPointAfterOnClick();
}
dismiss();
}
});
mainView.findViewById(R.id.add_point_before_row).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (listener != null) {
listener.addPointBeforeOnClick();
}
dismiss();
}
});
mainView.findViewById(R.id.cancel_row).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dismiss();
}
});
List<WptPt> points = measurementLayer.getMeasurementPoints();
int pos = measurementLayer.getSelectedPointPos();
WptPt pt = points.get(pos);
String pointTitle = pt.name;
if (!TextUtils.isEmpty(pointTitle)) {
((TextView) mainView.findViewById(R.id.selected_point_title)).setText(pointTitle);
} else {
if (actionType == NewGpxData.ActionType.ADD_ROUTE_POINTS) {
((TextView) mainView.findViewById(R.id.selected_point_title)).setText(mapActivity.getString(R.string.route_point) + " - " + (pos + 1));
} else {
((TextView) mainView.findViewById(R.id.selected_point_title)).setText(mapActivity.getString(R.string.plugin_distance_point) + " - " + (pos + 1));
}
}
String pointDesc = pt.desc;
if (!TextUtils.isEmpty(pointDesc)) {
((TextView) mainView.findViewById(R.id.selected_point_distance)).setText(pointDesc);
} else {
if (pos < 1) {
((TextView) mainView.findViewById(R.id.selected_point_distance)).setText(mapActivity.getString(R.string.shared_string_control_start));
} else {
float dist = 0;
for (int i = 1; i <= pos; i++) {
dist += MapUtils.getDistance(points.get(i - 1).lat, points.get(i - 1).lon, points.get(i).lat, points.get(i).lon);
}
((TextView) mainView.findViewById(R.id.selected_point_distance)).setText(OsmAndFormatter.getFormattedDistance(dist, mapActivity.getMyApplication()));
}
}
final int screenHeight = AndroidUtils.getScreenHeight(getActivity());
final int statusBarHeight = AndroidUtils.getStatusBarHeight(getActivity());
final int navBarHeight = AndroidUtils.getNavBarHeight(getActivity());
mainView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
final View scrollView = mainView.findViewById(R.id.selected_point_options_scroll_view);
int scrollViewHeight = scrollView.getHeight();
int dividerHeight = AndroidUtils.dpToPx(getContext(), 1);
int cancelButtonHeight = getContext().getResources().getDimensionPixelSize(R.dimen.measure_distance_bottom_sheet_cancel_button_height);
int spaceForScrollView = screenHeight - statusBarHeight - navBarHeight - dividerHeight - cancelButtonHeight;
if (scrollViewHeight > spaceForScrollView) {
scrollView.getLayoutParams().height = spaceForScrollView;
scrollView.requestLayout();
}
if (!portrait) {
if (screenHeight - statusBarHeight - mainView.getHeight()
>= AndroidUtils.dpToPx(getActivity(), 8)) {
AndroidUtils.setBackground(getActivity(), mainView, nightMode,
R.drawable.bg_bottom_sheet_topsides_landscape_light, R.drawable.bg_bottom_sheet_topsides_landscape_dark);
} else {
AndroidUtils.setBackground(getActivity(), mainView, nightMode,
R.drawable.bg_bottom_sheet_sides_landscape_light, R.drawable.bg_bottom_sheet_sides_landscape_dark);
}
}
ViewTreeObserver obs = mainView.getViewTreeObserver();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
obs.removeOnGlobalLayoutListener(this);
} else {
obs.removeGlobalOnLayoutListener(this);
}
}
});
return mainView;
}
@Override
public void onStart() {
super.onStart();
if (!portrait) {
final Window window = getDialog().getWindow();
WindowManager.LayoutParams params = window.getAttributes();
params.width = getActivity().getResources().getDimensionPixelSize(R.dimen.landscape_bottom_sheet_dialog_fragment_width);
window.setAttributes(params);
}
}
@Override
protected Drawable getContentIcon(@DrawableRes int id) {
return getIcon(id, nightMode ? R.color.ctx_menu_info_text_dark : R.color.on_map_icon_color);
}
@Override
public void dismiss() {
if (listener != null) {
listener.onCloseMenu();
}
super.dismiss();
}
@Override
public void onCancel(DialogInterface dialog) {
if (listener != null) {
listener.onCloseMenu();
}
super.onCancel(dialog);
}
interface SelectedPointFragmentListener {
void moveOnClick();
void deleteOnClick();
void addPointAfterOnClick();
void addPointBeforeOnClick();
void onCloseMenu();
}
}

View file

@ -0,0 +1,144 @@
package net.osmand.plus.measurementtool;
import android.app.Dialog;
import android.content.DialogInterface;
import android.graphics.drawable.Drawable;
import android.support.annotation.DrawableRes;
import android.support.design.widget.BottomSheetBehavior;
import android.support.design.widget.BottomSheetDialog;
import android.support.v4.content.ContextCompat;
import android.view.ContextThemeWrapper;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import net.osmand.AndroidUtils;
import net.osmand.plus.ApplicationMode;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.helpers.AndroidUiHelper;
import java.util.ArrayList;
import java.util.List;
public class SnapToRoadBottomSheetDialogFragment extends android.support.design.widget.BottomSheetDialogFragment {
public static final String TAG = "SnapToRoadBottomSheetDialogFragment";
private SnapToRoadFragmentListener listener;
private boolean nightMode;
private boolean portrait;
private boolean snapToRoadEnabled;
public void setListener(SnapToRoadFragmentListener listener) {
this.listener = listener;
}
@Override
public void setupDialog(Dialog dialog, int style) {
super.setupDialog(dialog, style);
nightMode = getMyApplication().getDaynightHelper().isNightModeForMapControls();
portrait = AndroidUiHelper.isOrientationPortrait(getActivity());
final OsmandSettings settings = getMyApplication().getSettings();
final int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme;
final View mainView = View.inflate(new ContextThemeWrapper(getContext(), themeRes), R.layout.fragment_snap_to_road_bottom_sheet_dialog, null);
AndroidUtils.setBackground(getActivity(), mainView, nightMode,
portrait ? R.drawable.bg_bottom_menu_light : R.drawable.bg_bottom_sheet_topsides_landscape_light,
portrait ? R.drawable.bg_bottom_menu_dark : R.drawable.bg_bottom_sheet_topsides_landscape_dark);
mainView.findViewById(R.id.cancel_row).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dismiss();
}
});
if (nightMode) {
((TextView) mainView.findViewById(R.id.choose_navigation_title))
.setTextColor(ContextCompat.getColor(getActivity(), R.color.ctx_menu_info_text_dark));
}
LinearLayout container = (LinearLayout) mainView.findViewById(R.id.navigation_types_container);
final List<ApplicationMode> modes = new ArrayList<>(ApplicationMode.values(settings));
modes.remove(ApplicationMode.DEFAULT);
View.OnClickListener onClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
snapToRoadEnabled = true;
if (listener != null) {
listener.onApplicationModeItemClick(modes.get((int) view.getTag()));
}
dismiss();
}
};
for (int i = 0; i < modes.size(); i++) {
ApplicationMode mode = modes.get(i);
View row = View.inflate(new ContextThemeWrapper(getContext(), themeRes), R.layout.list_item_icon_and_title, null);
((ImageView) row.findViewById(R.id.icon)).setImageDrawable(getContentIcon(mode.getSmallIconDark()));
((TextView) row.findViewById(R.id.title)).setText(mode.toHumanString(getContext()));
row.setOnClickListener(onClickListener);
row.setTag(i);
container.addView(row);
}
if (!portrait) {
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialogInterface) {
BottomSheetDialog dialog = (BottomSheetDialog) dialogInterface;
FrameLayout bottomSheet = (FrameLayout) dialog.findViewById(android.support.design.R.id.design_bottom_sheet);
BottomSheetBehavior.from(bottomSheet).setState(BottomSheetBehavior.STATE_EXPANDED);
}
});
}
dialog.setContentView(mainView);
((View) mainView.getParent()).setBackgroundResource(0);
}
@Override
public void onStart() {
super.onStart();
if (!portrait) {
final Window window = getDialog().getWindow();
WindowManager.LayoutParams params = window.getAttributes();
params.width = getActivity().getResources().getDimensionPixelSize(R.dimen.landscape_bottom_sheet_dialog_fragment_width);
window.setAttributes(params);
}
}
@Override
public void onDestroyView() {
if (listener != null) {
listener.onDestroyView(snapToRoadEnabled);
}
super.onDestroyView();
}
private OsmandApplication getMyApplication() {
return ((MapActivity) getActivity()).getMyApplication();
}
private Drawable getContentIcon(@DrawableRes int id) {
return getMyApplication().getIconsCache()
.getIcon(id, nightMode ? R.color.ctx_menu_info_text_dark : R.color.on_map_icon_color);
}
interface SnapToRoadFragmentListener {
void onDestroyView(boolean snapToRoadEnabled);
void onApplicationModeItemClick(ApplicationMode mode);
}
}

View file

@ -0,0 +1,181 @@
package net.osmand.plus.measurementtool.adapter;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.MotionEventCompat;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import net.osmand.plus.GPXUtilities.WptPt;
import net.osmand.plus.IconsCache;
import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.measurementtool.NewGpxData;
import net.osmand.util.MapUtils;
import java.util.Collections;
import java.util.List;
public class MeasurementToolAdapter extends RecyclerView.Adapter<MeasurementToolAdapter.MeasureToolItemVH>
implements MeasurementToolItemTouchHelperCallback.ItemTouchHelperAdapter {
private final MapActivity mapActivity;
private final List<WptPt> points;
private MeasurementAdapterListener listener;
private boolean nightMode;
private NewGpxData.ActionType actionType;
public MeasurementToolAdapter(MapActivity mapActivity, List<WptPt> points, NewGpxData.ActionType actionType) {
this.mapActivity = mapActivity;
this.points = points;
this.actionType = actionType;
}
public void setAdapterListener(MeasurementAdapterListener listener) {
this.listener = listener;
}
@Override
public MeasureToolItemVH onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.measure_points_list_item, viewGroup, false);
nightMode = mapActivity.getMyApplication().getDaynightHelper().isNightModeForMapControls();
if (!nightMode) {
view.findViewById(R.id.points_divider).setBackgroundResource(R.drawable.divider);
}
final int backgroundColor = ContextCompat.getColor(mapActivity,
nightMode ? R.color.ctx_menu_info_view_bg_dark : R.color.ctx_menu_info_view_bg_light);
view.setBackgroundColor(backgroundColor);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listener.onItemClick(view);
}
});
return new MeasureToolItemVH(view);
}
@Override
public void onBindViewHolder(final MeasureToolItemVH holder, int pos) {
IconsCache iconsCache = mapActivity.getMyApplication().getIconsCache();
holder.iconReorder.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_reorder));
holder.iconReorder.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
listener.onDragStarted(holder);
}
return false;
}
});
holder.icon.setImageDrawable(iconsCache.getIcon(R.drawable.ic_action_measure_point,
nightMode ? R.color.ctx_menu_info_text_dark : R.color.icon_color));
if (nightMode) {
holder.title.setTextColor(mapActivity.getMyApplication().getResources().getColor(R.color.primary_text_dark));
}
WptPt pt = points.get(pos);
String pointTitle = pt.name;
if (!TextUtils.isEmpty(pointTitle)) {
holder.title.setText(pointTitle);
} else {
if (actionType == NewGpxData.ActionType.ADD_ROUTE_POINTS) {
holder.title.setText(mapActivity.getString(R.string.route_point) + " - " + (pos + 1));
} else {
holder.title.setText(mapActivity.getString(R.string.plugin_distance_point) + " - " + (pos + 1));
}
}
String pointDesc = pt.desc;
if (!TextUtils.isEmpty(pointDesc)) {
holder.descr.setText(pointDesc);
} else {
if (pos < 1) {
holder.descr.setText(mapActivity.getString(R.string.shared_string_control_start));
} else {
float dist = 0;
for (int i = 1; i <= pos; i++) {
dist += MapUtils.getDistance(points.get(i - 1).lat, points.get(i - 1).lon,
points.get(i).lat, points.get(i).lon);
}
holder.descr.setText(OsmAndFormatter.getFormattedDistance(dist, mapActivity.getMyApplication()));
}
}
if (actionType == NewGpxData.ActionType.EDIT_SEGMENT) {
double elevation = pt.ele;
if (!Double.isNaN(elevation)) {
holder.elevation.setText(mapActivity.getString(R.string.measurement_tool_altitude, OsmAndFormatter.getFormattedAlt(elevation, mapActivity.getMyApplication())));
} else {
holder.elevation.setText("");
}
float speed = (float) pt.speed;
if (speed != 0) {
holder.speed.setText(mapActivity.getString(R.string.measurement_tool_speed, OsmAndFormatter.getFormattedSpeed(speed, mapActivity.getMyApplication())));
} else {
holder.speed.setText("");
}
}
holder.deleteBtn.setImageDrawable(iconsCache.getIcon(R.drawable.ic_action_remove_dark,
nightMode ? R.color.ctx_menu_info_text_dark : R.color.icon_color));
holder.deleteBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listener.onRemoveClick(holder.getAdapterPosition());
}
});
}
@Override
public int getItemCount() {
return points.size();
}
@Override
public boolean onItemMove(int from, int to) {
Collections.swap(points, from, to);
notifyItemMoved(from, to);
return true;
}
@Override
public void onItemDismiss(RecyclerView.ViewHolder holder) {
listener.onDragEnded(holder);
}
static class MeasureToolItemVH extends RecyclerView.ViewHolder {
final ImageView iconReorder;
final ImageView icon;
final TextView title;
final TextView descr;
final TextView elevation;
final TextView speed;
final ImageButton deleteBtn;
MeasureToolItemVH(View view) {
super(view);
iconReorder = (ImageView) view.findViewById(R.id.measure_point_reorder_icon);
icon = (ImageView) view.findViewById(R.id.measure_point_icon);
title = (TextView) view.findViewById(R.id.measure_point_title);
descr = (TextView) view.findViewById(R.id.measure_point_descr);
elevation = (TextView) view.findViewById(R.id.measure_point_ele);
speed = (TextView) view.findViewById(R.id.measure_point_speed);
deleteBtn = (ImageButton) view.findViewById(R.id.measure_point_remove_image_button);
}
}
public interface MeasurementAdapterListener {
void onRemoveClick(int position);
void onItemClick(View view);
void onDragStarted(RecyclerView.ViewHolder holder);
void onDragEnded(RecyclerView.ViewHolder holder);
}
}

View file

@ -0,0 +1,53 @@
package net.osmand.plus.measurementtool.adapter;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
public class MeasurementToolItemTouchHelperCallback extends ItemTouchHelper.Callback {
private final ItemTouchHelperAdapter adapter;
public MeasurementToolItemTouchHelperCallback(ItemTouchHelperAdapter adapter) {
this.adapter = adapter;
}
@Override
public boolean isLongPressDragEnabled() {
return false;
}
@Override
public boolean isItemViewSwipeEnabled() {
return false;
}
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
return makeMovementFlags(dragFlags, 0);
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) {
return adapter.onItemMove(source.getAdapterPosition(), target.getAdapterPosition());
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int i) {
}
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
adapter.onItemDismiss(viewHolder);
}
interface ItemTouchHelperAdapter {
boolean onItemMove(int from, int to);
void onItemDismiss(RecyclerView.ViewHolder holder);
}
}

View file

@ -0,0 +1,52 @@
package net.osmand.plus.measurementtool.command;
import net.osmand.plus.GPXUtilities.WptPt;
import net.osmand.plus.measurementtool.MeasurementToolLayer;
public class AddPointCommand extends MeasurementModeCommand {
private final int position;
private WptPt point;
private boolean center;
public AddPointCommand(MeasurementToolLayer measurementLayer, int position) {
this.measurementLayer = measurementLayer;
this.center = true;
this.position = position;
}
public AddPointCommand(MeasurementToolLayer measurementLayer, boolean center) {
this.measurementLayer = measurementLayer;
this.center = center;
position = measurementLayer.getMeasurementPoints().size();
}
@Override
public boolean execute() {
if (center) {
point = measurementLayer.addCenterPoint(position);
} else {
point = measurementLayer.addPoint(position);
}
measurementLayer.refreshMap();
return point != null;
}
@Override
public void undo() {
measurementLayer.getMeasurementPoints().remove(position);
measurementLayer.refreshMap();
}
@Override
public void redo() {
measurementLayer.getMeasurementPoints().add(position, point);
measurementLayer.refreshMap();
measurementLayer.moveMapToPoint(position);
}
@Override
MeasurementCommandType getType() {
return MeasurementCommandType.ADD_POINT;
}
}

View file

@ -0,0 +1,48 @@
package net.osmand.plus.measurementtool.command;
import net.osmand.plus.GPXUtilities.WptPt;
import net.osmand.plus.measurementtool.MeasurementToolLayer;
import java.util.LinkedList;
import java.util.List;
public class ClearPointsCommand extends MeasurementModeCommand {
private List<WptPt> points;
private List<WptPt> snappedToRoadPoints;
public ClearPointsCommand(MeasurementToolLayer measurementLayer) {
this.measurementLayer = measurementLayer;
}
@Override
public boolean execute() {
List<WptPt> pts = measurementLayer.getMeasurementPoints();
List<WptPt> snappedPts = measurementLayer.getSnappedToRoadPoints();
points = new LinkedList<>(pts);
snappedToRoadPoints = new LinkedList<>(snappedPts);
pts.clear();
snappedPts.clear();
measurementLayer.refreshMap();
return true;
}
@Override
public void undo() {
measurementLayer.getMeasurementPoints().addAll(points);
measurementLayer.getSnappedToRoadPoints().addAll(snappedToRoadPoints);
measurementLayer.refreshMap();
}
@Override
public void redo() {
measurementLayer.getMeasurementPoints().clear();
measurementLayer.getSnappedToRoadPoints().clear();
measurementLayer.refreshMap();
}
@Override
MeasurementCommandType getType() {
return MeasurementCommandType.CLEAR_POINTS;
}
}

View file

@ -0,0 +1,10 @@
package net.osmand.plus.measurementtool.command;
public interface Command {
boolean execute();
void undo();
void redo();
}

View file

@ -0,0 +1,63 @@
package net.osmand.plus.measurementtool.command;
import android.support.annotation.Nullable;
import net.osmand.plus.measurementtool.MeasurementToolLayer;
import net.osmand.plus.measurementtool.command.MeasurementModeCommand.MeasurementCommandType;
import java.util.Deque;
import java.util.LinkedList;
public class MeasurementCommandManager {
private final Deque<MeasurementModeCommand> undoCommands = new LinkedList<>();
private final Deque<MeasurementModeCommand> redoCommands = new LinkedList<>();
public boolean canUndo() {
return undoCommands.size() > 0;
}
public boolean canRedo() {
return redoCommands.size() > 0;
}
public boolean execute(MeasurementModeCommand command) {
if (command.execute()) {
undoCommands.push(command);
redoCommands.clear();
return true;
}
return false;
}
@Nullable
public MeasurementCommandType undo() {
if (canUndo()) {
MeasurementModeCommand command = undoCommands.pop();
redoCommands.push(command);
command.undo();
return command.getType();
}
return null;
}
@Nullable
public MeasurementCommandType redo() {
if (canRedo()) {
MeasurementModeCommand command = redoCommands.pop();
undoCommands.push(command);
command.redo();
return command.getType();
}
return null;
}
public void resetMeasurementLayer(MeasurementToolLayer layer) {
for (MeasurementModeCommand command : undoCommands) {
command.setMeasurementLayer(layer);
}
for (MeasurementModeCommand command : redoCommands) {
command.setMeasurementLayer(layer);
}
}
}

View file

@ -0,0 +1,23 @@
package net.osmand.plus.measurementtool.command;
import net.osmand.plus.measurementtool.MeasurementToolLayer;
public abstract class MeasurementModeCommand implements Command {
MeasurementToolLayer measurementLayer;
void setMeasurementLayer(MeasurementToolLayer layer) {
this.measurementLayer = layer;
}
abstract MeasurementCommandType getType();
public enum MeasurementCommandType {
ADD_POINT,
CLEAR_POINTS,
MOVE_POINT,
REMOVE_POINT,
REORDER_POINT,
SNAP_TO_ROAD
}
}

View file

@ -0,0 +1,42 @@
package net.osmand.plus.measurementtool.command;
import net.osmand.plus.GPXUtilities.WptPt;
import net.osmand.plus.measurementtool.MeasurementToolLayer;
public class MovePointCommand extends MeasurementModeCommand {
private final WptPt oldPoint;
private final WptPt newPoint;
private final int position;
public MovePointCommand(MeasurementToolLayer measurementLayer, WptPt oldPoint, WptPt newPoint, int position) {
this.measurementLayer = measurementLayer;
this.oldPoint = oldPoint;
this.newPoint = newPoint;
this.position = position;
}
@Override
public boolean execute() {
return true;
}
@Override
public void undo() {
measurementLayer.getMeasurementPoints().remove(position);
measurementLayer.getMeasurementPoints().add(position, oldPoint);
measurementLayer.refreshMap();
}
@Override
public void redo() {
measurementLayer.getMeasurementPoints().remove(position);
measurementLayer.getMeasurementPoints().add(position, newPoint);
measurementLayer.refreshMap();
}
@Override
MeasurementCommandType getType() {
return MeasurementCommandType.MOVE_POINT;
}
}

View file

@ -0,0 +1,40 @@
package net.osmand.plus.measurementtool.command;
import net.osmand.plus.GPXUtilities.WptPt;
import net.osmand.plus.measurementtool.MeasurementToolLayer;
public class RemovePointCommand extends MeasurementModeCommand {
private final int position;
private WptPt point;
public RemovePointCommand(MeasurementToolLayer measurementLayer, int position) {
this.measurementLayer = measurementLayer;
this.position = position;
}
@Override
public boolean execute() {
point = measurementLayer.getMeasurementPoints().remove(position);
measurementLayer.refreshMap();
return true;
}
@Override
public void undo() {
measurementLayer.getMeasurementPoints().add(position, point);
measurementLayer.refreshMap();
measurementLayer.moveMapToPoint(position);
}
@Override
public void redo() {
measurementLayer.getMeasurementPoints().remove(position);
measurementLayer.refreshMap();
}
@Override
MeasurementCommandType getType() {
return MeasurementCommandType.REMOVE_POINT;
}
}

View file

@ -0,0 +1,42 @@
package net.osmand.plus.measurementtool.command;
import net.osmand.plus.measurementtool.MeasurementToolLayer;
import java.util.Collections;
public class ReorderPointCommand extends MeasurementModeCommand {
private final int from;
private final int to;
public ReorderPointCommand(MeasurementToolLayer measurementLayer, int from, int to) {
this.measurementLayer = measurementLayer;
this.from = from;
this.to = to;
}
@Override
public boolean execute() {
return true;
}
@Override
public void undo() {
swap();
}
@Override
public void redo() {
swap();
}
private void swap() {
Collections.swap(measurementLayer.getMeasurementPoints(), from, to);
measurementLayer.refreshMap();
}
@Override
MeasurementCommandType getType() {
return MeasurementCommandType.REORDER_POINT;
}
}

View file

@ -0,0 +1,41 @@
package net.osmand.plus.measurementtool.command;
import net.osmand.plus.GPXUtilities.WptPt;
import net.osmand.plus.measurementtool.MeasurementToolLayer;
import java.util.List;
public class SnapToRoadCommand extends MeasurementModeCommand {
private List<WptPt> snappedPoints;
public SnapToRoadCommand(MeasurementToolLayer measurementLayer, List<WptPt> points) {
this.measurementLayer = measurementLayer;
this.snappedPoints = points;
}
@Override
public boolean execute() {
measurementLayer.getSnappedToRoadPoints().clear();
measurementLayer.getSnappedToRoadPoints().addAll(snappedPoints);
measurementLayer.refreshMap();
return true;
}
@Override
public void undo() {
measurementLayer.getSnappedToRoadPoints().clear();
measurementLayer.refreshMap();
}
@Override
public void redo() {
measurementLayer.getSnappedToRoadPoints().addAll(snappedPoints);
measurementLayer.refreshMap();
}
@Override
MeasurementCommandType getType() {
return MeasurementCommandType.SNAP_TO_ROAD;
}
}

View file

@ -124,6 +124,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment {
private View currentGpxView; private View currentGpxView;
private View footerView; private View footerView;
private boolean importing = false; private boolean importing = false;
private View emptyView;
@Override @Override
public void onAttach(Context activity) { public void onAttach(Context activity) {
@ -327,6 +328,16 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment {
} }
footerView = inflater.inflate(R.layout.list_shadow_footer, null, false); footerView = inflater.inflate(R.layout.list_shadow_footer, null, false);
listView.addFooterView(footerView); listView.addFooterView(footerView);
emptyView = v.findViewById(android.R.id.empty);
ImageView emptyImageView = (ImageView) emptyView.findViewById(R.id.empty_state_image_view);
emptyImageView.setImageResource(app.getSettings().isLightContent() ? R.drawable.ic_empty_state_trip_day_result : R.drawable.ic_empty_state_trip_night_result);
Button importButton = (Button) emptyView.findViewById(R.id.import_button);
importButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
addTrack();
}
});
if (this.adapter != null) { if (this.adapter != null) {
listView.setAdapter(this.adapter); listView.setAdapter(this.adapter);
} }
@ -1597,6 +1608,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment {
@Override @Override
protected void onPostExecute(Void aVoid) { protected void onPostExecute(Void aVoid) {
asyncProcessor = null; asyncProcessor = null;
listView.setEmptyView(emptyView);
} }
} }

View file

@ -41,6 +41,10 @@ import java.util.List;
public class FavoritesActivity extends TabActivity { public class FavoritesActivity extends TabActivity {
private static final int OPEN_GPX_DOCUMENT_REQUEST = 1006; private static final int OPEN_GPX_DOCUMENT_REQUEST = 1006;
private static final int IMPORT_FAVOURITES_REQUEST = 1007;
public static final String OPEN_FAVOURITES_TAB = "open_favourites_tab";
public static final String OPEN_MY_PLACES_TAB = "open_my_places_tab";
public static final int GPX_TAB = R.string.shared_string_my_tracks; public static final int GPX_TAB = R.string.shared_string_my_tracks;
public static final int FAV_TAB = R.string.shared_string_my_favorites; public static final int FAV_TAB = R.string.shared_string_my_favorites;
@ -67,6 +71,16 @@ public class FavoritesActivity extends TabActivity {
List<TabItem> mTabs = getTabItems(); List<TabItem> mTabs = getTabItems();
setTabs(mTabs); setTabs(mTabs);
// setupHomeButton(); // setupHomeButton();
ViewPager mViewPager = (ViewPager) findViewById(R.id.pager);
Intent intent = getIntent();
if (intent != null) {
if (intent.hasExtra(OPEN_FAVOURITES_TAB) && intent.getBooleanExtra(OPEN_FAVOURITES_TAB, false)) {
mViewPager.setCurrentItem(0, false);
} else if (intent.hasExtra(OPEN_MY_PLACES_TAB) && intent.getBooleanExtra(OPEN_MY_PLACES_TAB, false)) {
mViewPager.setCurrentItem(1, false);
}
}
} }
@TargetApi(Build.VERSION_CODES.KITKAT) @TargetApi(Build.VERSION_CODES.KITKAT)
@ -76,6 +90,13 @@ public class FavoritesActivity extends TabActivity {
startActivityForResult(intent, OPEN_GPX_DOCUMENT_REQUEST); startActivityForResult(intent, OPEN_GPX_DOCUMENT_REQUEST);
} }
@TargetApi(Build.VERSION_CODES.KITKAT)
public void importFavourites() {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.setType("*/*");
startActivityForResult(intent, IMPORT_FAVOURITES_REQUEST);
}
@Override @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == OPEN_GPX_DOCUMENT_REQUEST && resultCode == Activity.RESULT_OK) { if (requestCode == OPEN_GPX_DOCUMENT_REQUEST && resultCode == Activity.RESULT_OK) {
@ -101,6 +122,11 @@ public class FavoritesActivity extends TabActivity {
} }
} }
} }
} else if (requestCode == IMPORT_FAVOURITES_REQUEST && resultCode == Activity.RESULT_OK) {
if (data != null) {
Uri uri = data.getData();
gpxImportHelper.handleFavouritesImport(uri);
}
} else { } else {
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);
} }
@ -135,22 +161,9 @@ public class FavoritesActivity extends TabActivity {
} }
private List<TabItem> getTabItems() { private List<TabItem> getTabItems() {
File[] lf = ((OsmandApplication) getApplication()).getAppPath(IndexConstants.GPX_INDEX_DIR).listFiles();
boolean hasGpx = false;
if (lf != null) {
for (File t : lf) {
if (t.isDirectory() || (t.getName().toLowerCase().endsWith(".gpx"))) {
hasGpx = true;
break;
}
}
}
List<TabItem> mTabs = new ArrayList<>(); List<TabItem> mTabs = new ArrayList<>();
mTabs.add(getTabIndicator(FAV_TAB, FavoritesTreeFragment.class)); mTabs.add(getTabIndicator(FAV_TAB, FavoritesTreeFragment.class));
if (hasGpx) { mTabs.add(getTabIndicator(GPX_TAB, AvailableGPXFragment.class));
mTabs.add(getTabIndicator(GPX_TAB, AvailableGPXFragment.class));
}
OsmandPlugin.addMyPlacesTabPlugins(this, mTabs, getIntent()); OsmandPlugin.addMyPlacesTabPlugins(this, mTabs, getIntent());
return mTabs; return mTabs;
} }

View file

@ -57,7 +57,7 @@ import net.osmand.plus.activities.TrackActivity;
import net.osmand.plus.base.FavoriteImageDrawable; import net.osmand.plus.base.FavoriteImageDrawable;
import net.osmand.plus.base.OsmandExpandableListFragment; import net.osmand.plus.base.OsmandExpandableListFragment;
import net.osmand.plus.dialogs.DirectionsDialogs; import net.osmand.plus.dialogs.DirectionsDialogs;
import net.osmand.plus.views.AddGpxPointBottomSheetHelper.NewGpxPoint; import net.osmand.plus.measurementtool.NewGpxData;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import java.io.File; import java.io.File;
@ -99,6 +99,9 @@ public class TrackPointFragment extends OsmandExpandableListFragment {
private View waypointTextLayout; private View waypointTextLayout;
private FloatingActionButton routePointFab; private FloatingActionButton routePointFab;
private View routePointTextLayout; private View routePointTextLayout;
private FloatingActionButton lineFab;
private View lineTextLayout;
private View overlayView;
@Override @Override
public void onCreate(@Nullable Bundle savedInstanceState) { public void onCreate(@Nullable Bundle savedInstanceState) {
@ -114,6 +117,7 @@ public class TrackPointFragment extends OsmandExpandableListFragment {
public void onScrollStateChanged(AbsListView absListView, int i) { public void onScrollStateChanged(AbsListView absListView, int i) {
if (i == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) { if (i == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
if (menuOpened) { if (menuOpened) {
hideTransparentOverlay();
closeMenu(); closeMenu();
} }
} }
@ -128,43 +132,74 @@ public class TrackPointFragment extends OsmandExpandableListFragment {
: R.color.ctx_menu_info_view_bg_dark)); : R.color.ctx_menu_info_view_bg_dark));
} }
private void hideTransparentOverlay() {
overlayView.setVisibility(View.GONE);
}
private void showTransparentOverlay() {
overlayView.setVisibility(View.VISIBLE);
}
private View.OnClickListener onFabClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.overlay_view:
hideTransparentOverlay();
closeMenu();
break;
case R.id.menu_fab:
if (menuOpened) {
hideTransparentOverlay();
closeMenu();
} else {
showTransparentOverlay();
openMenu();
}
break;
case R.id.waypoint_text_layout:
case R.id.waypoint_fab:
PointDescription pointWptDescription = new PointDescription(PointDescription.POINT_TYPE_WPT, getString(R.string.add_waypoint));
addPoint(pointWptDescription);
break;
case R.id.route_text_layout:
case R.id.route_fab:
addNewGpxData(NewGpxData.ActionType.ADD_ROUTE_POINTS);
break;
case R.id.line_text_layout:
case R.id.line_fab:
addNewGpxData(NewGpxData.ActionType.ADD_SEGMENT);
break;
}
}
};
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.points_tree, container, false); View view = inflater.inflate(R.layout.track_points_tree, container, false);
ExpandableListView listView = (ExpandableListView) view.findViewById(android.R.id.list); ExpandableListView listView = (ExpandableListView) view.findViewById(android.R.id.list);
setHasOptionsMenu(true); setHasOptionsMenu(true);
overlayView = view.findViewById(R.id.overlay_view);
overlayView.setOnClickListener(onFabClickListener);
menuFab = (FloatingActionButton) view.findViewById(R.id.menu_fab); menuFab = (FloatingActionButton) view.findViewById(R.id.menu_fab);
menuFab.setOnClickListener(new View.OnClickListener() { menuFab.setOnClickListener(onFabClickListener);
@Override
public void onClick(View view) {
if (menuOpened) {
closeMenu();
} else {
openMenu();
}
}
});
waypointFab = (FloatingActionButton) view.findViewById(R.id.waypoint_fab); waypointFab = (FloatingActionButton) view.findViewById(R.id.waypoint_fab);
waypointFab.setOnClickListener(new View.OnClickListener() { waypointFab.setOnClickListener(onFabClickListener);
@Override
public void onClick(View view) {
PointDescription pointDescription = new PointDescription(PointDescription.POINT_TYPE_WPT, getString(R.string.add_waypoint));
addPoint(pointDescription);
}
});
waypointTextLayout = view.findViewById(R.id.waypoint_text_layout); waypointTextLayout = view.findViewById(R.id.waypoint_text_layout);
waypointTextLayout.setOnClickListener(onFabClickListener);
routePointFab = (FloatingActionButton) view.findViewById(R.id.route_fab); routePointFab = (FloatingActionButton) view.findViewById(R.id.route_fab);
routePointFab.setOnClickListener(new View.OnClickListener() { routePointFab.setOnClickListener(onFabClickListener);
@Override
public void onClick(View view) {
PointDescription pointDescription = new PointDescription(PointDescription.POINT_TYPE_RTE, getString(R.string.add_route_point));
addPoint(pointDescription);
}
});
routePointTextLayout = view.findViewById(R.id.route_text_layout); routePointTextLayout = view.findViewById(R.id.route_text_layout);
routePointTextLayout.setOnClickListener(onFabClickListener);
lineFab = (FloatingActionButton) view.findViewById(R.id.line_fab);
lineFab.setOnClickListener(onFabClickListener);
lineTextLayout = view.findViewById(R.id.line_text_layout);
lineTextLayout.setOnClickListener(onFabClickListener);
TextView tv = new TextView(getActivity()); TextView tv = new TextView(getActivity());
tv.setText(R.string.none_selected_gpx); tv.setText(R.string.none_selected_gpx);
@ -178,22 +213,11 @@ public class TrackPointFragment extends OsmandExpandableListFragment {
} }
private void addPoint(PointDescription pointDescription) { private void addPoint(PointDescription pointDescription) {
Intent currentIntent = getTrackActivity().getIntent(); getTrackActivity().addPoint(pointDescription);
if (currentIntent != null) { }
currentIntent.putExtra(TrackActivity.OPEN_POINTS_TAB, true);
}
final OsmandSettings settings = app.getSettings();
GPXFile gpx = getGpx();
LatLon location = settings.getLastKnownMapLocation();
if (gpx != null && location != null) {
settings.setMapLocationToShow(location.getLatitude(), location.getLongitude(),
settings.getLastKnownMapZoom(),
pointDescription,
false,
new NewGpxPoint(gpx, pointDescription));
MapActivity.launchMapActivityMoveToTop(getActivity()); private void addNewGpxData(NewGpxData.ActionType actionType) {
} getTrackActivity().addNewGpxData(actionType);
} }
private void openMenu() { private void openMenu() {
@ -202,6 +226,8 @@ public class TrackPointFragment extends OsmandExpandableListFragment {
waypointTextLayout.setVisibility(View.VISIBLE); waypointTextLayout.setVisibility(View.VISIBLE);
routePointFab.setVisibility(View.VISIBLE); routePointFab.setVisibility(View.VISIBLE);
routePointTextLayout.setVisibility(View.VISIBLE); routePointTextLayout.setVisibility(View.VISIBLE);
lineFab.setVisibility(View.VISIBLE);
lineTextLayout.setVisibility(View.VISIBLE);
menuOpened = true; menuOpened = true;
} }
@ -211,6 +237,8 @@ public class TrackPointFragment extends OsmandExpandableListFragment {
waypointTextLayout.setVisibility(View.GONE); waypointTextLayout.setVisibility(View.GONE);
routePointFab.setVisibility(View.GONE); routePointFab.setVisibility(View.GONE);
routePointTextLayout.setVisibility(View.GONE); routePointTextLayout.setVisibility(View.GONE);
lineFab.setVisibility(View.GONE);
lineTextLayout.setVisibility(View.GONE);
menuOpened = false; menuOpened = false;
} }

View file

@ -1,6 +1,7 @@
package net.osmand.plus.myplaces; package net.osmand.plus.myplaces;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
@ -17,10 +18,12 @@ import android.os.Handler;
import android.support.annotation.ColorInt; import android.support.annotation.ColorInt;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.support.v4.view.MenuItemCompat; import android.support.v4.view.MenuItemCompat;
import android.support.v4.view.PagerAdapter; import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewCompat; import android.support.v4.view.ViewCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.ListPopupWindow; import android.support.v7.widget.ListPopupWindow;
import android.support.v7.widget.SwitchCompat; import android.support.v7.widget.SwitchCompat;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
@ -34,6 +37,7 @@ import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.AbsListView;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.CompoundButton; import android.widget.CompoundButton;
@ -62,7 +66,6 @@ import net.osmand.plus.GPXDatabase.GpxDataItem;
import net.osmand.plus.GPXUtilities; import net.osmand.plus.GPXUtilities;
import net.osmand.plus.GPXUtilities.GPXFile; import net.osmand.plus.GPXUtilities.GPXFile;
import net.osmand.plus.GPXUtilities.GPXTrackAnalysis; import net.osmand.plus.GPXUtilities.GPXTrackAnalysis;
import net.osmand.plus.GPXUtilities.Route;
import net.osmand.plus.GPXUtilities.Track; import net.osmand.plus.GPXUtilities.Track;
import net.osmand.plus.GPXUtilities.TrkSegment; import net.osmand.plus.GPXUtilities.TrkSegment;
import net.osmand.plus.GPXUtilities.WptPt; import net.osmand.plus.GPXUtilities.WptPt;
@ -86,6 +89,7 @@ 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.GPXDataSetType;
import net.osmand.plus.helpers.GpxUiHelper.OrderedLineDataSet; import net.osmand.plus.helpers.GpxUiHelper.OrderedLineDataSet;
import net.osmand.plus.measurementtool.NewGpxData;
import net.osmand.plus.render.MapRenderRepositories; import net.osmand.plus.render.MapRenderRepositories;
import net.osmand.plus.resources.AsyncLoadingThread; import net.osmand.plus.resources.AsyncLoadingThread;
import net.osmand.plus.resources.ResourceManager; import net.osmand.plus.resources.ResourceManager;
@ -95,6 +99,7 @@ import net.osmand.plus.views.controls.PagerSlidingTabStrip;
import net.osmand.plus.views.controls.PagerSlidingTabStrip.CustomTabProvider; import net.osmand.plus.views.controls.PagerSlidingTabStrip.CustomTabProvider;
import net.osmand.plus.views.controls.WrapContentHeightViewPager; import net.osmand.plus.views.controls.WrapContentHeightViewPager;
import net.osmand.plus.views.controls.WrapContentHeightViewPager.ViewAtPositionInterface; import net.osmand.plus.views.controls.WrapContentHeightViewPager.ViewAtPositionInterface;
import net.osmand.plus.widgets.IconPopupMenu;
import net.osmand.render.RenderingRulesStorage; import net.osmand.render.RenderingRulesStorage;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -134,11 +139,22 @@ public class TrackSegmentFragment extends OsmAndListFragment {
private int defPointColor; private int defPointColor;
private Paint paintIcon; private Paint paintIcon;
private Bitmap pointSmall; private Bitmap pointSmall;
private SwitchCompat vis;
private ImageView imageView; private ImageView imageView;
private RotatedTileBox rotatedTileBox; private RotatedTileBox rotatedTileBox;
private Bitmap mapBitmap; private Bitmap mapBitmap;
private Bitmap mapTrackBitmap; private Bitmap mapTrackBitmap;
private boolean chartClicked;
private boolean menuOpened = false;
private FloatingActionButton menuFab;
private FloatingActionButton waypointFab;
private View waypointTextLayout;
private FloatingActionButton routePointFab;
private View routePointTextLayout;
private FloatingActionButton lineFab;
private View lineTextLayout;
private View overlayView;
@Override @Override
public void onCreate(@Nullable Bundle savedInstanceState) { public void onCreate(@Nullable Bundle savedInstanceState) {
@ -149,16 +165,72 @@ public class TrackSegmentFragment extends OsmAndListFragment {
@Override @Override
public void onActivityCreated(Bundle savedInstanceState) { public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState); super.onActivityCreated(savedInstanceState);
getListView().setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView absListView, int i) {
if (i == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
if (menuOpened) {
hideTransparentOverlay();
closeMenu();
}
}
}
@Override
public void onScroll(AbsListView absListView, int i, int i1, int i2) {
}
});
getListView().setBackgroundColor(getResources().getColor( getListView().setBackgroundColor(getResources().getColor(
getMyApplication().getSettings().isLightContent() ? R.color.ctx_menu_info_view_bg_light getMyApplication().getSettings().isLightContent() ? R.color.ctx_menu_info_view_bg_light
: R.color.ctx_menu_info_view_bg_dark)); : R.color.ctx_menu_info_view_bg_dark));
} }
private void hideTransparentOverlay() {
overlayView.setVisibility(View.GONE);
}
private void showTransparentOverlay() {
overlayView.setVisibility(View.VISIBLE);
}
private View.OnClickListener onFabClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.overlay_view:
hideTransparentOverlay();
closeMenu();
break;
case R.id.menu_fab:
if (menuOpened) {
hideTransparentOverlay();
closeMenu();
} else {
showTransparentOverlay();
openMenu();
}
break;
case R.id.waypoint_text_layout:
case R.id.waypoint_fab:
PointDescription pointWptDescription = new PointDescription(PointDescription.POINT_TYPE_WPT, getString(R.string.add_waypoint));
addPoint(pointWptDescription);
break;
case R.id.route_text_layout:
case R.id.route_fab:
addNewGpxData(NewGpxData.ActionType.ADD_ROUTE_POINTS);
break;
case R.id.line_text_layout:
case R.id.line_fab:
addNewGpxData(NewGpxData.ActionType.ADD_SEGMENT);
break;
}
}
};
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
setHasOptionsMenu(true); setHasOptionsMenu(true);
View view = getActivity().getLayoutInflater().inflate(R.layout.update_index, container, false); View view = getActivity().getLayoutInflater().inflate(R.layout.track_segments_tree, container, false);
view.findViewById(R.id.header_layout).setVisibility(View.GONE);
ListView listView = (ListView) view.findViewById(android.R.id.list); ListView listView = (ListView) view.findViewById(android.R.id.list);
listView.setDivider(null); listView.setDivider(null);
@ -169,6 +241,27 @@ public class TrackSegmentFragment extends OsmAndListFragment {
tv.setTextSize(24); tv.setTextSize(24);
listView.setEmptyView(tv); listView.setEmptyView(tv);
overlayView = view.findViewById(R.id.overlay_view);
overlayView.setOnClickListener(onFabClickListener);
menuFab = (FloatingActionButton) view.findViewById(R.id.menu_fab);
menuFab.setOnClickListener(onFabClickListener);
waypointFab = (FloatingActionButton) view.findViewById(R.id.waypoint_fab);
waypointFab.setOnClickListener(onFabClickListener);
waypointTextLayout = view.findViewById(R.id.waypoint_text_layout);
waypointTextLayout.setOnClickListener(onFabClickListener);
routePointFab = (FloatingActionButton) view.findViewById(R.id.route_fab);
routePointFab.setOnClickListener(onFabClickListener);
routePointTextLayout = view.findViewById(R.id.route_text_layout);
routePointTextLayout.setOnClickListener(onFabClickListener);
lineFab = (FloatingActionButton) view.findViewById(R.id.line_fab);
lineFab.setOnClickListener(onFabClickListener);
lineTextLayout = view.findViewById(R.id.line_text_layout);
lineTextLayout.setOnClickListener(onFabClickListener);
paint = new Paint(); paint = new Paint();
paint.setStyle(Paint.Style.STROKE); paint.setStyle(Paint.Style.STROKE);
paint.setAntiAlias(true); paint.setAntiAlias(true);
@ -182,11 +275,50 @@ public class TrackSegmentFragment extends OsmAndListFragment {
headerView = getActivity().getLayoutInflater().inflate(R.layout.gpx_item_list_header, null, false); headerView = getActivity().getLayoutInflater().inflate(R.layout.gpx_item_list_header, null, false);
listView.addHeaderView(headerView); listView.addHeaderView(headerView);
listView.addFooterView(getActivity().getLayoutInflater().inflate(R.layout.list_shadow_footer, null, false)); listView.addFooterView(getActivity().getLayoutInflater().inflate(R.layout.list_shadow_footer, null, false));
View emptyView = new View(getActivity());
emptyView.setLayoutParams(new AbsListView.LayoutParams(
AbsListView.LayoutParams.MATCH_PARENT,
AndroidUtils.dpToPx(getActivity(), 72)));
listView.addFooterView(emptyView);
updateHeader(); updateHeader();
setListAdapter(adapter); setListAdapter(adapter);
return view; return view;
} }
private void addPoint(PointDescription pointDescription) {
getTrackActivity().addPoint(pointDescription);
}
private void addNewGpxData(NewGpxData.ActionType actionType) {
getTrackActivity().addNewGpxData(actionType);
}
private void addNewGpxData(NewGpxData.ActionType actionType, TrkSegment segment) {
getTrackActivity().addNewGpxData(actionType, segment);
}
private void openMenu() {
menuFab.setImageDrawable(ContextCompat.getDrawable(getContext(), R.drawable.ic_action_remove_dark));
waypointFab.setVisibility(View.VISIBLE);
waypointTextLayout.setVisibility(View.VISIBLE);
routePointFab.setVisibility(View.VISIBLE);
routePointTextLayout.setVisibility(View.VISIBLE);
lineFab.setVisibility(View.VISIBLE);
lineTextLayout.setVisibility(View.VISIBLE);
menuOpened = true;
}
private void closeMenu() {
menuFab.setImageDrawable(ContextCompat.getDrawable(getContext(), R.drawable.ic_action_plus));
waypointFab.setVisibility(View.GONE);
waypointTextLayout.setVisibility(View.GONE);
routePointFab.setVisibility(View.GONE);
routePointTextLayout.setVisibility(View.GONE);
lineFab.setVisibility(View.GONE);
lineTextLayout.setVisibility(View.GONE);
menuOpened = false;
}
public TrackActivity getTrackActivity() { public TrackActivity getTrackActivity() {
return (TrackActivity) getActivity(); return (TrackActivity) getActivity();
} }
@ -312,7 +444,7 @@ public class TrackSegmentFragment extends OsmAndListFragment {
final View divider = headerView.findViewById(R.id.divider); final View divider = headerView.findViewById(R.id.divider);
final View splitIntervalView = headerView.findViewById(R.id.split_interval_view); final View splitIntervalView = headerView.findViewById(R.id.split_interval_view);
final View colorView = headerView.findViewById(R.id.color_view); final View colorView = headerView.findViewById(R.id.color_view);
final SwitchCompat vis = (SwitchCompat) headerView.findViewById(R.id.showOnMapToggle); vis = (SwitchCompat) headerView.findViewById(R.id.showOnMapToggle);
final ProgressBar progressBar = (ProgressBar) headerView.findViewById(R.id.mapLoadProgress); final ProgressBar progressBar = (ProgressBar) headerView.findViewById(R.id.mapLoadProgress);
final boolean selected = getGpx() != null && final boolean selected = getGpx() != null &&
((getGpx().showCurrentTrack && app.getSelectedGpxHelper().getSelectedCurrentRecordingTrack() != null) || ((getGpx().showCurrentTrack && app.getSelectedGpxHelper().getSelectedCurrentRecordingTrack() != null) ||
@ -598,56 +730,7 @@ public class TrackSegmentFragment extends OsmAndListFragment {
} }
private QuadRect getRect() { private QuadRect getRect() {
double left = 0, right = 0; return getTrackActivity().getRect();
double top = 0, bottom = 0;
if (getGpx() != null) {
for (Track track : getGpx().tracks) {
for (TrkSegment segment : track.segments) {
for (WptPt p : segment.points) {
if (left == 0 && right == 0) {
left = p.getLongitude();
right = p.getLongitude();
top = p.getLatitude();
bottom = p.getLatitude();
} else {
left = Math.min(left, p.getLongitude());
right = Math.max(right, p.getLongitude());
top = Math.max(top, p.getLatitude());
bottom = Math.min(bottom, p.getLatitude());
}
}
}
}
for (WptPt p : getGpx().points) {
if (left == 0 && right == 0) {
left = p.getLongitude();
right = p.getLongitude();
top = p.getLatitude();
bottom = p.getLatitude();
} else {
left = Math.min(left, p.getLongitude());
right = Math.max(right, p.getLongitude());
top = Math.max(top, p.getLatitude());
bottom = Math.min(bottom, p.getLatitude());
}
}
for (Route route : getGpx().routes) {
for (WptPt p : route.points) {
if (left == 0 && right == 0) {
left = p.getLongitude();
right = p.getLongitude();
top = p.getLatitude();
bottom = p.getLatitude();
} else {
left = Math.min(left, p.getLongitude());
right = Math.max(right, p.getLongitude());
top = Math.max(top, p.getLatitude());
bottom = Math.min(bottom, p.getLatitude());
}
}
}
}
return new QuadRect(left, top, right, bottom);
} }
private List<GpxDisplayGroup> getOriginalGroups() { private List<GpxDisplayGroup> getOriginalGroups() {
@ -1073,6 +1156,7 @@ public class TrackSegmentFragment extends OsmAndListFragment {
@Override @Override
public Object instantiateItem(ViewGroup container, int position) { public Object instantiateItem(ViewGroup container, int position) {
chartClicked = false;
GPXTabItemType tabType = tabTypes[position]; GPXTabItemType tabType = tabTypes[position];
View view = null; View view = null;
switch (tabType) { switch (tabType) {
@ -1091,107 +1175,117 @@ public class TrackSegmentFragment extends OsmAndListFragment {
if (gpxItem != null) { if (gpxItem != null) {
GPXTrackAnalysis analysis = gpxItem.analysis; GPXTrackAnalysis analysis = gpxItem.analysis;
final LineChart chart = (LineChart) view.findViewById(R.id.chart); final LineChart chart = (LineChart) view.findViewById(R.id.chart);
chart.setOnTouchListener(new View.OnTouchListener() { chart.setHighlightPerDragEnabled(false);
chart.setOnClickListener(new View.OnClickListener() {
@Override @Override
public boolean onTouch(View v, MotionEvent event) { public void onClick(View view) {
getListView().requestDisallowInterceptTouchEvent(true); if (!chartClicked) {
switch (event.getAction()) { chartClicked = true;
case android.view.MotionEvent.ACTION_DOWN: chart.setHighlightPerDragEnabled(true);
listViewYPos = event.getRawY(); chart.setOnTouchListener(new View.OnTouchListener() {
break; @Override
case android.view.MotionEvent.ACTION_MOVE: public boolean onTouch(View v, MotionEvent event) {
scrollBy(Math.round(listViewYPos - event.getRawY())); getListView().requestDisallowInterceptTouchEvent(true);
listViewYPos = event.getRawY(); switch (event.getAction()) {
break; case android.view.MotionEvent.ACTION_DOWN:
} listViewYPos = event.getRawY();
return false; break;
} case android.view.MotionEvent.ACTION_MOVE:
}); scrollBy(Math.round(listViewYPos - event.getRawY()));
chart.setOnChartValueSelectedListener(new OnChartValueSelectedListener() { listViewYPos = event.getRawY();
@Override break;
public void onValueSelected(Entry e, Highlight h) { }
WptPt wpt = getPoint(chart, h.getX()); return false;
if (wpt != null) {
selectedPointLatLon = new LatLon(wpt.lat, wpt.lon);
Bitmap bmp = drawSelectedPoint();
imageView.setImageDrawable(new BitmapDrawable(app.getResources(), bmp));
}
}
@Override
public void onNothingSelected() {
}
});
final View finalView = view;
chart.setOnChartGestureListener(new OnChartGestureListener() {
float highlightDrawX = -1;
@Override
public void onChartGestureStart(MotionEvent me, ChartGesture lastPerformedGesture) {
if (chart.getHighlighted() != null && chart.getHighlighted().length > 0) {
highlightDrawX = chart.getHighlighted()[0].getDrawX();
} else {
highlightDrawX = -1;
}
}
@Override
public void onChartGestureEnd(MotionEvent me, ChartGesture lastPerformedGesture) {
gpxItem.chartMatrix = new Matrix(chart.getViewPortHandler().getMatrixTouch());
Highlight[] highlights = chart.getHighlighted();
if (highlights != null && highlights.length > 0) {
gpxItem.chartHighlightPos = highlights[0].getX();
} else {
gpxItem.chartHighlightPos = -1;
}
for (int i = 0; i < getCount(); i++) {
View v = getViewAtPosition(i);
if (v != finalView) {
updateChart(i);
}
}
}
@Override
public void onChartLongPressed(MotionEvent me) {
}
@Override
public void onChartDoubleTapped(MotionEvent me) {
}
@Override
public void onChartSingleTapped(MotionEvent me) {
}
@Override
public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY) {
}
@Override
public void onChartScale(MotionEvent me, float scaleX, float scaleY) {
}
@Override
public void onChartTranslate(MotionEvent me, float dX, float dY) {
if (highlightDrawX != -1) {
Highlight h = chart.getHighlightByTouchPoint(highlightDrawX, 0f);
if (h != null) {
chart.highlightValue(h);
WptPt wpt = getPoint(chart, h.getX());
if (wpt != null) {
selectedPointLatLon = new LatLon(wpt.lat, wpt.lon);
Bitmap bmp = drawSelectedPoint();
imageView.setImageDrawable(new BitmapDrawable(app.getResources(), bmp));
} }
} });
chart.setOnChartValueSelectedListener(new OnChartValueSelectedListener() {
@Override
public void onValueSelected(Entry e, Highlight h) {
WptPt wpt = getPoint(chart, h.getX());
if (wpt != null) {
selectedPointLatLon = new LatLon(wpt.lat, wpt.lon);
Bitmap bmp = drawSelectedPoint();
imageView.setImageDrawable(new BitmapDrawable(app.getResources(), bmp));
}
}
@Override
public void onNothingSelected() {
}
});
final View finalView = view;
chart.setOnChartGestureListener(new OnChartGestureListener() {
float highlightDrawX = -1;
@Override
public void onChartGestureStart(MotionEvent me, ChartGesture lastPerformedGesture) {
if (chart.getHighlighted() != null && chart.getHighlighted().length > 0) {
highlightDrawX = chart.getHighlighted()[0].getDrawX();
} else {
highlightDrawX = -1;
}
}
@Override
public void onChartGestureEnd(MotionEvent me, ChartGesture lastPerformedGesture) {
gpxItem.chartMatrix = new Matrix(chart.getViewPortHandler().getMatrixTouch());
Highlight[] highlights = chart.getHighlighted();
if (highlights != null && highlights.length > 0) {
gpxItem.chartHighlightPos = highlights[0].getX();
} else {
gpxItem.chartHighlightPos = -1;
}
for (int i = 0; i < getCount(); i++) {
View v = getViewAtPosition(i);
if (v != finalView) {
updateChart(i);
}
}
}
@Override
public void onChartLongPressed(MotionEvent me) {
}
@Override
public void onChartDoubleTapped(MotionEvent me) {
}
@Override
public void onChartSingleTapped(MotionEvent me) {
}
@Override
public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY) {
}
@Override
public void onChartScale(MotionEvent me, float scaleX, float scaleY) {
}
@Override
public void onChartTranslate(MotionEvent me, float dX, float dY) {
if (highlightDrawX != -1) {
Highlight h = chart.getHighlightByTouchPoint(highlightDrawX, 0f);
if (h != null) {
chart.highlightValue(h);
WptPt wpt = getPoint(chart, h.getX());
if (wpt != null) {
selectedPointLatLon = new LatLon(wpt.lat, wpt.lon);
Bitmap bmp = drawSelectedPoint();
imageView.setImageDrawable(new BitmapDrawable(app.getResources(), bmp));
}
}
}
}
});
} }
} }
}); });
IconsCache ic = app.getIconsCache(); final IconsCache ic = app.getIconsCache();
switch (tabType) { switch (tabType) {
case GPX_TAB_ITEM_GENERAL: case GPX_TAB_ITEM_GENERAL:
if (analysis != null) { if (analysis != null) {
@ -1254,6 +1348,55 @@ public class TrackSegmentFragment extends OsmAndListFragment {
} }
}); });
} }
if (!gpxItem.group.getTrack().generalTrack) {
((ImageView) view.findViewById(R.id.overflow_menu)).setImageDrawable(ic.getThemedIcon(R.drawable.ic_overflow_menu_dark));
view.findViewById(R.id.overflow_menu).setVisibility(View.VISIBLE);
view.findViewById(R.id.overflow_menu).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
IconPopupMenu popupMenu = new IconPopupMenu(getTrackActivity(), view.findViewById(R.id.overflow_menu));
Menu menu = popupMenu.getMenu();
popupMenu.getMenuInflater().inflate(R.menu.track_segment_menu, menu);
menu.findItem(R.id.action_edit).setIcon(ic.getThemedIcon(R.drawable.ic_action_edit_dark));
menu.findItem(R.id.action_delete).setIcon(ic.getThemedIcon(R.drawable.ic_action_remove_dark));
popupMenu.setOnMenuItemClickListener(new IconPopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_edit:
TrkSegment segment = getTrkSegment();
if (segment != null) {
addNewGpxData(NewGpxData.ActionType.EDIT_SEGMENT, segment);
}
return true;
case R.id.action_delete:
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(R.string.recording_delete_confirm);
builder.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (deleteSegment()) {
GPXFile gpx = getGpx();
if (gpx != null) {
SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(gpx, vis.isChecked(), false);
new SaveGpxAsyncTask(gpx, vis.isChecked() ? sf : null).execute();
}
}
}
});
builder.setNegativeButton(R.string.shared_string_cancel, null);
builder.show();
return true;
}
return false;
}
});
popupMenu.show();
}
});
} else {
view.findViewById(R.id.overflow_menu).setVisibility(View.GONE);
}
break; break;
case GPX_TAB_ITEM_ALTITUDE: case GPX_TAB_ITEM_ALTITUDE:
@ -1308,6 +1451,46 @@ public class TrackSegmentFragment extends OsmAndListFragment {
} }
}); });
} }
if (!gpxItem.group.getTrack().generalTrack) {
((ImageView) view.findViewById(R.id.overflow_menu)).setImageDrawable(ic.getThemedIcon(R.drawable.ic_overflow_menu_dark));
view.findViewById(R.id.overflow_menu).setVisibility(View.VISIBLE);
view.findViewById(R.id.overflow_menu).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
IconPopupMenu popupMenu = new IconPopupMenu(getTrackActivity(), view.findViewById(R.id.overflow_menu));
Menu menu = popupMenu.getMenu();
popupMenu.getMenuInflater().inflate(R.menu.track_segment_menu, menu);
menu.findItem(R.id.action_edit).setIcon(ic.getThemedIcon(R.drawable.ic_action_edit_dark));
menu.findItem(R.id.action_delete).setIcon(ic.getThemedIcon(R.drawable.ic_action_remove_dark));
popupMenu.setOnMenuItemClickListener(new IconPopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_edit:
TrkSegment segment = getTrkSegment();
if (segment != null) {
addNewGpxData(NewGpxData.ActionType.EDIT_SEGMENT, segment);
}
return true;
case R.id.action_delete:
if (deleteSegment()) {
GPXFile gpx = getGpx();
if (gpx != null) {
SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(gpx, vis.isChecked(), false);
new SaveGpxAsyncTask(gpx, vis.isChecked() ? sf : null).execute();
}
}
return true;
}
return false;
}
});
popupMenu.show();
}
});
} else {
view.findViewById(R.id.overflow_menu).setVisibility(View.GONE);
}
break; break;
case GPX_TAB_ITEM_SPEED: case GPX_TAB_ITEM_SPEED:
@ -1361,6 +1544,47 @@ public class TrackSegmentFragment extends OsmAndListFragment {
} }
}); });
} }
if (!gpxItem.group.getTrack().generalTrack) {
((ImageView) view.findViewById(R.id.overflow_menu)).setImageDrawable(ic.getThemedIcon(R.drawable.ic_overflow_menu_dark));
view.findViewById(R.id.overflow_menu).setVisibility(View.VISIBLE);
view.findViewById(R.id.overflow_menu).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
IconPopupMenu popupMenu = new IconPopupMenu(getTrackActivity(), view.findViewById(R.id.overflow_menu));
Menu menu = popupMenu.getMenu();
popupMenu.getMenuInflater().inflate(R.menu.track_segment_menu, menu);
menu.findItem(R.id.action_edit).setIcon(ic.getThemedIcon(R.drawable.ic_action_edit_dark));
menu.findItem(R.id.action_delete).setIcon(ic.getThemedIcon(R.drawable.ic_action_remove_dark));
popupMenu.setOnMenuItemClickListener(new IconPopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_edit:
TrkSegment segment = getTrkSegment();
if (segment != null) {
addNewGpxData(NewGpxData.ActionType.EDIT_SEGMENT, segment);
}
return true;
case R.id.action_delete:
if (deleteSegment()) {
GPXFile gpx = getGpx();
if (gpx != null) {
SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(gpx, vis.isChecked(), false);
new SaveGpxAsyncTask(gpx, vis.isChecked() ? sf : null).execute();
}
}
return true;
}
return false;
}
});
popupMenu.show();
}
});
} else {
view.findViewById(R.id.overflow_menu).setVisibility(View.GONE);
}
break; break;
} }
} }
@ -1371,6 +1595,17 @@ public class TrackSegmentFragment extends OsmAndListFragment {
return view; return view;
} }
private boolean deleteSegment() {
TrkSegment segment = getTrkSegment();
if (segment != null) {
GPXFile gpx = getGpx();
if (gpx != null) {
return gpx.removeTrkSegment(segment);
}
}
return false;
}
@Override @Override
public void destroyItem(ViewGroup collection, int position, Object view) { public void destroyItem(ViewGroup collection, int position, Object view) {
views.remove(position); views.remove(position);
@ -1463,6 +1698,17 @@ public class TrackSegmentFragment extends OsmAndListFragment {
} }
} }
private TrkSegment getTrkSegment() {
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)) {
return s;
}
}
}
return null;
}
void openAnalyzeOnMap(GPXTabItemType tabType) { void openAnalyzeOnMap(GPXTabItemType tabType) {
LatLon location = null; LatLon location = null;
WptPt wpt = null; WptPt wpt = null;
@ -1535,6 +1781,42 @@ public class TrackSegmentFragment extends OsmAndListFragment {
getTrackActivity().getSlidingTabLayout().setVisibility(View.GONE); getTrackActivity().getSlidingTabLayout().setVisibility(View.GONE);
} }
private class SaveGpxAsyncTask extends AsyncTask<Void, Void, Void> {
private final GPXFile mGpx;
private final SelectedGpxFile mSelectedGpx;
private final TrackActivity mActivity;
SaveGpxAsyncTask(GPXFile gpx, SelectedGpxFile selectedGpxFile) {
mGpx = gpx;
mActivity = getTrackActivity();
mSelectedGpx = selectedGpxFile;
}
@Override
protected void onPreExecute() {
mActivity.setSupportProgressBarIndeterminateVisibility(true);
}
@Override
protected Void doInBackground(Void... params) {
GPXUtilities.writeGpxFile(new File(mGpx.path), mGpx, app);
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
if (mSelectedGpx != null) {
List<GpxDisplayGroup> groups = getDisplayGroups();
mSelectedGpx.setDisplayGroups(groups);
mSelectedGpx.processPoints();
}
updateContent();
if (!mActivity.isFinishing()) {
mActivity.setSupportProgressBarIndeterminateVisibility(false);
}
}
}
private class SplitTrackAsyncTask extends AsyncTask<Void, Void, Void> { private class SplitTrackAsyncTask extends AsyncTask<Void, Void, Void> {
@Nullable @Nullable
private final SelectedGpxFile mSelectedGpxFile; private final SelectedGpxFile mSelectedGpxFile;

View file

@ -1,15 +1,16 @@
package net.osmand.plus.routing; package net.osmand.plus.routing;
import java.util.List;
import net.osmand.Location; import net.osmand.Location;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.plus.ApplicationMode; import net.osmand.plus.ApplicationMode;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.routing.RouteProvider.GPXRouteParams; import net.osmand.plus.routing.RouteProvider.GPXRouteParams;
import net.osmand.plus.routing.RouteProvider.RouteService; import net.osmand.plus.routing.RouteProvider.RouteService;
import net.osmand.plus.routing.RouteProvider.SnapToRoadParams;
import net.osmand.router.RouteCalculationProgress; import net.osmand.router.RouteCalculationProgress;
import java.util.List;
public class RouteCalculationParams { public class RouteCalculationParams {
public Location start; public Location start;
@ -21,6 +22,7 @@ public class RouteCalculationParams {
public ApplicationMode mode; public ApplicationMode mode;
public RouteService type; public RouteService type;
public GPXRouteParams gpxRoute; public GPXRouteParams gpxRoute;
public SnapToRoadParams snapToRoadParams;
public RouteCalculationResult previousToRecalculate; public RouteCalculationResult previousToRecalculate;
public boolean onlyStartPointChanged; public boolean onlyStartPointChanged;
public boolean fast; public boolean fast;

View file

@ -44,11 +44,13 @@ import net.osmand.plus.TargetPointsHelper.TargetPoint;
import net.osmand.plus.Version; import net.osmand.plus.Version;
import net.osmand.plus.activities.SettingsNavigationActivity; import net.osmand.plus.activities.SettingsNavigationActivity;
import net.osmand.plus.render.NativeOsmandLibrary; import net.osmand.plus.render.NativeOsmandLibrary;
import net.osmand.plus.routing.RoutingHelper.RouteCalculationProgressCallback;
import net.osmand.router.GeneralRouter; import net.osmand.router.GeneralRouter;
import net.osmand.router.GeneralRouter.GeneralRouterProfile; import net.osmand.router.GeneralRouter.GeneralRouterProfile;
import net.osmand.router.GeneralRouter.RoutingParameter; import net.osmand.router.GeneralRouter.RoutingParameter;
import net.osmand.router.GeneralRouter.RoutingParameterType; import net.osmand.router.GeneralRouter.RoutingParameterType;
import net.osmand.router.PrecalculatedRouteDirection; import net.osmand.router.PrecalculatedRouteDirection;
import net.osmand.router.RouteCalculationProgress;
import net.osmand.router.RoutePlannerFrontEnd; import net.osmand.router.RoutePlannerFrontEnd;
import net.osmand.router.RoutePlannerFrontEnd.RouteCalculationMode; import net.osmand.router.RoutePlannerFrontEnd.RouteCalculationMode;
import net.osmand.router.RouteSegmentResult; import net.osmand.router.RouteSegmentResult;
@ -282,6 +284,19 @@ public class RouteProvider {
} }
} }
public static class SnapToRoadParams {
public ApplicationMode applicationMode;
public RouteCalculationProgress calculationProgress;
public RouteCalculationProgressCallback calculationProgressCallback;
public SnapToRoadListener listener;
public List<Location> points;
public interface SnapToRoadListener {
void onSnapToRoadDone();
}
}
private static Location createLocation(WptPt pt){ private static Location createLocation(WptPt pt){
Location loc = new Location("OsmandRouteProvider"); Location loc = new Location("OsmandRouteProvider");
loc.setLatitude(pt.lat); loc.setLatitude(pt.lat);
@ -754,6 +769,9 @@ public class RouteProvider {
paramsR.put(key, vl); paramsR.put(key, vl);
} }
} }
if (params.snapToRoadParams != null) {
paramsR.put(GeneralRouter.ALLOW_PRIVATE, "true");
}
float mb = (1 << 20); float mb = (1 << 20);
Runtime rt = Runtime.getRuntime(); Runtime rt = Runtime.getRuntime();
// make visible // make visible

View file

@ -19,6 +19,7 @@ import net.osmand.plus.notifications.OsmandNotification.NotificationType;
import net.osmand.plus.routing.RouteCalculationResult.NextDirectionInfo; import net.osmand.plus.routing.RouteCalculationResult.NextDirectionInfo;
import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder; import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder;
import net.osmand.plus.routing.RouteProvider.RouteService; import net.osmand.plus.routing.RouteProvider.RouteService;
import net.osmand.plus.routing.RouteProvider.SnapToRoadParams;
import net.osmand.router.RouteCalculationProgress; import net.osmand.router.RouteCalculationProgress;
import net.osmand.router.RouteSegmentResult; import net.osmand.router.RouteSegmentResult;
import net.osmand.router.TurnType; import net.osmand.router.TurnType;
@ -33,38 +34,38 @@ import java.util.List;
import static net.osmand.plus.notifications.OsmandNotification.NotificationType.NAVIGATION; import static net.osmand.plus.notifications.OsmandNotification.NotificationType.NAVIGATION;
public class RoutingHelper { public class RoutingHelper {
private static final org.apache.commons.logging.Log log = PlatformUtil.getLog(RoutingHelper.class); private static final org.apache.commons.logging.Log log = PlatformUtil.getLog(RoutingHelper.class);
public interface IRouteInformationListener { public interface IRouteInformationListener {
void newRouteIsCalculated(boolean newRoute, ValueHolder<Boolean> showToast); void newRouteIsCalculated(boolean newRoute, ValueHolder<Boolean> showToast);
void routeWasCancelled(); void routeWasCancelled();
void routeWasFinished(); void routeWasFinished();
} }
private static final float POSITION_TOLERANCE = 60; private static final float POSITION_TOLERANCE = 60;
private List<WeakReference<IRouteInformationListener>> listeners = new LinkedList<WeakReference<IRouteInformationListener>>(); private List<WeakReference<IRouteInformationListener>> listeners = new LinkedList<WeakReference<IRouteInformationListener>>();
private OsmandApplication app; private OsmandApplication app;
private boolean isFollowingMode = false; private boolean isFollowingMode = false;
private boolean isRoutePlanningMode = false; private boolean isRoutePlanningMode = false;
private boolean isPauseNavigation = false; private boolean isPauseNavigation = false;
private GPXRouteParamsBuilder currentGPXRoute = null; private GPXRouteParamsBuilder currentGPXRoute = null;
private RouteCalculationResult route = new RouteCalculationResult(""); private RouteCalculationResult route = new RouteCalculationResult("");
private LatLon finalLocation; private LatLon finalLocation;
private List<LatLon> intermediatePoints; private List<LatLon> intermediatePoints;
private Location lastProjection; private Location lastProjection;
private Location lastFixedLocation; private Location lastFixedLocation;
private static final int RECALCULATE_THRESHOLD_COUNT_CAUSING_FULL_RECALCULATE = 3; private static final int RECALCULATE_THRESHOLD_COUNT_CAUSING_FULL_RECALCULATE = 3;
private static final int RECALCULATE_THRESHOLD_CAUSING_FULL_RECALCULATE_INTERVAL = 2*60*1000; private static final int RECALCULATE_THRESHOLD_CAUSING_FULL_RECALCULATE_INTERVAL = 2*60*1000;
private Thread currentRunningJob; private Thread currentRunningJob;
@ -73,10 +74,10 @@ public class RoutingHelper {
private String lastRouteCalcErrorShort; private String lastRouteCalcErrorShort;
private long recalculateCountInInterval = 0; private long recalculateCountInInterval = 0;
private int evalWaitInterval = 0; private int evalWaitInterval = 0;
private ApplicationMode mode; private ApplicationMode mode;
private OsmandSettings settings; private OsmandSettings settings;
private RouteProvider provider; private RouteProvider provider;
private VoiceRouter voiceRouter; private VoiceRouter voiceRouter;
@ -101,12 +102,12 @@ public class RoutingHelper {
provider = new RouteProvider(); provider = new RouteProvider();
setAppMode(settings.APPLICATION_MODE.get()); setAppMode(settings.APPLICATION_MODE.get());
} }
public boolean isFollowingMode() { public boolean isFollowingMode() {
return isFollowingMode; return isFollowingMode;
} }
public OsmandApplication getApplication() { public OsmandApplication getApplication() {
return app; return app;
} }
@ -132,11 +133,11 @@ public class RoutingHelper {
app.startNavigationService(NavigationService.USED_BY_NAVIGATION, 0); app.startNavigationService(NavigationService.USED_BY_NAVIGATION, 0);
} }
} }
public boolean isPauseNavigation() { public boolean isPauseNavigation() {
return isPauseNavigation; return isPauseNavigation;
} }
public void setFollowingMode(boolean follow) { public void setFollowingMode(boolean follow) {
isFollowingMode = follow; isFollowingMode = follow;
isPauseNavigation = false; isPauseNavigation = false;
@ -151,24 +152,24 @@ public class RoutingHelper {
app.startNavigationService(NavigationService.USED_BY_NAVIGATION, 0); app.startNavigationService(NavigationService.USED_BY_NAVIGATION, 0);
} }
} }
public boolean isRoutePlanningMode() { public boolean isRoutePlanningMode() {
return isRoutePlanningMode; return isRoutePlanningMode;
} }
public void setRoutePlanningMode(boolean isRoutePlanningMode) { public void setRoutePlanningMode(boolean isRoutePlanningMode) {
this.isRoutePlanningMode = isRoutePlanningMode; this.isRoutePlanningMode = isRoutePlanningMode;
} }
public synchronized void setFinalAndCurrentLocation(LatLon finalLocation, List<LatLon> intermediatePoints, Location currentLocation){ public synchronized void setFinalAndCurrentLocation(LatLon finalLocation, List<LatLon> intermediatePoints, Location currentLocation){
RouteCalculationResult previousRoute = route; RouteCalculationResult previousRoute = route;
clearCurrentRoute(finalLocation, intermediatePoints); clearCurrentRoute(finalLocation, intermediatePoints);
// to update route // to update route
setCurrentLocation(currentLocation, false, previousRoute, true); setCurrentLocation(currentLocation, false, previousRoute, true);
} }
public synchronized void clearCurrentRoute(LatLon newFinalLocation, List<LatLon> newIntermediatePoints) { public synchronized void clearCurrentRoute(LatLon newFinalLocation, List<LatLon> newIntermediatePoints) {
route = new RouteCalculationResult(""); route = new RouteCalculationResult("");
isDeviatedFromRoute = false; isDeviatedFromRoute = false;
@ -184,7 +185,7 @@ public class RoutingHelper {
if(l == null) { if(l == null) {
it.remove(); it.remove();
} else { } else {
l.routeWasCancelled(); l.routeWasCancelled();
} }
} }
} }
@ -224,50 +225,50 @@ public class RoutingHelper {
public GPXRouteParamsBuilder getCurrentGPXRoute() { public GPXRouteParamsBuilder getCurrentGPXRoute() {
return currentGPXRoute; return currentGPXRoute;
} }
public void setGpxParams(GPXRouteParamsBuilder params) { public void setGpxParams(GPXRouteParamsBuilder params) {
currentGPXRoute = params; currentGPXRoute = params;
} }
public List<Location> getCurrentCalculatedRoute() { public List<Location> getCurrentCalculatedRoute() {
return route.getImmutableAllLocations(); return route.getImmutableAllLocations();
} }
public void setAppMode(ApplicationMode mode){ public void setAppMode(ApplicationMode mode){
this.mode = mode; this.mode = mode;
voiceRouter.updateAppMode(); voiceRouter.updateAppMode();
} }
public ApplicationMode getAppMode() { public ApplicationMode getAppMode() {
return mode; return mode;
} }
public LatLon getFinalLocation() { public LatLon getFinalLocation() {
return finalLocation; return finalLocation;
} }
public List<LatLon> getIntermediatePoints() { public List<LatLon> getIntermediatePoints() {
return intermediatePoints; return intermediatePoints;
} }
public boolean isRouteCalculated(){ public boolean isRouteCalculated(){
return route.isCalculated(); return route.isCalculated();
} }
public VoiceRouter getVoiceRouter() { public VoiceRouter getVoiceRouter() {
return voiceRouter; return voiceRouter;
} }
public Location getLastProjection(){ public Location getLastProjection(){
return lastProjection; return lastProjection;
} }
public void addListener(IRouteInformationListener l){ public void addListener(IRouteInformationListener l){
listeners.add(new WeakReference<RoutingHelper.IRouteInformationListener>(l)); listeners.add(new WeakReference<RoutingHelper.IRouteInformationListener>(l));
} }
public boolean removeListener(IRouteInformationListener lt){ public boolean removeListener(IRouteInformationListener lt){
Iterator<WeakReference<IRouteInformationListener>> it = listeners.iterator(); Iterator<WeakReference<IRouteInformationListener>> it = listeners.iterator();
while(it.hasNext()) { while(it.hasNext()) {
@ -280,14 +281,14 @@ public class RoutingHelper {
} }
return false; return false;
} }
public void updateLocation(Location currentLocation) { public void updateLocation(Location currentLocation) {
if(isFollowingMode() || (settings.getPointToStart() == null && isRoutePlanningMode) || if(isFollowingMode() || (settings.getPointToStart() == null && isRoutePlanningMode) ||
app.getLocationProvider().getLocationSimulation().isRouteAnimating()) { app.getLocationProvider().getLocationSimulation().isRouteAnimating()) {
setCurrentLocation(currentLocation, false); setCurrentLocation(currentLocation, false);
} }
} }
public Location setCurrentLocation(Location currentLocation, boolean returnUpdatedLocation) { public Location setCurrentLocation(Location currentLocation, boolean returnUpdatedLocation) {
return setCurrentLocation(currentLocation, returnUpdatedLocation, route, false); return setCurrentLocation(currentLocation, returnUpdatedLocation, route, false);
} }
@ -301,8 +302,8 @@ public class RoutingHelper {
List<Location> routeNodes = route.getImmutableAllLocations(); List<Location> routeNodes = route.getImmutableAllLocations();
return getOrthogonalDistance(lastFixedLocation, routeNodes.get(route.currentRoute -1), routeNodes.get(route.currentRoute)); return getOrthogonalDistance(lastFixedLocation, routeNodes.get(route.currentRoute -1), routeNodes.get(route.currentRoute));
} }
private Location setCurrentLocation(Location currentLocation, boolean returnUpdatedLocation, private Location setCurrentLocation(Location currentLocation, boolean returnUpdatedLocation,
RouteCalculationResult previousRoute, boolean targetPointsChanged) { RouteCalculationResult previousRoute, boolean targetPointsChanged) {
Location locationProjection = currentLocation; Location locationProjection = currentLocation;
if (finalLocation == null || currentLocation == null) { if (finalLocation == null || currentLocation == null) {
@ -367,7 +368,7 @@ public class RoutingHelper {
voiceRouter.announceOffRoute(distOrth); voiceRouter.announceOffRoute(distOrth);
} }
} }
// calculate projection of current location // calculate projection of current location
if (currentRoute > 0) { if (currentRoute > 0) {
locationProjection = new Location(currentLocation); locationProjection = new Location(currentLocation);
@ -386,8 +387,8 @@ public class RoutingHelper {
} }
if (calculateRoute) { if (calculateRoute) {
recalculateRouteInBackground(currentLocation, finalLocation, intermediatePoints, currentGPXRoute, recalculateRouteInBackground(currentLocation, finalLocation, intermediatePoints, currentGPXRoute,
previousRoute.isCalculated() ? previousRoute : null, false, !targetPointsChanged); previousRoute.isCalculated() ? previousRoute : null, false, !targetPointsChanged, null);
} else { } else {
Thread job = currentRunningJob; Thread job = currentRunningJob;
if(job instanceof RouteRecalculationThread) { if(job instanceof RouteRecalculationThread) {
@ -414,13 +415,13 @@ public class RoutingHelper {
loc.getLongitude(), from.getLatitude(), from.getLongitude(), loc.getLongitude(), from.getLatitude(), from.getLongitude(),
to.getLatitude(), to.getLongitude()); to.getLatitude(), to.getLongitude());
} }
private static LatLon getProject(Location loc, Location from, Location to) { private static LatLon getProject(Location loc, Location from, Location to) {
return MapUtils.getProjection(loc.getLatitude(), return MapUtils.getProjection(loc.getLatitude(),
loc.getLongitude(), from.getLatitude(), from.getLongitude(), loc.getLongitude(), from.getLatitude(), from.getLongitude(),
to.getLatitude(), to.getLongitude()); to.getLatitude(), to.getLongitude());
} }
private static int lookAheadFindMinOrthogonalDistance(Location currentLocation, List<Location> routeNodes, int currentRoute, int iterations) { private static int lookAheadFindMinOrthogonalDistance(Location currentLocation, List<Location> routeNodes, int currentRoute, int iterations) {
double newDist; double newDist;
double dist = Double.POSITIVE_INFINITY; double dist = Double.POSITIVE_INFINITY;
@ -444,7 +445,7 @@ public class RoutingHelper {
while (currentRoute + 1 < routeNodes.size()) { while (currentRoute + 1 < routeNodes.size()) {
double dist = currentLocation.distanceTo(routeNodes.get(currentRoute)); double dist = currentLocation.distanceTo(routeNodes.get(currentRoute));
if(currentRoute > 0) { if(currentRoute > 0) {
dist = getOrthogonalDistance(currentLocation, routeNodes.get(currentRoute - 1), dist = getOrthogonalDistance(currentLocation, routeNodes.get(currentRoute - 1),
routeNodes.get(currentRoute)); routeNodes.get(currentRoute));
} }
boolean processed = false; boolean processed = false;
@ -452,7 +453,7 @@ public class RoutingHelper {
// if not then look ahead only 3 in order to catch sharp turns // if not then look ahead only 3 in order to catch sharp turns
boolean longDistance = dist >= 250; boolean longDistance = dist >= 250;
int newCurrentRoute = lookAheadFindMinOrthogonalDistance(currentLocation, routeNodes, currentRoute, longDistance ? 15 : 8); int newCurrentRoute = lookAheadFindMinOrthogonalDistance(currentLocation, routeNodes, currentRoute, longDistance ? 15 : 8);
double newDist = getOrthogonalDistance(currentLocation, routeNodes.get(newCurrentRoute), double newDist = getOrthogonalDistance(currentLocation, routeNodes.get(newCurrentRoute),
routeNodes.get(newCurrentRoute + 1)); routeNodes.get(newCurrentRoute + 1));
if(longDistance) { if(longDistance) {
if(newDist < dist) { if(newDist < dist) {
@ -496,7 +497,7 @@ public class RoutingHelper {
break; break;
} }
} }
// 2. check if intermediate found // 2. check if intermediate found
if(route.getIntermediatePointsToPass() > 0 if(route.getIntermediatePointsToPass() > 0
&& route.getDistanceToNextIntermediate(lastFixedLocation) < getArrivalDistance() * 2f && !isRoutePlanningMode) { && route.getDistanceToNextIntermediate(lastFixedLocation) < getArrivalDistance() * 2f && !isRoutePlanningMode) {
@ -536,7 +537,7 @@ public class RoutingHelper {
//showMessage(app.getString(R.string.arrived_at_destination)); //showMessage(app.getString(R.string.arrived_at_destination));
TargetPointsHelper targets = app.getTargetPointsHelper(); TargetPointsHelper targets = app.getTargetPointsHelper();
TargetPoint tp = targets.getPointToNavigate(); TargetPoint tp = targets.getPointToNavigate();
String description = tp == null ? "" : tp.getOnlyName(); String description = tp == null ? "" : tp.getOnlyName();
if(isFollowingMode) { if(isFollowingMode) {
voiceRouter.arrivedDestinationPoint(description); voiceRouter.arrivedDestinationPoint(description);
} }
@ -564,7 +565,7 @@ public class RoutingHelper {
private float getArrivalDistance() { private float getArrivalDistance() {
return ((float)settings.getApplicationMode().getArrivalDistance()) * settings.ARRIVAL_DISTANCE_FACTOR.get(); return ((float)settings.getApplicationMode().getArrivalDistance()) * settings.ARRIVAL_DISTANCE_FACTOR.get();
} }
private boolean identifyUTurnIsNeeded(Location currentLocation, float posTolerance) { private boolean identifyUTurnIsNeeded(Location currentLocation, float posTolerance) {
if (finalLocation == null || currentLocation == null || !route.isCalculated()) { if (finalLocation == null || currentLocation == null || !route.isCalculated()) {
@ -596,9 +597,9 @@ public class RoutingHelper {
} }
return isOffRoute; return isOffRoute;
} }
/** /**
* Wrong movement direction is considered when between * Wrong movement direction is considered when between
* current location bearing (determines by 2 last fixed position or provided) * current location bearing (determines by 2 last fixed position or provided)
* and bearing from currentLocation to next (current) point * and bearing from currentLocation to next (current) point
* the difference is more than 60 degrees * the difference is more than 60 degrees
@ -648,11 +649,11 @@ public class RoutingHelper {
evalWaitInterval = Math.max(3000, evalWaitInterval * 3 / 2); evalWaitInterval = Math.max(3000, evalWaitInterval * 3 / 2);
evalWaitInterval = Math.min(evalWaitInterval, 120000); evalWaitInterval = Math.min(evalWaitInterval, 120000);
} }
} }
} }
// trigger voice prompt only if new route is in forward direction // trigger voice prompt only if new route is in forward direction
// If route is in wrong direction after one more setLocation it will be recalculated // If route is in wrong direction after one more setLocation it will be recalculated
if (!wrongMovementDirection || newRoute) { if (!wrongMovementDirection || newRoute) {
@ -687,23 +688,23 @@ public class RoutingHelper {
} }
}); });
} }
public int getLeftDistance(){ public int getLeftDistance(){
return route.getDistanceToFinish(lastFixedLocation); return route.getDistanceToFinish(lastFixedLocation);
} }
public int getLeftDistanceNextIntermediate() { public int getLeftDistanceNextIntermediate() {
return route.getDistanceToNextIntermediate(lastFixedLocation); return route.getDistanceToNextIntermediate(lastFixedLocation);
} }
public int getLeftTime() { public int getLeftTime() {
return route.getLeftTime(lastFixedLocation); return route.getLeftTime(lastFixedLocation);
} }
public OsmandSettings getSettings() { public OsmandSettings getSettings() {
return settings; return settings;
} }
public String getGeneralRouteInformation(){ public String getGeneralRouteInformation(){
int dist = getLeftDistance(); int dist = getLeftDistance();
int hours = getLeftTime() / (60 * 60); int hours = getLeftTime() / (60 * 60);
@ -711,11 +712,11 @@ public class RoutingHelper {
return app.getString(R.string.route_general_information, OsmAndFormatter.getFormattedDistance(dist, app), return app.getString(R.string.route_general_information, OsmAndFormatter.getFormattedDistance(dist, app),
hours, minutes); hours, minutes);
} }
public Location getLocationFromRouteDirection(RouteDirectionInfo i){ public Location getLocationFromRouteDirection(RouteDirectionInfo i){
return route.getLocationFromRouteDirection(i); return route.getLocationFromRouteDirection(i);
} }
public synchronized NextDirectionInfo getNextRouteDirectionInfo(NextDirectionInfo info, boolean toSpeak){ public synchronized NextDirectionInfo getNextRouteDirectionInfo(NextDirectionInfo info, boolean toSpeak){
NextDirectionInfo i = route.getNextRouteDirectionInfo(info, lastProjection, toSpeak); NextDirectionInfo i = route.getNextRouteDirectionInfo(info, lastProjection, toSpeak);
if(i != null) { if(i != null) {
@ -723,12 +724,12 @@ public class RoutingHelper {
} }
return i; return i;
} }
public synchronized float getCurrentMaxSpeed() { public synchronized float getCurrentMaxSpeed() {
return route.getCurrentMaxSpeed(); return route.getCurrentMaxSpeed();
} }
public static String formatStreetName(String name, String ref, String destination, String towards) { public static String formatStreetName(String name, String ref, String destination, String towards) {
//Hardy, 2016-08-05: //Hardy, 2016-08-05:
//Now returns: (ref) + ((" ")+name) + ((" ")+"toward "+dest) or "" //Now returns: (ref) + ((" ")+name) + ((" ")+"toward "+dest) or ""
@ -752,14 +753,14 @@ public class RoutingHelper {
return formattedStreetName.replace(";", ", "); return formattedStreetName.replace(";", ", ");
} }
// protected boolean isDistanceLess(float currentSpeed, double dist, double etalon, float defSpeed){ // protected boolean isDistanceLess(float currentSpeed, double dist, double etalon, float defSpeed){
// if(dist < etalon || ((dist / currentSpeed) < (etalon / defSpeed))){ // if(dist < etalon || ((dist / currentSpeed) < (etalon / defSpeed))){
// return true; // return true;
// } // }
// return false; // return false;
// } // }
public synchronized String getCurrentName(TurnType[] next){ public synchronized String getCurrentName(TurnType[] next){
NextDirectionInfo n = getNextRouteDirectionInfo(new NextDirectionInfo(), true); NextDirectionInfo n = getNextRouteDirectionInfo(new NextDirectionInfo(), true);
Location l = lastFixedLocation; Location l = lastFixedLocation;
@ -767,7 +768,7 @@ public class RoutingHelper {
if(l != null && l.hasSpeed()) { if(l != null && l.hasSpeed()) {
speed = l.getSpeed(); speed = l.getSpeed();
} }
if(n.distanceTo > 0 && n.directionInfo != null && !n.directionInfo.getTurnType().isSkipToSpeak() && if(n.distanceTo > 0 && n.directionInfo != null && !n.directionInfo.getTurnType().isSkipToSpeak() &&
voiceRouter.isDistanceLess(speed, n.distanceTo, voiceRouter.PREPARE_DISTANCE * 0.75f, 0f)) { voiceRouter.isDistanceLess(speed, n.distanceTo, voiceRouter.PREPARE_DISTANCE * 0.75f, 0f)) {
String nm = n.directionInfo.getStreetName(); String nm = n.directionInfo.getStreetName();
String rf = n.directionInfo.getRef(); String rf = n.directionInfo.getRef();
@ -781,7 +782,7 @@ public class RoutingHelper {
if(rs != null) { if(rs != null) {
String nm = rs.getObject().getName(settings.MAP_PREFERRED_LOCALE.get(), settings.MAP_TRANSLITERATE_NAMES.get()); String nm = rs.getObject().getName(settings.MAP_PREFERRED_LOCALE.get(), settings.MAP_TRANSLITERATE_NAMES.get());
String rf = rs.getObject().getRef(settings.MAP_PREFERRED_LOCALE.get(), settings.MAP_TRANSLITERATE_NAMES.get(), rs.isForwardDirection()); String rf = rs.getObject().getRef(settings.MAP_PREFERRED_LOCALE.get(), settings.MAP_TRANSLITERATE_NAMES.get(), rs.isForwardDirection());
String dn = rs.getObject().getDestinationName(settings.MAP_PREFERRED_LOCALE.get(), String dn = rs.getObject().getDestinationName(settings.MAP_PREFERRED_LOCALE.get(),
settings.MAP_TRANSLITERATE_NAMES.get(), rs.isForwardDirection()); settings.MAP_TRANSLITERATE_NAMES.get(), rs.isForwardDirection());
return formatStreetName(nm, rf, dn, "»"); return formatStreetName(nm, rf, dn, "»");
} }
@ -791,11 +792,11 @@ public class RoutingHelper {
public RouteSegmentResult getCurrentSegmentResult() { public RouteSegmentResult getCurrentSegmentResult() {
return route.getCurrentSegmentResult(); return route.getCurrentSegmentResult();
} }
public List<RouteSegmentResult> getUpcomingTunnel(float distToStart) { public List<RouteSegmentResult> getUpcomingTunnel(float distToStart) {
return route.getUpcomingTunnel(distToStart); return route.getUpcomingTunnel(distToStart);
} }
public synchronized NextDirectionInfo getNextRouteDirectionInfoAfter(NextDirectionInfo previous, NextDirectionInfo to, boolean toSpeak){ public synchronized NextDirectionInfo getNextRouteDirectionInfoAfter(NextDirectionInfo previous, NextDirectionInfo to, boolean toSpeak){
NextDirectionInfo i = route.getNextRouteDirectionInfoAfter(previous, to, toSpeak); NextDirectionInfo i = route.getNextRouteDirectionInfoAfter(previous, to, toSpeak);
if(i != null) { if(i != null) {
@ -803,15 +804,15 @@ public class RoutingHelper {
} }
return i; return i;
} }
public List<RouteDirectionInfo> getRouteDirections(){ public List<RouteDirectionInfo> getRouteDirections(){
return route.getRouteDirections(); return route.getRouteDirections();
} }
private class RouteRecalculationThread extends Thread { private class RouteRecalculationThread extends Thread {
private final RouteCalculationParams params; private final RouteCalculationParams params;
private boolean paramsChanged; private boolean paramsChanged;
private Thread prevRunningJob; private Thread prevRunningJob;
@ -824,7 +825,7 @@ public class RoutingHelper {
params.calculationProgress = new RouteCalculationProgress(); params.calculationProgress = new RouteCalculationProgress();
} }
} }
public boolean isParamsChanged() { public boolean isParamsChanged() {
return paramsChanged; return paramsChanged;
} }
@ -832,8 +833,8 @@ public class RoutingHelper {
public void stopCalculation(){ public void stopCalculation(){
params.calculationProgress.isCancelled = true; params.calculationProgress.isCancelled = true;
} }
@Override @Override
public void run() { public void run() {
synchronized (RoutingHelper.this) { synchronized (RoutingHelper.this) {
@ -870,6 +871,12 @@ public class RoutingHelper {
synchronized (RoutingHelper.this) { synchronized (RoutingHelper.this) {
if (res.isCalculated()) { if (res.isCalculated()) {
route = res; route = res;
if (params.snapToRoadParams != null) {
params.snapToRoadParams.points = res.getRouteLocations();
if (params.snapToRoadParams.listener != null) {
params.snapToRoadParams.listener.onSnapToRoadDone();
}
}
} else { } else {
evalWaitInterval = Math.max(3000, evalWaitInterval * 3 / 2); // for Issue #3899 evalWaitInterval = Math.max(3000, evalWaitInterval * 3 / 2); // for Issue #3899
evalWaitInterval = Math.min(evalWaitInterval, 120000); evalWaitInterval = Math.min(evalWaitInterval, 120000);
@ -903,14 +910,19 @@ public class RoutingHelper {
this.prevRunningJob = prevRunningJob; this.prevRunningJob = prevRunningJob;
} }
} }
public void recalculateSnapToRoad(final Location start, final LatLon end, final List<LatLon> intermediates, SnapToRoadParams params) {
recalculateRouteInBackground(start, end, intermediates, null, route, true, false, params);
}
public void recalculateRouteDueToSettingsChange() { public void recalculateRouteDueToSettingsChange() {
clearCurrentRoute(finalLocation, intermediatePoints); clearCurrentRoute(finalLocation, intermediatePoints);
recalculateRouteInBackground(lastFixedLocation, finalLocation, intermediatePoints, currentGPXRoute, route, true, false); recalculateRouteInBackground(lastFixedLocation, finalLocation, intermediatePoints, currentGPXRoute, route, true, false, null);
} }
private void recalculateRouteInBackground(final Location start, final LatLon end, final List<LatLon> intermediates, private void recalculateRouteInBackground(final Location start, final LatLon end, final List<LatLon> intermediates,
final GPXRouteParamsBuilder gpxRoute, final RouteCalculationResult previousRoute, boolean paramsChanged, boolean onlyStartPointChanged){ final GPXRouteParamsBuilder gpxRoute, final RouteCalculationResult previousRoute, boolean paramsChanged, boolean onlyStartPointChanged,
final SnapToRoadParams snapToRoadParams){
if (start == null || end == null) { if (start == null || end == null) {
return; return;
} }
@ -932,12 +944,23 @@ public class RoutingHelper {
recalculateCountInInterval = 0; recalculateCountInInterval = 0;
} }
params.leftSide = settings.DRIVING_REGION.get().leftHandDriving; params.leftSide = settings.DRIVING_REGION.get().leftHandDriving;
ApplicationMode mode;
if (snapToRoadParams != null && snapToRoadParams.applicationMode != null) {
params.snapToRoadParams = snapToRoadParams;
mode = snapToRoadParams.applicationMode;
} else {
mode = this.mode;
}
params.fast = settings.FAST_ROUTE_MODE.getModeValue(mode); params.fast = settings.FAST_ROUTE_MODE.getModeValue(mode);
params.type = settings.ROUTER_SERVICE.getModeValue(mode); params.type = settings.ROUTER_SERVICE.getModeValue(mode);
params.mode = mode; params.mode = mode;
params.ctx = app; params.ctx = app;
if (params.type == RouteService.OSMAND) { if (params.type == RouteService.OSMAND) {
params.calculationProgress = new RouteCalculationProgress(); if (snapToRoadParams != null && snapToRoadParams.calculationProgress != null) {
params.calculationProgress = snapToRoadParams.calculationProgress;
} else {
params.calculationProgress = new RouteCalculationProgress();
}
updateProgress(params); updateProgress(params);
} }
synchronized (this) { synchronized (this) {
@ -954,6 +977,12 @@ public class RoutingHelper {
} }
private void updateProgress(final RouteCalculationParams params) { private void updateProgress(final RouteCalculationParams params) {
final RouteCalculationProgressCallback progressRoute;
if (params.snapToRoadParams != null) {
progressRoute = params.snapToRoadParams.calculationProgressCallback;
} else {
progressRoute = this.progressRoute;
}
if(progressRoute != null ) { if(progressRoute != null ) {
app.runInUIThread(new Runnable() { app.runInUIThread(new Runnable() {
@ -970,7 +999,7 @@ public class RoutingHelper {
Thread t = currentRunningJob; Thread t = currentRunningJob;
if(t instanceof RouteRecalculationThread && ((RouteRecalculationThread) t).params != params) { if(t instanceof RouteRecalculationThread && ((RouteRecalculationThread) t).params != params) {
// different calculation started // different calculation started
return; return;
} else { } else {
if (calculationProgress.requestPrivateAccessRouting) { if (calculationProgress.requestPrivateAccessRouting) {
progressRoute.requestPrivateAccessRouting(); progressRoute.requestPrivateAccessRouting();
@ -987,13 +1016,13 @@ public class RoutingHelper {
}, 300); }, 300);
} }
} }
public void setProgressBar(RouteCalculationProgressCallback progressRoute) { public void setProgressBar(RouteCalculationProgressCallback progressRoute) {
this.progressRoute = progressRoute; this.progressRoute = progressRoute;
} }
public interface RouteCalculationProgressCallback { public interface RouteCalculationProgressCallback {
// set visibility // set visibility
public void updateProgress(int progress); public void updateProgress(int progress);
public void requestPrivateAccessRouting(); public void requestPrivateAccessRouting();
@ -1004,7 +1033,7 @@ public class RoutingHelper {
public boolean isRouteBeingCalculated(){ public boolean isRouteBeingCalculated(){
return currentRunningJob instanceof RouteRecalculationThread; return currentRunningJob instanceof RouteRecalculationThread;
} }
private void showMessage(final String msg){ private void showMessage(final String msg){
app.runInUIThread(new Runnable() { app.runInUIThread(new Runnable() {
@Override @Override
@ -1013,13 +1042,13 @@ public class RoutingHelper {
} }
}); });
} }
// NEVER returns null // NEVER returns null
public RouteCalculationResult getRoute() { public RouteCalculationResult getRoute() {
return route; return route;
} }
public GPXFile generateGPXFileWithRoute(){ public GPXFile generateGPXFileWithRoute(){
return provider.createOsmandRouterGPX(route, app); return provider.createOsmandRouterGPX(route, app);
} }

View file

@ -8,6 +8,7 @@ import android.widget.TextView;
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.RotatedTileBox; import net.osmand.data.RotatedTileBox;
import net.osmand.plus.GPXUtilities.GPXFile; import net.osmand.plus.GPXUtilities.GPXFile;
import net.osmand.plus.IconsCache; import net.osmand.plus.IconsCache;
@ -67,6 +68,7 @@ public class AddGpxPointBottomSheetHelper implements OnDismissListener {
public void onClick(View v) { public void onClick(View v) {
hide(); hide();
contextMenuLayer.cancelAddGpxPoint(); contextMenuLayer.cancelAddGpxPoint();
openTrackActivity();
} }
}); });
} }
@ -129,6 +131,14 @@ public class AddGpxPointBottomSheetHelper implements OnDismissListener {
@Override @Override
public void onDismiss() { public void onDismiss() {
MapContextMenu contextMenu = mapActivity.getContextMenu();
if (contextMenu.isVisible() && contextMenu.isClosable()) {
contextMenu.close();
}
openTrackActivity();
}
private void openTrackActivity() {
Intent newIntent = new Intent(mapActivity, mapActivity.getMyApplication().getAppCustomization().getTrackActivity()); Intent newIntent = new Intent(mapActivity, mapActivity.getMyApplication().getAppCustomization().getTrackActivity());
newIntent.putExtra(TrackActivity.TRACK_FILE_NAME, newGpxPoint.getGpx().path); newIntent.putExtra(TrackActivity.TRACK_FILE_NAME, newGpxPoint.getGpx().path);
newIntent.putExtra(TrackActivity.OPEN_POINTS_TAB, true); newIntent.putExtra(TrackActivity.OPEN_POINTS_TAB, true);
@ -139,10 +149,12 @@ public class AddGpxPointBottomSheetHelper implements OnDismissListener {
public static class NewGpxPoint { public static class NewGpxPoint {
private PointDescription pointDescription; private PointDescription pointDescription;
private GPXFile gpx; private GPXFile gpx;
private QuadRect rect;
public NewGpxPoint(GPXFile gpx, PointDescription pointDescription) { public NewGpxPoint(GPXFile gpx, PointDescription pointDescription, QuadRect rect) {
this.gpx = gpx; this.gpx = gpx;
this.pointDescription = pointDescription; this.pointDescription = pointDescription;
this.rect = rect;
} }
public GPXFile getGpx() { public GPXFile getGpx() {
@ -152,5 +164,9 @@ public class AddGpxPointBottomSheetHelper implements OnDismissListener {
public PointDescription getPointDescription() { public PointDescription getPointDescription() {
return pointDescription; return pointDescription;
} }
public QuadRect getRect() {
return rect;
}
} }
} }

View file

@ -449,7 +449,7 @@ public class ContextMenuLayer extends OsmandMapLayer {
} }
} }
private void quitAddGpxPoint() { public void quitAddGpxPoint() {
mInAddGpxPointMode = false; mInAddGpxPointMode = false;
mark(View.VISIBLE, R.id.map_ruler_layout, mark(View.VISIBLE, R.id.map_ruler_layout,
R.id.map_left_widgets_panel, R.id.map_right_widgets_panel, R.id.map_center_info); R.id.map_left_widgets_panel, R.id.map_right_widgets_panel, R.id.map_center_info);

View file

@ -218,7 +218,7 @@ public class MapQuickActionLayer extends OsmandMapLayer implements QuickActionRe
private void enterMovingMode(RotatedTileBox tileBox) { private void enterMovingMode(RotatedTileBox tileBox) {
previousMapPosition = view.getMapPosition(); previousMapPosition = view.getMapPosition();
view.setMapPosition(OsmandSettings.MIDDLE_CONSTANT); view.setMapPosition(OsmandSettings.MIDDLE_BOTTOM_CONSTANT);
MapContextMenu menu = mapActivity.getContextMenu(); MapContextMenu menu = mapActivity.getContextMenu();
LatLon ll = menu.isActive() && tileBox.containsLatLon(menu.getLatLon()) ? menu.getLatLon() : tileBox.getCenterLatLon(); LatLon ll = menu.isActive() && tileBox.containsLatLon(menu.getLatLon()) ? menu.getLatLon() : tileBox.getCenterLatLon();

View file

@ -578,12 +578,19 @@ public class OsmandMapTileView implements IMapDownloaderCallback {
final float ratioy; final float ratioy;
if (mapPosition == OsmandSettings.BOTTOM_CONSTANT) { if (mapPosition == OsmandSettings.BOTTOM_CONSTANT) {
ratioy = 0.85f; ratioy = 0.85f;
} else if (mapPosition == OsmandSettings.MIDDLE_CONSTANT) { } else if (mapPosition == OsmandSettings.MIDDLE_BOTTOM_CONSTANT) {
ratioy = 0.70f; ratioy = 0.70f;
} else if (mapPosition == OsmandSettings.MIDDLE_TOP_CONSTANT) {
ratioy = 0.25f;
} else { } else {
ratioy = 0.5f; ratioy = 0.5f;
} }
final float ratiox = mapPositionX == 0 ? 0.5f : 0.75f; final float ratiox;
if (mapPosition == OsmandSettings.LANDSCAPE_MIDDLE_RIGHT_CONSTANT) {
ratiox = 0.7f;
} else {
ratiox = mapPositionX == 0 ? 0.5f : 0.75f;
}
final int cy = (int) (ratioy * view.getHeight()); final int cy = (int) (ratioy * view.getHeight());
final int cx = (int) (ratiox * view.getWidth()); final int cx = (int) (ratiox * view.getWidth());
if (currentViewport.getPixWidth() != view.getWidth() || currentViewport.getPixHeight() != view.getHeight() || if (currentViewport.getPixWidth() != view.getWidth() || currentViewport.getPixHeight() != view.getHeight() ||

View file

@ -1,8 +1,10 @@
package net.osmand.plus.views.mapwidgets; package net.osmand.plus.views.mapwidgets;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.support.v7.widget.SwitchCompat;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
@ -229,7 +231,11 @@ public class MapInfoWidgetsFactory {
int refreshBtnIconDarkId = R.drawable.ic_action_refresh_dark; int refreshBtnIconDarkId = R.drawable.ic_action_refresh_dark;
int refreshBtnIconClrLightId = R.color.icon_color; int refreshBtnIconClrLightId = R.color.icon_color;
int refreshBtnIconClrDarkId = 0; int refreshBtnIconClrDarkId = 0;
boolean refreshBtnVisible = false; boolean refreshBtnVisible = false;
boolean saveViewVisible = false;
protected boolean topBarSwitchVisible = false;
protected boolean topBarSwitchChecked = false;
int titleTextClrLightId = R.color.primary_text_light; int titleTextClrLightId = R.color.primary_text_light;
int titleTextClrDarkId = R.color.primary_text_dark; int titleTextClrDarkId = R.color.primary_text_dark;
@ -247,6 +253,8 @@ public class MapInfoWidgetsFactory {
OnClickListener onTitleClickListener; OnClickListener onTitleClickListener;
OnClickListener onCloseButtonClickListener; OnClickListener onCloseButtonClickListener;
OnClickListener onRefreshButtonClickListener; OnClickListener onRefreshButtonClickListener;
OnClickListener onSaveViewClickListener;
OnCheckedChangeListener onSwitchCheckedChangeListener;
Runnable onCloseToolbarListener; Runnable onCloseToolbarListener;
@ -264,6 +272,10 @@ public class MapInfoWidgetsFactory {
this.title = title; this.title = title;
} }
public String getTitle() {
return title;
}
public void setBottomView(View bottomView) { public void setBottomView(View bottomView) {
this.bottomView = bottomView; this.bottomView = bottomView;
} }
@ -321,6 +333,18 @@ public class MapInfoWidgetsFactory {
this.refreshBtnVisible = visible; this.refreshBtnVisible = visible;
} }
public void setSaveViewVisible(boolean visible) {
this.saveViewVisible = visible;
}
public void setTopBarSwitchVisible(boolean visible) {
this.topBarSwitchVisible = visible;
}
public void setTopBarSwitchChecked(boolean checked) {
this.topBarSwitchChecked = checked;
}
public void setTitleTextClrIds(int titleTextClrLightId, int titleTextClrDarkId) { public void setTitleTextClrIds(int titleTextClrLightId, int titleTextClrDarkId) {
this.titleTextClrLightId = titleTextClrLightId; this.titleTextClrLightId = titleTextClrLightId;
this.titleTextClrDarkId = titleTextClrDarkId; this.titleTextClrDarkId = titleTextClrDarkId;
@ -343,6 +367,14 @@ public class MapInfoWidgetsFactory {
this.onCloseButtonClickListener = onCloseButtonClickListener; this.onCloseButtonClickListener = onCloseButtonClickListener;
} }
public void setOnSaveViewClickListener(OnClickListener onSaveViewClickListener) {
this.onSaveViewClickListener = onSaveViewClickListener;
}
public void setOnSwitchCheckedChangeListener(OnCheckedChangeListener onSwitchCheckedChangeListener) {
this.onSwitchCheckedChangeListener = onSwitchCheckedChangeListener;
}
public void setOnRefreshButtonClickListener(OnClickListener onRefreshButtonClickListener) { public void setOnRefreshButtonClickListener(OnClickListener onRefreshButtonClickListener) {
this.onRefreshButtonClickListener = onRefreshButtonClickListener; this.onRefreshButtonClickListener = onRefreshButtonClickListener;
} }
@ -355,6 +387,7 @@ public class MapInfoWidgetsFactory {
TextView titleView = view.getTitleView(); TextView titleView = view.getTitleView();
TextView descrView = view.getDescrView(); TextView descrView = view.getDescrView();
LinearLayout bottomViewLayout = view.getBottomViewLayout(); LinearLayout bottomViewLayout = view.getBottomViewLayout();
SwitchCompat switchCompat = view.getTopBarSwitch();
if (title != null) { if (title != null) {
titleView.setText(title); titleView.setText(title);
view.updateVisibility(titleView, true); view.updateVisibility(titleView, true);
@ -374,6 +407,10 @@ public class MapInfoWidgetsFactory {
} else { } else {
view.updateVisibility(bottomViewLayout, false); view.updateVisibility(bottomViewLayout, false);
} }
view.updateVisibility(switchCompat, topBarSwitchVisible);
if (topBarSwitchVisible) {
switchCompat.setChecked(topBarSwitchChecked);
}
if (view.getShadowView() != null) { if (view.getShadowView() != null) {
view.getShadowView().setVisibility(View.VISIBLE); view.getShadowView().setVisibility(View.VISIBLE);
} }
@ -393,6 +430,8 @@ public class MapInfoWidgetsFactory {
private TextView descrView; private TextView descrView;
private ImageButton refreshButton; private ImageButton refreshButton;
private ImageButton closeButton; private ImageButton closeButton;
private TextView saveView;
private SwitchCompat topBarSwitch;
private View shadowView; private View shadowView;
private boolean nightMode; private boolean nightMode;
@ -407,7 +446,9 @@ public class MapInfoWidgetsFactory {
refreshButton = (ImageButton) map.findViewById(R.id.widget_top_bar_refresh_button); refreshButton = (ImageButton) map.findViewById(R.id.widget_top_bar_refresh_button);
closeButton = (ImageButton) map.findViewById(R.id.widget_top_bar_close_button); closeButton = (ImageButton) map.findViewById(R.id.widget_top_bar_close_button);
titleView = (TextView) map.findViewById(R.id.widget_top_bar_title); titleView = (TextView) map.findViewById(R.id.widget_top_bar_title);
saveView = (TextView) map.findViewById(R.id.widget_top_bar_save);
descrView = (TextView) map.findViewById(R.id.widget_top_bar_description); descrView = (TextView) map.findViewById(R.id.widget_top_bar_description);
topBarSwitch = (SwitchCompat) map.findViewById(R.id.widget_top_bar_switch);
shadowView = map.findViewById(R.id.widget_top_bar_shadow); shadowView = map.findViewById(R.id.widget_top_bar_shadow);
updateVisibility(false); updateVisibility(false);
} }
@ -444,6 +485,14 @@ public class MapInfoWidgetsFactory {
return closeButton; return closeButton;
} }
public TextView getSaveView() {
return saveView;
}
public SwitchCompat getTopBarSwitch() {
return topBarSwitch;
}
public ImageButton getRefreshButton() { public ImageButton getRefreshButton() {
return refreshButton; return refreshButton;
} }
@ -515,6 +564,8 @@ public class MapInfoWidgetsFactory {
topBarTitleLayout.setOnClickListener(controller.onTitleClickListener); topBarTitleLayout.setOnClickListener(controller.onTitleClickListener);
closeButton.setOnClickListener(controller.onCloseButtonClickListener); closeButton.setOnClickListener(controller.onCloseButtonClickListener);
refreshButton.setOnClickListener(controller.onRefreshButtonClickListener); refreshButton.setOnClickListener(controller.onRefreshButtonClickListener);
saveView.setOnClickListener(controller.onSaveViewClickListener);
topBarSwitch.setOnCheckedChangeListener(controller.onSwitchCheckedChangeListener);
} }
public void updateInfo() { public void updateInfo() {
@ -553,6 +604,7 @@ public class MapInfoWidgetsFactory {
int descrColor = map.getResources().getColor(controller.descrTextClrDarkId); int descrColor = map.getResources().getColor(controller.descrTextClrDarkId);
titleView.setTextColor(titleColor); titleView.setTextColor(titleColor);
descrView.setTextColor(descrColor); descrView.setTextColor(descrColor);
saveView.setTextColor(titleColor);
} else { } else {
topBarLayout.setBackgroundResource(AndroidUiHelper.isOrientationPortrait(map) ? controller.bgLightId : controller.bgLightLandId); topBarLayout.setBackgroundResource(AndroidUiHelper.isOrientationPortrait(map) ? controller.bgLightId : controller.bgLightLandId);
if (controller.backBtnIconLightId == 0) { if (controller.backBtnIconLightId == 0) {
@ -574,6 +626,7 @@ public class MapInfoWidgetsFactory {
int descrColor = map.getResources().getColor(controller.descrTextClrLightId); int descrColor = map.getResources().getColor(controller.descrTextClrLightId);
titleView.setTextColor(titleColor); titleView.setTextColor(titleColor);
descrView.setTextColor(descrColor); descrView.setTextColor(descrColor);
saveView.setTextColor(titleColor);
} }
if (controller.singleLineTitle) { if (controller.singleLineTitle) {
titleView.setSingleLine(true); titleView.setSingleLine(true);
@ -595,6 +648,13 @@ public class MapInfoWidgetsFactory {
} else if (refreshButton.getVisibility() == View.VISIBLE) { } else if (refreshButton.getVisibility() == View.VISIBLE) {
refreshButton.setVisibility(View.GONE); refreshButton.setVisibility(View.GONE);
} }
if (controller.saveViewVisible) {
if (saveView.getVisibility() == View.GONE) {
saveView.setVisibility(View.VISIBLE);
}
} else if (saveView.getVisibility() == View.VISIBLE) {
saveView.setVisibility(View.GONE);
}
} }
public void updateColors() { public void updateColors() {