Merge pull request #4490 from osmandapp/sasha_pasha_branch

Sasha pasha branch
This commit is contained in:
Alexey 2017-09-27 12:49:25 +03:00 committed by GitHub
commit 330980dc2e
56 changed files with 3214 additions and 470 deletions

View file

@ -40,7 +40,7 @@
<uses-feature android:name="com.sec.feature.spen_usp" android:required="false"/>
<uses-sdk android:targetSdkVersion="21" android:minSdkVersion="9"
tools:overrideLibrary="com.getkeepsafe.taptargetview"/>
tools:overrideLibrary="com.getkeepsafe.taptargetview, studio.carbonylgroup.textfieldboxes"/>
<supports-screens android:resizeable="true" android:smallScreens="true" android:normalScreens="true" android:largeScreens="true"
android:xlargeScreens="true" android:anyDensity="true" />

View file

@ -399,6 +399,9 @@ dependencies {
exclude group: 'com.android.support'
}
compile 'com.github.PhilJay:MPAndroidChart:v3.0.1'
compile ("com.github.HITGIF:TextFieldBoxes:1.3.2"){
exclude group: 'com.android.support'
}
}
if(analytics) {
println "Apply GMS plugin"

View file

@ -32,4 +32,5 @@
<string name="default_changeset_reopen">Reopen</string>
<string name="items_modified">items modified</string>
<string name="osmand_unlimited">OsmAnd Unlimited</string>
<string name="markers">Markers</string>
</resources>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid
android:color="@color/marker_circle_button_color_dark"/>
</shape>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/marker_circle_background_dark_n"
android:insetBottom="14dp"
android:insetLeft="14dp"
android:insetRight="14dp"
android:insetTop="14dp"/>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/marker_circle_background_p_with_inset" android:state_pressed="true"/>
<item android:drawable="@drawable/marker_circle_background_dark_n_with_inset"/>
</selector>

View file

@ -33,11 +33,9 @@
<RelativeLayout
android:id="@+id/up_down_row"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_height="@dimen/measurement_tool_controls_height"
android:layout_weight="0.45"
android:background="?attr/selectableItemBackground"
android:paddingBottom="@dimen/measurement_tool_content_padding_medium"
android:paddingTop="@dimen/measurement_tool_content_padding_medium">
android:background="?attr/selectableItemBackground">
<ImageView
android:id="@+id/main_icon"
@ -131,9 +129,9 @@
android:layout_marginStart="@dimen/measurement_tool_text_margin"
android:layout_toEndOf="@id/main_icon"
android:layout_toRightOf="@id/main_icon"
tools:text="@string/add_point_after"
android:textAppearance="@style/TextAppearance.ListItemTitle"
android:visibility="gone"/>
android:visibility="gone"
tools:text="@string/add_point_after"/>
</RelativeLayout>
<View

View file

@ -0,0 +1,165 @@
<?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">
<LinearLayout
android:id="@+id/up_down_row"
android:layout_width="0dp"
android:layout_height="@dimen/measurement_tool_controls_height"
android:layout_weight="0.5"
android:background="?attr/selectableItemBackground">
<ImageView
android:id="@+id/up_down_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/bottom_sheet_content_margin"
android:layout_marginLeft="@dimen/bottom_sheet_content_margin"
android:layout_marginRight="@dimen/bottom_sheet_content_margin"
android:layout_marginStart="@dimen/bottom_sheet_content_margin"
android:background="@null"
tools:src="@drawable/ic_action_arrow_down"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<TextView
android:id="@+id/markers_distance_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/measurement_tool_text_margin_small"
android:layout_marginLeft="@dimen/measurement_tool_text_margin"
android:layout_marginRight="@dimen/measurement_tool_text_margin_small"
android:layout_marginStart="@dimen/measurement_tool_text_margin"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.ListItemTitle"
tools:text="1.39 km,"/>
<TextView
android:id="@+id/markers_time_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_list_text_size"
tools:text="~ 45 min."/>
</LinearLayout>
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/select_all_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="@dimen/measurement_tool_text_button_padding_small"
android:paddingLeft="@dimen/measurement_tool_text_button_padding"
android:paddingRight="@dimen/measurement_tool_text_button_padding_small"
android:paddingStart="@dimen/measurement_tool_text_button_padding"
android:text="@string/shared_string_select_all"
android:textColor="?attr/color_dialog_buttons"
osmand:textAllCapsCompat="true"
osmand:typeface="@string/font_roboto_medium"/>
</LinearLayout>
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="?attr/dashboard_divider"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="@dimen/measurement_tool_controls_height"
android:layout_weight="0.5">
<LinearLayout
android:id="@+id/sort_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:paddingLeft="@dimen/bottom_sheet_content_margin"
android:paddingRight="@dimen/bottom_sheet_content_margin">
<ImageView
android:id="@+id/sort_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="@null"
tools:src="@drawable/ic_sort_waypoint_dark"/>
<net.osmand.plus.widgets.TextViewEx
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="@dimen/measurement_tool_button_margin"
android:layout_marginStart="@dimen/measurement_tool_button_margin"
android:ellipsize="end"
android:gravity="center_vertical"
android:maxLines="1"
android:text="@string/shared_string_sort"
android:textColor="?attr/color_dialog_buttons"
osmand:textAllCapsCompat="true"
osmand:typeface="@string/font_roboto_medium"/>
</LinearLayout>
<Space
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
<Button
android:id="@+id/save_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|center_vertical"
android:layout_marginEnd="@dimen/measurement_tool_button_margin"
android:layout_marginRight="@dimen/measurement_tool_button_margin"
android:background="@drawable/btn_round_blue"
android:ellipsize="end"
android:maxLines="1"
android:minHeight="@dimen/measurement_tool_button_height"
android:text="@string/shared_string_save"
android:textColor="@color/color_white"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</FrameLayout>

View file

@ -0,0 +1,152 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:osmand="http://schemas.android.com/tools">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:orientation="vertical"
android:background="@color/map_widget_blue"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/coordinate_input_toolbar"
android:layout_width="match_parent"
android:layout_height="@dimen/dashboard_map_toolbar"
app:contentInsetLeft="54dp"
app:contentInsetStart="54dp">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical">
<net.osmand.plus.widgets.TextViewEx
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:ellipsize="end"
android:maxLines="1"
android:gravity="center_vertical"
android:text="@string/coordinates"
android:textColor="@color/color_white"
osmand:typeface="@string/font_roboto_medium"
android:textSize="@dimen/dialog_header_text_size"/>
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/options_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:ellipsize="end"
android:maxLines="1"
android:paddingRight="16dp"
android:paddingLeft="16dp"
android:text="@string/shared_string_options"
osmand:typeface="@string/font_roboto_regular"
android:textAllCaps="true"
android:textSize="@dimen/default_list_text_size"
android:textColor="@color/color_white"
android:background="?attr/selectableItemBackground"/>
</LinearLayout>
</android.support.v7.widget.Toolbar>
<LinearLayout
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<studio.carbonylgroup.textfieldboxes.TextFieldBoxes
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content">
<studio.carbonylgroup.textfieldboxes.ExtendedEditText
android:id="@+id/latitude_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</studio.carbonylgroup.textfieldboxes.TextFieldBoxes>
<View
android:layout_width="16dp"
android:layout_height="match_parent"/>
<studio.carbonylgroup.textfieldboxes.TextFieldBoxes
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content">
<studio.carbonylgroup.textfieldboxes.ExtendedEditText
android:id="@+id/longitude_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</studio.carbonylgroup.textfieldboxes.TextFieldBoxes>
</LinearLayout>
<LinearLayout
android:padding="16dp"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<studio.carbonylgroup.textfieldboxes.TextFieldBoxes
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content">
<studio.carbonylgroup.textfieldboxes.ExtendedEditText
android:id="@+id/name_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</studio.carbonylgroup.textfieldboxes.TextFieldBoxes>
<View
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"/>
</LinearLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
<FrameLayout
android:layout_gravity="bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<GridView
osmand:visibility="gone"
android:id="@+id/keyboard_grid_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/dashboard_divider"
android:horizontalSpacing="1dp"
android:verticalSpacing="1dp"
android:stretchMode="columnWidth"
android:numColumns="3"/>
</FrameLayout>
</FrameLayout>

View file

@ -5,8 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:osmand="http://schemas.android.com/tools"
android:orientation="vertical"
xmlns:tools="http://schemas.android.com/tools">
android:orientation="vertical">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
@ -20,46 +19,38 @@
app:contentInsetStart="54dp">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical">
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:gravity="center_vertical">
<net.osmand.plus.widgets.TextViewEx
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:ellipsize="end"
android:maxLines="1"
android:gravity="center_vertical"
android:text="@string/map_markers"
android:textColor="@color/color_white"
osmand:typeface="@string/font_roboto_medium"
android:textSize="@dimen/dialog_header_text_size"/>
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/order_by_mode_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/options_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:ellipsize="end"
android:maxLines="1"
tools:text="Date added"
android:textColor="@color/white_80_transparent"
osmand:typeface="@string/font_roboto_medium"
android:textSize="@dimen/default_list_text_size"/>
</LinearLayout>
<ImageButton
android:id="@+id/options_button"
style="@style/Widget.AppCompat.ActionButton"
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@drawable/ic_overflow_menu_white"/>
android:paddingRight="16dp"
android:paddingLeft="16dp"
android:text="@string/shared_string_options"
osmand:typeface="@string/font_roboto_regular"
android:textAllCaps="true"
android:textSize="@dimen/default_list_text_size"
android:textColor="@color/color_white"
android:background="?attr/selectableItemBackground"/>
</LinearLayout>
</android.support.v7.widget.Toolbar>

View file

@ -97,7 +97,7 @@
android:layout_gravity="center_vertical|end"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.ListItemTitle"
android:textColor="@color/map_widget_blue_pressed"
tools:textColor="@color/map_widget_blue_pressed"
tools:text="Top bar"/>
</LinearLayout>
@ -110,6 +110,35 @@
android:layout_marginTop="@dimen/measurement_tool_bottom_divider_margin_top"
android:background="?attr/dashboard_divider"/>
<LinearLayout
android:id="@+id/coordinate_input_row"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:background="?attr/selectableItemBackground"
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding">
<ImageView
android:id="@+id/coordinate_input_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:src="@drawable/ic_action_coordinates_longitude"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxLines="1"
android:text="@string/coordinate_input"
android:textAppearance="@style/TextAppearance.ListItemTitle"/>
</LinearLayout>
<LinearLayout
android:id="@+id/build_route_row"
android:layout_width="match_parent"

View file

@ -90,7 +90,7 @@
</LinearLayout>
<LinearLayout
android:id="@+id/date_added_row"
android:id="@+id/date_added_asc_row"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:background="?attr/selectableItemBackground"
@ -102,7 +102,7 @@
android:gravity="center_vertical">
<ImageView
android:id="@+id/date_added_icon"
android:id="@+id/date_added_asc_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
@ -110,11 +110,40 @@
tools:src="@drawable/ic_action_sort_by_date"/>
<TextView
android:id="@+id/date_added_text"
android:id="@+id/date_added_asc_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="@string/date_added"
tools:text="Date added (Ascendingly)"
android:textAppearance="@style/TextAppearance.ListItemTitle"/>
</LinearLayout>
<LinearLayout
android:id="@+id/date_added_desc_row"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:background="?attr/selectableItemBackground"
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding"
android:gravity="center_vertical">
<ImageView
android:id="@+id/date_added_desc_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:src="@drawable/ic_action_sort_by_date"/>
<TextView
android:id="@+id/date_added_desc_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
tools:text="Date added (Descendingly)"
android:textAppearance="@style/TextAppearance.ListItemTitle"/>
</LinearLayout>

View file

@ -0,0 +1,101 @@
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:background="?attr/bg_color"
android:orientation="vertical">
<ScrollView
android:id="@+id/marker_save_as_track_scroll_view"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/content_linear_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="@dimen/bottom_sheet_content_padding_small">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/save_as_track_title"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_title_height"
android:gravity="center_vertical"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding"
android:text="@string/marker_save_as_track"
android:textAppearance="@style/TextAppearance.ListItemTitle"
osmand:typeface="@string/font_roboto_medium"/>
<TextView
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_descr_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding"
android:text="@string/marker_save_as_track_descr"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"/>
</LinearLayout>
</ScrollView>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dashboard_divider"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/close_button"
android:background="?attr/selectableItemBackground"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="@dimen/bottom_sheet_cancel_button_height"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/shared_string_cancel"
android:textAllCaps="true"
android:textColor="?attr/color_dialog_buttons"
android:textSize="@dimen/default_desc_text_size"
android:textStyle="bold"/>
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="?attr/dashboard_divider"/>
<TextView
android:id="@+id/save_button"
android:background="?attr/selectableItemBackground"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="@dimen/bottom_sheet_cancel_button_height"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/shared_string_save"
android:textAllCaps="true"
android:textColor="?attr/color_dialog_buttons"
android:textSize="@dimen/default_desc_text_size"
android:textStyle="bold"/>
</LinearLayout>
</FrameLayout>
</LinearLayout>

View file

@ -182,11 +182,17 @@
android:layout_marginTop="@dimen/bottom_sheet_content_padding_small"
android:background="?attr/dashboard_divider"/>
<RelativeLayout
<FrameLayout
android:id="@+id/top_bar_row_frame"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_list_item_height">
<LinearLayout
android:background="?attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/top_bar_row"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:foreground="?attr/selectableItemBackground"
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
@ -197,7 +203,6 @@
android:id="@+id/top_bar_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:background="@drawable/ic_action_device_top"
@ -205,11 +210,9 @@
<TextView
android:id="@+id/top_bar_text"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/top_bar_icon"
android:layout_toRightOf="@id/top_bar_icon"
android:maxLines="1"
android:text="@string/shared_string_topbar"
android:textAppearance="@style/TextAppearance.ListItemTitle"/>
@ -218,15 +221,21 @@
android:id="@+id/top_bar_radio_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="@null"
android:clickable="false"
android:focusable="false"/>
</RelativeLayout>
</LinearLayout>
<RelativeLayout
</FrameLayout>
<FrameLayout
android:id="@+id/widget_row_frame"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_list_item_height">
<LinearLayout
android:background="?attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/widget_row"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_list_item_height"
@ -241,7 +250,6 @@
android:id="@+id/widget_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:background="@drawable/ic_action_device_top"
@ -249,11 +257,9 @@
<TextView
android:id="@+id/widget_text"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/widget_icon"
android:layout_toRightOf="@id/widget_icon"
android:maxLines="1"
android:text="@string/shared_string_widgets"
android:textAppearance="@style/TextAppearance.ListItemTitle"/>
@ -262,15 +268,21 @@
android:id="@+id/widget_radio_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="@null"
android:clickable="false"
android:focusable="false"/>
</RelativeLayout>
</LinearLayout>
<RelativeLayout
</FrameLayout>
<FrameLayout
android:id="@+id/none_row_frame"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_list_item_height">
<LinearLayout
android:background="?attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/none_row"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_list_item_height"
@ -285,18 +297,15 @@
android:id="@+id/none_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:background="@drawable/ic_action_device_top"/>
<TextView
android:id="@+id/none_text"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/none_icon"
android:layout_toRightOf="@id/none_icon"
android:maxLines="1"
android:text="@string/shared_string_none"
android:textAppearance="@style/TextAppearance.ListItemTitle"/>
@ -305,13 +314,12 @@
android:id="@+id/none_radio_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="@null"
android:clickable="false"
android:focusable="false"/>
</RelativeLayout>
</LinearLayout>
</FrameLayout>
</LinearLayout>

View file

@ -29,10 +29,8 @@
<RelativeLayout
android:id="@+id/up_down_row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:paddingBottom="@dimen/measurement_tool_content_padding_medium"
android:paddingTop="@dimen/measurement_tool_content_padding_medium">
android:layout_height="@dimen/measurement_tool_up_down_row_height"
android:background="?attr/selectableItemBackground">
<ImageView
android:id="@+id/main_icon"
@ -126,9 +124,9 @@
android:layout_marginStart="@dimen/measurement_tool_text_margin"
android:layout_toEndOf="@id/main_icon"
android:layout_toRightOf="@id/main_icon"
tools:text="@string/add_point_after"
android:textAppearance="@style/TextAppearance.ListItemTitle"
android:visibility="gone"/>
android:visibility="gone"
tools:text="@string/add_point_after"/>
</RelativeLayout>
<View

View file

@ -0,0 +1,181 @@
<?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:id="@+id/up_down_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_up_down_row_height"
android:background="?attr/selectableItemBackground">
<ImageView
android:id="@+id/up_down_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/bottom_sheet_content_margin"
android:layout_marginLeft="@dimen/bottom_sheet_content_margin"
android:layout_marginRight="@dimen/bottom_sheet_content_margin"
android:layout_marginStart="@dimen/bottom_sheet_content_margin"
android:background="@null"
tools:src="@drawable/ic_action_arrow_down"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<TextView
android:id="@+id/markers_distance_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/measurement_tool_text_margin_small"
android:layout_marginLeft="@dimen/measurement_tool_text_margin"
android:layout_marginRight="@dimen/measurement_tool_text_margin_small"
android:layout_marginStart="@dimen/measurement_tool_text_margin"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.ListItemTitle"
tools:text="1.39 km,"/>
<TextView
android:id="@+id/markers_time_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_list_text_size"
tools:text="~ 45 min."/>
</LinearLayout>
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/select_all_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="@dimen/measurement_tool_text_button_padding_small"
android:paddingLeft="@dimen/measurement_tool_text_button_padding"
android:paddingRight="@dimen/measurement_tool_text_button_padding_small"
android:paddingStart="@dimen/measurement_tool_text_button_padding"
android:text="@string/shared_string_select_all"
android:textColor="?attr/color_dialog_buttons"
osmand:textAllCapsCompat="true"
osmand:typeface="@string/font_roboto_medium"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dashboard_divider"/>
<FrameLayout
android:id="@+id/markers_list_container"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_points_list_container_height"
android:background="@color/ctx_menu_info_view_bg_dark"
android:visibility="gone"
tools:visibility="visible">
<android.support.v7.widget.RecyclerView
android:id="@+id/markers_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<include layout="@layout/card_bottom_divider"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_gravity="bottom"
android:alpha="0.5"
android:scaleType="fitXY"
android:src="@drawable/bg_shadow_onmap"/>
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_controls_height">
<LinearLayout
android:id="@+id/sort_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:paddingLeft="@dimen/bottom_sheet_content_margin"
android:paddingRight="@dimen/bottom_sheet_content_margin">
<ImageView
android:id="@+id/sort_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="@null"
tools:src="@drawable/ic_sort_waypoint_dark"/>
<net.osmand.plus.widgets.TextViewEx
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="@dimen/measurement_tool_button_margin"
android:layout_marginStart="@dimen/measurement_tool_button_margin"
android:ellipsize="end"
android:gravity="center_vertical"
android:maxLines="1"
android:text="@string/shared_string_sort"
android:textColor="?attr/color_dialog_buttons"
osmand:textAllCapsCompat="true"
osmand:typeface="@string/font_roboto_medium"/>
</LinearLayout>
<Space
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
<Button
android:id="@+id/save_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|center_vertical"
android:layout_marginEnd="@dimen/measurement_tool_button_margin"
android:layout_marginRight="@dimen/measurement_tool_button_margin"
android:background="@drawable/btn_round_blue"
android:ellipsize="end"
android:maxLines="1"
android:minHeight="@dimen/measurement_tool_button_height"
android:text="@string/shared_string_save"
android:textColor="@color/color_white"/>
</LinearLayout>
</LinearLayout>
</FrameLayout>

View file

@ -0,0 +1,16 @@
<?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="56dp"
android:background="?attr/bg_color"
android:orientation="vertical">
<TextView
android:id="@+id/keyboard_item"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
tools:text="3"/>
</LinearLayout>

View file

@ -7,12 +7,18 @@
android:descendantFocusability="blocksDescendants"
android:orientation="vertical">
<include
android:id="@+id/top_divider"
layout="@layout/list_item_divider"
android:visibility="gone"
tools:visibility="visible"/>
<LinearLayout
android:id="@+id/main_layout"
android:background="?attr/bg_color"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:background="?attr/bg_color"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
@ -23,25 +29,25 @@
android:id="@+id/map_marker_reorder_icon"
android:layout_width="56dp"
android:layout_height="56dp"
android:scaleType="centerInside"
android:layout_gravity="center_vertical"
android:scaleType="centerInside"
android:tint="?attr/secondary_icon_color"
tools:src="@drawable/ic_action_reorder"/>
<View
tools:visibility="visible"
android:visibility="gone"
android:id="@+id/flag_icon_left_space"
android:layout_width="16dp"
android:layout_height="wrap_content"/>
android:layout_height="wrap_content"
android:visibility="gone"
tools:visibility="visible"/>
<android.support.v7.widget.AppCompatImageView
android:id="@+id/map_marker_icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
android:layout_marginRight="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
tools:src="@drawable/ic_action_flag_dark"/>
<LinearLayout
@ -55,36 +61,46 @@
android:layout_height="28dp">
<android.support.v7.widget.AppCompatTextView
android:layout_gravity="bottom"
android:id="@+id/map_marker_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_list_text_size"
tools:text="Van Gogh Museum"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:gravity="center_vertical">
<android.support.v7.widget.AppCompatTextView
android:id="@+id/map_marker_first_descr"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"
android:visibility="gone"
tools:text="Start • "
tools:visibility="visible"/>
<ImageView
android:id="@+id/map_marker_direction_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginRight="4dp"
android:layout_marginEnd="4dp"
android:layout_marginRight="4dp"
tools:src="@drawable/ic_direction_arrow"/>
<android.support.v7.widget.AppCompatTextView
android:id="@+id/map_marker_distance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxLines="1"
android:textSize="@dimen/default_desc_text_size"
tools:text="213 m"/>
@ -92,13 +108,12 @@
<View
android:id="@+id/map_marker_left_point_space"
android:layout_width="4dp"
android:layout_height="wrap_content"/>
android:layout_height="match_parent"/>
<android.support.v7.widget.AppCompatTextView
android:id="@+id/map_marker_point_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="•"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"
@ -108,13 +123,12 @@
<View
android:id="@+id/map_marker_right_point_space"
android:layout_width="4dp"
android:layout_height="wrap_content"/>
android:layout_height="match_parent"/>
<android.support.v7.widget.AppCompatTextView
android:id="@+id/map_marker_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?android:textColorSecondary"
@ -128,10 +142,21 @@
android:id="@+id/map_marker_options_button"
android:layout_width="56dp"
android:layout_height="56dp"
android:background="@drawable/marker_circle_background_light_with_inset"
android:focusableInTouchMode="true"
tools:background="@drawable/marker_circle_background_dark_with_inset"
tools:src="@drawable/ic_action_marker_passed"/>
<CheckBox
android:id="@+id/map_marker_check_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="16dp"
android:background="@null"
android:visibility="gone"
tools:visibility="visible"/>
</LinearLayout>
<View
@ -140,13 +165,13 @@
android:layout_height="1dp"
android:layout_marginLeft="56dp"
android:layout_marginStart="56dp"
android:background="?attr/dashboard_divider"/>
tools:background="?attr/dashboard_divider"/>
</LinearLayout>
<include layout="@layout/card_bottom_divider"
tools:visibility="visible"
<include
android:id="@+id/bottom_shadow"
layout="@layout/card_bottom_divider"
android:visibility="gone"
android:id="@+id/bottom_shadow"/>
tools:visibility="visible"/>
</LinearLayout>

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.TextInputLayout
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/shared_string_name">
<android.support.design.widget.TextInputEditText
android:id="@+id/name_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.design.widget.TextInputLayout>
</LinearLayout>

View file

@ -0,0 +1,23 @@
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<studio.carbonylgroup.textfieldboxes.TextFieldBoxes
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding"
osmand:labelText="@string/shared_string_name">
<studio.carbonylgroup.textfieldboxes.ExtendedEditText
android:id="@+id/name_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</studio.carbonylgroup.textfieldboxes.TextFieldBoxes>
</LinearLayout>

View file

@ -0,0 +1,97 @@
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/list_item_divider"/>
<LinearLayout
android:id="@+id/background_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/bg_color"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.AppCompatImageView
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_gravity="center_vertical"
android:scaleType="centerInside"
android:src="@drawable/map_pedestrian_location"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:minHeight="56dp"
android:orientation="vertical"
android:paddingBottom="12dp"
android:paddingTop="10dp">
<android.support.v7.widget.AppCompatTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/my_location"
android:textAppearance="@style/TextAppearance.ListItemTitle"/>
<android.support.v7.widget.AppCompatTextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:ellipsize="end"
android:maxLines="2"
android:text="@string/add_location_as_first_point_descr"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginLeft="56dp"
android:layout_marginStart="56dp">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/use_location_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="@dimen/measurement_tool_text_button_padding_small"
android:paddingRight="@dimen/measurement_tool_text_button_padding_small"
android:text="@string/use_location"
android:textColor="?attr/color_dialog_buttons"
osmand:textAllCapsCompat="true"
osmand:typeface="@string/font_roboto_medium"/>
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/do_not_use_location_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:paddingLeft="@dimen/measurement_tool_text_button_padding_small"
android:paddingStart="@dimen/measurement_tool_text_button_padding_small"
android:text="@string/shared_string_do_not_use"
android:textColor="?attr/color_dialog_buttons"
osmand:textAllCapsCompat="true"
osmand:typeface="@string/font_roboto_medium"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>

View file

@ -12,6 +12,6 @@
<item
android:id="@+id/action_history"
android:icon="@drawable/ic_action_history2"
android:icon="@drawable/ic_action_history"
android:title="@string/shared_string_history"/>
</menu>

View file

@ -104,6 +104,7 @@
<dimen name="measurement_tool_text_margin_small">6dp</dimen>
<dimen name="measurement_tool_text_margin">12dp</dimen>
<dimen name="measurement_tool_points_list_container_height">330dp</dimen>
<dimen name="measurement_tool_up_down_row_height">48dp</dimen>
<dimen name="measurement_tool_controls_height">78dp</dimen>
<dimen name="measurement_tool_text_button_padding_small">18dp</dimen>
<dimen name="measurement_tool_text_button_padding">24dp</dimen>

View file

@ -262,4 +262,6 @@
<color name="map_markers_on_map_color">#17828a</color>
<color name="show_direction_menu_selected_item_bg">#f2f4ff</color>
<color name="marker_circle_button_color_dark">#525e66</color>
</resources>

View file

@ -169,6 +169,7 @@
<dimen name="measurement_tool_text_margin_small">4dp</dimen>
<dimen name="measurement_tool_text_margin">8dp</dimen>
<dimen name="measurement_tool_points_list_container_height">220dp</dimen>
<dimen name="measurement_tool_up_down_row_height">48dp</dimen>
<dimen name="measurement_tool_controls_height">52dp</dimen>
<dimen name="measurement_tool_text_button_padding_small">12dp</dimen>
<dimen name="measurement_tool_text_button_padding">16dp</dimen>

View file

@ -9,6 +9,18 @@
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
-->
<string name="use_location">Use location</string>
<string name="add_location_as_first_point_descr">Add your location as first point to plan perfect route.</string>
<string name="my_location">My Location</string>
<string name="shared_string_finish">Finish</string>
<string name="plan_route">Plan route</string>
<string name="shared_string_sort">Sort</string>
<string name="coordinate_input">Coordinate input</string>
<string name="is_saved">is saved</string>
<string name="marker_save_as_track_descr">OsmAnd will save all your markers to a separate file, you can enter filename:</string>
<string name="marker_save_as_track">Save as track</string>
<string name="move_to_history">Move to history</string>
<string name="group_will_be_removed_after_restart">Group will be removed after restart</string>
<string name="show_guide_line">Show guide line</string>
<string name="show_arrows_on_the_map">Show arrows on the map</string>
<string name="show_passed">Show \'Last used\' date</string>

View file

@ -4,7 +4,6 @@ import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.text.format.DateFormat;
import net.osmand.IndexConstants;
import net.osmand.data.FavouritePoint;
@ -20,16 +19,13 @@ import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import static net.osmand.data.PointDescription.POINT_TYPE_MAP_MARKER;
@ -230,6 +226,7 @@ public class MapMarkersHelper {
settings = ctx.getSettings();
markersDbHelper = ctx.getMapMarkersDbHelper();
startFromMyLocation = settings.ROUTE_MAP_MARKERS_START_MY_LOC.get();
removeDisabledGroups();
loadMarkers();
createMapMarkersGroups();
}
@ -372,6 +369,7 @@ public class MapMarkersHelper {
}
if (!favGroup.visible) {
removeActiveMarkersFromSyncGroup(group.getId());
removeActiveMarkersFromGroup(group.getId());
return;
}
if (group.getColor() == -1) {
@ -394,6 +392,7 @@ public class MapMarkersHelper {
GPXFile gpx = selectedGpxFile == null ? null : selectedGpxFile.getGpxFile();
if (gpx == null) {
removeActiveMarkersFromSyncGroup(group.getId());
removeActiveMarkersFromGroup(group.getId());
return;
}
@ -441,6 +440,7 @@ public class MapMarkersHelper {
if (!marker.history) {
markersDbHelper.removeMarker(marker, false);
mapMarkers.remove(marker);
removeMarkerFromGroup(marker);
needRefresh = true;
}
}
@ -480,6 +480,21 @@ public class MapMarkersHelper {
}
}
public void addMarker(MapMarker marker, int position) {
if (marker != null) {
markersDbHelper.addMarker(marker);
if (marker.history) {
mapMarkersHistory.add(position, marker);
sortMarkers(mapMarkersHistory, true, OsmandSettings.MapMarkersOrderByMode.DATE_ADDED_DESC);
} else {
mapMarkers.add(position, marker);
checkAndFixActiveMarkersOrderIfNeeded();
}
addMarkerToGroup(marker);
refresh();
}
}
public void restoreMarkerFromHistory(MapMarker marker, int position) {
if (marker != null) {
markersDbHelper.restoreMapMarkerFromHistory(marker);
@ -506,12 +521,17 @@ public class MapMarkersHelper {
}
}
public void removeMarkerFromHistory(MapMarker marker) {
public void removeMarker(MapMarker marker) {
if (marker != null) {
markersDbHelper.removeMarker(marker, true);
boolean history = marker.history;
markersDbHelper.removeMarker(marker, history);
if (history) {
mapMarkersHistory.remove(marker);
refresh();
} else {
mapMarkers.remove(marker);
}
removeMarkerFromGroup(marker);
refresh();
}
}
@ -531,6 +551,18 @@ public class MapMarkersHelper {
return mapMarkersHistory;
}
public void deselectAllActiveMarkers() {
for (MapMarker m : mapMarkers) {
m.selected = false;
}
}
public void selectAllActiveMarkers() {
for (MapMarker m : mapMarkers) {
m.selected = true;
}
}
public List<MapMarker> getSelectedMarkers() {
List<MapMarker> list = new ArrayList<>();
for (MapMarker m : this.mapMarkers) {
@ -610,8 +642,23 @@ public class MapMarkersHelper {
if (removeActiveMarkers) {
removeActiveMarkersFromSyncGroup(id);
}
MapMarkersGroup group = getMapMarkerGroupByName(id);
if (group != null) {
mapMarkersGroups.remove(group);
}
}
}
public void removeDisabledGroups() {
markersDbHelper.removeDisabledGroups();
}
public void updateGroupDisabled(String id, boolean disabled) {
if (id != null) {
markersDbHelper.updateSyncGroupDisabled(id, disabled);
}
loadMarkers();
}
public void removeActiveMarkersFromSyncGroup(String syncGroupId) {
if (syncGroupId != null) {
@ -652,7 +699,7 @@ public class MapMarkersHelper {
}
if (colorIndex == -1) {
if (mapMarkers.size() > 0) {
colorIndex = (mapMarkers.get(mapMarkers.size() - 1).colorIndex + 1) % MAP_MARKERS_COLORS_COUNT;
colorIndex = (mapMarkers.get(0).colorIndex + 1) % MAP_MARKERS_COLORS_COUNT;
} else {
colorIndex = 0;
}
@ -672,7 +719,7 @@ public class MapMarkersHelper {
marker.history = false;
marker.nextKey = MapMarkersDbHelper.TAIL_NEXT_VALUE;
markersDbHelper.addMarker(marker);
mapMarkers.add(marker);
mapMarkers.add(0, marker);
addMarkerToGroup(marker);
checkAndFixActiveMarkersOrderIfNeeded();
}
@ -688,7 +735,7 @@ public class MapMarkersHelper {
}
}
public void moveMapMarker(@Nullable MapMarker marker, LatLon latLon) {
public void moveMapMarker(MapMarker marker, LatLon latLon) {
if (marker != null) {
LatLon point = new LatLon(latLon.getLatitude(), latLon.getLongitude());
int index = mapMarkers.indexOf(marker);
@ -699,6 +746,7 @@ public class MapMarkersHelper {
markersDbHelper.updateMarker(marker);
checkAndFixActiveMarkersOrderIfNeeded();
refresh();
lookupAddress(marker);
}
}
@ -792,13 +840,11 @@ public class MapMarkersHelper {
}
}
public void generateGpx() {
public String generateGpx(String fileName) {
final File dir = ctx.getAppPath(IndexConstants.GPX_INDEX_DIR + "/map markers");
if (!dir.exists()) {
dir.mkdirs();
}
Date date = new Date();
String fileName = DateFormat.format("yyyy-MM-dd", date).toString() + "_" + new SimpleDateFormat("HH-mm_EEE", Locale.US).format(date);
File fout = new File(dir, fileName + ".gpx");
int ind = 1;
while (fout.exists()) {
@ -814,6 +860,7 @@ public class MapMarkersHelper {
file.addPoint(wpt);
}
GPXUtilities.writeGpxFile(fout, file, ctx);
return fout.getAbsolutePath();
}
private void removeHistoryMarkersFromGroups() {
@ -825,15 +872,36 @@ public class MapMarkersHelper {
}
}
markersGroup.setMarkers(activeMarkers);
updateShowHideHistoryButtonInGroup(markersGroup);
updateGroup(markersGroup);
}
}
private void updateShowHideHistoryButtonInGroup(MapMarkersGroup mapMarkersGroup) {
private void removeActiveMarkersFromGroup(String groupId) {
MapMarkersGroup group = getMapMarkerGroupByKey(groupId);
if (group != null) {
List<MapMarker> markers = group.getMarkers();
List<MapMarker> historyMarkers = new ArrayList<>();
for (MapMarker marker : markers) {
if (marker.history) {
historyMarkers.add(marker);
}
}
group.setMarkers(historyMarkers);
updateGroup(group);
}
}
public void updateGroup(MapMarkersGroup mapMarkersGroup) {
if (mapMarkersGroup.getMarkers().size() == 0) {
mapMarkersGroups.remove(mapMarkersGroup);
return;
}
int historyMarkersCount = mapMarkersGroup.getHistoryMarkers().size();
ShowHideHistoryButton showHideHistoryButton = mapMarkersGroup.getShowHideHistoryButton();
if (showHideHistoryButton != null && historyMarkersCount == 0) {
if (showHideHistoryButton != null) {
if (historyMarkersCount == 0) {
mapMarkersGroup.setShowHideHistoryButton(null);
}
} else if (historyMarkersCount > 0) {
showHideHistoryButton = new ShowHideHistoryButton();
showHideHistoryButton.setShowHistory(false);
@ -847,7 +915,7 @@ public class MapMarkersHelper {
MapMarkersGroup mapMarkersGroup = getMapMarkerGroupByName(marker.groupName);
if (mapMarkersGroup != null) {
mapMarkersGroup.getMarkers().add(marker);
updateShowHideHistoryButtonInGroup(mapMarkersGroup);
updateGroup(mapMarkersGroup);
if (mapMarkersGroup.getName() == null) {
sortMarkers(mapMarkersGroup.getMarkers(), false, OsmandSettings.MapMarkersOrderByMode.DATE_ADDED_DESC);
}
@ -861,18 +929,25 @@ public class MapMarkersHelper {
private MapMarkersGroup createMapMarkerGroup(MapMarker marker) {
MapMarkersGroup group = new MapMarkersGroup();
if (marker.groupName != null) {
group.setName(marker.groupName);
group.setGroupKey(marker.groupKey);
MapMarkersHelper.MarkersSyncGroup syncGroup = getGroup(marker.groupKey);
if (syncGroup != null) {
group.setType(syncGroup.getType());
} else {
group.setType(MarkersSyncGroup.FAVORITES_TYPE);
}
group.setColor(MapMarker.getColorId(marker.colorIndex));
}
group.setCreationDate(marker.creationDate);
mapMarkersGroups.add(group);
sortGroups();
return group;
}
private void createHeaderAndHistoryButtonInGroup(MapMarkersGroup group) {
if (group.getName() != null) {
GroupHeader header = new GroupHeader();
int type = group.getType();
if (type != -1) {
@ -880,7 +955,8 @@ public class MapMarkersHelper {
}
header.setGroup(group);
group.setGroupHeader(header);
updateShowHideHistoryButtonInGroup(group);
updateGroup(group);
}
}
private void removeMarkerFromGroup(MapMarker marker) {
@ -888,7 +964,7 @@ public class MapMarkersHelper {
MapMarkersGroup mapMarkersGroup = getMapMarkerGroupByName(marker.groupName);
if (mapMarkersGroup != null) {
mapMarkersGroup.getMarkers().remove(marker);
updateShowHideHistoryButtonInGroup(mapMarkersGroup);
updateGroup(mapMarkersGroup);
}
}
}
@ -915,7 +991,17 @@ public class MapMarkersHelper {
} else {
MapMarkersGroup group = groupsMap.get(groupName);
if (group == null) {
group = createMapMarkerGroup(marker);
group = new MapMarkersGroup();
group.setName(marker.groupName);
group.setGroupKey(marker.groupKey);
MapMarkersHelper.MarkersSyncGroup syncGroup = getGroup(marker.groupKey);
if (syncGroup != null) {
group.setType(syncGroup.getType());
} else {
group.setType(MarkersSyncGroup.FAVORITES_TYPE);
}
group.setColor(MapMarker.getColorId(marker.colorIndex));
group.setCreationDate(marker.creationDate);
groupsMap.put(groupName, group);
} else {
long markerCreationDate = marker.creationDate;
@ -927,20 +1013,27 @@ public class MapMarkersHelper {
}
}
mapMarkersGroups = new ArrayList<>(groupsMap.values());
sortGroups(mapMarkersGroups);
if (noGroup != null) {
mapMarkersGroups.add(noGroup);
}
sortGroups();
for (MapMarkersGroup group : mapMarkersGroups) {
createHeaderAndHistoryButtonInGroup(group);
}
if (noGroup != null) {
sortMarkers(noGroup.getMarkers(), false, OsmandSettings.MapMarkersOrderByMode.DATE_ADDED_DESC);
mapMarkersGroups.add(0, noGroup);
}
}
private void sortGroups(List<MapMarkersGroup> groups) {
Collections.sort(groups, new Comparator<MapMarkersGroup>() {
private void sortGroups() {
if (mapMarkersGroups.size() > 0) {
MapMarkersGroup noGroup = null;
for (int i = 0; i < mapMarkersGroups.size(); i++) {
MapMarkersGroup group = mapMarkersGroups.get(i);
if (group.getName() == null) {
sortMarkers(group.getMarkers(), false, OsmandSettings.MapMarkersOrderByMode.DATE_ADDED_DESC);
noGroup = mapMarkersGroups.remove(i);
}
}
Collections.sort(mapMarkersGroups, new Comparator<MapMarkersGroup>() {
@Override
public int compare(MapMarkersGroup group1, MapMarkersGroup group2) {
long t1 = group1.getCreationDate();
@ -954,6 +1047,10 @@ public class MapMarkersHelper {
}
}
});
if (noGroup != null) {
mapMarkersGroups.add(0, noGroup);
}
}
}
public MapMarkersGroup getMapMarkerGroupByName(String name) {
@ -966,8 +1063,19 @@ public class MapMarkersHelper {
return null;
}
public MapMarkersGroup getMapMarkerGroupByKey(String key) {
for (MapMarkersGroup group : mapMarkersGroups) {
if ((key == null && group.getGroupKey() == null)
|| (group.getGroupKey() != null && group.getGroupKey().equals(key))) {
return group;
}
}
return null;
}
public static class MapMarkersGroup {
private String name;
private String groupKey;
private GroupHeader header;
private int type = -1;
private List<MapMarker> markers = new ArrayList<>();
@ -984,6 +1092,14 @@ public class MapMarkersHelper {
this.name = name;
}
public String getGroupKey() {
return groupKey;
}
public void setGroupKey(String groupKey) {
this.groupKey = groupKey;
}
public GroupHeader getGroupHeader() {
return header;
}

View file

@ -3158,12 +3158,17 @@ public class OsmandSettings {
}
public enum MapMarkersOrderByMode {
CUSTOM,
DISTANCE_DESC,
DISTANCE_ASC,
NAME,
DATE_ADDED_DESC,
DATE_ADDED_ASC;
public boolean isCustom() {
return this == CUSTOM;
}
public boolean isDistanceDescending() {
return this == DISTANCE_DESC;
}

View file

@ -187,14 +187,8 @@ public class EditFavoriteGroupDialogFragment extends BottomSheetDialogFragment {
addToMarkersView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
List<LatLon> points = new ArrayList<>(group.points.size());
List<PointDescription> names = new ArrayList<>(group.points.size());
for (FavouritePoint fp : group.points) {
points.add(new LatLon(fp.getLatitude(), fp.getLongitude()));
names.add(new PointDescription(PointDescription.POINT_TYPE_MAP_MARKER, fp.getName()));
}
markersHelper.addMarkersSyncGroup(syncGroup);
markersHelper.addMapMarkers(points, names, syncGroup);
markersHelper.syncGroup(syncGroup);
dismiss();
MapActivity.launchMapActivityMoveToTop(getActivity());
}

View file

@ -411,7 +411,8 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment {
new MarkersSyncGroup(favGr.name, favGr.name, MarkersSyncGroup.FAVORITES_TYPE, favGr.color);
if (entry.getValue().size() == favGr.points.size()) {
markersHelper.addMarkersSyncGroup(syncGr);
}
markersHelper.syncGroup(syncGr);
} else {
for (FavouritePoint fp : entry.getValue()) {
points.add(new LatLon(fp.getLatitude(), fp.getLongitude()));
names.add(new PointDescription(PointDescription.POINT_TYPE_MAP_MARKER, fp.getName()));
@ -420,6 +421,7 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment {
points.clear();
names.clear();
}
}
MapActivity.launchMapActivityMoveToTop(getActivity());
} else {
final TargetPointsHelper targetPointsHelper = getMyApplication().getTargetPointsHelper();

View file

@ -59,6 +59,7 @@ import net.osmand.plus.AppInitializer;
import net.osmand.plus.AppInitializer.AppInitializeListener;
import net.osmand.plus.AppInitializer.InitEvents;
import net.osmand.plus.ApplicationMode;
import net.osmand.plus.GPXUtilities;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
import net.osmand.plus.MapMarkersHelper.MapMarker;
import net.osmand.plus.MapMarkersHelper.MapMarkerChangedListener;
@ -97,6 +98,8 @@ import net.osmand.plus.mapcontextmenu.other.DestinationReachedMenu;
import net.osmand.plus.mapcontextmenu.other.MapRouteInfoMenu;
import net.osmand.plus.mapcontextmenu.other.MapRouteInfoMenuFragment;
import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu;
import net.osmand.plus.mapmarkers.MapMarkersDialogFragment;
import net.osmand.plus.mapmarkers.PlanRouteFragment;
import net.osmand.plus.measurementtool.MeasurementEditingContext;
import net.osmand.plus.measurementtool.MeasurementToolFragment;
import net.osmand.plus.measurementtool.NewGpxData;
@ -503,6 +506,12 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
return;
}
}
if (getPlanRouteFragment() != null) {
if (getPlanRouteFragment().quit(true)) {
MapMarkersDialogFragment.showInstance(this);
}
return;
}
if (getMeasurementToolFragment() != null) {
getMeasurementToolFragment().quit(true);
return;
@ -1724,6 +1733,11 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
return fragment!= null && !fragment.isDetached() && !fragment.isRemoving() ? (QuickSearchDialogFragment) fragment : null;
}
public PlanRouteFragment getPlanRouteFragment() {
Fragment fragment = getSupportFragmentManager().findFragmentByTag(PlanRouteFragment.TAG);
return fragment != null && !fragment.isDetached() && !fragment.isRemoving() ? (PlanRouteFragment) fragment : null;
}
public MeasurementToolFragment getMeasurementToolFragment() {
Fragment fragment = getSupportFragmentManager().findFragmentByTag(MeasurementToolFragment.TAG);
return fragment != null && !fragment.isDetached() && !fragment.isRemoving() ? (MeasurementToolFragment) fragment : null;

View file

@ -0,0 +1,148 @@
package net.osmand.plus.mapmarkers;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.Toolbar;
import android.text.InputType;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.TextView;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
public class CoordinateInputDialogFragment extends DialogFragment {
public static final String TAG = "CoordinateInputDialogFragment";
private boolean lightTheme;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
OsmandApplication app = getMyApplication();
lightTheme = app.getSettings().OSMAND_THEME.get() == OsmandSettings.OSMAND_LIGHT_THEME;
int themeId = lightTheme ? R.style.OsmandLightTheme : R.style.OsmandDarkTheme;
setStyle(STYLE_NO_FRAME, themeId);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
final View mainView = inflater.inflate(R.layout.fragment_coordinate_input_dialog, container);
final MapActivity mapActivity = getMapActivity();
Toolbar toolbar = (Toolbar) mainView.findViewById(R.id.coordinate_input_toolbar);
if (!lightTheme) {
toolbar.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.actionbar_dark_color));
}
toolbar.setNavigationIcon(getMyApplication().getIconsCache().getIcon(R.drawable.ic_arrow_back));
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dismiss();
}
});
final View optionsButton = mainView.findViewById(R.id.options_button);
optionsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
final EditText latitudeEditText = (EditText) mainView.findViewById(R.id.latitude_edit_text);
final EditText longitudeEditText = (EditText) mainView.findViewById(R.id.longitude_edit_text);
final EditText nameEditText = (EditText) mainView.findViewById(R.id.name_edit_text);
View.OnTouchListener editTextOnTouchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
EditText editText = null;
switch (view.getId()) {
case R.id.latitude_edit_text:
editText = latitudeEditText;
break;
case R.id.longitude_edit_text:
editText = longitudeEditText;
break;
case R.id.name_edit_text:
editText = nameEditText;
break;
}
if (editText != null) {
editText.requestFocus();
}
return true;
}
};
latitudeEditText.setOnTouchListener(editTextOnTouchListener);
longitudeEditText.setOnTouchListener(editTextOnTouchListener);
nameEditText.setOnTouchListener(editTextOnTouchListener);
String[] keyboardItems = new String[] { "1", "2", "3",
"4", "5", "6",
"7", "8", "9",
getString(R.string.shared_string_delete), "0", getString(R.string.shared_string_clear) };
GridView keyboardGrid = (GridView) mainView.findViewById(R.id.keyboard_grid_view);
KeyboardAdapter keyboardAdapter = new KeyboardAdapter(mapActivity, keyboardItems);
keyboardGrid.setAdapter(keyboardAdapter);
return mainView;
}
private MapActivity getMapActivity() {
return (MapActivity) getActivity();
}
private OsmandApplication getMyApplication() {
return (OsmandApplication) getActivity().getApplication();
}
public static boolean showInstance(@NonNull MapActivity mapActivity) {
try {
if (mapActivity.isActivityDestroyed()) {
return false;
}
CoordinateInputDialogFragment fragment = new CoordinateInputDialogFragment();
fragment.show(mapActivity.getSupportFragmentManager(), TAG);
return true;
} catch (RuntimeException e) {
return false;
}
}
private class KeyboardAdapter extends ArrayAdapter<String> {
KeyboardAdapter(@NonNull Context context, String[] items) {
super(context, 0, items);
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.input_coordinate_keyboard_item, parent, false);
}
((TextView) convertView.findViewById(R.id.keyboard_item)).setText(getItem(position));
return convertView;
}
}
}

View file

@ -11,6 +11,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import net.osmand.AndroidUtils;
import net.osmand.Location;
import net.osmand.data.LatLon;
import net.osmand.plus.MapMarkersHelper.MapMarker;
@ -32,16 +33,20 @@ public class MapMarkersActiveFragment extends Fragment implements OsmAndCompassL
private Location location;
private Float heading;
private boolean locationUpdateStarted;
private boolean compassUpdateAllowed = true;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
final RecyclerView recyclerView = new RecyclerView(getContext());
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
final MapActivity mapActivity = (MapActivity) getActivity();
boolean isSmartphone = getResources().getConfiguration().smallestScreenWidthDp < 600;
recyclerView.setPadding(0, 0, 0, AndroidUtils.dpToPx(mapActivity, isSmartphone ? 72 : 108));
recyclerView.setClipToPadding(false);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
adapter = new MapMarkersActiveAdapter(mapActivity);
final ItemTouchHelper touchHelper = new ItemTouchHelper(new MapMarkersItemTouchHelperCallback(adapter));
final ItemTouchHelper touchHelper = new ItemTouchHelper(new MapMarkersItemTouchHelperCallback(mapActivity, adapter));
touchHelper.attachToRecyclerView(recyclerView);
adapter.setAdapterListener(new MapMarkersActiveAdapterListener() {
@ -60,22 +65,36 @@ public class MapMarkersActiveFragment extends Fragment implements OsmAndCompassL
@Override
public void onDragStarted(RecyclerView.ViewHolder holder) {
compassUpdateAllowed = false;
fromPosition = holder.getAdapterPosition();
touchHelper.startDrag(holder);
}
@Override
public void onDragEnded(RecyclerView.ViewHolder holder) {
public void onDragOrSwipeEnded(RecyclerView.ViewHolder holder) {
compassUpdateAllowed = true;
toPosition = holder.getAdapterPosition();
if (toPosition >= 0 && fromPosition >= 0 && toPosition != fromPosition) {
hideSnackbar();
mapActivity.getMyApplication().getMapMarkersHelper().checkAndFixActiveMarkersOrderIfNeeded();
adapter.notifyDataSetChanged();
mapActivity.getMyApplication().getSettings().MAP_MARKERS_ORDER_BY_MODE.set(OsmandSettings.MapMarkersOrderByMode.CUSTOM);
}
}
@Override
public void onSwipeStarted() {
compassUpdateAllowed = false;
}
});
recyclerView.setAdapter(adapter);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
compassUpdateAllowed = newState == RecyclerView.SCROLL_STATE_IDLE;
}
});
return recyclerView;
}
@ -143,6 +162,9 @@ public class MapMarkersActiveFragment extends Fragment implements OsmAndCompassL
}
private void updateLocationUi() {
if (!compassUpdateAllowed) {
return;
}
final MapActivity mapActivity = (MapActivity) getActivity();
if (mapActivity != null && adapter != null) {
mapActivity.getMyApplication().runInUIThread(new Runnable() {

View file

@ -21,7 +21,7 @@ import java.util.Random;
public class MapMarkersDbHelper {
private static final int DB_VERSION = 7;
private static final int DB_VERSION = 9;
public static final String DB_NAME = "map_markers_db";
private static final String MARKERS_TABLE_NAME = "map_markers";
@ -36,6 +36,7 @@ public class MapMarkersDbHelper {
private static final String MARKERS_COL_GROUP_KEY = "group_key";
private static final String MARKERS_COL_COLOR = "marker_color";
private static final String MARKERS_COL_NEXT_KEY = "marker_next_key";
private static final String MARKERS_COL_DISABLED = "marker_disabled";
private static final String MARKERS_TABLE_CREATE = "CREATE TABLE IF NOT EXISTS " +
MARKERS_TABLE_NAME + " (" +
@ -49,7 +50,8 @@ public class MapMarkersDbHelper {
MARKERS_COL_GROUP_NAME + " TEXT, " +
MARKERS_COL_GROUP_KEY + " TEXT, " +
MARKERS_COL_COLOR + " int, " +
MARKERS_COL_NEXT_KEY + " TEXT);";
MARKERS_COL_NEXT_KEY + " TEXT, " +
MARKERS_COL_DISABLED + " int);";
private static final String MARKERS_TABLE_SELECT = "SELECT " +
MARKERS_COL_ID + ", " +
@ -62,19 +64,22 @@ public class MapMarkersDbHelper {
MARKERS_COL_GROUP_NAME + ", " +
MARKERS_COL_GROUP_KEY + ", " +
MARKERS_COL_COLOR + ", " +
MARKERS_COL_NEXT_KEY +
MARKERS_COL_NEXT_KEY + ", " +
MARKERS_COL_DISABLED +
" FROM " + MARKERS_TABLE_NAME;
private static final String GROUPS_TABLE_NAME = "map_markers_groups";
private static final String GROUPS_COL_ID = "group_id";
private static final String GROUPS_COL_NAME = "group_name";
private static final String GROUPS_COL_TYPE = "group_type";
private static final String GROUPS_COL_DISABLED = "group_disabled";
private static final String GROUPS_TABLE_CREATE = "CREATE TABLE IF NOT EXISTS " +
GROUPS_TABLE_NAME + " (" +
GROUPS_COL_ID + " TEXT PRIMARY KEY, " +
GROUPS_COL_NAME + " TEXT, " +
GROUPS_COL_TYPE + " int);";
GROUPS_COL_TYPE + " int, " +
GROUPS_COL_DISABLED + " int);"; // 1 = true, 0 = false
private static final String GROUPS_TABLE_SELECT = "SELECT " +
GROUPS_COL_ID + ", " +
@ -117,10 +122,18 @@ public class MapMarkersDbHelper {
}
private void onUpgrade(SQLiteConnection db, int oldVersion, int newVersion) {
// When the DB_VERSION will increase from 7, DROP TABLE must be removed. Existing markers should not be deleted.
db.execSQL("DROP TABLE IF EXISTS " + MARKERS_TABLE_NAME);
db.execSQL("DROP TABLE IF EXISTS " + GROUPS_TABLE_NAME);
onCreate(db);
if (oldVersion < 8) {
db.execSQL("ALTER TABLE " + MARKERS_TABLE_NAME + " ADD " + MARKERS_COL_DISABLED + " int");
db.execSQL("ALTER TABLE " + GROUPS_TABLE_NAME + " ADD " + GROUPS_COL_DISABLED + " int");
}
if (oldVersion < 9) {
db.execSQL("UPDATE " + GROUPS_TABLE_NAME +
" SET " + GROUPS_COL_DISABLED + " = ? " +
"WHERE " + GROUPS_COL_DISABLED + " IS NULL", new Object[]{0});
db.execSQL("UPDATE " + MARKERS_TABLE_NAME +
" SET " + MARKERS_COL_DISABLED + " = ? " +
"WHERE " + MARKERS_COL_DISABLED + " IS NULL", new Object[]{0});
}
}
private void saveExistingMarkersToDb() {
@ -158,7 +171,7 @@ public class MapMarkersDbHelper {
SQLiteConnection db = openConnection(false);
if (db != null) {
try {
db.execSQL("INSERT INTO " + GROUPS_TABLE_NAME + " VALUES (?, ?, ?)", new Object[]{id, name, type});
db.execSQL("INSERT INTO " + GROUPS_TABLE_NAME + " VALUES (?, ?, ?, ?)", new Object[]{id, name, type, 0});
} finally {
db.close();
}
@ -235,6 +248,34 @@ public class MapMarkersDbHelper {
}
}
public void updateSyncGroupDisabled(String id, boolean disabled) {
SQLiteConnection db = openConnection(false);
if (db != null) {
try {
db.execSQL("UPDATE " + GROUPS_TABLE_NAME +
" SET " + GROUPS_COL_DISABLED + " = ? " +
"WHERE " + GROUPS_COL_ID + " = ?", new Object[]{disabled ? 1 : 0, id});
db.execSQL("UPDATE " + MARKERS_TABLE_NAME +
" SET " + MARKERS_COL_DISABLED + " = ? " +
"WHERE " + MARKERS_COL_GROUP_KEY + " = ?", new Object[]{disabled ? 1 : 0, id});
} finally {
db.close();
}
}
}
public void removeDisabledGroups() {
SQLiteConnection db = openConnection(false);
if (db != null) {
try {
db.execSQL("DELETE FROM " + GROUPS_TABLE_NAME + " WHERE " + GROUPS_COL_DISABLED + " = ? ", new Object[]{1});
db.execSQL("DELETE FROM " + MARKERS_TABLE_NAME + " WHERE " + MARKERS_COL_DISABLED + " = ? ", new Object[]{1});
} finally {
db.close();
}
}
}
public void addMarker(MapMarker marker) {
addMarker(marker, false);
}
@ -278,10 +319,10 @@ public class MapMarkersDbHelper {
"WHERE " + MARKERS_COL_NEXT_KEY + " = ?", new Object[]{marker.id, TAIL_NEXT_VALUE});
}
db.execSQL("INSERT INTO " + MARKERS_TABLE_NAME + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
db.execSQL("INSERT INTO " + MARKERS_TABLE_NAME + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
new Object[]{marker.id, marker.getLatitude(), marker.getLongitude(), descr, active,
currentTime, visited, marker.groupName, marker.groupKey, marker.colorIndex,
marker.history ? HISTORY_NEXT_VALUE : TAIL_NEXT_VALUE});
marker.history ? HISTORY_NEXT_VALUE : TAIL_NEXT_VALUE, 0});
}
public List<MapMarker> getMarkersFromGroup(MarkersSyncGroup group) {
@ -328,8 +369,8 @@ public class MapMarkersDbHelper {
SQLiteConnection db = openConnection(true);
if (db != null) {
try {
SQLiteCursor query = db.rawQuery(MARKERS_TABLE_SELECT + " WHERE " + MARKERS_COL_ACTIVE + " = ?",
new String[]{String.valueOf(1)});
SQLiteCursor query = db.rawQuery(MARKERS_TABLE_SELECT + " WHERE " + MARKERS_COL_ACTIVE + " = ? " + "AND " + MARKERS_COL_DISABLED + " = ?",
new String[]{String.valueOf(1), String.valueOf(0)});
if (query.moveToFirst()) {
do {
MapMarker marker = readItem(query);
@ -469,8 +510,8 @@ public class MapMarkersDbHelper {
SQLiteConnection db = openConnection(true);
if (db != null) {
try {
SQLiteCursor query = db.rawQuery(MARKERS_TABLE_SELECT + " WHERE " + MARKERS_COL_ACTIVE + " = ?",
new String[]{String.valueOf(0)});
SQLiteCursor query = db.rawQuery(MARKERS_TABLE_SELECT + " WHERE " + MARKERS_COL_ACTIVE + " = ? " + "AND " + MARKERS_COL_DISABLED + " = ?",
new String[]{String.valueOf(0), String.valueOf(0)});
if (query.moveToFirst()) {
do {
markers.add(readItem(query));

View file

@ -1,5 +1,6 @@
package net.osmand.plus.mapmarkers;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@ -23,9 +24,10 @@ import net.osmand.plus.OsmandSettings;
import net.osmand.plus.OsmandSettings.MapMarkersOrderByMode;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.dashboard.DashboardOnMap;
import net.osmand.plus.activities.TrackActivity;
import net.osmand.plus.mapmarkers.OptionsBottomSheetDialogFragment.MarkerOptionsFragmentListener;
import net.osmand.plus.mapmarkers.OrderByBottomSheetDialogFragment.OrderByFragmentListener;
import net.osmand.plus.mapmarkers.SaveAsTrackBottomSheetDialogFragment.MarkerSaveAsTrackFragmentListener;
import net.osmand.plus.mapmarkers.ShowDirectionBottomSheetDialogFragment.ShowDirectionFragmentListener;
import java.util.ArrayList;
@ -42,7 +44,6 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm
private Snackbar snackbar;
private LockableViewPager viewPager;
private TextView orderByModeTitle;
private boolean lightTheme;
@ -93,6 +94,10 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm
if (orderByFragment != null) {
((OrderByBottomSheetDialogFragment) orderByFragment).setListener(createOrderByFragmentListener());
}
Fragment saveAsTrackFragment = fragmentManager.findFragmentByTag(SaveAsTrackBottomSheetDialogFragment.TAG);
if (saveAsTrackFragment != null) {
((SaveAsTrackBottomSheetDialogFragment) saveAsTrackFragment).setListener(createSaveAsTrackFragmentListener());
}
View mainView = inflater.inflate(R.layout.fragment_map_markers_dialog, container);
@ -100,7 +105,6 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm
if (!lightTheme) {
toolbar.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.actionbar_dark_color));
}
orderByModeTitle = toolbar.findViewById(R.id.order_by_mode_text);
setOrderByMode(getMyApplication().getSettings().MAP_MARKERS_ORDER_BY_MODE.get());
toolbar.setNavigationIcon(getMyApplication().getIconsCache().getIcon(R.drawable.ic_arrow_back));
@ -139,8 +143,8 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm
if (viewPager.getCurrentItem() != 0) {
activeFragment.updateAdapter();
historyFragment.hideSnackbar();
groupsFragment.hideSnackbar();
}
orderByModeTitle.setVisibility(View.VISIBLE);
viewPager.setCurrentItem(0);
optionsButton.setVisibility(View.VISIBLE);
return true;
@ -151,7 +155,6 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm
activeFragment.hideSnackbar();
historyFragment.hideSnackbar();
}
orderByModeTitle.setVisibility(View.GONE);
viewPager.setCurrentItem(1);
optionsButton.setVisibility(View.GONE);
return true;
@ -159,9 +162,9 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm
activeFragment.stopLocationUpdate();
if (viewPager.getCurrentItem() != 2) {
historyFragment.updateAdapter();
groupsFragment.hideSnackbar();
activeFragment.hideSnackbar();
}
orderByModeTitle.setVisibility(View.GONE);
viewPager.setCurrentItem(2);
optionsButton.setVisibility(View.GONE);
return true;
@ -196,15 +199,22 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm
fragment.show(mapActivity.getSupportFragmentManager(), ShowDirectionBottomSheetDialogFragment.TAG);
}
@Override
public void coordinateInputOnClick() {
CoordinateInputDialogFragment.showInstance(mapActivity);
}
@Override
public void buildRouteOnClick() {
mapActivity.getDashboard().setDashboardVisibility(true, DashboardOnMap.DashboardType.MAP_MARKERS_SELECTION);
PlanRouteFragment.showInstance(mapActivity.getSupportFragmentManager());
dismiss();
}
@Override
public void saveAsNewTrackOnClick() {
mapActivity.getMyApplication().getMapMarkersHelper().generateGpx();
SaveAsTrackBottomSheetDialogFragment fragment = new SaveAsTrackBottomSheetDialogFragment();
fragment.setListener(createSaveAsTrackFragmentListener());
fragment.show(mapActivity.getSupportFragmentManager(), SaveAsTrackBottomSheetDialogFragment.TAG);
}
@Override
@ -243,6 +253,33 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm
};
}
private MarkerSaveAsTrackFragmentListener createSaveAsTrackFragmentListener() {
return new MarkerSaveAsTrackFragmentListener() {
final MapActivity mapActivity = getMapActivity();
@Override
public void saveGpx(final String fileName) {
final String gpxPath = mapActivity.getMyApplication().getMapMarkersHelper().generateGpx(fileName);
snackbar = Snackbar.make(viewPager, fileName + " " + getString(R.string.is_saved) + ".", Snackbar.LENGTH_LONG)
.setAction(R.string.shared_string_show, new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(mapActivity, getMyApplication().getAppCustomization().getTrackActivity());
intent.putExtra(TrackActivity.TRACK_FILE_NAME, gpxPath);
intent.putExtra(TrackActivity.OPEN_POINTS_TAB, true);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
});
View snackBarView = snackbar.getView();
TextView tv = (TextView) snackBarView.findViewById(android.support.design.R.id.snackbar_action);
tv.setTextColor(ContextCompat.getColor(mapActivity, R.color.color_dialog_buttons_dark));
snackbar.show();
}
};
}
private OrderByFragmentListener createOrderByFragmentListener() {
return new OrderByFragmentListener() {
@Override
@ -253,22 +290,11 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm
}
private void setOrderByMode(MapMarkersOrderByMode orderByMode) {
String modeStr = "";
if (orderByMode.isDistanceDescending()) {
modeStr = getString(R.string.distance) + " (" + getString(R.string.descendingly) + ")";
} else if (orderByMode.isDistanceAscending()) {
modeStr = getString(R.string.distance) + " (" + getString(R.string.ascendingly) + ")";
} else if (orderByMode.isName()) {
modeStr = getString(R.string.shared_string_name);
} else if (orderByMode.isDateAddedDescending()) {
modeStr = getString(R.string.date_added) + " (" + getString(R.string.descendingly) + ")";
} else {
modeStr = getString(R.string.date_added) + " (" + getString(R.string.ascendingly) + ")";
}
orderByModeTitle.setText(modeStr);
if (orderByMode != MapMarkersOrderByMode.CUSTOM) {
getMyApplication().getMapMarkersHelper().orderMarkers(orderByMode);
activeFragment.updateAdapter();
}
}
private MapActivity getMapActivity() {
return (MapActivity) getActivity();

View file

@ -1,22 +1,38 @@
package net.osmand.plus.mapmarkers;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import net.osmand.AndroidUtils;
import net.osmand.Location;
import net.osmand.data.LatLon;
import net.osmand.plus.MapMarkersHelper;
import net.osmand.plus.MapMarkersHelper.MapMarker;
import net.osmand.plus.OsmAndLocationProvider.OsmAndCompassListener;
import net.osmand.plus.OsmAndLocationProvider.OsmAndLocationListener;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.MapViewTrackingUtilities;
import net.osmand.plus.dashboard.DashLocationFragment;
import net.osmand.plus.mapmarkers.adapters.MapMarkerItemViewHolder;
import net.osmand.plus.mapmarkers.adapters.MapMarkersGroupsAdapter;
import net.osmand.util.MapUtils;
@ -28,13 +44,158 @@ public class MapMarkersGroupsFragment extends Fragment implements OsmAndCompassL
private Float heading;
private Location location;
private boolean locationUpdateStarted;
private Paint backgroundPaint = new Paint();
private Paint iconPaint = new Paint();
private Paint textPaint = new Paint();
private Snackbar snackbar;
private boolean compassUpdateAllowed = true;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
final RecyclerView recyclerView = new RecyclerView(getContext());
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
final MapActivity mapActivity = (MapActivity) getActivity();
final boolean night = !mapActivity.getMyApplication().getSettings().isLightContent();
final RecyclerView recyclerView = new RecyclerView(getContext());
boolean isSmartphone = getResources().getConfiguration().smallestScreenWidthDp < 600;
recyclerView.setPadding(0, 0, 0, AndroidUtils.dpToPx(mapActivity, isSmartphone ? 72 : 108));
recyclerView.setClipToPadding(false);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
backgroundPaint.setColor(ContextCompat.getColor(getActivity(), night ? R.color.dashboard_divider_dark : R.color.dashboard_divider_light));
backgroundPaint.setStyle(Paint.Style.FILL_AND_STROKE);
backgroundPaint.setAntiAlias(true);
iconPaint.setAntiAlias(true);
iconPaint.setFilterBitmap(true);
iconPaint.setDither(true);
textPaint.setTextSize(getResources().getDimension(R.dimen.default_desc_text_size));
textPaint.setFakeBoldText(true);
textPaint.setAntiAlias(true);
final String delStr = getString(R.string.shared_string_delete).toUpperCase();
final String moveToHistoryStr = getString(R.string.move_to_history).toUpperCase();
final Rect bounds = new Rect();
textPaint.getTextBounds(delStr, 0, delStr.length(), bounds);
final int delStrWidth = bounds.width();
final int textHeight = bounds.height();
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
private float marginSides = getResources().getDimension(R.dimen.list_content_padding);
private Bitmap deleteBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_action_delete_dark);
private Bitmap historyBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_action_history);
private boolean iconHidden;
@Override
public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
boolean markerViewHolder = viewHolder instanceof MapMarkerItemViewHolder;
int pos = viewHolder.getAdapterPosition();
if (markerViewHolder && pos != -1) {
MapMarker marker = (MapMarker) adapter.getItem(pos);
if (marker.history) {
return ItemTouchHelper.LEFT;
} else {
return ItemTouchHelper.RIGHT;
}
} else {
return 0;
}
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE && viewHolder instanceof MapMarkerItemViewHolder) {
if (!iconHidden && isCurrentlyActive) {
((MapMarkerItemViewHolder) viewHolder).optionsBtn.setVisibility(View.GONE);
compassUpdateAllowed = false;
iconHidden = true;
}
View itemView = viewHolder.itemView;
int colorIcon;
int colorText;
if (Math.abs(dX) > itemView.getWidth() / 2) {
colorIcon = R.color.map_widget_blue;
colorText = R.color.map_widget_blue;
} else {
colorIcon = night ? 0 : R.color.icon_color;
colorText = R.color.dashboard_subheader_text_light;
}
if (colorIcon != 0) {
iconPaint.setColorFilter(new PorterDuffColorFilter(ContextCompat.getColor(getActivity(), colorIcon), PorterDuff.Mode.SRC_IN));
}
textPaint.setColor(ContextCompat.getColor(getActivity(), colorText));
float textMarginTop = ((float) itemView.getHeight() - (float) textHeight) / 2;
if (dX > 0) {
c.drawRect(itemView.getLeft(), itemView.getTop(), dX, itemView.getBottom(), backgroundPaint);
float iconMarginTop = ((float) itemView.getHeight() - (float) historyBitmap.getHeight()) / 2;
c.drawBitmap(historyBitmap, itemView.getLeft() + marginSides, itemView.getTop() + iconMarginTop, iconPaint);
c.drawText(moveToHistoryStr, itemView.getLeft() + 2 * marginSides + historyBitmap.getWidth(),
itemView.getTop() + textMarginTop + textHeight, textPaint);
} else {
c.drawRect(itemView.getRight() + dX, itemView.getTop(), itemView.getRight(), itemView.getBottom(), backgroundPaint);
float iconMarginTop = ((float) itemView.getHeight() - (float) deleteBitmap.getHeight()) / 2;
c.drawBitmap(deleteBitmap, itemView.getRight() - deleteBitmap.getWidth() - marginSides, itemView.getTop() + iconMarginTop, iconPaint);
c.drawText(delStr, itemView.getRight() - deleteBitmap.getWidth() - 2 * marginSides - delStrWidth,
itemView.getTop() + textMarginTop + textHeight, textPaint);
}
}
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
if (viewHolder instanceof MapMarkerItemViewHolder) {
((MapMarkerItemViewHolder) viewHolder).optionsBtn.setVisibility(View.VISIBLE);
iconHidden = false;
compassUpdateAllowed = true;
}
super.clearView(recyclerView, viewHolder);
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, final int direction) {
final int pos = viewHolder.getAdapterPosition();
Object item = adapter.getItem(pos);
if (item instanceof MapMarker) {
final MapMarker marker = (MapMarker) item;
int snackbarStringRes;
if (direction == ItemTouchHelper.RIGHT) {
mapActivity.getMyApplication().getMapMarkersHelper().moveMapMarkerToHistory((MapMarker) item);
MapMarkersHelper.MapMarkersGroup group = mapActivity.getMyApplication().getMapMarkersHelper().getMapMarkerGroupByName(marker.groupName);
if (group != null) {
mapActivity.getMyApplication().getMapMarkersHelper().updateGroup(group);
}
snackbarStringRes = R.string.marker_moved_to_history;
} else {
mapActivity.getMyApplication().getMapMarkersHelper().removeMarker((MapMarker) item);
snackbarStringRes = R.string.item_removed;
}
updateAdapter();
snackbar = Snackbar.make(viewHolder.itemView, snackbarStringRes, Snackbar.LENGTH_LONG)
.setAction(R.string.shared_string_undo, new View.OnClickListener() {
@Override
public void onClick(View view) {
if (direction == ItemTouchHelper.RIGHT) {
mapActivity.getMyApplication().getMapMarkersHelper().restoreMarkerFromHistory(marker, 0);
} else {
mapActivity.getMyApplication().getMapMarkersHelper().addMarker(marker);
}
updateAdapter();
}
});
View snackBarView = snackbar.getView();
TextView tv = (TextView) snackBarView.findViewById(android.support.design.R.id.snackbar_action);
tv.setTextColor(ContextCompat.getColor(mapActivity, R.color.color_dialog_buttons_dark));
snackbar.show();
}
}
};
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
itemTouchHelper.attachToRecyclerView(recyclerView);
adapter = new MapMarkersGroupsAdapter(mapActivity);
recyclerView.setAdapter(adapter);
@ -83,6 +244,15 @@ public class MapMarkersGroupsFragment extends Fragment implements OsmAndCompassL
}
}
void hideSnackbar() {
if (adapter != null) {
adapter.hideSnackbar();
}
if (snackbar != null && snackbar.isShown()) {
snackbar.dismiss();
}
}
@Override
public void updateLocation(Location location) {
boolean newLocation = this.location == null && location != null;
@ -116,6 +286,9 @@ public class MapMarkersGroupsFragment extends Fragment implements OsmAndCompassL
}
private void updateLocationUi() {
if (!compassUpdateAllowed) {
return;
}
final MapActivity mapActivity = (MapActivity) getActivity();
if (mapActivity != null && adapter != null) {
mapActivity.getMyApplication().runInUIThread(new Runnable() {

View file

@ -20,6 +20,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import net.osmand.AndroidUtils;
import net.osmand.plus.MapMarkersHelper;
import net.osmand.plus.MapMarkersHelper.MapMarker;
import net.osmand.plus.OsmandApplication;
@ -74,6 +75,9 @@ public class MapMarkersHistoryFragment extends Fragment implements MapMarkersHel
}
final RecyclerView recyclerView = new RecyclerView(getContext());
boolean isSmartphone = getResources().getConfiguration().smallestScreenWidthDp < 600;
recyclerView.setPadding(0, 0, 0, AndroidUtils.dpToPx(mapActivity, isSmartphone ? 72 : 108));
recyclerView.setClipToPadding(false);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
@ -152,7 +156,7 @@ public class MapMarkersHistoryFragment extends Fragment implements MapMarkersHel
app.getMapMarkersHelper().restoreMarkerFromHistory((MapMarker) item, 0);
snackbarStringRes = R.string.marker_moved_to_active;
} else {
app.getMapMarkersHelper().removeMarkerFromHistory((MapMarker) item);
app.getMapMarkersHelper().removeMarker((MapMarker) item);
snackbarStringRes = R.string.item_removed;
}
adapter.notifyItemRemoved(pos);
@ -208,6 +212,9 @@ public class MapMarkersHistoryFragment extends Fragment implements MapMarkersHel
if (snackbar != null && snackbar.isShown()) {
snackbar.dismiss();
}
if (adapter != null) {
adapter.hideSnackbar();
}
}
private HistoryMarkerMenuBottomSheetDialogFragment.HistoryMarkerMenuFragmentListener createHistoryMarkerMenuListener() {
@ -225,7 +232,7 @@ public class MapMarkersHistoryFragment extends Fragment implements MapMarkersHel
public void onDeleteMarker(int pos) {
Object item = adapter.getItem(pos);
if (item instanceof MapMarker) {
app.getMapMarkersHelper().removeMarkerFromHistory((MapMarker) item);
app.getMapMarkersHelper().removeMarker((MapMarker) item);
adapter.notifyItemRemoved(pos);
}
}

View file

@ -5,6 +5,7 @@ import android.os.Build;
import android.os.Bundle;
import android.support.annotation.DrawableRes;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
@ -18,6 +19,7 @@ import android.widget.TextView;
import net.osmand.AndroidUtils;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.BottomSheetDialogFragment;
import net.osmand.plus.helpers.AndroidUiHelper;
@ -35,8 +37,9 @@ public class OptionsBottomSheetDialogFragment extends BottomSheetDialogFragment
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
MapActivity mapActivity = (MapActivity) getActivity();
portrait = AndroidUiHelper.isOrientationPortrait(getActivity());
boolean nightMode = getMyApplication().getDaynightHelper().isNightModeForMapControls();
boolean nightMode = !getMyApplication().getSettings().isLightContent();
final int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme;
final View mainView = View.inflate(new ContextThemeWrapper(getContext(), themeRes), R.layout.fragment_marker_options_bottom_sheet_dialog, container);
@ -61,6 +64,8 @@ public class OptionsBottomSheetDialogFragment extends BottomSheetDialogFragment
if (imageResId != 0) {
showDirectionIcon.setImageDrawable(getIcon(imageResId, R.color.dashboard_blue));
}
((ImageView) mainView.findViewById(R.id.coordinate_input_icon))
.setImageDrawable(getContentIcon(R.drawable.ic_action_coordinates_longitude));
((ImageView) mainView.findViewById(R.id.build_route_icon))
.setImageDrawable(getContentIcon(R.drawable.map_directions));
((ImageView) mainView.findViewById(R.id.save_as_new_track_icon))
@ -68,6 +73,7 @@ public class OptionsBottomSheetDialogFragment extends BottomSheetDialogFragment
((ImageView) mainView.findViewById(R.id.move_all_to_history_icon))
.setImageDrawable(getContentIcon(R.drawable.ic_action_history2));
((TextView) mainView.findViewById(R.id.show_direction_text_view)).setTextColor(ContextCompat.getColor(mapActivity, nightMode ? R.color.color_dialog_buttons_dark : R.color.map_widget_blue_pressed));
((TextView) mainView.findViewById(R.id.show_direction_text_view)).setText(getMyApplication().getSettings().MAP_MARKERS_MODE.get().toHumanString(getActivity()));
mainView.findViewById(R.id.sort_by_row).setOnClickListener(new View.OnClickListener() {
@ -88,6 +94,15 @@ public class OptionsBottomSheetDialogFragment extends BottomSheetDialogFragment
dismiss();
}
});
mainView.findViewById(R.id.coordinate_input_row).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (listener != null) {
listener.coordinateInputOnClick();
}
dismiss();
}
});
mainView.findViewById(R.id.build_route_row).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
@ -184,6 +199,8 @@ public class OptionsBottomSheetDialogFragment extends BottomSheetDialogFragment
void showDirectionOnClick();
void coordinateInputOnClick();
void buildRouteOnClick();
void saveAsNewTrackOnClick();

View file

@ -58,12 +58,19 @@ public class OrderByBottomSheetDialogFragment extends BottomSheetDialogFragment
ImageView nameIcon = (ImageView) mainView.findViewById(R.id.name_icon);
nameIcon.setImageDrawable(getContentIcon(R.drawable.ic_action_sort_by_name));
ImageView dateAddedIcon = (ImageView) mainView.findViewById(R.id.date_added_icon);
dateAddedIcon.setImageDrawable(getContentIcon(R.drawable.ic_action_sort_by_date));
ImageView dateAddedAscIcon = (ImageView) mainView.findViewById(R.id.date_added_asc_icon);
dateAddedAscIcon.setImageDrawable(getContentIcon(R.drawable.ic_action_sort_by_date));
ImageView dateAddedDescIcon = (ImageView) mainView.findViewById(R.id.date_added_desc_icon);
dateAddedDescIcon.setImageDrawable(getContentIcon(R.drawable.ic_action_sort_by_date));
((TextView) mainView.findViewById(R.id.date_added_asc_text)).setText(getString(R.string.date_added) + " (" + getString(R.string.ascendingly) + ")");
((TextView) mainView.findViewById(R.id.date_added_desc_text)).setText(getString(R.string.date_added) + " (" + getString(R.string.descendingly) + ")");
mainView.findViewById(R.id.distance_row).setOnClickListener(orderByModeOnClickListener);
mainView.findViewById(R.id.name_row).setOnClickListener(orderByModeOnClickListener);
mainView.findViewById(R.id.date_added_row).setOnClickListener(orderByModeOnClickListener);
mainView.findViewById(R.id.date_added_asc_row).setOnClickListener(orderByModeOnClickListener);
mainView.findViewById(R.id.date_added_desc_row).setOnClickListener(orderByModeOnClickListener);
mainView.findViewById(R.id.close_row).setOnClickListener(new View.OnClickListener() {
@Override
@ -136,21 +143,20 @@ public class OrderByBottomSheetDialogFragment extends BottomSheetDialogFragment
MapMarkersOrderByMode modeToSet;
switch (view.getId()) {
case R.id.distance_row:
if (currentOrderByMode == MapMarkersOrderByMode.DISTANCE_DESC) {
modeToSet = MapMarkersOrderByMode.DISTANCE_ASC;
} else {
if (currentOrderByMode == MapMarkersOrderByMode.DISTANCE_ASC) {
modeToSet = MapMarkersOrderByMode.DISTANCE_DESC;
} else {
modeToSet = MapMarkersOrderByMode.DISTANCE_ASC;
}
break;
case R.id.name_row:
modeToSet = MapMarkersOrderByMode.NAME;
break;
case R.id.date_added_row:
if (currentOrderByMode == MapMarkersOrderByMode.DATE_ADDED_DESC) {
case R.id.date_added_asc_row:
modeToSet = MapMarkersOrderByMode.DATE_ADDED_ASC;
} else {
break;
case R.id.date_added_desc_row:
modeToSet = MapMarkersOrderByMode.DATE_ADDED_DESC;
}
break;
default:
modeToSet = currentOrderByMode;

View file

@ -0,0 +1,561 @@
package net.osmand.plus.mapmarkers;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.DrawableRes;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import net.osmand.AndroidUtils;
import net.osmand.Location;
import net.osmand.data.LatLon;
import net.osmand.plus.ApplicationMode;
import net.osmand.plus.IconsCache;
import net.osmand.plus.MapMarkersHelper;
import net.osmand.plus.MapMarkersHelper.MapMarker;
import net.osmand.plus.OsmAndLocationProvider.OsmAndLocationListener;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.MapViewTrackingUtilities;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.mapmarkers.adapters.MapMarkersItemTouchHelperCallback;
import net.osmand.plus.mapmarkers.adapters.MapMarkersListAdapter;
import net.osmand.plus.measurementtool.RecyclerViewFragment;
import net.osmand.plus.measurementtool.SnapToRoadBottomSheetDialogFragment;
import net.osmand.plus.measurementtool.SnapToRoadBottomSheetDialogFragment.SnapToRoadFragmentListener;
import net.osmand.plus.views.MapMarkersLayer;
import net.osmand.plus.views.OsmandMapTileView;
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory;
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarController;
import static net.osmand.plus.OsmandSettings.LANDSCAPE_MIDDLE_RIGHT_CONSTANT;
import static net.osmand.plus.OsmandSettings.MIDDLE_TOP_CONSTANT;
public class PlanRouteFragment extends Fragment implements OsmAndLocationListener {
public static final String TAG = "PlanRouteFragment";
private MapMarkersHelper markersHelper;
private MapMarkersListAdapter adapter;
private IconsCache iconsCache;
private PlanRouteToolbarController toolbarController;
private ApplicationMode appMode;
private int previousMapPosition;
private int selectedCount = 0;
private Location location;
private boolean locationUpdateStarted;
private boolean nightMode;
private boolean portrait;
private boolean markersListOpened;
private boolean wasCollapseButtonVisible;
private View mainView;
private RecyclerView markersRv;
private ImageView upDownIconIv;
private TextView distanceTv;
private TextView timeTv;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
final MapActivity mapActivity = getMapActivity();
markersHelper = mapActivity.getMyApplication().getMapMarkersHelper();
// Handling screen rotation
FragmentManager fragmentManager = mapActivity.getSupportFragmentManager();
Fragment snapToRoadFragment = fragmentManager.findFragmentByTag(SnapToRoadBottomSheetDialogFragment.TAG);
if (snapToRoadFragment != null) {
((SnapToRoadBottomSheetDialogFragment) snapToRoadFragment).setListener(createSnapToRoadFragmentListener());
}
// If rotate the screen from landscape to portrait when the list of markers is displayed then
// the RecyclerViewFragment will exist without view. This is necessary to remove it.
if (!portrait) {
hideMarkersListFragment();
}
iconsCache = mapActivity.getMyApplication().getIconsCache();
nightMode = mapActivity.getMyApplication().getDaynightHelper().isNightModeForMapControls();
final int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme;
final int backgroundColor = ContextCompat.getColor(mapActivity,
nightMode ? R.color.ctx_menu_info_view_bg_dark : R.color.ctx_menu_info_view_bg_light);
portrait = AndroidUiHelper.isOrientationPortrait(mapActivity);
View view = View.inflate(new ContextThemeWrapper(getContext(), themeRes), R.layout.fragment_plan_route, null);
mainView = view.findViewById(R.id.main_view);
AndroidUtils.setBackground(mapActivity, mainView, nightMode, R.drawable.bg_bottom_menu_light, R.drawable.bg_bottom_menu_dark);
distanceTv = (TextView) mainView.findViewById(R.id.markers_distance_text_view);
timeTv = (TextView) mainView.findViewById(R.id.markers_time_text_view);
enterPlanRouteMode();
View markersListContainer = mainView.findViewById(R.id.markers_list_container);
if (portrait && markersListContainer != null) {
markersListContainer.setBackgroundColor(backgroundColor);
}
upDownIconIv = (ImageView) mainView.findViewById(R.id.up_down_icon);
upDownIconIv.setImageDrawable(getContentIcon(R.drawable.ic_action_arrow_up));
((ImageView) mainView.findViewById(R.id.sort_icon)).setImageDrawable(getContentIcon(R.drawable.ic_sort_waypoint_dark));
mainView.findViewById(R.id.up_down_row).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!markersListOpened) {
showMarkersList();
} else {
hideMarkersList();
}
}
});
mainView.findViewById(R.id.select_all_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int activeMarkersCount = markersHelper.getMapMarkers().size();
if (selectedCount == activeMarkersCount) {
markersHelper.deselectAllActiveMarkers();
selectedCount = 0;
} else {
markersHelper.selectAllActiveMarkers();
selectedCount = activeMarkersCount;
}
adapter.notifyDataSetChanged();
updateSelectButton();
}
});
mainView.findViewById(R.id.sort_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(mapActivity, "Sort", Toast.LENGTH_SHORT).show();
}
});
mainView.findViewById(R.id.save_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(mapActivity, "Save", Toast.LENGTH_SHORT).show();
}
});
toolbarController = new PlanRouteToolbarController();
toolbarController.setBackBtnIconIds(R.drawable.ic_action_mode_back, R.drawable.ic_action_mode_back);
toolbarController.setTitle(getString(R.string.plan_route));
toolbarController.setOnBackButtonClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
quit(false);
}
});
mapActivity.showTopToolbar(toolbarController);
if (portrait) {
markersRv = mainView.findViewById(R.id.markers_recycler_view);
} else {
markersRv = new RecyclerView(mapActivity);
}
adapter = new MapMarkersListAdapter(mapActivity);
final ItemTouchHelper touchHelper = new ItemTouchHelper(new MapMarkersItemTouchHelperCallback(adapter));
touchHelper.attachToRecyclerView(markersRv);
adapter.setAdapterListener(new MapMarkersListAdapter.MapMarkersListAdapterListener() {
private int fromPosition;
private int toPosition;
@Override
public void onItemClick(View view) {
int pos = markersRv.getChildAdapterPosition(view);
MapMarker marker = adapter.getItem(pos);
selectedCount = marker.selected ? selectedCount - 1 : selectedCount + 1;
marker.selected = !marker.selected;
adapter.notifyItemChanged(pos);
updateSelectButton();
}
@Override
public void onDragStarted(RecyclerView.ViewHolder holder) {
fromPosition = holder.getAdapterPosition();
touchHelper.startDrag(holder);
}
@Override
public void onDragEnded(RecyclerView.ViewHolder holder) {
toPosition = holder.getAdapterPosition();
if (toPosition >= 0 && fromPosition >= 0 && toPosition != fromPosition) {
mapActivity.getMyApplication().getMapMarkersHelper().checkAndFixActiveMarkersOrderIfNeeded();
adapter.notifyDataSetChanged();
}
}
});
boolean isSmartphone = getResources().getConfiguration().smallestScreenWidthDp < 600;
markersRv.setPadding(0, 0, 0, AndroidUtils.dpToPx(mapActivity, isSmartphone ? 72 : 108));
markersRv.setClipToPadding(false);
markersRv.setLayoutManager(new LinearLayoutManager(getContext()));
markersRv.setAdapter(adapter);
return view;
}
@Override
public void onResume() {
super.onResume();
startLocationUpdate();
}
@Override
public void onPause() {
super.onPause();
stopLocationUpdate();
}
@Override
public void onDestroyView() {
super.onDestroyView();
exitPlanRouteMode();
if (markersListOpened) {
hideMarkersList();
}
}
@Override
public void updateLocation(Location location) {
boolean newLocation = this.location == null && location != null;
boolean locationChanged = this.location != null && location != null
&& this.location.getLatitude() != location.getLatitude()
&& this.location.getLongitude() != location.getLongitude();
if (newLocation || locationChanged) {
this.location = location;
updateLocationUi();
}
}
private MapActivity getMapActivity() {
return (MapActivity) getActivity();
}
private MapMarkersLayer getMapMarkersLayer() {
MapActivity mapActivity = getMapActivity();
if (mapActivity != null) {
return mapActivity.getMapLayers().getMapMarkersLayer();
}
return null;
}
private Drawable getContentIcon(@DrawableRes int id) {
return iconsCache.getIcon(id, nightMode ? R.color.ctx_menu_info_text_dark : R.color.icon_color);
}
private Drawable getActiveIcon(@DrawableRes int id) {
return iconsCache.getIcon(id, nightMode ? R.color.osmand_orange : R.color.color_myloc_distance);
}
private SnapToRoadFragmentListener createSnapToRoadFragmentListener() {
return new SnapToRoadFragmentListener() {
@Override
public void onDestroyView(boolean snapToRoadEnabled) {
}
@Override
public void onApplicationModeItemClick(ApplicationMode mode) {
appMode = mode;
setupAppModesBtn();
}
};
}
private void enterPlanRouteMode() {
final MapActivity mapActivity = getMapActivity();
MapMarkersLayer markersLayer = getMapMarkersLayer();
if (mapActivity != null && markersLayer != null) {
markersLayer.setInPlanRouteMode(true);
mapActivity.disableDrawer();
mark(portrait ? View.INVISIBLE : View.GONE,
R.id.map_left_widgets_panel,
R.id.map_right_widgets_panel,
R.id.map_center_info);
mark(View.GONE,
R.id.map_route_info_button,
R.id.map_menu_button,
R.id.map_compass_button,
R.id.map_layers_button,
R.id.map_search_button,
R.id.map_quick_actions_button);
View collapseButton = mapActivity.findViewById(R.id.map_collapse_button);
if (collapseButton != null && collapseButton.getVisibility() == View.VISIBLE) {
wasCollapseButtonVisible = true;
collapseButton.setVisibility(View.INVISIBLE);
} else {
wasCollapseButtonVisible = false;
}
if (appMode == null) {
appMode = mapActivity.getMyApplication().getSettings().getApplicationMode();
}
setupAppModesBtn();
mapActivity.refreshMap();
updateText();
updateSelectButton();
}
}
private void setupAppModesBtn() {
final MapActivity mapActivity = getMapActivity();
if (mapActivity != null && appMode != null) {
final ImageButton appModesBtn = (ImageButton) mapActivity.findViewById(R.id.snap_to_road_image_button);
appModesBtn.setBackgroundResource(nightMode ? R.drawable.btn_circle_night : R.drawable.btn_circle);
appModesBtn.setImageDrawable(getActiveIcon(appMode.getSmallIconDark()));
appModesBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SnapToRoadBottomSheetDialogFragment fragment = new SnapToRoadBottomSheetDialogFragment();
fragment.setListener(createSnapToRoadFragmentListener());
fragment.show(mapActivity.getSupportFragmentManager(), SnapToRoadBottomSheetDialogFragment.TAG);
}
});
appModesBtn.setVisibility(View.VISIBLE);
}
}
private void exitPlanRouteMode() {
MapActivity mapActivity = getMapActivity();
MapMarkersLayer markersLayer = getMapMarkersLayer();
if (mapActivity != null && markersLayer != null) {
markersLayer.setInPlanRouteMode(false);
mapActivity.enableDrawer();
if (toolbarController != null) {
mapActivity.hideTopToolbar(toolbarController);
}
mark(View.VISIBLE,
R.id.map_left_widgets_panel,
R.id.map_right_widgets_panel,
R.id.map_center_info,
R.id.map_route_info_button,
R.id.map_menu_button,
R.id.map_compass_button,
R.id.map_layers_button,
R.id.map_search_button,
R.id.map_quick_actions_button);
View collapseButton = mapActivity.findViewById(R.id.map_collapse_button);
if (collapseButton != null && wasCollapseButtonVisible) {
collapseButton.setVisibility(View.VISIBLE);
}
mapActivity.findViewById(R.id.snap_to_road_image_button).setVisibility(View.GONE);
mainView.findViewById(R.id.snap_to_road_progress_bar).setVisibility(View.GONE);
mapActivity.refreshMap();
}
}
private void updateText() {
distanceTv.setText("1.39 km,");
timeTv.setText("~ 45 min.");
}
private void updateSelectButton() {
if (selectedCount == markersHelper.getMapMarkers().size()) {
((TextView) mainView.findViewById(R.id.select_all_button)).setText(getString(R.string.shared_string_deselect_all));
} else {
((TextView) mainView.findViewById(R.id.select_all_button)).setText(getString(R.string.shared_string_select_all));
}
}
private void updateLocationUi() {
final MapActivity mapActivity = (MapActivity) getActivity();
if (mapActivity != null && adapter != null) {
mapActivity.getMyApplication().runInUIThread(new Runnable() {
@Override
public void run() {
if (location == null) {
location = mapActivity.getMyApplication().getLocationProvider().getLastKnownLocation();
}
MapViewTrackingUtilities utilities = mapActivity.getMapViewTrackingUtilities();
boolean useCenter = !(utilities.isMapLinkedToLocation() && location != null);
adapter.setUseCenter(useCenter);
adapter.setLocation(useCenter ? mapActivity.getMapLocation() : new LatLon(location.getLatitude(), location.getLongitude()));
adapter.notifyDataSetChanged();
}
});
}
}
private void mark(int status, int... widgets) {
MapActivity mapActivity = getMapActivity();
if (mapActivity != null) {
for (int widget : widgets) {
View v = mapActivity.findViewById(widget);
if (v != null) {
v.setVisibility(status);
}
}
}
}
private void showMarkersList() {
MapActivity mapActivity = getMapActivity();
MapMarkersLayer markersLayer = getMapMarkersLayer();
if (mapActivity != null && markersLayer != null) {
markersListOpened = true;
markersLayer.setMarkersListOpened(true);
upDownIconIv.setImageDrawable(getContentIcon(R.drawable.ic_action_arrow_down));
View listContainer = mainView.findViewById(R.id.markers_list_container);
if (portrait && listContainer != null) {
listContainer.setVisibility(View.VISIBLE);
} else {
showMarkersListFragment();
}
OsmandMapTileView tileView = mapActivity.getMapView();
previousMapPosition = tileView.getMapPosition();
if (portrait) {
tileView.setMapPosition(MIDDLE_TOP_CONSTANT);
} else {
tileView.setMapPosition(LANDSCAPE_MIDDLE_RIGHT_CONSTANT);
}
mapActivity.refreshMap();
}
}
private void hideMarkersList() {
MapActivity mapActivity = getMapActivity();
MapMarkersLayer markersLayer = getMapMarkersLayer();
if (mapActivity != null && markersLayer != null) {
markersListOpened = false;
markersLayer.setMarkersListOpened(false);
upDownIconIv.setImageDrawable(getContentIcon(R.drawable.ic_action_arrow_up));
View listContainer = mainView.findViewById(R.id.markers_list_container);
if (portrait && listContainer != null) {
listContainer.setVisibility(View.GONE);
} else {
hideMarkersListFragment();
}
mapActivity.getMapView().setMapPosition(previousMapPosition);
mapActivity.refreshMap();
}
}
private void showMarkersListFragment() {
MapActivity mapActivity = getMapActivity();
if (mapActivity != null) {
View upDownRow = mainView.findViewById(R.id.up_down_row);
int screenHeight = AndroidUtils.getScreenHeight(mapActivity) - AndroidUtils.getStatusBarHeight(mapActivity);
RecyclerViewFragment fragment = new RecyclerViewFragment();
fragment.setRecyclerView(markersRv);
fragment.setWidth(upDownRow.getWidth());
fragment.setHeight(screenHeight - upDownRow.getHeight());
mapActivity.getSupportFragmentManager().beginTransaction()
.add(R.id.fragmentContainer, fragment, RecyclerViewFragment.TAG)
.commitAllowingStateLoss();
}
}
private void hideMarkersListFragment() {
MapActivity mapActivity = getMapActivity();
if (mapActivity != null) {
try {
FragmentManager manager = mapActivity.getSupportFragmentManager();
Fragment fragment = manager.findFragmentByTag(RecyclerViewFragment.TAG);
if (fragment != null) {
manager.beginTransaction().remove(fragment).commitNowAllowingStateLoss();
}
} catch (Exception e) {
// ignore
}
}
}
private void startLocationUpdate() {
MapActivity mapActivity = getMapActivity();
if (mapActivity != null && !locationUpdateStarted) {
locationUpdateStarted = true;
mapActivity.getMyApplication().getLocationProvider().addLocationListener(this);
updateLocationUi();
}
}
private void stopLocationUpdate() {
MapActivity mapActivity = getMapActivity();
if (mapActivity != null && locationUpdateStarted) {
locationUpdateStarted = false;
mapActivity.getMyApplication().getLocationProvider().removeLocationListener(this);
}
}
public boolean quit(boolean hideMarkersListFirst) {
if (markersListOpened && hideMarkersListFirst) {
hideMarkersList();
return false;
} else {
dismiss(getMapActivity());
return true;
}
}
private void dismiss(MapActivity activity) {
if (markersListOpened) {
hideMarkersList();
}
markersHelper.deselectAllActiveMarkers();
activity.getSupportFragmentManager().beginTransaction().remove(this).commitAllowingStateLoss();
}
public static boolean showInstance(FragmentManager fragmentManager) {
try {
PlanRouteFragment fragment = new PlanRouteFragment();
fragment.setRetainInstance(true);
fragmentManager.beginTransaction()
.add(R.id.bottomFragmentContainer, fragment, PlanRouteFragment.TAG)
.commitAllowingStateLoss();
return true;
} catch (Exception e) {
return false;
}
}
private class PlanRouteToolbarController extends TopToolbarController {
PlanRouteToolbarController() {
super(MapInfoWidgetsFactory.TopToolbarControllerType.MEASUREMENT_TOOL);
setBackBtnIconClrIds(0, 0);
setTitleTextClrIds(R.color.primary_text_dark, R.color.primary_text_dark);
setDescrTextClrIds(R.color.primary_text_dark, R.color.primary_text_dark);
setBgIds(R.drawable.gradient_toolbar, R.drawable.gradient_toolbar,
R.drawable.gradient_toolbar, R.drawable.gradient_toolbar);
setCloseBtnVisible(false);
}
@Override
public void updateToolbar(MapInfoWidgetsFactory.TopToolbarView view) {
super.updateToolbar(view);
View shadow = view.getShadowView();
if (shadow != null) {
shadow.setVisibility(View.GONE);
}
}
}
}

