FileDocCategorySizeDatePackage
ViewImage.javaAPI DocAndroid 1.5 API57894Wed May 06 22:42:42 BST 2009com.android.camera

ViewImage

public class ViewImage extends android.app.Activity implements View.OnClickListener

Fields Summary
private static final String
TAG
private ImageGetter
mGetter
private android.net.Uri
mSavedUri
static final boolean
sSlideShowHidesStatusBar
private static final int[]
sOrder_adjacents
private static final int[]
sOrder_slideshow
private LocalHandler
mHandler
private Random
mRandom
private int[]
mShuffleOrder
private boolean
mUseShuffleOrder
private boolean
mSlideShowLoop
private static final int
MODE_NORMAL
private static final int
MODE_SLIDESHOW
private int
mMode
private boolean
mFullScreenInNormalMode
private boolean
mShowActionIcons
private android.view.View
mActionIconPanel
private android.view.View
mShutterButton
private boolean
mSortAscending
private int
mSlideShowInterval
private int
mLastSlideShowImage
private boolean
mFirst
private int
mCurrentPosition
private boolean
mLayoutComplete
private int
mAnimationIndex
private android.view.animation.Animation[]
mSlideShowInAnimation
private android.view.animation.Animation[]
mSlideShowOutAnimation
private android.content.SharedPreferences
mPrefs
private android.view.View
mNextImageView
private android.view.View
mPrevImageView
private android.view.animation.Animation
mHideNextImageViewAnimation
private android.view.animation.Animation
mHidePrevImageViewAnimation
private android.view.animation.Animation
mShowNextImageViewAnimation
private android.view.animation.Animation
mShowPrevImageViewAnimation
static final int
sPadding
static final int
sHysteresis
static final int
sBaseScrollDuration
private ImageManager.IImageList
mAllImages
private int
mSlideShowImageCurrent
private ImageViewTouch[]
mSlideShowImageViews
private android.view.GestureDetector
mGestureDetector
private android.widget.ZoomButtonsController
mZoomButtonsController
private ImageViewTouch[]
mImageViews
private ScrollHandler
mScroller
private MenuHelper.MenuItemsResult
mImageMenuRunnable
private Runnable
mDismissOnScreenControlsRunnable
private boolean
mCameraReviewMode
private static final boolean
sUseBounce
private static final boolean
sAnimateTransitions
protected Runnable
mDeletePhotoRunnable
Constructors Summary
Methods Summary
private voidanimateScrollTo(int xNew, int yNew)

        mScroller.startScrollTo(xNew, yNew);
    
private booleandesiredSortOrder()

        String sortOrder = mPrefs.getString("pref_gallery_sort_key", null);
        boolean sortAscending = false;
        if (sortOrder != null) {
            sortAscending = sortOrder.equals("ascending");
        }
        if (mCameraReviewMode) {
            // Force left-arrow older pictures, right-arrow newer pictures.
            sortAscending = true;
        }
        return sortAscending;
    
public booleandispatchTouchEvent(android.view.MotionEvent m)

        boolean sup = super.dispatchTouchEvent(m);

        // This is a hack to show the on screen controls. We should make sure
        // this event is not handled by others(ie. sup == false), and listen for
        // the events on zoom/prev/next buttons.
        // However, since we have no other pressable views, it is OK now.
        // TODO: Fix the above issue.
        if (mMode == MODE_NORMAL) {
            switch (m.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    showOnScreenControls();
                    break;
                case MotionEvent.ACTION_UP:
                    scheduleDismissOnScreenControls();
                    break;
            }
        }

        if (sup == false) {
            if (mMode == MODE_SLIDESHOW) {
                mSlideShowImageViews[mSlideShowImageCurrent].handleTouchEvent(m);
            } else if (mMode == MODE_NORMAL) {
                mImageViews[1].handleTouchEvent(m);
            }
            return true;
        }
        return true;
    
