Merge pull request #9677 from osmandapp/plan_route_point_menu_trim

Plan route point menu trim
This commit is contained in:
vshcherb 2020-08-21 12:58:37 +02:00 committed by GitHub
commit aeb10fa101
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 491 additions and 167 deletions

View file

@ -33,8 +33,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
android:textAppearance="@style/TextAppearance.ListItemTitle" style="@style/TextAppearance.ListItemTitle"
tools:text="Some title"/> tools:text="Some title" />
<TextView <TextView
android:id="@+id/description" android:id="@+id/description"
@ -42,8 +42,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="2" android:maxLines="2"
android:textAppearance="@style/TextAppearance.ContextMenuSubtitle" style="@style/TextAppearance.ContextMenuSubtitle"
tools:text="Some description"/> tools:text="Some description" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>

View file

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:minHeight="@dimen/measurement_tool_up_down_row_height"
android:paddingLeft="@dimen/content_padding"
android:paddingRight="@dimen/content_padding"
android:paddingEnd="@dimen/content_padding"
android:paddingStart="@dimen/content_padding">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/icon"
android:layout_width="@dimen/standard_icon_size"
android:layout_height="@dimen/standard_icon_size"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin_large"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin_large"
tools:src="@drawable/list_destination" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
style="@style/TextAppearance.ListItemTitle"
tools:text="Some title" />
<TextView
android:id="@+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
style="@style/TextAppearance.ContextMenuSubtitle"
tools:text="Some description" />
</LinearLayout>
</LinearLayout>

View file

@ -6,6 +6,10 @@
android:orientation="vertical" android:orientation="vertical"
tools:background="?attr/bg_color"> tools:background="?attr/bg_color">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ScrollView <ScrollView
android:id="@+id/scroll_view" android:id="@+id/scroll_view"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -26,6 +30,15 @@
android:orientation="vertical" android:orientation="vertical"
android:visibility="gone" /> android:visibility="gone" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/buttons_shadow"
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_gravity="bottom"
android:visibility="gone"
android:background="@drawable/bg_contextmenu_shadow_top_light" />
</FrameLayout>
<include layout="@layout/bottom_buttons" /> <include layout="@layout/bottom_buttons" />
</LinearLayout> </LinearLayout>

View file

@ -11,6 +11,10 @@
Thx - Hardy Thx - Hardy
--> -->
<string name="plan_route_change_route_type_after">Change route type after</string>
<string name="plan_route_change_route_type_before">Change route type before</string>
<string name="plan_route_trim_after">Trim after</string>
<string name="plan_route_trim_before">Trim before</string>
<string name="access_hint_enter_address">Enter address</string> <string name="access_hint_enter_address">Enter address</string>
<string name="add_address">Add address</string> <string name="add_address">Add address</string>
<string name="delete_address">Delete address</string> <string name="delete_address">Delete address</string>

View file

