diff --git a/OsmAnd/res/layout/bottom_sheet_item_description_with_padding.xml b/OsmAnd/res/layout/bottom_sheet_item_description_with_padding.xml new file mode 100644 index 0000000000..b6516e85ff --- /dev/null +++ b/OsmAnd/res/layout/bottom_sheet_item_description_with_padding.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/global_preferences_toolbar_with_switch.xml b/OsmAnd/res/layout/global_preferences_toolbar_with_switch.xml index 8d062117ae..1b4fc65968 100644 --- a/OsmAnd/res/layout/global_preferences_toolbar_with_switch.xml +++ b/OsmAnd/res/layout/global_preferences_toolbar_with_switch.xml @@ -34,8 +34,9 @@ + + diff --git a/OsmAnd/res/layout/preference_button.xml b/OsmAnd/res/layout/preference_button.xml index 66d59b377b..5d5deb7500 100644 --- a/OsmAnd/res/layout/preference_button.xml +++ b/OsmAnd/res/layout/preference_button.xml @@ -28,25 +28,37 @@ + android:layout_marginLeft="@dimen/content_padding" + android:layout_marginStart="@dimen/content_padding" + android:orientation="vertical"> - + + + android:layout_height="1dp" + android:visibility="gone" + android:background="?attr/dashboard_divider" /> diff --git a/OsmAnd/res/layout/quick_action_list.xml b/OsmAnd/res/layout/quick_action_list.xml index 7c6f0b8c12..02c9e637ac 100644 --- a/OsmAnd/res/layout/quick_action_list.xml +++ b/OsmAnd/res/layout/quick_action_list.xml @@ -1,6 +1,5 @@ - - + - - - - - - - - - - - - - - - - + android:layout_height="match_parent" + android:layout_below="@id/appbar" + android:clipToPadding="false" /> + app:srcCompat="@drawable/ic_action_plus" /> + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/quick_action_list_header.xml b/OsmAnd/res/layout/quick_action_list_header.xml index 16bdd6c486..37bf925e37 100644 --- a/OsmAnd/res/layout/quick_action_list_header.xml +++ b/OsmAnd/res/layout/quick_action_list_header.xml @@ -1,21 +1,23 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="@dimen/bottom_sheet_list_item_height" + android:background="?attr/bg_color" + android:paddingStart="@dimen/content_padding" + android:paddingLeft="@dimen/content_padding" + android:paddingEnd="@dimen/content_padding" + android:paddingRight="@dimen/content_padding"> - + \ No newline at end of file diff --git a/OsmAnd/res/layout/quick_action_list_item.xml b/OsmAnd/res/layout/quick_action_list_item.xml index 1661bc06cd..df86cc46dc 100644 --- a/OsmAnd/res/layout/quick_action_list_item.xml +++ b/OsmAnd/res/layout/quick_action_list_item.xml @@ -1,92 +1,138 @@ + 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:background="?attr/bg_color" + android:orientation="vertical"> - + - + + + + + + android:layout_marginLeft="@dimen/content_padding" + android:layout_marginStart="@dimen/content_padding" + android:layout_height="wrap_content" + android:orientation="vertical"> - + android:minHeight="@dimen/setting_profile_item_height" + android:orientation="horizontal"> - + + + + + + + + + + + + + + + + + + + android:layout_height="1dp" + android:background="?attr/dashboard_divider" /> - - + android:background="?attr/dashboard_divider" /> \ No newline at end of file diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index 72f5e2b989..da3ab7066b 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -2107,8 +2107,7 @@ إضافة للمفضلة إضافة إجراء حذف إجراء - هل تريد حذف الإجراء -\n \"%s\" ؟ + هل تريد حذف الإجراء\n \"%s\" ؟ اسم الإجراء إضافة خطأ إلى OSM عرض مربع حوار الأماكن المفضلة diff --git a/OsmAnd/res/values-b+kab/strings.xml b/OsmAnd/res/values-b+kab/strings.xml index e931417beb..fdf37cff65 100644 --- a/OsmAnd/res/values-b+kab/strings.xml +++ b/OsmAnd/res/values-b+kab/strings.xml @@ -1054,12 +1054,10 @@ Sken %1$S Inurifen Sken inurifen - Tebɣiḍ ad tekseḍ tigawt-agi\? Kkes tigawt Tigawt Taɣect: Rnu - Agdil Ali Ṣeggem akken iwat anadi-ik Rnu ugar... diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 65a1231387..3cb9e2e346 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,6 +11,10 @@ Thx - Hardy --> + Selected: %d + Are you sure you want to irrevocably delete %d quick actions? + Delete all? + You can Export or Import quick actions with application profiles. Unsupported type World overview map (detailed) Could not find any such profiles. diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index 75330977de..842ed8af57 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -730,13 +730,15 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven prevActivityIntent = null; return; } - if (getMapView().getLayerByClass(MapQuickActionLayer.class).onBackPressed()) { - return; - } QuickActionListFragment quickActionListFragment = getQuickActionListFragment(); - if (quickActionListFragment != null && quickActionListFragment.isVisible() - && quickActionListFragment.fromDashboard()) { - this.getDashboard().setDashboardVisibility(true, DashboardType.CONFIGURE_SCREEN, null); + if (quickActionListFragment != null && quickActionListFragment.isVisible()) { + if (quickActionListFragment.fromDashboard()) { + this.getDashboard().setDashboardVisibility(true, DashboardType.CONFIGURE_SCREEN, null); + } else { + getMapView().getLayerByClass(MapQuickActionLayer.class).onBackPressed(); + } + } else if (getMapView().getLayerByClass(MapQuickActionLayer.class).onBackPressed()) { + return; } ImportSettingsFragment importSettingsFragment = getImportSettingsFragment(); if (importSettingsFragment != null) { diff --git a/OsmAnd/src/net/osmand/plus/quickaction/ConfirmationBottomSheet.java b/OsmAnd/src/net/osmand/plus/quickaction/ConfirmationBottomSheet.java new file mode 100644 index 0000000000..87af1a0442 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/quickaction/ConfirmationBottomSheet.java @@ -0,0 +1,101 @@ +package net.osmand.plus.quickaction; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +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 net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.base.MenuBottomSheetDialogFragment; +import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; +import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; + +public class ConfirmationBottomSheet extends MenuBottomSheetDialogFragment { + + private static final String TITLE_KEY = "title"; + private static final String MESSAGE_KEY = "message"; + private static final String RIGHT_BUTTON_TITLE_KEY = "right_button_title"; + + private String title; + private CharSequence message; + private int rightButtonTitle; + + public static final String TAG = ConfirmationBottomSheet.class.getSimpleName(); + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { + OsmandApplication app = requiredMyApplication(); + if (savedInstanceState != null) { + title = savedInstanceState.getString(TITLE_KEY); + message = savedInstanceState.getCharSequence(MESSAGE_KEY); + rightButtonTitle = savedInstanceState.getInt(RIGHT_BUTTON_TITLE_KEY); + } + View view = super.onCreateView(inflater, parent, savedInstanceState); + UiUtilities.setupDialogButton(nightMode, rightButton, + UiUtilities.DialogButtonType.SECONDARY, rightButtonTitle); + TextView tvRightButton = rightButton.findViewById(R.id.button_text); + int colorDelete = ContextCompat.getColor(app, R.color.color_osm_edit_delete); + tvRightButton.setTextColor(colorDelete); + return view; + } + + @Override + public void createMenuItems(Bundle savedInstanceState) { + items.add(new TitleItem(title)); + items.add(new BottomSheetItemWithDescription.Builder() + .setDescription(message) + .setLayoutId(R.layout.bottom_sheet_item_preference_descr) + .create()); + } + + @Override + protected void onRightBottomButtonClick() { + Fragment target = getTargetFragment(); + if (target instanceof OnConfirmButtonClickListener) { + ((OnConfirmButtonClickListener) target).onConfirmButtonClick(); + } + dismiss(); + } + + @Override + protected int getRightBottomButtonTextId() { + return rightButtonTitle; + } + + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putString(TITLE_KEY, title); + outState.putCharSequence(MESSAGE_KEY, message); + outState.putInt(RIGHT_BUTTON_TITLE_KEY, rightButtonTitle); + } + + public static void showInstance(@NonNull FragmentManager fm, + Fragment targetFragment, + @NonNull String title, + @NonNull CharSequence message, + int rightButtonTitle, + boolean usedOnMap) { + ConfirmationBottomSheet f = new ConfirmationBottomSheet(); + f.title = title; + f.message = message; + f.rightButtonTitle = rightButtonTitle; + f.setTargetFragment(targetFragment, 0); + f.setUsedOnMap(usedOnMap); + f.show(fm, ConfirmationBottomSheet.TAG); + } + + public interface OnConfirmButtonClickListener { + void onConfirmButtonClick(); + } +} diff --git a/OsmAnd/src/net/osmand/plus/quickaction/CreateEditActionDialog.java b/OsmAnd/src/net/osmand/plus/quickaction/CreateEditActionDialog.java index 9fdc94c8df..7d013003d5 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/CreateEditActionDialog.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/CreateEditActionDialog.java @@ -1,7 +1,6 @@ package net.osmand.plus.quickaction; import android.app.Dialog; -import android.content.Context; import android.content.DialogInterface; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; @@ -34,13 +33,14 @@ import net.osmand.plus.activities.MapActivity; import java.util.List; -import static net.osmand.plus.quickaction.QuickActionListFragment.showConfirmActionDeleteDialog; +import static net.osmand.plus.quickaction.QuickActionListFragment.showConfirmDeleteAnActionBottomSheet; /** * Created by rosty on 12/27/16. */ -public class CreateEditActionDialog extends DialogFragment implements CallbackWithObject { +public class CreateEditActionDialog extends DialogFragment + implements CallbackWithObject, ConfirmationBottomSheet.OnConfirmButtonClickListener { public static final String TAG = CreateEditActionDialog.class.getSimpleName(); @@ -181,19 +181,9 @@ public class CreateEditActionDialog extends DialogFragment implements CallbackWi item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { - Context ctx = getContext(); - if (ctx != null) { - DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - quickActionRegistry.deleteQuickAction(action); - quickActionRegistry.notifyUpdates(); - - dialog.dismiss(); - dismiss(); - } - }; - showConfirmActionDeleteDialog(ctx, action, !isLightContent, listener); - } + showConfirmDeleteAnActionBottomSheet( + getActivity(), CreateEditActionDialog.this, + action, false); return true; } }); @@ -296,4 +286,11 @@ public class CreateEditActionDialog extends DialogFragment implements CallbackWi } return false; } + + @Override + public void onConfirmButtonClick() { + quickActionRegistry.deleteQuickAction(action); + quickActionRegistry.notifyUpdates(); + dismiss(); + } } diff --git a/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java b/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java index 5c6781fbc5..1005caac2c 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java @@ -1,25 +1,32 @@ package net.osmand.plus.quickaction; import android.content.Context; -import android.content.DialogInterface; +import android.graphics.Typeface; +import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Bundle; +import android.text.SpannableString; +import android.text.style.StyleSpan; import android.util.Log; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; +import android.widget.CompoundButton; +import android.widget.FrameLayout; import android.widget.ImageView; -import android.widget.LinearLayout; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.widget.SwitchCompat; import androidx.appcompat.widget.Toolbar; import androidx.core.content.ContextCompat; import androidx.core.view.MotionEventCompat; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentManager; import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -32,59 +39,81 @@ import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.BaseOsmAndFragment; +import net.osmand.plus.settings.backend.ApplicationMode; +import net.osmand.plus.views.MapQuickActionLayer; import net.osmand.plus.views.controls.ReorderItemTouchHelperCallback; import net.osmand.plus.views.controls.ReorderItemTouchHelperCallback.OnItemMoveCallback; import net.osmand.plus.views.controls.ReorderItemTouchHelperCallback.UnmovableItem; import java.util.ArrayList; import java.util.Collections; +import java.util.Iterator; import java.util.List; -import static net.osmand.AndroidUtils.dpToPx; +import static net.osmand.plus.UiUtilities.CompoundButtonType.TOOLBAR; /** * Created by okorsun on 20.12.16. */ -public class QuickActionListFragment extends BaseOsmAndFragment implements QuickActionRegistry.QuickActionUpdatesListener { +public class QuickActionListFragment extends BaseOsmAndFragment + implements QuickActionRegistry.QuickActionUpdatesListener, + ConfirmationBottomSheet.OnConfirmButtonClickListener { public static final String TAG = QuickActionListFragment.class.getSimpleName(); public static final String FROM_DASHBOARD_KEY = "from_dashboard"; + public static final String ACTIONS_TO_DELETE_KEY = "actions_to_delete"; + public static final String SCREEN_TYPE_KEY = "screen_type"; - private RecyclerView quickActionRV; + private static final int REORDER_SCREEN_TYPE = 0; + private static final int DELETING_SCREEN_TYPE = 1; + + private static final int ITEMS_IN_GROUP = 6; + + private RecyclerView rv; private FloatingActionButton fab; + private View bottomPanel; + private Toolbar toolbar; + private View toolbarSwitchContainer; + private ImageView navigationIcon; + private ImageView deleteIconInToolbar; private QuickActionAdapter adapter; private ItemTouchHelper touchHelper; private QuickActionRegistry quickActionRegistry; + private ArrayList actionsToDelete = new ArrayList<>(); + private int screenType = REORDER_SCREEN_TYPE; private boolean fromDashboard; - private boolean isLightContent; + private boolean nightMode; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState != null) { fromDashboard = savedInstanceState.getBoolean(FROM_DASHBOARD_KEY, false); + actionsToDelete = savedInstanceState.getStringArrayList(ACTIONS_TO_DELETE_KEY); + screenType = savedInstanceState.getInt(SCREEN_TYPE_KEY, REORDER_SCREEN_TYPE); } } @Nullable @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - isLightContent = getMyApplication().getSettings().isLightContent(); + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + OsmandApplication app = requireMyApplication(); + nightMode = !app.getSettings().isLightContent(); - View view = UiUtilities.getInflater(getContext(), !isLightContent).inflate(R.layout.quick_action_list, container, false); + View view = UiUtilities.getInflater(getContext(), nightMode).inflate(R.layout.quick_action_list, container, false); - quickActionRV = (RecyclerView) view.findViewById(R.id.recycler_view); + rv = (RecyclerView) view.findViewById(R.id.recycler_view); fab = (FloatingActionButton) view.findViewById(R.id.fabButton); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - AddQuickActionDialog dialog = new AddQuickActionDialog(); - dialog.show(getFragmentManager(), AddQuickActionDialog.TAG); + showAddQuickActionDialog(); } }); @@ -92,61 +121,257 @@ public class QuickActionListFragment extends BaseOsmAndFragment implements Quick AndroidUtils.addStatusBarPadding21v(getContext(), view); } - return view; - } + bottomPanel = view.findViewById(R.id.bottom_panel); + View btnSelectAll = bottomPanel.findViewById(R.id.select_all); + View btnDelete = bottomPanel.findViewById(R.id.delete); - @Override - public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); + btnSelectAll.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + actionsToDelete = new ArrayList<>(); + for (QuickAction action : adapter.getQuickActions()) { + String id = String.valueOf(action.id); + actionsToDelete.add(id); + } + updateListItems(); + updateToolbarTitle(); + } + }); - quickActionRegistry = getMyApplication().getQuickActionRegistry(); + btnDelete.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + showConfirmDeleteActionsBottomSheet(getMapActivity()); + } + }); + UiUtilities.setupDialogButton(nightMode, btnDelete, + UiUtilities.DialogButtonType.SECONDARY, R.string.shared_string_delete); - setUpToolbar(view); - setUpQuickActionRV(); - } + quickActionRegistry = requireMyApplication().getQuickActionRegistry(); + + toolbar = (Toolbar) view.findViewById(R.id.toolbar); + navigationIcon = toolbar.findViewById(R.id.close_button); + deleteIconInToolbar = toolbar.findViewById(R.id.action_button); + toolbarSwitchContainer = toolbar.findViewById(R.id.toolbar_switch_container); + setUpToolbar(); - private void setUpQuickActionRV() { adapter = new QuickActionAdapter(new OnStartDragListener() { @Override public void onStartDrag(RecyclerView.ViewHolder viewHolder) { touchHelper.startDrag(viewHolder); } }); - quickActionRV.setAdapter(adapter); - quickActionRV.setLayoutManager(new LinearLayoutManager(getContext())); + rv.setAdapter(adapter); + rv.setLayoutManager(new LinearLayoutManager(getContext())); ItemTouchHelper.Callback touchHelperCallback = new ReorderItemTouchHelperCallback(adapter); touchHelper = new ItemTouchHelper(touchHelperCallback); - touchHelper.attachToRecyclerView(quickActionRV); - adapter.addItems(quickActionRegistry.getFilteredQuickActions()); + touchHelper.attachToRecyclerView(rv); - quickActionRV.addOnScrollListener(new RecyclerView.OnScrollListener() { + rv.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { - if (dy > 0 && fab.getVisibility() == View.VISIBLE) - fab.hide(); - else if (dy < 0 && fab.getVisibility() != View.VISIBLE) - fab.show(); + if (screenType == REORDER_SCREEN_TYPE) { + if (dy > 0 && fab.getVisibility() == View.VISIBLE) + fab.hide(); + else if (dy < 0 && fab.getVisibility() != View.VISIBLE) + fab.show(); + } } }); + updateListItems(); + updateVisibility(); + return view; } - private void setUpToolbar(View view) { - Toolbar toolbar = (Toolbar) view.findViewById(R.id.custom_toolbar); + private void setUpToolbar() { + final OsmandApplication app = requireMyApplication(); + TextView tvTitle = toolbar.findViewById(R.id.toolbar_title); + tvTitle.setTextColor(ContextCompat.getColor(app, + nightMode ? R.color.text_color_primary_dark : R.color.color_white)); + boolean isWidgetVisibleOnMap = app.getQuickActionRegistry().isQuickActionOn(); + updateToolbarTitle(); + updateToolbarNavigationIcon(); + updateToolbarActionButton(); + updateToolbarSwitch(isWidgetVisibleOnMap); + } + + private void updateToolbarNavigationIcon() { OsmandApplication app = requireMyApplication(); - Drawable icBack = app.getUIUtilities().getIcon(AndroidUtils.getNavigationIconResId(app), - isLightContent ? R.color.active_buttons_and_links_text_light : R.color.active_buttons_and_links_text_dark); - toolbar.setNavigationIcon(icBack); - toolbar.setNavigationContentDescription(R.string.access_shared_string_navigate_up); - toolbar.setNavigationOnClickListener(new View.OnClickListener() { + + int activeButtonsColorResId = nightMode ? + R.color.active_buttons_and_links_text_dark : + R.color.active_buttons_and_links_text_light; + + if (screenType == REORDER_SCREEN_TYPE) { + Drawable icBack = app.getUIUtilities().getIcon( + AndroidUtils.getNavigationIconResId(app), + activeButtonsColorResId); + navigationIcon.setImageDrawable(icBack); + navigationIcon.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + requireActivity().onBackPressed(); + } + }); + } else { + Drawable icClose = getIcon(R.drawable.ic_action_close, activeButtonsColorResId); + navigationIcon.setImageDrawable(icClose); + navigationIcon.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + changeScreen(); + } + }); + } + } + + private void updateListItems() { + final MapActivity ma = getMapActivity(); + final OsmandApplication app = ma.getMyApplication(); + final List actions = quickActionRegistry.getFilteredQuickActions(); + + updateToolbarActionButton(); + List items = new ArrayList<>(); + if (actions.size() > 0) { + items.add(new ListItem(ItemType.LIST_DIVIDER)); + int screen = 0; + for (int i = 0; i < actions.size(); i++) { + if (i % ITEMS_IN_GROUP == 0) { + items.add(new ListItem(ItemType.HEADER, ++screen)); + } + items.add(new ListItem(ItemType.ACTION, actions.get(i))); + } + } + if (screenType == REORDER_SCREEN_TYPE) { + items.add(new ListItem(ItemType.LIST_DIVIDER)); + String promo = app.getString(R.string.export_import_quick_actions_with_profiles_promo); + items.add(new ListItem(ItemType.DESCRIPTION, promo)); + items.add(new ListItem(ItemType.BUTTON, + new ControlButton(getString(R.string.quick_action_new_action), + R.drawable.ic_action_plus, + new View.OnClickListener() { + @Override + public void onClick(View view) { + showAddQuickActionDialog(); + } + }))); + items.add(new ListItem(ItemType.BUTTON, + new ControlButton(getString(R.string.shared_string_delete_all), + R.drawable.ic_action_delete_dark, + new View.OnClickListener() { + @Override + public void onClick(View view) { + actionsToDelete = new ArrayList<>(); + for (ListItem item : adapter.items) { + if (item.type == ItemType.ACTION) { + QuickAction action = (QuickAction) item.value; + actionsToDelete.add(String.valueOf(action.id)); + } + } + showConfirmDeleteActionsBottomSheet(ma); + } + }))); + } + items.add(new ListItem(ItemType.BOTTOM_SHADOW)); + adapter.setItems(items); + } + + private void updateVisibility() { + if (screenType == REORDER_SCREEN_TYPE) { + fab.setVisibility(View.VISIBLE); + bottomPanel.setVisibility(View.GONE); + toolbarSwitchContainer.setVisibility(View.VISIBLE); + deleteIconInToolbar.setVisibility(View.VISIBLE); + } else { + fab.setVisibility(View.GONE); + bottomPanel.setVisibility(View.VISIBLE); + toolbarSwitchContainer.setVisibility(View.GONE); + deleteIconInToolbar.setVisibility(View.GONE); + } + } + + private void changeScreen() { + actionsToDelete = new ArrayList<>(); + screenType = screenType == REORDER_SCREEN_TYPE ? + DELETING_SCREEN_TYPE : REORDER_SCREEN_TYPE; + updateToolbarTitle(); + updateToolbarNavigationIcon(); + updateListItems(); + updateVisibility(); + } + + private void updateToolbarActionButton() { + OsmandApplication app = requireMyApplication(); + ImageView deletingModeIcon = toolbar.findViewById(R.id.action_button); + int activeButtonsColorResId = nightMode ? + R.color.active_buttons_and_links_text_dark : + R.color.active_buttons_and_links_text_light; + boolean hasActiveQuickActions = quickActionRegistry.getQuickActions().size() > 0; + int activeColor = ContextCompat.getColor(app, activeButtonsColorResId); + int deleteIconColor = hasActiveQuickActions ? activeColor : + UiUtilities.getColorWithAlpha(activeColor, 0.25f); + Drawable deleteIcon = getPaintedContentIcon( + R.drawable.ic_action_delete_dark, deleteIconColor); + deletingModeIcon.setImageDrawable(deleteIcon); + deletingModeIcon.setOnClickListener(new View.OnClickListener() { @Override - public void onClick(View v) { - getActivity().onBackPressed(); + public void onClick(View view) { + changeScreen(); } }); - toolbar.setTitle(R.string.configure_screen_quick_action); - toolbar.setTitleTextColor(ContextCompat.getColor(getContext(), - isLightContent ? R.color.color_white : R.color.text_color_primary_dark)); + deletingModeIcon.setEnabled(hasActiveQuickActions); + } + + private void updateToolbarTitle() { + if (toolbar != null) { + TextView tvTitle = toolbar.findViewById(R.id.toolbar_title); + if (screenType == REORDER_SCREEN_TYPE) { + tvTitle.setText(getString(R.string.configure_screen_quick_action)); + } else { + int selectedCount = actionsToDelete != null ? actionsToDelete.size() : 0; + String title = String.format( + getString(R.string.shared_string_selected_n_with_colon), selectedCount); + tvTitle.setText(title); + } + } + } + + private void updateToolbarSwitch(final boolean isChecked) { + OsmandApplication app = requireMyApplication(); + ApplicationMode appMode = app.getSettings().getApplicationMode(); + int profileColor = appMode.getIconColorInfo().getColor(nightMode); + int color = ContextCompat.getColor(app, isChecked ? profileColor : R.color.preference_top_switch_off); + AndroidUtils.setBackground(toolbarSwitchContainer, new ColorDrawable(color)); + + SwitchCompat switchView = toolbarSwitchContainer.findViewById(R.id.switchWidget); + switchView.setChecked(isChecked); + UiUtilities.setupCompoundButton(switchView, nightMode, TOOLBAR); + + toolbarSwitchContainer.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + boolean visible = !isChecked; + updateToolbarSwitch(visible); + setWidgetVisibilityOnMap(visible); + } + }); + + TextView title = toolbarSwitchContainer.findViewById(R.id.switchButtonText); + title.setText(isChecked ? R.string.shared_string_enabled : R.string.shared_string_disabled); + } + + private void setWidgetVisibilityOnMap(boolean visible) { + OsmandApplication app = requireMyApplication(); + app.getQuickActionRegistry().setQuickActionFabState(visible); + + MapActivity activity = getMapActivity(); + if (activity != null) { + MapQuickActionLayer mil = activity.getMapLayers().getMapQuickActionLayer(); + if (mil != null) { + mil.refreshLayer(); + } + } } @Override @@ -169,11 +394,13 @@ public class QuickActionListFragment extends BaseOsmAndFragment implements Quick public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(FROM_DASHBOARD_KEY, fromDashboard); + outState.putStringArrayList(ACTIONS_TO_DELETE_KEY, actionsToDelete); + outState.putInt(SCREEN_TYPE_KEY, screenType); } @Override public int getStatusBarColorId() { - return isLightContent ? R.color.status_bar_color_light : R.color.status_bar_color_dark; + return nightMode ? R.color.status_bar_color_dark : R.color.status_bar_color_light; } private MapActivity getMapActivity() { @@ -184,38 +411,27 @@ public class QuickActionListFragment extends BaseOsmAndFragment implements Quick quickActionRegistry.updateQuickActions(adapter.getQuickActions()); } - static void showConfirmActionDeleteDialog(Context ctx, QuickAction action, boolean nightMode, DialogInterface.OnClickListener listener) { - OsmandApplication app = (OsmandApplication) ctx.getApplicationContext(); - - AlertDialog.Builder builder = new AlertDialog.Builder(UiUtilities.getThemedContext(ctx, nightMode)); - builder.setTitle(R.string.quick_actions_delete); - builder.setMessage(app.getString(R.string.quick_actions_delete_text, ctx.getString(action.getNameRes()))); - builder.setIcon(app.getUIUtilities().getThemedIcon(R.drawable.ic_action_delete_dark)); - builder.setPositiveButton(R.string.shared_string_yes, listener); - builder.setNegativeButton(R.string.shared_string_no, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - dialog.dismiss(); - } - }); - AlertDialog dialog = builder.show(); - int activeColorId = nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light; - int activeColor = ContextCompat.getColor(ctx, activeColorId); - dialog.getButton(DialogInterface.BUTTON_NEGATIVE).setTextColor(activeColor); - dialog.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(activeColor); + @Override + public void onActionsUpdated() { + updateListItems(); } @Override - public void onActionsUpdated() { - adapter.addItems(quickActionRegistry.getFilteredQuickActions()); + public void onConfirmButtonClick() { + if (adapter != null && actionsToDelete != null) { + adapter.deleteItems(actionsToDelete); + actionsToDelete = new ArrayList<>(); + if (screenType == DELETING_SCREEN_TYPE) { + changeScreen(); + } else { + updateToolbarActionButton(); + } + } } - public class QuickActionAdapter extends RecyclerView.Adapter implements OnItemMoveCallback { - public static final int SCREEN_ITEM_TYPE = 1; - public static final int SCREEN_HEADER_TYPE = 2; + private class QuickActionAdapter extends RecyclerView.Adapter implements OnItemMoveCallback { - private static final int ITEMS_IN_GROUP = 6; - - private List itemsList = new ArrayList<>(); + private List items = new ArrayList<>(); private final OnStartDragListener onStartDragListener; public QuickActionAdapter(OnStartDragListener onStartDragListener) { @@ -224,170 +440,235 @@ public class QuickActionListFragment extends BaseOsmAndFragment implements Quick @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - LayoutInflater inflater = UiUtilities.getInflater(parent.getContext(), !isLightContent); - if (viewType == SCREEN_ITEM_TYPE) - return new QuickActionItemVH(inflater.inflate(R.layout.quick_action_list_item, parent, false)); - else - return new QuickActionHeaderVH(inflater.inflate(R.layout.quick_action_list_header, parent, false)); + Context themedCtx = UiUtilities.getThemedContext(parent.getContext(), nightMode); + LayoutInflater inflater = UiUtilities.getInflater(themedCtx, nightMode); + int listBgColor = ContextCompat.getColor(themedCtx, + AndroidUtils.resolveAttribute(themedCtx, R.attr.bg_color)); + ItemType type = viewType < ItemType.values().length ? ItemType.values()[viewType] : ItemType.LIST_DIVIDER; + View itemView; + switch (type) { + case ACTION: + itemView = inflater.inflate(R.layout.quick_action_list_item, parent, false); + return new QuickActionVH(itemView); + case HEADER: + itemView = inflater.inflate(R.layout.quick_action_list_header, parent, false); + return new QuickActionHeaderVH(itemView); + case DESCRIPTION: + itemView = inflater.inflate(R.layout.bottom_sheet_item_description_with_padding, parent, false); + itemView.setBackgroundColor(listBgColor); + return new DescriptionVH(itemView); + case LIST_DIVIDER: + itemView = inflater.inflate(R.layout.list_item_divider, parent, false); + return new ListDividerVH(itemView); + case BUTTON: + itemView = inflater.inflate(R.layout.preference_button, parent, false); + FrameLayout frame = new FrameLayout(themedCtx); + frame.setLayoutParams(new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + frame.addView(itemView); + frame.setBackgroundColor(listBgColor); + return new ButtonVH(frame); + case BOTTOM_SHADOW: + itemView = inflater.inflate(R.layout.card_bottom_divider, parent, false); + final int spaceHeight = getResources() + .getDimensionPixelSize(R.dimen.bottom_sheet_big_item_height); + itemView.setMinimumHeight(spaceHeight); + return new BottomShadowVH(itemView); + default: + throw new IllegalArgumentException("Unsupported view type"); + } } @Override public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) { - int viewType = getItemViewType(position); - final QuickAction item = QuickActionRegistry.produceAction(itemsList.get(position)); + OsmandApplication app = requireMyApplication(); + ListItem item = items.get(position); + int activeColorResId = nightMode ? + R.color.active_color_primary_dark : R.color.active_color_primary_light; - if (viewType == SCREEN_ITEM_TYPE) { - final QuickActionItemVH itemVH = (QuickActionItemVH) holder; - Context ctx = getContext(); - itemVH.title.setText(item.getName(ctx)); - itemVH.subTitle.setText(getResources().getString(R.string.quick_action_item_action, getActionPosition(position))); - itemVH.icon.setImageDrawable(getMyApplication().getUIUtilities().getThemedIcon(item.getIconRes(ctx))); - itemVH.handleView.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - if (MotionEventCompat.getActionMasked(event) == - MotionEvent.ACTION_DOWN) { - onStartDragListener.onStartDrag(itemVH); + if (holder instanceof QuickActionVH) { + final QuickActionVH h = (QuickActionVH) holder; + final QuickAction action = (QuickAction) item.value; + + if (screenType == REORDER_SCREEN_TYPE) { + h.handleView.setVisibility(View.VISIBLE); + h.deleteBtn.setVisibility(View.VISIBLE); + h.checkbox.setVisibility(View.GONE); + + h.handleView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + if (MotionEventCompat.getActionMasked(event) == + MotionEvent.ACTION_DOWN) { + onStartDragListener.onStartDrag(h); + } + return false; } - return false; - } - }); - itemVH.closeBtn.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Context ctx = getContext(); - if (ctx != null) { - DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - adapter.deleteItem(holder.getAdapterPosition()); - dialog.dismiss(); - } - }; - showConfirmActionDeleteDialog(ctx, item, !isLightContent, listener); + }); + + h.deleteBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + actionsToDelete = new ArrayList<>(); + actionsToDelete.add(String.valueOf(action.id)); + showConfirmDeleteAnActionBottomSheet(getActivity(), + QuickActionListFragment.this, action, nightMode); } - } - }); + }); - itemVH.container.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - CreateEditActionDialog dialog = CreateEditActionDialog.newInstance(item.id); - dialog.show(getFragmentManager(), AddQuickActionDialog.TAG); - } - }); + h.itemContainer.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + CreateEditActionDialog dialog = CreateEditActionDialog.newInstance(action.id); + dialog.show(getFragmentManager(), AddQuickActionDialog.TAG); + } + }); - LinearLayout.LayoutParams dividerParams = (LinearLayout.LayoutParams) itemVH.divider.getLayoutParams(); - //noinspection ResourceType - dividerParams.setMargins(!isLongDivider(position) ? dpToPx(ctx, 56f) : 0, 0, 0, 0); - itemVH.divider.setLayoutParams(dividerParams); - } else { - QuickActionHeaderVH headerVH = (QuickActionHeaderVH) holder; - headerVH.headerName.setText(getResources().getString(R.string.quick_action_item_screen, position / (ITEMS_IN_GROUP + 1) + 1)); + } else { + h.handleView.setVisibility(View.GONE); + h.deleteBtn.setVisibility(View.GONE); + h.checkbox.setVisibility(View.VISIBLE); + + h.checkbox.setClickable(false); + + h.itemContainer.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + String id = String.valueOf(action.id); + boolean isChecked = actionsToDelete.contains(id); + h.checkbox.setChecked(!isChecked); + if (!isChecked) { + actionsToDelete.add(id); + } else { + actionsToDelete.remove(id); + } + updateToolbarTitle(); + } + }); + + String id = String.valueOf(action.id); + h.checkbox.setChecked(actionsToDelete.contains(id)); + } + + List actions = getQuickActions(); + int actionGlobalPosition = actions.indexOf(action); + int actionPosition = actionGlobalPosition % ITEMS_IN_GROUP + 1; + h.title.setText(action.getName(app)); + h.subTitle.setText(getResources().getString(R.string.quick_action_item_action, actionPosition)); + h.icon.setImageDrawable(getContentIcon(action.getIconRes(app))); + + boolean lastActionInList = actionGlobalPosition == actions.size() - 1; + boolean lastOnScreen = actionPosition == ITEMS_IN_GROUP; + if (!lastActionInList) { + if (lastOnScreen) { + h.itemDivider.setVisibility(View.GONE); + h.longDivider.setVisibility(View.VISIBLE); + } else { + h.itemDivider.setVisibility(View.VISIBLE); + h.longDivider.setVisibility(View.GONE); + } + } else { + h.itemDivider.setVisibility(View.GONE); + h.longDivider.setVisibility(View.GONE); + } + } else if (holder instanceof QuickActionHeaderVH){ + QuickActionHeaderVH h = (QuickActionHeaderVH) holder; + String title = String.format( + getResources().getString(R.string.quick_action_item_screen), + position / (ITEMS_IN_GROUP + 1) + 1); + h.headerName.setText(title); + } else if (holder instanceof ButtonVH) { + ControlButton buttonInfo = (ControlButton) item.value; + ButtonVH h = (ButtonVH) holder; + h.container.setOnClickListener(buttonInfo.listener); + h.title.setText(buttonInfo.title); + int iconColor = ContextCompat.getColor(app, activeColorResId); + int titleColor = ContextCompat.getColor(app, activeColorResId); + if (buttonInfo.iconRes == R.drawable.ic_action_delete_dark) { + boolean hasActiveActions = getQuickActions().size() > 0; + h.container.setEnabled(hasActiveActions); + int deleteAllIconColor = ContextCompat.getColor(app, R.color.color_osm_edit_delete); + iconColor = hasActiveActions ? deleteAllIconColor : UiUtilities.getColorWithAlpha(deleteAllIconColor, 0.25f); + titleColor = hasActiveActions ? titleColor : UiUtilities.getColorWithAlpha(titleColor, 0.25f); + h.divider.setVisibility(View.GONE); + } else { + h.container.setEnabled(true); + h.divider.setVisibility(View.VISIBLE); + } + h.icon.setImageDrawable(getPaintedContentIcon(buttonInfo.iconRes, iconColor)); + h.title.setTextColor(titleColor); + Drawable background = UiUtilities.getColoredSelectableDrawable(app, + ContextCompat.getColor(app, activeColorResId), 0.3f); + View selectableView = h.container.findViewById(R.id.selectable_list_item); + AndroidUtils.setBackground(selectableView, background); + } else if (holder instanceof DescriptionVH) { + String description = (String) item.value; + ((DescriptionVH) holder).tvDescription.setText(description); } } @Override public int getItemCount() { - return itemsList.size(); + return items.size(); } @Override public int getItemViewType(int position) { - return itemsList.get(position).getType() == 0 ? SCREEN_HEADER_TYPE : SCREEN_ITEM_TYPE; + ListItem item = items.get(position); + return item.type.ordinal(); } - public void deleteItem(int position) { - if (position == -1 || position >= itemsList.size()) - return; - - itemsList.remove(position); - notifyItemRemoved(position); - - moveHeaders(position); - showFABIfNotScrollable(); - saveQuickActions(); - } - - private void moveHeaders(int position) { - for (int i = position; i < itemsList.size(); i++) { - if (getItemViewType(i) == SCREEN_HEADER_TYPE) { - if (i != itemsList.size() - 2) { - Collections.swap(itemsList, i, i + 1); - notifyItemMoved(i, i + 1); - i++; - } else { - itemsList.remove(i); - notifyItemRemoved(i); + public void deleteItems(List actionsToDelete) { + if (actionsToDelete != null && actionsToDelete.size() > 0) { + Iterator it = items.iterator(); + while (it.hasNext()) { + ListItem item = it.next(); + if (item.type == ItemType.ACTION) { + for (String actionId : actionsToDelete) { + QuickAction qa = (QuickAction) item.value; + if (actionId != null) { + if (qa.getId() == Long.parseLong(actionId)) { + it.remove(); + break; + } + } + } } } - } - notifyItemRangeChanged(position, itemsList.size() - position); - - int lastPosition = itemsList.size() - 1; - if (getItemViewType(lastPosition) == SCREEN_HEADER_TYPE) { - itemsList.remove(lastPosition); - notifyItemRemoved(lastPosition); + saveQuickActions(); + updateListItems(); + showFABIfNotScrollable(); } } private void showFABIfNotScrollable() { - LinearLayoutManager layoutManager = (LinearLayoutManager) quickActionRV.getLayoutManager(); + LinearLayoutManager layoutManager = (LinearLayoutManager) rv.getLayoutManager(); int lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition(); - if ((lastVisibleItemPosition == itemsList.size() - 1 || lastVisibleItemPosition == itemsList.size()) && + if (screenType == REORDER_SCREEN_TYPE && + (lastVisibleItemPosition == items.size() - 1 + || lastVisibleItemPosition == items.size()) && layoutManager.findFirstVisibleItemPosition() == 0 && fab.getVisibility() != View.VISIBLE || - itemsList.size() == 0) + items.size() == 0) fab.show(); } public List getQuickActions() { List result = new ArrayList<>(); - for (int i = 0; i < itemsList.size(); i++) { - if (getItemViewType(i) == SCREEN_ITEM_TYPE) - result.add(itemsList.get(i)); + for (ListItem item : items) { + if (item.type == ItemType.ACTION) { + result.add((QuickAction) item.value); + } } return result; } - public void addItems(List data) { - List resultList = new ArrayList<>(); - for (int i = 0; i < data.size(); i++) { - if (i % ITEMS_IN_GROUP == 0) - resultList.add(createHeader()); - - resultList.add(data.get(i)); - } - - itemsList = resultList; - notifyDataSetChanged(); - } - - public void addItem(QuickAction item) { - int oldSize = itemsList.size(); - if (oldSize % (ITEMS_IN_GROUP + 1) == 0) - itemsList.add(createHeader()); - itemsList.add(item); - notifyItemRangeInserted(oldSize, itemsList.size() - oldSize); - } - - private QuickAction createHeader() { - return new QuickAction(); - } - - private int getActionPosition(int globalPosition) { - return globalPosition % (ITEMS_IN_GROUP + 1); - } - - private boolean isLongDivider(int globalPosition) { - return getActionPosition(globalPosition) == ITEMS_IN_GROUP || globalPosition == getItemCount() - 1; - } - @Override public boolean onItemMove(int selectedPosition, int targetPosition) { Log.v(TAG, "selected: " + selectedPosition + ", target: " + targetPosition); - Collections.swap(itemsList, selectedPosition, targetPosition); + Collections.swap(items, selectedPosition, targetPosition); if (selectedPosition - targetPosition < -1) { notifyItemMoved(selectedPosition, targetPosition); notifyItemMoved(targetPosition - 1, selectedPosition); @@ -407,32 +688,42 @@ public class QuickActionListFragment extends BaseOsmAndFragment implements Quick saveQuickActions(); } - public class QuickActionItemVH extends RecyclerView.ViewHolder { + public void setItems(List items) { + this.items = items; + notifyDataSetChanged(); + } + + private class QuickActionVH extends RecyclerView.ViewHolder { public TextView title; public TextView subTitle; public ImageView icon; - public View divider; + public View itemDivider; + public View longDivider; public ImageView handleView; - public ImageView closeBtn; - public View container; + public ImageView deleteBtn; + public CompoundButton checkbox; + public View itemContainer; - public QuickActionItemVH(View itemView) { + public QuickActionVH(View itemView) { super(itemView); -// AndroidUtils.setListItemBackground(itemView.getContext(), itemView, getMyApplication().getDaynightHelper().isNightMode()); + OsmandApplication app = requireMyApplication(); title = (TextView) itemView.findViewById(R.id.title); subTitle = (TextView) itemView.findViewById(R.id.subtitle); icon = (ImageView) itemView.findViewById(R.id.imageView); - divider = itemView.findViewById(R.id.divider); - handleView = (ImageView) itemView.findViewById(R.id.handle_view); - closeBtn = (ImageView) itemView.findViewById(R.id.closeImageButton); - container = itemView.findViewById(R.id.searchListItemLayout); + itemDivider = itemView.findViewById(R.id.item_divider); + longDivider = itemView.findViewById(R.id.long_divider); + deleteBtn = (ImageView) itemView.findViewById(R.id.action_icon); + handleView = (ImageView) itemView.findViewById(R.id.move_icon); + checkbox = (CompoundButton) itemView.findViewById(R.id.checkbox); + itemContainer = itemView.findViewById(R.id.searchListItemLayout); - handleView.setImageDrawable(getMyApplication().getUIUtilities().getThemedIcon(R.drawable.ic_action_item_move)); - closeBtn.setImageDrawable(getMyApplication().getUIUtilities().getThemedIcon(R.drawable.ic_action_remove_dark)); + deleteBtn.setImageDrawable(app.getUIUtilities().getIcon(R.drawable.ic_action_remove, R.color.color_osm_edit_delete)); + handleView.setImageDrawable(app.getUIUtilities().getThemedIcon(R.drawable.ic_action_item_move)); + UiUtilities.setupCompoundButton(checkbox, nightMode, UiUtilities.CompoundButtonType.GLOBAL); } } - public class QuickActionHeaderVH extends RecyclerView.ViewHolder implements UnmovableItem { + private class QuickActionHeaderVH extends RecyclerView.ViewHolder implements UnmovableItem { public TextView headerName; @@ -446,6 +737,105 @@ public class QuickActionListFragment extends BaseOsmAndFragment implements Quick return true; } } + + private class DescriptionVH extends RecyclerView.ViewHolder + implements ReorderItemTouchHelperCallback.UnmovableItem { + + private TextView tvDescription; + + public DescriptionVH(View itemView) { + super(itemView); + tvDescription = itemView.findViewById(R.id.description); + } + + @Override + public boolean isMovingDisabled() { + return true; + } + } + + private class ListDividerVH extends RecyclerView.ViewHolder + implements ReorderItemTouchHelperCallback.UnmovableItem { + + public ListDividerVH(View itemView) { + super(itemView); + } + + @Override + public boolean isMovingDisabled() { + return true; + } + } + + private class BottomShadowVH extends RecyclerView.ViewHolder + implements ReorderItemTouchHelperCallback.UnmovableItem { + + public BottomShadowVH(View itemView) { + super(itemView); + } + + @Override + public boolean isMovingDisabled() { + return true; + } + } + + private class ButtonVH extends RecyclerView.ViewHolder + implements ReorderItemTouchHelperCallback.UnmovableItem { + + private View container; + private ImageView icon; + private TextView title; + private View divider; + + public ButtonVH(View itemView) { + super(itemView); + container = itemView; + icon = itemView.findViewById(android.R.id.icon); + title = itemView.findViewById(android.R.id.title); + divider = itemView.findViewById(R.id.divider); + } + + @Override + public boolean isMovingDisabled() { + return true; + } + } + } + + protected enum ItemType { + ACTION, + HEADER, + DESCRIPTION, + LIST_DIVIDER, + BOTTOM_SHADOW, + BUTTON + } + + private static class ListItem { + ItemType type; + Object value; + + public ListItem(ItemType type) { + this.type = type; + } + + public ListItem(ItemType type, Object value) { + this.type = type; + this.value = value; + } + } + + protected static class ControlButton { + private String title; + private int iconRes; + private View.OnClickListener listener; + + public ControlButton(String title, int iconRes, View.OnClickListener listener) { + this.title = title; + this.iconRes = iconRes; + this.listener = listener; + } } public boolean fromDashboard() { @@ -459,4 +849,35 @@ public class QuickActionListFragment extends BaseOsmAndFragment implements Quick public interface OnStartDragListener { void onStartDrag(RecyclerView.ViewHolder viewHolder); } + + private void showAddQuickActionDialog() { + FragmentManager fm = getFragmentManager(); + if (fm != null) { + AddQuickActionDialog dialog = new AddQuickActionDialog(); + dialog.show(fm, AddQuickActionDialog.TAG); + } + } + + private void showConfirmDeleteActionsBottomSheet(MapActivity ma) { + String message = String.format( + getString(R.string.delete_all_actions_message_q), + actionsToDelete.size()); + ConfirmationBottomSheet.showInstance(ma.getSupportFragmentManager(), + QuickActionListFragment.this, + getString(R.string.shared_string_delete_all_q), + message, R.string.shared_string_delete, false); + } + + static void showConfirmDeleteAnActionBottomSheet(FragmentActivity ctx, Fragment target, + QuickAction action, boolean usedOnMap) { + String actionName = action.getName(ctx); + String message = String.format(ctx.getString( + R.string.quick_actions_delete_text), actionName); + SpannableString styledMessage = UiUtilities.createSpannableString( + message, actionName, new StyleSpan(Typeface.BOLD)); + + ConfirmationBottomSheet.showInstance(ctx.getSupportFragmentManager(), target, + ctx.getString(R.string.quick_actions_delete), styledMessage, + R.string.shared_string_delete, usedOnMap); + } } diff --git a/OsmAnd/src/net/osmand/plus/widgets/TextViewEx.java b/OsmAnd/src/net/osmand/plus/widgets/TextViewEx.java index 8755462ac6..ea1ff0e935 100644 --- a/OsmAnd/src/net/osmand/plus/widgets/TextViewEx.java +++ b/OsmAnd/src/net/osmand/plus/widgets/TextViewEx.java @@ -14,7 +14,7 @@ import androidx.appcompat.text.AllCapsTransformationMethod; import net.osmand.plus.R; import net.osmand.plus.helpers.FontCache; -public class TextViewEx extends TextView { +public class TextViewEx extends androidx.appcompat.widget.AppCompatTextView { public TextViewEx(Context context) { super(context); } @@ -31,13 +31,6 @@ public class TextViewEx extends TextView { parseAttributes(this, attrs, defStyleAttr, 0); } - @TargetApi(21) - public TextViewEx(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - - parseAttributes(this, attrs, defStyleAttr, defStyleRes); - } - /*internal*/ static void parseAttributes(TextView target, AttributeSet attrs, int defStyleAttr, int defStyleRes) { if (attrs == null) { diff --git a/OsmAnd/src/net/osmand/plus/widgets/TextViewExProgress.java b/OsmAnd/src/net/osmand/plus/widgets/TextViewExProgress.java index a7a79088ee..e8819511dd 100644 --- a/OsmAnd/src/net/osmand/plus/widgets/TextViewExProgress.java +++ b/OsmAnd/src/net/osmand/plus/widgets/TextViewExProgress.java @@ -27,11 +27,6 @@ public class TextViewExProgress extends TextViewEx { initPaint(); } - public TextViewExProgress(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - initPaint(); - } - @Override public void onDraw(Canvas canvas) { super.onDraw(canvas);