/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.camera; import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Paint; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.drawable.BitmapDrawable; import android.net.Uri; import android.os.Environment; import android.os.Handler; import android.os.Bundle; import android.util.AttributeSet; import android.util.Log; import android.view.KeyEvent; import android.os.Message; import android.view.View; import android.view.Window; import android.widget.ImageView; import android.widget.ViewSwitcher; import android.widget.Gallery.LayoutParams; import android.view.WindowManager; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import com.android.camera.ImageManager.IGetBitmap_cancelable; import com.android.camera.ImageManager.IImage; import com.android.camera.ImageManager.IImageList; import android.view.MotionEvent; public class SlideShow extends Activity implements ViewSwitcher.ViewFactory { static final private String TAG = "SlideShow"; static final int sLag = 2000; static final int sNextImageInterval = 3000; private ImageManager.IImageList mImageList; private int mCurrentPosition = 0; private ImageView mSwitcher; private boolean mPosted = false; @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); Window wp = getWindow(); wp.setFlags(FLAG_KEEP_SCREEN_ON, FLAG_KEEP_SCREEN_ON); setContentView(R.layout.slide_show); mSwitcher = (ImageView)findViewById(R.id.imageview); if (android.util.Config.LOGV) Log.v(TAG, "mSwitcher " + mSwitcher); } @Override protected void onResume() { super.onResume(); if (mImageList == null) { mImageList = new FileImageList(); mCurrentPosition = 0; } loadImage(); } @Override protected void onPause() { super.onPause(); cancelPost(); } static public class ImageViewTouch extends ImageView { class xy { public xy(float xIn, float yIn) { x = xIn; y = yIn; timeAdded = System.currentTimeMillis(); } public xy(MotionEvent e) { x = e.getX(); y = e.getY(); timeAdded = System.currentTimeMillis(); } float x,y; long timeAdded; } SlideShow mSlideShow; Paint mPaints[] = new Paint[1]; ArrayList mPoints = new ArrayList(); boolean mDown; public ImageViewTouch(Context context) { super(context); mSlideShow = (SlideShow) context; setScaleType(ImageView.ScaleType.CENTER); setupPaint(); } public ImageViewTouch(Context context, AttributeSet attrs) { super(context, attrs); mSlideShow = (SlideShow) context; setScaleType(ImageView.ScaleType.CENTER); setupPaint(); } private void setupPaint() { for (int i = 0; i < mPaints.length; i++) { Paint p = new Paint(); p.setARGB(255, 255, 255, 0); p.setAntiAlias(true); p.setStyle(Paint.Style.FILL); p.setStrokeWidth(3F); mPaints[i] = p; } } private void addEvent(MotionEvent event) { long now = System.currentTimeMillis(); mPoints.add(new xy(event)); for (int i = 0; i < event.getHistorySize(); i++) mPoints.add(new xy(event.getHistoricalX(i), event.getHistoricalY(i))); while (mPoints.size() > 0) { xy ev = mPoints.get(0); if (now - ev.timeAdded < sLag) break; mPoints.remove(0); } } public boolean onTouchEvent(MotionEvent event) { addEvent(event); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mDown = true; mSlideShow.cancelPost(); postInvalidate(); break; case MotionEvent.ACTION_UP: mDown = false; postInvalidate(); break; case MotionEvent.ACTION_MOVE: mSlideShow.cancelPost(); postInvalidate(); break; } return true; } protected void onDraw(Canvas canvas) { super.onDraw(canvas); boolean didPaint = false; long now = System.currentTimeMillis(); for (xy ev: mPoints) { Paint p = mPaints[0]; long delta = now - ev.timeAdded; if (delta > sLag) continue; int alpha2 = Math.max(0, 255 - (255 * (int)delta / sLag)); if (alpha2 == 0) continue; p.setAlpha(alpha2); canvas.drawCircle(ev.x, ev.y, 2, p); didPaint = true; } if (didPaint && !mDown) postInvalidate(); } } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_DPAD_LEFT: cancelPost(); loadPreviousImage(); return true; case KeyEvent.KEYCODE_DPAD_RIGHT: cancelPost(); loadNextImage(); return true; case KeyEvent.KEYCODE_DPAD_CENTER: if (mPosted) cancelPost(); else loadNextImage(); return true; } return super.onKeyDown(keyCode, event); } private void cancelPost() { mHandler.removeCallbacks(mNextImageRunnable); mPosted = false; } private void post() { mHandler.postDelayed(mNextImageRunnable, sNextImageInterval); mPosted = true; } private void loadImage() { ImageManager.IImage image = mImageList.getImageAt(mCurrentPosition); if (image == null) return; Bitmap bitmap = image.thumbBitmap(); if (bitmap == null) return; mSwitcher.setImageDrawable(new BitmapDrawable(bitmap)); post(); } private Runnable mNextImageRunnable = new Runnable() { public void run() { if (android.util.Config.LOGV) Log.v(TAG, "mNextImagerunnable called"); loadNextImage(); } }; private void loadNextImage() { if (++mCurrentPosition >= mImageList.getCount()) mCurrentPosition = 0; loadImage(); } private void loadPreviousImage() { if (mCurrentPosition == 0) mCurrentPosition = mImageList.getCount() - 1; else mCurrentPosition -= 1; loadImage(); } public View makeView() { ImageView i = new ImageView(this); i.setBackgroundColor(0xFF000000); i.setScaleType(ImageView.ScaleType.FIT_CENTER); i.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); return i; } private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { } }; class FileImageList implements IImageList { public HashMap getBucketIds() { throw new UnsupportedOperationException(); } public void checkThumbnails(ThumbCheckCallback cb, int totalThumbnails) { // TODO Auto-generated method stub } public void commitChanges() { // TODO Auto-generated method stub } public void removeOnChangeListener(OnChange changeCallback) { // TODO Auto-generated method stub } public void setOnChangeListener(OnChange changeCallback, Handler h) { // TODO Auto-generated method stub } private ArrayList mImages = new ArrayList(); // image uri ==> Image object private HashMap mCache = new HashMap(); class FileImage extends ImageManager.SimpleBaseImage { long mId; String mPath; FileImage(long id, String path) { mId = id; mPath = path; } public long imageId() { return mId; } public String getDataPath() { return mPath; } public Bitmap fullSizeBitmap(int targetWidthOrHeight) { return BitmapFactory.decodeFile(mPath); } public IGetBitmap_cancelable fullSizeBitmap_cancelable(int targetWidthOrHeight) { return null; } public Bitmap thumbBitmap() { Bitmap b = fullSizeBitmap(320); Matrix m = new Matrix(); float scale = 320F / (float) b.getWidth(); m.setScale(scale, scale); Bitmap scaledBitmap = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, true); return scaledBitmap; } public Bitmap miniThumbBitmap() { return thumbBitmap(); } public long fullSizeImageId() { return mId; } } private void enumerate(String path, ArrayList list) { File f = new File(path); if (f.isDirectory()) { String [] children = f.list(); if (children != null) { for (int i = 0; i < children.length; i++) { if (children[i].charAt(0) != '.') enumerate(path + "/" + children[i], list); } } } else { if (path.endsWith(".jpeg") || path.endsWith(".jpg") || path.endsWith(".png")) { if (f.length() > 0) { list.add(path); } } } } public FileImageList() { ArrayList list = new ArrayList(); enumerate(Environment.getExternalStorageDirectory().getPath(), list); enumerate("/data/images", list); for (int i = 0; i < list.size(); i++) { FileImage img = new FileImage(i, list.get(i)); mCache.put((long)i, img); mImages.add(img); } } public IImage getImageAt(int i) { if (i >= mImages.size()) return null; return mImages.get(i); } public IImage getImageForUri(Uri uri) { // TODO make this a hash lookup int count = getCount(); for (int i = 0; i < count; i++) { IImage image = getImageAt(i); if (image.fullSizeImageUri().equals(uri)) { return image; } } return null; } public IImage getImageWithId(long id) { throw new UnsupportedOperationException(); } public void removeImageAt(int i) { throw new UnsupportedOperationException(); } public boolean removeImage(IImage image) { throw new UnsupportedOperationException(); } public int getCount() { return mImages.size(); } public boolean isEmpty() { return mImages.isEmpty(); } public void deactivate() { // nothing to do here } } }