View file

@ -0,0 +1,160 @@
package net.osmand.plus.mapmarkers;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.ContextThemeWrapper;
import android.view.Gravity;
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.EditText;
import android.widget.LinearLayout;
import net.osmand.AndroidUtils;
import net.osmand.IndexConstants;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.BottomSheetDialogFragment;
import net.osmand.plus.helpers.AndroidUiHelper;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import studio.carbonylgroup.textfieldboxes.ExtendedEditText;
import static net.osmand.plus.helpers.GpxImportHelper.GPX_SUFFIX;
public class SaveAsTrackBottomSheetDialogFragment extends BottomSheetDialogFragment {
public final static String TAG = "SaveAsTrackBottomSheetDialogFragment";
private boolean portrait;
private MarkerSaveAsTrackFragmentListener listener;
public void setListener(MarkerSaveAsTrackFragmentListener listener) {
this.listener = listener;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
MapActivity mapActivity = (MapActivity) getActivity();
portrait = AndroidUiHelper.isOrientationPortrait(getActivity());
boolean nightMode = !getMyApplication().getSettings().isLightContent();
final int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme;
final View mainView = View.inflate(new ContextThemeWrapper(getContext(), themeRes), R.layout.fragment_marker_save_as_track_bottom_sheet_dialog, container);
LinearLayout contentLayout = (LinearLayout) mainView.findViewById(R.id.content_linear_layout);
int layoutRes;
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
layoutRes = R.layout.markers_track_name_text_field_box;
} else {
layoutRes = R.layout.markers_track_name_edit_text;
}
contentLayout.addView(getLayoutInflater().inflate(layoutRes, contentLayout, false), 2);
if (portrait) {
AndroidUtils.setBackground(getActivity(), mainView, nightMode, R.drawable.bg_bottom_menu_light, R.drawable.bg_bottom_menu_dark);
}
final File dir = mapActivity.getMyApplication().getAppPath(IndexConstants.GPX_INDEX_DIR + "/map markers");
if (!dir.exists()) {
dir.mkdirs();
}
Date date = new Date();
final String suggestedName = mapActivity.getString(R.string.markers) + "_" + DateFormat.format("dd_MM_yyyy", date).toString();
String displayedName = suggestedName;
File fout = new File(dir, suggestedName + GPX_SUFFIX);
int ind = 1;
while (fout.exists()) {
displayedName = suggestedName + "_" + (++ind);
fout = new File(dir, displayedName + GPX_SUFFIX);
}
final EditText nameEditText = (EditText) mainView.findViewById(R.id.name_edit_text);
nameEditText.setText(displayedName);
nameEditText.requestFocus();
mainView.findViewById(R.id.save_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (listener != null) {
listener.saveGpx(nameEditText.getText().toString());
}
dismiss();
}
});
mainView.findViewById(R.id.close_button).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() {
boolean dimensSet;
@Override
public void onGlobalLayout() {
if (!dimensSet) {
final View scrollView = mainView.findViewById(R.id.marker_save_as_track_scroll_view);
int scrollViewHeight = scrollView.getHeight();
int dividerHeight = AndroidUtils.dpToPx(getContext(), 1);
int cancelButtonHeight = getContext().getResources().getDimensionPixelSize(R.dimen.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, false,
R.drawable.bg_bottom_sheet_topsides_landscape_light, R.drawable.bg_bottom_sheet_topsides_landscape_dark);
} else {
AndroidUtils.setBackground(getActivity(), mainView, false,
R.drawable.bg_bottom_sheet_sides_landscape_light, R.drawable.bg_bottom_sheet_sides_landscape_dark);
}
}
dimensSet = true;
}
final Window window = getDialog().getWindow();
WindowManager.LayoutParams params = window.getAttributes();
params.height = ViewGroup.LayoutParams.WRAP_CONTENT;
params.gravity = Gravity.BOTTOM;
window.setAttributes(params);
}
});
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);
}
}
interface MarkerSaveAsTrackFragmentListener {
void saveGpx(String fileName);
}
}

