Merge pull request #11203 from osmandapp/RouteLine
Route Line Customization
This commit is contained in:
commit
feadaa0da5
34 changed files with 2000 additions and 70 deletions
|
@ -10,8 +10,6 @@ import net.osmand.router.GeneralRouter.RouteDataObjectAttribute;
|
|||
|
||||
public class TransportRoutingConfiguration {
|
||||
|
||||
public static final String KEY = "public_transport";
|
||||
|
||||
public int ZOOM_TO_LOAD_TILES = 15;
|
||||
|
||||
public int walkRadius = 1500; // ? 3000
|
||||
|
|
162
OsmAnd/res/layout/route_line_appearance.xml
Normal file
162
OsmAnd/res/layout/route_line_appearance.xml
Normal file
|
@ -0,0 +1,162 @@
|
|||
<?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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/color_transparent">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/main_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include layout="@layout/context_menu_top_shadow" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/route_menu_top_shadow_all"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/bg_color"
|
||||
android:minHeight="@dimen/bottom_sheet_title_height"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingRight="@dimen/content_padding">
|
||||
|
||||
<View
|
||||
android:layout_width="@dimen/content_padding"
|
||||
android:layout_height="2dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="@dimen/context_menu_padding_margin_tiny"
|
||||
android:layout_marginBottom="@dimen/list_item_button_padding"
|
||||
android:background="?attr/bg_dash_line" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/header_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical"
|
||||
android:letterSpacing="@dimen/text_button_letter_spacing"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/bottom_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:foreground="@drawable/bg_contextmenu_shadow"
|
||||
android:foregroundGravity="top|fill_horizontal">
|
||||
|
||||
<net.osmand.plus.LockableScrollView
|
||||
android:id="@+id/route_menu_bottom_scroll"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/route_info_bg">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/route_menu_cards_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/route_info_bg"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="@dimen/dialog_button_ex_height" />
|
||||
|
||||
</net.osmand.plus.LockableScrollView>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/context_menu_toolbar_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:alpha="0">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/card_and_list_background_basic"
|
||||
android:minHeight="@dimen/toolbar_height"
|
||||
android:padding="0dp"
|
||||
osmand:contentInsetEnd="0dp"
|
||||
osmand:contentInsetLeft="0dp"
|
||||
osmand:contentInsetRight="0dp"
|
||||
osmand:contentInsetStart="0dp"
|
||||
osmand:theme="@style/ThemeOverlay.AppCompat.ActionBar">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="@dimen/toolbar_height">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageButton
|
||||
android:id="@+id/close_button"
|
||||
style="@style/Widget.AppCompat.Toolbar.Button.Navigation"
|
||||
android:layout_width="@dimen/toolbar_height"
|
||||
android:layout_height="@dimen/toolbar_height"
|
||||
android:tint="?android:textColorPrimary"
|
||||
android:contentDescription="@string/access_shared_string_navigate_up"
|
||||
osmand:srcCompat="@drawable/ic_arrow_back" />
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/toolbar_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/content_padding"
|
||||
android:layout_marginLeft="@dimen/content_padding"
|
||||
android:layout_marginEnd="@dimen/content_padding"
|
||||
android:layout_marginRight="@dimen/content_padding"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:letterSpacing="@dimen/text_button_letter_spacing"
|
||||
android:maxLines="2"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/dialog_header_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
android:text="@string/shared_string_route_line" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<include layout="@layout/context_menu_controls" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/control_buttons"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/buttons_shadow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="8dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="@drawable/shadow" />
|
||||
|
||||
<include
|
||||
layout="@layout/bottom_buttons"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dialog_button_ex_height"
|
||||
android:layout_gravity="bottom" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
98
OsmAnd/res/layout/route_line_color_card.xml
Normal file
98
OsmAnd/res/layout/route_line_color_card.xml
Normal file
|
@ -0,0 +1,98 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:letterSpacing="@dimen/description_letter_spacing"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingTop="@dimen/content_padding_small"
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
android:paddingBottom="@dimen/content_padding_small"
|
||||
android:text="@string/shared_string_color"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium" />
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/color_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="end"
|
||||
android:letterSpacing="@dimen/description_letter_spacing"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingTop="@dimen/content_padding_small"
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
android:paddingBottom="@dimen/content_padding_small"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
tools:text="Orange" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="@dimen/content_padding_half"
|
||||
android:paddingLeft="@dimen/content_padding_half"
|
||||
android:paddingEnd="@dimen/content_padding"
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
tools:itemCount="2"
|
||||
tools:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
tools:listitem="@layout/point_editor_group_select_item"
|
||||
tools:orientation="horizontal" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/theme_toggle_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/content_padding_small" >
|
||||
|
||||
<include layout="@layout/custom_radio_buttons" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="start"
|
||||
android:letterSpacing="@dimen/description_letter_spacing"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingTop="@dimen/content_padding_small"
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
android:paddingBottom="@dimen/content_padding_small"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_regular"
|
||||
tools:text="Specify color for map mode: day." />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/colors_card_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="@dimen/content_padding_small"/>
|
||||
|
||||
</LinearLayout>
|
170
OsmAnd/res/layout/route_line_width_card.xml
Normal file
170
OsmAnd/res/layout/route_line_width_card.xml
Normal file
|
@ -0,0 +1,170 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical">
|
||||
|
||||
<View
|
||||
android:id="@+id/top_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/divider_color_basic"
|
||||
android:focusable="false" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:letterSpacing="@dimen/description_letter_spacing"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingTop="@dimen/content_padding_small"
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
android:paddingBottom="@dimen/content_padding_small"
|
||||
android:text="@string/select_track_width"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium" />
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/width_type"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="end"
|
||||
android:letterSpacing="@dimen/description_letter_spacing"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingTop="@dimen/content_padding_small"
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
android:paddingBottom="@dimen/content_padding_small"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
tools:text="21" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="@dimen/context_menu_padding_margin_tiny">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="@dimen/content_padding_half"
|
||||
android:paddingLeft="@dimen/content_padding_half"
|
||||
android:paddingEnd="@dimen/content_padding"
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
tools:itemCount="3"
|
||||
tools:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
tools:listitem="@layout/point_editor_group_select_item"
|
||||
tools:orientation="horizontal" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/slider_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="@dimen/content_padding"
|
||||
android:paddingBottom="@dimen/favorites_select_group_button_height">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="@dimen/content_padding"
|
||||
android:paddingEnd="@dimen/content_padding">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:lineSpacingExtra="@dimen/line_spacing_extra_description"
|
||||
android:text="@string/shared_string_custom"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/default_list_text_size" />
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/width_value_tv"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="end"
|
||||
android:lineSpacingExtra="@dimen/line_spacing_extra_description"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
tools:text="1" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.slider.Slider
|
||||
android:id="@+id/width_slider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/content_padding"
|
||||
android:layout_marginRight="@dimen/content_padding"
|
||||
android:stepSize="1" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="@dimen/content_padding"
|
||||
android:paddingEnd="@dimen/content_padding">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/width_value_min"
|
||||
android:layout_width="@dimen/standard_icon_size"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:lineSpacingExtra="@dimen/line_spacing_extra_description"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
tools:text="1" />
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/width_value_max"
|
||||
android:layout_width="@dimen/standard_icon_size"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="end"
|
||||
android:lineSpacingExtra="@dimen/line_spacing_extra_description"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
tools:text="24" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="start"
|
||||
android:letterSpacing="@dimen/description_letter_spacing"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingTop="@dimen/content_padding_small"
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
android:paddingBottom="@dimen/content_padding_small"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_regular"
|
||||
tools:text="Route line would be use width specified on selected map style: OsmAnd." />
|
||||
|
||||
</LinearLayout>
|
|
@ -11,6 +11,11 @@
|
|||
Thx - Hardy
|
||||
|
||||
-->
|
||||
|
||||
<string name="specify_color_for_map_mode">Specify color for map mode: %1$s.</string>
|
||||
<string name="route_line_use_map_style_appearance">Route line would be use %1$s specified on selected map style: %2$s.</string>
|
||||
<string name="shared_string_route_line">Route line</string>
|
||||
<string name="customize_route_line">Customize route line</string>
|
||||
<string name="trip_recording_show_start_dialog_setting">If disabled, recording will start right after tap on the widget or menu item, skipping the confirmation dialog.</string>
|
||||
<string name="show_start_dialog">Show start dialog</string>
|
||||
<string name="lost_data_warning">All unsaved data will be lost.</string>
|
||||
|
|
|
@ -76,4 +76,11 @@
|
|||
android:title="@string/select_navigation_icon"
|
||||
android:selectable="false"/>
|
||||
|
||||
<Preference
|
||||
android:key="customize_route_line"
|
||||
android:layout="@layout/preference_button"
|
||||
android:persistent="false"
|
||||
android:title="@string/customize_route_line"
|
||||
android:icon="@drawable/ic_action_route_distance" />
|
||||
|
||||
</PreferenceScreen>
|
|
@ -125,6 +125,7 @@ import net.osmand.plus.settings.datastorage.DataStorageFragment;
|
|||
import net.osmand.plus.settings.fragments.BaseSettingsFragment;
|
||||
import net.osmand.plus.settings.fragments.BaseSettingsFragment.SettingsScreenType;
|
||||
import net.osmand.plus.settings.fragments.ConfigureProfileFragment;
|
||||
import net.osmand.plus.settings.fragments.RouteLineAppearanceFragment;
|
||||
import net.osmand.plus.track.TrackAppearanceFragment;
|
||||
import net.osmand.plus.track.TrackMenuFragment;
|
||||
import net.osmand.plus.views.AddGpxPointBottomSheetHelper.NewGpxPoint;
|
||||
|
@ -2265,6 +2266,10 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
|
|||
return getFragment(TrackMenuFragment.TAG);
|
||||
}
|
||||
|
||||
public RouteLineAppearanceFragment getRouteLineAppearanceFragment() {
|
||||
return getFragment(RouteLineAppearanceFragment.TAG);
|
||||
}
|
||||
|
||||
public void backToConfigureProfileFragment() {
|
||||
FragmentManager fragmentManager = getSupportFragmentManager();
|
||||
int backStackEntryCount = fragmentManager.getBackStackEntryCount();
|
||||
|
|
|
@ -193,10 +193,7 @@ public class SelectMapStyleBottomSheetDialogFragment extends MenuBottomSheetDial
|
|||
|
||||
List<String> names = new ArrayList<>(renderers.keySet());
|
||||
for (String name : names) {
|
||||
String translation = RendererRegistry.getTranslatedRendererName(context, name);
|
||||
if (translation == null) {
|
||||
translation = name.replace('_', ' ').replace('-', ' ');
|
||||
}
|
||||
String translation = RendererRegistry.getRendererName(context, name);
|
||||
res.put(translation, name);
|
||||
}
|
||||
|
||||
|
|
|
@ -106,6 +106,7 @@ import static net.osmand.plus.measurementtool.command.ClearPointsCommand.ClearCo
|
|||
import static net.osmand.plus.measurementtool.command.ClearPointsCommand.ClearCommandMode.AFTER;
|
||||
import static net.osmand.plus.measurementtool.command.ClearPointsCommand.ClearCommandMode.ALL;
|
||||
import static net.osmand.plus.measurementtool.command.ClearPointsCommand.ClearCommandMode.BEFORE;
|
||||
import static net.osmand.plus.routing.TransportRoutingHelper.PUBLIC_TRANSPORT_KEY;
|
||||
|
||||
public class MeasurementToolFragment extends BaseOsmAndFragment implements RouteBetweenPointsFragmentListener,
|
||||
OptionsFragmentListener, GpxApproximationFragmentListener, SelectedPointFragmentListener,
|
||||
|
@ -906,7 +907,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
case SnapTrackWarningFragment.CONTINUE_RESULT_CODE:
|
||||
if (mapActivity != null) {
|
||||
ApplicationMode mode = editingCtx.getAppMode();
|
||||
if (mode == ApplicationMode.DEFAULT || "public_transport".equals(mode.getRoutingProfile())) {
|
||||
if (mode == ApplicationMode.DEFAULT || PUBLIC_TRANSPORT_KEY.equals(mode.getRoutingProfile())) {
|
||||
mode = null;
|
||||
}
|
||||
List<List<WptPt>> pointsSegments = editingCtx.getPointsSegments(true, false);
|
||||
|
|
|
@ -20,6 +20,8 @@ import java.util.ArrayList;
|
|||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import static net.osmand.plus.routing.TransportRoutingHelper.PUBLIC_TRANSPORT_KEY;
|
||||
|
||||
public class ProfileCard extends BaseCard {
|
||||
|
||||
private ApplicationMode selectedMode;
|
||||
|
@ -42,7 +44,7 @@ public class ProfileCard extends BaseCard {
|
|||
Iterator<ApplicationMode> iterator = modes.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
ApplicationMode mode = iterator.next();
|
||||
if ("public_transport".equals(mode.getRoutingProfile())) {
|
||||
if (PUBLIC_TRANSPORT_KEY.equals(mode.getRoutingProfile())) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import static net.osmand.plus.UiUtilities.CustomRadioButtonType.END;
|
|||
import static net.osmand.plus.UiUtilities.CustomRadioButtonType.START;
|
||||
import static net.osmand.plus.measurementtool.MeasurementEditingContext.DEFAULT_APP_MODE;
|
||||
import static net.osmand.plus.measurementtool.SelectFileBottomSheet.BOTTOM_SHEET_HEIGHT_DP;
|
||||
import static net.osmand.plus.routing.TransportRoutingHelper.PUBLIC_TRANSPORT_KEY;
|
||||
|
||||
public class RouteBetweenPointsBottomSheetDialogFragment extends BottomSheetBehaviourDialogFragment {
|
||||
|
||||
|
@ -116,7 +117,7 @@ public class RouteBetweenPointsBottomSheetDialogFragment extends BottomSheetBeha
|
|||
|
||||
for (int i = 0; i < modes.size(); i++) {
|
||||
ApplicationMode mode = modes.get(i);
|
||||
if (!"public_transport".equals(mode.getRoutingProfile())) {
|
||||
if (!PUBLIC_TRANSPORT_KEY.equals(mode.getRoutingProfile())) {
|
||||
icon = app.getUIUtilities().getPaintedIcon(mode.getIconRes(), mode.getProfileColor(nightMode));
|
||||
addProfileView(navigationType, onClickListener, i, icon, mode.toHumanString(), mode.equals(appMode));
|
||||
}
|
||||
|
|
|
@ -102,9 +102,7 @@ public class MapStyleAction extends SwitchableAction<String> {
|
|||
|
||||
@Override
|
||||
public String getTranslatedItemName(Context context, String item) {
|
||||
String translation = RendererRegistry.getTranslatedRendererName(context, item);
|
||||
return translation != null ? translation
|
||||
: item.replace('_', ' ').replace('-', ' ');
|
||||
return RendererRegistry.getRendererName(context, item);
|
||||
}
|
||||
|
||||
public List<String> getFilteredStyles() {
|
||||
|
@ -175,9 +173,8 @@ public class MapStyleAction extends SwitchableAction<String> {
|
|||
List<String> visibleNamesList = new ArrayList<>();
|
||||
final List<String> items = new ArrayList<>(renderers.keySet());
|
||||
for (String item : items) {
|
||||
String translation = RendererRegistry.getTranslatedRendererName(activity, item);
|
||||
visibleNamesList.add(translation != null ? translation
|
||||
: item.replace('_', ' ').replace('-', ' '));
|
||||
String name = RendererRegistry.getRendererName(activity, item);
|
||||
visibleNamesList.add(name);
|
||||
}
|
||||
|
||||
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(themedContext, R.layout.dialog_text_item);
|
||||
|
|
|
@ -289,6 +289,20 @@ public class RendererRegistry {
|
|||
return renderers;
|
||||
}
|
||||
|
||||
public String getSelectedRendererName() {
|
||||
RenderingRulesStorage storage = getCurrentSelectedRenderer();
|
||||
if (storage == null) {
|
||||
return "";
|
||||
}
|
||||
return RendererRegistry.getRendererName(app, storage.getName());
|
||||
}
|
||||
|
||||
public static String getRendererName(@NonNull Context ctx, @NonNull String name) {
|
||||
String translation = getTranslatedRendererName(ctx, name);
|
||||
return translation != null ? translation :
|
||||
name.replace('_', ' ').replace('-', ' ');
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getTranslatedRendererName(@NonNull Context ctx, @NonNull String key) {
|
||||
switch (key) {
|
||||
|
|
156
OsmAnd/src/net/osmand/plus/routing/RouteLineDrawInfo.java
Normal file
156
OsmAnd/src/net/osmand/plus/routing/RouteLineDrawInfo.java
Normal file
|
@ -0,0 +1,156 @@
|
|||
package net.osmand.plus.routing;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
public class RouteLineDrawInfo {
|
||||
|
||||
private static final String LINE_COLOR = "line_color";
|
||||
private static final String LINE_WIDTH = "line_width";
|
||||
private static final String NAVIGATION_ICON_ID = "navigation_icon_id";
|
||||
private static final String NAVIGATION_ICON_COLOR = "navigation_icon_color";
|
||||
private static final String CENTER_X = "center_x";
|
||||
private static final String CENTER_Y = "center_y";
|
||||
private static final String SCREEN_HEIGHT = "screen_height";
|
||||
|
||||
// parameters to save
|
||||
@ColorInt
|
||||
private Integer color;
|
||||
private String width;
|
||||
|
||||
// temporally parameters to show in preview
|
||||
@ColorInt
|
||||
private int iconColor;
|
||||
private int iconId;
|
||||
private int centerX;
|
||||
private int centerY;
|
||||
private int screenHeight;
|
||||
|
||||
public RouteLineDrawInfo(@Nullable @ColorInt Integer color,
|
||||
@Nullable String width) {
|
||||
this.color = color;
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public RouteLineDrawInfo(@NonNull Bundle bundle) {
|
||||
readBundle(bundle);
|
||||
}
|
||||
|
||||
public RouteLineDrawInfo(@NonNull RouteLineDrawInfo existed) {
|
||||
this.color = existed.color;
|
||||
this.width = existed.width;
|
||||
this.iconId = existed.iconId;
|
||||
this.iconColor = existed.iconColor;
|
||||
this.centerX = existed.centerX;
|
||||
this.centerY = existed.centerY;
|
||||
this.screenHeight = existed.screenHeight;
|
||||
}
|
||||
|
||||
public void setColor(@Nullable Integer color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public void setWidth(@Nullable String width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public void setIconId(int iconId) {
|
||||
this.iconId = iconId;
|
||||
}
|
||||
|
||||
public void setIconColor(int iconColor) {
|
||||
this.iconColor = iconColor;
|
||||
}
|
||||
|
||||
public void setCenterX(int centerX) {
|
||||
this.centerX = centerX;
|
||||
}
|
||||
|
||||
public void setCenterY(int centerY) {
|
||||
this.centerY = centerY;
|
||||
}
|
||||
|
||||
public void setScreenHeight(int screenHeight) {
|
||||
this.screenHeight = screenHeight;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getIconId() {
|
||||
return iconId;
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
public int getIconColor() {
|
||||
return iconColor;
|
||||
}
|
||||
|
||||
public int getCenterX() {
|
||||
return centerX;
|
||||
}
|
||||
|
||||
public int getCenterY() {
|
||||
return centerY;
|
||||
}
|
||||
|
||||
public int getScreenHeight() {
|
||||
return screenHeight;
|
||||
}
|
||||
|
||||
private void readBundle(@NonNull Bundle bundle) {
|
||||
if (bundle.containsKey(LINE_COLOR)) {
|
||||
color = bundle.getInt(LINE_COLOR);
|
||||
}
|
||||
width = bundle.getString(LINE_WIDTH);
|
||||
iconId = bundle.getInt(NAVIGATION_ICON_ID);
|
||||
iconColor = bundle.getInt(NAVIGATION_ICON_COLOR);
|
||||
centerX = bundle.getInt(CENTER_X);
|
||||
centerY = bundle.getInt(CENTER_Y);
|
||||
screenHeight = bundle.getInt(SCREEN_HEIGHT);
|
||||
}
|
||||
|
||||
public void saveToBundle(@NonNull Bundle bundle) {
|
||||
if (color != null) {
|
||||
bundle.putInt(LINE_COLOR, color);
|
||||
}
|
||||
if (width != null) {
|
||||
bundle.putString(LINE_WIDTH, width);
|
||||
}
|
||||
bundle.putInt(NAVIGATION_ICON_ID, iconId);
|
||||
bundle.putInt(NAVIGATION_ICON_COLOR, iconColor);
|
||||
bundle.putInt(CENTER_X, centerX);
|
||||
bundle.putInt(CENTER_Y, centerY);
|
||||
bundle.putInt(SCREEN_HEIGHT, screenHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof RouteLineDrawInfo)) return false;
|
||||
|
||||
RouteLineDrawInfo that = (RouteLineDrawInfo) o;
|
||||
|
||||
if (!Algorithms.objectEquals(getColor(), that.getColor())) return false;
|
||||
return Algorithms.objectEquals(getWidth(), that.getWidth());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = color != null ? color.hashCode() : 0;
|
||||
result = 31 * result + (width != null ? width.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -55,6 +55,8 @@ public class TransportRoutingHelper {
|
|||
|
||||
private static final org.apache.commons.logging.Log log = PlatformUtil.getLog(TransportRoutingHelper.class);
|
||||
|
||||
public static final String PUBLIC_TRANSPORT_KEY = "public_transport";
|
||||
|
||||
private List<WeakReference<IRouteInformationListener>> listeners = new LinkedList<>();
|
||||
|
||||
private final OsmandApplication app;
|
||||
|
|
332
OsmAnd/src/net/osmand/plus/routing/cards/RouteLineColorCard.java
Normal file
332
OsmAnd/src/net/osmand/plus/routing/cards/RouteLineColorCard.java
Normal file
|
@ -0,0 +1,332 @@
|
|||
package net.osmand.plus.routing.cards;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.os.Build;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.helpers.ColorDialogs;
|
||||
import net.osmand.plus.helpers.enums.DayNightMode;
|
||||
import net.osmand.plus.render.RendererRegistry;
|
||||
import net.osmand.plus.routepreparationmenu.cards.BaseCard;
|
||||
import net.osmand.plus.routepreparationmenu.cards.BaseCard.CardListener;
|
||||
import net.osmand.plus.routing.RouteLineDrawInfo;
|
||||
import net.osmand.plus.settings.backend.ListStringPreference;
|
||||
import net.osmand.plus.track.AppearanceViewHolder;
|
||||
import net.osmand.plus.track.ColorsCard;
|
||||
import net.osmand.plus.track.CustomColorBottomSheet.ColorPickerListener;
|
||||
import net.osmand.plus.widgets.MultiStateToggleButton;
|
||||
import net.osmand.plus.widgets.MultiStateToggleButton.OnRadioItemClickListener;
|
||||
import net.osmand.plus.widgets.MultiStateToggleButton.RadioItem;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class RouteLineColorCard extends BaseCard implements CardListener, ColorPickerListener {
|
||||
|
||||
private static final int DAY_TITLE_ID = R.string.day;
|
||||
private static final int NIGHT_TITLE_ID = R.string.night;
|
||||
|
||||
private final Fragment targetFragment;
|
||||
|
||||
private ColorsCard colorsCard;
|
||||
private ColorTypeAdapter colorAdapter;
|
||||
private RecyclerView groupRecyclerView;
|
||||
private TextView tvColorName;
|
||||
private TextView tvDescription;
|
||||
private View themeToggleContainer;
|
||||
private ViewGroup cardsContainer;
|
||||
|
||||
private ColorMode selectedMode;
|
||||
private RouteLineDrawInfo routeLineDrawInfo;
|
||||
private DayNightMode initMapTheme;
|
||||
private DayNightMode selectedMapTheme;
|
||||
|
||||
private enum ColorMode {
|
||||
DEFAULT(R.string.map_widget_renderer, R.drawable.ic_action_map_style),
|
||||
CUSTOM(R.string.shared_string_custom, R.drawable.ic_action_settings);
|
||||
|
||||
ColorMode(int titleId, int iconId) {
|
||||
this.titleId = titleId;
|
||||
this.iconId = iconId;
|
||||
}
|
||||
|
||||
int titleId;
|
||||
int iconId;
|
||||
}
|
||||
|
||||
public RouteLineColorCard(@NonNull MapActivity mapActivity,
|
||||
@NonNull Fragment targetFragment,
|
||||
@NonNull RouteLineDrawInfo routeLineDrawInfo,
|
||||
@NonNull DayNightMode initMapTheme,
|
||||
@NonNull DayNightMode selectedMapTheme) {
|
||||
super(mapActivity);
|
||||
this.targetFragment = targetFragment;
|
||||
this.routeLineDrawInfo = routeLineDrawInfo;
|
||||
this.initMapTheme = initMapTheme;
|
||||
this.selectedMapTheme = selectedMapTheme;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCardLayoutId() {
|
||||
return R.layout.route_line_color_card;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateContent() {
|
||||
tvColorName = view.findViewById(R.id.color_name);
|
||||
tvDescription = view.findViewById(R.id.description);
|
||||
|
||||
colorAdapter = new ColorTypeAdapter();
|
||||
groupRecyclerView = view.findViewById(R.id.recycler_view);
|
||||
groupRecyclerView.setAdapter(colorAdapter);
|
||||
groupRecyclerView.setLayoutManager(new LinearLayoutManager(app, RecyclerView.HORIZONTAL, false));
|
||||
|
||||
themeToggleContainer = view.findViewById(R.id.theme_toggle_container);
|
||||
LinearLayout radioGroup = (LinearLayout) view.findViewById(R.id.custom_radio_buttons);
|
||||
setupRadioGroup(radioGroup);
|
||||
|
||||
cardsContainer = (ViewGroup) view.findViewById(R.id.colors_card_container);
|
||||
createColorSelector(cardsContainer);
|
||||
|
||||
initSelectedMode();
|
||||
}
|
||||
|
||||
private void initSelectedMode() {
|
||||
selectedMode = routeLineDrawInfo.getColor() == null ? ColorMode.DEFAULT : ColorMode.CUSTOM;
|
||||
modeChanged();
|
||||
}
|
||||
|
||||
private void modeChanged() {
|
||||
if (selectedMode == ColorMode.DEFAULT) {
|
||||
themeToggleContainer.setVisibility(View.GONE);
|
||||
cardsContainer.setVisibility(View.GONE);
|
||||
changeMapTheme(initMapTheme);
|
||||
} else {
|
||||
themeToggleContainer.setVisibility(View.VISIBLE);
|
||||
cardsContainer.setVisibility(View.VISIBLE);
|
||||
changeMapTheme(isNightMap() ? DayNightMode.NIGHT : DayNightMode.DAY);
|
||||
}
|
||||
updateSelectedColor();
|
||||
updateDescription();
|
||||
}
|
||||
|
||||
private void setupRadioGroup(LinearLayout buttonsContainer) {
|
||||
RadioItem day = createMapThemeButton(false);
|
||||
RadioItem night = createMapThemeButton(true);
|
||||
|
||||
MultiStateToggleButton radioGroup = new MultiStateToggleButton(app, buttonsContainer, nightMode);
|
||||
radioGroup.setItems(day, night);
|
||||
|
||||
radioGroup.setSelectedItem(!isNightMap() ? day : night);
|
||||
}
|
||||
|
||||
private RadioItem createMapThemeButton(final boolean isNight) {
|
||||
RadioItem item = new RadioItem(app.getString(!isNight ? DAY_TITLE_ID : NIGHT_TITLE_ID));
|
||||
item.setOnClickListener(new OnRadioItemClickListener() {
|
||||
@Override
|
||||
public boolean onRadioItemClick(RadioItem radioItem, View view) {
|
||||
selectedMapTheme = isNight ? DayNightMode.NIGHT : DayNightMode.DAY;
|
||||
changeMapTheme(selectedMapTheme);
|
||||
updateDescription();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return item;
|
||||
}
|
||||
|
||||
private void changeMapTheme(DayNightMode mapTheme) {
|
||||
if (targetFragment instanceof OnMapThemeUpdateListener) {
|
||||
((OnMapThemeUpdateListener) targetFragment).onMapThemeUpdated(mapTheme);
|
||||
}
|
||||
}
|
||||
|
||||
private void createColorSelector(ViewGroup container) {
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
List<Integer> colors = new ArrayList<>();
|
||||
for (int color : ColorDialogs.pallette) {
|
||||
colors.add(color);
|
||||
}
|
||||
Integer selectedColor = routeLineDrawInfo.getColor();
|
||||
if (selectedColor != null) {
|
||||
if (!ColorDialogs.isPaletteColor(selectedColor)) {
|
||||
colors.add(selectedColor);
|
||||
}
|
||||
} else {
|
||||
selectedColor = colors.get(0);
|
||||
}
|
||||
ListStringPreference preference = app.getSettings().CUSTOM_ROUTE_LINE_COLORS;
|
||||
colorsCard = new ColorsCard(mapActivity, selectedColor, targetFragment, colors, preference, null);
|
||||
colorsCard.setListener(this);
|
||||
container.addView(colorsCard.build(mapActivity));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onColorSelected(Integer prevColor, int newColor) {
|
||||
colorsCard.onColorSelected(prevColor, newColor);
|
||||
updateSelectedColor();
|
||||
}
|
||||
|
||||
private void updateSelectedColor() {
|
||||
Integer color = selectedMode == ColorMode.CUSTOM ? colorsCard.getSelectedColor() : null;
|
||||
routeLineDrawInfo.setColor(color);
|
||||
updateColorName();
|
||||
if (targetFragment instanceof OnSelectedColorChangeListener) {
|
||||
((OnSelectedColorChangeListener) targetFragment).onSelectedColorChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateColorName() {
|
||||
if (selectedMode == ColorMode.DEFAULT) {
|
||||
tvColorName.setText(app.getString(R.string.map_widget_renderer));
|
||||
} else if (routeLineDrawInfo.getColor() != null) {
|
||||
int colorNameId = ColorDialogs.getColorName(routeLineDrawInfo.getColor());
|
||||
tvColorName.setText(app.getString(colorNameId));
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDescription() {
|
||||
String description;
|
||||
if (selectedMode == ColorMode.DEFAULT) {
|
||||
String pattern = app.getString(R.string.route_line_use_map_style_appearance);
|
||||
String color = app.getString(R.string.shared_string_color).toLowerCase();
|
||||
description = String.format(pattern, color, app.getRendererRegistry().getSelectedRendererName());
|
||||
} else {
|
||||
String pattern = app.getString(R.string.specify_color_for_map_mode);
|
||||
String mapModeTitle = app.getString(isNightMap() ? NIGHT_TITLE_ID : DAY_TITLE_ID);
|
||||
description = String.format(pattern, mapModeTitle.toLowerCase());
|
||||
}
|
||||
tvDescription.setText(description);
|
||||
}
|
||||
|
||||
private boolean isNightMap() {
|
||||
return selectedMapTheme.isNight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCardLayoutNeeded(@NonNull BaseCard card) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCardPressed(@NonNull BaseCard card) {
|
||||
if (card instanceof ColorsCard) {
|
||||
updateSelectedColor();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCardButtonPressed(@NonNull BaseCard card, int buttonIndex) {
|
||||
|
||||
}
|
||||
|
||||
private class ColorTypeAdapter extends RecyclerView.Adapter<AppearanceViewHolder> {
|
||||
|
||||
private List<ColorMode> items = Arrays.asList(ColorMode.values());
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public AppearanceViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
LayoutInflater themedInflater = UiUtilities.getInflater(parent.getContext(), nightMode);
|
||||
View view = themedInflater.inflate(R.layout.point_editor_group_select_item, parent, false);
|
||||
view.getLayoutParams().width = app.getResources().getDimensionPixelSize(R.dimen.gpx_group_button_width);
|
||||
view.getLayoutParams().height = app.getResources().getDimensionPixelSize(R.dimen.gpx_group_button_height);
|
||||
|
||||
AppearanceViewHolder holder = new AppearanceViewHolder(view);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
AndroidUtils.setBackground(app, holder.button, nightMode, R.drawable.ripple_solid_light_6dp,
|
||||
R.drawable.ripple_solid_dark_6dp);
|
||||
}
|
||||
return holder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final AppearanceViewHolder holder, int position) {
|
||||
ColorMode item = items.get(position);
|
||||
holder.title.setText(app.getString(item.titleId));
|
||||
|
||||
updateButtonBg(holder, item);
|
||||
updateTextAndIconColor(holder, item);
|
||||
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
selectedMode = items.get(holder.getAdapterPosition());
|
||||
notifyItemRangeChanged(0, getItemCount());
|
||||
|
||||
modeChanged();
|
||||
|
||||
CardListener listener = getListener();
|
||||
if (listener != null) {
|
||||
listener.onCardPressed(RouteLineColorCard.this);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateButtonBg(AppearanceViewHolder holder, ColorMode item) {
|
||||
GradientDrawable rectContourDrawable = (GradientDrawable) AppCompatResources.getDrawable(app, R.drawable.bg_select_group_button_outline);
|
||||
if (rectContourDrawable != null) {
|
||||
if (selectedMode == item) {
|
||||
int strokeColor = ContextCompat.getColor(app, nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light);
|
||||
rectContourDrawable.setStroke(AndroidUtils.dpToPx(app, 2), strokeColor);
|
||||
} else {
|
||||
int strokeColor = ContextCompat.getColor(app, nightMode ?
|
||||
R.color.stroked_buttons_and_links_outline_dark :
|
||||
R.color.stroked_buttons_and_links_outline_light);
|
||||
rectContourDrawable.setStroke(AndroidUtils.dpToPx(app, 1), strokeColor);
|
||||
}
|
||||
holder.button.setImageDrawable(rectContourDrawable);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTextAndIconColor(AppearanceViewHolder holder, ColorMode item) {
|
||||
Context ctx = holder.itemView.getContext();
|
||||
int iconColorId;
|
||||
int textColorId;
|
||||
|
||||
if (selectedMode == item) {
|
||||
iconColorId = AndroidUtils.getColorFromAttr(ctx, R.attr.default_icon_color);
|
||||
textColorId = AndroidUtils.getColorFromAttr(ctx, android.R.attr.textColor);
|
||||
} else {
|
||||
iconColorId = AndroidUtils.getColorFromAttr(ctx, R.attr.colorPrimary);
|
||||
textColorId = iconColorId;
|
||||
}
|
||||
|
||||
holder.icon.setImageDrawable(app.getUIUtilities().getPaintedIcon(item.iconId, iconColorId));
|
||||
holder.title.setTextColor(textColorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return items.size();
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnSelectedColorChangeListener {
|
||||
void onSelectedColorChanged();
|
||||
}
|
||||
|
||||
public interface OnMapThemeUpdateListener {
|
||||
void onMapThemeUpdated(@NonNull DayNightMode mapTheme);
|
||||
}
|
||||
}
|
305
OsmAnd/src/net/osmand/plus/routing/cards/RouteLineWidthCard.java
Normal file
305
OsmAnd/src/net/osmand/plus/routing/cards/RouteLineWidthCard.java
Normal file
|
@ -0,0 +1,305 @@
|
|||
package net.osmand.plus.routing.cards;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.os.Build;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ScrollUtils;
|
||||
import com.google.android.material.slider.Slider;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.helpers.AndroidUiHelper;
|
||||
import net.osmand.plus.render.RendererRegistry;
|
||||
import net.osmand.plus.routepreparationmenu.cards.BaseCard;
|
||||
import net.osmand.plus.routing.RouteLineDrawInfo;
|
||||
import net.osmand.plus.track.AppearanceViewHolder;
|
||||
import net.osmand.plus.track.TrackAppearanceFragment.OnNeedScrollListener;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class RouteLineWidthCard extends BaseCard {
|
||||
|
||||
private final static int CUSTOM_WIDTH_MIN = 1;
|
||||
private final static int CUSTOM_WIDTH_MAX = 24;
|
||||
|
||||
private RouteLineDrawInfo routeLineDrawInfo;
|
||||
private OnNeedScrollListener onNeedScrollListener;
|
||||
|
||||
private WidthMode selectedMode;
|
||||
|
||||
private WidthAdapter widthAdapter;
|
||||
private View sliderContainer;
|
||||
private RecyclerView groupRecyclerView;
|
||||
private TextView tvModeType;
|
||||
private TextView tvDescription;
|
||||
|
||||
private enum WidthMode {
|
||||
DEFAULT(R.string.map_widget_renderer, R.drawable.ic_action_map_style, null),
|
||||
THIN(R.string.rendering_value_thin_name, R.drawable.ic_action_track_line_thin_color, "thin"),
|
||||
MEDIUM(R.string.rendering_value_medium_name, R.drawable.ic_action_track_line_medium_color, "medium"),
|
||||
THICK(R.string.rendering_value_bold_name, R.drawable.ic_action_track_line_bold_color, "bold"),
|
||||
CUSTOM(R.string.shared_string_custom, R.drawable.ic_action_settings, null);
|
||||
|
||||
WidthMode(int titleId, int iconId, String widthKey) {
|
||||
this.titleId = titleId;
|
||||
this.iconId = iconId;
|
||||
this.widthKey = widthKey;
|
||||
}
|
||||
|
||||
int titleId;
|
||||
int iconId;
|
||||
String widthKey;
|
||||
}
|
||||
|
||||
public RouteLineWidthCard(@NonNull MapActivity mapActivity,
|
||||
@NonNull RouteLineDrawInfo routeLineDrawInfo,
|
||||
@NonNull OnNeedScrollListener onNeedScrollListener) {
|
||||
super(mapActivity);
|
||||
this.routeLineDrawInfo = routeLineDrawInfo;
|
||||
this.onNeedScrollListener = onNeedScrollListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCardLayoutId() {
|
||||
return R.layout.route_line_width_card;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateContent() {
|
||||
widthAdapter = new WidthAdapter();
|
||||
groupRecyclerView = view.findViewById(R.id.recycler_view);
|
||||
groupRecyclerView.setAdapter(widthAdapter);
|
||||
groupRecyclerView.setLayoutManager(new LinearLayoutManager(app, RecyclerView.HORIZONTAL, false));
|
||||
|
||||
tvModeType = view.findViewById(R.id.width_type);
|
||||
tvDescription = view.findViewById(R.id.description);
|
||||
sliderContainer = view.findViewById(R.id.slider_container);
|
||||
AndroidUiHelper.updateVisibility(view.findViewById(R.id.top_divider), isShowDivider());
|
||||
|
||||
initSelectedMode();
|
||||
}
|
||||
|
||||
private void initSelectedMode() {
|
||||
selectedMode = findAppropriateMode(getRouteLineWidth());
|
||||
modeChanged();
|
||||
}
|
||||
|
||||
private void modeChanged() {
|
||||
updateHeader();
|
||||
updateDescription();
|
||||
updateCustomWidthSlider();
|
||||
scrollMenuToSelectedItem();
|
||||
}
|
||||
|
||||
public void updateItems() {
|
||||
if (widthAdapter != null) {
|
||||
widthAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void setRouteLineWidth(String widthKey) {
|
||||
routeLineDrawInfo.setWidth(widthKey);
|
||||
mapActivity.refreshMap();
|
||||
}
|
||||
|
||||
private String getRouteLineWidth() {
|
||||
return routeLineDrawInfo.getWidth();
|
||||
}
|
||||
|
||||
private void updateHeader() {
|
||||
tvModeType.setText(app.getString(selectedMode.titleId));
|
||||
}
|
||||
|
||||
private void updateDescription() {
|
||||
if (selectedMode == WidthMode.DEFAULT) {
|
||||
String pattern = app.getString(R.string.route_line_use_map_style_appearance);
|
||||
String width = app.getString(R.string.shared_string_color).toLowerCase();
|
||||
String description = String.format(pattern, width, app.getRendererRegistry().getSelectedRendererName());
|
||||
tvDescription.setText(description);
|
||||
tvDescription.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
tvDescription.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCustomWidthSlider() {
|
||||
if (selectedMode == WidthMode.CUSTOM) {
|
||||
Slider slider = view.findViewById(R.id.width_slider);
|
||||
final TextView tvCustomWidth = view.findViewById(R.id.width_value_tv);
|
||||
|
||||
slider.setValueTo(CUSTOM_WIDTH_MAX);
|
||||
slider.setValueFrom(CUSTOM_WIDTH_MIN);
|
||||
|
||||
((TextView) view.findViewById(R.id.width_value_min)).setText(String.valueOf(CUSTOM_WIDTH_MIN));
|
||||
((TextView) view.findViewById(R.id.width_value_max)).setText(String.valueOf(CUSTOM_WIDTH_MAX));
|
||||
|
||||
String widthKey = getRouteLineWidth();
|
||||
int width = Algorithms.parseIntSilently(widthKey, 1);
|
||||
widthKey = String.valueOf(width);
|
||||
setRouteLineWidth(widthKey);
|
||||
tvCustomWidth.setText(widthKey);
|
||||
slider.setValue(width);
|
||||
|
||||
slider.addOnChangeListener(new Slider.OnChangeListener() {
|
||||
@Override
|
||||
public void onValueChange(@NonNull Slider slider, float value, boolean fromUser) {
|
||||
if (fromUser) {
|
||||
String newWidth = String.valueOf((int) value);
|
||||
setRouteLineWidth(newWidth);
|
||||
tvCustomWidth.setText(newWidth);
|
||||
}
|
||||
}
|
||||
});
|
||||
UiUtilities.setupSlider(slider, nightMode, null, true);
|
||||
ScrollUtils.addOnGlobalLayoutListener(sliderContainer, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (sliderContainer.getVisibility() == View.VISIBLE) {
|
||||
onNeedScrollListener.onVerticalScrollNeeded(sliderContainer.getBottom());
|
||||
}
|
||||
}
|
||||
});
|
||||
AndroidUiHelper.updateVisibility(sliderContainer, true);
|
||||
} else {
|
||||
AndroidUiHelper.updateVisibility(sliderContainer, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void scrollMenuToSelectedItem() {
|
||||
int position = widthAdapter.getItemPosition(selectedMode);
|
||||
if (position != -1) {
|
||||
groupRecyclerView.scrollToPosition(position);
|
||||
}
|
||||
}
|
||||
|
||||
private static WidthMode findAppropriateMode(@Nullable String widthKey) {
|
||||
if (widthKey != null) {
|
||||
for (WidthMode mode : WidthMode.values()) {
|
||||
if (mode.widthKey != null && mode.widthKey.equals(widthKey)) {
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
return WidthMode.CUSTOM;
|
||||
}
|
||||
return WidthMode.DEFAULT;
|
||||
}
|
||||
|
||||
private class WidthAdapter extends RecyclerView.Adapter<AppearanceViewHolder> {
|
||||
|
||||
private final List<WidthMode> items = Arrays.asList(WidthMode.values());
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public AppearanceViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
LayoutInflater themedInflater = UiUtilities.getInflater(parent.getContext(), nightMode);
|
||||
View view = themedInflater.inflate(R.layout.point_editor_group_select_item, parent, false);
|
||||
view.getLayoutParams().width = app.getResources().getDimensionPixelSize(R.dimen.gpx_group_button_width);
|
||||
view.getLayoutParams().height = app.getResources().getDimensionPixelSize(R.dimen.gpx_group_button_height);
|
||||
|
||||
AppearanceViewHolder holder = new AppearanceViewHolder(view);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
AndroidUtils.setBackground(app, holder.button, nightMode, R.drawable.ripple_solid_light_6dp,
|
||||
R.drawable.ripple_solid_dark_6dp);
|
||||
}
|
||||
return holder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final AppearanceViewHolder holder, int position) {
|
||||
WidthMode item = items.get(position);
|
||||
holder.title.setText(app.getString(item.titleId));
|
||||
|
||||
updateButtonBg(holder, item);
|
||||
updateTextAndIconColor(holder, item);
|
||||
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
int prevSelectedPosition = getItemPosition(selectedMode);
|
||||
selectedMode = items.get(holder.getAdapterPosition());
|
||||
notifyItemChanged(holder.getAdapterPosition());
|
||||
notifyItemChanged(prevSelectedPosition);
|
||||
|
||||
if (selectedMode != WidthMode.CUSTOM) {
|
||||
setRouteLineWidth(selectedMode.widthKey);
|
||||
}
|
||||
modeChanged();
|
||||
|
||||
CardListener listener = getListener();
|
||||
if (listener != null) {
|
||||
listener.onCardPressed(RouteLineWidthCard.this);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateTextAndIconColor(AppearanceViewHolder holder, WidthMode item) {
|
||||
Context ctx = holder.itemView.getContext();
|
||||
int iconColor;
|
||||
int textColorId;
|
||||
|
||||
if (selectedMode == item) {
|
||||
iconColor = getIconColor(item, AndroidUtils.getColorFromAttr(ctx, R.attr.default_icon_color));
|
||||
textColorId = AndroidUtils.getColorFromAttr(ctx, android.R.attr.textColor);
|
||||
} else {
|
||||
iconColor = getIconColor(item, AndroidUtils.getColorFromAttr(ctx, R.attr.colorPrimary));
|
||||
textColorId = AndroidUtils.getColorFromAttr(ctx, R.attr.colorPrimary);
|
||||
}
|
||||
|
||||
holder.icon.setImageDrawable(app.getUIUtilities().getPaintedIcon(item.iconId, iconColor));
|
||||
holder.title.setTextColor(textColorId);
|
||||
}
|
||||
|
||||
private int getIconColor(@NonNull WidthMode mode, @ColorInt int defaultColor) {
|
||||
return mode.widthKey != null ? getRouteLineColor() : defaultColor;
|
||||
}
|
||||
|
||||
private int getRouteLineColor() {
|
||||
Integer color = routeLineDrawInfo.getColor();
|
||||
return color != null ? color :
|
||||
mapActivity.getMapLayers().getRouteLayer().getRouteLineColor(nightMode);
|
||||
}
|
||||
|
||||
private void updateButtonBg(AppearanceViewHolder holder, WidthMode item) {
|
||||
GradientDrawable rectContourDrawable = (GradientDrawable) AppCompatResources.getDrawable(app, R.drawable.bg_select_group_button_outline);
|
||||
if (rectContourDrawable != null) {
|
||||
if (selectedMode == item) {
|
||||
int strokeColor = ContextCompat.getColor(app, nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light);
|
||||
rectContourDrawable.setStroke(AndroidUtils.dpToPx(app, 2), strokeColor);
|
||||
} else {
|
||||
int strokeColor = ContextCompat.getColor(app, nightMode ?
|
||||
R.color.stroked_buttons_and_links_outline_dark
|
||||
: R.color.stroked_buttons_and_links_outline_light);
|
||||
rectContourDrawable.setStroke(AndroidUtils.dpToPx(app, 1), strokeColor);
|
||||
}
|
||||
holder.button.setImageDrawable(rectContourDrawable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return items.size();
|
||||
}
|
||||
|
||||
int getItemPosition(WidthMode widthMode) {
|
||||
return items.indexOf(widthMode);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -84,6 +84,7 @@ import java.util.StringTokenizer;
|
|||
import static net.osmand.aidlapi.OsmAndCustomizationConstants.CONFIGURE_MAP_ITEM_ID_SCHEME;
|
||||
import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_ITEM_ID_SCHEME;
|
||||
import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAP_CONTEXT_MENU_ACTIONS;
|
||||
import static net.osmand.plus.routing.TransportRoutingHelper.PUBLIC_TRANSPORT_KEY;
|
||||
|
||||
public class OsmandSettings {
|
||||
|
||||
|
@ -998,7 +999,7 @@ public class OsmandSettings {
|
|||
ROUTING_PROFILE.setModeDefaultValue(ApplicationMode.CAR, "car");
|
||||
ROUTING_PROFILE.setModeDefaultValue(ApplicationMode.BICYCLE, "bicycle");
|
||||
ROUTING_PROFILE.setModeDefaultValue(ApplicationMode.PEDESTRIAN, "pedestrian");
|
||||
ROUTING_PROFILE.setModeDefaultValue(ApplicationMode.PUBLIC_TRANSPORT, "public_transport");
|
||||
ROUTING_PROFILE.setModeDefaultValue(ApplicationMode.PUBLIC_TRANSPORT, PUBLIC_TRANSPORT_KEY);
|
||||
ROUTING_PROFILE.setModeDefaultValue(ApplicationMode.BOAT, "boat");
|
||||
ROUTING_PROFILE.setModeDefaultValue(ApplicationMode.AIRCRAFT, "STRAIGHT_LINE_MODE");
|
||||
ROUTING_PROFILE.setModeDefaultValue(ApplicationMode.SKI, "ski");
|
||||
|
@ -2690,6 +2691,9 @@ public class OsmandSettings {
|
|||
|
||||
public final CommonPreference<Float> ROUTE_RECALCULATION_DISTANCE = new FloatPreference(this, "routing_recalc_distance", 0.f).makeProfile();
|
||||
public final CommonPreference<Float> ROUTE_STRAIGHT_ANGLE = new FloatPreference(this, "routing_straight_angle", 30.f).makeProfile();
|
||||
public final ListStringPreference CUSTOM_ROUTE_LINE_COLORS = (ListStringPreference) new ListStringPreference(this, "custom_route_line_colors", null, ",").makeShared().makeGlobal();
|
||||
public final CommonPreference<Integer> ROUTE_LINE_COLOR = new IntPreference(this, "route_line_color", 0).makeProfile();
|
||||
public final CommonPreference<String> ROUTE_LINE_WIDTH = new StringPreference(this, "route_line_width", null).makeProfile();
|
||||
|
||||
public final OsmandPreference<Boolean> USE_OSM_LIVE_FOR_ROUTING = new BooleanPreference(this, "enable_osmc_routing", true).makeProfile();
|
||||
|
||||
|
|
|
@ -685,6 +685,11 @@ public abstract class BaseSettingsFragment extends PreferenceFragmentCompat impl
|
|||
ContextCompat.getColor(app, nightMode ? R.color.icon_color_active_dark : R.color.icon_color_active_light);
|
||||
}
|
||||
|
||||
@ColorRes
|
||||
protected int getActiveColorRes() {
|
||||
return isNightMode() ? R.color.active_color_primary_dark : R.color.active_color_primary_light;
|
||||
}
|
||||
|
||||
@ColorRes
|
||||
protected int getBackgroundColorRes() {
|
||||
return isNightMode() ? R.color.list_background_color_dark : R.color.list_background_color_light;
|
||||
|
|
|
@ -54,10 +54,13 @@ import net.osmand.plus.profiles.SelectProfileBottomSheet.DialogMode;
|
|||
import net.osmand.plus.profiles.SelectProfileBottomSheet.OnSelectProfileCallback;
|
||||
import net.osmand.plus.routepreparationmenu.cards.BaseCard;
|
||||
import net.osmand.plus.routepreparationmenu.cards.BaseCard.CardListener;
|
||||
import net.osmand.plus.routing.RouteLineDrawInfo;
|
||||
import net.osmand.plus.routing.RouteService;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.plus.settings.backend.CommonPreference;
|
||||
import net.osmand.plus.settings.backend.backup.ProfileSettingsItem;
|
||||
import net.osmand.plus.settings.backend.backup.SettingsHelper;
|
||||
import net.osmand.plus.settings.fragments.RouteLineAppearanceFragment.OnApplyRouteLineListener;
|
||||
import net.osmand.plus.track.ColorsCard;
|
||||
import net.osmand.plus.track.CustomColorBottomSheet.ColorPickerListener;
|
||||
import net.osmand.plus.widgets.FlowLayout;
|
||||
|
@ -74,8 +77,9 @@ import java.util.List;
|
|||
import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_SETTINGS_ID;
|
||||
import static net.osmand.plus.profiles.SelectProfileBottomSheet.PROFILES_LIST_UPDATED_ARG;
|
||||
import static net.osmand.plus.profiles.SelectProfileBottomSheet.PROFILE_KEY_ARG;
|
||||
import static net.osmand.plus.routing.TransportRoutingHelper.PUBLIC_TRANSPORT_KEY;
|
||||
|
||||
public class ProfileAppearanceFragment extends BaseSettingsFragment implements OnSelectProfileCallback, CardListener, ColorPickerListener {
|
||||
public class ProfileAppearanceFragment extends BaseSettingsFragment implements OnSelectProfileCallback, CardListener, ColorPickerListener, OnApplyRouteLineListener {
|
||||
|
||||
private static final Log LOG = PlatformUtil.getLog(ProfileAppearanceFragment.class);
|
||||
|
||||
|
@ -91,6 +95,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O
|
|||
private static final String LOCATION_ICON_ITEMS = "location_icon_items";
|
||||
private static final String SELECT_NAV_ICON = "select_nav_icon";
|
||||
private static final String NAV_ICON_ITEMS = "nav_icon_items";
|
||||
private static final String CUSTOMIZE_ROUTE_LINE = "customize_route_line";
|
||||
|
||||
private static final String PROFILE_NAME_KEY = "profile_name_key";
|
||||
private static final String PROFILE_STRINGKEY_KEY = "profile_stringkey_key";
|
||||
|
@ -159,6 +164,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O
|
|||
changedProfile.routeService = profile.routeService;
|
||||
changedProfile.locationIcon = profile.locationIcon;
|
||||
changedProfile.navigationIcon = profile.navigationIcon;
|
||||
changedProfile.routeLineDrawInfo = profile.routeLineDrawInfo;
|
||||
isNewProfile = ApplicationMode.valueOfStringKey(changedProfile.stringKey, null) == null;
|
||||
}
|
||||
requireMyActivity().getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
|
||||
|
@ -179,6 +185,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O
|
|||
profile.routeService = baseModeForNewProfile.getRouteService();
|
||||
profile.locationIcon = baseModeForNewProfile.getLocationIcon();
|
||||
profile.navigationIcon = baseModeForNewProfile.getNavigationIcon();
|
||||
profile.routeLineDrawInfo = createRouteLineDrawInfo(baseModeForNewProfile);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -239,6 +246,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O
|
|||
findPreference(SELECT_ICON).setVisible(false);
|
||||
findPreference(ICON_ITEMS).setVisible(false);
|
||||
}
|
||||
updateRouteLinePreference();
|
||||
}
|
||||
|
||||
@SuppressLint("InlinedApi")
|
||||
|
@ -318,6 +326,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O
|
|||
outState.putBoolean(IS_BASE_PROFILE_IMPORTED, isBaseProfileImported);
|
||||
outState.putSerializable(PROFILE_LOCATION_ICON_KEY, changedProfile.locationIcon);
|
||||
outState.putSerializable(PROFILE_NAVIGATION_ICON_KEY, changedProfile.navigationIcon);
|
||||
changedProfile.routeLineDrawInfo.saveToBundle(outState);
|
||||
}
|
||||
|
||||
private void restoreState(Bundle savedInstanceState) {
|
||||
|
@ -331,6 +340,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O
|
|||
isBaseProfileImported = savedInstanceState.getBoolean(IS_BASE_PROFILE_IMPORTED);
|
||||
changedProfile.locationIcon = (LocationIcon) savedInstanceState.getSerializable(PROFILE_LOCATION_ICON_KEY);
|
||||
changedProfile.navigationIcon = (NavigationIcon) savedInstanceState.getSerializable(PROFILE_NAVIGATION_ICON_KEY);
|
||||
changedProfile.routeLineDrawInfo = new RouteLineDrawInfo(savedInstanceState);
|
||||
isNewProfile = savedInstanceState.getBoolean(IS_NEW_PROFILE_KEY);
|
||||
}
|
||||
|
||||
|
@ -709,6 +719,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O
|
|||
changedProfile.routingProfile = changedProfile.parent.getRoutingProfile();
|
||||
changedProfile.routeService = changedProfile.parent.getRouteService();
|
||||
this.isBaseProfileImported = isBaseProfileImported;
|
||||
updateRouteLinePreference();
|
||||
}
|
||||
|
||||
private void setupBaseProfileView(String stringKey) {
|
||||
|
@ -716,6 +727,14 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O
|
|||
baseProfileName.setText(Algorithms.capitalizeFirstLetter(mode.toHumanString()));
|
||||
}
|
||||
|
||||
private void updateRouteLinePreference() {
|
||||
Preference preference = findPreference(CUSTOMIZE_ROUTE_LINE);
|
||||
boolean isDefaultProfile = getSelectedAppMode().equals(ApplicationMode.DEFAULT) && !isNewProfile;
|
||||
boolean isPublicTransport = PUBLIC_TRANSPORT_KEY.equals(changedProfile.routingProfile);
|
||||
preference.setVisible(!isDefaultProfile && !isPublicTransport);
|
||||
preference.setIcon(getIcon(R.drawable.ic_action_route_distance, getActiveColorRes()));
|
||||
}
|
||||
|
||||
private boolean checkProfileName() {
|
||||
if (Algorithms.isBlank(changedProfile.name)) {
|
||||
Activity activity = getActivity();
|
||||
|
@ -756,6 +775,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O
|
|||
mode.setCustomIconColor(changedProfile.customColor);
|
||||
mode.setLocationIcon(changedProfile.locationIcon);
|
||||
mode.setNavigationIcon(changedProfile.navigationIcon);
|
||||
saveRouteLineAppearance(mode, changedProfile.routeLineDrawInfo);
|
||||
|
||||
FragmentActivity activity = getActivity();
|
||||
if (activity != null) {
|
||||
|
@ -783,6 +803,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O
|
|||
if (!ApplicationMode.values(app).contains(mode)) {
|
||||
ApplicationMode.changeProfileAvailability(mode, true, app);
|
||||
}
|
||||
saveRouteLineAppearance(mode, changedProfile.routeLineDrawInfo);
|
||||
return mode;
|
||||
}
|
||||
|
||||
|
@ -967,6 +988,21 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
String prefId = preference.getKey();
|
||||
if (CUSTOMIZE_ROUTE_LINE.equals(prefId)) {
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
RouteLineDrawInfo drawInfo = changedProfile.routeLineDrawInfo;
|
||||
drawInfo.setIconId(changedProfile.navigationIcon.getIconId());
|
||||
drawInfo.setIconColor(changedProfile.getActualColor());
|
||||
RouteLineAppearanceFragment.showInstance(mapActivity, drawInfo, this);
|
||||
}
|
||||
}
|
||||
return super.onPreferenceClick(preference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCardButtonPressed(@NonNull BaseCard card, int buttonIndex) {
|
||||
}
|
||||
|
@ -977,6 +1013,29 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O
|
|||
this.onCardPressed(colorsCard);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyRouteLineAppearance(@NonNull RouteLineDrawInfo routeLineDrawInfo) {
|
||||
changedProfile.routeLineDrawInfo = routeLineDrawInfo;
|
||||
}
|
||||
|
||||
private RouteLineDrawInfo createRouteLineDrawInfo(@NonNull ApplicationMode appMode) {
|
||||
int storedValue = settings.ROUTE_LINE_COLOR.getModeValue(appMode);
|
||||
Integer color = storedValue != 0 ? storedValue : null;
|
||||
String widthKey = settings.ROUTE_LINE_WIDTH.getModeValue(appMode);
|
||||
return new RouteLineDrawInfo(color, widthKey);
|
||||
}
|
||||
|
||||
private void saveRouteLineAppearance(@NonNull ApplicationMode appMode,
|
||||
@NonNull RouteLineDrawInfo drawInfo) {
|
||||
Integer color = drawInfo.getColor();
|
||||
if (color != null) {
|
||||
settings.ROUTE_LINE_COLOR.setModeValue(appMode, color);
|
||||
} else {
|
||||
settings.ROUTE_LINE_COLOR.resetModeToDefault(appMode);
|
||||
}
|
||||
settings.ROUTE_LINE_WIDTH.setModeValue(appMode, drawInfo.getWidth());
|
||||
}
|
||||
|
||||
public static boolean showInstance(FragmentActivity activity, SettingsScreenType screenType, @Nullable String appMode, boolean imported) {
|
||||
try {
|
||||
Fragment fragment = Fragment.instantiate(activity, screenType.fragmentName);
|
||||
|
@ -1008,6 +1067,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O
|
|||
RouteService routeService;
|
||||
NavigationIcon navigationIcon;
|
||||
LocationIcon locationIcon;
|
||||
RouteLineDrawInfo routeLineDrawInfo;
|
||||
|
||||
@ColorInt
|
||||
public int getActualColor() {
|
||||
|
@ -1044,6 +1104,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O
|
|||
return false;
|
||||
if (routeService != that.routeService) return false;
|
||||
if (navigationIcon != that.navigationIcon) return false;
|
||||
if (routeLineDrawInfo != null ? !routeLineDrawInfo.equals(that.routeLineDrawInfo) : that.routeLineDrawInfo != null) return false;
|
||||
return locationIcon == that.locationIcon;
|
||||
}
|
||||
|
||||
|
@ -1059,6 +1120,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O
|
|||
result = 31 * result + (routeService != null ? routeService.hashCode() : 0);
|
||||
result = 31 * result + (navigationIcon != null ? navigationIcon.hashCode() : 0);
|
||||
result = 31 * result + (locationIcon != null ? locationIcon.hashCode() : 0);
|
||||
result = 31 * result + (routeLineDrawInfo != null ? routeLineDrawInfo.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,431 @@
|
|||
package net.osmand.plus.settings.fragments;
|
||||
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ScrollView;
|
||||
|
||||
import androidx.activity.OnBackPressedCallback;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.UiUtilities.DialogButtonType;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.base.ContextMenuScrollFragment;
|
||||
import net.osmand.plus.helpers.AndroidUiHelper;
|
||||
import net.osmand.plus.helpers.enums.DayNightMode;
|
||||
import net.osmand.plus.routing.RouteLineDrawInfo;
|
||||
import net.osmand.plus.routing.cards.RouteLineColorCard;
|
||||
import net.osmand.plus.routing.cards.RouteLineColorCard.OnMapThemeUpdateListener;
|
||||
import net.osmand.plus.routing.cards.RouteLineColorCard.OnSelectedColorChangeListener;
|
||||
import net.osmand.plus.routing.cards.RouteLineWidthCard;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.plus.track.CustomColorBottomSheet.ColorPickerListener;
|
||||
import net.osmand.plus.track.TrackAppearanceFragment.OnNeedScrollListener;
|
||||
|
||||
public class RouteLineAppearanceFragment extends ContextMenuScrollFragment implements ColorPickerListener, OnSelectedColorChangeListener, OnMapThemeUpdateListener {
|
||||
|
||||
public static final String TAG = RouteLineAppearanceFragment.class.getName();
|
||||
|
||||
private static final String INIT_MAP_THEME = "init_map_theme";
|
||||
private static final String SELECTED_MAP_THEME = "selected_map_theme";
|
||||
|
||||
private RouteLineDrawInfo routeLineDrawInfo;
|
||||
|
||||
private int toolbarHeightPx;
|
||||
private DayNightMode initMapTheme;
|
||||
private DayNightMode selectedMapTheme;
|
||||
|
||||
private View buttonsShadow;
|
||||
private View controlButtons;
|
||||
private View toolbarContainer;
|
||||
|
||||
private RouteLineColorCard colorCard;
|
||||
private RouteLineWidthCard widthCard;
|
||||
|
||||
@Override
|
||||
public int getMainLayoutId() {
|
||||
return R.layout.route_line_appearance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeaderViewHeight() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHeaderViewDetached() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getToolbarHeight() {
|
||||
return isPortrait() ? toolbarHeightPx : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getMiddleStateKoef() {
|
||||
return 0.5f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInitialMenuState() {
|
||||
return MenuState.HALF_SCREEN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSupportedMenuStatesPortrait() {
|
||||
return MenuState.HALF_SCREEN | MenuState.FULL_SCREEN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldShowMapControls(int menuState) {
|
||||
return menuState == MenuState.HALF_SCREEN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
toolbarHeightPx = getResources().getDimensionPixelSize(R.dimen.dashboard_map_toolbar);
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
routeLineDrawInfo = new RouteLineDrawInfo(savedInstanceState);
|
||||
initMapTheme = DayNightMode.valueOf(savedInstanceState.getString(INIT_MAP_THEME));
|
||||
selectedMapTheme = DayNightMode.valueOf(savedInstanceState.getString(SELECTED_MAP_THEME));
|
||||
} else {
|
||||
initMapTheme = getMyApplication().getSettings().DAYNIGHT_MODE.get();
|
||||
selectedMapTheme = initMapTheme;
|
||||
}
|
||||
|
||||
requireMapActivity().getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
|
||||
public void handleOnBackPressed() {
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View view = super.onCreateView(inflater, container, savedInstanceState);
|
||||
if (view != null) {
|
||||
toolbarContainer = view.findViewById(R.id.context_menu_toolbar_container);
|
||||
buttonsShadow = view.findViewById(R.id.buttons_shadow);
|
||||
controlButtons = view.findViewById(R.id.control_buttons);
|
||||
if (isPortrait()) {
|
||||
updateCardsLayout();
|
||||
} else {
|
||||
int widthNoShadow = getLandscapeNoShadowWidth();
|
||||
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(widthNoShadow, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
params.gravity = Gravity.BOTTOM | Gravity.START;
|
||||
controlButtons.setLayoutParams(params);
|
||||
}
|
||||
initContent(view);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
private void initContent(@NonNull View view) {
|
||||
setupCards();
|
||||
setupToolbar();
|
||||
setupButtons(view);
|
||||
setupScrollShadow();
|
||||
enterAppearanceMode();
|
||||
openMenuHalfScreen();
|
||||
calculateLayout();
|
||||
}
|
||||
|
||||
private void calculateLayout() {
|
||||
runLayoutListener(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateMapControlsPos(RouteLineAppearanceFragment.this, getViewY(), true);
|
||||
initVisibleRect();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setupCards() {
|
||||
MapActivity mapActivity = requireMapActivity();
|
||||
ViewGroup cardsContainer = getCardsContainer();
|
||||
cardsContainer.removeAllViews();
|
||||
|
||||
colorCard = new RouteLineColorCard(mapActivity, this, routeLineDrawInfo, initMapTheme, selectedMapTheme);
|
||||
cardsContainer.addView(colorCard.build(mapActivity));
|
||||
|
||||
widthCard = new RouteLineWidthCard(mapActivity, routeLineDrawInfo, createScrollListener());
|
||||
cardsContainer.addView(widthCard.build(mapActivity));
|
||||
}
|
||||
|
||||
private OnNeedScrollListener createScrollListener() {
|
||||
return new OnNeedScrollListener() {
|
||||
|
||||
@Override
|
||||
public void onVerticalScrollNeeded(int y) {
|
||||
View view = widthCard.getView();
|
||||
if (view != null) {
|
||||
int resultYPosition = view.getTop() + y;
|
||||
int dialogHeight = getInnerScrollableHeight();
|
||||
ScrollView scrollView = (ScrollView) getBottomScrollView();
|
||||
if (resultYPosition > (scrollView.getScrollY() + dialogHeight)) {
|
||||
scrollView.smoothScrollTo(0, resultYPosition - dialogHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int getInnerScrollableHeight() {
|
||||
int totalScreenHeight = getViewHeight() - getMenuStatePosY(getCurrentMenuState());
|
||||
int frameTotalHeight = controlButtons.getHeight() + buttonsShadow.getHeight();
|
||||
return totalScreenHeight - frameTotalHeight;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void setupToolbar() {
|
||||
ImageView closeButton = toolbarContainer.findViewById(R.id.close_button);
|
||||
closeButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
closeButton.setImageResource(AndroidUtils.getNavigationIconResId(toolbarContainer.getContext()));
|
||||
updateToolbarVisibility(toolbarContainer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatusBarColorId() {
|
||||
View view = getView();
|
||||
if (Build.VERSION.SDK_INT >= 23 && !isNightMode() && view != null) {
|
||||
view.setSystemUiVisibility(view.getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
||||
}
|
||||
return isNightMode() ? R.color.divider_color_dark : R.color.divider_color_light;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getToolbarAlpha(int y) {
|
||||
return isPortrait() ? 1f : 0f;
|
||||
}
|
||||
|
||||
private void setupButtons(View view) {
|
||||
View buttonsContainer = view.findViewById(R.id.buttons_container);
|
||||
buttonsContainer.setBackgroundColor(AndroidUtils.getColorFromAttr(view.getContext(), R.attr.bg_color));
|
||||
View saveButton = view.findViewById(R.id.right_bottom_button);
|
||||
saveButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (getTargetFragment() instanceof OnApplyRouteLineListener) {
|
||||
((OnApplyRouteLineListener) getTargetFragment()).applyRouteLineAppearance(routeLineDrawInfo);
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
View cancelButton = view.findViewById(R.id.dismiss_button);
|
||||
cancelButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
FragmentActivity activity = getActivity();
|
||||
if (activity != null) {
|
||||
activity.onBackPressed();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
UiUtilities.setupDialogButton(isNightMode(), cancelButton, DialogButtonType.SECONDARY, R.string.shared_string_cancel);
|
||||
UiUtilities.setupDialogButton(isNightMode(), saveButton, DialogButtonType.PRIMARY, R.string.shared_string_apply);
|
||||
|
||||
AndroidUiHelper.updateVisibility(saveButton, true);
|
||||
AndroidUiHelper.updateVisibility(view.findViewById(R.id.buttons_divider), true);
|
||||
}
|
||||
|
||||
private void setupScrollShadow() {
|
||||
final View scrollView = getBottomScrollView();
|
||||
scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
|
||||
@Override
|
||||
public void onScrollChanged() {
|
||||
boolean scrollToBottomAvailable = scrollView.canScrollVertically(1);
|
||||
if (scrollToBottomAvailable) {
|
||||
showShadowButton();
|
||||
} else {
|
||||
hideShadowButton();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void showShadowButton() {
|
||||
buttonsShadow.setVisibility(View.VISIBLE);
|
||||
buttonsShadow.animate()
|
||||
.alpha(0.8f)
|
||||
.setDuration(200)
|
||||
.setListener(null);
|
||||
}
|
||||
|
||||
private void hideShadowButton() {
|
||||
buttonsShadow.animate()
|
||||
.alpha(0f)
|
||||
.setDuration(200);
|
||||
}
|
||||
|
||||
private void initVisibleRect() {
|
||||
MapActivity ctx = getMapActivity();
|
||||
int screenHeight = AndroidUtils.getScreenHeight(ctx);
|
||||
int screenWidth = AndroidUtils.getScreenWidth(ctx);
|
||||
int statusBarHeight = AndroidUtils.getStatusBarHeight(ctx);
|
||||
int centerX;
|
||||
int centerY;
|
||||
if (isPortrait()) {
|
||||
centerX = screenWidth / 2;
|
||||
centerY = (getViewY() + toolbarContainer.getHeight() + statusBarHeight) / 2;
|
||||
} else {
|
||||
boolean isRtl = AndroidUtils.isLayoutRtl(ctx);
|
||||
int dialogWidth = getLandscapeNoShadowWidth();
|
||||
int left = isRtl ? 0 : dialogWidth;
|
||||
int right = isRtl ? screenWidth - dialogWidth : screenWidth;
|
||||
centerX = (left + right) / 2;
|
||||
centerY = (screenHeight + statusBarHeight) / 2 ;
|
||||
}
|
||||
routeLineDrawInfo.setCenterX(centerX);
|
||||
routeLineDrawInfo.setCenterY(centerY);
|
||||
routeLineDrawInfo.setScreenHeight(screenHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
setDrawInfoOnRouteLayer(routeLineDrawInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
setDrawInfoOnRouteLayer(null);
|
||||
}
|
||||
|
||||
private void setDrawInfoOnRouteLayer(@Nullable RouteLineDrawInfo drawInfo) {
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
mapActivity.getMapLayers().getRouteLayer().setRouteLineDrawInfo(drawInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putString(INIT_MAP_THEME, initMapTheme.name());
|
||||
outState.putString(SELECTED_MAP_THEME, selectedMapTheme.name());
|
||||
routeLineDrawInfo.saveToBundle(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
exitAppearanceMode();
|
||||
}
|
||||
|
||||
private void enterAppearanceMode() {
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
boolean portrait = AndroidUiHelper.isOrientationPortrait(mapActivity);
|
||||
AndroidUiHelper.setVisibility(mapActivity, portrait ? View.INVISIBLE : View.GONE,
|
||||
R.id.map_left_widgets_panel,
|
||||
R.id.map_right_widgets_panel,
|
||||
R.id.map_center_info);
|
||||
}
|
||||
}
|
||||
|
||||
private void exitAppearanceMode() {
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
AndroidUiHelper.setVisibility(mapActivity, View.VISIBLE,
|
||||
R.id.map_left_widgets_panel,
|
||||
R.id.map_right_widgets_panel,
|
||||
R.id.map_center_info,
|
||||
R.id.map_search_button);
|
||||
changeMapTheme(initMapTheme);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCardsLayout() {
|
||||
View mainView = getMainView();
|
||||
if (mainView != null) {
|
||||
LinearLayout cardsContainer = getCardsContainer();
|
||||
View topShadow = getTopShadow();
|
||||
FrameLayout bottomContainer = getBottomContainer();
|
||||
if (getCurrentMenuState() == MenuState.HEADER_ONLY) {
|
||||
topShadow.setVisibility(View.INVISIBLE);
|
||||
bottomContainer.setBackgroundDrawable(null);
|
||||
AndroidUtils.setBackground(mainView.getContext(), cardsContainer, isNightMode(), R.drawable.travel_card_bg_light, R.drawable.travel_card_bg_dark);
|
||||
} else {
|
||||
topShadow.setVisibility(View.VISIBLE);
|
||||
AndroidUtils.setBackground(mainView.getContext(), bottomContainer, isNightMode(), R.color.list_background_color_light, R.color.list_background_color_dark);
|
||||
AndroidUtils.setBackground(mainView.getContext(), cardsContainer, isNightMode(), R.color.list_background_color_light, R.color.list_background_color_dark);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onColorSelected(Integer prevColor, int newColor) {
|
||||
colorCard.onColorSelected(prevColor, newColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSelectedColorChanged() {
|
||||
if (widthCard != null) {
|
||||
widthCard.updateItems();
|
||||
}
|
||||
if (getMapActivity() != null) {
|
||||
getMapActivity().refreshMap();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean showInstance(@NonNull MapActivity mapActivity,
|
||||
@NonNull RouteLineDrawInfo drawInfo,
|
||||
@NonNull Fragment target) {
|
||||
try {
|
||||
RouteLineAppearanceFragment fragment = new RouteLineAppearanceFragment();
|
||||
fragment.setTargetFragment(target, 0);
|
||||
fragment.routeLineDrawInfo = new RouteLineDrawInfo(drawInfo);
|
||||
|
||||
mapActivity.getSupportFragmentManager()
|
||||
.beginTransaction()
|
||||
.replace(R.id.fragmentContainer, fragment, TAG)
|
||||
.addToBackStack(TAG)
|
||||
.commitAllowingStateLoss();
|
||||
return true;
|
||||
} catch (RuntimeException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapThemeUpdated(@NonNull DayNightMode mapTheme) {
|
||||
changeMapTheme(mapTheme);
|
||||
}
|
||||
|
||||
private void changeMapTheme(@NonNull DayNightMode mapTheme) {
|
||||
OsmandApplication app = getMyApplication();
|
||||
if (app != null) {
|
||||
app.getSettings().DAYNIGHT_MODE.set(mapTheme);
|
||||
selectedMapTheme = mapTheme;
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnApplyRouteLineListener {
|
||||
void applyRouteLineAppearance(@NonNull RouteLineDrawInfo routeLineDrawInfo);
|
||||
}
|
||||
}
|
|
@ -8,13 +8,13 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||
|
||||
import net.osmand.plus.R;
|
||||
|
||||
public class TrackAppearanceViewHolder extends RecyclerView.ViewHolder {
|
||||
public class AppearanceViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
final TextView title;
|
||||
final ImageView icon;
|
||||
final ImageView button;
|
||||
public final TextView title;
|
||||
public final ImageView icon;
|
||||
public final ImageView button;
|
||||
|
||||
TrackAppearanceViewHolder(View itemView) {
|
||||
public AppearanceViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
title = itemView.findViewById(R.id.groupName);
|
||||
icon = itemView.findViewById(R.id.groupIcon);
|
|
@ -6,7 +6,6 @@ import android.view.View;
|
|||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
|
@ -28,12 +27,6 @@ import org.apache.commons.logging.Log;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.ColorRes;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
public class ColorsCard extends BaseCard implements ColorPickerListener {
|
||||
|
||||
public static final int MAX_CUSTOM_COLORS = 6;
|
||||
|
@ -58,7 +51,12 @@ public class ColorsCard extends BaseCard implements ColorPickerListener {
|
|||
return R.layout.colors_card;
|
||||
}
|
||||
|
||||
public ColorsCard(MapActivity mapActivity, int selectedColor, Fragment targetFragment, List<Integer> colors, ListStringPreference colorsListPreference, ApplicationMode appMode) {
|
||||
public ColorsCard(MapActivity mapActivity,
|
||||
int selectedColor,
|
||||
Fragment targetFragment,
|
||||
List<Integer> colors,
|
||||
ListStringPreference colorsListPreference,
|
||||
ApplicationMode appMode) {
|
||||
super(mapActivity);
|
||||
this.targetFragment = targetFragment;
|
||||
this.selectedColor = selectedColor;
|
||||
|
|
|
@ -135,7 +135,7 @@ public class TrackColoringCard extends BaseCard {
|
|||
updateHeader();
|
||||
}
|
||||
|
||||
private class TrackColoringAdapter extends RecyclerView.Adapter<TrackAppearanceViewHolder> {
|
||||
private class TrackColoringAdapter extends RecyclerView.Adapter<AppearanceViewHolder> {
|
||||
|
||||
private List<TrackAppearanceItem> items;
|
||||
|
||||
|
@ -145,16 +145,16 @@ public class TrackColoringCard extends BaseCard {
|
|||
|
||||
@NonNull
|
||||
@Override
|
||||
public TrackAppearanceViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
public AppearanceViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
LayoutInflater themedInflater = UiUtilities.getInflater(parent.getContext(), nightMode);
|
||||
View view = themedInflater.inflate(R.layout.point_editor_group_select_item, parent, false);
|
||||
view.getLayoutParams().width = app.getResources().getDimensionPixelSize(R.dimen.gpx_group_button_width);
|
||||
view.getLayoutParams().height = app.getResources().getDimensionPixelSize(R.dimen.gpx_group_button_height);
|
||||
return new TrackAppearanceViewHolder(view);
|
||||
return new AppearanceViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final TrackAppearanceViewHolder holder, int position) {
|
||||
public void onBindViewHolder(@NonNull final AppearanceViewHolder holder, int position) {
|
||||
final TrackAppearanceItem item = items.get(position);
|
||||
|
||||
if (item.isActive() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
|
@ -186,7 +186,7 @@ public class TrackColoringCard extends BaseCard {
|
|||
});
|
||||
}
|
||||
|
||||
private void updateButtonBg(TrackAppearanceViewHolder holder, TrackAppearanceItem item) {
|
||||
private void updateButtonBg(AppearanceViewHolder holder, TrackAppearanceItem item) {
|
||||
GradientDrawable rectContourDrawable = (GradientDrawable) AppCompatResources.getDrawable(app, R.drawable.bg_select_group_button_outline);
|
||||
if (rectContourDrawable != null) {
|
||||
Context ctx = holder.itemView.getContext();
|
||||
|
@ -217,7 +217,7 @@ public class TrackColoringCard extends BaseCard {
|
|||
}
|
||||
}
|
||||
|
||||
private void updateTextAndIconColor(TrackAppearanceViewHolder holder, TrackAppearanceItem item) {
|
||||
private void updateTextAndIconColor(AppearanceViewHolder holder, TrackAppearanceItem item) {
|
||||
Context ctx = holder.itemView.getContext();
|
||||
boolean isSelected = item.getAttrName().equals(getSelectedAppearanceItem().getAttrName());
|
||||
int iconColorId;
|
||||
|
|
|
@ -184,7 +184,7 @@ public class TrackWidthCard extends BaseCard {
|
|||
}
|
||||
}
|
||||
|
||||
private class GpxWidthAdapter extends RecyclerView.Adapter<TrackAppearanceViewHolder> {
|
||||
private class GpxWidthAdapter extends RecyclerView.Adapter<AppearanceViewHolder> {
|
||||
|
||||
private List<AppearanceListItem> items;
|
||||
|
||||
|
@ -194,13 +194,13 @@ public class TrackWidthCard extends BaseCard {
|
|||
|
||||
@NonNull
|
||||
@Override
|
||||
public TrackAppearanceViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
public AppearanceViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
LayoutInflater themedInflater = UiUtilities.getInflater(parent.getContext(), nightMode);
|
||||
View view = themedInflater.inflate(R.layout.point_editor_group_select_item, parent, false);
|
||||
view.getLayoutParams().width = app.getResources().getDimensionPixelSize(R.dimen.gpx_group_button_width);
|
||||
view.getLayoutParams().height = app.getResources().getDimensionPixelSize(R.dimen.gpx_group_button_height);
|
||||
|
||||
TrackAppearanceViewHolder holder = new TrackAppearanceViewHolder(view);
|
||||
AppearanceViewHolder holder = new AppearanceViewHolder(view);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
AndroidUtils.setBackground(app, holder.button, nightMode, R.drawable.ripple_solid_light_6dp,
|
||||
R.drawable.ripple_solid_dark_6dp);
|
||||
|
@ -209,7 +209,7 @@ public class TrackWidthCard extends BaseCard {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final TrackAppearanceViewHolder holder, int position) {
|
||||
public void onBindViewHolder(@NonNull final AppearanceViewHolder holder, int position) {
|
||||
AppearanceListItem item = items.get(position);
|
||||
holder.title.setText(item.getLocalizedValue());
|
||||
|
||||
|
@ -238,7 +238,7 @@ public class TrackWidthCard extends BaseCard {
|
|||
});
|
||||
}
|
||||
|
||||
private void updateWidthIcon(TrackAppearanceViewHolder holder, AppearanceListItem item) {
|
||||
private void updateWidthIcon(AppearanceViewHolder holder, AppearanceListItem item) {
|
||||
int color = trackDrawInfo.getColor();
|
||||
|
||||
int iconId;
|
||||
|
@ -251,7 +251,7 @@ public class TrackWidthCard extends BaseCard {
|
|||
holder.icon.setImageDrawable(app.getUIUtilities().getPaintedIcon(iconId, color));
|
||||
}
|
||||
|
||||
private void updateButtonBg(TrackAppearanceViewHolder holder, AppearanceListItem item) {
|
||||
private void updateButtonBg(AppearanceViewHolder holder, AppearanceListItem item) {
|
||||
GradientDrawable rectContourDrawable = (GradientDrawable) AppCompatResources.getDrawable(app, R.drawable.bg_select_group_button_outline);
|
||||
if (rectContourDrawable != null) {
|
||||
if (getSelectedItem() != null && getSelectedItem().equals(item)) {
|
||||
|
|
|
@ -377,6 +377,7 @@ public abstract class OsmandMapLayer {
|
|||
public Paint paint;
|
||||
public Paint customColorPaint;
|
||||
public int customColor = 0;
|
||||
public float customWidth = 0;
|
||||
public int defaultWidth = 0;
|
||||
public int defaultColor = 0;
|
||||
public boolean isPaint2;
|
||||
|
@ -481,8 +482,13 @@ public abstract class OsmandMapLayer {
|
|||
if (isShadowPaint) {
|
||||
canvas.drawPath(path, shadowPaint);
|
||||
}
|
||||
if (customColor != 0 || customWidth != 0) {
|
||||
if (customColor != 0) {
|
||||
customColorPaint.setColor(customColor);
|
||||
}
|
||||
if (customWidth != 0) {
|
||||
customColorPaint.setStrokeWidth(customWidth);
|
||||
}
|
||||
canvas.drawPath(path, customColorPaint);
|
||||
} else {
|
||||
canvas.drawPath(path, paint);
|
||||
|
|
|
@ -872,14 +872,16 @@ public class MapControlsLayer extends OsmandMapLayer {
|
|||
boolean showBottomMenuButtons = (showRouteCalculationControls || !routeFollowingMode)
|
||||
&& !isInMovingMarkerMode() && !isInGpxDetailsMode() && !isInMeasurementToolMode()
|
||||
&& !isInPlanRouteMode() && !shouldHideTopControls && !isInChoosingRoutesMode()
|
||||
&& !isInWaypointsChoosingMode() && !isInFollowTrackMode() && !isInTrackAppearanceMode();
|
||||
&& !isInWaypointsChoosingMode() && !isInFollowTrackMode() && !isInTrackAppearanceMode()
|
||||
&& !isInRouteLineAppearanceMode();
|
||||
routePlanningBtn.updateVisibility(showBottomMenuButtons);
|
||||
menuControl.updateVisibility(showBottomMenuButtons);
|
||||
|
||||
boolean additionalDialogsHide = !isInGpxApproximationMode()
|
||||
&& !isInTrackAppearanceMode()
|
||||
&& !isInChoosingRoutesMode()
|
||||
&& !isInWaypointsChoosingMode();
|
||||
&& !isInWaypointsChoosingMode()
|
||||
&& !isInRouteLineAppearanceMode();
|
||||
boolean showZoomButtons = !routeDialogOpened && !shouldHideTopControls
|
||||
&& !isInFollowTrackMode()
|
||||
&& (additionalDialogsHide || !portrait);
|
||||
|
@ -888,7 +890,8 @@ public class MapControlsLayer extends OsmandMapLayer {
|
|||
|
||||
boolean forceHideCompass = routeDialogOpened || trackDialogOpened || isInMeasurementToolMode()
|
||||
|| isInPlanRouteMode() || shouldHideTopControls || isInChoosingRoutesMode()
|
||||
|| isInTrackAppearanceMode() || isInWaypointsChoosingMode() || isInFollowTrackMode();
|
||||
|| isInTrackAppearanceMode() || isInWaypointsChoosingMode() || isInFollowTrackMode()
|
||||
|| isInRouteLineAppearanceMode();
|
||||
compassHud.forceHideCompass = forceHideCompass;
|
||||
compassHud.updateVisibility(!forceHideCompass && shouldShowCompass());
|
||||
|
||||
|
@ -899,7 +902,8 @@ public class MapControlsLayer extends OsmandMapLayer {
|
|||
}
|
||||
boolean showTopButtons = !routeDialogOpened && !trackDialogOpened && !shouldHideTopControls
|
||||
&& !isInMeasurementToolMode() && !isInPlanRouteMode() && !isInChoosingRoutesMode()
|
||||
&& !isInTrackAppearanceMode() && !isInWaypointsChoosingMode() && !isInFollowTrackMode();
|
||||
&& !isInTrackAppearanceMode() && !isInWaypointsChoosingMode() && !isInFollowTrackMode()
|
||||
&& !isInRouteLineAppearanceMode();
|
||||
layersHud.updateVisibility(showTopButtons);
|
||||
quickSearchHud.updateVisibility(showTopButtons);
|
||||
|
||||
|
@ -1029,7 +1033,8 @@ public class MapControlsLayer extends OsmandMapLayer {
|
|||
&& !isInGpxApproximationMode()
|
||||
&& !isInChoosingRoutesMode()
|
||||
&& !isInWaypointsChoosingMode()
|
||||
&& !isInFollowTrackMode();
|
||||
&& !isInFollowTrackMode()
|
||||
&& !isInRouteLineAppearanceMode();
|
||||
backToLocationControl.updateVisibility(visible && !dialogOpened && !isInPlanRouteMode()
|
||||
&& (additionalDialogsHide || !isPotrait()));
|
||||
}
|
||||
|
@ -1397,6 +1402,10 @@ public class MapControlsLayer extends OsmandMapLayer {
|
|||
return MapRouteInfoMenu.waypointsVisible;
|
||||
}
|
||||
|
||||
private boolean isInRouteLineAppearanceMode() {
|
||||
return mapActivity.getMapLayers().getRouteLayer().isInRouteLineAppearanceMode();
|
||||
}
|
||||
|
||||
private boolean isInFollowTrackMode() {
|
||||
return MapRouteInfoMenu.followTrackVisible;
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ public class MapQuickActionLayer extends OsmandMapLayer implements QuickActionRe
|
|||
private final MapMarkersLayer mapMarkersLayer;
|
||||
private final MapControlsLayer mapControlsLayer;
|
||||
private final GPXLayer gpxLayer;
|
||||
private final RouteLayer routeLayer;
|
||||
private ImageView contextMarker;
|
||||
private final MapActivity mapActivity;
|
||||
private final OsmandApplication app;
|
||||
|
@ -90,6 +91,7 @@ public class MapQuickActionLayer extends OsmandMapLayer implements QuickActionRe
|
|||
mapMarkersLayer = mapActivity.getMapLayers().getMapMarkersLayer();
|
||||
gpxLayer = mapActivity.getMapLayers().getGpxLayer();
|
||||
mapControlsLayer = mapActivity.getMapLayers().getMapControlsLayer();
|
||||
routeLayer = mapActivity.getMapLayers().getRouteLayer();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -426,6 +428,7 @@ public class MapQuickActionLayer extends OsmandMapLayer implements QuickActionRe
|
|||
mapMarkersLayer.isInPlanRouteMode() ||
|
||||
gpxLayer.isInTrackAppearanceMode() ||
|
||||
mapControlsLayer.isInTrackMenuMode() ||
|
||||
routeLayer.isInRouteLineAppearanceMode() ||
|
||||
mapRouteInfoMenu.isVisible() ||
|
||||
MapRouteInfoMenu.chooseRoutesVisible ||
|
||||
MapRouteInfoMenu.waypointsVisible ||
|
||||
|
|
|
@ -11,17 +11,21 @@ import android.graphics.Path;
|
|||
import android.graphics.PointF;
|
||||
import android.graphics.PorterDuff.Mode;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.core.graphics.drawable.DrawableCompat;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.Location;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.data.QuadPoint;
|
||||
import net.osmand.data.QuadRect;
|
||||
import net.osmand.data.RotatedTileBox;
|
||||
import net.osmand.data.TransportStop;
|
||||
|
@ -30,8 +34,11 @@ import net.osmand.plus.activities.MapActivity;
|
|||
import net.osmand.plus.mapcontextmenu.other.TrackChartPoints;
|
||||
import net.osmand.plus.measurementtool.MeasurementToolFragment;
|
||||
import net.osmand.plus.profiles.LocationIcon;
|
||||
import net.osmand.plus.render.OsmandRenderer;
|
||||
import net.osmand.plus.render.OsmandRenderer.RenderingContext;
|
||||
import net.osmand.plus.routing.RouteCalculationResult;
|
||||
import net.osmand.plus.routing.RouteDirectionInfo;
|
||||
import net.osmand.plus.routing.RouteLineDrawInfo;
|
||||
import net.osmand.plus.routing.RouteService;
|
||||
import net.osmand.plus.routing.RoutingHelper;
|
||||
import net.osmand.plus.routing.TransportRoutingHelper;
|
||||
|
@ -41,16 +48,29 @@ import net.osmand.plus.views.layers.geometry.PublicTransportGeometryWay;
|
|||
import net.osmand.plus.views.layers.geometry.PublicTransportGeometryWayContext;
|
||||
import net.osmand.plus.views.layers.geometry.RouteGeometryWay;
|
||||
import net.osmand.plus.views.layers.geometry.RouteGeometryWayContext;
|
||||
import net.osmand.render.RenderingRuleProperty;
|
||||
import net.osmand.render.RenderingRuleSearchRequest;
|
||||
import net.osmand.render.RenderingRulesStorage;
|
||||
import net.osmand.router.TransportRouteResult;
|
||||
import net.osmand.util.Algorithms;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static net.osmand.plus.dialogs.ConfigureMapMenu.CURRENT_TRACK_WIDTH_ATTR;
|
||||
|
||||
public class RouteLayer extends OsmandMapLayer implements ContextMenuLayer.IContextMenuProvider {
|
||||
|
||||
private static final Log log = PlatformUtil.getLog(RouteLayer.class);
|
||||
|
||||
private static final int DEFAULT_WIDTH_MULTIPLIER = 7;
|
||||
|
||||
private OsmandMapTileView view;
|
||||
|
||||
private final RoutingHelper helper;
|
||||
|
@ -64,13 +84,16 @@ public class RouteLayer extends OsmandMapLayer implements ContextMenuLayer.ICont
|
|||
private Paint paintIconAction;
|
||||
private Paint paintGridOuterCircle;
|
||||
private Paint paintGridCircle;
|
||||
private Paint paintRouteLinePreview;
|
||||
|
||||
private LayerDrawable selectedPoint;
|
||||
private TrackChartPoints trackChartPoints;
|
||||
private RouteLineDrawInfo routeLineDrawInfo;
|
||||
|
||||
private RenderingLineAttributes attrs;
|
||||
private RenderingLineAttributes attrsPT;
|
||||
private RenderingLineAttributes attrsW;
|
||||
private Map<String, Float> cachedRouteLineWidth = new HashMap<>();
|
||||
private boolean nightMode;
|
||||
|
||||
private RouteGeometryWayContext routeWayContext;
|
||||
|
@ -79,6 +102,7 @@ public class RouteLayer extends OsmandMapLayer implements ContextMenuLayer.ICont
|
|||
private PublicTransportGeometryWay publicTransportRouteGeometry;
|
||||
|
||||
private LayerDrawable projectionIcon;
|
||||
private LayerDrawable previewIcon;
|
||||
|
||||
public RouteLayer(RoutingHelper helper) {
|
||||
this.helper = helper;
|
||||
|
@ -149,6 +173,8 @@ public class RouteLayer extends OsmandMapLayer implements ContextMenuLayer.ICont
|
|||
paintGridOuterCircle.setAntiAlias(true);
|
||||
paintGridOuterCircle.setColor(Color.WHITE);
|
||||
paintGridOuterCircle.setAlpha(204);
|
||||
|
||||
paintRouteLinePreview = new Paint();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -206,8 +232,8 @@ public class RouteLayer extends OsmandMapLayer implements ContextMenuLayer.ICont
|
|||
}
|
||||
|
||||
private boolean isPlanRouteGraphsAvailable() {
|
||||
if (view.getContext() instanceof MapActivity) {
|
||||
MapActivity mapActivity = (MapActivity) view.getContext();
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
MeasurementToolFragment fragment = mapActivity.getMeasurementToolFragment();
|
||||
if (fragment != null) {
|
||||
return fragment.hasVisibleGraph();
|
||||
|
@ -216,6 +242,24 @@ public class RouteLayer extends OsmandMapLayer implements ContextMenuLayer.ICont
|
|||
return false;
|
||||
}
|
||||
|
||||
public boolean isInRouteLineAppearanceMode() {
|
||||
return routeLineDrawInfo != null;
|
||||
}
|
||||
|
||||
public void setRouteLineDrawInfo(RouteLineDrawInfo drawInfo) {
|
||||
this.routeLineDrawInfo = drawInfo;
|
||||
if (drawInfo == null) {
|
||||
previewIcon = null;
|
||||
}
|
||||
}
|
||||
|
||||
private MapActivity getMapActivity() {
|
||||
if (view.getContext() instanceof MapActivity) {
|
||||
return (MapActivity) view.getContext();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void updateAttrs(DrawSettings settings, RotatedTileBox tileBox) {
|
||||
boolean updatePaints = attrs.updatePaints(view.getApplication(), settings, tileBox);
|
||||
attrs.isPaint3 = false;
|
||||
|
@ -265,7 +309,37 @@ public class RouteLayer extends OsmandMapLayer implements ContextMenuLayer.ICont
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {}
|
||||
public void onDraw(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {
|
||||
if (routeLineDrawInfo != null) {
|
||||
float angle = tileBox.getRotate();
|
||||
QuadPoint c = tileBox.getCenterPixelPoint();
|
||||
|
||||
canvas.rotate(-angle, c.x, c.y);
|
||||
drawRouteLinePreview(canvas, tileBox, routeLineDrawInfo);
|
||||
canvas.rotate(angle, c.x, c.y);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawRouteLinePreview(Canvas canvas,
|
||||
RotatedTileBox tileBox,
|
||||
RouteLineDrawInfo drawInfo) {
|
||||
paintRouteLinePreview.setColor(getRouteLineColor(nightMode));
|
||||
paintRouteLinePreview.setStrokeWidth(getRouteLineWidth(tileBox));
|
||||
|
||||
int centerX = drawInfo.getCenterX();
|
||||
int centerY = drawInfo.getCenterY();
|
||||
int screenHeight = drawInfo.getScreenHeight();
|
||||
|
||||
canvas.drawLine(centerX, 0, centerX, screenHeight, paintRouteLinePreview);
|
||||
|
||||
if (previewIcon == null) {
|
||||
previewIcon = (LayerDrawable) AppCompatResources.getDrawable(view.getContext(), drawInfo.getIconId());
|
||||
DrawableCompat.setTint(previewIcon.getDrawable(1), drawInfo.getIconColor());
|
||||
}
|
||||
canvas.rotate(-90, centerX, centerY);
|
||||
drawIcon(canvas, previewIcon, centerX, centerY);
|
||||
canvas.rotate(90, centerX, centerY);
|
||||
}
|
||||
|
||||
private void drawAction(RotatedTileBox tb, Canvas canvas, List<Location> actionPoints) {
|
||||
if (actionPoints.size() > 0) {
|
||||
|
@ -328,19 +402,76 @@ public class RouteLayer extends OsmandMapLayer implements ContextMenuLayer.ICont
|
|||
}
|
||||
int locationX = (int) projectionXY[0];
|
||||
int locationY = (int) projectionXY[1];
|
||||
drawIcon(canvas, projectionIcon, locationX, locationY);
|
||||
}
|
||||
|
||||
projectionIcon.setBounds(locationX - projectionIcon.getIntrinsicWidth() / 2,
|
||||
locationY - projectionIcon.getIntrinsicHeight() / 2,
|
||||
locationX + projectionIcon.getIntrinsicWidth() / 2,
|
||||
locationY + projectionIcon.getIntrinsicHeight() / 2);
|
||||
projectionIcon.draw(canvas);
|
||||
|
||||
private static void drawIcon(Canvas canvas, Drawable drawable, int locationX, int locationY) {
|
||||
drawable.setBounds(locationX - drawable.getIntrinsicWidth() / 2,
|
||||
locationY - drawable.getIntrinsicHeight() / 2,
|
||||
locationX + drawable.getIntrinsicWidth() / 2,
|
||||
locationY + drawable.getIntrinsicHeight() / 2);
|
||||
drawable.draw(canvas);
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
public int getRouteLineColor(boolean night) {
|
||||
Integer color;
|
||||
if (routeLineDrawInfo != null) {
|
||||
color = routeLineDrawInfo.getColor();
|
||||
} else {
|
||||
int storedValue = view.getSettings().ROUTE_LINE_COLOR.getModeValue(helper.getAppMode());
|
||||
color = storedValue != 0 ? storedValue : null;
|
||||
}
|
||||
|
||||
if (color == null) {
|
||||
updateAttrs(new DrawSettings(night), view.getCurrentRotatedTileBox());
|
||||
return attrs.paint.getColor();
|
||||
color = attrs.paint.getColor();
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
private float getRouteLineWidth(@NonNull RotatedTileBox tileBox) {
|
||||
String widthKey;
|
||||
if (routeLineDrawInfo != null) {
|
||||
widthKey = routeLineDrawInfo.getWidth();
|
||||
} else {
|
||||
widthKey = view.getSettings().ROUTE_LINE_WIDTH.getModeValue(helper.getAppMode());
|
||||
}
|
||||
return widthKey != null ? getWidthByKey(tileBox, widthKey) : attrs.paint.getStrokeWidth();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Float getWidthByKey(RotatedTileBox tileBox, String widthKey) {
|
||||
Float resultValue = cachedRouteLineWidth.get(widthKey);
|
||||
if (resultValue != null) {
|
||||
return resultValue;
|
||||
}
|
||||
if (!Algorithms.isEmpty(widthKey) && Algorithms.isInt(widthKey)) {
|
||||
try {
|
||||
int widthDp = Integer.parseInt(widthKey);
|
||||
resultValue = (float) AndroidUtils.dpToPx(view.getApplication(), widthDp);
|
||||
} catch (NumberFormatException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
resultValue = DEFAULT_WIDTH_MULTIPLIER * view.getDensity();
|
||||
}
|
||||
} else {
|
||||
RenderingRulesStorage rrs = view.getApplication().getRendererRegistry().getCurrentSelectedRenderer();
|
||||
RenderingRuleSearchRequest req = new RenderingRuleSearchRequest(rrs);
|
||||
req.setBooleanFilter(rrs.PROPS.R_NIGHT_MODE, nightMode);
|
||||
req.setIntFilter(rrs.PROPS.R_MINZOOM, tileBox.getZoom());
|
||||
req.setIntFilter(rrs.PROPS.R_MAXZOOM, tileBox.getZoom());
|
||||
RenderingRuleProperty ctWidth = rrs.PROPS.get(CURRENT_TRACK_WIDTH_ATTR);
|
||||
if (ctWidth != null) {
|
||||
req.setStringFilter(ctWidth, widthKey);
|
||||
}
|
||||
if (req.searchRenderingAttribute("gpx")) {
|
||||
RenderingContext rc = new OsmandRenderer.RenderingContext(view.getContext());
|
||||
rc.setDensityValue((float) tileBox.getMapDensity());
|
||||
resultValue = rc.getComplexValue(req, req.ALL.R_STROKE_WIDTH);
|
||||
}
|
||||
}
|
||||
cachedRouteLineWidth.put(widthKey, resultValue);
|
||||
return resultValue;
|
||||
}
|
||||
|
||||
public void drawLocations(RotatedTileBox tb, Canvas canvas, double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude) {
|
||||
|
@ -364,6 +495,7 @@ public class RouteLayer extends OsmandMapLayer implements ContextMenuLayer.ICont
|
|||
boolean straight = route.getRouteService() == RouteService.STRAIGHT;
|
||||
publicTransportRouteGeometry.clearRoute();
|
||||
routeGeometry.updateRoute(tb, route);
|
||||
routeGeometry.setRouteStyleParams(getRouteLineColor(nightMode), getRouteLineWidth(tb));
|
||||
if (directTo) {
|
||||
routeGeometry.drawSegments(tb, canvas, topLatitude, leftLongitude, bottomLatitude, rightLongitude,
|
||||
null, 0);
|
||||
|
@ -636,12 +768,12 @@ public class RouteLayer extends OsmandMapLayer implements ContextMenuLayer.ICont
|
|||
|
||||
@Override
|
||||
public boolean disableSingleTap() {
|
||||
return false;
|
||||
return isInRouteLineAppearanceMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean disableLongPressOnMap() {
|
||||
return false;
|
||||
return isInRouteLineAppearanceMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -95,6 +95,7 @@ public class GeometryWayDrawer<T extends GeometryWayContext> {
|
|||
|
||||
public void drawPath(Canvas canvas, Path path, GeometryWayStyle<?> style) {
|
||||
context.getAttrs().customColor = style.getColor();
|
||||
context.getAttrs().customWidth = style.getWidth();
|
||||
context.getAttrs().drawPath(canvas, path);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ public abstract class GeometryWayStyle<T extends GeometryWayContext> {
|
|||
|
||||
private T context;
|
||||
protected Integer color;
|
||||
protected Float width;
|
||||
|
||||
public GeometryWayStyle(T context) {
|
||||
this.context = context;
|
||||
|
@ -17,6 +18,12 @@ public abstract class GeometryWayStyle<T extends GeometryWayContext> {
|
|||
this.color = color;
|
||||
}
|
||||
|
||||
public GeometryWayStyle(T context, Integer color, Float width) {
|
||||
this.context = context;
|
||||
this.color = color;
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public T getContext() {
|
||||
return context;
|
||||
}
|
||||
|
@ -29,6 +36,10 @@ public abstract class GeometryWayStyle<T extends GeometryWayContext> {
|
|||
return color;
|
||||
}
|
||||
|
||||
public Float getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public Integer getStrokeColor() {
|
||||
return context.getStrokeColor(color);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
package net.osmand.plus.views.layers.geometry;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Paint;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import net.osmand.Location;
|
||||
import net.osmand.data.RotatedTileBox;
|
||||
|
@ -17,15 +20,26 @@ public class RouteGeometryWay extends GeometryWay<RouteGeometryWayContext, Geome
|
|||
private RoutingHelper helper;
|
||||
private RouteCalculationResult route;
|
||||
|
||||
private Integer customColor;
|
||||
private Float customWidth;
|
||||
|
||||
public RouteGeometryWay(RouteGeometryWayContext context) {
|
||||
super(context, new GeometryWayDrawer<>(context));
|
||||
this.helper = context.getApp().getRoutingHelper();
|
||||
}
|
||||
|
||||
public void setRouteStyleParams(@Nullable @ColorInt Integer color, @Nullable Float width) {
|
||||
this.customColor = color;
|
||||
this.customWidth = width;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public GeometryWayStyle<RouteGeometryWayContext> getDefaultWayStyle() {
|
||||
return new GeometrySolidWayStyle(getContext(), getContext().getAttrs().paint.getColor());
|
||||
Paint paint = getContext().getAttrs().paint;
|
||||
int color = customColor != null ? customColor : paint.getColor();
|
||||
float width = customWidth != null ? customWidth : paint.getStrokeWidth();
|
||||
return new GeometrySolidWayStyle(getContext(), color, width);
|
||||
}
|
||||
|
||||
public void updateRoute(RotatedTileBox tb, RouteCalculationResult route) {
|
||||
|
@ -50,8 +64,8 @@ public class RouteGeometryWay extends GeometryWay<RouteGeometryWayContext, Geome
|
|||
|
||||
private static class GeometrySolidWayStyle extends GeometryWayStyle<RouteGeometryWayContext> {
|
||||
|
||||
GeometrySolidWayStyle(RouteGeometryWayContext context, Integer color) {
|
||||
super(context, color);
|
||||
GeometrySolidWayStyle(RouteGeometryWayContext context, Integer color, Float width) {
|
||||
super(context, color, width);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1207,6 +1207,7 @@ public class MapInfoWidgetsFactory {
|
|||
boolean visible = settings.SHOW_COORDINATES_WIDGET.get() && !map.shouldHideTopControls()
|
||||
&& map.getMapRouteInfoMenu().shouldShowTopControls() && !map.isTopToolbarActive()
|
||||
&& !map.getMapLayers().getGpxLayer().isInTrackAppearanceMode()
|
||||
&& !map.getMapLayers().getRouteLayer().isInRouteLineAppearanceMode()
|
||||
&& !MapRouteInfoMenu.chooseRoutesVisible && !MapRouteInfoMenu.waypointsVisible
|
||||
&& !MapRouteInfoMenu.followTrackVisible;
|
||||
|
||||
|
|
|
@ -191,7 +191,8 @@ public class MapMarkersWidgetsFactory {
|
|||
|| map.isTopToolbarActive()
|
||||
|| map.shouldHideTopControls()
|
||||
|| map.getMapLayers().getGpxLayer().isInTrackAppearanceMode()
|
||||
|| map.getMapLayers().getMapMarkersLayer().isInPlanRouteMode()) {
|
||||
|| map.getMapLayers().getMapMarkersLayer().isInPlanRouteMode()
|
||||
|| map.getMapLayers().getRouteLayer().isInRouteLineAppearanceMode()) {
|
||||
updateVisibility(false);
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue