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 17 package com.android.gallery3d.ui; 18 19 import android.graphics.Bitmap; 20 import android.graphics.Canvas; 21 import android.graphics.LightingColorFilter; 22 import android.graphics.Paint; 23 24 import com.android.gallery3d.anim.FloatAnimation; 25 26 public class AdaptiveBackground extends GLView { 27 28 private static final int BACKGROUND_WIDTH = 128; 29 private static final int BACKGROUND_HEIGHT = 64; 30 private static final int FILTERED_COLOR = 0xffaaaaaa; 31 private static final int ANIMATION_DURATION = 500; 32 33 private BasicTexture mOldBackground; 34 private BasicTexture mBackground; 35 36 private final Paint mPaint; 37 private Bitmap mPendingBitmap; 38 private final FloatAnimation mAnimation = 39 new FloatAnimation(0, 1, ANIMATION_DURATION); 40 41 public AdaptiveBackground() { 42 Paint paint = new Paint(); 43 paint.setFilterBitmap(true); 44 paint.setColorFilter(new LightingColorFilter(FILTERED_COLOR, 0)); 45 mPaint = paint; 46 } 47 48 public Bitmap getAdaptiveBitmap(Bitmap bitmap) { 49 Bitmap target = Bitmap.createBitmap( 50 BACKGROUND_WIDTH, BACKGROUND_HEIGHT, Bitmap.Config.ARGB_8888); 51 Canvas canvas = new Canvas(target); 52 int width = bitmap.getWidth(); 53 int height = bitmap.getHeight(); 54 int left = 0; 55 int top = 0; 56 if (width * BACKGROUND_HEIGHT > height * BACKGROUND_WIDTH) { 57 float scale = (float) BACKGROUND_HEIGHT / height; 58 canvas.scale(scale, scale); 59 left = (BACKGROUND_WIDTH - (int) (width * scale + 0.5)) / 2; 60 } else { 61 float scale = (float) BACKGROUND_WIDTH / width; 62 canvas.scale(scale, scale); 63 top = (BACKGROUND_HEIGHT - (int) (height * scale + 0.5)) / 2; 64 } 65 canvas.drawBitmap(bitmap, left, top, mPaint); 66 BoxBlurFilter.apply(target, 67 BoxBlurFilter.MODE_REPEAT, BoxBlurFilter.MODE_CLAMP); 68 return target; 69 } 70 71 private void startTransition(Bitmap bitmap) { 72 BitmapTexture texture = new BitmapTexture(bitmap); 73 if (mBackground == null) { 74 mBackground = texture; 75 } else { 76 if (mOldBackground != null) mOldBackground.recycle(); 77 mOldBackground = mBackground; 78 mBackground = texture; 79 mAnimation.start(); 80 } 81 invalidate(); 82 } 83 84 public void setImage(Bitmap bitmap) { 85 if (mAnimation.isActive()) { 86 mPendingBitmap = bitmap; 87 } else { 88 startTransition(bitmap); 89 } 90 } 91 92 public void setScrollPosition(int position) { 93 if (mScrollX == position) return; 94 mScrollX = position; 95 invalidate(); 96 } 97 98 @Override 99 protected void render(GLCanvas canvas) { 100 if (mBackground == null) return; 101 102 int height = getHeight(); 103 float scale = (float) height / BACKGROUND_HEIGHT; 104 int width = (int) (BACKGROUND_WIDTH * scale + 0.5f); 105 int scroll = mScrollX; 106 int start = (scroll / width) * width; 107 108 if (mOldBackground == null) { 109 for (int i = start, n = scroll + getWidth(); i < n; i += width) { 110 mBackground.draw(canvas, i - scroll, 0, width, height); 111 } 112 } else { 113 boolean moreAnimation = 114 mAnimation.calculate(canvas.currentAnimationTimeMillis()); 115 float ratio = mAnimation.get(); 116 for (int i = start, n = scroll + getWidth(); i < n; i += width) { 117 canvas.drawMixed(mOldBackground, 118 mBackground, ratio, i - scroll, 0, width, height); 119 } 120 if (moreAnimation) { 121 invalidate(); 122 } else if (mPendingBitmap != null) { 123 startTransition(mPendingBitmap); 124 mPendingBitmap = null; 125 } 126 } 127 } 128 } 129