View file

@ -119,12 +119,12 @@ public class ShowDirectionBottomSheetDialogFragment extends BottomSheetDialogFra
});
ImageView topBarIcon = (ImageView) mainView.findViewById(R.id.top_bar_icon);
topBarIcon.setBackgroundDrawable(getIcon(R.drawable.ic_action_device_top, R.color.on_map_icon_color));
topBarIcon.setImageDrawable(getContentIcon(R.drawable.ic_action_device_topbar));
topBarIcon.setBackgroundDrawable(getContentIcon(R.drawable.ic_action_device_top));
topBarIcon.setImageDrawable(getIcon(R.drawable.ic_action_device_topbar, R.color.dashboard_blue));
ImageView widgetIcon = (ImageView) mainView.findViewById(R.id.widget_icon);
widgetIcon.setBackgroundDrawable(getIcon(R.drawable.ic_action_device_top, R.color.on_map_icon_color));
widgetIcon.setImageDrawable(getContentIcon(R.drawable.ic_action_device_widget));
widgetIcon.setBackgroundDrawable(getContentIcon(R.drawable.ic_action_device_top));
widgetIcon.setImageDrawable(getIcon(R.drawable.ic_action_device_widget, R.color.dashboard_blue));
ImageView noneIcon = (ImageView) mainView.findViewById(R.id.none_icon);
noneIcon.setBackgroundDrawable(getContentIcon(R.drawable.ic_action_device_top));
@ -207,15 +207,15 @@ public class ShowDirectionBottomSheetDialogFragment extends BottomSheetDialogFra
private void highlightSelectedItem(OsmandSettings.MapMarkersMode mode, boolean check) {
int iconBgColor = check ? R.color.dashboard_blue : R.color.on_map_icon_color;
int iconColor = check ? R.color.color_dialog_buttons_dark : R.color.dashboard_blue;
int textColor = ContextCompat.getColor(getContext(), check ? R.color.dashboard_blue : night ? R.color.color_white : R.color.color_black);
int textColor = ContextCompat.getColor(getContext(), check ? (night ? R.color.color_dialog_buttons_dark : R.color.dashboard_blue) : night ? R.color.color_white : R.color.color_black);
switch (mode) {
case TOOLBAR:
((RadioButton) mainView.findViewById(R.id.top_bar_radio_button)).setChecked(check);
ImageView topBarIcon = (ImageView) mainView.findViewById(R.id.top_bar_icon);
if (check) {
mainView.findViewById(R.id.top_bar_row).setBackgroundColor(ContextCompat.getColor(getContext(), R.color.show_direction_menu_selected_item_bg));
mainView.findViewById(R.id.top_bar_row_frame).setBackgroundColor(ContextCompat.getColor(getContext(), R.color.show_direction_menu_selected_item_bg));
} else {
mainView.findViewById(R.id.top_bar_row).setBackgroundResource(0);
mainView.findViewById(R.id.top_bar_row_frame).setBackgroundResource(0);
}
((TextView) mainView.findViewById(R.id.top_bar_text)).setTextColor(textColor);
topBarIcon.setBackgroundDrawable(getIcon(R.drawable.ic_action_device_top, iconBgColor));
@ -225,9 +225,9 @@ public class ShowDirectionBottomSheetDialogFragment extends BottomSheetDialogFra
((RadioButton) mainView.findViewById(R.id.widget_radio_button)).setChecked(check);
ImageView widgetIcon = (ImageView) mainView.findViewById(R.id.widget_icon);
if (check) {
mainView.findViewById(R.id.widget_row).setBackgroundColor(ContextCompat.getColor(getContext(), R.color.show_direction_menu_selected_item_bg));
mainView.findViewById(R.id.widget_row_frame).setBackgroundColor(ContextCompat.getColor(getContext(), R.color.show_direction_menu_selected_item_bg));
} else {
mainView.findViewById(R.id.widget_row).setBackgroundResource(0);
mainView.findViewById(R.id.widget_row_frame).setBackgroundResource(0);
}
((TextView) mainView.findViewById(R.id.widget_text)).setTextColor(textColor);
widgetIcon.setBackgroundDrawable(getIcon(R.drawable.ic_action_device_top, iconBgColor));
@ -237,9 +237,9 @@ public class ShowDirectionBottomSheetDialogFragment extends BottomSheetDialogFra
((RadioButton) mainView.findViewById(R.id.none_radio_button)).setChecked(check);
ImageView noneIcon = (ImageView) mainView.findViewById(R.id.none_icon);
if (check) {
mainView.findViewById(R.id.none_row).setBackgroundColor(ContextCompat.getColor(getContext(), R.color.show_direction_menu_selected_item_bg));
mainView.findViewById(R.id.none_row_frame).setBackgroundColor(ContextCompat.getColor(getContext(), R.color.show_direction_menu_selected_item_bg));
} else {
mainView.findViewById(R.id.none_row).setBackgroundResource(0);
mainView.findViewById(R.id.none_row_frame).setBackgroundResource(0);
}
((TextView) mainView.findViewById(R.id.none_text)).setTextColor(textColor);
noneIcon.setBackgroundDrawable(getIcon(R.drawable.ic_action_device_top, iconBgColor));

View file

@ -2,6 +2,7 @@ package net.osmand.plus.mapmarkers.adapters;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.CheckBox;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
@ -11,10 +12,12 @@ import net.osmand.plus.R;
public class MapMarkerItemViewHolder extends RecyclerView.ViewHolder {
final View mainLayout;
final View topDivider;
final ImageView iconDirection;
final ImageView iconReorder;
final ImageView icon;
final TextView title;
final TextView firstDescription;
final TextView distance;
final View flagIconLeftSpace;
final View leftPointSpace;
@ -22,16 +25,19 @@ public class MapMarkerItemViewHolder extends RecyclerView.ViewHolder {
final View rightPointSpace;
final TextView description;
public final ImageButton optionsBtn;
final CheckBox checkBox;
final View divider;
final View bottomShadow;
public MapMarkerItemViewHolder(View view) {
super(view);
mainLayout = view.findViewById(R.id.main_layout);
topDivider = view.findViewById(R.id.top_divider);
iconDirection = (ImageView) view.findViewById(R.id.map_marker_direction_icon);
iconReorder = (ImageView) view.findViewById(R.id.map_marker_reorder_icon);
icon = (ImageView) view.findViewById(R.id.map_marker_icon);
title = (TextView) view.findViewById(R.id.map_marker_title);
firstDescription = (TextView) view.findViewById(R.id.map_marker_first_descr);
distance = (TextView) view.findViewById(R.id.map_marker_distance);
flagIconLeftSpace = view.findViewById(R.id.flag_icon_left_space);
leftPointSpace = view.findViewById(R.id.map_marker_left_point_space);
@ -39,6 +45,7 @@ public class MapMarkerItemViewHolder extends RecyclerView.ViewHolder {
rightPointSpace = view.findViewById(R.id.map_marker_right_point_space);
description = (TextView) view.findViewById(R.id.map_marker_description);
optionsBtn = (ImageButton) view.findViewById(R.id.map_marker_options_button);
checkBox = (CheckBox) view.findViewById(R.id.map_marker_check_box);
divider = view.findViewById(R.id.divider);
bottomShadow = view.findViewById(R.id.bottom_shadow);
}

View file

@ -13,6 +13,7 @@ import android.widget.TextView;
import net.osmand.data.LatLon;
import net.osmand.plus.IconsCache;
import net.osmand.plus.MapMarkersHelper;
import net.osmand.plus.MapMarkersHelper.MapMarker;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
@ -112,8 +113,8 @@ public class MapMarkersActiveAdapter extends RecyclerView.Adapter<MapMarkerItemV
holder.icon.setImageDrawable(iconsCache.getIcon(R.drawable.ic_action_flag_dark, markerColor));
holder.mainLayout.setBackgroundColor(ContextCompat.getColor(mapActivity, night ? R.color.bg_color_dark : R.color.bg_color_light));
holder.title.setTextColor(ContextCompat.getColor(mapActivity, night ? R.color.color_white : R.color.color_black));
holder.divider.setBackgroundColor(ContextCompat.getColor(mapActivity, night ? R.color.dashboard_divider_dark : R.color.dashboard_divider_light));
holder.optionsBtn.setBackgroundDrawable(mapActivity.getResources().getDrawable(R.drawable.marker_circle_background_light_with_inset));
holder.divider.setBackgroundColor(ContextCompat.getColor(mapActivity, night ? R.color.actionbar_dark_color : R.color.dashboard_divider_light));
holder.optionsBtn.setBackgroundDrawable(mapActivity.getResources().getDrawable(night ? R.drawable.marker_circle_background_dark_with_inset : R.drawable.marker_circle_background_light_with_inset));
holder.optionsBtn.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_marker_passed));
holder.iconReorder.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_reorder));
holder.description.setTextColor(ContextCompat.getColor(mapActivity, night ? R.color.dash_search_icon_dark : R.color.icon_color));
@ -129,6 +130,8 @@ public class MapMarkersActiveAdapter extends RecyclerView.Adapter<MapMarkerItemV
holder.divider.setVisibility(View.VISIBLE);
}
holder.point.setVisibility(View.VISIBLE);
holder.iconReorder.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
@ -147,7 +150,13 @@ public class MapMarkersActiveAdapter extends RecyclerView.Adapter<MapMarkerItemV
descr = mapActivity.getString(R.string.shared_string_favorites);
}
} else {
descr = new SimpleDateFormat("MMM dd", Locale.getDefault()).format(new Date(marker.creationDate));
Date date = new Date(marker.creationDate);
String month = new SimpleDateFormat("MMM", Locale.getDefault()).format(date);
if (month.length() > 1) {
month = Character.toUpperCase(month.charAt(0)) + month.substring(1);
}
String day = new SimpleDateFormat("dd", Locale.getDefault()).format(date);
descr = month + " " + day;
}
holder.description.setText(descr);
@ -213,6 +222,11 @@ public class MapMarkersActiveAdapter extends RecyclerView.Adapter<MapMarkerItemV
}
}
@Override
public void onSwipeStarted() {
listener.onSwipeStarted();
}
@Override
public boolean onItemMove(int from, int to) {
Collections.swap(markers, from, to);
@ -220,9 +234,43 @@ public class MapMarkersActiveAdapter extends RecyclerView.Adapter<MapMarkerItemV
return true;
}
@Override
public void onItemSwiped(RecyclerView.ViewHolder holder) {
final int pos = holder.getAdapterPosition();
final MapMarker marker = getItem(pos);
mapActivity.getMyApplication().getMapMarkersHelper().moveMapMarkerToHistory(marker);
MapMarkersHelper.MapMarkersGroup group = mapActivity.getMyApplication().getMapMarkersHelper().getMapMarkerGroupByName(marker.groupName);
if (group != null) {
mapActivity.getMyApplication().getMapMarkersHelper().updateGroup(group);
}
notifyItemRemoved(pos);
if (showDirectionEnabled && pos < 2 && getItemCount() > 1) {
notifyItemChanged(1);
} else if (pos == getItemCount()) {
notifyItemChanged(pos - 1);
}
snackbar = Snackbar.make(holder.itemView, R.string.marker_moved_to_history, Snackbar.LENGTH_LONG)
.setAction(R.string.shared_string_undo, new View.OnClickListener() {
@Override
public void onClick(View view) {
mapActivity.getMyApplication().getMapMarkersHelper().restoreMarkerFromHistory(marker, pos);
notifyItemInserted(pos);
if (showDirectionEnabled && pos < 2 && getItemCount() > 2) {
notifyItemChanged(2);
} else if (pos == getItemCount() - 1) {
notifyItemChanged(pos - 1);
}
}
});
View snackBarView = snackbar.getView();
TextView tv = (TextView) snackBarView.findViewById(android.support.design.R.id.snackbar_action);
tv.setTextColor(ContextCompat.getColor(mapActivity, R.color.color_dialog_buttons_dark));
snackbar.show();
}
@Override
public void onItemDismiss(RecyclerView.ViewHolder holder) {
listener.onDragEnded(holder);
listener.onDragOrSwipeEnded(holder);
}
public interface MapMarkersActiveAdapterListener {
@ -231,6 +279,8 @@ public class MapMarkersActiveAdapter extends RecyclerView.Adapter<MapMarkerItemV
void onDragStarted(RecyclerView.ViewHolder holder);
void onDragEnded(RecyclerView.ViewHolder holder);
void onDragOrSwipeEnded(RecyclerView.ViewHolder holder);
void onSwipeStarted();
}
}

View file

@ -1,5 +1,6 @@
package net.osmand.plus.mapmarkers.adapters;
import android.support.design.widget.Snackbar;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
@ -7,6 +8,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.TextView;
import net.osmand.data.LatLon;
import net.osmand.plus.IconsCache;
@ -48,6 +50,7 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
private boolean useCenter;
private boolean showDirectionEnabled;
private List<MapMarker> showDirectionMarkers;
private Snackbar snackbar;
public MapMarkersGroupsAdapter(MapActivity mapActivity) {
this.mapActivity = mapActivity;
@ -147,6 +150,7 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
if (viewType == MARKER_TYPE) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.map_marker_item_new, viewGroup, false);
view.setClickable(true);
return new MapMarkerItemViewHolder(view);
} else if (viewType == HEADER_TYPE) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.map_marker_item_header, viewGroup, false);
@ -168,7 +172,12 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
final boolean markerInHistory = marker.history;
int color = MapMarker.getColorId(marker.colorIndex);
int color;
if (marker.history) {
color = R.color.icon_color_light;
} else {
color = MapMarker.getColorId(marker.colorIndex);
}
ImageView markerImageViewToUpdate;
int drawableResToUpdate;
final boolean markerToHighlight = showDirectionMarkers.contains(marker);
@ -191,8 +200,8 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
itemViewHolder.icon.setImageDrawable(iconsCache.getIcon(R.drawable.ic_action_flag_dark, color));
itemViewHolder.mainLayout.setBackgroundColor(ContextCompat.getColor(mapActivity, night ? R.color.bg_color_dark : R.color.bg_color_light));
itemViewHolder.title.setTextColor(ContextCompat.getColor(mapActivity, night ? R.color.color_white : R.color.color_black));
itemViewHolder.divider.setBackgroundColor(ContextCompat.getColor(mapActivity, night ? R.color.dashboard_divider_dark : R.color.dashboard_divider_light));
itemViewHolder.optionsBtn.setBackgroundDrawable(mapActivity.getResources().getDrawable(R.drawable.marker_circle_background_light_with_inset));
itemViewHolder.divider.setBackgroundColor(ContextCompat.getColor(mapActivity, night ? R.color.actionbar_dark_color : R.color.dashboard_divider_light));
itemViewHolder.optionsBtn.setBackgroundDrawable(mapActivity.getResources().getDrawable(night ? R.drawable.marker_circle_background_dark_with_inset : R.drawable.marker_circle_background_light_with_inset));
itemViewHolder.optionsBtn.setImageDrawable(iconsCache.getThemedIcon(markerInHistory ? R.drawable.ic_action_reset_to_default_dark : R.drawable.ic_action_marker_passed));
itemViewHolder.description.setTextColor(ContextCompat.getColor(mapActivity, night ? R.color.dash_search_icon_dark : R.color.icon_color));
@ -202,16 +211,40 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
itemViewHolder.title.setText(marker.getName(app));
if (markerInHistory) {
boolean noGroup = marker.groupName == null;
boolean createdEarly = false;
if (noGroup && !markerInHistory) {
Calendar currentDateCalendar = Calendar.getInstance();
currentDateCalendar.setTimeInMillis(System.currentTimeMillis());
int currentDay = currentDateCalendar.get(Calendar.DAY_OF_YEAR);
int currentYear = currentDateCalendar.get(Calendar.YEAR);
Calendar markerCalendar = Calendar.getInstance();
markerCalendar.setTimeInMillis(System.currentTimeMillis());
int markerDay = markerCalendar.get(Calendar.DAY_OF_YEAR);
int markerYear = markerCalendar.get(Calendar.YEAR);
createdEarly = currentDay - markerDay >= 2 || currentYear != markerYear;
}
if (markerInHistory || createdEarly) {
itemViewHolder.point.setVisibility(View.VISIBLE);
itemViewHolder.description.setVisibility(View.VISIBLE);
itemViewHolder.description.setText(app.getString(R.string.passed, new SimpleDateFormat("MMM dd", Locale.getDefault()).format(new Date(marker.visitedDate))));
Date date;
if (markerInHistory) {
date = new Date(marker.visitedDate);
} else {
date = new Date(marker.creationDate);
}
String month = new SimpleDateFormat("MMM", Locale.getDefault()).format(date);
if (month.length() > 1) {
month = Character.toUpperCase(month.charAt(0)) + month.substring(1);
}
String day = new SimpleDateFormat("dd", Locale.getDefault()).format(date);
itemViewHolder.description.setText(app.getString(R.string.passed, month + " " + day));
} else {
itemViewHolder.point.setVisibility(View.GONE);
itemViewHolder.description.setVisibility(View.GONE);
}
String markerGroupName = marker.groupName;
final String markerGroupName = marker.groupName;
final MapMarkersGroup group = app.getMapMarkersHelper().getMapMarkerGroupByName(markerGroupName);
itemViewHolder.optionsBtn.setOnClickListener(new View.OnClickListener() {
@Override
@ -237,6 +270,7 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
ShowHideHistoryButton showHideHistoryButton = group.getShowHideHistoryButton();
if (showHideHistoryButton == null) {
items.remove(marker);
if (markerGroupName != null) {
showHideHistoryButton = new ShowHideHistoryButton();
showHideHistoryButton.setShowHistory(false);
showHideHistoryButton.setMarkerGroup(group);
@ -245,6 +279,13 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
items.add(index + 1, showHideHistoryButton);
group.setShowHideHistoryButton(showHideHistoryButton);
}
} else {
boolean firstItemInDisplayGroup = position - 1 != -1 && getItem(position - 1) instanceof Integer;
boolean lastItemInDisplayGroup = !(getItem(position) instanceof MapMarker);
if (firstItemInDisplayGroup && lastItemInDisplayGroup) {
items.remove(position - 1);
}
}
} else if (!showHideHistoryButton.isShowHistory()) {
items.remove(marker);
}
@ -252,6 +293,22 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
}
updateShowDirectionMarkers();
notifyDataSetChanged();
if (!markerInHistory) {
snackbar = Snackbar.make(itemViewHolder.itemView, R.string.marker_moved_to_history, Snackbar.LENGTH_LONG)
.setAction(R.string.shared_string_undo, new View.OnClickListener() {
@Override
public void onClick(View view) {
mapActivity.getMyApplication().getMapMarkersHelper().restoreMarkerFromHistory(marker, 0);
createDisplayGroups();
updateShowDirectionMarkers();
notifyDataSetChanged();
}
});
View snackBarView = snackbar.getView();
TextView tv = (TextView) snackBarView.findViewById(android.support.design.R.id.snackbar_action);
tv.setTextColor(ContextCompat.getColor(mapActivity, R.color.color_dialog_buttons_dark));
snackbar.show();
}
}
});
itemViewHolder.iconReorder.setVisibility(View.GONE);
@ -304,12 +361,29 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
headerViewHolder.iconSpace.setVisibility(View.GONE);
headerViewHolder.icon.setImageDrawable(iconsCache.getIcon(groupHeader.getIconRes(), R.color.divider_color));
boolean groupIsDisabled = groupHeader.getGroup().isDisabled();
headerViewHolder.disableGroupSwitch.setVisibility(View.VISIBLE);
headerViewHolder.disableGroupSwitch.setChecked(!groupIsDisabled);
headerViewHolder.disableGroupSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
groupHeader.getGroup().setDisabled(!b);
notifyDataSetChanged();
public void onCheckedChanged(CompoundButton compoundButton, boolean enabled) {
groupHeader.getGroup().setDisabled(!enabled);
final String groupKey = groupHeader.getGroup().getGroupKey();
app.getMapMarkersHelper().updateGroupDisabled(groupKey, !enabled);
if (!enabled) {
snackbar = Snackbar.make(holder.itemView, app.getString(R.string.group_will_be_removed_after_restart), Snackbar.LENGTH_LONG)
.setAction(R.string.shared_string_undo, new View.OnClickListener() {
@Override
public void onClick(View view) {
groupHeader.getGroup().setDisabled(false);
app.getMapMarkersHelper().updateGroupDisabled(groupKey, false);
headerViewHolder.disableGroupSwitch.setChecked(true);
}
});
View snackBarView = snackbar.getView();
TextView tv = (TextView) snackBarView.findViewById(android.support.design.R.id.snackbar_action);
tv.setTextColor(ContextCompat.getColor(mapActivity, R.color.color_dialog_buttons_dark));
snackbar.show();
}
}
});
} else {
@ -339,6 +413,12 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
}
}
public void hideSnackbar() {
if (snackbar != null && snackbar.isShown()) {
snackbar.dismiss();
}
}
@Override
public int getItemViewType(int position) {
Object item = items.get(position);
@ -366,7 +446,11 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
SimpleDateFormat dateFormat = new SimpleDateFormat("LLLL", Locale.getDefault());
Date date = new Date();
date.setMonth(month);
return dateFormat.format(date);
String monthStr = dateFormat.format(date);
if (monthStr.length() > 1) {
monthStr = Character.toUpperCase(monthStr.charAt(0)) + monthStr.substring(1);
}
return monthStr;
}
private int getLastDisplayItemIndexOfGroup(MapMarkersGroup group) {

View file

@ -1,9 +1,12 @@
package net.osmand.plus.mapmarkers.adapters;
import android.support.design.widget.Snackbar;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import net.osmand.plus.IconsCache;
import net.osmand.plus.MapMarkersHelper.MapMarker;
@ -30,9 +33,12 @@ public class MapMarkersHistoryAdapter extends RecyclerView.Adapter<RecyclerView.
private OsmandApplication app;
private List<Object> items = new ArrayList<>();
private MapMarkersHistoryAdapterListener listener;
private Snackbar snackbar;
private boolean night;
public MapMarkersHistoryAdapter(OsmandApplication app) {
this.app = app;
night = !app.getSettings().isLightContent();
createHeaders();
}
@ -113,13 +119,20 @@ public class MapMarkersHistoryAdapter extends RecyclerView.Adapter<RecyclerView.
final MapMarker marker = (MapMarker) getItem(position);
itemViewHolder.iconReorder.setVisibility(View.GONE);
int color = MapMarker.getColorId(marker.colorIndex);
int color = R.color.icon_color_light;
itemViewHolder.icon.setImageDrawable(iconsCache.getIcon(R.drawable.ic_action_flag_dark, color));
itemViewHolder.title.setText(marker.getName(app));
itemViewHolder.description.setText(app.getString(R.string.passed, new SimpleDateFormat("MMM dd", Locale.getDefault()).format(new Date(marker.visitedDate))));
Date date = new Date(marker.visitedDate);
String month = new SimpleDateFormat("MMM", Locale.getDefault()).format(date);
if (month.length() > 1) {
month = Character.toUpperCase(month.charAt(0)) + month.substring(1);
}
String day = new SimpleDateFormat("dd", Locale.getDefault()).format(date);
itemViewHolder.description.setText(app.getString(R.string.passed, month + " " + day));
itemViewHolder.optionsBtn.setBackgroundDrawable(app.getResources().getDrawable(night ? R.drawable.marker_circle_background_dark_with_inset : R.drawable.marker_circle_background_light_with_inset));
itemViewHolder.optionsBtn.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_reset_to_default_dark));
itemViewHolder.optionsBtn.setOnClickListener(new View.OnClickListener() {
@Override
@ -130,19 +143,33 @@ public class MapMarkersHistoryAdapter extends RecyclerView.Adapter<RecyclerView.
}
app.getMapMarkersHelper().restoreMarkerFromHistory(marker, 0);
notifyItemRemoved(position);
snackbar = Snackbar.make(itemViewHolder.itemView, app.getString(R.string.marker_moved_to_active), Snackbar.LENGTH_LONG)
.setAction(R.string.shared_string_undo, new View.OnClickListener() {
@Override
public void onClick(View view) {
app.getMapMarkersHelper().moveMapMarkerToHistory(marker);
notifyDataSetChanged();
}
});
View snackBarView = snackbar.getView();
TextView tv = (TextView) snackBarView.findViewById(android.support.design.R.id.snackbar_action);
tv.setTextColor(ContextCompat.getColor(app, R.color.color_dialog_buttons_dark));
snackbar.show();
}
});
itemViewHolder.flagIconLeftSpace.setVisibility(View.VISIBLE);
itemViewHolder.iconDirection.setVisibility(View.GONE);
itemViewHolder.leftPointSpace.setVisibility(View.GONE);
itemViewHolder.rightPointSpace.setVisibility(View.GONE);
if (position == getItemCount() - 1) {
itemViewHolder.bottomShadow.setVisibility(View.VISIBLE);
boolean lastItem = position == getItemCount() - 1;
if ((getItemCount() > position + 1 && getItemViewType(position + 1) == HEADER_TYPE) || lastItem) {
itemViewHolder.divider.setVisibility(View.GONE);
} else {
itemViewHolder.bottomShadow.setVisibility(View.GONE);
itemViewHolder.divider.setBackgroundColor(ContextCompat.getColor(app, night ? R.color.actionbar_dark_color : R.color.dashboard_divider_light));
itemViewHolder.divider.setVisibility(View.VISIBLE);
}
itemViewHolder.bottomShadow.setVisibility(lastItem ? View.VISIBLE : View.GONE);
} else if (holder instanceof MapMarkerHeaderViewHolder) {
final MapMarkerHeaderViewHolder dateViewHolder = (MapMarkerHeaderViewHolder) holder;
final Integer dateHeader = (Integer) getItem(position);
@ -165,6 +192,12 @@ public class MapMarkersHistoryAdapter extends RecyclerView.Adapter<RecyclerView.
}
}
public void hideSnackbar() {
if (snackbar != null && snackbar.isShown()) {
snackbar.dismiss();
}
}
@Override
public int getItemViewType(int position) {
Object item = items.get(position);
@ -190,7 +223,11 @@ public class MapMarkersHistoryAdapter extends RecyclerView.Adapter<RecyclerView.
SimpleDateFormat dateFormat = new SimpleDateFormat("LLLL", Locale.getDefault());
Date date = new Date();
date.setMonth(month);
return dateFormat.format(date);
String monthStr = dateFormat.format(date);
if (monthStr.length() > 1) {
monthStr = Character.toUpperCase(monthStr.charAt(0)) + monthStr.substring(1);
}
return monthStr;
}
public interface MapMarkersHistoryAdapterListener {

View file

@ -1,14 +1,72 @@
package net.osmand.plus.mapmarkers.adapters;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.View;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
public class MapMarkersItemTouchHelperCallback extends ItemTouchHelper.Callback {
private final ItemTouchHelperAdapter adapter;
private MapActivity mapActivity;
private boolean swipeEnabled = true;
private Paint backgroundPaint = new Paint();
private Paint iconPaint = new Paint();
private Paint textPaint = new Paint();
private float marginSides;
private Bitmap deleteBitmap;
private Bitmap historyBitmap;
private boolean iconHidden;
private boolean night;
private String delStr;
private String moveToHistoryStr;
private int delStrWidth;
private int textHeight;
public MapMarkersItemTouchHelperCallback(ItemTouchHelperAdapter adapter) {
this.adapter = adapter;
swipeEnabled = false;
}
public MapMarkersItemTouchHelperCallback(MapActivity mapActivity, ItemTouchHelperAdapter adapter) {
this.mapActivity = mapActivity;
this.adapter = adapter;
marginSides = mapActivity.getResources().getDimension(R.dimen.list_content_padding);
deleteBitmap = BitmapFactory.decodeResource(mapActivity.getResources(), R.drawable.ic_action_delete_dark);
historyBitmap = BitmapFactory.decodeResource(mapActivity.getResources(), R.drawable.ic_action_history);
night = !mapActivity.getMyApplication().getSettings().isLightContent();
backgroundPaint.setColor(ContextCompat.getColor(mapActivity, night ? R.color.dashboard_divider_dark : R.color.dashboard_divider_light));
backgroundPaint.setStyle(Paint.Style.FILL_AND_STROKE);
backgroundPaint.setAntiAlias(true);
iconPaint.setAntiAlias(true);
iconPaint.setFilterBitmap(true);
iconPaint.setDither(true);
textPaint.setTextSize(mapActivity.getResources().getDimension(R.dimen.default_desc_text_size));
textPaint.setFakeBoldText(true);
textPaint.setAntiAlias(true);
delStr = mapActivity.getString(R.string.shared_string_delete).toUpperCase();
moveToHistoryStr = mapActivity.getString(R.string.move_to_history).toUpperCase();
Rect bounds = new Rect();
textPaint.getTextBounds(delStr, 0, delStr.length(), bounds);
delStrWidth = bounds.width();
textHeight = bounds.height();
}
@Override
@ -18,13 +76,14 @@ public class MapMarkersItemTouchHelperCallback extends ItemTouchHelper.Callback
@Override
public boolean isItemViewSwipeEnabled() {
return false;
return swipeEnabled;
}
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
return makeMovementFlags(dragFlags, 0);
final int moveFlags = ItemTouchHelper.RIGHT;
return makeMovementFlags(dragFlags, swipeEnabled ? moveFlags : 0);
}
@Override
@ -33,20 +92,59 @@ public class MapMarkersItemTouchHelperCallback extends ItemTouchHelper.Callback
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int i) {
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE && viewHolder instanceof MapMarkerItemViewHolder) {
if (!iconHidden && isCurrentlyActive) {
((MapMarkerItemViewHolder) viewHolder).optionsBtn.setVisibility(View.GONE);
iconHidden = true;
adapter.onSwipeStarted();
}
View itemView = viewHolder.itemView;
int colorIcon;
int colorText;
if (Math.abs(dX) > itemView.getWidth() / 2) {
colorIcon = R.color.map_widget_blue;
colorText = R.color.map_widget_blue;
} else {
colorIcon = night ? 0 : R.color.icon_color;
colorText = R.color.dashboard_subheader_text_light;
}
if (colorIcon != 0) {
iconPaint.setColorFilter(new PorterDuffColorFilter(ContextCompat.getColor(mapActivity, colorIcon), PorterDuff.Mode.SRC_IN));
}
textPaint.setColor(ContextCompat.getColor(mapActivity, colorText));
float textMarginTop = ((float) itemView.getHeight() - (float) textHeight) / 2;
c.drawRect(itemView.getLeft(), itemView.getTop(), dX, itemView.getBottom(), backgroundPaint);
float iconMarginTop = ((float) itemView.getHeight() - (float) historyBitmap.getHeight()) / 2;
c.drawBitmap(historyBitmap, itemView.getLeft() + marginSides, itemView.getTop() + iconMarginTop, iconPaint);
c.drawText(moveToHistoryStr, itemView.getLeft() + 2 * marginSides + historyBitmap.getWidth(),
itemView.getTop() + textMarginTop + textHeight, textPaint);
}
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int i) {
adapter.onItemSwiped(viewHolder);
}
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
((MapMarkerItemViewHolder) viewHolder).optionsBtn.setVisibility(View.VISIBLE);
iconHidden = false;
adapter.onItemDismiss(viewHolder);
}
interface ItemTouchHelperAdapter {
void onSwipeStarted();
boolean onItemMove(int from, int to);
void onItemSwiped(RecyclerView.ViewHolder holder);
void onItemDismiss(RecyclerView.ViewHolder holder);
}
}

