diff --git a/OsmAnd/res/layout/bottom_sheet_item_edit_with_recyclerview.xml b/OsmAnd/res/layout/bottom_sheet_item_edit_with_recyclerview.xml
new file mode 100644
index 0000000000..39c3cc29e7
--- /dev/null
+++ b/OsmAnd/res/layout/bottom_sheet_item_edit_with_recyclerview.xml
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OsmAnd/res/layout/bottom_sheet_item_preference_info.xml b/OsmAnd/res/layout/bottom_sheet_item_preference_info.xml
new file mode 100644
index 0000000000..528e1206c9
--- /dev/null
+++ b/OsmAnd/res/layout/bottom_sheet_item_preference_info.xml
@@ -0,0 +1,20 @@
+
+
\ No newline at end of file
diff --git a/OsmAnd/res/layout/point_editor_fragment_new.xml b/OsmAnd/res/layout/point_editor_fragment_new.xml
index f9000f7492..972d6bbb5f 100644
--- a/OsmAnd/res/layout/point_editor_fragment_new.xml
+++ b/OsmAnd/res/layout/point_editor_fragment_new.xml
@@ -75,7 +75,7 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="@string/shared_string_name"
- app:boxBackgroundColor="#4DCCCCCC">
+ app:boxBackgroundColor="@color/material_text_input_layout_bg">
+ app:boxBackgroundColor="@color/material_text_input_layout_bg">
#252727
#e68200
#232525
+ #4DCCCCCC
#0f67eb
#b87114
diff --git a/OsmAnd/res/values/sizes.xml b/OsmAnd/res/values/sizes.xml
index 8f6a9e92ab..5e22e66f86 100644
--- a/OsmAnd/res/values/sizes.xml
+++ b/OsmAnd/res/values/sizes.xml
@@ -270,6 +270,7 @@
10dp
56dp
1.25
+ 1.5
128dp
236dp
diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml
index fca05e36a0..394c037039 100644
--- a/OsmAnd/res/values/strings.xml
+++ b/OsmAnd/res/values/strings.xml
@@ -11,6 +11,8 @@
Thx - Hardy
-->
+ meters
+ tones
Default screen timeout
If the \"%1$s\" option is enabled, the activity time will depend on it.
Keep screen off
@@ -28,6 +30,9 @@
Screen control
Always
OsmAnd GPX is not well formed, please contact support team to investigate further
+ Provide your vehicle weight, some routes restrictions may be applied for heavy vehicles.
+ Provide your vehicle height, some routes restrictions may apply for high vehicles.
+ Provide your vehicle width some routes restrictions may be applied for wide vehicles.
Unsupported type
World overview map (detailed)
Could not find any such profiles.
diff --git a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/VehicleParametersNumericBottomSheet.java b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/VehicleParametersNumericBottomSheet.java
new file mode 100644
index 0000000000..79b5b53ce3
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/VehicleParametersNumericBottomSheet.java
@@ -0,0 +1,214 @@
+package net.osmand.plus.settings.bottomsheets;
+
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.content.ContextCompat;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import net.osmand.plus.OsmandApplication;
+import net.osmand.plus.R;
+import net.osmand.plus.UiUtilities;
+import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
+import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription;
+import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
+import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerSpaceItem;
+import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
+import net.osmand.plus.mapcontextmenu.editors.IconCategoriesAdapter;
+import net.osmand.plus.settings.backend.ApplicationMode;
+import net.osmand.plus.settings.fragments.ApplyQueryType;
+import net.osmand.plus.settings.fragments.OnConfirmPreferenceChange;
+import net.osmand.plus.settings.preferences.SizePreference;
+import net.osmand.router.GeneralRouter;
+import net.osmand.util.Algorithms;
+
+import java.util.Arrays;
+
+public class VehicleParametersNumericBottomSheet extends BasePreferenceBottomSheet {
+ public enum VehicleSizeAssets {
+ WIDTH(GeneralRouter.VEHICLE_WIDTH, R.drawable.img_help_width_limit_day, R.drawable.img_help_width_limit_night,
+ R.string.width_limit_description, R.string.shared_string_meters, R.string.m),
+ HEIGHT(GeneralRouter.VEHICLE_HEIGHT, R.drawable.img_help_height_limit_day, R.drawable.img_help_height_limit_night,
+ R.string.height_limit_description, R.string.shared_string_meters, R.string.m),
+ WEIGHT(GeneralRouter.VEHICLE_WEIGHT, R.drawable.img_help_weight_limit_day, R.drawable.img_help_weight_limit_night,
+ R.string.weight_limit_description, R.string.shared_string_tones, R.string.metric_ton);
+
+ String routerParameterName;
+ int dayIconId;
+ int nightIconId;
+ int descriptionRes;
+ int metricRes;
+ int metricShortRes;
+
+ VehicleSizeAssets(String routerParameterName, int dayIconId, int nightIconId, int descriptionRes, int metricRes,
+ int metricShortRes) {
+ this.routerParameterName = routerParameterName;
+ this.dayIconId = dayIconId;
+ this.nightIconId = nightIconId;
+ this.descriptionRes = descriptionRes;
+ this.metricRes = metricRes;
+ this.metricShortRes = metricShortRes;
+ }
+
+ public static VehicleSizeAssets getAssets(String parameterName) {
+ for (VehicleSizeAssets type : VehicleSizeAssets.values()) {
+ if (type.routerParameterName.equals(parameterName)) {
+ return type;
+ }
+ }
+ return null;
+ }
+
+ public int getDayIconId() {
+ return dayIconId;
+ }
+
+ public int getNightIconId() {
+ return nightIconId;
+ }
+
+ public int getDescriptionRes() {
+ return descriptionRes;
+ }
+
+ public int getMetricRes() {
+ return metricRes;
+ }
+
+ public int getMetricShortRes() {
+ return metricShortRes;
+ }
+ }
+
+ public static final String TAG = VehicleParametersNumericBottomSheet.class.getSimpleName();
+ private String selectedItem;
+ private float currentValue;
+
+ @Override
+ public void createMenuItems(Bundle savedInstanceState) {
+ OsmandApplication app = getMyApplication();
+ if (app == null) {
+ return;
+ }
+ SizePreference preference = (SizePreference) getPreference();
+
+ String key = preference.getKey();
+ String parameterName = key.substring(key.lastIndexOf("_") + 1);
+ VehicleSizeAssets vehicleSizeAssets = VehicleSizeAssets.getAssets(parameterName);
+ if (vehicleSizeAssets == null) {
+ return;
+ }
+ items.add(new TitleItem(preference.getTitle().toString()));
+ ImageView imageView = new ImageView(getContext());
+ imageView.setImageDrawable(ContextCompat.getDrawable(app,
+ !nightMode ? vehicleSizeAssets.getDayIconId() : vehicleSizeAssets.getNightIconId()));
+ items.add(new SimpleBottomSheetItem.Builder().setCustomView(imageView).create());
+ items.add(new DividerSpaceItem(app, getResources().getDimensionPixelSize(R.dimen.bottom_sheet_content_margin_small)));
+ BaseBottomSheetItem description = new BottomSheetItemWithDescription.Builder()
+ .setDescription(app.getString(vehicleSizeAssets.getDescriptionRes()))
+ .setLayoutId(R.layout.bottom_sheet_item_preference_info)
+ .create();
+ items.add(description);
+ items.add(new DividerSpaceItem(app, getResources().getDimensionPixelSize(R.dimen.bottom_sheet_content_margin_small)));
+ items.add(createComboView(app, preference));
+ }
+
+ private BaseBottomSheetItem createComboView(OsmandApplication app, final SizePreference preference) {
+ View mainView = UiUtilities.getMaterialInflater(app, nightMode)
+ .inflate(R.layout.bottom_sheet_item_edit_with_recyclerview, null);
+ final IconCategoriesAdapter adapter = new IconCategoriesAdapter(app);
+ final TextView metric = mainView.findViewById(R.id.metric);
+ metric.setText(app.getString(preference.getAssets().getMetricRes()));
+ final TextView text = mainView.findViewById(R.id.text_edit);
+ currentValue = Float.parseFloat(preference.getValue());
+ selectedItem = preference.getEntryFromValue(preference.getValue());
+ String currentValueStr = currentValue == 0.0f ? "" : String.valueOf(currentValue + 0.01f);
+ text.setText(currentValueStr);
+ text.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ if (!Algorithms.isEmpty(s)) {
+ currentValue = Float.parseFloat(s.toString()) - 0.01f;
+ } else {
+ currentValue = 0.0f;
+ }
+ selectedItem = preference.getEntryFromValue(String.valueOf(currentValue));
+ adapter.notifyDataSetChanged();
+ }
+ });
+
+ adapter.setItems(Arrays.asList(preference.getEntries()));
+ adapter.setListenerCategory(new IconCategoriesAdapter.IconCategoriesAdapterListener() {
+ @Override
+ public void onItemClick(String item) {
+ selectedItem = item;
+ currentValue = preference.getValueFromEntries(selectedItem);
+ String currentValueStr = currentValue == 0.0f ? "" : String.valueOf(currentValue + 0.01f);
+ text.setText(currentValueStr);
+ adapter.notifyDataSetChanged();
+ }
+
+ @Override
+ public String getSelectedItem() {
+ return selectedItem;
+ }
+ });
+
+ RecyclerView recyclerView = mainView.findViewById(R.id.recycler_view);
+ recyclerView.setAdapter(adapter);
+ adapter.notifyDataSetChanged();
+ return new BaseBottomSheetItem.Builder()
+ .setCustomView(mainView)
+ .create();
+ }
+
+ @Override
+ protected int getRightBottomButtonTextId() {
+ return R.string.shared_string_apply;
+ }
+
+ @Override
+ protected void onRightBottomButtonClick() {
+ Fragment target = getTargetFragment();
+ if (target instanceof OnConfirmPreferenceChange) {
+
+ ((OnConfirmPreferenceChange) target).onConfirmPreferenceChange(
+ getPreference().getKey(), String.valueOf(currentValue), ApplyQueryType.BOTTOM_SHEET);
+ }
+ dismiss();
+ }
+
+ public static boolean showInstance(@NonNull FragmentManager fragmentManager, String key, Fragment target,
+ boolean usedOnMap, @Nullable ApplicationMode appMode) {
+ try {
+ Bundle args = new Bundle();
+ args.putString(PREFERENCE_ID, key);
+
+ VehicleParametersNumericBottomSheet fragment = new VehicleParametersNumericBottomSheet();
+ fragment.setArguments(args);
+ fragment.setUsedOnMap(usedOnMap);
+ fragment.setAppMode(appMode);
+ fragment.setTargetFragment(target, 0);
+ fragment.show(fragmentManager, TAG);
+ return true;
+ } catch (RuntimeException e) {
+ return false;
+ }
+ }
+}
diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/VehicleParametersFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/VehicleParametersFragment.java
index 14ff53106b..591d7930f6 100644
--- a/OsmAnd/src/net/osmand/plus/settings/fragments/VehicleParametersFragment.java
+++ b/OsmAnd/src/net/osmand/plus/settings/fragments/VehicleParametersFragment.java
@@ -4,6 +4,7 @@ import android.content.Context;
import android.graphics.drawable.Drawable;
import android.widget.ImageView;
+import androidx.fragment.app.FragmentManager;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
@@ -14,7 +15,9 @@ import net.osmand.plus.routing.RouteProvider.RouteService;
import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmandSettings;
+import net.osmand.plus.settings.bottomsheets.VehicleParametersNumericBottomSheet;
import net.osmand.plus.settings.preferences.ListPreferenceEx;
+import net.osmand.plus.settings.preferences.SizePreference;
import net.osmand.router.GeneralRouter;
import java.util.Map;
@@ -78,17 +81,29 @@ public class VehicleParametersFragment extends BaseSettingsFragment implements O
String defValue = parameter.getType() == GeneralRouter.RoutingParameterType.NUMERIC ? ROUTING_PARAMETER_NUMERIC_DEFAULT : ROUTING_PARAMETER_SYMBOLIC_DEFAULT;
OsmandSettings.StringPreference pref = (OsmandSettings.StringPreference) app.getSettings().getCustomRoutingProperty(parameterId, defValue);
-
Object[] values = parameter.getPossibleValues();
String[] valuesStr = new String[values.length];
for (int i = 0; i < values.length; i++) {
valuesStr[i] = values[i].toString();
}
+ String[] entriesStr = parameter.getPossibleValueDescriptions().clone();
+ entriesStr[0] = app.getString(R.string.shared_string_none);
- ListPreferenceEx listPreference = createListPreferenceEx(pref.getId(), parameter.getPossibleValueDescriptions(), valuesStr, title, R.layout.preference_with_descr);
- listPreference.setDescription(description);
- listPreference.setIcon(getPreferenceIcon(parameterId));
- getPreferenceScreen().addPreference(listPreference);
+ Context ctx = getContext();
+ if (ctx == null) {
+ return;
+ }
+ SizePreference vehicleSizePref = new SizePreference(ctx);
+ vehicleSizePref.setKey(pref.getId());
+ vehicleSizePref.setAssets(VehicleParametersNumericBottomSheet.VehicleSizeAssets.getAssets(parameterId));
+ vehicleSizePref.setDefaultValue(defValue);
+ vehicleSizePref.setTitle(title);
+ vehicleSizePref.setEntries(entriesStr);
+ vehicleSizePref.setEntryValues(valuesStr);
+ vehicleSizePref.setSummary(description);
+ vehicleSizePref.setIcon(getPreferenceIcon(parameterId));
+ vehicleSizePref.setLayoutResource(R.layout.preference_with_descr);
+ getPreferenceScreen().addPreference(vehicleSizePref);
}
private void setupDefaultSpeedPref() {
@@ -130,6 +145,18 @@ public class VehicleParametersFragment extends BaseSettingsFragment implements O
return super.onPreferenceClick(preference);
}
+ @Override
+ public void onDisplayPreferenceDialog(Preference preference) {
+ if (preference instanceof SizePreference) {
+ FragmentManager fragmentManager = getFragmentManager();
+ if (fragmentManager != null) {
+ VehicleParametersNumericBottomSheet.showInstance(getFragmentManager(), preference.getKey(), this, false, getSelectedAppMode());
+ }
+ } else {
+ super.onDisplayPreferenceDialog(preference);
+ }
+ }
+
@Override
public void onPreferenceChanged(String prefId) {
recalculateRoute();
diff --git a/OsmAnd/src/net/osmand/plus/settings/preferences/SizePreference.java b/OsmAnd/src/net/osmand/plus/settings/preferences/SizePreference.java
new file mode 100644
index 0000000000..edeb8063b4
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/settings/preferences/SizePreference.java
@@ -0,0 +1,92 @@
+package net.osmand.plus.settings.preferences;
+
+import android.content.Context;
+
+import androidx.preference.DialogPreference;
+
+import net.osmand.plus.R;
+
+import static net.osmand.plus.settings.bottomsheets.VehicleParametersNumericBottomSheet.*;
+
+public class SizePreference extends DialogPreference {
+
+ private String[] entries;
+ private Object[] entryValues;
+ private String description;
+ private VehicleSizeAssets assets;
+
+ public VehicleSizeAssets getAssets() {
+ return assets;
+ }
+
+ public void setAssets(VehicleSizeAssets assets) {
+ this.assets = assets;
+ }
+
+ public void setDefaultValue(String defaultValue) {
+ this.defaultValue = defaultValue;
+ }
+
+ private String defaultValue;
+
+ public SizePreference(Context context) {
+ super(context);
+ }
+
+ public String[] getEntries() {
+ return entries;
+ }
+
+ public void setEntries(String[] entries) {
+ this.entries = entries;
+ }
+
+ public Object[] getEntryValues() {
+ return entryValues;
+ }
+
+ public void setEntryValues(Object[] entryValues) {
+ this.entryValues = entryValues;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getEntryFromValue(String value) {
+ for (int i = 0; i < entryValues.length; i++) {
+ if (entryValues[i].equals(value)) {
+ return entries[i];
+ }
+ }
+ return "";
+ }
+
+ public float getValueFromEntries(String item) {
+ String[] entries = getEntries();
+ for (int i = 0; i < entries.length; i++) {
+ if (entries[i].equals(item)) {
+ return Float.parseFloat(getEntryValues()[i].toString());
+ }
+ }
+ return 0.0f;
+ }
+
+ @Override
+ public CharSequence getSummary() {
+ String persistedString = getValue();
+ if (!persistedString.equals(defaultValue)) {
+ persistedString = String.valueOf(Float.parseFloat(persistedString) + 0.01f);
+ return String.format(getContext().getString(R.string.ltr_or_rtl_combine_via_space), persistedString, getContext().getString(assets.getMetricShortRes()));
+ }
+ return "-";
+ }
+
+ public String getValue() {
+ return getPersistedString(defaultValue);
+ }
+}