private voidgenerateShuffleOrder()

        if (mShuffleOrder == null || mShuffleOrder.length != mAllImages.getCount()) {
            mShuffleOrder = new int[mAllImages.getCount()];
        }

        for (int i = 0; i < mShuffleOrder.length; i++) {
            mShuffleOrder[i] = i;
        }

        for (int i = mShuffleOrder.length - 1; i > 0; i--) {
            int r = mRandom.nextInt(i);
            int tmp = mShuffleOrder[r];
            mShuffleOrder[r] = mShuffleOrder[i];
            mShuffleOrder[i] = tmp;
        }
    
private android.net.UrigetCurrentUri()

        ImageManager.IImage image = mAllImages.getImageAt(mCurrentPosition);
        Uri uri = null;
        if (image != null){
            String bucket = null;
            uri = image.fullSizeImageUri();
            if(getIntent() != null && getIntent().getData() != null)
                bucket = getIntent().getData().getQueryParameter("bucketId");

            if(bucket != null)
                uri = uri.buildUpon().appendQueryParameter("bucketId", bucket).build();
        }
        return uri;
    
private voidinit(android.net.Uri uri)

        if (uri == null)
            return;

        mSortAscending = desiredSortOrder();
        int sort = mSortAscending ? ImageManager.SORT_ASCENDING : ImageManager.SORT_DESCENDING;
        mAllImages = ImageManager.makeImageList(uri, this, sort);

        uri = uri.buildUpon().query(null).build();
        // TODO smarter/faster here please
        for (int i = 0; i < mAllImages.getCount(); i++) {
            ImageManager.IImage image = mAllImages.getImageAt(i);
            if (image.fullSizeImageUri().equals(uri)) {
                mCurrentPosition = i;
                mLastSlideShowImage = mCurrentPosition;
                break;
            }
        }
    
private booleanisPickIntent()

        String action = getIntent().getAction();
        return (Intent.ACTION_PICK.equals(action) || Intent.ACTION_GET_CONTENT.equals(action));
    
private voidloadNextImage(int requestedPos, long delay, boolean firstCall)

        if (firstCall && mUseShuffleOrder) {
            generateShuffleOrder();
        }

        final long targetDisplayTime = System.currentTimeMillis() + delay;

        ImageGetterCallback cb = new ImageGetterCallback() {
            public void completed(boolean wasCanceled) {
            }

            public boolean wantsThumbnail(int pos, int offset) {
                return true;
            }

            public boolean wantsFullImage(int pos, int offset) {
                return false;
            }

            public int [] loadOrder() {
                return sOrder_slideshow;
            }

            public int fullImageSizeToUse(int pos, int offset) {
                return 480; // TODO compute this
            }

            public void imageLoaded(final int pos, final int offset, final Bitmap bitmap, final boolean isThumb) {
                long timeRemaining = Math.max(0, targetDisplayTime - System.currentTimeMillis());
                mHandler.postDelayedGetterCallback(new Runnable() {
                    public void run() {
                        if (mMode == MODE_NORMAL) return;

                        ImageViewTouchBase oldView = mSlideShowImageViews[mSlideShowImageCurrent];

                        if (++mSlideShowImageCurrent == mSlideShowImageViews.length) {
                            mSlideShowImageCurrent = 0;
                        }

                        ImageViewTouchBase newView = mSlideShowImageViews[mSlideShowImageCurrent];
                        newView.setVisibility(View.VISIBLE);
                        newView.setImageBitmapResetBase(bitmap, isThumb, isThumb);
                        newView.bringToFront();

                        int animation = 0;

                        if (mAnimationIndex == -1) {
                            int n = mRandom.nextInt(mSlideShowInAnimation.length);
                            animation = n;
                        } else {
                            animation = mAnimationIndex;
                        }

                        Animation aIn = mSlideShowInAnimation[animation];
                        newView.setAnimation(aIn);
                        newView.setVisibility(View.VISIBLE);
                        aIn.startNow();

                        Animation aOut = mSlideShowOutAnimation[animation];
                        oldView.setVisibility(View.INVISIBLE);
                        oldView.setAnimation(aOut);
                        aOut.startNow();

                        mCurrentPosition = requestedPos;

                        if (mCurrentPosition == mLastSlideShowImage && !firstCall) {
                            if (mSlideShowLoop) {
                                if (mUseShuffleOrder) {
                                    generateShuffleOrder();
                                }
                            } else {
                                setMode(MODE_NORMAL);
                                return;
                            }
                        }

                        if (Config.LOGV)
                            Log.v(TAG, "mCurrentPosition is now " + mCurrentPosition);
                        loadNextImage((mCurrentPosition + 1) % mAllImages.getCount(), mSlideShowInterval, false);
                    }
                }, timeRemaining);
            }
        };
        // Could be null if we're stopping a slide show in the course of pausing
        if (mGetter != null) {
            int pos = requestedPos;
            if (mShuffleOrder != null) {
                pos = mShuffleOrder[pos];
            }
            mGetter.setPosition(pos, cb);
        }
    