View file

@ -0,0 +1,186 @@
package net.osmand.plus.mapmarkers.adapters;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.MotionEventCompat;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import net.osmand.data.LatLon;
import net.osmand.plus.IconsCache;
import net.osmand.plus.MapMarkersHelper.MapMarker;
import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.util.MapUtils;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
public class MapMarkersListAdapter extends RecyclerView.Adapter<MapMarkerItemViewHolder>
implements MapMarkersItemTouchHelperCallback.ItemTouchHelperAdapter {
private MapActivity mapActivity;
private List<MapMarker> markers;
private MapMarkersListAdapterListener listener;
private LatLon location;
private boolean useCenter;
public void setAdapterListener(MapMarkersListAdapterListener listener) {
this.listener = listener;
}
public void setLocation(LatLon location) {
this.location = location;
}
public void setUseCenter(boolean useCenter) {
this.useCenter = useCenter;
}
public MapMarkersListAdapter(MapActivity mapActivity) {
this.mapActivity = mapActivity;
markers = mapActivity.getMyApplication().getMapMarkersHelper().getMapMarkers();
}
@Override
public MapMarkerItemViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.map_marker_item_new, viewGroup, false);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listener.onItemClick(view);
}
});
return new MapMarkerItemViewHolder(view);
}
@Override
public void onBindViewHolder(final MapMarkerItemViewHolder holder, int pos) {
boolean night = !mapActivity.getMyApplication().getSettings().isLightContent();
IconsCache iconsCache = mapActivity.getMyApplication().getIconsCache();
MapMarker marker = markers.get(pos);
holder.icon.setImageDrawable(iconsCache.getIcon(R.drawable.ic_action_flag_dark, MapMarker.getColorId(marker.colorIndex)));
holder.iconReorder.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_reorder));
holder.iconDirection.setVisibility(View.GONE);
holder.mainLayout.setBackgroundColor(ContextCompat.getColor(mapActivity, night ? R.color.bg_color_dark : R.color.bg_color_light));
holder.title.setTextColor(ContextCompat.getColor(mapActivity, night ? R.color.color_white : R.color.color_black));
holder.divider.setBackgroundColor(ContextCompat.getColor(mapActivity, night ? R.color.actionbar_dark_color : R.color.dashboard_divider_light));
holder.optionsBtn.setVisibility(View.GONE);
holder.description.setTextColor(ContextCompat.getColor(mapActivity, night ? R.color.dash_search_icon_dark : R.color.icon_color));
holder.checkBox.setVisibility(View.VISIBLE);
holder.checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listener.onItemClick(holder.itemView);
}
});
holder.checkBox.setChecked(marker.selected);
if (pos == 0 || pos == getItemCount() - 1) {
holder.firstDescription.setVisibility(View.VISIBLE);
if (pos == 0) {
holder.topDivider.setVisibility(View.VISIBLE);
holder.firstDescription.setText(mapActivity.getString(R.string.shared_string_control_start) + "");
} else {
holder.firstDescription.setText(mapActivity.getString(R.string.shared_string_finish) + "");
}
} else {
holder.firstDescription.setVisibility(View.GONE);
holder.topDivider.setVisibility(View.GONE);
}
if (pos == getItemCount() - 1) {
holder.bottomShadow.setVisibility(View.VISIBLE);
holder.divider.setVisibility(View.GONE);
} else {
holder.bottomShadow.setVisibility(View.GONE);
holder.divider.setVisibility(View.VISIBLE);
}
holder.point.setVisibility(View.VISIBLE);
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.title.setText(marker.getName(mapActivity));
String descr;
if ((descr = marker.groupName) != null) {
if (descr.equals("")) {
descr = mapActivity.getString(R.string.shared_string_favorites);
}
} else {
Date date = new Date(marker.creationDate);
String month = new SimpleDateFormat("MMM", Locale.getDefault()).format(date);
if (month.length() > 1) {
month = Character.toUpperCase(month.charAt(0)) + month.substring(1);
}
String day = new SimpleDateFormat("dd", Locale.getDefault()).format(date);
descr = month + " " + day;
}
holder.description.setText(descr);
if (location != null) {
holder.distance.setTextColor(ContextCompat.getColor(mapActivity, useCenter
? R.color.color_distance : R.color.color_myloc_distance));
float dist = (float) MapUtils.getDistance(location.getLatitude(), location.getLongitude(),
marker.getLatitude(), marker.getLongitude());
holder.distance.setText(OsmAndFormatter.getFormattedDistance(dist, mapActivity.getMyApplication()));
}
}
@Override
public int getItemCount() {
return markers.size();
}
public MapMarker getItem(int position) {
return markers.get(position);
}
@Override
public void onSwipeStarted() {
}
@Override
public boolean onItemMove(int from, int to) {
Collections.swap(markers, from, to);
notifyItemMoved(from, to);
return true;
}
@Override
public void onItemSwiped(RecyclerView.ViewHolder holder) {
}
@Override
public void onItemDismiss(RecyclerView.ViewHolder holder) {
listener.onDragEnded(holder);
}
public interface MapMarkersListAdapterListener {
void onItemClick(View view);
void onDragStarted(RecyclerView.ViewHolder holder);
void onDragEnded(RecyclerView.ViewHolder holder);
}
}

