diff options
author | Michael Jurka <mikejurka@google.com> | 2010-12-14 16:46:39 -0800 |
---|---|---|
committer | Michael Jurka <mikejurka@google.com> | 2010-12-15 21:18:17 -0800 |
commit | 38b4f7c5eab773ad36048b5ab8713750dcaaf748 (patch) | |
tree | 68f28e9d9a7fcd279cd53eb5ea994b3e64186fee | |
parent | 760e5375f003accf04f789e90a919ed476d4c335 (diff) | |
download | packages_apps_trebuchet-38b4f7c5eab773ad36048b5ab8713750dcaaf748.zip packages_apps_trebuchet-38b4f7c5eab773ad36048b5ab8713750dcaaf748.tar.gz packages_apps_trebuchet-38b4f7c5eab773ad36048b5ab8713750dcaaf748.tar.bz2 |
holo look for pressed/focused workspace icons
Change-Id: Ia964c868afd200be3828e4397659391f857599e6
-rw-r--r-- | res/drawable/shortcut_selector.xml | 25 | ||||
-rw-r--r-- | res/values/colors.xml | 5 | ||||
-rw-r--r-- | res/values/styles.xml | 1 | ||||
-rw-r--r-- | src/com/android/launcher2/BubbleTextView.java | 144 | ||||
-rw-r--r-- | src/com/android/launcher2/HolographicOutlineHelper.java | 66 | ||||
-rw-r--r-- | src/com/android/launcher2/Workspace.java | 6 |
6 files changed, 189 insertions, 58 deletions
diff --git a/res/drawable/shortcut_selector.xml b/res/drawable/shortcut_selector.xml deleted file mode 100644 index 8059f00..0000000 --- a/res/drawable/shortcut_selector.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:state_window_focused="true" android:state_focused="true" android:drawable="@drawable/focused_application_background" /> - <item android:state_pressed="true" android:drawable="@drawable/pressed_application_background" /> - <item android:drawable="@android:color/transparent" /> -</selector> diff --git a/res/values/colors.xml b/res/values/colors.xml index 57f8bfc..4abbd50 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -33,4 +33,9 @@ <color name="dimmed_view_color">#FF7F7F7F</color> <color name="drag_outline_color">#9DBE12</color> + + <color name="workspace_item_pressed_outline_color">#6595f9</color> + <color name="workspace_item_pressed_glow_color">#0997ff</color> + <color name="workspace_item_focused_outline_color">#6595f9</color> + <color name="workspace_item_focused_glow_color">#0997ff</color> </resources> diff --git a/res/values/styles.xml b/res/values/styles.xml index 1e2dba2..7592a15 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -44,7 +44,6 @@ <item name="android:gravity">center_horizontal</item> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">match_parent</item> - <item name="android:background">@drawable/shortcut_selector</item> <item name="android:paddingLeft">5dip</item> <item name="android:paddingRight">5dip</item> </style> diff --git a/src/com/android/launcher2/BubbleTextView.java b/src/com/android/launcher2/BubbleTextView.java index 995877b..6e2a58b 100644 --- a/src/com/android/launcher2/BubbleTextView.java +++ b/src/com/android/launcher2/BubbleTextView.java @@ -16,18 +16,19 @@ package com.android.launcher2; +import com.android.launcher.R; + import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; -import android.graphics.RectF; +import android.graphics.Rect; +import android.graphics.Region.Op; import android.graphics.drawable.Drawable; -import android.text.Layout; import android.util.AttributeSet; - -import com.android.launcher.R; +import android.view.MotionEvent; /** * TextView that draws a bubble behind the text. We cannot use a LineBackgroundSpan @@ -44,16 +45,23 @@ public class BubbleTextView extends CacheableTextView { static final float PADDING_H = 8.0f; static final float PADDING_V = 3.0f; - private final RectF mRect = new RectF(); private Paint mPaint; private float mBubbleColorAlpha; private int mPrevAlpha = -1; + private final HolographicOutlineHelper mOutlineHelper = new HolographicOutlineHelper(); + private final Canvas mTempCanvas = new Canvas(); + private final Rect mTempRect = new Rect(); + private final Paint mTempPaint = new Paint(); + private boolean mDidInvalidateForPressedState; + private Bitmap mPressedOrFocusedBackground; + private int mFocusedOutlineColor; + private int mFocusedGlowColor; + private int mPressedOutlineColor; + private int mPressedGlowColor; + private boolean mBackgroundSizeChanged; private Drawable mBackground; - private float mCornerRadius; - private float mPaddingH; - private float mPaddingV; public BubbleTextView(Context context) { super(context); @@ -80,12 +88,13 @@ public class BubbleTextView extends CacheableTextView { mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setColor(bubbleColor); mBubbleColorAlpha = Color.alpha(bubbleColor) / 255.0f; - - final float scale = res.getDisplayMetrics().density; - mCornerRadius = CORNER_RADIUS * scale; - mPaddingH = PADDING_H * scale; - //noinspection PointlessArithmeticExpression - mPaddingV = PADDING_V * scale; + mFocusedOutlineColor = + getResources().getColor(R.color.workspace_item_focused_outline_color); + mFocusedGlowColor = getResources().getColor(R.color.workspace_item_focused_glow_color); + mPressedOutlineColor = + getResources().getColor(R.color.workspace_item_pressed_outline_color); + mPressedGlowColor = + getResources().getColor(R.color.workspace_item_pressed_glow_color); } protected int getCacheTopPadding() { @@ -110,7 +119,6 @@ public class BubbleTextView extends CacheableTextView { setText(info.title); buildAndEnableCache(); setTag(info); - } @Override @@ -128,6 +136,28 @@ public class BubbleTextView extends CacheableTextView { @Override protected void drawableStateChanged() { + if (isPressed()) { + // In this case, we have already created the pressed outline on ACTION_DOWN, + // so we just need to do an invalidate to trigger draw + if (!mDidInvalidateForPressedState) { + invalidate(); + } + } else { + // Otherwise, either clear the pressed/focused background, or create a background + // for the focused state + final boolean backgroundEmptyBefore = mPressedOrFocusedBackground == null; + mPressedOrFocusedBackground = null; + if (isFocused()) { + mPressedOrFocusedBackground = createGlowingOutline( + mTempCanvas, mFocusedGlowColor, mFocusedOutlineColor); + invalidate(); + } + final boolean backgroundEmptyNow = mPressedOrFocusedBackground == null; + if (!backgroundEmptyBefore && backgroundEmptyNow) { + invalidate(); + } + } + Drawable d = mBackground; if (d != null && d.isStateful()) { d.setState(getDrawableState()); @@ -135,8 +165,91 @@ public class BubbleTextView extends CacheableTextView { super.drawableStateChanged(); } + /** + * Draw the View v into the given Canvas. + * + * @param v the view to draw + * @param destCanvas the canvas to draw on + * @param padding the horizontal and vertical padding to use when drawing + */ + private void drawWithPadding(Canvas destCanvas, int padding) { + final Rect clipRect = mTempRect; + getDrawingRect(clipRect); + + // adjust the clip rect so that we don't include the text label + clipRect.bottom = + getExtendedPaddingTop() - (int) BubbleTextView.PADDING_V + getLayout().getLineTop(0); + + // Draw the View into the bitmap. + // The translate of scrollX and scrollY is necessary when drawing TextViews, because + // they set scrollX and scrollY to large values to achieve centered text + destCanvas.save(); + destCanvas.translate(-getScrollX() + padding / 2, -getScrollY() + padding / 2); + destCanvas.clipRect(clipRect, Op.REPLACE); + draw(destCanvas); + destCanvas.restore(); + } + + /** + * Returns a new bitmap to be used as the object outline, e.g. to visualize the drop location. + * Responsibility for the bitmap is transferred to the caller. + */ + private Bitmap createGlowingOutline(Canvas canvas, int outlineColor, int glowColor) { + final int padding = HolographicOutlineHelper.MAX_OUTER_BLUR_RADIUS; + final Bitmap b = Bitmap.createBitmap( + getWidth() + padding, getHeight() + padding, Bitmap.Config.ARGB_8888); + + canvas.setBitmap(b); + drawWithPadding(canvas, padding); + mOutlineHelper.applyExtraThickExpensiveOutlineWithBlur(b, canvas, glowColor, outlineColor); + + return b; + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + // Call the superclass onTouchEvent first, because sometimes it changes the state to + // isPressed() on an ACTION_UP + boolean result = super.onTouchEvent(event); + + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + // So that the pressed outline is visible immediately when isPressed() is true, + // we pre-create it on ACTION_DOWN (it takes a small but perceptible amount of time + // to create it) + if (mPressedOrFocusedBackground == null) { + mPressedOrFocusedBackground = createGlowingOutline( + mTempCanvas, mPressedGlowColor, mPressedOutlineColor); + } + // Invalidate so the pressed state is visible, or set a flag so we know that we + // have to call invalidate as soon as the state is "pressed" + if (isPressed()) { + mDidInvalidateForPressedState = true; + invalidate(); + } else { + mDidInvalidateForPressedState = false; + } + break; + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: + // If we've touched down and up on an item, and it's still not "pressed", then + // destroy the pressed outline + if (!isPressed()) { + mPressedOrFocusedBackground = null; + } + break; + } + return result; + } + @Override public void draw(Canvas canvas) { + if (mPressedOrFocusedBackground != null && (isPressed() || isFocused())) { + canvas.drawBitmap(mPressedOrFocusedBackground, + mScrollX - HolographicOutlineHelper.MAX_OUTER_BLUR_RADIUS / 2, + mScrollY - HolographicOutlineHelper.MAX_OUTER_BLUR_RADIUS / 2, + mTempPaint); + } if (isBuildingCache()) { // We enhance the shadow by drawing the shadow twice this.setShadowLayer(SHADOW_LARGE_RADIUS, 0.0f, SHADOW_Y_OFFSET, SHADOW_LARGE_COLOUR); @@ -162,7 +275,6 @@ public class BubbleTextView extends CacheableTextView { canvas.translate(-scrollX, -scrollY); } } - super.draw(canvas); } } diff --git a/src/com/android/launcher2/HolographicOutlineHelper.java b/src/com/android/launcher2/HolographicOutlineHelper.java index 0311afa..6d0899d 100644 --- a/src/com/android/launcher2/HolographicOutlineHelper.java +++ b/src/com/android/launcher2/HolographicOutlineHelper.java @@ -31,26 +31,30 @@ public class HolographicOutlineHelper { private final Paint mErasePaint = new Paint(); private final Paint mAlphaClipPaint = new Paint(); - public static final int OUTER_BLUR_RADIUS; + public static final int MAX_OUTER_BLUR_RADIUS; + private static final BlurMaskFilter sExtraThickOuterBlurMaskFilter; private static final BlurMaskFilter sThickOuterBlurMaskFilter; private static final BlurMaskFilter sMediumOuterBlurMaskFilter; private static final BlurMaskFilter sThinOuterBlurMaskFilter; private static final BlurMaskFilter sThickInnerBlurMaskFilter; + private static final BlurMaskFilter sExtraThickInnerBlurMaskFilter; private static final BlurMaskFilter sMediumInnerBlurMaskFilter; private static final int THICK = 0; private static final int MEDIUM = 1; + private static final int EXTRA_THICK = 2; static { final float scale = LauncherApplication.getScreenDensity(); - OUTER_BLUR_RADIUS = (int) (scale * 6.0f); + MAX_OUTER_BLUR_RADIUS = (int) (scale * 12.0f); - sThickOuterBlurMaskFilter = new BlurMaskFilter(OUTER_BLUR_RADIUS, - BlurMaskFilter.Blur.OUTER); + sExtraThickOuterBlurMaskFilter = new BlurMaskFilter(scale * 12.0f, BlurMaskFilter.Blur.OUTER); + sThickOuterBlurMaskFilter = new BlurMaskFilter(scale * 6.0f, BlurMaskFilter.Blur.OUTER); sMediumOuterBlurMaskFilter = new BlurMaskFilter(scale * 2.0f, BlurMaskFilter.Blur.OUTER); sThinOuterBlurMaskFilter = new BlurMaskFilter(scale * 1.0f, BlurMaskFilter.Blur.OUTER); + sExtraThickInnerBlurMaskFilter = new BlurMaskFilter(scale * 6.0f, BlurMaskFilter.Blur.NORMAL); sThickInnerBlurMaskFilter = new BlurMaskFilter(scale * 4.0f, BlurMaskFilter.Blur.NORMAL); sMediumInnerBlurMaskFilter = new BlurMaskFilter(scale * 2.0f, BlurMaskFilter.Blur.NORMAL); } @@ -122,19 +126,50 @@ public class HolographicOutlineHelper { Bitmap glowShape = srcDst.extractAlpha(mAlphaClipPaint, mTempOffset); // calculate the outer blur first - mBlurPaint.setMaskFilter(thickness == THICK ? sThickOuterBlurMaskFilter : - sMediumOuterBlurMaskFilter); + BlurMaskFilter outerBlurMaskFilter; + switch (thickness) { + case EXTRA_THICK: + outerBlurMaskFilter = sExtraThickOuterBlurMaskFilter; + break; + case THICK: + outerBlurMaskFilter = sThickOuterBlurMaskFilter; + break; + case MEDIUM: + outerBlurMaskFilter = sMediumOuterBlurMaskFilter; + break; + default: + throw new RuntimeException("Invalid blur thickness"); + } + mBlurPaint.setMaskFilter(outerBlurMaskFilter); int[] outerBlurOffset = new int[2]; Bitmap thickOuterBlur = glowShape.extractAlpha(mBlurPaint, outerBlurOffset); - mBlurPaint.setMaskFilter(sThinOuterBlurMaskFilter); - int[] thinOuterBlurOffset = new int[2]; - Bitmap thinOuterBlur = glowShape.extractAlpha(mBlurPaint, thinOuterBlurOffset); + if (thickness == EXTRA_THICK) { + mBlurPaint.setMaskFilter(sMediumOuterBlurMaskFilter); + } else { + mBlurPaint.setMaskFilter(sThinOuterBlurMaskFilter); + } + + int[] brightOutlineOffset = new int[2]; + Bitmap brightOutline = glowShape.extractAlpha(mBlurPaint, brightOutlineOffset); // calculate the inner blur srcDstCanvas.setBitmap(glowShape); srcDstCanvas.drawColor(0xFF000000, PorterDuff.Mode.SRC_OUT); - mBlurPaint.setMaskFilter(thickness == THICK ? sThickInnerBlurMaskFilter : - sMediumInnerBlurMaskFilter); + BlurMaskFilter innerBlurMaskFilter; + switch (thickness) { + case EXTRA_THICK: + innerBlurMaskFilter = sExtraThickInnerBlurMaskFilter; + break; + case THICK: + innerBlurMaskFilter = sThickInnerBlurMaskFilter; + break; + case MEDIUM: + innerBlurMaskFilter = sMediumInnerBlurMaskFilter; + break; + default: + throw new RuntimeException("Invalid blur thickness"); + } + mBlurPaint.setMaskFilter(innerBlurMaskFilter); int[] thickInnerBlurOffset = new int[2]; Bitmap thickInnerBlur = glowShape.extractAlpha(mBlurPaint, thickInnerBlurOffset); @@ -158,16 +193,21 @@ public class HolographicOutlineHelper { // draw the bright outline mHolographicPaint.setColor(outlineColor); - srcDstCanvas.drawBitmap(thinOuterBlur, thinOuterBlurOffset[0], thinOuterBlurOffset[1], + srcDstCanvas.drawBitmap(brightOutline, brightOutlineOffset[0], brightOutlineOffset[1], mHolographicPaint); // cleanup - thinOuterBlur.recycle(); + brightOutline.recycle(); thickOuterBlur.recycle(); thickInnerBlur.recycle(); glowShape.recycle(); } + void applyExtraThickExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas, int color, + int outlineColor) { + applyExpensiveOutlineWithBlur(srcDst, srcDstCanvas, color, outlineColor, EXTRA_THICK); + } + void applyThickExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas, int color, int outlineColor) { applyExpensiveOutlineWithBlur(srcDst, srcDstCanvas, color, outlineColor, THICK); diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java index 4b96543..f70480d 100644 --- a/src/com/android/launcher2/Workspace.java +++ b/src/com/android/launcher2/Workspace.java @@ -1207,7 +1207,7 @@ public class Workspace extends SmoothPagedView final Canvas canvas = new Canvas(); // We need to add extra padding to the bitmap to make room for the glow effect - final int bitmapPadding = HolographicOutlineHelper.OUTER_BLUR_RADIUS; + final int bitmapPadding = HolographicOutlineHelper.MAX_OUTER_BLUR_RADIUS; // The outline is used to visualize where the item will land if dropped mDragOutline = createDragOutline(b, canvas, bitmapPadding); @@ -1452,7 +1452,7 @@ public class Workspace extends SmoothPagedView final Canvas canvas = new Canvas(); // We need to add extra padding to the bitmap to make room for the glow effect - final int bitmapPadding = HolographicOutlineHelper.OUTER_BLUR_RADIUS; + final int bitmapPadding = HolographicOutlineHelper.MAX_OUTER_BLUR_RADIUS; // The outline is used to visualize where the item will land if dropped mDragOutline = createDragOutline(child, canvas, bitmapPadding); @@ -1793,7 +1793,7 @@ public class Workspace extends SmoothPagedView // Create the drag outline // We need to add extra padding to the bitmap to make room for the glow effect final Canvas canvas = new Canvas(); - final int bitmapPadding = HolographicOutlineHelper.OUTER_BLUR_RADIUS; + final int bitmapPadding = HolographicOutlineHelper.MAX_OUTER_BLUR_RADIUS; mDragOutline = createExternalDragOutline(canvas, bitmapPadding); // Show the current page outlines to indicate that we can accept this drop |