private voidmakeGetter()

        mGetter = new ImageGetter();
    
private android.view.animation.AnimationmakeInAnimation(int id)

        Animation inAnimation = AnimationUtils.loadAnimation(this, id);
        return inAnimation;
    
private android.view.animation.AnimationmakeOutAnimation(int id)

        Animation outAnimation = AnimationUtils.loadAnimation(this, id);
        return outAnimation;
    
private voidmoveNextOrPrevious(int delta)

        int nextImagePos = mCurrentPosition + delta;
        if ((0 <= nextImagePos) && (nextImagePos < mAllImages.getCount())) {
            setImage(nextImagePos);
        }
    
protected voidonActivityResult(int requestCode, int resultCode, android.content.Intent data)

        switch (requestCode) {
        case MenuHelper.RESULT_COMMON_MENU_CROP:
            if (resultCode == RESULT_OK) {
                // The CropImage activity passes back the Uri of the cropped image as
                // the Action rather than the Data.
                mSavedUri = Uri.parse(data.getAction());
            }
            break;
        }
    
public voidonClick(android.view.View v)

        switch (v.getId()) {

        case R.id.shutter_button: {
            if (mCameraReviewMode) {
                finish();
            } else {
                MenuHelper.gotoStillImageCapture(this);
            }
        }
        break;

        case R.id.gallery: {
            MenuHelper.gotoCameraImageGallery(this);
        }
        break;

        case R.id.discard: {
            MenuHelper.deletePhoto(this, mDeletePhotoRunnable);
        }
        break;

        case R.id.share: {
            Uri u = mAllImages.getImageAt(mCurrentPosition).fullSizeImageUri();
            if (MenuHelper.isMMSUri(u)) return;
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_SEND);
            intent.setType("image/jpeg");
            intent.putExtra(Intent.EXTRA_STREAM, u);
            try {
                startActivity(Intent.createChooser(intent, getText(R.string.sendImage)));
            } catch (android.content.ActivityNotFoundException ex) {
                Toast.makeText(this, R.string.no_way_to_share_image, Toast.LENGTH_SHORT).show();
            }
        }
        break;

        case R.id.setas: {
            Uri u = mAllImages.getImageAt(mCurrentPosition).fullSizeImageUri();
            Intent intent = new Intent(Intent.ACTION_ATTACH_DATA, u);
            try {
                startActivity(Intent.createChooser(intent, getText(R.string.setImage)));
            } catch (android.content.ActivityNotFoundException ex) {
                Toast.makeText(this, R.string.no_way_to_share_video, Toast.LENGTH_SHORT).show();
            }
        }
        break;

        case R.id.next_image: {
            moveNextOrPrevious(1);
        }
        break;

        case R.id.prev_image: {
            moveNextOrPrevious(-1);
        }
        break;
        }
    
