1/* 2 * Copyright (C) 2009 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.cooliris.media; 18 19import javax.microedition.khronos.opengles.GL11; 20 21import android.os.SystemClock; 22import android.view.MotionEvent; 23 24import com.cooliris.app.Res; 25import com.cooliris.media.RenderView.Lists; 26 27public final class ImageButton extends Layer { 28 private static final float TRACKING_MARGIN = 30.0f; 29 30 // Images for the normal and pressed states. 31 private int mImage = 0; 32 private int mPressedImage = 0; 33 34 // The action to be invoked when a single tap occurs on the button. 35 private Runnable mAction = null; 36 37 // Animation state for button crossfades. 38 private final FloatAnim mFade = new FloatAnim(1f); 39 private int mCurrentImage = 0; 40 private int mPreviousImage = 0; 41 private boolean mPressed = false; 42 43 private final int mTransparent = Res.drawable.transparent; 44 45 public void setImages(int image, int pressedImage) { 46 mImage = image; 47 mPressedImage = pressedImage; 48 if (!mPressed) { 49 setImage(image, true); 50 } 51 } 52 53 public final void setAction(Runnable action) { 54 mAction = action; 55 } 56 57 private boolean containsPoint(float x, float y, boolean addTrackingMargin) { 58 if (mImage != 0) { 59 float minX = mX; 60 float minY = mY; 61 float maxX = minX + mWidth; 62 float maxY = minY + mHeight; 63 if (addTrackingMargin) { 64 minX -= TRACKING_MARGIN; 65 minY -= TRACKING_MARGIN; 66 maxX += TRACKING_MARGIN; 67 maxY += TRACKING_MARGIN; 68 } 69 return x >= minX && y >= minY && x < maxX && y < maxY; 70 } 71 return false; 72 } 73 74 @Override 75 public void generate(RenderView view, Lists lists) { 76 lists.updateList.add(this); 77 lists.blendedList.add(this); 78 lists.hitTestList.add(this); 79 } 80 81 @Override 82 public void renderBlended(RenderView view, GL11 gl) { 83 // Get the value of the animation. 84 final float ratio = mFade.getValue(view.getFrameTime()); 85 Texture currentImage = view.getResource(mCurrentImage); 86 Texture previousImage = view.getResource(mPreviousImage); 87 Texture transparent = view.getResource(mTransparent); 88 if (currentImage == null) { 89 currentImage = transparent; 90 } 91 if (previousImage == null) { 92 previousImage = transparent; 93 } 94 if (ratio >= 0.99f) { 95 view.draw2D(currentImage, mX, mY); 96 } else { 97 view.drawMixed2D(previousImage, currentImage, ratio, mX, mY, 0f, currentImage.getWidth(), currentImage.getHeight()); 98 } 99 } 100 101 @Override 102 public boolean onTouchEvent(MotionEvent e) { 103 final int action = e.getAction(); 104 switch (action) { 105 case MotionEvent.ACTION_DOWN: 106 case MotionEvent.ACTION_MOVE: 107 final boolean hit = containsPoint(e.getX(), e.getY(), true); 108 mPressed = hit; 109 if (hit) { 110 setImage(mPressedImage, false); 111 } else { 112 setImage(mImage, true); 113 } 114 break; 115 case MotionEvent.ACTION_UP: 116 if (mPressed) { 117 if (mAction != null) 118 mAction.run(); 119 } 120 case MotionEvent.ACTION_CANCEL: 121 mPressed = false; 122 setImage(mImage, true); 123 break; 124 default: 125 break; 126 } 127 return true; 128 } 129 130 private void setImage(int image, boolean animate) { 131 if (mCurrentImage != image) { 132 if (animate) { 133 mFade.setValue(0f); 134 mFade.animateValue(1f, 0.25f, SystemClock.uptimeMillis()); // TODO: 135 // use 136 // frame 137 // clock. 138 mPreviousImage = mCurrentImage; 139 } else { 140 mFade.setValue(1f); 141 } 142 mCurrentImage = image; 143 } 144 } 145} 146