@ -197,6 +197,7 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra
if (contentView.getHeight() > contentHeight) { if (contentView.getHeight() > contentHeight) {
if (useScrollableItemsContainer() || useExpandableList()) { if (useScrollableItemsContainer() || useExpandableList()) {
contentView.getLayoutParams().height = contentHeight; contentView.getLayoutParams().height = contentHeight;
mainView.findViewById(R.id.buttons_shadow).setVisibility(View.VISIBLE);
} else { } else {
contentView.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT; contentView.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
} }

View file

@ -0,0 +1,94 @@
package net.osmand.plus.base.bottomsheetmenu;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import androidx.annotation.ColorRes;
import androidx.annotation.LayoutRes;
import androidx.core.view.ViewCompat;
public class BottomSheetItemWithDescriptionDifHeight extends BottomSheetItemWithDescription {
private int minHeight;
public BottomSheetItemWithDescriptionDifHeight(View customView,
@LayoutRes int layoutId,
Object tag,
boolean disabled,
View.OnClickListener onClickListener,
int position,
Drawable icon,
Drawable background,
CharSequence title,
@ColorRes int titleColorId,
boolean iconHidden,
CharSequence description,
@ColorRes int descriptionColorId,
int descriptionMaxLines,
boolean descriptionLinksClickable,
int minHeight) {
super(customView,
layoutId,
tag,
disabled,
onClickListener,
position,
icon,
background,
title,
titleColorId,
iconHidden,
description,
descriptionColorId,
descriptionMaxLines,
descriptionLinksClickable);
this.minHeight = minHeight;
}
@Override
public void inflate(Context context, ViewGroup container, boolean nightMode) {
super.inflate(context, container, nightMode);
if (minHeight == 0) {
minHeight = ViewCompat.getMinimumHeight(view);
}
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view.getLayoutParams();
params.height = minHeight;
view.setMinimumHeight(minHeight);
}
public static class Builder extends BottomSheetItemWithDescription.Builder {
int minHeight;
public Builder setMinHeight(int minHeight) {
this.minHeight = minHeight;
return this;
}
public BottomSheetItemWithDescriptionDifHeight create() {
return new BottomSheetItemWithDescriptionDifHeight(customView,
layoutId,
tag,
disabled,
onClickListener,
position,
icon,
background,
title,
titleColorId,
iconHidden,
description,
descriptionColorId,
descriptionMaxLines,
descriptionLinksClickable,
minHeight);
}
}
}

View file

@ -293,15 +293,43 @@ public class MeasurementEditingContext {
return pt; return pt;
} }
public void trimBefore(int selectedPointPosition) {
splitSegments(selectedPointPosition);
clearBeforeSegments();
}
public void trimAfter(int selectedPointPosition) {
splitSegments(selectedPointPosition + 1);
clearAfterSegments();
}
public void clearSegments() { public void clearSegments() {
clearBeforeSegments();
clearAfterSegments();
}
public void clearBeforeSegments() {
before.points.clear(); before.points.clear();
after.points.clear(); if (beforeCacheForSnap != null) {
if (beforeCacheForSnap != null && afterCacheForSnap != null) {
beforeCacheForSnap.points.clear(); beforeCacheForSnap.points.clear();
}
}
public void clearAfterSegments() {
after.points.clear();
if (afterCacheForSnap != null) {
afterCacheForSnap.points.clear(); afterCacheForSnap.points.clear();
} }
} }
public boolean isFirstPointSelected() {
return selectedPointPosition == 0;
}
public boolean isLastPointSelected() {
return selectedPointPosition == getPoints().size() - 1;
}
public void scheduleRouteCalculateIfNotEmpty() { public void scheduleRouteCalculateIfNotEmpty() {
if (application == null || (before.points.size() == 0 && after.points.size() == 0)) { if (application == null || (before.points.size() == 0 && after.points.size() == 0)) {
return; return;

View file

@ -100,9 +100,11 @@ import static net.osmand.plus.measurementtool.SelectFileBottomSheet.Mode.ADD_TO_
import static net.osmand.plus.measurementtool.SelectFileBottomSheet.Mode.OPEN_TRACK; import static net.osmand.plus.measurementtool.SelectFileBottomSheet.Mode.OPEN_TRACK;
import static net.osmand.plus.measurementtool.SelectFileBottomSheet.SelectFileListener; import static net.osmand.plus.measurementtool.SelectFileBottomSheet.SelectFileListener;
import static net.osmand.plus.measurementtool.StartPlanRouteBottomSheet.StartPlanRouteListener; import static net.osmand.plus.measurementtool.StartPlanRouteBottomSheet.StartPlanRouteListener;
import static net.osmand.plus.measurementtool.command.ClearPointsCommand.*;
import static net.osmand.plus.measurementtool.command.ClearPointsCommand.ClearCommandMode.*;
public class MeasurementToolFragment extends BaseOsmAndFragment implements RouteBetweenPointsFragmentListener, public class MeasurementToolFragment extends BaseOsmAndFragment implements RouteBetweenPointsFragmentListener,
OptionsFragmentListener, GpxApproximationFragmentListener { OptionsFragmentListener, GpxApproximationFragmentListener, SelectedPointFragmentListener {
public static final String TAG = MeasurementToolFragment.class.getSimpleName(); public static final String TAG = MeasurementToolFragment.class.getSimpleName();
@ -194,12 +196,6 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
measurementLayer.setEditingCtx(editingCtx); measurementLayer.setEditingCtx(editingCtx);
// Handling screen rotation // Handling screen rotation
FragmentManager fragmentManager = mapActivity.getSupportFragmentManager();
Fragment selectedPointFragment = fragmentManager.findFragmentByTag(SelectedPointBottomSheetDialogFragment.TAG);
if (selectedPointFragment != null) {
SelectedPointBottomSheetDialogFragment fragment = (SelectedPointBottomSheetDialogFragment) selectedPointFragment;
fragment.setListener(createSelectedPointFragmentListener());
}
Fragment saveAsNewTrackFragment = mapActivity.getSupportFragmentManager().findFragmentByTag(SaveAsNewTrackBottomSheetDialogFragment.TAG); Fragment saveAsNewTrackFragment = mapActivity.getSupportFragmentManager().findFragmentByTag(SaveAsNewTrackBottomSheetDialogFragment.TAG);
if (saveAsNewTrackFragment != null) { if (saveAsNewTrackFragment != null) {
((SaveAsNewTrackBottomSheetDialogFragment) saveAsNewTrackFragment).setListener(createSaveAsNewTrackFragmentListener()); ((SaveAsNewTrackBottomSheetDialogFragment) saveAsNewTrackFragment).setListener(createSaveAsNewTrackFragmentListener());
@ -706,7 +702,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
@Override @Override
public void clearAllOnClick() { public void clearAllOnClick() {
MeasurementToolLayer measurementLayer = getMeasurementLayer(); MeasurementToolLayer measurementLayer = getMeasurementLayer();
editingCtx.getCommandManager().execute(new ClearPointsCommand(measurementLayer)); editingCtx.getCommandManager().execute(new ClearPointsCommand(measurementLayer, ALL));
editingCtx.cancelSnapToRoad(); editingCtx.cancelSnapToRoad();
if (pointsListOpened) { if (pointsListOpened) {
hidePointsList(); hidePointsList();
@ -722,13 +718,9 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
} }
private SelectedPointFragmentListener createSelectedPointFragmentListener() {
return new SelectedPointFragmentListener() {
final MeasurementToolLayer measurementLayer = getMeasurementLayer();
@Override @Override
public void moveOnClick() { public void onMovePoint() {
MeasurementToolLayer measurementLayer = getMeasurementLayer();
if (measurementLayer != null) { if (measurementLayer != null) {
measurementLayer.enterMovingPointMode(); measurementLayer.enterMovingPointMode();
} }
@ -736,13 +728,17 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
} }
@Override @Override
public void deleteOnClick() { public void onDeletePoint() {
MeasurementToolLayer measurementLayer = getMeasurementLayer();
if (measurementLayer != null) {
removePoint(measurementLayer, editingCtx.getSelectedPointPosition()); removePoint(measurementLayer, editingCtx.getSelectedPointPosition());
}
editingCtx.setSelectedPointPosition(-1); editingCtx.setSelectedPointPosition(-1);
} }
@Override @Override
public void addPointAfterOnClick() { public void onAddPointAfter() {
MeasurementToolLayer measurementLayer = getMeasurementLayer();
if (measurementLayer != null) { if (measurementLayer != null) {
measurementLayer.moveMapToPoint(editingCtx.getSelectedPointPosition()); measurementLayer.moveMapToPoint(editingCtx.getSelectedPointPosition());
editingCtx.setInAddPointMode(true); editingCtx.setInAddPointMode(true);
@ -754,7 +750,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
} }
@Override @Override
public void addPointBeforeOnClick() { public void onAddPointBefore() {
MeasurementToolLayer measurementLayer = getMeasurementLayer();
if (measurementLayer != null) { if (measurementLayer != null) {
measurementLayer.moveMapToPoint(editingCtx.getSelectedPointPosition()); measurementLayer.moveMapToPoint(editingCtx.getSelectedPointPosition());
editingCtx.setInAddPointMode(true); editingCtx.setInAddPointMode(true);
@ -765,6 +762,40 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
switchAddPointBeforeAfterMode(true); switchAddPointBeforeAfterMode(true);
} }
@Override
public void onTrimRouteBefore() {
trimRoute(BEFORE);
}
@Override
public void onTrimRouteAfter() {
trimRoute(AFTER);
}
private void trimRoute(ClearCommandMode before) {
MeasurementToolLayer measurementLayer = getMeasurementLayer();
editingCtx.getCommandManager().execute(new ClearPointsCommand(measurementLayer, before));
if (pointsListOpened) {
hidePointsList();
}
editingCtx.setSelectedPointPosition(-1);
editingCtx.splitSegments(editingCtx.getBeforePoints().size() + editingCtx.getAfterPoints().size());
updateUndoRedoButton(false, redoBtn);
updateUndoRedoButton(true, undoBtn);
updateDistancePointsText();
saved = false;
}
@Override
public void onChangeRouteTypeBefore() {
}
@Override
public void onChangeRouteTypeAfter() {
}
@Override @Override
public void onCloseMenu() { public void onCloseMenu() {
setDefaultMapPosition(); setDefaultMapPosition();
@ -774,8 +805,6 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
public void onClearSelection() { public void onClearSelection() {
editingCtx.setSelectedPointPosition(-1); editingCtx.setSelectedPointPosition(-1);
} }
};
}
@Override @Override
public void onCloseRouteDialog() { public void onCloseRouteDialog() {
@ -981,7 +1010,6 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
mainIcon.setImageDrawable(getActiveIcon(R.drawable.ic_action_ruler)); mainIcon.setImageDrawable(getActiveIcon(R.drawable.ic_action_ruler));
editingCtx.resetAppMode(); editingCtx.resetAppMode();
editingCtx.cancelSnapToRoad(); editingCtx.cancelSnapToRoad();
visibleSnapToRoadIcon(false);
MapActivity mapActivity = getMapActivity(); MapActivity mapActivity = getMapActivity();
if (mapActivity != null) { if (mapActivity != null) {
mainView.findViewById(R.id.snap_to_road_progress_bar).setVisibility(View.GONE); mainView.findViewById(R.id.snap_to_road_progress_bar).setVisibility(View.GONE);
@ -1005,17 +1033,6 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
} }
} }
private void visibleSnapToRoadIcon(boolean show) {
MapActivity mapActivity = getMapActivity();
if (mapActivity != null) {
if (show) {
mapActivity.findViewById(R.id.snap_to_road_image_button).setVisibility(View.VISIBLE);
} else {
mapActivity.findViewById(R.id.snap_to_road_image_button).setVisibility(View.GONE);
}
}
}
private void displayRoutePoints() { private void displayRoutePoints() {
MeasurementToolLayer measurementLayer = getMeasurementLayer(); MeasurementToolLayer measurementLayer = getMeasurementLayer();
GPXFile gpx = editingCtx.getNewGpxData().getGpxFile(); GPXFile gpx = editingCtx.getNewGpxData().getGpxFile();
@ -1037,10 +1054,9 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
} }
private void openSelectedPointMenu(MapActivity mapActivity) { private void openSelectedPointMenu(MapActivity mapActivity) {
SelectedPointBottomSheetDialogFragment fragment = new SelectedPointBottomSheetDialogFragment(); if (mapActivity != null) {
fragment.setUsedOnMap(true); SelectedPointBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager(), this);
fragment.setListener(createSelectedPointFragmentListener()); }
fragment.show(mapActivity.getSupportFragmentManager(), SelectedPointBottomSheetDialogFragment.TAG);
} }
private void openSaveAsNewTrackMenu(MapActivity mapActivity) { private void openSaveAsNewTrackMenu(MapActivity mapActivity) {

View file

@ -15,7 +15,7 @@ import net.osmand.PlatformUtil;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.base.MenuBottomSheetDialogFragment; import net.osmand.plus.base.MenuBottomSheetDialogFragment;
import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescriptionDifHeight;
import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
@ -58,11 +58,12 @@ public class OptionsBottomSheetDialogFragment extends MenuBottomSheetDialogFragm
icon = getContentIcon(R.drawable.ic_action_help); icon = getContentIcon(R.drawable.ic_action_help);
} }
BaseBottomSheetItem snapToRoadItem = new BottomSheetItemWithDescription.Builder() BaseBottomSheetItem snapToRoadItem = new BottomSheetItemWithDescriptionDifHeight.Builder()
.setMinHeight(getResources().getDimensionPixelSize(R.dimen.card_row_min_height))
.setDescription(description) .setDescription(description)
.setIcon(icon) .setIcon(icon)
.setTitle(getString(R.string.route_between_points)) .setTitle(getString(R.string.route_between_points))
.setLayoutId(R.layout.bottom_sheet_item_with_descr_56dp) .setLayoutId(R.layout.bottom_sheet_item_with_descr_pad_32dp)
.setOnClickListener(new View.OnClickListener() { .setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -118,8 +119,8 @@ public class OptionsBottomSheetDialogFragment extends MenuBottomSheetDialogFragm
items.add(new OptionsDividerItem(getContext())); items.add(new OptionsDividerItem(getContext()));
BaseBottomSheetItem clearAllItem = new SimpleBottomSheetItem.Builder() BaseBottomSheetItem clearAllItem = new SimpleBottomSheetItem.Builder()
.setIcon(getIcon(R.drawable.ic_action_reset_to_default_dark, ( .setIcon(getIcon(R.drawable.ic_action_reset_to_default_dark,
nightMode ? R.color.color_osm_edit_delete : R.color.color_osm_edit_delete))) nightMode ? R.color.color_osm_edit_delete : R.color.color_osm_edit_delete))
.setTitle(getString(R.string.shared_string_clear_all)) .setTitle(getString(R.string.shared_string_clear_all))
.setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp) .setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp)
.setOnClickListener(new View.OnClickListener() { .setOnClickListener(new View.OnClickListener() {
@ -138,7 +139,7 @@ public class OptionsBottomSheetDialogFragment extends MenuBottomSheetDialogFragm
private BaseBottomSheetItem getSaveAsNewTrackItem() { private BaseBottomSheetItem getSaveAsNewTrackItem() {
return new SimpleBottomSheetItem.Builder() return new SimpleBottomSheetItem.Builder()
.setIcon(getContentIcon(R.drawable.ic_action_save_to_file)) .setIcon(getContentIcon(R.drawable.ic_action_save_as_new_file))
.setTitle(getString(R.string.save_as_new_track)) .setTitle(getString(R.string.save_as_new_track))
.setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp) .setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp)
.setOnClickListener(new View.OnClickListener() { .setOnClickListener(new View.OnClickListener() {

View file

@ -2,45 +2,61 @@ package net.osmand.plus.measurementtool;
import android.app.Activity; import android.app.Activity;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.View; import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import net.osmand.GPXUtilities.WptPt; import net.osmand.GPXUtilities.WptPt;
import net.osmand.PlatformUtil;
import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.MenuBottomSheetDialogFragment; import net.osmand.plus.base.MenuBottomSheetDialogFragment;
import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription;
import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerHalfItem;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleDividerItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleDividerItem;
import net.osmand.plus.helpers.FontCache;
import net.osmand.plus.measurementtool.NewGpxData.ActionType; import net.osmand.plus.measurementtool.NewGpxData.ActionType;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.util.MapUtils; import net.osmand.util.MapUtils;
import org.apache.commons.logging.Log;
import java.util.List; import java.util.List;
public class SelectedPointBottomSheetDialogFragment extends MenuBottomSheetDialogFragment { public class SelectedPointBottomSheetDialogFragment extends MenuBottomSheetDialogFragment {
public final static String TAG = "SelectedPointBottomSheetDialogFragment"; public static final String TAG = SelectedPointBottomSheetDialogFragment.class.getSimpleName();
private static final Log LOG = PlatformUtil.getLog(SelectedPointBottomSheetDialogFragment.class);
private SelectedPointFragmentListener listener; private MeasurementEditingContext editingCtx;
public void setListener(SelectedPointFragmentListener listener) {
this.listener = listener;
}
@Override @Override
public void createMenuItems(Bundle savedInstanceState) { public void createMenuItems(Bundle savedInstanceState) {
MapActivity mapActivity = getMapActivity();
if (mapActivity == null) {
return;
}
editingCtx = mapActivity.getMapLayers().getMeasurementToolLayer().getEditingCtx();
View titleView = UiUtilities.getInflater(getContext(), nightMode)
.inflate(R.layout.bottom_sheet_item_with_descr_pad_32dp, null, false);
TextView title = titleView.findViewById(R.id.title);
title.setTypeface(FontCache.getRobotoMedium(getActivity()));
BaseBottomSheetItem titleItem = new BottomSheetItemWithDescription.Builder() BaseBottomSheetItem titleItem = new BottomSheetItemWithDescription.Builder()
.setDescription(getDescription()) .setDescription(getDescription(true))
.setIcon(getActiveIcon(R.drawable.ic_action_measure_point)) .setIcon(getActiveIcon(R.drawable.ic_action_measure_point))
.setTitle(getTitle()) .setTitle(getTitle())
.setLayoutId(R.layout.bottom_sheet_item_with_descr_56dp) .setCustomView(titleView)
.create(); .create();
items.add(titleItem); items.add(titleItem);
@ -49,12 +65,13 @@ public class SelectedPointBottomSheetDialogFragment extends MenuBottomSheetDialo
BaseBottomSheetItem moveItem = new SimpleBottomSheetItem.Builder() BaseBottomSheetItem moveItem = new SimpleBottomSheetItem.Builder()
.setIcon(getContentIcon(R.drawable.ic_action_move_point)) .setIcon(getContentIcon(R.drawable.ic_action_move_point))
.setTitle(getString(R.string.shared_string_move)) .setTitle(getString(R.string.shared_string_move))
.setLayoutId(R.layout.bottom_sheet_item_simple) .setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp)
.setOnClickListener(new View.OnClickListener() { .setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if (listener != null) { Fragment targetFragment = getTargetFragment();
listener.moveOnClick(); if (targetFragment instanceof SelectedPointFragmentListener) {
((SelectedPointFragmentListener) targetFragment).onMovePoint();
} }
dismiss(); dismiss();
} }
@ -62,33 +79,18 @@ public class SelectedPointBottomSheetDialogFragment extends MenuBottomSheetDialo
.create(); .create();
items.add(moveItem); items.add(moveItem);
BaseBottomSheetItem deleteItem = new SimpleBottomSheetItem.Builder() items.add(new OptionsDividerItem(getContext()));
.setIcon(getContentIcon(R.drawable.ic_action_remove_dark))
.setTitle(getString(R.string.shared_string_delete))
.setLayoutId(R.layout.bottom_sheet_item_simple)
.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) {
listener.deleteOnClick();
}
dismiss();
}
})
.create();
items.add(deleteItem);
items.add(new DividerHalfItem(getContext()));
BaseBottomSheetItem addAfterItem = new SimpleBottomSheetItem.Builder() BaseBottomSheetItem addAfterItem = new SimpleBottomSheetItem.Builder()
.setIcon(getContentIcon(R.drawable.ic_action_addpoint_above)) .setIcon(getContentIcon(R.drawable.ic_action_addpoint_above))
.setTitle(getString(R.string.add_point_after)) .setTitle(getString(R.string.add_point_after))
.setLayoutId(R.layout.bottom_sheet_item_simple) .setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp)
.setOnClickListener(new View.OnClickListener() { .setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if (listener != null) { Fragment targetFragment = getTargetFragment();
listener.addPointAfterOnClick(); if (targetFragment instanceof SelectedPointFragmentListener) {
((SelectedPointFragmentListener) targetFragment).onAddPointAfter();
} }
dismiss(); dismiss();
} }
@ -99,33 +101,96 @@ public class SelectedPointBottomSheetDialogFragment extends MenuBottomSheetDialo
BaseBottomSheetItem addBeforeItem = new SimpleBottomSheetItem.Builder() BaseBottomSheetItem addBeforeItem = new SimpleBottomSheetItem.Builder()
.setIcon(getContentIcon(R.drawable.ic_action_addpoint_below)) .setIcon(getContentIcon(R.drawable.ic_action_addpoint_below))
.setTitle(getString(R.string.add_point_before)) .setTitle(getString(R.string.add_point_before))
.setLayoutId(R.layout.bottom_sheet_item_simple) .setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp)
.setOnClickListener(new View.OnClickListener() { .setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if (listener != null) { Fragment targetFragment = getTargetFragment();
listener.addPointBeforeOnClick(); if (targetFragment instanceof SelectedPointFragmentListener) {
((SelectedPointFragmentListener) targetFragment).onAddPointBefore();
} }
dismiss(); dismiss();
} }
}) })
.create(); .create();
items.add(addBeforeItem); items.add(addBeforeItem);
items.add(new OptionsDividerItem(getContext()));
BaseBottomSheetItem trimRouteBefore = new BottomSheetItemWithDescription.Builder()
.setDescription(getDescription(true))
.setIcon(getContentIcon(R.drawable.ic_action_trim_left))
.setTitle(getString(R.string.plan_route_trim_before))
.setLayoutId(R.layout.bottom_sheet_item_with_descr_pad_32dp)
.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Fragment targetFragment = getTargetFragment();
if (targetFragment instanceof SelectedPointFragmentListener) {
((SelectedPointFragmentListener) targetFragment).onTrimRouteBefore();
}
dismiss();
}
})
.setDisabled(editingCtx.isFirstPointSelected())
.create();
items.add(trimRouteBefore);
BaseBottomSheetItem trimRouteAfter = new BottomSheetItemWithDescription.Builder()
.setDescription(getDescription(false))
.setIcon(getContentIcon(R.drawable.ic_action_trim_right))
.setTitle(getString(R.string.plan_route_trim_after))
.setLayoutId(R.layout.bottom_sheet_item_with_descr_pad_32dp)
.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Fragment targetFragment = getTargetFragment();
if (targetFragment instanceof SelectedPointFragmentListener) {
((SelectedPointFragmentListener) targetFragment).onTrimRouteAfter();
}
dismiss();
}
})
.setDisabled(editingCtx.isLastPointSelected())
.create();
items.add(trimRouteAfter);
items.add(new OptionsDividerItem(getContext()));
BaseBottomSheetItem deleteItem = new SimpleBottomSheetItem.Builder()
.setIcon(getIcon(R.drawable.ic_action_delete_dark,
nightMode ? R.color.color_osm_edit_delete : R.color.color_osm_edit_delete))
.setTitle(getString(R.string.shared_string_delete))
.setLayoutId(R.layout.bottom_sheet_item_simple_pad_32dp)
.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Fragment targetFragment = getTargetFragment();
if (targetFragment instanceof SelectedPointFragmentListener) {
((SelectedPointFragmentListener) targetFragment).onDeletePoint();
}
dismiss();
}
})
.create();
items.add(deleteItem);
} }
@Override @Override
public void dismiss() { public void dismiss() {
if (listener != null) { Fragment targetFragment = getTargetFragment();
listener.onCloseMenu(); if (targetFragment instanceof SelectedPointFragmentListener) {
((SelectedPointFragmentListener) targetFragment).onCloseMenu();
} }
super.dismiss(); super.dismiss();
} }
@Override @Override
public void onCancel(DialogInterface dialog) { public void onCancel(@NonNull DialogInterface dialog) {
if (listener != null) { Fragment targetFragment = getTargetFragment();
listener.onCloseMenu(); if (targetFragment instanceof SelectedPointFragmentListener) {
listener.onClearSelection(); ((SelectedPointFragmentListener) targetFragment).onCloseMenu();
((SelectedPointFragmentListener) targetFragment).onClearSelection();
} }
super.onCancel(dialog); super.onCancel(dialog);
} }
@ -137,8 +202,9 @@ public class SelectedPointBottomSheetDialogFragment extends MenuBottomSheetDialo
@Override @Override
protected void onDismissButtonClickAction() { protected void onDismissButtonClickAction() {
if (listener != null) { Fragment targetFragment = getTargetFragment();
listener.onClearSelection(); if (targetFragment instanceof SelectedPointFragmentListener) {
((SelectedPointFragmentListener) targetFragment).onClearSelection();
} }
} }
@ -153,56 +219,52 @@ public class SelectedPointBottomSheetDialogFragment extends MenuBottomSheetDialo
@NonNull @NonNull
private String getTitle() { private String getTitle() {
MapActivity mapActivity = getMapActivity();
if (mapActivity == null) {
return "";
}
MeasurementEditingContext editingCtx = mapActivity.getMapLayers().getMeasurementToolLayer().getEditingCtx();
int pos = editingCtx.getSelectedPointPosition(); int pos = editingCtx.getSelectedPointPosition();
String pointName = editingCtx.getPoints().get(pos).name; String pointName = editingCtx.getPoints().get(pos).name;
if (!TextUtils.isEmpty(pointName)) { if (!TextUtils.isEmpty(pointName)) {
return pointName; return pointName;
} }
NewGpxData newGpxData = editingCtx.getNewGpxData(); NewGpxData newGpxData = editingCtx.getNewGpxData();
if (newGpxData != null && newGpxData.getActionType() == ActionType.ADD_ROUTE_POINTS) { if (newGpxData != null && newGpxData.getActionType() == ActionType.ADD_ROUTE_POINTS) {
return getString(R.string.route_point) + " - " + (pos + 1); return getString(R.string.route_point) + " - " + (pos + 1);
} }
return getString(R.string.plugin_distance_point) + " - " + (pos + 1); return getString(R.string.plugin_distance_point) + " - " + (pos + 1);
} }
@NonNull @NonNull
private String getDescription() { private String getDescription(boolean before) {
MapActivity mapActivity = getMapActivity(); MapActivity mapActivity = getMapActivity();
if (mapActivity == null) { if (mapActivity == null) {
return ""; return "";
} }
StringBuilder description = new StringBuilder(); StringBuilder description = new StringBuilder();
MeasurementEditingContext editingCtx = mapActivity.getMapLayers().getMeasurementToolLayer().getEditingCtx(); MeasurementEditingContext editingCtx = mapActivity.getMapLayers().getMeasurementToolLayer().getEditingCtx();
int pos = editingCtx.getSelectedPointPosition(); int pos = editingCtx.getSelectedPointPosition();
List<WptPt> points = editingCtx.getPoints(); List<WptPt> points = editingCtx.getPoints();
WptPt pt = points.get(pos); WptPt pt = points.get(pos);
String pointDesc = pt.desc; String pointDesc = pt.desc;
if (!TextUtils.isEmpty(pointDesc)) { if (!TextUtils.isEmpty(pointDesc)) {
description.append(pointDesc); description.append(pointDesc);
} else if (pos < 1) { } else if (pos < 1 && before) {
description.append(getString(R.string.shared_string_control_start)); description.append(getString(R.string.shared_string_control_start));
} else { } else {
float dist = 0; float dist = 0;
for (int i = 1; i <= pos; i++) { int startIdx;
int endIdx;
if (before) {
startIdx = 1;
endIdx = pos;
} else {
startIdx = pos + 1;
endIdx = points.size() - 1;
}
for (int i = startIdx; i <= endIdx; i++) {
WptPt first = points.get(i - 1); WptPt first = points.get(i - 1);
WptPt second = points.get(i); WptPt second = points.get(i);
dist += MapUtils.getDistance(first.lat, first.lon, second.lat, second.lon); dist += MapUtils.getDistance(first.lat, first.lon, second.lat, second.lon);
} }
description.append(OsmAndFormatter.getFormattedDistance(dist, mapActivity.getMyApplication())); description.append(OsmAndFormatter.getFormattedDistance(dist, mapActivity.getMyApplication()));
} }
NewGpxData newGpxData = editingCtx.getNewGpxData(); NewGpxData newGpxData = editingCtx.getNewGpxData();
if (newGpxData != null && newGpxData.getActionType() == ActionType.EDIT_SEGMENT) { if (newGpxData != null && newGpxData.getActionType() == ActionType.EDIT_SEGMENT) {
double elevation = pt.ele; double elevation = pt.ele;
@ -216,19 +278,52 @@ public class SelectedPointBottomSheetDialogFragment extends MenuBottomSheetDialo
description.append(OsmAndFormatter.getFormattedSpeed(speed, mapActivity.getMyApplication())); description.append(OsmAndFormatter.getFormattedSpeed(speed, mapActivity.getMyApplication()));
} }
} }
return description.toString(); return description.toString();
} }
@Nullable
private Drawable getRouteTypeIcon(boolean before) {
Drawable icon = getContentIcon(R.drawable.ic_action_split_interval);
int pos = editingCtx.getSelectedPointPosition();
pos = before ? pos : Math.max(pos - 1, 0);
String profileType = editingCtx.getPoints().get(pos).getProfileType();
ApplicationMode routeAppMode = ApplicationMode.valueOfStringKey(profileType, null);
if (routeAppMode != null) {
icon = getIcon(routeAppMode.getIconRes(), routeAppMode.getIconColorInfo().getColor(nightMode));
}
return icon;
}
public static void showInstance(@NonNull FragmentManager fm, @Nullable Fragment targetFragment) {
try {
if (!fm.isStateSaved()) {
SelectedPointBottomSheetDialogFragment fragment = new SelectedPointBottomSheetDialogFragment();
fragment.setRetainInstance(true);
fragment.setTargetFragment(targetFragment, 0);
fragment.show(fm, TAG);
}
} catch (RuntimeException e) {
LOG.error("showInstance", e);
}
}
interface SelectedPointFragmentListener { interface SelectedPointFragmentListener {
void moveOnClick(); void onMovePoint();
void deleteOnClick(); void onDeletePoint();
void addPointAfterOnClick(); void onAddPointAfter();
void addPointBeforeOnClick(); void onAddPointBefore();
void onTrimRouteBefore();
void onTrimRouteAfter();
void onChangeRouteTypeBefore();
void onChangeRouteTypeAfter();
void onCloseMenu(); void onCloseMenu();

View file

@ -9,23 +9,48 @@ import java.util.List;
public class ClearPointsCommand extends MeasurementModeCommand { public class ClearPointsCommand extends MeasurementModeCommand {
private List<WptPt> points; private List<WptPt> points;
private boolean needUpdateCache;
ClearCommandMode clearMode;
private int pointPosition;
public ClearPointsCommand(MeasurementToolLayer measurementLayer) { public enum ClearCommandMode {
ALL,
BEFORE,
AFTER
}
public ClearPointsCommand(MeasurementToolLayer measurementLayer, ClearCommandMode clearMode) {
super(measurementLayer); super(measurementLayer);
this.clearMode = clearMode;
} }
@Override @Override
public boolean execute() { public boolean execute() {
pointPosition = getEditingCtx().getSelectedPointPosition();
executeCommand();
return true;
}
private void executeCommand() {
List<WptPt> pts = getEditingCtx().getPoints(); List<WptPt> pts = getEditingCtx().getPoints();
points = new ArrayList<>(pts); points = new ArrayList<>(pts);
switch (clearMode) {
case ALL:
pts.clear(); pts.clear();
getEditingCtx().clearSegments(); getEditingCtx().clearSegments();
break;
case BEFORE:
getEditingCtx().trimBefore(pointPosition);
break;
case AFTER:
getEditingCtx().trimAfter(pointPosition);
}
refreshMap(); refreshMap();
return true;
} }
@Override @Override
public void undo() { public void undo() {
getEditingCtx().clearSegments();
getEditingCtx().addPoints(points); getEditingCtx().addPoints(points);
getEditingCtx().updateCacheForSnap(); getEditingCtx().updateCacheForSnap();
refreshMap(); refreshMap();
@ -33,8 +58,7 @@ public class ClearPointsCommand extends MeasurementModeCommand {
@Override @Override
public void redo() { public void redo() {
getEditingCtx().clearSegments(); executeCommand();
refreshMap();
} }
@Override @Override