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