AlbumSetPage.java revision d208e12012152bf757c0492cd3bfc91f101294cc
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.app; 18 19import android.app.Activity; 20import android.content.Context; 21import android.content.Intent; 22import android.graphics.Rect; 23import android.os.Bundle; 24import android.os.Handler; 25import android.os.Message; 26import android.os.Vibrator; 27import android.view.View; 28import android.view.View.OnClickListener; 29import android.widget.Button; 30import android.widget.RelativeLayout; 31import android.widget.Toast; 32 33import com.actionbarsherlock.view.Menu; 34import com.actionbarsherlock.view.MenuInflater; 35import com.actionbarsherlock.view.MenuItem; 36import com.android.gallery3d.R; 37import com.android.gallery3d.common.Utils; 38import com.android.gallery3d.data.DataManager; 39import com.android.gallery3d.data.MediaDetails; 40import com.android.gallery3d.data.MediaObject; 41import com.android.gallery3d.data.MediaSet; 42import com.android.gallery3d.data.Path; 43import com.android.gallery3d.picasasource.PicasaSource; 44import com.android.gallery3d.settings.GallerySettings; 45import com.android.gallery3d.ui.ActionModeHandler; 46import com.android.gallery3d.ui.ActionModeHandler.ActionModeListener; 47import com.android.gallery3d.ui.AlbumSetSlotRenderer; 48import com.android.gallery3d.ui.DetailsHelper; 49import com.android.gallery3d.ui.DetailsHelper.CloseListener; 50import com.android.gallery3d.ui.FadeTexture; 51import com.android.gallery3d.ui.GLCanvas; 52import com.android.gallery3d.ui.GLRoot; 53import com.android.gallery3d.ui.GLView; 54import com.android.gallery3d.ui.PreparePageFadeoutTexture; 55import com.android.gallery3d.ui.SelectionManager; 56import com.android.gallery3d.ui.SlotView; 57import com.android.gallery3d.ui.SynchronizedHandler; 58import com.android.gallery3d.util.Future; 59import com.android.gallery3d.util.GalleryUtils; 60import com.android.gallery3d.util.HelpUtils; 61 62import java.lang.ref.WeakReference; 63 64public class AlbumSetPage extends ActivityState implements 65 SelectionManager.SelectionListener, GalleryActionBar.ClusterRunner, 66 EyePosition.EyePositionListener, MediaSet.SyncListener { 67 @SuppressWarnings("unused") 68 private static final String TAG = "AlbumSetPage"; 69 70 private static final int MSG_PICK_ALBUM = 1; 71 72 public static final String KEY_MEDIA_PATH = "media-path"; 73 public static final String KEY_SET_TITLE = "set-title"; 74 public static final String KEY_SET_SUBTITLE = "set-subtitle"; 75 public static final String KEY_SELECTED_CLUSTER_TYPE = "selected-cluster"; 76 77 private static final int DATA_CACHE_SIZE = 256; 78 private static final int REQUEST_DO_ANIMATION = 1; 79 80 private static final int BIT_LOADING_RELOAD = 1; 81 private static final int BIT_LOADING_SYNC = 2; 82 83 private boolean mIsActive = false; 84 private SlotView mSlotView; 85 private AlbumSetSlotRenderer mAlbumSetView; 86 private Config.AlbumSetPage mConfig; 87 88 private MediaSet mMediaSet; 89 private String mTitle; 90 private String mSubtitle; 91 private boolean mShowClusterMenu; 92 private GalleryActionBar mActionBar; 93 private int mSelectedAction; 94 private Vibrator mVibrator; 95 96 protected SelectionManager mSelectionManager; 97 private AlbumSetDataLoader mAlbumSetDataAdapter; 98 99 private boolean mGetContent; 100 private boolean mGetAlbum; 101 private ActionModeHandler mActionModeHandler; 102 private DetailsHelper mDetailsHelper; 103 private MyDetailsSource mDetailsSource; 104 private boolean mShowDetails; 105 private EyePosition mEyePosition; 106 private Handler mHandler; 107 108 // The eyes' position of the user, the origin is at the center of the 109 // device and the unit is in pixels. 110 private float mX; 111 private float mY; 112 private float mZ; 113 114 private Future<Integer> mSyncTask = null; 115 116 private int mLoadingBits = 0; 117 private boolean mInitialSynced = false; 118 119 private Button mCameraButton; 120 private boolean mShowedEmptyToastForSelf = false; 121 122 @Override 123 protected int getBackgroundColorId() { 124 return R.color.albumset_background; 125 } 126 127 private final GLView mRootPane = new GLView() { 128 private final float mMatrix[] = new float[16]; 129 130 @Override 131 protected void renderBackground(GLCanvas view) { 132 view.clearBuffer(getBackgroundColor()); 133 } 134 135 @Override 136 protected void onLayout( 137 boolean changed, int left, int top, int right, int bottom) { 138 mEyePosition.resetPosition(); 139 140 int slotViewTop = mActionBar.getHeight() + mConfig.paddingTop; 141 int slotViewBottom = bottom - top - mConfig.paddingBottom; 142 int slotViewRight = right - left; 143 144 if (mShowDetails) { 145 mDetailsHelper.layout(left, slotViewTop, right, bottom); 146 } else { 147 mAlbumSetView.setHighlightItemPath(null); 148 } 149 150 mSlotView.layout(0, slotViewTop, slotViewRight, slotViewBottom); 151 } 152 153 @Override 154 protected void render(GLCanvas canvas) { 155 canvas.save(GLCanvas.SAVE_FLAG_MATRIX); 156 GalleryUtils.setViewPointMatrix(mMatrix, 157 getWidth() / 2 + mX, getHeight() / 2 + mY, mZ); 158 canvas.multiplyMatrix(mMatrix, 0); 159 super.render(canvas); 160 canvas.restore(); 161 } 162 }; 163 164 @Override 165 public void onEyePositionChanged(float x, float y, float z) { 166 mRootPane.lockRendering(); 167 mX = x; 168 mY = y; 169 mZ = z; 170 mRootPane.unlockRendering(); 171 mRootPane.invalidate(); 172 } 173 174 @Override 175 public void onBackPressed() { 176 if (mShowDetails) { 177 hideDetails(); 178 } else if (mSelectionManager.inSelectionMode()) { 179 mSelectionManager.leaveSelectionMode(); 180 } else { 181 super.onBackPressed(); 182 } 183 } 184 185 private void getSlotCenter(int slotIndex, int center[]) { 186 Rect offset = new Rect(); 187 mRootPane.getBoundsOf(mSlotView, offset); 188 Rect r = mSlotView.getSlotRect(slotIndex); 189 int scrollX = mSlotView.getScrollX(); 190 int scrollY = mSlotView.getScrollY(); 191 center[0] = offset.left + (r.left + r.right) / 2 - scrollX; 192 center[1] = offset.top + (r.top + r.bottom) / 2 - scrollY; 193 } 194 195 public void onSingleTapUp(int slotIndex) { 196 if (!mIsActive) return; 197 198 if (mSelectionManager.inSelectionMode()) { 199 MediaSet targetSet = mAlbumSetDataAdapter.getMediaSet(slotIndex); 200 if (targetSet == null) return; // Content is dirty, we shall reload soon 201 mSelectionManager.toggle(targetSet.getPath()); 202 mSlotView.invalidate(); 203 } else { 204 // Show pressed-up animation for the single-tap. 205 mAlbumSetView.setPressedIndex(slotIndex); 206 mAlbumSetView.setPressedUp(); 207 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_PICK_ALBUM, slotIndex, 0), 208 FadeTexture.DURATION); 209 } 210 } 211 212 private static boolean albumShouldOpenInFilmstrip(MediaSet album) { 213 int itemCount = album.getMediaItemCount(); 214 return (album.isCameraRoll() && itemCount > 0) || itemCount == 1; 215 } 216 217 WeakReference<Toast> mEmptyAlbumToast = null; 218 219 private void showEmptyAlbumToast(int toastLength) { 220 Toast toast; 221 if (mEmptyAlbumToast != null) { 222 toast = mEmptyAlbumToast.get(); 223 if (toast != null) { 224 toast.show(); 225 return; 226 } 227 } 228 toast = Toast.makeText(mActivity, R.string.empty_album, toastLength); 229 mEmptyAlbumToast = new WeakReference<Toast>(toast); 230 toast.show(); 231 } 232 233 private void hideEmptyAlbumToast() { 234 if (mEmptyAlbumToast != null) { 235 Toast toast = mEmptyAlbumToast.get(); 236 if (toast != null) toast.cancel(); 237 } 238 } 239 240 private void pickAlbum(int slotIndex) { 241 if (!mIsActive) return; 242 243 MediaSet targetSet = mAlbumSetDataAdapter.getMediaSet(slotIndex); 244 if (targetSet == null) return; // Content is dirty, we shall reload soon 245 if (targetSet.getTotalMediaItemCount() == 0) { 246 showEmptyAlbumToast(Toast.LENGTH_SHORT); 247 return; 248 } 249 hideEmptyAlbumToast(); 250 251 String mediaPath = targetSet.getPath().toString(); 252 253 Bundle data = new Bundle(getData()); 254 int[] center = new int[2]; 255 getSlotCenter(slotIndex, center); 256 data.putIntArray(AlbumPage.KEY_SET_CENTER, center); 257 if (mGetAlbum && targetSet.isLeafAlbum()) { 258 Activity activity = mActivity; 259 Intent result = new Intent() 260 .putExtra(AlbumPicker.KEY_ALBUM_PATH, targetSet.getPath().toString()); 261 activity.setResult(Activity.RESULT_OK, result); 262 activity.finish(); 263 } else if (targetSet.getSubMediaSetCount() > 0) { 264 data.putString(AlbumSetPage.KEY_MEDIA_PATH, mediaPath); 265 mActivity.getStateManager().startStateForResult( 266 AlbumSetPage.class, REQUEST_DO_ANIMATION, data); 267 } else { 268 if (!mGetContent && (targetSet.getSupportedOperations() 269 & MediaObject.SUPPORT_IMPORT) != 0) { 270 data.putBoolean(AlbumPage.KEY_AUTO_SELECT_ALL, true); 271 } else if (!mGetContent && albumShouldOpenInFilmstrip(targetSet)) { 272 PreparePageFadeoutTexture.prepareFadeOutTexture(mActivity, mSlotView, mRootPane); 273 data.putParcelable(PhotoPage.KEY_OPEN_ANIMATION_RECT, 274 mSlotView.getSlotRect(slotIndex, mRootPane)); 275 data.putInt(PhotoPage.KEY_INDEX_HINT, 0); 276 data.putString(PhotoPage.KEY_MEDIA_SET_PATH, 277 mediaPath); 278 data.putBoolean(PhotoPage.KEY_START_IN_FILMSTRIP, true); 279 mActivity.getStateManager().startStateForResult( 280 PhotoPage.class, AlbumPage.REQUEST_PHOTO, data); 281 return; 282 } 283 data.putString(AlbumPage.KEY_MEDIA_PATH, mediaPath); 284 285 // We only show cluster menu in the first AlbumPage in stack 286 boolean inAlbum = mActivity.getStateManager().hasStateClass(AlbumPage.class); 287 data.putBoolean(AlbumPage.KEY_SHOW_CLUSTER_MENU, !inAlbum); 288 mActivity.getStateManager().startStateForResult( 289 AlbumPage.class, REQUEST_DO_ANIMATION, data); 290 } 291 } 292 293 private void onDown(int index) { 294 mAlbumSetView.setPressedIndex(index); 295 } 296 297 private void onUp(boolean followedByLongPress) { 298 if (followedByLongPress) { 299 // Avoid showing press-up animations for long-press. 300 mAlbumSetView.setPressedIndex(-1); 301 } else { 302 mAlbumSetView.setPressedUp(); 303 } 304 } 305 306 public void onLongTap(int slotIndex) { 307 if (mGetContent || mGetAlbum) return; 308 MediaSet set = mAlbumSetDataAdapter.getMediaSet(slotIndex); 309 if (set == null) return; 310 mSelectionManager.setAutoLeaveSelectionMode(true); 311 mSelectionManager.toggle(set.getPath()); 312 mSlotView.invalidate(); 313 } 314 315 @Override 316 public void doCluster(int clusterType) { 317 String basePath = mMediaSet.getPath().toString(); 318 String newPath = FilterUtils.switchClusterPath(basePath, clusterType); 319 Bundle data = new Bundle(getData()); 320 data.putString(AlbumSetPage.KEY_MEDIA_PATH, newPath); 321 data.putInt(KEY_SELECTED_CLUSTER_TYPE, clusterType); 322 mActivity.getStateManager().switchState(this, AlbumSetPage.class, data); 323 } 324 325 @Override 326 public void onCreate(Bundle data, Bundle restoreState) { 327 super.onCreate(data, restoreState); 328 initializeViews(); 329 initializeData(data); 330 Context context = mActivity.getAndroidContext(); 331 mGetContent = data.getBoolean(Gallery.KEY_GET_CONTENT, false); 332 mGetAlbum = data.getBoolean(Gallery.KEY_GET_ALBUM, false); 333 mTitle = data.getString(AlbumSetPage.KEY_SET_TITLE); 334 mSubtitle = data.getString(AlbumSetPage.KEY_SET_SUBTITLE); 335 mEyePosition = new EyePosition(context, this); 336 mDetailsSource = new MyDetailsSource(); 337 mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); 338 mActionBar = mActivity.getGalleryActionBar(); 339 mSelectedAction = data.getInt(AlbumSetPage.KEY_SELECTED_CLUSTER_TYPE, 340 FilterUtils.CLUSTER_BY_ALBUM); 341 342 mHandler = new SynchronizedHandler(mActivity.getGLRoot()) { 343 @Override 344 public void handleMessage(Message message) { 345 switch (message.what) { 346 case MSG_PICK_ALBUM: { 347 pickAlbum(message.arg1); 348 break; 349 } 350 default: throw new AssertionError(message.what); 351 } 352 } 353 }; 354 } 355 356 @Override 357 public void onDestroy() { 358 cleanupCameraButton(); 359 super.onDestroy(); 360 } 361 362 private boolean setupCameraButton() { 363 RelativeLayout galleryRoot = (RelativeLayout) ((Activity) mActivity) 364 .findViewById(R.id.gallery_root); 365 if (galleryRoot == null) return false; 366 367 mCameraButton = new Button(mActivity); 368 mCameraButton.setText(R.string.camera_label); 369 mCameraButton.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.camera_white, 0, 0); 370 mCameraButton.setOnClickListener(new OnClickListener() { 371 @Override 372 public void onClick(View arg0) { 373 GalleryUtils.startCameraActivity(mActivity); 374 } 375 }); 376 RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams( 377 RelativeLayout.LayoutParams.WRAP_CONTENT, 378 RelativeLayout.LayoutParams.WRAP_CONTENT); 379 lp.addRule(RelativeLayout.CENTER_IN_PARENT); 380 galleryRoot.addView(mCameraButton, lp); 381 return true; 382 } 383 384 private void cleanupCameraButton() { 385 if (mCameraButton == null) return; 386 RelativeLayout galleryRoot = (RelativeLayout) ((Activity) mActivity) 387 .findViewById(R.id.gallery_root); 388 if (galleryRoot == null) return; 389 galleryRoot.removeView(mCameraButton); 390 mCameraButton = null; 391 } 392 393 private void showCameraButton() { 394 if (mCameraButton == null && !setupCameraButton()) return; 395 mCameraButton.setVisibility(View.VISIBLE); 396 } 397 398 private void hideCameraButton() { 399 if (mCameraButton == null) return; 400 mCameraButton.setVisibility(View.GONE); 401 } 402 403 private void clearLoadingBit(int loadingBit) { 404 mLoadingBits &= ~loadingBit; 405 if (mLoadingBits == 0 && mIsActive) { 406 if (mAlbumSetDataAdapter.size() == 0) { 407 // If this is not the top of the gallery folder hierarchy, 408 // tell the parent AlbumSetPage instance to handle displaying 409 // the empty album toast, otherwise show it within this 410 // instance 411 if (mActivity.getStateManager().getStateCount() > 1) { 412 Intent result = new Intent(); 413 result.putExtra(AlbumPage.KEY_EMPTY_ALBUM, true); 414 setStateResult(Activity.RESULT_OK, result); 415 mActivity.getStateManager().finishState(this); 416 } else { 417 mShowedEmptyToastForSelf = true; 418 showEmptyAlbumToast(Toast.LENGTH_LONG); 419 showCameraButton(); 420 } 421 return; 422 } 423 } 424 // Hide the empty album toast if we are in the root instance of 425 // AlbumSetPage and the album is no longer empty (for instance, 426 // after a sync is completed and web albums have been synced) 427 if (mShowedEmptyToastForSelf) { 428 mShowedEmptyToastForSelf = false; 429 hideEmptyAlbumToast(); 430 hideCameraButton(); 431 } 432 } 433 434 private void setLoadingBit(int loadingBit) { 435 mLoadingBits |= loadingBit; 436 } 437 438 @Override 439 public void onPause() { 440 super.onPause(); 441 mIsActive = false; 442 mActionModeHandler.pause(); 443 mAlbumSetDataAdapter.pause(); 444 mAlbumSetView.pause(); 445 mEyePosition.pause(); 446 DetailsHelper.pause(); 447 // Call disableClusterMenu to avoid receiving callback after paused. 448 // Don't hide menu here otherwise the list menu will disappear earlier than 449 // the action bar, which is janky and unwanted behavior. 450 mActionBar.disableClusterMenu(false); 451 if (mSyncTask != null) { 452 mSyncTask.cancel(); 453 mSyncTask = null; 454 clearLoadingBit(BIT_LOADING_SYNC); 455 } 456 } 457 458 @Override 459 public void onResume() { 460 super.onResume(); 461 mIsActive = true; 462 setContentPane(mRootPane); 463 464 // Set the reload bit here to prevent it exit this page in clearLoadingBit(). 465 setLoadingBit(BIT_LOADING_RELOAD); 466 mAlbumSetDataAdapter.resume(); 467 468 mAlbumSetView.resume(); 469 mEyePosition.resume(); 470 mActionModeHandler.resume(); 471 if (mShowClusterMenu) { 472 mActionBar.enableClusterMenu(mSelectedAction, this); 473 } 474 if (!mInitialSynced) { 475 setLoadingBit(BIT_LOADING_SYNC); 476 mSyncTask = mMediaSet.requestSync(AlbumSetPage.this); 477 } 478 } 479 480 private void initializeData(Bundle data) { 481 String mediaPath = data.getString(AlbumSetPage.KEY_MEDIA_PATH); 482 mMediaSet = mActivity.getDataManager().getMediaSet(mediaPath); 483 mSelectionManager.setSourceMediaSet(mMediaSet); 484 mAlbumSetDataAdapter = new AlbumSetDataLoader( 485 mActivity, mMediaSet, DATA_CACHE_SIZE); 486 mAlbumSetDataAdapter.setLoadingListener(new MyLoadingListener()); 487 mAlbumSetView.setModel(mAlbumSetDataAdapter); 488 } 489 490 private void initializeViews() { 491 mSelectionManager = new SelectionManager(mActivity, true); 492 mSelectionManager.setSelectionListener(this); 493 494 mConfig = Config.AlbumSetPage.get(mActivity); 495 mSlotView = new SlotView(mActivity, mConfig.slotViewSpec); 496 mAlbumSetView = new AlbumSetSlotRenderer( 497 mActivity, mSelectionManager, mSlotView, mConfig.labelSpec, 498 mConfig.placeholderColor); 499 mSlotView.setSlotRenderer(mAlbumSetView); 500 mSlotView.setListener(new SlotView.SimpleListener() { 501 @Override 502 public void onDown(int index) { 503 AlbumSetPage.this.onDown(index); 504 } 505 506 @Override 507 public void onUp(boolean followedByLongPress) { 508 AlbumSetPage.this.onUp(followedByLongPress); 509 } 510 511 @Override 512 public void onSingleTapUp(int slotIndex) { 513 AlbumSetPage.this.onSingleTapUp(slotIndex); 514 } 515 516 @Override 517 public void onLongTap(int slotIndex) { 518 AlbumSetPage.this.onLongTap(slotIndex); 519 } 520 }); 521 522 mActionModeHandler = new ActionModeHandler(mActivity, mSelectionManager); 523 mActionModeHandler.setActionModeListener(new ActionModeListener() { 524 @Override 525 public boolean onActionItemClicked(MenuItem item) { 526 return onItemSelected(item); 527 } 528 }); 529 mRootPane.addComponent(mSlotView); 530 } 531 532 @Override 533 protected boolean onCreateActionBar(Menu menu) { 534 Activity activity = mActivity; 535 final boolean inAlbum = mActivity.getStateManager().hasStateClass(AlbumPage.class); 536 MenuInflater inflater = getSupportMenuInflater(); 537 538 if (mGetContent) { 539 inflater.inflate(R.menu.pickup, menu); 540 int typeBits = mData.getInt( 541 Gallery.KEY_TYPE_BITS, DataManager.INCLUDE_IMAGE); 542 mActionBar.setTitle(GalleryUtils.getSelectionModePrompt(typeBits)); 543 } else if (mGetAlbum) { 544 inflater.inflate(R.menu.pickup, menu); 545 mActionBar.setTitle(R.string.select_album); 546 } else { 547 inflater.inflate(R.menu.albumset, menu); 548 mShowClusterMenu = !inAlbum; 549 boolean selectAlbums = !inAlbum && 550 mActionBar.getClusterTypeAction() == FilterUtils.CLUSTER_BY_ALBUM; 551 MenuItem selectItem = menu.findItem(R.id.action_select); 552 selectItem.setTitle(activity.getString( 553 selectAlbums ? R.string.select_album : R.string.select_group)); 554 555 MenuItem cameraItem = menu.findItem(R.id.action_camera); 556 cameraItem.setVisible(GalleryUtils.isCameraAvailable(activity)); 557 558 FilterUtils.setupMenuItems(mActionBar, mMediaSet.getPath(), false); 559 560 Intent helpIntent = HelpUtils.getHelpIntent(activity, R.string.help_url_gallery_main); 561 562 MenuItem helpItem = menu.findItem(R.id.action_general_help); 563 helpItem.setVisible(helpIntent != null); 564 if (helpIntent != null) helpItem.setIntent(helpIntent); 565 566 mActionBar.setTitle(mTitle); 567 mActionBar.setSubtitle(mSubtitle); 568 } 569 return true; 570 } 571 572 @Override 573 protected boolean onItemSelected(MenuItem item) { 574 Activity activity = mActivity; 575 switch (item.getItemId()) { 576 case R.id.action_cancel: 577 activity.setResult(Activity.RESULT_CANCELED); 578 activity.finish(); 579 return true; 580 case R.id.action_select: 581 mSelectionManager.setAutoLeaveSelectionMode(false); 582 mSelectionManager.enterSelectionMode(); 583 return true; 584 case R.id.action_details: 585 if (mAlbumSetDataAdapter.size() != 0) { 586 if (mShowDetails) { 587 hideDetails(); 588 } else { 589 showDetails(); 590 } 591 } else { 592 Toast.makeText(activity, 593 activity.getText(R.string.no_albums_alert), 594 Toast.LENGTH_SHORT).show(); 595 } 596 return true; 597 case R.id.action_camera: { 598 GalleryUtils.startCameraActivity(activity); 599 return true; 600 } 601 case R.id.action_manage_offline: { 602 Bundle data = new Bundle(); 603 String mediaPath = mActivity.getDataManager().getTopSetPath( 604 DataManager.INCLUDE_ALL); 605 data.putString(AlbumSetPage.KEY_MEDIA_PATH, mediaPath); 606 mActivity.getStateManager().startState(ManageCachePage.class, data); 607 return true; 608 } 609 case R.id.action_sync_picasa_albums: { 610 PicasaSource.requestSync(activity); 611 return true; 612 } 613 case R.id.action_settings: { 614 activity.startActivity(new Intent(activity, GallerySettings.class)); 615 return true; 616 } 617 default: 618 return false; 619 } 620 } 621 622 @Override 623 protected void onStateResult(int requestCode, int resultCode, Intent data) { 624 if (data != null && data.getBooleanExtra(AlbumPage.KEY_EMPTY_ALBUM, false)) { 625 showEmptyAlbumToast(Toast.LENGTH_SHORT); 626 } 627 switch (requestCode) { 628 case REQUEST_DO_ANIMATION: { 629 mSlotView.startRisingAnimation(); 630 } 631 } 632 } 633 634 private String getSelectedString() { 635 int count = mSelectionManager.getSelectedCount(); 636 int action = mActionBar.getClusterTypeAction(); 637 int string = action == FilterUtils.CLUSTER_BY_ALBUM 638 ? R.plurals.number_of_albums_selected 639 : R.plurals.number_of_groups_selected; 640 String format = mActivity.getResources().getQuantityString(string, count); 641 return String.format(format, count); 642 } 643 644 @Override 645 public void onSelectionModeChange(int mode) { 646 switch (mode) { 647 case SelectionManager.ENTER_SELECTION_MODE: { 648 mActionBar.disableClusterMenu(true); 649 mActionModeHandler.startActionMode(); 650 if (mHapticsEnabled) mVibrator.vibrate(100); 651 break; 652 } 653 case SelectionManager.LEAVE_SELECTION_MODE: { 654 mActionModeHandler.finishActionMode(); 655 if (mShowClusterMenu) { 656 mActionBar.enableClusterMenu(mSelectedAction, this); 657 } 658 mRootPane.invalidate(); 659 break; 660 } 661 case SelectionManager.SELECT_ALL_MODE: { 662 mActionModeHandler.updateSupportedOperation(); 663 mRootPane.invalidate(); 664 break; 665 } 666 } 667 } 668 669 @Override 670 public void onSelectionChange(Path path, boolean selected) { 671 mActionModeHandler.setTitle(getSelectedString()); 672 mActionModeHandler.updateSupportedOperation(path, selected); 673 } 674 675 private void hideDetails() { 676 mShowDetails = false; 677 mDetailsHelper.hide(); 678 mAlbumSetView.setHighlightItemPath(null); 679 mSlotView.invalidate(); 680 } 681 682 private void showDetails() { 683 mShowDetails = true; 684 if (mDetailsHelper == null) { 685 mDetailsHelper = new DetailsHelper(mActivity, mRootPane, mDetailsSource); 686 mDetailsHelper.setCloseListener(new CloseListener() { 687 @Override 688 public void onClose() { 689 hideDetails(); 690 } 691 }); 692 } 693 mDetailsHelper.show(); 694 } 695 696 @Override 697 public void onSyncDone(final MediaSet mediaSet, final int resultCode) { 698 if (resultCode == MediaSet.SYNC_RESULT_ERROR) { 699 Log.d(TAG, "onSyncDone: " + Utils.maskDebugInfo(mediaSet.getName()) + " result=" 700 + resultCode); 701 } 702 ((Activity) mActivity).runOnUiThread(new Runnable() { 703 @Override 704 public void run() { 705 GLRoot root = mActivity.getGLRoot(); 706 root.lockRenderThread(); 707 try { 708 if (resultCode == MediaSet.SYNC_RESULT_SUCCESS) { 709 mInitialSynced = true; 710 } 711 clearLoadingBit(BIT_LOADING_SYNC); 712 if (resultCode == MediaSet.SYNC_RESULT_ERROR && mIsActive) { 713 Log.w(TAG, "failed to load album set"); 714 } 715 } finally { 716 root.unlockRenderThread(); 717 } 718 } 719 }); 720 } 721 722 private class MyLoadingListener implements LoadingListener { 723 @Override 724 public void onLoadingStarted() { 725 setLoadingBit(BIT_LOADING_RELOAD); 726 } 727 728 @Override 729 public void onLoadingFinished() { 730 clearLoadingBit(BIT_LOADING_RELOAD); 731 } 732 } 733 734 private class MyDetailsSource implements DetailsHelper.DetailsSource { 735 private int mIndex; 736 737 @Override 738 public int size() { 739 return mAlbumSetDataAdapter.size(); 740 } 741 742 @Override 743 public int setIndex() { 744 Path id = mSelectionManager.getSelected(false).get(0); 745 mIndex = mAlbumSetDataAdapter.findSet(id); 746 return mIndex; 747 } 748 749 @Override 750 public MediaDetails getDetails() { 751 MediaObject item = mAlbumSetDataAdapter.getMediaSet(mIndex); 752 if (item != null) { 753 mAlbumSetView.setHighlightItemPath(item.getPath()); 754 return item.getDetails(); 755 } else { 756 return null; 757 } 758 } 759 } 760} 761