public voidonCreate(android.os.Bundle instanceState)

        super.onCreate(instanceState);
        Intent intent = getIntent();
        mCameraReviewMode = intent.getBooleanExtra("com.android.camera.ReviewMode", false);
        mFullScreenInNormalMode = intent.getBooleanExtra(MediaStore.EXTRA_FULL_SCREEN, true);
        mShowActionIcons = intent.getBooleanExtra(MediaStore.EXTRA_SHOW_ACTION_ICONS, false);

        setRequestedOrientation();

        mPrefs = PreferenceManager.getDefaultSharedPreferences(this);

        setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.viewimage);

        mImageViews[0] = (ImageViewTouch) findViewById(R.id.image1);
        mImageViews[1] = (ImageViewTouch) findViewById(R.id.image2);
        mImageViews[2] = (ImageViewTouch) findViewById(R.id.image3);

        for(ImageViewTouch v : mImageViews) {
            v.setEnableTrackballScroll(!mShowActionIcons);
        }

        mScroller = (ScrollHandler)findViewById(R.id.scroller);
        makeGetter();

        mAnimationIndex = -1;

        mSlideShowInAnimation = new Animation[] {
            makeInAnimation(R.anim.transition_in),
            makeInAnimation(R.anim.slide_in),
            makeInAnimation(R.anim.slide_in_vertical),
        };

        mSlideShowOutAnimation = new Animation[] {
            makeOutAnimation(R.anim.transition_out),
            makeOutAnimation(R.anim.slide_out),
            makeOutAnimation(R.anim.slide_out_vertical),
        };

        mSlideShowImageViews[0] = (ImageViewTouch) findViewById(R.id.image1_slideShow);
        mSlideShowImageViews[1] = (ImageViewTouch) findViewById(R.id.image2_slideShow);
        for (ImageViewTouch v : mSlideShowImageViews) {
            v.setImageBitmapResetBase(null, true, true);
            v.setVisibility(View.INVISIBLE);
            v.setEnableTrackballScroll(!mShowActionIcons);
        }

        mActionIconPanel = findViewById(R.id.action_icon_panel);
        {
            int[] pickIds = {R.id.attach, R.id.cancel};
            int[] normalIds = {R.id.gallery, R.id.setas, R.id.share, R.id.discard};
            int[] hideIds = pickIds;
            int[] connectIds = normalIds;
            if (isPickIntent()) {
                hideIds = normalIds;
                connectIds = pickIds;
            }
            for(int id : hideIds) {
                mActionIconPanel.findViewById(id).setVisibility(View.GONE);
            }
            for(int id : connectIds) {
                View view = mActionIconPanel.findViewById(id);
                view.setOnClickListener(this);
                Animation animation = new AlphaAnimation(0F, 1F);
                animation.setDuration(500);
                view.setAnimation(animation);
            }
        }
        mShutterButton = findViewById(R.id.shutter_button);
        mShutterButton.setOnClickListener(this);

        Uri uri = getIntent().getData();

        if (Config.LOGV)
            Log.v(TAG, "uri is " + uri);
        if (instanceState != null) {
            if (instanceState.containsKey("uri")) {
                uri = Uri.parse(instanceState.getString("uri"));
            }
        }
        if (uri == null) {
            finish();
            return;
        }
        init(uri);

        Bundle b = getIntent().getExtras();

        boolean slideShow = b != null ? b.getBoolean("slideshow", false) : false;
        if (slideShow) {
            setMode(MODE_SLIDESHOW);
            loadNextImage(mCurrentPosition, 0, true);
        } else {
            if (mFullScreenInNormalMode) {
                getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
            }
            if (mShowActionIcons) {
                mActionIconPanel.setVisibility(View.VISIBLE);
                mShutterButton.setVisibility(View.VISIBLE);
            }
        }

        setupZoomButtonController(findViewById(R.id.rootLayout));
        setupDismissOnScreenControlRunnable();

        mNextImageView = findViewById(R.id.next_image);
        mPrevImageView = findViewById(R.id.prev_image);
        mNextImageView.setOnClickListener(this);
        mPrevImageView.setOnClickListener(this);

        if (mShowActionIcons) {
            mNextImageView.setFocusable(true);
            mPrevImageView.setFocusable(true);
        }
    