View file

@ -173,8 +173,8 @@ public class MeasurementToolFragment extends Fragment {
((SaveAsNewTrackBottomSheetDialogFragment) saveAsNewTrackFragment).setListener(createSaveAsNewTrackFragmentListener());
}
// If rotate the screen from landscape to portrait when the list of points is displayed then
// the PointsListFragment will exist without view. This is necessary to remove it.
if (portrait) {
// the RecyclerViewFragment will exist without view. This is necessary to remove it.
if (!portrait) {
hidePointsListFragment();
}
@ -636,7 +636,7 @@ public class MeasurementToolFragment extends Fragment {
return new SnapToRoadFragmentListener() {
@Override
public void onDestroyView(boolean snapToRoadEnabled) {
if (!snapToRoadEnabled) {
if (!snapToRoadEnabled && !editingCtx.isInSnapToRoadMode()) {
toolBarController.setTitle(previousToolBarTitle);
MapActivity mapActivity = getMapActivity();
if (mapActivity != null) {
@ -1029,12 +1029,12 @@ public class MeasurementToolFragment extends Fragment {
MapActivity mapActivity = getMapActivity();
if (mapActivity != null) {
int screenHeight = AndroidUtils.getScreenHeight(mapActivity) - AndroidUtils.getStatusBarHeight(mapActivity);
MeasurePointsListFragment fragment = new MeasurePointsListFragment();
RecyclerViewFragment fragment = new RecyclerViewFragment();
fragment.setRecyclerView(pointsRv);
fragment.setWidth(upDownRow.getWidth());
fragment.setHeight(screenHeight - upDownRow.getHeight());
mapActivity.getSupportFragmentManager().beginTransaction()
.add(R.id.fragmentContainer, fragment, MeasurePointsListFragment.TAG)
.add(R.id.fragmentContainer, fragment, RecyclerViewFragment.TAG)
.commitAllowingStateLoss();
}
}
@ -1044,7 +1044,7 @@ public class MeasurementToolFragment extends Fragment {
if (mapActivity != null) {
try {
FragmentManager manager = mapActivity.getSupportFragmentManager();
Fragment fragment = manager.findFragmentByTag(MeasurePointsListFragment.TAG);
Fragment fragment = manager.findFragmentByTag(RecyclerViewFragment.TAG);
if (fragment != null) {
manager.beginTransaction().remove(fragment).commitAllowingStateLoss();
}

View file

@ -225,23 +225,19 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
WptPt pt = before.points.get(before.points.size() - 1);
int locX = tb.getPixXFromLonNoRot(pt.lon);
int locY = tb.getPixYFromLatNoRot(pt.lat);
path.moveTo(locX, locY);
tx.add(locX);
ty.add(locY);
path.lineTo(tb.getCenterPixelX(), tb.getCenterPixelY());
tx.add(tb.getCenterPixelX());
ty.add(tb.getCenterPixelY());
}
if (after.points.size() > 0) {
if (before.points.size() == 0) {
path.moveTo(tb.getCenterPixelX(), tb.getCenterPixelY());
tx.add(tb.getCenterPixelX());
ty.add(tb.getCenterPixelY());
}
WptPt pt = after.points.get(0);
int locX = tb.getPixXFromLonNoRot(pt.lon);
int locY = tb.getPixYFromLatNoRot(pt.lat);
path.lineTo(locX, locY);
tx.add(locX);
ty.add(locY);
}

View file

@ -18,9 +18,9 @@ import net.osmand.AndroidUtils;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
public class MeasurePointsListFragment extends Fragment {
public class RecyclerViewFragment extends Fragment {
public static final String TAG = "MeasurePointsListFragment";
public static final String TAG = "RecyclerViewFragment";
private RecyclerView rv;
private int height;

View file

@ -139,7 +139,7 @@ public class SnapToRoadBottomSheetDialogFragment extends android.support.design.
.getIcon(id, nightMode ? R.color.ctx_menu_info_text_dark : R.color.on_map_icon_color);
}
interface SnapToRoadFragmentListener {
public interface SnapToRoadFragmentListener {
void onDestroyView(boolean snapToRoadEnabled);

View file

@ -712,7 +712,7 @@ public class MapControlsLayer extends OsmandMapLayer {
((app.accessibilityEnabled() || (System.currentTimeMillis() - touchEvent < TIMEOUT_TO_SHOW_BUTTONS)) && routeFollowingMode);
updateMyLocation(rh, routeDialogOpened || trackDialogOpened);
boolean showButtons = (showRouteCalculationControls || !routeFollowingMode)
&& !isInMovingMarkerMode() && !isInGpxDetailsMode() && !isInMeasurementToolMode();
&& !isInMovingMarkerMode() && !isInGpxDetailsMode() && !isInMeasurementToolMode() && !isInPlanRouteMode();
//routePlanningBtn.setIconResId(routeFollowingMode ? R.drawable.ic_action_gabout_dark : R.drawable.map_directions);
if (rh.isFollowingMode()) {
routePlanningBtn.setIconResId(R.drawable.map_start_navigation);
@ -727,16 +727,16 @@ public class MapControlsLayer extends OsmandMapLayer {
routePlanningBtn.updateVisibility(showButtons);
menuControl.updateVisibility(showButtons);
mapZoomIn.updateVisibility(!routeDialogOpened);
mapZoomOut.updateVisibility(!routeDialogOpened);
compassHud.updateVisibility(!routeDialogOpened && !trackDialogOpened && shouldShowCompass() &&
!isInMeasurementToolMode());
mapZoomIn.updateVisibility(!routeDialogOpened && !isInExpandedRouteMode());
mapZoomOut.updateVisibility(!routeDialogOpened && !isInExpandedRouteMode());
compassHud.updateVisibility(!routeDialogOpened && !trackDialogOpened && shouldShowCompass()
&& !isInMeasurementToolMode() && !isInPlanRouteMode());
if (layersHud.setIconResId(settings.getApplicationMode().getMapIconId())) {
layersHud.update(app, isNight);
}
layersHud.updateVisibility(!routeDialogOpened && !trackDialogOpened && !isInMeasurementToolMode());
quickSearchHud.updateVisibility(!routeDialogOpened && !trackDialogOpened && !isInMeasurementToolMode());
layersHud.updateVisibility(!routeDialogOpened && !trackDialogOpened && !isInMeasurementToolMode() && !isInPlanRouteMode());
quickSearchHud.updateVisibility(!routeDialogOpened && !trackDialogOpened && !isInMeasurementToolMode() && !isInPlanRouteMode());
if (!routePlanningMode && !routeFollowingMode) {
if (mapView.isZooming()) {
@ -814,7 +814,7 @@ public class MapControlsLayer extends OsmandMapLayer {
backToLocationControl.iv.setContentDescription(mapActivity.getString(R.string.map_widget_back_to_loc));
}
boolean visible = !(tracked && rh.isFollowingMode());
backToLocationControl.updateVisibility(visible && !dialogOpened);
backToLocationControl.updateVisibility(visible && !dialogOpened && !isInExpandedRouteMode());
if (app.accessibilityEnabled()) {
backToLocationControl.iv.setClickable(enabled && visible);
}
@ -1132,6 +1132,14 @@ public class MapControlsLayer extends OsmandMapLayer {
return mapActivity.getMapLayers().getMeasurementToolLayer().isInMeasurementMode();
}
private boolean isInPlanRouteMode() {
return mapActivity.getMapLayers().getMapMarkersLayer().isInPlanRouteMode();
}
private boolean isInExpandedRouteMode() {
return mapActivity.getMapLayers().getMapMarkersLayer().isMarkersListOpened();
}
public static View.OnLongClickListener getOnClickMagnifierListener(final OsmandMapTileView view) {
return new View.OnLongClickListener() {

View file

@ -5,9 +5,11 @@ import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.PointF;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
@ -19,6 +21,7 @@ import net.osmand.data.QuadPoint;
import net.osmand.data.RotatedTileBox;
import net.osmand.plus.MapMarkersHelper;
import net.osmand.plus.MapMarkersHelper.MapMarker;
import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.TargetPointsHelper.TargetPoint;
@ -27,6 +30,7 @@ import net.osmand.plus.views.ContextMenuLayer.ApplyMovedObjectCallback;
import net.osmand.plus.views.ContextMenuLayer.IContextMenuProvider;
import net.osmand.plus.views.ContextMenuLayer.IContextMenuProviderSelection;
import net.osmand.plus.views.mapwidgets.MapMarkersWidgetsFactory;
import net.osmand.util.MapUtils;
import java.util.ArrayList;
import java.util.List;
@ -37,6 +41,8 @@ public class MapMarkersLayer extends OsmandMapLayer implements IContextMenuProvi
IContextMenuProviderSelection, ContextMenuLayer.IMoveObjectProvider {
protected static final int DIST_TO_SHOW = 80;
private static final int TEXT_SIZE = 12;
private static final int VERTICAL_OFFSET = 10;
private final MapActivity map;
private OsmandMapTileView view;
@ -63,6 +69,7 @@ public class MapMarkersLayer extends OsmandMapLayer implements IContextMenuProvi
private float[] calculations = new float[2];
private final RenderingLineAttributes lineAttrs = new RenderingLineAttributes("measureDistanceLine");
private final RenderingLineAttributes textAttrs = new RenderingLineAttributes("rulerCircle");
private Paint paint;
private Path path;
private List<LatLon> route = new ArrayList<>();
@ -70,9 +77,13 @@ public class MapMarkersLayer extends OsmandMapLayer implements IContextMenuProvi
private TIntArrayList tx = new TIntArrayList();
private TIntArrayList ty = new TIntArrayList();
private Path linePath = new Path();
private String distanceText;
private ContextMenuLayer contextMenuLayer;
private boolean inPlanRouteMode;
private boolean markersListOpened;
public MapMarkersLayer(MapActivity map) {
this.map = map;
}
@ -81,6 +92,22 @@ public class MapMarkersLayer extends OsmandMapLayer implements IContextMenuProvi
return widgetsFactory;
}
public boolean isInPlanRouteMode() {
return inPlanRouteMode;
}
public void setInPlanRouteMode(boolean inPlanRouteMode) {
this.inPlanRouteMode = inPlanRouteMode;
}
public boolean isMarkersListOpened() {
return inPlanRouteMode && markersListOpened;
}
public void setMarkersListOpened(boolean markersListOpened) {
this.markersListOpened = markersListOpened;
}
private void initUI() {
bitmapPaint = new Paint();
bitmapPaint.setDither(true);
@ -113,6 +140,10 @@ public class MapMarkersLayer extends OsmandMapLayer implements IContextMenuProvi
paint.setColor(ContextCompat.getColor(map, R.color.marker_red));
paint.setAlpha(200);
float textSize = TEXT_SIZE * map.getResources().getDisplayMetrics().density;
textAttrs.paint2.setTextSize(textSize);
textAttrs.paint3.setTextSize(textSize);
widgetsFactory = new MapMarkersWidgetsFactory(map);
contextMenuLayer = view.getLayerByClass(ContextMenuLayer.class);
@ -199,8 +230,6 @@ public class MapMarkersLayer extends OsmandMapLayer implements IContextMenuProvi
return;
}
lineAttrs.updatePaints(view, nightMode, tileBox);
MapMarkersHelper markersHelper = map.getMyApplication().getMapMarkersHelper();
if (route.size() > 0) {
path.reset();
@ -228,25 +257,66 @@ public class MapMarkersLayer extends OsmandMapLayer implements IContextMenuProvi
List<MapMarker> activeMapMarkers = markersHelper.getMapMarkers();
if (settings.SHOW_LINES_TO_FIRST_MARKERS.get() && myLoc != null) {
int locX = tileBox.getPixXFromLonNoRot(myLoc.getLongitude());
int locY = tileBox.getPixYFromLatNoRot(myLoc.getLatitude());
lineAttrs.updatePaints(view, nightMode, tileBox);
textAttrs.updatePaints(view, nightMode, tileBox);
textAttrs.paint2.setStyle(Paint.Style.FILL);
int locX = (int) tileBox.getPixXFromLatLon(myLoc.getLatitude(), myLoc.getLongitude());
int locY = (int) tileBox.getPixYFromLatLon(myLoc.getLatitude(), myLoc.getLongitude());
int[] colors = MapMarker.getColors(map);
for (int i = 0; i < activeMapMarkers.size() && i < 2; i++) {
MapMarker marker = activeMapMarkers.get(i);
int markerX = tileBox.getPixXFromLonNoRot(marker.getLongitude());
int markerY = tileBox.getPixYFromLatNoRot(marker.getLatitude());
int markerX = (int) tileBox.getPixXFromLatLon(marker.getLatitude(), marker.getLongitude());
int markerY = (int) tileBox.getPixYFromLatLon(marker.getLatitude(), marker.getLongitude());
linePath.reset();
tx.clear();
ty.clear();
linePath.moveTo(locX, locY);
linePath.lineTo(markerX, markerY);
tx.add(locX);
ty.add(locY);
tx.add(markerX);
ty.add(markerY);
calculatePath(tileBox, tx, ty, linePath);
PathMeasure pm = new PathMeasure(linePath, false);
float[] pos = new float[2];
pm.getPosTan(pm.getLength() / 2, pos, null);
float generalDist = (float) MapUtils.getDistance(myLoc.getLatitude(), myLoc.getLongitude(), marker.getLatitude(), marker.getLongitude());
String generalDistSt = OsmAndFormatter.getFormattedDistance(generalDist, view.getApplication());
boolean locationInvisible = locX < 0 || locX > tileBox.getPixWidth() || locY < 0 || locY > tileBox.getPixHeight();
if (locationInvisible) {
float centerToMarkerDist = (float) MapUtils.getDistance(tileBox.getLatLonFromPixel(pos[0], pos[1]), marker.getLatitude(), marker.getLongitude());
String centerToMarkerDistSt = OsmAndFormatter.getFormattedDistance(centerToMarkerDist, view.getApplication());
if (locX >= markerX) {
distanceText = centerToMarkerDistSt + " | " + generalDistSt;
} else {
distanceText = generalDistSt + " | " + centerToMarkerDistSt;
}
} else {
distanceText = generalDistSt;
}
Rect bounds = new Rect();
textAttrs.paint2.getTextBounds(distanceText, 0, distanceText.length(), bounds);
float hOffset = pm.getLength() / 2 - bounds.width() / 2;
lineAttrs.paint.setColor(colors[marker.colorIndex]);
canvas.rotate(-tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY());
canvas.drawPath(linePath, lineAttrs.paint);
if (locationInvisible && !(pos[0] == 0 && pos[1] == 0)) {
canvas.drawCircle(pos[0], pos[1], 5, new Paint());
}
if (locX >= markerX) {
canvas.rotate(180, pos[0], pos[1]);
canvas.drawTextOnPath(distanceText, linePath, hOffset, bounds.height() + VERTICAL_OFFSET, textAttrs.paint3);
canvas.drawTextOnPath(distanceText, linePath, hOffset, bounds.height() + VERTICAL_OFFSET, textAttrs.paint2);
canvas.rotate(-180, pos[0], pos[1]);
} else {
canvas.drawTextOnPath(distanceText, linePath, hOffset, -VERTICAL_OFFSET, textAttrs.paint3);
canvas.drawTextOnPath(distanceText, linePath, hOffset, -VERTICAL_OFFSET, textAttrs.paint2);
}
canvas.rotate(tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY());
}
}
@ -426,6 +496,7 @@ public class MapMarkersLayer extends OsmandMapLayer implements IContextMenuProvi
public void setSelectedObject(Object o) {
if (o instanceof MapMarker) {
map.getMyApplication().getMapMarkersHelper().moveMarkerToTop((MapMarker) o);
map.getMyApplication().getSettings().MAP_MARKERS_ORDER_BY_MODE.set(OsmandSettings.MapMarkersOrderByMode.CUSTOM);
}
}

View file

@ -139,49 +139,54 @@ public abstract class OsmandMapLayer {
}
public int calculatePath(RotatedTileBox tb, TIntArrayList xs, TIntArrayList ys, Path path) {
boolean start = false;
int px = xs.get(0);
int py = ys.get(0);
int h = tb.getPixHeight();
int w = tb.getPixWidth();
boolean segmentStarted = false;
int prevX = xs.get(0);
int prevY = ys.get(0);
int height = tb.getPixHeight();
int width = tb.getPixWidth();
int cnt = 0;
boolean pin = isIn(px, py, 0, 0, w, h);
boolean prevIn = isIn(prevX, prevY, 0, 0, width, height);
for (int i = 1; i < xs.size(); i++) {
int x = xs.get(i);
int y = ys.get(i);
boolean in = isIn(x, y, 0, 0, w, h);
int currX = xs.get(i);
int currY = ys.get(i);
boolean currIn = isIn(currX, currY, 0, 0, width, height);
boolean draw = false;
if (pin && in) {
if (prevIn && currIn) {
draw = true;
} else {
long intersection = MapAlgorithms.calculateIntersection(x, y,
px, py, 0, w, h, 0);
long intersection = MapAlgorithms.calculateIntersection(currX, currY, prevX, prevY, 0, width, height, 0);
if (intersection != -1) {
if (pin && (i == 1)) {
if (prevIn && (i == 1)) {
cnt++;
path.moveTo(px, py);
start = true;
path.moveTo(prevX, prevY);
segmentStarted = true;
}
px = (int) (intersection >> 32);
py = (int) (intersection & 0xffffffff);
prevX = (int) (intersection >> 32);
prevY = (int) (intersection & 0xffffffff);
draw = true;
}
if (i == xs.size() - 1 && !currIn) {
long inter = MapAlgorithms.calculateIntersection(prevX, prevY, currX, currY, 0, width, height, 0);
if (inter != -1) {
currX = (int) (inter >> 32);
currY = (int) (inter & 0xffffffff);
}
}
}
if (draw) {
if (!start) {
if (!segmentStarted) {
cnt++;
path.moveTo(px, py);
path.moveTo(prevX, prevY);
segmentStarted = true;
}
path.lineTo(x, y);
start = true;
path.lineTo(currX, currY);
} else {
start = false;
segmentStarted = false;
}
pin = in;
px = x;
py = y;
prevIn = currIn;
prevX = currX;
prevY = currY;
}
return cnt;
}
@ -407,7 +412,7 @@ public abstract class OsmandMapLayer {
private void updateDefaultColor(Paint paint, int defaultColor) {
if((paint.getColor() == 0 || paint.getColor() == Color.BLACK) && defaultColor != 0) {
if ((paint.getColor() == 0 || paint.getColor() == Color.BLACK) && defaultColor != 0) {
paint.setColor(defaultColor);
}
}

View file

@ -5,6 +5,8 @@ import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Handler;
@ -22,15 +24,19 @@ import net.osmand.plus.OsmandSettings;
import net.osmand.plus.OsmandSettings.RulerMode;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.util.MapUtils;
import java.util.ArrayList;
import gnu.trove.list.array.TIntArrayList;
public class RulerControlLayer extends OsmandMapLayer {
private static final int VERTICAL_OFFSET = 15;
private static final long DRAW_TIME = 2000;
private static final long DELAY_BEFORE_DRAW = 500;
private static final int TEXT_SIZE = 14;
private static final int MAX_ITERATIONS = 50;
private static final int DISTANCE_TEXT_SIZE = 16;
private final MapActivity mapActivity;
private OsmandApplication app;
@ -62,12 +68,18 @@ public class RulerControlLayer extends OsmandMapLayer {
private boolean touched;
private boolean wasZoom;
private TIntArrayList tx = new TIntArrayList();
private TIntArrayList ty = new TIntArrayList();
private Path linePath = new Path();
private Bitmap centerIconDay;
private Bitmap centerIconNight;
private Paint bitmapPaint;
private RenderingLineAttributes lineAttrs;
private RenderingLineAttributes circleAttrs;
private RenderingLineAttributes circleAttrsAlt;
private float circleTextSize;
private float lineTextSize;
private Handler handler;
@ -110,15 +122,16 @@ public class RulerControlLayer extends OsmandMapLayer {
lineAttrs = new RenderingLineAttributes("rulerLine");
float textSize = TEXT_SIZE * mapActivity.getResources().getDisplayMetrics().density;
circleTextSize = TEXT_SIZE * mapActivity.getResources().getDisplayMetrics().density;
lineTextSize = DISTANCE_TEXT_SIZE * mapActivity.getResources().getDisplayMetrics().density;
circleAttrs = new RenderingLineAttributes("rulerCircle");
circleAttrs.paint2.setTextSize(textSize);
circleAttrs.paint3.setTextSize(textSize);
circleAttrs.paint2.setTextSize(circleTextSize);
circleAttrs.paint3.setTextSize(circleTextSize);
circleAttrsAlt = new RenderingLineAttributes("rulerCircleAlt");
circleAttrsAlt.paint2.setTextSize(textSize);
circleAttrsAlt.paint3.setTextSize(textSize);
circleAttrsAlt.paint2.setTextSize(circleTextSize);
circleAttrsAlt.paint3.setTextSize(circleTextSize);
handler = new Handler() {
@Override
@ -202,22 +215,16 @@ public class RulerControlLayer extends OsmandMapLayer {
drawCenterIcon(canvas, tb, center, settings.isNightMode(), mode);
Location currentLoc = app.getLocationProvider().getLastKnownLocation();
if (showDistBetweenFingerAndLocation && currentLoc != null) {
float x = tb.getPixXFromLatLon(touchPointLatLon.getLatitude(), touchPointLatLon.getLongitude());
float y = tb.getPixYFromLatLon(touchPointLatLon.getLatitude(), touchPointLatLon.getLongitude());
drawDistBetweenFingerAndLocation(canvas, tb, x, y, currentLoc, settings.isNightMode());
drawDistBetweenFingerAndLocation(canvas, tb, currentLoc, settings.isNightMode());
} else if (showTwoFingersDistance) {
LatLon firstTouchPoint = view.getFirstTouchPointLatLon();
LatLon secondTouchPoint = view.getSecondTouchPointLatLon();
float x1 = tb.getPixXFromLonNoRot(firstTouchPoint.getLongitude());
float y1 = tb.getPixYFromLatNoRot(firstTouchPoint.getLatitude());
float x2 = tb.getPixXFromLonNoRot(secondTouchPoint.getLongitude());
float y2 = tb.getPixYFromLatNoRot(secondTouchPoint.getLatitude());
drawTwoFingersDistance(canvas, x1, y1, x2, y2, settings.isNightMode());
drawTwoFingersDistance(canvas, tb, view.getFirstTouchPointLatLon(), view.getSecondTouchPointLatLon(), settings.isNightMode());
}
if (mode == RulerMode.FIRST || mode == RulerMode.SECOND) {
updateData(tb, center);
RenderingLineAttributes attrs;
if (mode == RulerMode.FIRST) {
circleAttrs.paint2.setTextSize(circleTextSize);
circleAttrs.paint3.setTextSize(circleTextSize);
attrs = circleAttrs;
} else {
attrs = circleAttrsAlt;
@ -238,10 +245,46 @@ public class RulerControlLayer extends OsmandMapLayer {
handler.sendEmptyMessageDelayed(0, DRAW_TIME + 50);
}
private void drawTwoFingersDistance(Canvas canvas, float x1, float y1, float x2, float y2, boolean nightMode) {
canvas.drawLine(x1, y1, x2, y2, lineAttrs.paint);
private void drawTwoFingersDistance(Canvas canvas, RotatedTileBox tb, LatLon firstTouch, LatLon secondTouch, boolean nightMode) {
float x1 = tb.getPixXFromLatLon(firstTouch.getLatitude(), firstTouch.getLongitude());
float y1 = tb.getPixYFromLatLon(firstTouch.getLatitude(), firstTouch.getLongitude());
float x2 = tb.getPixXFromLatLon(secondTouch.getLatitude(), secondTouch.getLongitude());
float y2 = tb.getPixYFromLatLon(secondTouch.getLatitude(), secondTouch.getLongitude());
Path path = new Path();
path.moveTo(x1, y1);
path.lineTo(x2, y2);
String text = OsmAndFormatter.getFormattedDistance((float) MapUtils.getDistance(firstTouch, secondTouch), app);
canvas.rotate(-tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY());
canvas.drawPath(path, lineAttrs.paint);
drawFingerTouchIcon(canvas, x1, y1, nightMode);
drawFingerTouchIcon(canvas, x2, y2, nightMode);
drawTextOnCenterOfPath(canvas, x1, x2, path, text);
canvas.rotate(tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY());
}
private void drawTextOnCenterOfPath(Canvas canvas, float x1, float x2, Path path, String text) {
PathMeasure pm = new PathMeasure(path, false);
Rect bounds = new Rect();
circleAttrs.paint2.getTextBounds(text, 0, text.length(), bounds);
float hOffset = pm.getLength() / 2 - bounds.width() / 2;
circleAttrs.paint2.setTextSize(lineTextSize);
circleAttrs.paint3.setTextSize(lineTextSize);
if (x1 >= x2) {
float[] pos = new float[2];
pm.getPosTan(pm.getLength() / 2, pos, null);
canvas.rotate(180, pos[0], pos[1]);
canvas.drawTextOnPath(text, path, hOffset, bounds.height() + VERTICAL_OFFSET, circleAttrs.paint3);
canvas.drawTextOnPath(text, path, hOffset, bounds.height() + VERTICAL_OFFSET, circleAttrs.paint2);
canvas.rotate(-180, pos[0], pos[1]);
} else {
canvas.drawTextOnPath(text, path, hOffset, -VERTICAL_OFFSET, circleAttrs.paint3);
canvas.drawTextOnPath(text, path, hOffset, -VERTICAL_OFFSET, circleAttrs.paint2);
}
}
private void drawFingerTouchIcon(Canvas canvas, float x, float y, boolean nightMode) {
@ -267,42 +310,32 @@ public class RulerControlLayer extends OsmandMapLayer {
canvas.rotate(tb.getRotate(), center.x, center.y);
}
private void drawDistBetweenFingerAndLocation(Canvas canvas, RotatedTileBox tb, float x, float y,
Location currentLoc, boolean nightMode) {
int currX = (int) tb.getPixXFromLatLon(currentLoc.getLatitude(), currentLoc.getLongitude());
int currY = (int) tb.getPixYFromLatLon(currentLoc.getLatitude(), currentLoc.getLongitude());
int width = tb.getPixWidth();
int height = tb.getPixHeight();
boolean needDraw = true;
private void drawDistBetweenFingerAndLocation(Canvas canvas, RotatedTileBox tb, Location currLoc, boolean night) {
float x = tb.getPixXFromLatLon(touchPointLatLon.getLatitude(), touchPointLatLon.getLongitude());
float y = tb.getPixYFromLatLon(touchPointLatLon.getLatitude(), touchPointLatLon.getLongitude());
int currX = (int) tb.getPixXFromLatLon(currLoc.getLatitude(), currLoc.getLongitude());
int currY = (int) tb.getPixYFromLatLon(currLoc.getLatitude(), currLoc.getLongitude());
if ((currX < 0 && x == 0) || (currY < 0 && y == 0)
|| (currX > width && x == width) || (currY > height && y == height)) {
needDraw = false;
} else if (currX < 0 || currY < 0 || currX > width || currY > height) {
float xNew = (currX + x) / 2;
float yNew = (currY + y) / 2;
int count = 0;
linePath.reset();
tx.reset();
ty.reset();
while (count < MAX_ITERATIONS) {
count++;
if (xNew < 0 || yNew < 0 || xNew > width || yNew > height) {
currX = (int) xNew;
currY = (int) yNew;
} else {
break;
}
xNew = (xNew + x) / 2;
yNew = (yNew + y) / 2;
}
}
tx.add((int) x);
ty.add((int) y);
tx.add(currX);
ty.add(currY);
calculatePath(tb, tx, ty, linePath);
float dist = (float) MapUtils.getDistance(touchPointLatLon, currLoc.getLatitude(), currLoc.getLongitude());
String text = OsmAndFormatter.getFormattedDistance(dist, app);
if (needDraw) {
canvas.rotate(-tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY());
canvas.drawLine(currX, currY, x, y, lineAttrs.paint);
drawFingerTouchIcon(canvas, x, y, nightMode);
canvas.drawPath(linePath, lineAttrs.paint);
drawFingerTouchIcon(canvas, x, y, night);
drawTextOnCenterOfPath(canvas, x, currX, linePath, text);
canvas.rotate(tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY());
}
}
private void updateData(RotatedTileBox tb, QuadPoint center) {
if (tb.getPixHeight() > 0 && tb.getPixWidth() > 0 && maxRadiusInDp > 0) {