blob: 2be99ac2a01581c04faf5d9722270956944a19ef [file] [log] [blame]
The Android Open Source Project1d4c7502008-10-21 07:00:00 -07001/*
2 * Copyright (C) 2007 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.camera;
18
19import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
20import android.app.Activity;
21import android.content.Context;
22import android.graphics.Bitmap;
23import android.graphics.BitmapFactory;
24import android.graphics.Paint;
25import android.graphics.Canvas;
26import android.graphics.Matrix;
27import android.graphics.drawable.BitmapDrawable;
28import android.net.Uri;
29import android.os.Environment;
30import android.os.Handler;
31import android.os.Bundle;
32import android.util.AttributeSet;
33import android.util.Log;
34import android.view.KeyEvent;
35import android.os.Message;
36import android.view.View;
37import android.view.Window;
38import android.widget.ImageView;
39import android.widget.ViewSwitcher;
40import android.widget.Gallery.LayoutParams;
41
42import android.view.WindowManager;
43
44import java.io.File;
45import java.util.ArrayList;
46import java.util.HashMap;
47
48import com.android.camera.ImageManager.IGetBitmap_cancelable;
49import com.android.camera.ImageManager.IImage;
50import com.android.camera.ImageManager.IImageList;
51
52import android.view.MotionEvent;
53
54public class SlideShow extends Activity implements ViewSwitcher.ViewFactory
55{
56 static final private String TAG = "SlideShow";
57 static final int sLag = 2000;
58 static final int sNextImageInterval = 3000;
59 private ImageManager.IImageList mImageList;
60 private int mCurrentPosition = 0;
61 private ImageView mSwitcher;
62 private boolean mPosted = false;
The Android Open Source Project0eaec582008-12-17 18:05:54 -080063
The Android Open Source Project1d4c7502008-10-21 07:00:00 -070064 @Override
65 protected void onCreate(Bundle icicle)
66 {
67 super.onCreate(icicle);
68 Window wp = getWindow();
69 wp.setFlags(FLAG_KEEP_SCREEN_ON, FLAG_KEEP_SCREEN_ON);
The Android Open Source Project0eaec582008-12-17 18:05:54 -080070
The Android Open Source Project1d4c7502008-10-21 07:00:00 -070071 setContentView(R.layout.slide_show);
The Android Open Source Project0eaec582008-12-17 18:05:54 -080072
The Android Open Source Project1d4c7502008-10-21 07:00:00 -070073 mSwitcher = (ImageView)findViewById(R.id.imageview);
74 if (android.util.Config.LOGV)
75 Log.v(TAG, "mSwitcher " + mSwitcher);
76 }
The Android Open Source Project0eaec582008-12-17 18:05:54 -080077
The Android Open Source Project1d4c7502008-10-21 07:00:00 -070078 @Override
79 protected void onResume()
80 {
81 super.onResume();
82
83 if (mImageList == null) {
84 mImageList = new FileImageList();
85 mCurrentPosition = 0;
86 }
87 loadImage();
88 }
The Android Open Source Project0eaec582008-12-17 18:05:54 -080089
The Android Open Source Project1d4c7502008-10-21 07:00:00 -070090 @Override
91 protected void onPause() {
92 super.onPause();
93 cancelPost();
94 }
The Android Open Source Project0eaec582008-12-17 18:05:54 -080095
The Android Open Source Project1d4c7502008-10-21 07:00:00 -070096 static public class ImageViewTouch extends ImageView {
97 class xy {
98 public xy(float xIn, float yIn) {
99 x = xIn;
100 y = yIn;
101 timeAdded = System.currentTimeMillis();
102 }
103 public xy(MotionEvent e) {
104 x = e.getX();
105 y = e.getY();
106 timeAdded = System.currentTimeMillis();
107 }
108 float x,y;
109 long timeAdded;
110 }
The Android Open Source Project0eaec582008-12-17 18:05:54 -0800111
The Android Open Source Project1d4c7502008-10-21 07:00:00 -0700112 SlideShow mSlideShow;
113 Paint mPaints[] = new Paint[1];
114 ArrayList<xy> mPoints = new ArrayList<xy>();
115 boolean mDown;
The Android Open Source Project0eaec582008-12-17 18:05:54 -0800116
The Android Open Source Project1d4c7502008-10-21 07:00:00 -0700117 public ImageViewTouch(Context context) {
118 super(context);
119 mSlideShow = (SlideShow) context;
120 setScaleType(ImageView.ScaleType.CENTER);
121 setupPaint();
122 }
The Android Open Source Project0eaec582008-12-17 18:05:54 -0800123
The Android Open Source Project1d4c7502008-10-21 07:00:00 -0700124 public ImageViewTouch(Context context, AttributeSet attrs) {
125 super(context, attrs);
126 mSlideShow = (SlideShow) context;
127 setScaleType(ImageView.ScaleType.CENTER);
128 setupPaint();
129 }
The Android Open Source Project0eaec582008-12-17 18:05:54 -0800130
The Android Open Source Project1d4c7502008-10-21 07:00:00 -0700131 private void setupPaint() {
132 for (int i = 0; i < mPaints.length; i++) {
133 Paint p = new Paint();
134 p.setARGB(255, 255, 255, 0);
135 p.setAntiAlias(true);
136 p.setStyle(Paint.Style.FILL);
137 p.setStrokeWidth(3F);
138 mPaints[i] = p;
139 }
140 }
The Android Open Source Project0eaec582008-12-17 18:05:54 -0800141
The Android Open Source Project1d4c7502008-10-21 07:00:00 -0700142 private void addEvent(MotionEvent event) {
143 long now = System.currentTimeMillis();
144 mPoints.add(new xy(event));
145 for (int i = 0; i < event.getHistorySize(); i++)
146 mPoints.add(new xy(event.getHistoricalX(i), event.getHistoricalY(i)));
147 while (mPoints.size() > 0) {
148 xy ev = mPoints.get(0);
149 if (now - ev.timeAdded < sLag)
150 break;
151 mPoints.remove(0);
152 }
153 }
The Android Open Source Project0eaec582008-12-17 18:05:54 -0800154
The Android Open Source Project1d4c7502008-10-21 07:00:00 -0700155 public boolean onTouchEvent(MotionEvent event) {
156 addEvent(event);
157 switch (event.getAction()) {
158 case MotionEvent.ACTION_DOWN:
159 mDown = true;
160 mSlideShow.cancelPost();
161 postInvalidate();
162 break;
163 case MotionEvent.ACTION_UP:
164 mDown = false;
165 postInvalidate();
166 break;
167 case MotionEvent.ACTION_MOVE:
168 mSlideShow.cancelPost();
169 postInvalidate();
170 break;
171 }
172 return true;
173 }
174
175 protected void onDraw(Canvas canvas) {
176 super.onDraw(canvas);
177
178 boolean didPaint = false;
179 long now = System.currentTimeMillis();
180 for (xy ev: mPoints) {
181 Paint p = mPaints[0];
182 long delta = now - ev.timeAdded;
183 if (delta > sLag)
184 continue;
The Android Open Source Project0eaec582008-12-17 18:05:54 -0800185
The Android Open Source Project1d4c7502008-10-21 07:00:00 -0700186 int alpha2 = Math.max(0, 255 - (255 * (int)delta / sLag));
187 if (alpha2 == 0)
188 continue;
189 p.setAlpha(alpha2);
190 canvas.drawCircle(ev.x, ev.y, 2, p);
191 didPaint = true;
192 }
193 if (didPaint && !mDown)
194 postInvalidate();
195 }
196 }
197
The Android Open Source Project0eaec582008-12-17 18:05:54 -0800198
The Android Open Source Project1d4c7502008-10-21 07:00:00 -0700199 @Override
200 public boolean onKeyDown(int keyCode, KeyEvent event) {
201 switch (keyCode) {
202 case KeyEvent.KEYCODE_DPAD_LEFT:
203 cancelPost();
204 loadPreviousImage();
205 return true;
The Android Open Source Project0eaec582008-12-17 18:05:54 -0800206
The Android Open Source Project1d4c7502008-10-21 07:00:00 -0700207 case KeyEvent.KEYCODE_DPAD_RIGHT:
208 cancelPost();
209 loadNextImage();
210 return true;
The Android Open Source Project0eaec582008-12-17 18:05:54 -0800211
The Android Open Source Project1d4c7502008-10-21 07:00:00 -0700212 case KeyEvent.KEYCODE_DPAD_CENTER:
The Android Open Source Project0eaec582008-12-17 18:05:54 -0800213 if (mPosted)
The Android Open Source Project1d4c7502008-10-21 07:00:00 -0700214 cancelPost();
215 else
216 loadNextImage();
217 return true;
218 }
219 return super.onKeyDown(keyCode, event);
220 }
The Android Open Source Project0eaec582008-12-17 18:05:54 -0800221
The Android Open Source Project1d4c7502008-10-21 07:00:00 -0700222 private void cancelPost() {
223 mHandler.removeCallbacks(mNextImageRunnable);
224 mPosted = false;
225 }
The Android Open Source Project0eaec582008-12-17 18:05:54 -0800226
The Android Open Source Project1d4c7502008-10-21 07:00:00 -0700227 private void post() {
228 mHandler.postDelayed(mNextImageRunnable, sNextImageInterval);
229 mPosted = true;
230 }
231
232 private void loadImage() {
233 ImageManager.IImage image = mImageList.getImageAt(mCurrentPosition);
234 if (image == null)
235 return;
The Android Open Source Project0eaec582008-12-17 18:05:54 -0800236
The Android Open Source Project1d4c7502008-10-21 07:00:00 -0700237 Bitmap bitmap = image.thumbBitmap();
238 if (bitmap == null)
239 return;
240
241 mSwitcher.setImageDrawable(new BitmapDrawable(bitmap));
242 post();
243 }
The Android Open Source Project0eaec582008-12-17 18:05:54 -0800244
The Android Open Source Project1d4c7502008-10-21 07:00:00 -0700245 private Runnable mNextImageRunnable = new Runnable() {
246 public void run() {
247 if (android.util.Config.LOGV)
248 Log.v(TAG, "mNextImagerunnable called");
249 loadNextImage();
250 }
251 };
The Android Open Source Project0eaec582008-12-17 18:05:54 -0800252
The Android Open Source Project1d4c7502008-10-21 07:00:00 -0700253 private void loadNextImage() {
254 if (++mCurrentPosition >= mImageList.getCount())
255 mCurrentPosition = 0;
256 loadImage();
257 }
The Android Open Source Project0eaec582008-12-17 18:05:54 -0800258
The Android Open Source Project1d4c7502008-10-21 07:00:00 -0700259 private void loadPreviousImage() {
260 if (mCurrentPosition == 0)
261 mCurrentPosition = mImageList.getCount() - 1;
262 else
263 mCurrentPosition -= 1;
264
265 loadImage();
266 }
267
268 public View makeView() {
269 ImageView i = new ImageView(this);
270 i.setBackgroundColor(0xFF000000);
271 i.setScaleType(ImageView.ScaleType.FIT_CENTER);
272 i.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
273 return i;
274 }
The Android Open Source Project0eaec582008-12-17 18:05:54 -0800275
The Android Open Source Project1d4c7502008-10-21 07:00:00 -0700276 private final Handler mHandler = new Handler() {
277 @Override
278 public void handleMessage(Message msg) {
279 }
280 };
281
282 class FileImageList implements IImageList {
283 public HashMap<String, String> getBucketIds() {
284 throw new UnsupportedOperationException();
285 }
286
287 public void checkThumbnails(ThumbCheckCallback cb) {
288 // TODO Auto-generated method stub
The Android Open Source Project0eaec582008-12-17 18:05:54 -0800289
The Android Open Source Project1d4c7502008-10-21 07:00:00 -0700290 }
291
292 public void commitChanges() {
293 // TODO Auto-generated method stub
The Android Open Source Project0eaec582008-12-17 18:05:54 -0800294
The Android Open Source Project1d4c7502008-10-21 07:00:00 -0700295 }
296
297 public void removeOnChangeListener(OnChange changeCallback) {
298 // TODO Auto-generated method stub
The Android Open Source Project0eaec582008-12-17 18:05:54 -0800299
The Android Open Source Project1d4c7502008-10-21 07:00:00 -0700300 }
301
302 public void setOnChangeListener(OnChange changeCallback, Handler h) {
303 // TODO Auto-generated method stub
The Android Open Source Project0eaec582008-12-17 18:05:54 -0800304
The Android Open Source Project1d4c7502008-10-21 07:00:00 -0700305 }
306
307 private ArrayList<FileImage> mImages = new ArrayList<FileImage>();
308 // image uri ==> Image object
309 private HashMap<Long, IImage> mCache = new HashMap<Long, IImage>();
310
311 class FileImage extends ImageManager.SimpleBaseImage {
312 long mId;
313 String mPath;
314
315 FileImage(long id, String path) {
316 mId = id;
317 mPath = path;
318 }
319
320 public long imageId() {
321 return mId;
322 }
The Android Open Source Project0eaec582008-12-17 18:05:54 -0800323
The Android Open Source Project1d4c7502008-10-21 07:00:00 -0700324 public String getDataPath() {
325 return mPath;
326 }
327
328 public Bitmap fullSizeBitmap(int targetWidthOrHeight) {
329 return BitmapFactory.decodeFile(mPath);
330 }
331
332 public IGetBitmap_cancelable fullSizeBitmap_cancelable(int targetWidthOrHeight) {
333 return null;
334 }
The Android Open Source Project0eaec582008-12-17 18:05:54 -0800335
The Android Open Source Project1d4c7502008-10-21 07:00:00 -0700336 public Bitmap thumbBitmap() {
337 Bitmap b = fullSizeBitmap(320);
338 Matrix m = new Matrix();
339 float scale = 320F / (float) b.getWidth();
340 m.setScale(scale, scale);
341 Bitmap scaledBitmap = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, true);
342 return scaledBitmap;
343 }
The Android Open Source Project0eaec582008-12-17 18:05:54 -0800344
The Android Open Source Project1d4c7502008-10-21 07:00:00 -0700345 public Bitmap miniThumbBitmap() {
346 return thumbBitmap();
347 }
348
349 public long fullSizeImageId() {
350 return mId;
351 }
352 }
353
354 private void enumerate(String path, ArrayList<String> list) {
355 File f = new File(path);
356 if (f.isDirectory()) {
357 String [] children = f.list();
358 if (children != null) {
359 for (int i = 0; i < children.length; i++) {
360 if (children[i].charAt(0) != '.')
361 enumerate(path + "/" + children[i], list);
362 }
363 }
364 } else {
365 if (path.endsWith(".jpeg") || path.endsWith(".jpg") || path.endsWith(".png")) {
366 if (f.length() > 0) {
367 list.add(path);
368 }
369 }
370 }
371 }
372
373 public FileImageList() {
374 ArrayList<String> list = new ArrayList<String>();
375 enumerate(Environment.getExternalStorageDirectory().getPath(), list);
376 enumerate("/data/images", list);
377
378 for (int i = 0; i < list.size(); i++) {
379 FileImage img = new FileImage(i, list.get(i));
380 mCache.put((long)i, img);
381 mImages.add(img);
382 }
383 }
384
385 public IImage getImageAt(int i) {
386 if (i >= mImages.size())
387 return null;
388
389 return mImages.get(i);
390 }
391
392 public IImage getImageForUri(Uri uri) {
393 // TODO make this a hash lookup
394 int count = getCount();
395 for (int i = 0; i < count; i++) {
396 IImage image = getImageAt(i);
397 if (image.fullSizeImageUri().equals(uri)) {
398 return image;
399 }
400 }
401 return null;
402 }
403
404 public IImage getImageWithId(long id) {
405 throw new UnsupportedOperationException();
406 }
407
408 public void removeImageAt(int i) {
409 throw new UnsupportedOperationException();
410 }
411
412 public boolean removeImage(IImage image) {
413 throw new UnsupportedOperationException();
414 }
415
416 public int getCount() {
417 return mImages.size();
418 }
The Android Open Source Project0eaec582008-12-17 18:05:54 -0800419
420 public boolean isEmpty() {
421 return mImages.isEmpty();
422 }
423
The Android Open Source Project1d4c7502008-10-21 07:00:00 -0700424 public void deactivate() {
425 // nothing to do here
426 }
427 }
428
429}