public booleanonCreateOptionsMenu(android.view.Menu menu)

        super.onCreateOptionsMenu(menu);

        if (! mCameraReviewMode) {
            MenuItem item = menu.add(Menu.CATEGORY_SECONDARY, 203, 0, R.string.slide_show);
            item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
                public boolean onMenuItemClick(MenuItem item) {
                    setMode(MODE_SLIDESHOW);
                    mLastSlideShowImage = mCurrentPosition;
                    loadNextImage(mCurrentPosition, 0, true);
                    return true;
                }
            });
            item.setIcon(android.R.drawable.ic_menu_slideshow);
        }

        final SelectedImageGetter selectedImageGetter = new SelectedImageGetter() {
            public ImageManager.IImage getCurrentImage() {
                return mAllImages.getImageAt(mCurrentPosition);
            }

            public Uri getCurrentImageUri() {
                return mAllImages.getImageAt(mCurrentPosition).fullSizeImageUri();
            }
        };

        mImageMenuRunnable = MenuHelper.addImageMenuItems(
                menu,
                MenuHelper.INCLUDE_ALL,
                true,
                ViewImage.this,
                mHandler,
                mDeletePhotoRunnable,
                new MenuHelper.MenuInvoker() {
                    public void run(MenuHelper.MenuCallback cb) {
                        setMode(MODE_NORMAL);
                        cb.run(selectedImageGetter.getCurrentImageUri(), selectedImageGetter.getCurrentImage());
                        for (ImageViewTouchBase iv: mImageViews) {
                            iv.recycleBitmaps();
                            iv.setImageBitmap(null, true);
                        }
                        setImage(mCurrentPosition);
                    }
                });

        if (true) {
            MenuItem item = menu.add(Menu.CATEGORY_SECONDARY, 203, 1000, R.string.camerasettings);
            item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
                public boolean onMenuItemClick(MenuItem item) {
                    Intent preferences = new Intent();
                    preferences.setClass(ViewImage.this, GallerySettings.class);
                    startActivity(preferences);
                    return true;
                }
            });
            item.setAlphabeticShortcut('p");
            item.setIcon(android.R.drawable.ic_menu_preferences);
        }

        // Hidden menu just so the shortcut will bring up the zoom controls
        menu.add(Menu.CATEGORY_SECONDARY, 203, 0, R.string.camerasettings)      // the string resource is a placeholder
        .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
            public boolean onMenuItemClick(MenuItem item) {
                showOnScreenControls();
                scheduleDismissOnScreenControls();
                return true;
            }
        })
        .setAlphabeticShortcut('z")
        .setVisible(false);


        return true;
    
protected voidonDestroy()

        // This is necessary to make the ZoomButtonsController unregister
        // its configuration change receiver.
        if (mZoomButtonsController != null) {
            mZoomButtonsController.setVisible(false);
        }

        super.onDestroy();
    
private voidonLayoutChanged()

        // if we get here after "onPause" then ignore the event
        if (mGetter == null) return;
        mDismissOnScreenControlsRunnable.run();
        mGetter.cancelCurrent();
        for (ImageViewTouch iv: mImageViews) {
            iv.clear();
        }
        mFirst = true;
        setImage(mCurrentPosition);
    
public booleanonMenuItemSelected(int featureId, android.view.MenuItem item)

        boolean b = super.onMenuItemSelected(featureId, item);
        if (mImageMenuRunnable != null)
            mImageMenuRunnable.aboutToCall(item, mAllImages.getImageAt(mCurrentPosition));
        return b;
    
public voidonPause()

        super.onPause();

        mGetter.cancelCurrent();
        mGetter.stop();
        mGetter = null;
        setMode(MODE_NORMAL);

        // removing all callback in the message queue
        mHandler.removeAllGetterCallbacks();

        mSavedUri = getCurrentUri();

        mAllImages.deactivate();
        mDismissOnScreenControlsRunnable.run();
        if (mDismissOnScreenControlsRunnable != null)
            mHandler.removeCallbacks(mDismissOnScreenControlsRunnable);

        for (ImageViewTouch iv: mImageViews) {
            iv.recycleBitmaps();
            iv.setImageBitmap(null, true);
        }

        for (ImageViewTouch iv: mSlideShowImageViews) {
            iv.recycleBitmaps();
            iv.setImageBitmap(null, true);
        }
    
public booleanonPrepareOptionsMenu(android.view.Menu menu)


    
        
        super.onPrepareOptionsMenu(menu);
        setMode(MODE_NORMAL);

        if (mImageMenuRunnable != null) {
            mImageMenuRunnable.gettingReadyToOpen(menu, mAllImages.getImageAt(mCurrentPosition));
        }

        Uri uri = mAllImages.getImageAt(mCurrentPosition).fullSizeImageUri();
        MenuHelper.enableShareMenuItem(menu, !MenuHelper.isMMSUri(uri));

        return true;
    
public voidonResume()

        super.onResume();

        init(mSavedUri);

        // normally this will never be zero but if one "backs" into this
        // activity after removing the sdcard it could be zero.  in that
        // case just "finish" since there's nothing useful that can happen.
        int count = mAllImages.getCount();
        if (count == 0) {
            finish();
        } else if (count <= mCurrentPosition) {
            mCurrentPosition = count - 1;
        }

        ImageManager.IImage image = mAllImages.getImageAt(mCurrentPosition);

        if (mGetter == null) {
            makeGetter();
        }

        mFirst = true;
        setImage(mCurrentPosition);
    
public voidonSaveInstanceState(android.os.Bundle b)

        super.onSaveInstanceState(b);

        Uri uri = getCurrentUri();
        if (uri != null) {
            b.putString("uri", uri.toString());
        }

        if (mMode == MODE_SLIDESHOW) {
            b.putBoolean("slideshow", true);
        }
    
private voidscheduleDismissOnScreenControls()

        mHandler.removeCallbacks(mDismissOnScreenControlsRunnable);
        mHandler.postDelayed(mDismissOnScreenControlsRunnable, 1500);
    
private voidsetImage(int pos)

        if (!mLayoutComplete) return;

        final boolean left = (pos == mCurrentPosition - 1);
        final boolean right = (pos == mCurrentPosition + 1);

        mCurrentPosition = pos;

        ImageViewTouchBase current = mImageViews[1];
        current.mSuppMatrix.reset();
        current.setImageMatrix(current.getImageViewMatrix());

        if (false) {
            Log.v(TAG, "before...");
            for (ImageViewTouchBase ivtb : mImageViews)
                ivtb.dump();
        }

        if (!mFirst) {
            if (left) {
                mImageViews[2].copyFrom(mImageViews[1]);
                mImageViews[1].copyFrom(mImageViews[0]);
            } else if (right) {
                mImageViews[0].copyFrom(mImageViews[1]);
                mImageViews[1].copyFrom(mImageViews[2]);
            }
        }
        if (false) {
            Log.v(TAG, "after copy...");
            for (ImageViewTouchBase ivtb : mImageViews)
                ivtb.dump();
        }

        for (ImageViewTouchBase ivt: mImageViews) {
            ivt.mIsZooming = false;
        }
        int width = mImageViews[1].getWidth();
        int from;
        int to = width + sPadding;
        if (mFirst) {
            from = to;
            mFirst = false;
        } else {
            from = left ? (width + sPadding) + mScroller.getScrollX()
                        : mScroller.getScrollX() - (width + sPadding);
        }

        if (sAnimateTransitions) {
            mScroller.scrollTo(from, 0);
            animateScrollTo(to, 0);
        } else {
            mScroller.scrollTo(to, 0);
        }

        ImageGetterCallback cb = new ImageGetterCallback() {
            public void completed(boolean wasCanceled) {
                if (!mShowActionIcons) {
                    mImageViews[1].setFocusableInTouchMode(true);
                    mImageViews[1].requestFocus();
                }
            }

            public boolean wantsThumbnail(int pos, int offset) {
                ImageViewTouchBase ivt = mImageViews[1 + offset];
                return ivt.mThumbBitmap == null;
            }

            public boolean wantsFullImage(int pos, int offset) {
                ImageViewTouchBase ivt = mImageViews[1 + offset];
                if (ivt.mBitmapDisplayed != null && !ivt.mBitmapIsThumbnail) {
                    return false;
                }
                if (offset != 0) {
                    return false;
                }
                return true;
            }

            public int fullImageSizeToUse(int pos, int offset) {
                // TODO
                // this number should be bigger so that we can zoom.  we may need to
                // get fancier and read in the fuller size image as the user starts
                // to zoom.  use -1 to get the full full size image.
                // for now use 480 so we don't run out of memory
                final int imageViewSize = 480;
                return imageViewSize;
            }

            public int [] loadOrder() {
                return sOrder_adjacents;
            }

            public void imageLoaded(int pos, int offset, Bitmap bitmap, boolean isThumb) {
                // shouldn't get here after onPause()
                ImageViewTouchBase ivt = mImageViews[1 + offset];
                if (offset == 0) updateZoomButtonsEnabled();
                ivt.setImageBitmapResetBase(bitmap, isThumb, isThumb);
            }
        };

        // Could be null if we're stopping a slide show in the course of pausing
        if (mGetter != null) {
            mGetter.setPosition(pos, cb);
        }

        showOnScreenControls();
        scheduleDismissOnScreenControls();
    
private voidsetMode(int mode)

        if (mMode == mode) {
            return;
        }

        findViewById(R.id.slideShowContainer).setVisibility(mode == MODE_SLIDESHOW ? View.VISIBLE : View.GONE);
        findViewById(R.id.abs)               .setVisibility(mode == MODE_NORMAL    ? View.VISIBLE : View.GONE);

        Window win = getWindow();
        mMode = mode;
        if (mode == MODE_SLIDESHOW) {
            win.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN
                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
            if (sSlideShowHidesStatusBar) {
                win.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
            }
            for (ImageViewTouchBase ivt: mImageViews) {
                ivt.clear();
            }
            mActionIconPanel.setVisibility(View.GONE);
            mShutterButton.setVisibility(View.GONE);

            if (false) {
                Log.v(TAG, "current is " + this.mSlideShowImageCurrent);
                this.mSlideShowImageViews[0].dump();
                this.mSlideShowImageViews[0].dump();
            }

            findViewById(R.id.slideShowContainer).getRootView().requestLayout();
            mUseShuffleOrder   = mPrefs.getBoolean("pref_gallery_slideshow_shuffle_key", false);
            mSlideShowLoop     = mPrefs.getBoolean("pref_gallery_slideshow_repeat_key", false);
            try {
                mAnimationIndex = Integer.parseInt(mPrefs.getString("pref_gallery_slideshow_transition_key", "0"));
            } catch (Exception ex) {
                Log.e(TAG, "couldn't parse preference: " + ex.toString());
                mAnimationIndex = 0;
            }
            try {
                mSlideShowInterval = Integer.parseInt(mPrefs.getString("pref_gallery_slideshow_interval_key", "3")) * 1000;
            } catch (Exception ex) {
                Log.e(TAG, "couldn't parse preference: " + ex.toString());
                mSlideShowInterval = 3000;
            }

            if (Config.LOGV) {
                Log.v(TAG, "read prefs...  shuffle: " + mUseShuffleOrder);
                Log.v(TAG, "read prefs...     loop: " + mSlideShowLoop);
                Log.v(TAG, "read prefs...  animidx: " + mAnimationIndex);
                Log.v(TAG, "read prefs... interval: " + mSlideShowInterval);
            }

            if (mUseShuffleOrder) {
                generateShuffleOrder();
            }
        } else {
            if (Config.LOGV)
                Log.v(TAG, "slide show mode off, mCurrentPosition == " + mCurrentPosition);
            win.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
            if (mFullScreenInNormalMode) {
                win.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
            } else {
                win.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
            }

            if (mGetter != null)
                mGetter.cancelCurrent();

            if (sSlideShowHidesStatusBar) {
                win.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
            }
            if (mShowActionIcons) {
                mActionIconPanel.setVisibility(View.VISIBLE);
                mShutterButton.setVisibility(View.VISIBLE);
            }

            ImageViewTouchBase dst = mImageViews[1];
            dst.mLastXTouchPos = -1;
            dst.mLastYTouchPos = -1;

            for (ImageViewTouchBase ivt: mSlideShowImageViews) {
                ivt.clear();
            }

            mShuffleOrder = null;

            // mGetter null is a proxy for being paused
            if (mGetter != null) {
                mFirst = true;  // don't animate
                setImage(mCurrentPosition);
            }
        }

        // this line shouldn't be necessary but the view hierarchy doesn't
        // seem to realize that the window layout changed
        mScroller.requestLayout();
    
private voidsetRequestedOrientation()

        Intent intent = getIntent();
        if (intent.hasExtra(MediaStore.EXTRA_SCREEN_ORIENTATION)) {
            int orientation = intent.getIntExtra(MediaStore.EXTRA_SCREEN_ORIENTATION,
                    ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
            if (orientation != getRequestedOrientation()) {
                setRequestedOrientation(orientation);
            }
        } else {
            MenuHelper.requestOrientation(this, mPrefs);
        }
    
private voidsetupDismissOnScreenControlRunnable()

        mDismissOnScreenControlsRunnable = new Runnable() {
            public void run() {
                if (!mShowActionIcons) {
                    if (mNextImageView.getVisibility() == View.VISIBLE) {
                        Animation a = mHideNextImageViewAnimation;
                        a.setDuration(500);
                        a.startNow();
                        mNextImageView.setAnimation(a);
                        mNextImageView.setVisibility(View.INVISIBLE);
                    }

                    if (mPrevImageView.getVisibility() == View.VISIBLE) {
                        Animation a = mHidePrevImageViewAnimation;
                        a.setDuration(500);
                        a.startNow();
                        mPrevImageView.setAnimation(a);
                        mPrevImageView.setVisibility(View.INVISIBLE);
                    }
                    mZoomButtonsController.setVisible(false);
                }
            }
        };
    
private voidsetupZoomButtonController(android.view.View rootView)

        mGestureDetector = new GestureDetector(this, new MyGestureListener());
        mZoomButtonsController = new ZoomButtonsController(rootView);
        mZoomButtonsController.setAutoDismissed(false);
        mZoomButtonsController.setOnZoomListener(
                new ZoomButtonsController.OnZoomListener() {
            public void onVisibilityChanged(boolean visible) {
                if (visible) {
                    updateZoomButtonsEnabled();
                }
            }

            public void onZoom(boolean zoomIn) {
                if (zoomIn) {
                    mImageViews[1].zoomIn();
                } else {
                    mImageViews[1].zoomOut();
                }
            }
        });
    
private voidshowOnScreenControls()

        mHandler.removeCallbacks(mDismissOnScreenControlsRunnable);
        updateNextPrevControls();
        updateZoomButtonsEnabled();
        mZoomButtonsController.setVisible(true);
    
private voidupdateNextPrevControls()


       
        boolean showPrev =  mCurrentPosition > 0;
        boolean showNext = mCurrentPosition < mAllImages.getCount() - 1;

        boolean prevIsVisible = mPrevImageView.getVisibility() == View.VISIBLE;
        boolean nextIsVisible = mNextImageView.getVisibility() == View.VISIBLE;

        if (showPrev && !prevIsVisible) {
            Animation a = mShowPrevImageViewAnimation;
            a.setDuration(500);
            a.startNow();
            mPrevImageView.setAnimation(a);
            mPrevImageView.setVisibility(View.VISIBLE);
        } else if (!showPrev && prevIsVisible) {
            Animation a = mHidePrevImageViewAnimation;
            a.setDuration(500);
            a.startNow();
            mPrevImageView.setAnimation(a);
            mPrevImageView.setVisibility(View.GONE);
        }

        if (showNext && !nextIsVisible) {
            Animation a = mShowNextImageViewAnimation;
            a.setDuration(500);
            a.startNow();
            mNextImageView.setAnimation(a);
            mNextImageView.setVisibility(View.VISIBLE);
        } else if (!showNext && nextIsVisible) {
            Animation a = mHideNextImageViewAnimation;
            a.setDuration(500);
            a.startNow();
            mNextImageView.setAnimation(a);
            mNextImageView.setVisibility(View.GONE);
        }
    
private voidupdateZoomButtonsEnabled()

        ImageViewTouch imageView = mImageViews[1];
        float scale = imageView.getScale();
        mZoomButtonsController.setZoomInEnabled(scale < imageView.mMaxZoom);
        mZoomButtonsController.setZoomOutEnabled(scale > 1);