summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/widget/RotarySelector.java274
-rwxr-xr-xcore/res/res/drawable-hdpi/ic_jog_dial_sound_off.pngbin0 -> 5698 bytes
-rwxr-xr-xcore/res/res/drawable-hdpi/ic_jog_dial_sound_on.pngbin0 -> 5685 bytes
-rwxr-xr-xcore/res/res/drawable-hdpi/ic_jog_dial_unlock.pngbin0 -> 5758 bytes
-rwxr-xr-xcore/res/res/drawable-hdpi/jog_dial_arrow_long_left_green.pngbin0 -> 7469 bytes
-rwxr-xr-xcore/res/res/drawable-hdpi/jog_dial_arrow_long_left_yellow.pngbin0 -> 7378 bytes
-rwxr-xr-xcore/res/res/drawable-hdpi/jog_dial_arrow_long_middle_yellow.pngbin0 -> 4877 bytes
-rwxr-xr-xcore/res/res/drawable-hdpi/jog_dial_arrow_long_right_red.pngbin0 -> 7501 bytes
-rwxr-xr-xcore/res/res/drawable-hdpi/jog_dial_arrow_long_right_yellow.pngbin0 -> 7523 bytes
-rwxr-xr-xcore/res/res/drawable-hdpi/jog_dial_arrow_short_left.pngbin0 -> 3704 bytes
-rwxr-xr-xcore/res/res/drawable-hdpi/jog_dial_arrow_short_left_and_right.pngbin0 -> 6553 bytes
-rwxr-xr-xcore/res/res/drawable-hdpi/jog_dial_arrow_short_right.pngbin0 -> 3826 bytes
-rwxr-xr-xcore/res/res/drawable-hdpi/jog_dial_bg.pngbin0 -> 21832 bytes
-rwxr-xr-xcore/res/res/drawable-hdpi/jog_dial_dimple.pngbin0 -> 5439 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_jog_dial_sound_off.pngbin0 -> 3401 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_jog_dial_sound_on.pngbin0 -> 3213 bytes
-rwxr-xr-x[-rw-r--r--]core/res/res/drawable-mdpi/ic_jog_dial_unlock.png (renamed from core/res/res/drawable/ic_jog_dial_unlock.png)bin3339 -> 3339 bytes
-rwxr-xr-x[-rw-r--r--]core/res/res/drawable-mdpi/jog_dial_arrow_long_left_green.png (renamed from core/res/res/drawable/jog_dial_arrow_long_left_green.png)bin4486 -> 4486 bytes
-rwxr-xr-x[-rw-r--r--]core/res/res/drawable-mdpi/jog_dial_arrow_long_left_yellow.png (renamed from core/res/res/drawable/jog_dial_arrow_long_left_yellow.png)bin4520 -> 4520 bytes
-rwxr-xr-x[-rw-r--r--]core/res/res/drawable-mdpi/jog_dial_arrow_long_middle_yellow.png (renamed from core/res/res/drawable/jog_dial_arrow_long_middle_yellow.png)bin2915 -> 2915 bytes
-rwxr-xr-x[-rw-r--r--]core/res/res/drawable-mdpi/jog_dial_arrow_long_right_red.png (renamed from core/res/res/drawable/jog_dial_arrow_long_right_red.png)bin4465 -> 4465 bytes
-rwxr-xr-x[-rw-r--r--]core/res/res/drawable-mdpi/jog_dial_arrow_long_right_yellow.png (renamed from core/res/res/drawable/jog_dial_arrow_long_right_yellow.png)bin4592 -> 4592 bytes
-rwxr-xr-x[-rw-r--r--]core/res/res/drawable-mdpi/jog_dial_arrow_short_left.png (renamed from core/res/res/drawable/jog_dial_arrow_short_left.png)bin2206 -> 2206 bytes
-rwxr-xr-x[-rw-r--r--]core/res/res/drawable-mdpi/jog_dial_arrow_short_left_and_right.png (renamed from core/res/res/drawable/jog_dial_arrow_short_left_and_right.png)bin3673 -> 3673 bytes
-rwxr-xr-x[-rw-r--r--]core/res/res/drawable-mdpi/jog_dial_arrow_short_right.png (renamed from core/res/res/drawable/jog_dial_arrow_short_right.png)bin2204 -> 2204 bytes
-rwxr-xr-xcore/res/res/drawable-mdpi/jog_dial_bg.pngbin0 -> 13048 bytes
-rwxr-xr-x[-rw-r--r--]core/res/res/drawable-mdpi/jog_dial_dimple.png (renamed from core/res/res/drawable/jog_dial_dimple.png)bin3334 -> 3334 bytes
-rw-r--r--core/res/res/drawable/ic_jog_dial_answer.pngbin3610 -> 0 bytes
-rw-r--r--core/res/res/drawable/ic_jog_dial_decline.pngbin3284 -> 0 bytes
-rw-r--r--core/res/res/drawable/ic_jog_dial_silence_ringer.pngbin3259 -> 0 bytes
-rw-r--r--core/res/res/drawable/ic_jog_dial_turn_ring_vol_off.pngbin2872 -> 0 bytes
-rw-r--r--core/res/res/drawable/ic_jog_dial_turn_ring_vol_on.pngbin3215 -> 0 bytes
-rw-r--r--core/res/res/drawable/jog_dial_bg_cropped.pngbin15936 -> 0 bytes
-rw-r--r--core/res/res/layout/keyguard_screen_rotary_unlock_land.xml145
-rw-r--r--core/res/res/values/attrs.xml8
35 files changed, 339 insertions, 88 deletions
diff --git a/core/java/com/android/internal/widget/RotarySelector.java b/core/java/com/android/internal/widget/RotarySelector.java
index 426cef5..a6ce7f8 100644
--- a/core/java/com/android/internal/widget/RotarySelector.java
+++ b/core/java/com/android/internal/widget/RotarySelector.java
@@ -18,7 +18,12 @@ package com.android.internal.widget;
import android.content.Context;
import android.content.res.Resources;
+import android.content.res.TypedArray;
import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Matrix;
import android.graphics.drawable.Drawable;
import android.os.Vibrator;
import android.util.AttributeSet;
@@ -38,6 +43,9 @@ import com.android.internal.R;
* security pattern is set.
*/
public class RotarySelector extends View {
+ public static final int HORIZONTAL = 0;
+ public static final int VERTICAL = 1;
+
private static final String LOG_TAG = "RotarySelector";
private static final boolean DBG = false;
@@ -47,15 +55,15 @@ public class RotarySelector extends View {
private float mDensity;
// UI elements
- private Drawable mBackground;
+ private Bitmap mBackground;
private Drawable mDimple;
private Drawable mLeftHandleIcon;
private Drawable mRightHandleIcon;
- private Drawable mArrowShortLeftAndRight;
- private Drawable mArrowLongLeft; // Long arrow starting on the left, pointing clockwise
- private Drawable mArrowLongRight; // Long arrow starting on the right, pointing CCW
+ private Bitmap mArrowShortLeftAndRight;
+ private Bitmap mArrowLongLeft; // Long arrow starting on the left, pointing clockwise
+ private Bitmap mArrowLongRight; // Long arrow starting on the right, pointing CCW
// positions of the left and right handle
private int mLeftHandleX;
@@ -74,6 +82,12 @@ public class RotarySelector extends View {
private DecelerateInterpolator mInterpolator;
+ private Paint mPaint = new Paint();
+
+ // used to rotate the background and arrow assets depending on orientation
+ final Matrix mBgMatrix = new Matrix();
+ final Matrix mArrowMatrix = new Matrix();
+
/**
* If the user is currently dragging something.
*/
@@ -117,7 +131,6 @@ public class RotarySelector extends View {
static final int SNAP_BACK_ANIMATION_DURATION_MILLIS = 300;
static final int SPIN_ANIMATION_DURATION_MILLIS = 800;
- private static final boolean DRAW_CENTER_DIMPLE = true;
private int mEdgeTriggerThresh;
private int mDimpleWidth;
private int mBackgroundWidth;
@@ -137,6 +150,10 @@ public class RotarySelector extends View {
*/
private int mDimplesOfFling = 0;
+ /**
+ * Either {@link #HORIZONTAL} or {@link #VERTICAL}.
+ */
+ private int mOrientation;
public RotarySelector(Context context) {
@@ -148,28 +165,23 @@ public class RotarySelector extends View {
*/
public RotarySelector(Context context, AttributeSet attrs) {
super(context, attrs);
- if (DBG) log("IncomingCallDialWidget constructor...");
+
+ TypedArray a =
+ context.obtainStyledAttributes(attrs, R.styleable.RotarySelector);
+ mOrientation = a.getInt(R.styleable.RotarySelector_orientation, HORIZONTAL);
+ a.recycle();
Resources r = getResources();
mDensity = r.getDisplayMetrics().density;
if (DBG) log("- Density: " + mDensity);
// Assets (all are BitmapDrawables).
- mBackground = r.getDrawable(R.drawable.jog_dial_bg_cropped);
+ mBackground = getBitmapFor(R.drawable.jog_dial_bg);
mDimple = r.getDrawable(R.drawable.jog_dial_dimple);
- mArrowLongLeft = r.getDrawable(R.drawable.jog_dial_arrow_long_left_green);
- mArrowLongRight = r.getDrawable(R.drawable.jog_dial_arrow_long_right_red);
- mArrowShortLeftAndRight = r.getDrawable(R.drawable.jog_dial_arrow_short_left_and_right);
-
- // Arrows:
- // All arrow assets are the same size (they're the full width of
- // the screen) regardless of which arrows are actually visible.
- int arrowW = mArrowShortLeftAndRight.getIntrinsicWidth();
- int arrowH = mArrowShortLeftAndRight.getIntrinsicHeight();
- mArrowShortLeftAndRight.setBounds(0, 0, arrowW, arrowH);
- mArrowLongLeft.setBounds(0, 0, arrowW, arrowH);
- mArrowLongRight.setBounds(0, 0, arrowW, arrowH);
+ mArrowLongLeft = getBitmapFor(R.drawable.jog_dial_arrow_long_left_green);
+ mArrowLongRight = getBitmapFor(R.drawable.jog_dial_arrow_long_right_red);
+ mArrowShortLeftAndRight = getBitmapFor(R.drawable.jog_dial_arrow_short_left_and_right);
mInterpolator = new DecelerateInterpolator(1f);
@@ -177,8 +189,8 @@ public class RotarySelector extends View {
mDimpleWidth = mDimple.getIntrinsicWidth();
- mBackgroundWidth = mBackground.getIntrinsicWidth();
- mBackgroundHeight = mBackground.getIntrinsicHeight();
+ mBackgroundWidth = mBackground.getWidth();
+ mBackgroundHeight = mBackground.getHeight();
mOuterRadius = (int) (mDensity * OUTER_ROTARY_RADIUS_DIP);
mInnerRadius = (int) ((OUTER_ROTARY_RADIUS_DIP - ROTARY_STROKE_WIDTH_DIP) * mDensity);
@@ -187,15 +199,35 @@ public class RotarySelector extends View {
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
}
+ private Bitmap getBitmapFor(int resId) {
+ return BitmapFactory.decodeResource(getContext().getResources(), resId);
+ }
+
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
- mLeftHandleX = (int) (EDGE_PADDING_DIP * mDensity) + mDimpleWidth / 2;
- mRightHandleX =
- getWidth() - (int) (EDGE_PADDING_DIP * mDensity) - mDimpleWidth / 2;
+ final int edgePadding = (int) (EDGE_PADDING_DIP * mDensity);
+ mLeftHandleX = edgePadding + mDimpleWidth / 2;
+ final int length = isHoriz() ? w : h;
+ mRightHandleX = length - edgePadding - mDimpleWidth / 2;
+ mDimpleSpacing = (length / 2) - mLeftHandleX;
+
+ // bg matrix only needs to be calculated once
+ mBgMatrix.setTranslate(0, 0);
+ if (!isHoriz()) {
+ // set up matrix for translating drawing of background and arrow assets
+ final int left = w - mBackgroundHeight;
+ mBgMatrix.preRotate(-90, 0, 0);
+ mBgMatrix.postTranslate(left, h);
+
+ } else {
+ mBgMatrix.postTranslate(0, h - mBackgroundHeight);
+ }
+ }
- mDimpleSpacing = (getWidth() / 2) - mLeftHandleX;
+ private boolean isHoriz() {
+ return mOrientation == HORIZONTAL;
}
/**
@@ -252,28 +284,35 @@ public class RotarySelector extends View {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- final int width = MeasureSpec.getSize(widthMeasureSpec); // screen width
-
- final int arrowH = mArrowShortLeftAndRight.getIntrinsicHeight();
- final int backgroundH = mBackgroundHeight;
+ final int length = isHoriz() ?
+ MeasureSpec.getSize(widthMeasureSpec) :
+ MeasureSpec.getSize(heightMeasureSpec);
+ final int arrowScrunch = (int) (ARROW_SCRUNCH_DIP * mDensity);
+ final int arrowH = mArrowShortLeftAndRight.getHeight();
// by making the height less than arrow + bg, arrow and bg will be scrunched together,
// overlaying somewhat (though on transparent portions of the drawable).
// this works because the arrows are drawn from the top, and the rotary bg is drawn
// from the bottom.
- final int arrowScrunch = (int) (ARROW_SCRUNCH_DIP * mDensity);
- setMeasuredDimension(width, backgroundH + arrowH - arrowScrunch);
- }
+ final int height = mBackgroundHeight + arrowH - arrowScrunch;
-// private Paint mPaint = new Paint();
+ if (isHoriz()) {
+ setMeasuredDimension(length, height);
+ } else {
+ setMeasuredDimension(height, length);
+ }
+ }
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
- if (DBG) {
- log(String.format("onDraw: mAnimating=%s, mRotaryOffsetX=%d, mGrabbedState=%d",
- mAnimating, mRotaryOffsetX, mGrabbedState));
- }
+
+ final int width = getWidth();
+
+ // DEBUG: draw bounding box around widget
+// mPaint.setColor(Color.RED);
+// mPaint.setStyle(Paint.Style.STROKE);
+// canvas.drawRect(0, 0, width, getHeight(), mPaint);
final int height = getHeight();
@@ -283,76 +322,113 @@ public class RotarySelector extends View {
}
// Background:
- final int backgroundW = mBackgroundWidth;
- final int backgroundH = mBackgroundHeight;
- final int backgroundY = height - backgroundH;
- if (DBG) log("- Background INTRINSIC: " + backgroundW + " x " + backgroundH);
- mBackground.setBounds(0, backgroundY,
- backgroundW, backgroundY + backgroundH);
- if (DBG) log(" Background BOUNDS: " + mBackground.getBounds());
- mBackground.draw(canvas);
-
+ canvas.drawBitmap(mBackground, mBgMatrix, mPaint);
// Draw the correct arrow(s) depending on the current state:
- Drawable currentArrow;
+ mArrowMatrix.reset();
switch (mGrabbedState) {
case NOTHING_GRABBED:
- currentArrow = null; //mArrowShortLeftAndRight;
+ //mArrowShortLeftAndRight;
break;
case LEFT_HANDLE_GRABBED:
- currentArrow = mArrowLongLeft;
+ mArrowMatrix.setTranslate(0, 0);
+ if (!isHoriz()) {
+ mArrowMatrix.preRotate(-90, 0, 0);
+ mArrowMatrix.postTranslate(0, height);
+ }
+ canvas.drawBitmap(mArrowLongLeft, mArrowMatrix, mPaint);
break;
case RIGHT_HANDLE_GRABBED:
- currentArrow = mArrowLongRight;
+ mArrowMatrix.setTranslate(0, 0);
+ if (!isHoriz()) {
+ mArrowMatrix.preRotate(-90, 0, 0);
+ // since bg width is > height of screen in landscape mode...
+ mArrowMatrix.postTranslate(0, height + (mBackgroundWidth - height));
+ }
+ canvas.drawBitmap(mArrowLongRight, mArrowMatrix, mPaint);
break;
default:
throw new IllegalStateException("invalid mGrabbedState: " + mGrabbedState);
}
- if (currentArrow != null) currentArrow.draw(canvas);
- // debug: draw circle that should match the outer arc (good sanity check)
-// mPaint.setColor(Color.RED);
-// mPaint.setStyle(Paint.Style.STROKE);
+ final int bgHeight = mBackgroundHeight;
+ final int bgTop = isHoriz() ?
+ height - bgHeight:
+ width - bgHeight;
+ // DEBUG: draw circle bounding arc drawable: good sanity check we're doing the math
+ // correctly
// float or = OUTER_ROTARY_RADIUS_DIP * mDensity;
-// canvas.drawCircle(getWidth() / 2, or + mBackground.getBounds().top, or, mPaint);
-
- final int bgTop = mBackground.getBounds().top;
+// final int vOffset = mBackgroundWidth - height;
+// final int midX = isHoriz() ?
+// width / 2 :
+// mBackgroundWidth / 2 - vOffset;
+// if (isHoriz()) {
+// canvas.drawCircle(midX, or + bgTop, or, mPaint);
+// } else {
+// canvas.drawCircle(or + bgTop, midX, or, mPaint);
+// }
+
+ // left dimple / icon
{
final int xOffset = mLeftHandleX + mRotaryOffsetX;
final int drawableY = getYOnArc(
- mBackground,
+ mBackgroundWidth,
mInnerRadius,
mOuterRadius,
xOffset);
-
- drawCentered(mDimple, canvas, xOffset, drawableY + bgTop);
- if (mGrabbedState != RIGHT_HANDLE_GRABBED) {
- drawCentered(mLeftHandleIcon, canvas, xOffset, drawableY + bgTop);
+ if (isHoriz()) {
+ drawCentered(mDimple, canvas, xOffset, drawableY + bgTop);
+ if (mGrabbedState != RIGHT_HANDLE_GRABBED) {
+ drawCentered(mLeftHandleIcon, canvas, xOffset, drawableY + bgTop);
+ }
+ } else {
+ // vertical
+ drawCentered(mDimple, canvas, drawableY + bgTop, height - xOffset);
+ if (mGrabbedState != RIGHT_HANDLE_GRABBED) {
+ drawCentered(mLeftHandleIcon, canvas, drawableY + bgTop, height - xOffset);
+ }
}
}
- if (DRAW_CENTER_DIMPLE) {
- final int xOffset = getWidth() / 2 + mRotaryOffsetX;
+ // center dimple
+ {
+ final int xOffset = isHoriz() ?
+ width / 2 + mRotaryOffsetX:
+ height / 2 + mRotaryOffsetX;
final int drawableY = getYOnArc(
- mBackground,
+ mBackgroundWidth,
mInnerRadius,
mOuterRadius,
xOffset);
- drawCentered(mDimple, canvas, xOffset, drawableY + bgTop);
+ if (isHoriz()) {
+ drawCentered(mDimple, canvas, xOffset, drawableY + bgTop);
+ } else {
+ // vertical
+ drawCentered(mDimple, canvas, drawableY + bgTop, height - xOffset);
+ }
}
+ // right dimple / icon
{
final int xOffset = mRightHandleX + mRotaryOffsetX;
final int drawableY = getYOnArc(
- mBackground,
+ mBackgroundWidth,
mInnerRadius,
mOuterRadius,
xOffset);
- drawCentered(mDimple, canvas, xOffset, drawableY + bgTop);
- if (mGrabbedState != LEFT_HANDLE_GRABBED) {
- drawCentered(mRightHandleIcon, canvas, xOffset, drawableY + bgTop);
+ if (isHoriz()) {
+ drawCentered(mDimple, canvas, xOffset, drawableY + bgTop);
+ if (mGrabbedState != LEFT_HANDLE_GRABBED) {
+ drawCentered(mRightHandleIcon, canvas, xOffset, drawableY + bgTop);
+ }
+ } else {
+ // vertical
+ drawCentered(mDimple, canvas, drawableY + bgTop, height - xOffset);
+ if (mGrabbedState != LEFT_HANDLE_GRABBED) {
+ drawCentered(mRightHandleIcon, canvas, drawableY + bgTop, height - xOffset);
+ }
}
}
@@ -361,12 +437,16 @@ public class RotarySelector extends View {
final int halfdimple = mDimpleWidth / 2;
while (dimpleLeft > -halfdimple) {
final int drawableY = getYOnArc(
- mBackground,
+ mBackgroundWidth,
mInnerRadius,
mOuterRadius,
dimpleLeft);
- drawCentered(mDimple, canvas, dimpleLeft, drawableY + bgTop);
+ if (isHoriz()) {
+ drawCentered(mDimple, canvas, dimpleLeft, drawableY + bgTop);
+ } else {
+ drawCentered(mDimple, canvas, drawableY + bgTop, height - dimpleLeft);
+ }
dimpleLeft -= mDimpleSpacing;
}
@@ -375,40 +455,43 @@ public class RotarySelector extends View {
final int rightThresh = mRight + halfdimple;
while (dimpleRight < rightThresh) {
final int drawableY = getYOnArc(
- mBackground,
+ mBackgroundWidth,
mInnerRadius,
mOuterRadius,
dimpleRight);
- drawCentered(mDimple, canvas, dimpleRight, drawableY + bgTop);
+ if (isHoriz()) {
+ drawCentered(mDimple, canvas, dimpleRight, drawableY + bgTop);
+ } else {
+ drawCentered(mDimple, canvas, drawableY + bgTop, height - dimpleRight);
+ }
dimpleRight += mDimpleSpacing;
}
}
/**
- * Assuming drawable is a bounding box around a piece of an arc drawn by two concentric circles
+ * Assuming bitmap is a bounding box around a piece of an arc drawn by two concentric circles
* (as the background drawable for the rotary widget is), and given an x coordinate along the
* drawable, return the y coordinate of a point on the arc that is between the two concentric
* circles. The resulting y combined with the incoming x is a point along the circle in
* between the two concentric circles.
*
- * @param drawable The drawable.
+ * @param backgroundWidth The width of the asset (the bottom of the box surrounding the arc).
* @param innerRadius The radius of the circle that intersects the drawable at the bottom two
* corders of the drawable (top two corners in terms of drawing coordinates).
* @param outerRadius The radius of the circle who's top most point is the top center of the
* drawable (bottom center in terms of drawing coordinates).
- * @param x The distance along the x axis of the desired point.
- * @return The y coordinate, in drawing coordinates, that will place (x, y) along the circle
+ * @param x The distance along the x axis of the desired point. @return The y coordinate, in drawing coordinates, that will place (x, y) along the circle
* in between the two concentric circles.
*/
- private int getYOnArc(Drawable drawable, int innerRadius, int outerRadius, int x) {
+ private int getYOnArc(int backgroundWidth, int innerRadius, int outerRadius, int x) {
// the hypotenuse
final int halfWidth = (outerRadius - innerRadius) / 2;
final int middleRadius = innerRadius + halfWidth;
// the bottom leg of the triangle
- final int triangleBottom = (drawable.getIntrinsicWidth() / 2) - x;
+ final int triangleBottom = (backgroundWidth / 2) - x;
// "Our offense is like the pythagorean theorem: There is no answer!" - Shaquille O'Neal
final int triangleY =
@@ -437,8 +520,11 @@ public class RotarySelector extends View {
}
mVelocityTracker.addMovement(event);
+ final int height = getHeight();
- final int eventX = (int) event.getX();
+ final int eventX = isHoriz() ?
+ (int) event.getX():
+ height - ((int) event.getY());
final int hitWindow = mDimpleWidth;
final int action = event.getAction();
@@ -468,12 +554,16 @@ public class RotarySelector extends View {
if (mGrabbedState == LEFT_HANDLE_GRABBED) {
mRotaryOffsetX = eventX - mLeftHandleX;
invalidate();
- if (eventX >= getRight() - mEdgeTriggerThresh && !mTriggered) {
+ final int rightThresh = isHoriz() ? getRight() : height;
+ if (eventX >= rightThresh - mEdgeTriggerThresh && !mTriggered) {
mTriggered = true;
dispatchTriggerEvent(OnDialTriggerListener.LEFT_HANDLE);
final VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
- final int velocity = Math.max(mMinimumVelocity, (int) velocityTracker.getXVelocity());
+ final int rawVelocity = isHoriz() ?
+ (int) velocityTracker.getXVelocity():
+ -(int) velocityTracker.getYVelocity();
+ final int velocity = Math.max(mMinimumVelocity, rawVelocity);
mDimplesOfFling = Math.max(
8,
Math.abs(velocity / mDimpleSpacing));
@@ -490,7 +580,10 @@ public class RotarySelector extends View {
dispatchTriggerEvent(OnDialTriggerListener.RIGHT_HANDLE);
final VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
- final int velocity = Math.min(-mMinimumVelocity, (int) velocityTracker.getXVelocity());
+ final int rawVelocity = isHoriz() ?
+ (int) velocityTracker.getXVelocity():
+ - (int) velocityTracker.getYVelocity();
+ final int velocity = Math.min(-mMinimumVelocity, rawVelocity);
mDimplesOfFling = Math.max(
8,
Math.abs(velocity / mDimpleSpacing));
@@ -559,6 +652,7 @@ public class RotarySelector extends View {
final long millisSoFar = currentAnimationTimeMillis() - mAnimationStartTime;
final long millisLeft = mAnimationDuration - millisSoFar;
final int totalDeltaX = mAnimatingDeltaXStart - mAnimatingDeltaXEnd;
+ final boolean goingRight = totalDeltaX < 0;
if (DBG) log("millisleft for animating: " + millisLeft);
if (millisLeft <= 0) {
reset();
@@ -569,13 +663,17 @@ public class RotarySelector extends View {
mInterpolator.getInterpolation((float) millisSoFar / mAnimationDuration);
final int dx = (int) (totalDeltaX * (1 - interpolation));
mRotaryOffsetX = mAnimatingDeltaXEnd + dx;
+
+ // once we have gone far enough to animate the current buttons off screen, we start
+ // wrapping the offset back to the other side so that when the animation is finished,
+ // the buttons will come back into their original places.
if (mDimplesOfFling > 0) {
- if (mRotaryOffsetX < 4 * mDimpleSpacing) {
+ if (!goingRight && mRotaryOffsetX < 3 * mDimpleSpacing) {
// wrap around on fling left
- mRotaryOffsetX += (4 + mDimplesOfFling - 4) * mDimpleSpacing;
- } else if (mRotaryOffsetX > 4 * mDimpleSpacing) {
+ mRotaryOffsetX += mDimplesOfFling * mDimpleSpacing;
+ } else if (goingRight && mRotaryOffsetX > 3 * mDimpleSpacing) {
// wrap around on fling right
- mRotaryOffsetX -= (4 + mDimplesOfFling - 4) * mDimpleSpacing;
+ mRotaryOffsetX -= mDimplesOfFling * mDimpleSpacing;
}
}
invalidate();
diff --git a/core/res/res/drawable-hdpi/ic_jog_dial_sound_off.png b/core/res/res/drawable-hdpi/ic_jog_dial_sound_off.png
new file mode 100755
index 0000000..d73db48
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_jog_dial_sound_off.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_jog_dial_sound_on.png b/core/res/res/drawable-hdpi/ic_jog_dial_sound_on.png
new file mode 100755
index 0000000..90da6e3
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_jog_dial_sound_on.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_jog_dial_unlock.png b/core/res/res/drawable-hdpi/ic_jog_dial_unlock.png
new file mode 100755
index 0000000..a9af1af
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_jog_dial_unlock.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_dial_arrow_long_left_green.png b/core/res/res/drawable-hdpi/jog_dial_arrow_long_left_green.png
new file mode 100755
index 0000000..f19811e
--- /dev/null
+++ b/core/res/res/drawable-hdpi/jog_dial_arrow_long_left_green.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_dial_arrow_long_left_yellow.png b/core/res/res/drawable-hdpi/jog_dial_arrow_long_left_yellow.png
new file mode 100755
index 0000000..0596035
--- /dev/null
+++ b/core/res/res/drawable-hdpi/jog_dial_arrow_long_left_yellow.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_dial_arrow_long_middle_yellow.png b/core/res/res/drawable-hdpi/jog_dial_arrow_long_middle_yellow.png
new file mode 100755
index 0000000..3ab2723
--- /dev/null
+++ b/core/res/res/drawable-hdpi/jog_dial_arrow_long_middle_yellow.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_dial_arrow_long_right_red.png b/core/res/res/drawable-hdpi/jog_dial_arrow_long_right_red.png
new file mode 100755
index 0000000..dd6899f
--- /dev/null
+++ b/core/res/res/drawable-hdpi/jog_dial_arrow_long_right_red.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_dial_arrow_long_right_yellow.png b/core/res/res/drawable-hdpi/jog_dial_arrow_long_right_yellow.png
new file mode 100755
index 0000000..27151e0
--- /dev/null
+++ b/core/res/res/drawable-hdpi/jog_dial_arrow_long_right_yellow.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_dial_arrow_short_left.png b/core/res/res/drawable-hdpi/jog_dial_arrow_short_left.png
new file mode 100755
index 0000000..66d49bb
--- /dev/null
+++ b/core/res/res/drawable-hdpi/jog_dial_arrow_short_left.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_dial_arrow_short_left_and_right.png b/core/res/res/drawable-hdpi/jog_dial_arrow_short_left_and_right.png
new file mode 100755
index 0000000..c47e176
--- /dev/null
+++ b/core/res/res/drawable-hdpi/jog_dial_arrow_short_left_and_right.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_dial_arrow_short_right.png b/core/res/res/drawable-hdpi/jog_dial_arrow_short_right.png
new file mode 100755
index 0000000..f5ea157
--- /dev/null
+++ b/core/res/res/drawable-hdpi/jog_dial_arrow_short_right.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_dial_bg.png b/core/res/res/drawable-hdpi/jog_dial_bg.png
new file mode 100755
index 0000000..8adbfd8
--- /dev/null
+++ b/core/res/res/drawable-hdpi/jog_dial_bg.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_dial_dimple.png b/core/res/res/drawable-hdpi/jog_dial_dimple.png
new file mode 100755
index 0000000..0eaea91
--- /dev/null
+++ b/core/res/res/drawable-hdpi/jog_dial_dimple.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_jog_dial_sound_off.png b/core/res/res/drawable-mdpi/ic_jog_dial_sound_off.png
new file mode 100644
index 0000000..b9aec69
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_jog_dial_sound_off.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_jog_dial_sound_on.png b/core/res/res/drawable-mdpi/ic_jog_dial_sound_on.png
new file mode 100644
index 0000000..4952746
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_jog_dial_sound_on.png
Binary files differ
diff --git a/core/res/res/drawable/ic_jog_dial_unlock.png b/core/res/res/drawable-mdpi/ic_jog_dial_unlock.png
index e697d91..e697d91 100644..100755
--- a/core/res/res/drawable/ic_jog_dial_unlock.png
+++ b/core/res/res/drawable-mdpi/ic_jog_dial_unlock.png
Binary files differ
diff --git a/core/res/res/drawable/jog_dial_arrow_long_left_green.png b/core/res/res/drawable-mdpi/jog_dial_arrow_long_left_green.png
index 334a8e0..334a8e0 100644..100755
--- a/core/res/res/drawable/jog_dial_arrow_long_left_green.png
+++ b/core/res/res/drawable-mdpi/jog_dial_arrow_long_left_green.png
Binary files differ
diff --git a/core/res/res/drawable/jog_dial_arrow_long_left_yellow.png b/core/res/res/drawable-mdpi/jog_dial_arrow_long_left_yellow.png
index 2e011ca..2e011ca 100644..100755
--- a/core/res/res/drawable/jog_dial_arrow_long_left_yellow.png
+++ b/core/res/res/drawable-mdpi/jog_dial_arrow_long_left_yellow.png
Binary files differ
diff --git a/core/res/res/drawable/jog_dial_arrow_long_middle_yellow.png b/core/res/res/drawable-mdpi/jog_dial_arrow_long_middle_yellow.png
index 323745e..323745e 100644..100755
--- a/core/res/res/drawable/jog_dial_arrow_long_middle_yellow.png
+++ b/core/res/res/drawable-mdpi/jog_dial_arrow_long_middle_yellow.png
Binary files differ
diff --git a/core/res/res/drawable/jog_dial_arrow_long_right_red.png b/core/res/res/drawable-mdpi/jog_dial_arrow_long_right_red.png
index 1e97c9a..1e97c9a 100644..100755
--- a/core/res/res/drawable/jog_dial_arrow_long_right_red.png
+++ b/core/res/res/drawable-mdpi/jog_dial_arrow_long_right_red.png
Binary files differ
diff --git a/core/res/res/drawable/jog_dial_arrow_long_right_yellow.png b/core/res/res/drawable-mdpi/jog_dial_arrow_long_right_yellow.png
index 3536e58..3536e58 100644..100755
--- a/core/res/res/drawable/jog_dial_arrow_long_right_yellow.png
+++ b/core/res/res/drawable-mdpi/jog_dial_arrow_long_right_yellow.png
Binary files differ
diff --git a/core/res/res/drawable/jog_dial_arrow_short_left.png b/core/res/res/drawable-mdpi/jog_dial_arrow_short_left.png
index 4a4ab3ae..4a4ab3ae 100644..100755
--- a/core/res/res/drawable/jog_dial_arrow_short_left.png
+++ b/core/res/res/drawable-mdpi/jog_dial_arrow_short_left.png
Binary files differ
diff --git a/core/res/res/drawable/jog_dial_arrow_short_left_and_right.png b/core/res/res/drawable-mdpi/jog_dial_arrow_short_left_and_right.png
index 987cfa7..987cfa7 100644..100755
--- a/core/res/res/drawable/jog_dial_arrow_short_left_and_right.png
+++ b/core/res/res/drawable-mdpi/jog_dial_arrow_short_left_and_right.png
Binary files differ
diff --git a/core/res/res/drawable/jog_dial_arrow_short_right.png b/core/res/res/drawable-mdpi/jog_dial_arrow_short_right.png
index ee79875..ee79875 100644..100755
--- a/core/res/res/drawable/jog_dial_arrow_short_right.png
+++ b/core/res/res/drawable-mdpi/jog_dial_arrow_short_right.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_dial_bg.png b/core/res/res/drawable-mdpi/jog_dial_bg.png
new file mode 100755
index 0000000..2f8f24d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/jog_dial_bg.png
Binary files differ
diff --git a/core/res/res/drawable/jog_dial_dimple.png b/core/res/res/drawable-mdpi/jog_dial_dimple.png
index 85d3a43..85d3a43 100644..100755
--- a/core/res/res/drawable/jog_dial_dimple.png
+++ b/core/res/res/drawable-mdpi/jog_dial_dimple.png
Binary files differ
diff --git a/core/res/res/drawable/ic_jog_dial_answer.png b/core/res/res/drawable/ic_jog_dial_answer.png
deleted file mode 100644
index e2bc483..0000000
--- a/core/res/res/drawable/ic_jog_dial_answer.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/ic_jog_dial_decline.png b/core/res/res/drawable/ic_jog_dial_decline.png
deleted file mode 100644
index 81c76b5..0000000
--- a/core/res/res/drawable/ic_jog_dial_decline.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/ic_jog_dial_silence_ringer.png b/core/res/res/drawable/ic_jog_dial_silence_ringer.png
deleted file mode 100644
index 6d573e6..0000000
--- a/core/res/res/drawable/ic_jog_dial_silence_ringer.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/ic_jog_dial_turn_ring_vol_off.png b/core/res/res/drawable/ic_jog_dial_turn_ring_vol_off.png
deleted file mode 100644
index 3804c25..0000000
--- a/core/res/res/drawable/ic_jog_dial_turn_ring_vol_off.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/ic_jog_dial_turn_ring_vol_on.png b/core/res/res/drawable/ic_jog_dial_turn_ring_vol_on.png
deleted file mode 100644
index 62f8e15..0000000
--- a/core/res/res/drawable/ic_jog_dial_turn_ring_vol_on.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/jog_dial_bg_cropped.png b/core/res/res/drawable/jog_dial_bg_cropped.png
deleted file mode 100644
index 60d93d2..0000000
--- a/core/res/res/drawable/jog_dial_bg_cropped.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/layout/keyguard_screen_rotary_unlock_land.xml b/core/res/res/layout/keyguard_screen_rotary_unlock_land.xml
new file mode 100644
index 0000000..5fe1dde
--- /dev/null
+++ b/core/res/res/layout/keyguard_screen_rotary_unlock_land.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2009, 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.
+*/
+-->
+
+<!-- This is the general lock screen which shows information about the
+ state of the device, as well as instructions on how to get past it
+ depending on the state of the device.-->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:rotaryunlock="http://schemas.android.com/apk/res/com.android.rotaryunlock"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:id="@+id/root"
+ >
+<LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:background="#A0000000"
+ >
+
+ <!-- left side -->
+ <RelativeLayout
+ android:orientation="vertical"
+ android:layout_width="0dip"
+ android:layout_height="fill_parent"
+ android:layout_weight="1.0"
+ android:gravity="center_horizontal"
+ >
+
+ <TextView
+ android:id="@+id/carrier"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_centerHorizontal="true"
+ android:layout_marginTop="20dip"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textColor="?android:attr/textColorSecondary"
+ />
+
+ <TextView
+ android:id="@+id/time"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/carrier"
+ android:layout_centerHorizontal="true"
+ android:layout_marginTop="25dip"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:textSize="55sp"
+ />
+
+ <TextView
+ android:id="@+id/date"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/time"
+ android:layout_centerHorizontal="true"
+ android:layout_marginTop="-12dip"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ />
+
+ <View
+ android:id="@+id/divider"
+ android:layout_width="fill_parent"
+ android:layout_height="1dip"
+ android:layout_marginTop="10dip"
+ android:layout_below="@id/date"
+ android:background="@android:drawable/divider_horizontal_dark"
+ />
+
+ <TextView
+ android:id="@+id/status1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/divider"
+ android:layout_centerHorizontal="true"
+ android:layout_marginTop="6dip"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textColor="?android:attr/textColorSecondary"
+ android:drawablePadding="4dip"
+ />
+
+ <TextView
+ android:id="@+id/status2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/status1"
+ android:layout_centerHorizontal="true"
+ android:layout_marginTop="6dip"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textColor="?android:attr/textColorSecondary"
+ android:drawablePadding="4dip"
+ />
+
+ <TextView
+ android:id="@+id/screenLocked"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/status2"
+ android:layout_centerHorizontal="true"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textColor="?android:attr/textColorSecondary"
+ android:gravity="center"
+ android:layout_marginTop="12dip"
+ />
+ <!-- emergency call button shown when sim is missing or PUKd -->
+ <Button
+ android:id="@+id/emergencyCallButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/screenLocked"
+ android:layout_centerHorizontal="true"
+ android:layout_marginTop="24dip"
+ android:drawableLeft="@drawable/ic_emergency"
+ android:drawablePadding="8dip"
+ />
+ </RelativeLayout>
+
+
+ <!-- right side -->
+ <com.android.internal.widget.RotarySelector
+ android:id="@+id/rotary"
+ android:layout_width="wrap_content"
+ android:layout_height="fill_parent"
+ android:orientation="vertical"
+ />
+
+
+</LinearLayout>
+</FrameLayout> \ No newline at end of file
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index df2a715..f5b8ab6 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2295,6 +2295,14 @@
<attr name="layout_scale" format="float" />
</declare-styleable>
+ <!-- attributes for internal rotary widget used in lock screen and phone app
+ @hide -->
+ <declare-styleable name="RotarySelector">
+ <!-- Use "horizontal" or "vertical". The default is horizontal. -->
+ <attr name="orientation" />
+ </declare-styleable>
+
+
<!-- ========================= -->
<!-- Drawable class attributes -->
<!-- ========================= -->