package com.fruit.launcher; import android.content.Context; import android.content.SharedPreferences; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.SystemClock; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; public class HolderLayout extends ViewGroup { // ADW: Animation vars private final static int CLOSED = 1; private final static int OPEN = 2; private final static int CLOSING = 3; private final static int OPENING = 4; private int mStatus = OPEN; private boolean isAnimating; private long startTime; private float mScaleFactor; private int mIconSize = 0; private Paint mPaint; private Paint mLabelPaint; private int mBgAlpha = 255; private boolean shouldDrawLabels = false; private int mAnimationDuration = 800; private boolean mDrawLabels = true; private boolean mFadeDrawLabels = false; private float mLabelFactor; private long mCurrentTime; private float mPorcentajeScale; // ADW: listener to dispatch open/close animation events private OnFadingListener mOnFadingListener; private int distH; private int distV; private float x; private float y; private float width; private float height; private Rect rl1 = new Rect(); private Rect rl2 = new Rect(); private float scale; private Rect r3 = new Rect(); private int xx; public HolderLayout(Context context) { super(context); // TODO Auto-generated constructor stub mPaint = new Paint(); mPaint.setDither(false); mLabelPaint = new Paint(); mLabelPaint.setDither(false); setWillNotDraw(false); updateLabelVars(context); } public HolderLayout(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub mPaint = new Paint(); mPaint.setDither(false); mLabelPaint = new Paint(); mLabelPaint.setDither(false); setWillNotDraw(false); updateLabelVars(context); } public HolderLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub mPaint = new Paint(); mPaint.setDither(false); mLabelPaint = new Paint(); mLabelPaint.setDither(false); setWillNotDraw(false); updateLabelVars(context); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { // TODO Auto-generated method stub } @Override protected boolean addViewInLayout(View child, int index, LayoutParams params, boolean preventRequestLayout) { // TODO Auto-generated method stub return super .addViewInLayout(child, index, params, preventRequestLayout); } @Override protected void attachViewToParent(View child, int index, LayoutParams params) { // TODO Auto-generated method stub super.attachViewToParent(child, index, params); } @Override protected void dispatchSetPressed(boolean pressed) { // TODO Auto-generated method stub // super.dispatchSetPressed(pressed); } @Override public void dispatchSetSelected(boolean selected) { // TODO Auto-generated method stub super.dispatchSetSelected(selected); } /* * @Override public void requestChildFocus(View child, View focused) { * super.requestChildFocus(child, focused); if (child != null) { Rect r = * new Rect(); child.getDrawingRect(r); requestRectangleOnScreen(r); } } */ @Override protected void setChildrenDrawingCacheEnabled(boolean enabled) { final int count = getChildCount(); for (int i = 0; i < count; i++) { final View view = getChildAt(i); view.setDrawingCacheEnabled(enabled); // Update the drawing caches view.buildDrawingCache(true); } } @Override protected void setChildrenDrawnWithCacheEnabled(boolean enabled) { super.setChildrenDrawnWithCacheEnabled(enabled); } @Override protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) { // TODO Auto-generated method stub // super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { // Log.d("HolderLayout","INTERCEPT"); return true; } @Override public boolean onTouchEvent(MotionEvent ev) { // Log.d("HolderLayout","TOUCH"); return true; } /** * ADW: easing functions for animation */ static float easeOut(float time, float begin, float end, float duration) { float change = end - begin; return change * ((time /= duration - 1) * time * time + 1) + begin; } static float easeIn(float time, float begin, float end, float duration) { float change = end - begin; return change * (time /= duration) * time * time + begin; } static float easeInOut(float time, float begin, float end, float duration) { float change = end - begin; if ((time /= duration / 2.0f) < 1) { return change / 2.0f * time * time * time + begin; } return change / 2.0f * ((time -= 2.0f) * time * time + 2.0f) + begin; } /** * ADW: Override drawing methods to do animation */ @Override public void draw(Canvas canvas) { if (isAnimating) { if (startTime == 0) { startTime = SystemClock.uptimeMillis(); mCurrentTime = 0; } else { mCurrentTime = SystemClock.uptimeMillis() - startTime; } if (mStatus == OPENING) { mScaleFactor = easeOut(mCurrentTime, 3.0f, 1.0f, mAnimationDuration); mLabelFactor = easeOut(mCurrentTime, -1.0f, 1.0f, mAnimationDuration); } else if (mStatus == CLOSING) { mScaleFactor = easeIn(mCurrentTime, 1.0f, 3.0f, mAnimationDuration); mLabelFactor = easeIn(mCurrentTime, 1.0f, -1.0f, mAnimationDuration); } if (mLabelFactor < 0) { mLabelFactor = 0; } if (mCurrentTime >= mAnimationDuration) { isAnimating = false; if (mStatus == OPENING) { mStatus = OPEN; dispatchFadingEvent(OnFadingListener.OPEN); } else if (mStatus == CLOSING) { mStatus = CLOSED; dispatchFadingEvent(OnFadingListener.CLOSE); } } } if (mStatus != CLOSED) { shouldDrawLabels = mFadeDrawLabels && mDrawLabels && (mStatus == OPENING || mStatus == CLOSING); mPorcentajeScale = 1.0f; if (isAnimating) { mPorcentajeScale = 1.0f - ((mScaleFactor - 1) / 3.0f); if (mPorcentajeScale > 0.9f) { mPorcentajeScale = 1f; } if (mPorcentajeScale < 0) { mPorcentajeScale = 0; } dispatchFadingAlphaEvent(mPorcentajeScale); mBgAlpha = (int) (mPorcentajeScale * 255); } mPaint.setAlpha(mBgAlpha); super.draw(canvas); } } @Override protected boolean drawChild(Canvas canvas, View child, long drawingTime) { int saveCount = canvas.save(); Drawable[] tmp = ((TextView) child).getCompoundDrawables(); if (mIconSize == 0) { if (tmp[1] == null) { return false; } mIconSize = tmp[1].getIntrinsicHeight(); mIconSize = mIconSize + child.getPaddingTop(); } if (isAnimating) { postInvalidate(); // float x; // float y; distH = (child.getLeft() + (child.getWidth() / 2)) - (getWidth() / 2); distV = (child.getTop() + (child.getHeight() / 2)) - (getHeight() / 2); x = child.getLeft() + (distH * (mScaleFactor - 1)) * (mScaleFactor); y = child.getTop() + (distV * (mScaleFactor - 1)) * (mScaleFactor); width = child.getWidth() * mScaleFactor; height = (child.getHeight() - (child.getHeight() - mIconSize)) * mScaleFactor; if (shouldDrawLabels) { child.setDrawingCacheEnabled(true); } if (shouldDrawLabels && child.getDrawingCache() != null) { // ADW: try to manually draw labels rl1.set(0, mIconSize, child.getDrawingCache().getWidth(), child .getDrawingCache().getHeight()); rl2.set(child.getLeft(), child.getTop() + mIconSize, child.getLeft() + child.getDrawingCache().getWidth(), child.getTop() + child.getDrawingCache().getHeight()); mLabelPaint.setAlpha((int) (mLabelFactor * 255)); canvas.drawBitmap(child.getDrawingCache(), rl1, rl2, mLabelPaint); } scale = (width / child.getWidth()); r3 = tmp[1].getBounds(); xx = (child.getWidth() / 2) - (r3.width() / 2); canvas.save(); canvas.translate(x + xx, y + child.getPaddingTop()); canvas.scale(scale, scale); tmp[1].draw(canvas); canvas.restore(); } else { if (mDrawLabels) { child.setDrawingCacheEnabled(true); if (child.getDrawingCache() != null) { mPaint.setAlpha(255); canvas.drawBitmap(child.getDrawingCache(), child.getLeft(), child.getTop(), mPaint); } else { canvas.save(); canvas.translate(child.getLeft(), child.getTop()); child.draw(canvas); canvas.restore(); } } else { r3 = tmp[1].getBounds(); int xx = (child.getWidth() / 2) - (r3.width() / 2); canvas.save(); canvas.translate(child.getLeft() + xx, child.getTop() + child.getPaddingTop()); tmp[1].draw(canvas); canvas.restore(); } } canvas.restoreToCount(saveCount); return true; } /** * Open/close public methods */ public void open(boolean animate, int speed) { if (mStatus != OPENING) { mAnimationDuration = speed; if (animate) { isAnimating = true; mStatus = OPENING; } else { isAnimating = false; mStatus = OPEN; dispatchFadingEvent(OnFadingListener.OPEN); } startTime = 0; invalidate(); } } public void close(boolean animate, int speed) { if (mStatus != CLOSING) { mAnimationDuration = speed; if (animate) { mStatus = CLOSING; isAnimating = true; } else { mStatus = CLOSED; isAnimating = false; dispatchFadingEvent(OnFadingListener.CLOSE); } startTime = 0; invalidate(); } } /** * Interface definition for a callback to be invoked when an open/close * animation starts/ends */ public interface OnFadingListener { public static final int OPEN = 1; public static final int CLOSE = 2; void onUpdate(int Status); void onAlphaChange(float alphaPercent); } public void setOnFadingListener(OnFadingListener listener) { mOnFadingListener = listener; } /** * Dispatches a trigger event to listener. Ignored if a listener is not set. * * @param whichHandle * the handle that triggered the event. */ private void dispatchFadingEvent(int status) { if (mOnFadingListener != null) { mOnFadingListener.onUpdate(status); } } /** * Dispatches a trigger event to listener. Ignored if a listener is not set. * * @param whichHandle * the handle that triggered the event. */ private void dispatchFadingAlphaEvent(float alphaPercent) { if (mOnFadingListener != null) { mOnFadingListener.onAlphaChange(alphaPercent); } } public void updateLabelVars(Context context) { final String ALMOSTNEXUS_PREFERENCES = "launcher.preferences.almostnexus"; SharedPreferences sp = context.getSharedPreferences( ALMOSTNEXUS_PREFERENCES, Context.MODE_PRIVATE); mDrawLabels = sp.getBoolean("drawerLabels", context.getResources() .getBoolean(R.bool.config_drawerLabels)); mFadeDrawLabels = sp.getBoolean("fadeDrawerLabels", context .getResources().getBoolean(R.bool.config_fadeDrawerLabels)); } }