SelectionManager.java revision e3c968f892585490b938ea2bcef81f8dca4a81f8
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.gallery3d.ui; 18 19import com.android.gallery3d.app.GalleryContext; 20import com.android.gallery3d.data.DataManager; 21import com.android.gallery3d.data.MediaItem; 22import com.android.gallery3d.data.MediaSet; 23import com.android.gallery3d.data.Path; 24 25import android.content.Context; 26import android.os.Vibrator; 27 28import java.util.ArrayList; 29import java.util.HashSet; 30import java.util.Set; 31 32public class SelectionManager { 33 @SuppressWarnings("unused") 34 private static final String TAG = "SelectionManager"; 35 36 public static final int ENTER_SELECTION_MODE = 1; 37 public static final int LEAVE_SELECTION_MODE = 2; 38 public static final int SELECT_ALL_MODE = 3; 39 40 private Set<Path> mClickedSet; 41 private MediaSet mSourceMediaSet; 42 private final Vibrator mVibrator; 43 private SelectionListener mListener; 44 private DataManager mDataManager; 45 private boolean mInverseSelection; 46 private boolean mIsAlbumSet; 47 private boolean mInSelectionMode; 48 private boolean mAutoLeave = true; 49 private int mTotal; 50 51 public interface SelectionListener { 52 public void onSelectionModeChange(int mode); 53 public void onSelectionChange(Path path, boolean selected); 54 } 55 56 public SelectionManager(GalleryContext galleryContext, boolean isAlbumSet) { 57 Context context = galleryContext.getAndroidContext(); 58 mDataManager = galleryContext.getDataManager(); 59 mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); 60 mClickedSet = new HashSet<Path>(); 61 mIsAlbumSet = isAlbumSet; 62 mTotal = -1; 63 } 64 65 // Whether we will leave selection mode automatically once the number of 66 // selected items is down to zero. 67 public void setAutoLeaveSelectionMode(boolean enable) { 68 mAutoLeave = enable; 69 } 70 71 public void setSelectionListener(SelectionListener listener) { 72 mListener = listener; 73 } 74 75 public void selectAll() { 76 mInverseSelection = true; 77 mClickedSet.clear(); 78 enterSelectionMode(); 79 if (mListener != null) mListener.onSelectionModeChange(SELECT_ALL_MODE); 80 } 81 82 public void deSelectAll() { 83 leaveSelectionMode(); 84 mInverseSelection = false; 85 mClickedSet.clear(); 86 } 87 88 public boolean inSelectAllMode() { 89 return mInverseSelection; 90 } 91 92 public boolean inSelectionMode() { 93 return mInSelectionMode; 94 } 95 96 public void enterSelectionMode() { 97 if (mInSelectionMode) return; 98 99 mInSelectionMode = true; 100 mVibrator.vibrate(100); 101 if (mListener != null) mListener.onSelectionModeChange(ENTER_SELECTION_MODE); 102 } 103 104 public void leaveSelectionMode() { 105 if (!mInSelectionMode) return; 106 107 mInSelectionMode = false; 108 mInverseSelection = false; 109 mClickedSet.clear(); 110 if (mListener != null) mListener.onSelectionModeChange(LEAVE_SELECTION_MODE); 111 } 112 113 public boolean isItemSelected(Path itemId) { 114 return mInverseSelection ^ mClickedSet.contains(itemId); 115 } 116 117 public int getSelectedCount() { 118 int count = mClickedSet.size(); 119 if (mInverseSelection) { 120 if (mTotal < 0) { 121 mTotal = mIsAlbumSet 122 ? mSourceMediaSet.getSubMediaSetCount() 123 : mSourceMediaSet.getMediaItemCount(); 124 } 125 count = mTotal - count; 126 } 127 return count; 128 } 129 130 public void toggle(Path path) { 131 if (mClickedSet.contains(path)) { 132 mClickedSet.remove(path); 133 } else { 134 enterSelectionMode(); 135 mClickedSet.add(path); 136 } 137 138 if (mListener != null) mListener.onSelectionChange(path, isItemSelected(path)); 139 if (getSelectedCount() == 0 && mAutoLeave) { 140 leaveSelectionMode(); 141 } 142 } 143 144 private static void expandMediaSet(ArrayList<Path> items, MediaSet set) { 145 int subCount = set.getSubMediaSetCount(); 146 for (int i = 0; i < subCount; i++) { 147 expandMediaSet(items, set.getSubMediaSet(i)); 148 } 149 int total = set.getMediaItemCount(); 150 int batch = 50; 151 int index = 0; 152 153 while (index < total) { 154 int count = index + batch < total 155 ? batch 156 : total - index; 157 ArrayList<MediaItem> list = set.getMediaItem(index, count); 158 for (MediaItem item : list) { 159 items.add(item.getPath()); 160 } 161 index += batch; 162 } 163 } 164 165 public ArrayList<Path> getSelected(boolean expandSet) { 166 ArrayList<Path> selected = new ArrayList<Path>(); 167 if (mIsAlbumSet) { 168 if (mInverseSelection) { 169 int max = mSourceMediaSet.getSubMediaSetCount(); 170 for (int i = 0; i < max; i++) { 171 MediaSet set = mSourceMediaSet.getSubMediaSet(i); 172 Path id = set.getPath(); 173 if (!mClickedSet.contains(id)) { 174 if (expandSet) { 175 expandMediaSet(selected, set); 176 } else { 177 selected.add(id); 178 } 179 } 180 } 181 } else { 182 for (Path id : mClickedSet) { 183 if (expandSet) { 184 expandMediaSet(selected, mDataManager.getMediaSet(id)); 185 } else { 186 selected.add(id); 187 } 188 } 189 } 190 } else { 191 if (mInverseSelection) { 192 193 int total = mSourceMediaSet.getMediaItemCount(); 194 int index = 0; 195 while (index < total) { 196 int count = Math.min(total - index, MediaSet.MEDIAITEM_BATCH_FETCH_COUNT); 197 ArrayList<MediaItem> list = mSourceMediaSet.getMediaItem(index, count); 198 for (MediaItem item : list) { 199 Path id = item.getPath(); 200 if (!mClickedSet.contains(id)) selected.add(id); 201 } 202 index += count; 203 } 204 } else { 205 for (Path id : mClickedSet) { 206 selected.add(id); 207 } 208 } 209 } 210 return selected; 211 } 212 213 public void setSourceMediaSet(MediaSet set) { 214 mSourceMediaSet = set; 215 mTotal = -1; 216 } 217 218 public MediaSet getSourceMediaSet() { 219 return mSourceMediaSet; 220 } 221} 222