From 1c8fcefcc0d5966be27365c7e1ced4e523f027fc Mon Sep 17 00:00:00 2001 From: Skalii Date: Thu, 4 Feb 2021 12:13:05 +0200 Subject: [PATCH] add bottom sheet for track recording process --- .../layout/bottom_sheet_button_with_icon.xml | 59 +++++ OsmAnd/res/layout/item_gpx_stat_block.xml | 2 + .../layout/trip_recording_active_fragment.xml | 155 +++++++++++ OsmAnd/res/values/strings.xml | 1 + .../monitoring/OsmandMonitoringPlugin.java | 4 +- .../TripRecordingActiveBottomSheet.java | 244 ++++++++++++++++++ 6 files changed, 464 insertions(+), 1 deletion(-) create mode 100644 OsmAnd/res/layout/bottom_sheet_button_with_icon.xml create mode 100644 OsmAnd/res/layout/trip_recording_active_fragment.xml create mode 100644 OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java diff --git a/OsmAnd/res/layout/bottom_sheet_button_with_icon.xml b/OsmAnd/res/layout/bottom_sheet_button_with_icon.xml new file mode 100644 index 0000000000..ba24cc289c --- /dev/null +++ b/OsmAnd/res/layout/bottom_sheet_button_with_icon.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/item_gpx_stat_block.xml b/OsmAnd/res/layout/item_gpx_stat_block.xml index dd0ed2a571..f180bdb73f 100644 --- a/OsmAnd/res/layout/item_gpx_stat_block.xml +++ b/OsmAnd/res/layout/item_gpx_stat_block.xml @@ -31,6 +31,7 @@ android:layout_height="match_parent" android:layout_weight="1" android:background="@null" + android:letterSpacing="@dimen/description_letter_spacing" android:lines="1" android:textColor="?android:attr/textColorPrimary" android:textSize="@dimen/default_desc_text_size" @@ -61,6 +62,7 @@ android:layout_height="wrap_content" android:background="@null" android:ellipsize="end" + android:letterSpacing="@dimen/description_letter_spacing" android:lines="1" android:maxWidth="@dimen/grid_menu_item_width" android:textColor="?android:attr/textColorSecondary" diff --git a/OsmAnd/res/layout/trip_recording_active_fragment.xml b/OsmAnd/res/layout/trip_recording_active_fragment.xml new file mode 100644 index 0000000000..4f45d49fc9 --- /dev/null +++ b/OsmAnd/res/layout/trip_recording_active_fragment.xml @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 1d23e9db07..20294eb4e9 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -12,6 +12,7 @@ --> + On pause Hillshade / Slope / Contour lines Select edits for upload Uploaded %1$d of %2$d diff --git a/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java b/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java index 42bae2ab62..1ddb443891 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java @@ -318,7 +318,9 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { } public void controlDialog(final Activity activity, final boolean showTrackSelection) { - final boolean wasTrackMonitored = settings.SAVE_GLOBAL_TRACK_TO_GPX.get(); + FragmentActivity fragmentActivity = (FragmentActivity) activity; + TripRecordingActiveBottomSheet.showInstance(fragmentActivity.getSupportFragmentManager()); + /*final boolean wasTrackMonitored = settings.SAVE_GLOBAL_TRACK_TO_GPX.get(); final boolean nightMode; if (activity instanceof MapActivity) { nightMode = app.getDaynightHelper().isNightModeForMapControls(); diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java new file mode 100644 index 0000000000..6234d58b18 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java @@ -0,0 +1,244 @@ +package net.osmand.plus.monitoring; + +import android.app.Activity; +import android.app.Dialog; +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.ColorRes; +import androidx.annotation.DrawableRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.StringRes; +import androidx.appcompat.content.res.AppCompatResources; +import androidx.appcompat.widget.AppCompatImageView; +import androidx.appcompat.widget.SwitchCompat; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.FragmentManager; + +import net.osmand.plus.GpxSelectionHelper; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.base.MenuBottomSheetDialogFragment; +import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; +import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.track.TrackAppearanceFragment; +import net.osmand.plus.widgets.TextViewEx; +import net.osmand.util.Algorithms; + +import static net.osmand.plus.UiUtilities.CompoundButtonType.PROFILE_DEPENDENT; + +public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragment { + + public static final String TAG = TripRecordingActiveBottomSheet.class.getSimpleName(); + + private OsmandApplication app; + private OsmandSettings settings; + + @Override + public void createMenuItems(Bundle savedInstanceState) { + app = requiredMyApplication(); + settings = app.getSettings(); + Context context = requireContext(); + + LayoutInflater inflater = UiUtilities.getInflater(context, nightMode); + View itemView = inflater.inflate(R.layout.trip_recording_active_fragment, null, false); + items.add(new BottomSheetItemWithDescription.Builder() + .setCustomView(itemView) + .create()); + + TextView statusTitle = itemView.findViewById(R.id.status); + statusTitle.setText(ItemType.SEARCHING_GPS.titleId); + statusTitle.setTextColor(ContextCompat.getColor(app, getSecondaryTextColorId())); + ImageView statusIcon = itemView.findViewById(R.id.icon_status); + Drawable statusDrawable = UiUtilities.tintDrawable( + AppCompatResources.getDrawable(app, ItemType.SEARCHING_GPS.iconId), + ContextCompat.getColor(app, nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light) + ); + statusIcon.setImageDrawable(statusDrawable); + + View buttonClear = itemView.findViewById(R.id.button_clear); + View buttonStart = itemView.findViewById(R.id.button_start); + View buttonSave = itemView.findViewById(R.id.button_save); + View buttonPause = itemView.findViewById(R.id.button_pause); + View buttonStop = itemView.findViewById(R.id.button_stop); + + createButton(buttonClear, ItemType.CLEAR_DATA, true, null); + createButton(buttonStart, ItemType.START_SEGMENT, true, null); + createButton(buttonSave, ItemType.SAVE, true, "17 min. ago"); + createButton(buttonPause, ItemType.PAUSE, true, null); + createButton(buttonStop, ItemType.STOP, true, null); + + LinearLayout showTrackOnMapView = itemView.findViewById(R.id.show_track_on_map); + TextView showTrackOnMapTitle = showTrackOnMapView.findViewById(R.id.title); + showTrackOnMapTitle.setText(R.string.show_track_on_map); + + ImageView trackAppearanceIcon = showTrackOnMapView.findViewById(R.id.icon_after_divider); + + int color = settings.CURRENT_TRACK_COLOR.get(); + String width = settings.CURRENT_TRACK_WIDTH.get(); + boolean showArrows = settings.CURRENT_TRACK_SHOW_ARROWS.get(); + Drawable drawable = TrackAppearanceFragment.getTrackIcon(app, width, showArrows, color); + + trackAppearanceIcon.setImageDrawable(drawable); + trackAppearanceIcon.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + MapActivity mapActivity = getMapActivity(); + if (mapActivity != null) { + hide(); + GpxSelectionHelper.SelectedGpxFile selectedGpxFile = app.getSavingTrackHelper().getCurrentTrack(); + TrackAppearanceFragment.showInstance(mapActivity, selectedGpxFile, TripRecordingActiveBottomSheet.this); + } + } + }); + + final SwitchCompat showTrackOnMapButton = showTrackOnMapView.findViewById(R.id.switch_button); + showTrackOnMapButton.setChecked(app.getSelectedGpxHelper().getSelectedCurrentRecordingTrack() != null); + View basicItem = itemView.findViewById(R.id.basic_item_body); + basicItem.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + boolean checked = !showTrackOnMapButton.isChecked(); + showTrackOnMapButton.setChecked(checked); + app.getSelectedGpxHelper().selectGpxFile(app.getSavingTrackHelper().getCurrentGpx(), checked, false); + } + }); + UiUtilities.setupCompoundButton(showTrackOnMapButton, nightMode, PROFILE_DEPENDENT); + + } + + private void createButton(View view, ItemType type, boolean enabled, @Nullable String description) { + + Context ctx = view.getContext(); + + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) { + view.setBackground(AppCompatResources.getDrawable(ctx, nightMode ? R.drawable.dlg_btn_secondary_dark : R.drawable.dlg_btn_secondary_light)); + } else { + view.setBackgroundDrawable(AppCompatResources.getDrawable(ctx, nightMode ? R.drawable.dlg_btn_secondary_dark : R.drawable.dlg_btn_secondary_light)); + } + + TextViewEx title = view.findViewById(R.id.title); + TextViewEx desc = view.findViewById(R.id.desc); + AppCompatImageView icon = view.findViewById(R.id.icon); + + title.setText(type.getTitleId()); + title.setTextColor(ContextCompat.getColor(ctx, type == ItemType.CLEAR_DATA ? R.color.color_osm_edit_delete + : enabled ? getActiveTextColorId() : getSecondaryTextColorId())); + + Drawable tintDrawable = UiUtilities.tintDrawable( + AppCompatResources.getDrawable(ctx, type.iconId), + ContextCompat.getColor(ctx, type == ItemType.CLEAR_DATA ? R.color.color_osm_edit_delete + : enabled ? getActiveIconColorId() : getSecondaryIconColorId()) + ); + icon.setBackgroundDrawable(tintDrawable); + + boolean isShowDesc = !Algorithms.isBlank(description); + int marginSingle = app.getResources().getDimensionPixelSize(R.dimen.context_menu_padding_margin_medium); + AndroidUiHelper.updateVisibility(desc, isShowDesc); + UiUtilities.setMargins(title, 0, isShowDesc ? 0 : marginSingle, 0, isShowDesc ? 0 : marginSingle); + desc.setText(description); + } + + enum ItemType { + SEARCHING_GPS(R.string.searching_gps, R.drawable.ic_action_gps_info), + RECORDING(R.string.recording_default_name, R.drawable.ic_action_track_recordable), + ON_PAUSE(R.string.on_pause, R.drawable.ic_pause), + CLEAR_DATA(R.string.clear_recorded_data, R.drawable.ic_action_delete_dark), + START_SEGMENT(R.string.gpx_start_new_segment, R.drawable.ic_action_new_segment), + SAVE(R.string.shared_string_save, R.drawable.ic_action_save_to_file), + PAUSE(R.string.shared_string_pause, R.drawable.ic_pause), + STOP(R.string.shared_string_control_stop, R.drawable.ic_action_rec_stop); + + @StringRes + private int titleId; + @DrawableRes + private int iconId; + + ItemType(@StringRes int titleId, @DrawableRes int iconId) { + this.titleId = titleId; + this.iconId = iconId; + } + + public int getTitleId() { + return titleId; + } + + public int getIconId() { + return iconId; + } + } + + @ColorRes + protected int getActiveTextColorId() { + return nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light; + } + + @ColorRes + protected int getSecondaryTextColorId() { + return nightMode ? R.color.text_color_secondary_dark : R.color.text_color_secondary_light; + } + + @ColorRes + protected int getActiveIconColorId() { + return nightMode ? R.color.icon_color_active_dark : R.color.icon_color_active_light; + } + + @ColorRes + protected int getSecondaryIconColorId() { + return nightMode ? R.color.icon_color_secondary_dark : R.color.icon_color_secondary_light; + } + + @ColorRes + protected int getOsmandIconColorId() { + return nightMode ? R.color.icon_color_osmand_dark : R.color.icon_color_osmand_light; + } + + @Override + protected int getDismissButtonHeight() { + return getResources().getDimensionPixelSize(R.dimen.bottom_sheet_cancel_button_height); + } + + @Override + protected int getDismissButtonTextId() { + return R.string.shared_string_close; + } + + @Override + protected boolean useVerticalButtons() { + return true; + } + + @Nullable + public MapActivity getMapActivity() { + Activity activity = getActivity(); + if (activity instanceof MapActivity) { + return (MapActivity) activity; + } + return null; + } + + public void hide() { + Dialog dialog = getDialog(); + if (dialog != null) { + dialog.hide(); + } + } + + public static void showInstance(@NonNull FragmentManager fragmentManager) { + if (!fragmentManager.isStateSaved()) { + TripRecordingActiveBottomSheet fragment = new TripRecordingActiveBottomSheet(); + fragment.show(fragmentManager, TAG); + } + } +}