1 package com.cooliris.wallpaper;
3 //import android.app.Service;
4 import com.cooliris.media.Vector3f;
6 import android.content.Context;
7 import android.graphics.Bitmap;
8 import android.graphics.Canvas;
9 import android.graphics.Color;
10 import android.graphics.Paint;
11 import android.graphics.PorterDuffColorFilter;
12 import android.graphics.Rect;
13 import android.graphics.RectF;
14 import android.os.Handler;
15 import android.os.SystemClock;
16 import android.view.SurfaceHolder;
17 import android.view.SurfaceView;
18 import android.graphics.PorterDuff.Mode;
20 public class Slideshow extends SurfaceView implements SurfaceHolder.Callback {
21 public Slideshow(Context context) {
23 SurfaceHolder holder = getHolder();
24 holder.addCallback(this);
27 public static final int SLIDESHOW_DURATION = 2000;
29 public interface DataSource {
32 * @param currentSlideshowCounter
35 Bitmap getBitmapForIndex(Context context, int currentSlideshowCounter);
38 private final Handler mHandler = new Handler();
39 private final Runnable mDrawFrame = new Runnable() {
44 private static final Paint sPaint = new Paint();
46 sPaint.setFilterBitmap(true);
47 sPaint.setDither(true);
49 private boolean mVisible = true;
50 private DataSource mSource;
51 private int mCurrentSlideshowCounter;
52 private Bitmap mBitmap;
54 private RectF mFrameRect;
55 private static final Vector3f sGrow = new Vector3f();
56 private Bitmap mQueuedBitmap;
57 private Rect mQueuedRect;
58 private RectF mQueuedFrameRect;
59 private static final Vector3f sQueuedGrow = new Vector3f();
61 private long mPrevTime;
62 private long mTimeElapsed;
64 public void setDataSource(DataSource source) {
68 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
69 mHandler.post(mDrawFrame);
70 if (mBitmap != null) {
71 mRect = getRectToFitBitmap(mBitmap.getWidth(), mBitmap.getHeight(), width, height);
72 mFrameRect.right = width;
73 mFrameRect.bottom = height;
75 if (mQueuedBitmap != null) {
76 mQueuedRect = getRectToFitBitmap(mQueuedBitmap.getWidth(), mQueuedBitmap.getHeight(), width, height);
77 mQueuedFrameRect.right = width;
78 mQueuedFrameRect.bottom = height;
82 public void surfaceCreated(SurfaceHolder holder) {
83 // We may need to make calls to super once this is a subclass of WallpaperService.
84 mHandler.post(mDrawFrame);
87 public void surfaceDestroyed(SurfaceHolder holder) {
91 public void drawFrame() {
92 final SurfaceHolder holder = getHolder();
93 Rect frame = holder.getSurfaceFrame();
94 final Paint paint = sPaint;
97 c = holder.lockCanvas();
99 long now = SystemClock.uptimeMillis();
100 long delta = now - mPrevTime;
103 mTimeElapsed += delta;
105 performSetup(frame.width(), frame.height());
106 // We draw the source bitmap
107 if (mBitmap != null) {
108 if (mTimeElapsed > SLIDESHOW_DURATION) {
109 float alpha = ((float)(mTimeElapsed - SLIDESHOW_DURATION)) / 2000.0f;
110 paint.setColorFilter(null);
112 //int val = (int)(255 * (1.0f - alpha));
113 //int srcColor = Color.argb(val, 0, 0, 0);
114 //PorterDuffColorFilter colorFilter = new PorterDuffColorFilter(srcColor, Mode.SRC_IN);
115 //paint.setColorFilter(null);
117 c.drawBitmap(mBitmap, mRect, mFrameRect, paint);
119 int val = (int)(255 * alpha);
120 int srcColor = Color.argb(val, 0, 0, 0);
121 PorterDuffColorFilter colorFilter = new PorterDuffColorFilter(srcColor, Mode.DST_IN);
122 paint.setColorFilter(colorFilter);
125 c.drawBitmap(mQueuedBitmap, mQueuedRect, mQueuedFrameRect, paint);
126 performUpdate(mQueuedFrameRect, sQueuedGrow, delta);
128 // We switch the image.
130 mBitmap = mQueuedBitmap;
131 mFrameRect = mQueuedFrameRect;
132 sGrow.set(sQueuedGrow);
133 mQueuedBitmap = null;
135 mQueuedFrameRect = null;
139 paint.setColorFilter(null);
140 c.drawBitmap(mBitmap, mRect, mFrameRect, paint);
142 performUpdate(mFrameRect, sGrow, delta);
148 holder.unlockCanvasAndPost(c);
150 mHandler.removeCallbacks(mDrawFrame);
152 mHandler.postDelayed(mDrawFrame, 20);
156 private void performUpdate(RectF rect, Vector3f grow, long delta) {
157 float timeElapsed = ((float)(delta)) / 1000.0f;
158 float amountToGrowX = timeElapsed * (rect.width() / 15.0f);
159 float amountToGrowY = amountToGrowX * (rect.height() / rect.width());
160 rect.top -= amountToGrowY * grow.x;
161 rect.left -= amountToGrowX * grow.y;
163 rect.bottom += amountToGrowY * (1 - grow.x);
164 rect.right += amountToGrowX * (1 - grow.y);
167 private void performSetup(int viewWidth, int viewHeight) {
168 if (mBitmap == null) {
169 mBitmap = getRandomBitmap();
170 if (mBitmap != null) {
171 mRect = getRectToFitBitmap(mBitmap.getWidth(), mBitmap.getHeight(), viewWidth, viewHeight);
172 mFrameRect = new RectF();
173 mFrameRect.right = viewWidth;
174 mFrameRect.bottom = viewHeight;
175 sGrow.set((float)Math.random(), (float)Math.random(), 0);
178 if (mQueuedBitmap == null) {
179 mQueuedBitmap = getRandomBitmap();
180 if (mQueuedBitmap == null) {
181 mQueuedBitmap = mBitmap;
183 if (mQueuedBitmap != null) {
184 mQueuedRect = getRectToFitBitmap(mQueuedBitmap.getWidth(), mQueuedBitmap.getHeight(), viewWidth, viewHeight);
185 mQueuedFrameRect = new RectF();
186 mQueuedFrameRect.right = viewWidth;
187 mQueuedFrameRect.bottom = viewHeight;
188 sQueuedGrow.set((float)Math.random(), (float)Math.random(), 0);
193 private Rect getRectToFitBitmap(int bitmapWidth, int bitmapHeight, int viewWidth, int viewHeight) {
194 Rect rect = new Rect();
195 float viewAspect = (float)viewHeight / viewWidth;
196 float newWidth = bitmapWidth * viewAspect;
197 if (bitmapHeight < newWidth) {
198 // Vertically constrained.
199 newWidth = bitmapHeight / viewAspect;
200 rect.set((int)(bitmapWidth/2 - newWidth/2), 0, (int)(bitmapWidth/2 + newWidth/2), bitmapHeight);
202 // Horizontally constrained
203 float newHeight = bitmapWidth * viewAspect;
204 rect.set(0, (int)(bitmapHeight/2 - newHeight/2), bitmapWidth, (int)(bitmapHeight/2 + newHeight/2));
209 private Bitmap getRandomBitmap() {
210 if (mSource != null) {
211 return mSource.getBitmapForIndex(getContext(), mCurrentSlideshowCounter++);
216 public void onVisibilityChanged(boolean visible) {
219 mHandler.removeCallbacks(mDrawFrame);