From 3ae60552d69476b07d950c98dd6cf08176bd6612 Mon Sep 17 00:00:00 2001 From: ewings1 Date: Wed, 13 Mar 2019 01:20:12 -0400 Subject: [PATCH 1/5] Very basic implementation of multiple selection Action Mode for playback queue --- .../android/vanilla/ShowQueueAdapter.java | 6 ++ .../android/vanilla/ShowQueueFragment.java | 62 ++++++++++++++++++- .../blinkenlights/android/vanilla/Song.java | 19 ++++++ app/src/main/res/menu/action_mode_menu.xml | 11 ++++ .../res/values-v21/theme-standard_light.xml | 1 + app/src/main/res/values/theme-standard.xml | 1 + app/src/main/res/values/translatable.xml | 1 + 7 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 app/src/main/res/menu/action_mode_menu.xml diff --git a/app/src/main/java/ch/blinkenlights/android/vanilla/ShowQueueAdapter.java b/app/src/main/java/ch/blinkenlights/android/vanilla/ShowQueueAdapter.java index 33f0698ed..94955d3ed 100644 --- a/app/src/main/java/ch/blinkenlights/android/vanilla/ShowQueueAdapter.java +++ b/app/src/main/java/ch/blinkenlights/android/vanilla/ShowQueueAdapter.java @@ -138,6 +138,12 @@ public View getView(int position, View convertView, ViewGroup parent) { row.highlightRow(position == mHighlightRow); + if (song.selected) { + row.setBackgroundColor(convertView.getResources().getColor(R.color.material_grey_600)); + } else { + row.setBackgroundColor(R.styleable.DragSortListView_float_background_color); + } + return row; } diff --git a/app/src/main/java/ch/blinkenlights/android/vanilla/ShowQueueFragment.java b/app/src/main/java/ch/blinkenlights/android/vanilla/ShowQueueFragment.java index 682d705cf..ca1c2a7f5 100644 --- a/app/src/main/java/ch/blinkenlights/android/vanilla/ShowQueueFragment.java +++ b/app/src/main/java/ch/blinkenlights/android/vanilla/ShowQueueFragment.java @@ -26,10 +26,15 @@ import android.content.Context; import android.content.Intent; import android.os.Bundle; +import android.view.ActionMode; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; + import com.mobeta.android.dslv.DragSortListView; @@ -37,6 +42,7 @@ public class ShowQueueFragment extends Fragment implements TimelineCallback, AdapterView.OnItemClickListener, CoordClickListener.Callback, + ActionMode.Callback, DragSortListView.DropListener, DragSortListView.RemoveListener, FancyMenu.Callback @@ -45,6 +51,8 @@ public class ShowQueueFragment extends Fragment private DragSortListView mListView; private ShowQueueAdapter mListAdapter; private boolean mIsPopulated; + private boolean mActionModeActive; + private ActionMode actionMode; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -52,10 +60,13 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa View view = inflater.inflate(R.layout.showqueue_listview, container, false); Context context = getActivity(); + mActionModeActive = false; mListAdapter = new ShowQueueAdapter(context, R.layout.draggable_row); mListView = (DragSortListView) view.findViewById(R.id.list); mListView.setAdapter(mListAdapter); +// mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); +// mListView.setMultiChoiceModeListener(this); mListView.setDropListener(this); mListView.setRemoveListener(this); mListView.setOnItemClickListener(this); @@ -94,6 +105,7 @@ public void onResume() { private final static int CTX_MENU_REMOVE = 104; private final static int CTX_MENU_SHOW_DETAILS = 105; private final static int CTX_MENU_ADD_TO_PLAYLIST = 106; + private final static int CTX_MENU_SELECT = 107; /** * Called on long-click on a adapeter row @@ -117,6 +129,7 @@ public boolean onItemLongClickWithCoords(AdapterView parent, View view, int p fm.add(CTX_MENU_ENQUEUE_ARTIST, 0, R.drawable.menu_enqueue, R.string.enqueue_current_artist).setIntent(intent); fm.add(CTX_MENU_ENQUEUE_GENRE, 0, R.drawable.menu_enqueue, R.string.enqueue_current_genre).setIntent(intent); fm.add(CTX_MENU_ADD_TO_PLAYLIST, 0, R.drawable.menu_add_to_playlist, R.string.add_to_playlist).setIntent(intent); + fm.add(CTX_MENU_SELECT, 0, R.drawable.menu_enqueue, R.string.multiple_select).setIntent(intent); fm.addSpacer(0); fm.add(CTX_MENU_SHOW_DETAILS, 0, R.drawable.menu_details, R.string.details).setIntent(intent); @@ -161,6 +174,13 @@ public boolean onFancyItemSelected(FancyMenuItem item) { PlaylistDialog dialog = PlaylistDialog.newInstance(callback, intent, null); dialog.show(getFragmentManager(), "PlaylistDialog"); break; + case CTX_MENU_SELECT: + if (!mActionModeActive) { + actionMode = getActivity().startActionMode(this); + mListAdapter.getItem(pos).setSelected(true); + mListAdapter.notifyDataSetChanged(); + } + break; default: throw new IllegalArgumentException("Unhandled menu id received!"); // we could actually dispatch this to the hosting activity, but we do not need this for now. @@ -195,7 +215,13 @@ public void remove(int which) { */ @Override public void onItemClick(AdapterView parent, View view, int position, long id) { - playbackService().jumpToQueuePosition(position); + if (!mActionModeActive) { + playbackService().jumpToQueuePosition(position); + } else { + boolean isSelected = mListAdapter.getItem(position).isSelected(); + mListAdapter.getItem(position).setSelected(!isSelected); + mListAdapter.notifyDataSetChanged(); + } } /** @@ -287,4 +313,38 @@ public void replaceSong(int delta, Song song) { } public void setState(long uptime, int state) { } + + @Override + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + mActionModeActive = true; + MenuInflater inflater = mode.getMenuInflater(); + inflater.inflate(R.menu.action_mode_menu, menu); + + return true; + } + + @Override + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + return true; + } + + @Override + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + switch (item.getItemId()) { + case R.id.test_button1: + mode.finish(); + return true; + default: + return false; + } + } + + @Override + public void onDestroyActionMode(ActionMode mode) { + for (int i=0; i < mListAdapter.getCount(); ++i) { + mListAdapter.getItem(i).setSelected(false); + } + mListAdapter.notifyDataSetChanged(); + mActionModeActive = false; + } } diff --git a/app/src/main/java/ch/blinkenlights/android/vanilla/Song.java b/app/src/main/java/ch/blinkenlights/android/vanilla/Song.java index 20d937844..ff1b16152 100644 --- a/app/src/main/java/ch/blinkenlights/android/vanilla/Song.java +++ b/app/src/main/java/ch/blinkenlights/android/vanilla/Song.java @@ -134,6 +134,10 @@ public class Song implements Comparable { */ public int discNumber; + /** + * Whether the song is selected in playlist + */ + public boolean selected; /** * Song flags. Currently {@link #FLAG_RANDOM} or {@link #FLAG_NO_COVER}. */ @@ -156,6 +160,7 @@ public Song(long id, int flags) { this.id = id; this.flags = flags; + this.selected = false; } /** @@ -173,6 +178,20 @@ public boolean isFilled() { return (id != -1 && path != null); } + /** + * Returns true if the song is selected + */ + public boolean isSelected() + { + return selected; + } + /** + * Change if the song is selected + */ + public void setSelected(boolean selected) + { + this.selected = selected; + } /** * Populate fields with data from the supplied cursor. diff --git a/app/src/main/res/menu/action_mode_menu.xml b/app/src/main/res/menu/action_mode_menu.xml new file mode 100644 index 000000000..58ca40da3 --- /dev/null +++ b/app/src/main/res/menu/action_mode_menu.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/app/src/main/res/values-v21/theme-standard_light.xml b/app/src/main/res/values-v21/theme-standard_light.xml index f202e865f..7a0f2e6dd 100644 --- a/app/src/main/res/values-v21/theme-standard_light.xml +++ b/app/src/main/res/values-v21/theme-standard_light.xml @@ -43,6 +43,7 @@