diff options
Diffstat (limited to 'InCallUI/src/com/android/incallui/widget/multiwaveview')
-rw-r--r-- | InCallUI/src/com/android/incallui/widget/multiwaveview/GlowPadView.java | 115 |
1 files changed, 102 insertions, 13 deletions
diff --git a/InCallUI/src/com/android/incallui/widget/multiwaveview/GlowPadView.java b/InCallUI/src/com/android/incallui/widget/multiwaveview/GlowPadView.java index b577b7cc7..3fc978a10 100644 --- a/InCallUI/src/com/android/incallui/widget/multiwaveview/GlowPadView.java +++ b/InCallUI/src/com/android/incallui/widget/multiwaveview/GlowPadView.java @@ -48,8 +48,8 @@ import java.util.ArrayList; /** * This is a copy of com.android.internal.widget.multiwaveview.GlowPadView with minor changes * to remove dependencies on private api's. - * - * Contains changes up to If296b60af2421bfa1a9a082e608ba77b2392a218 + * + * Incoporated the scaling functionality. * * A re-usable widget containing a center, outer ring and wave animation. */ @@ -116,6 +116,8 @@ public class GlowPadView extends View { private float mWaveCenterY; private int mMaxTargetHeight; private int mMaxTargetWidth; + private float mRingScaleFactor = 1f; + private boolean mAllowScaling; private float mOuterRadius = 0.0f; private float mSnapMargin = 0.0f; @@ -219,6 +221,7 @@ public class GlowPadView extends View { mVibrationDuration); mFeedbackCount = a.getInt(R.styleable.GlowPadView_feedbackCount, mFeedbackCount); + mAllowScaling = a.getBoolean(R.styleable.GlowPadView_allowScaling, false); TypedValue handle = a.peekValue(R.styleable.GlowPadView_handleDrawable); mHandleDrawable = new TargetDrawable(res, handle != null ? handle.resourceId : 0, 2); mHandleDrawable.setState(TargetDrawable.STATE_INACTIVE); @@ -320,6 +323,22 @@ public class GlowPadView extends View { return (int) (Math.max(mOuterRing.getHeight(), 2 * mOuterRadius) + mMaxTargetHeight); } + /** + * This gets the suggested width accounting for the ring's scale factor. + */ + protected int getScaledSuggestedMinimumWidth() { + return (int) (mRingScaleFactor * Math.max(mOuterRing.getWidth(), 2 * mOuterRadius) + + mMaxTargetWidth); + } + + /** + * This gets the suggested height accounting for the ring's scale factor. + */ + protected int getScaledSuggestedMinimumHeight() { + return (int) (mRingScaleFactor * Math.max(mOuterRing.getHeight(), 2 * mOuterRadius) + + mMaxTargetHeight); + } + private int resolveMeasured(int measureSpec, int desired) { int result = 0; @@ -344,7 +363,14 @@ public class GlowPadView extends View { final int minimumHeight = getSuggestedMinimumHeight(); int computedWidth = resolveMeasured(widthMeasureSpec, minimumWidth); int computedHeight = resolveMeasured(heightMeasureSpec, minimumHeight); - computeInsets((computedWidth - minimumWidth), (computedHeight - minimumHeight)); + + mRingScaleFactor = computeScaleFactor(minimumWidth, minimumHeight, + computedWidth, computedHeight); + + int scaledWidth = getScaledSuggestedMinimumWidth(); + int scaledHeight = getScaledSuggestedMinimumHeight(); + + computeInsets(computedWidth - scaledWidth, computedHeight - scaledHeight); setMeasuredDimension(computedWidth, computedHeight); } @@ -509,8 +535,9 @@ public class GlowPadView extends View { "onUpdate", mUpdateListener)); } - final float ringScaleTarget = expanded ? + float ringScaleTarget = expanded ? RING_SCALE_EXPANDED : RING_SCALE_COLLAPSED; + ringScaleTarget *= mRingScaleFactor; mTargetAnimations.add(Tweener.to(mOuterRing, duration, "ease", interpolator, "alpha", 0.0f, @@ -540,11 +567,12 @@ public class GlowPadView extends View { "delay", delay, "onUpdate", mUpdateListener)); } + float ringScale = mRingScaleFactor * RING_SCALE_EXPANDED; mTargetAnimations.add(Tweener.to(mOuterRing, duration, "ease", Ease.Cubic.easeOut, "alpha", 1.0f, - "scaleX", 1.0f, - "scaleY", 1.0f, + "scaleX", ringScale, + "scaleY", ringScale, "delay", delay, "onUpdate", mUpdateListener, "onComplete", mTargetUpdateListener)); @@ -784,8 +812,12 @@ public class GlowPadView extends View { } private void updateGlowPosition(float x, float y) { - mPointCloud.glowManager.setX(x); - mPointCloud.glowManager.setY(y); + float dx = x - mOuterRing.getX(); + float dy = y - mOuterRing.getY(); + dx *= 1f / mRingScaleFactor; + dy *= 1f / mRingScaleFactor; + mPointCloud.glowManager.setX(mOuterRing.getX() + dx); + mPointCloud.glowManager.setY(mOuterRing.getY() + dy); } private void handleDown(MotionEvent event) { @@ -857,7 +889,7 @@ public class GlowPadView extends View { if (mDragging) { // For multiple targets, snap to the one that matches - final float snapRadius = mOuterRadius - mSnapMargin; + final float snapRadius = mRingScaleFactor * mOuterRadius - mSnapMargin; final float snapDistance2 = snapRadius * snapRadius; // Find first target in range for (int i = 0; i < ntargets; i++) { @@ -1016,6 +1048,61 @@ public class GlowPadView extends View { } } + /** + * Given the desired width and height of the ring and the allocated width and height, compute + * how much we need to scale the ring. + */ + private float computeScaleFactor(int desiredWidth, int desiredHeight, + int actualWidth, int actualHeight) { + + // Return unity if scaling is not allowed. + if (!mAllowScaling) return 1f; + + final int layoutDirection = getLayoutDirection(); + final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity, layoutDirection); + + float scaleX = 1f; + float scaleY = 1f; + + // We use the gravity as a cue for whether we want to scale on a particular axis. + // We only scale to fit horizontally if we're not pinned to the left or right. Likewise, + // we only scale to fit vertically if we're not pinned to the top or bottom. In these + // cases, we want the ring to hang off the side or top/bottom, respectively. + switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) { + case Gravity.LEFT: + case Gravity.RIGHT: + break; + case Gravity.CENTER_HORIZONTAL: + default: + if (desiredWidth > actualWidth) { + scaleX = (1f * actualWidth - mMaxTargetWidth) / + (desiredWidth - mMaxTargetWidth); + } + break; + } + switch (absoluteGravity & Gravity.VERTICAL_GRAVITY_MASK) { + case Gravity.TOP: + case Gravity.BOTTOM: + break; + case Gravity.CENTER_VERTICAL: + default: + if (desiredHeight > actualHeight) { + scaleY = (1f * actualHeight - mMaxTargetHeight) / + (desiredHeight - mMaxTargetHeight); + } + break; + } + return Math.min(scaleX, scaleY); + } + + private float getRingWidth() { + return mRingScaleFactor * Math.max(mOuterRing.getWidth(), 2 * mOuterRadius); + } + + private float getRingHeight() { + return mRingScaleFactor * Math.max(mOuterRing.getHeight(), 2 * mOuterRadius); + } + @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); @@ -1024,8 +1111,8 @@ public class GlowPadView extends View { // Target placement width/height. This puts the targets on the greater of the ring // width or the specified outer radius. - final float placementWidth = Math.max(mOuterRing.getWidth(), 2 * mOuterRadius); - final float placementHeight = Math.max(mOuterRing.getHeight(), 2 * mOuterRadius); + final float placementWidth = getRingWidth(); + final float placementHeight = getRingHeight(); float newWaveCenterX = mHorizontalInset + Math.max(width, mMaxTargetWidth + placementWidth) / 2; float newWaveCenterY = mVerticalInset @@ -1040,6 +1127,8 @@ public class GlowPadView extends View { mOuterRing.setPositionX(newWaveCenterX); mOuterRing.setPositionY(newWaveCenterY); + mPointCloud.setScale(mRingScaleFactor); + mHandleDrawable.setPositionX(newWaveCenterX); mHandleDrawable.setPositionY(newWaveCenterY); @@ -1063,8 +1152,8 @@ public class GlowPadView extends View { final float angle = alpha * i; targetIcon.setPositionX(centerX); targetIcon.setPositionY(centerY); - targetIcon.setX(mOuterRadius * (float) Math.cos(angle)); - targetIcon.setY(mOuterRadius * (float) Math.sin(angle)); + targetIcon.setX(getRingWidth() / 2 * (float) Math.cos(angle)); + targetIcon.setY(getRingHeight() / 2 * (float) Math.sin(angle)); } } |