Merge change Ia895aa7d into eclair
* changes: Fix for 2209086: Initial pass at new SlidingTab widget and integration into LockScreen.
626
core/java/com/android/internal/widget/SlidingTab.java
Normal file
@@ -0,0 +1,626 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.internal.widget;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.os.Vibrator;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.ImageView.ScaleType;
|
||||||
|
import com.android.internal.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A special widget containing two Sliders and a threshold for each. Moving either slider beyond
|
||||||
|
* the threshold will cause the registered OnTriggerListener.onTrigger() to be called with
|
||||||
|
* {@link OnTriggerListener#LEFT_HANDLE} or {@link OnTriggerListener#RIGHT_HANDLE} to be called.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SlidingTab extends ViewGroup {
|
||||||
|
private static final String LOG_TAG = "SlidingTab";
|
||||||
|
private static final boolean DBG = false;
|
||||||
|
private static final int HORIZONTAL = 0; // as defined in attrs.xml
|
||||||
|
private static final int VERTICAL = 1;
|
||||||
|
private static final int MSG_ANIMATE = 100;
|
||||||
|
|
||||||
|
// TODO: Make these configurable
|
||||||
|
private static final float TARGET_ZONE = 2.0f / 3.0f;
|
||||||
|
private static final long VIBRATE_SHORT = 30;
|
||||||
|
private static final long VIBRATE_LONG = 40;
|
||||||
|
|
||||||
|
private OnTriggerListener mOnTriggerListener;
|
||||||
|
private int mGrabbedState = OnTriggerListener.NO_HANDLE;
|
||||||
|
private boolean mTriggered = false;
|
||||||
|
private Vibrator mVibrator;
|
||||||
|
private float mDensity; // used to scale dimensions for bitmaps.
|
||||||
|
|
||||||
|
private final SlidingTabHandler mHandler = new SlidingTabHandler();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Either {@link #HORIZONTAL} or {@link #VERTICAL}.
|
||||||
|
*/
|
||||||
|
private int mOrientation;
|
||||||
|
|
||||||
|
private Slider mLeftSlider;
|
||||||
|
private Slider mRightSlider;
|
||||||
|
private Slider mCurrentSlider;
|
||||||
|
private boolean mTracking;
|
||||||
|
private float mTargetZone;
|
||||||
|
private Slider mOtherSlider;
|
||||||
|
private boolean mAnimating;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface definition for a callback to be invoked when a tab is triggered
|
||||||
|
* by moving it beyond a target zone.
|
||||||
|
*/
|
||||||
|
public interface OnTriggerListener {
|
||||||
|
/**
|
||||||
|
* The interface was triggered because the user let go of the handle without reaching the
|
||||||
|
* target zone.
|
||||||
|
*/
|
||||||
|
public static final int NO_HANDLE = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The interface was triggered because the user grabbed the left handle and moved it past
|
||||||
|
* the target zone.
|
||||||
|
*/
|
||||||
|
public static final int LEFT_HANDLE = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The interface was triggered because the user grabbed the right handle and moved it past
|
||||||
|
* the target zone.
|
||||||
|
*/
|
||||||
|
public static final int RIGHT_HANDLE = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the user moves a handle beyond the target zone.
|
||||||
|
*
|
||||||
|
* @param v The view that was triggered.
|
||||||
|
* @param whichHandle Which "dial handle" the user grabbed,
|
||||||
|
* either {@link #LEFT_HANDLE}, {@link #RIGHT_HANDLE}.
|
||||||
|
*/
|
||||||
|
void onTrigger(View v, int whichHandle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the "grabbed state" changes (i.e. when the user either grabs or releases
|
||||||
|
* one of the handles.)
|
||||||
|
*
|
||||||
|
* @param v the view that was triggered
|
||||||
|
* @param grabbedState the new state: {@link #NO_HANDLE}, {@link #LEFT_HANDLE},
|
||||||
|
* or {@link #RIGHT_HANDLE}.
|
||||||
|
*/
|
||||||
|
void onGrabbedStateChange(View v, int grabbedState);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple container class for all things pertinent to a slider.
|
||||||
|
* A slider consists of 3 Views:
|
||||||
|
*
|
||||||
|
* {@link #tab} is the tab shown on the screen in the default state.
|
||||||
|
* {@link #text} is the view revealed as the user slides the tab out.
|
||||||
|
* {@link #target} is the target the user must drag the slider past to trigger the slider.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static class Slider {
|
||||||
|
/**
|
||||||
|
* Tab alignment - determines which side the tab should be drawn on
|
||||||
|
*/
|
||||||
|
public static final int ALIGN_LEFT = 0;
|
||||||
|
public static final int ALIGN_RIGHT = 1;
|
||||||
|
public static final int ALIGN_TOP = 2;
|
||||||
|
public static final int ALIGN_BOTTOM = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* States for the view.
|
||||||
|
*/
|
||||||
|
private static final int STATE_NORMAL = 0;
|
||||||
|
private static final int STATE_PRESSED = 1;
|
||||||
|
private static final int STATE_ACTIVE = 2;
|
||||||
|
|
||||||
|
private final ImageView tab;
|
||||||
|
private final TextView text;
|
||||||
|
private final ImageView target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param parent the container view of this one
|
||||||
|
* @param tabId drawable for the tab
|
||||||
|
* @param barId drawable for the bar
|
||||||
|
* @param targetId drawable for the target
|
||||||
|
*/
|
||||||
|
Slider(ViewGroup parent, int tabId, int barId, int targetId) {
|
||||||
|
// Create tab
|
||||||
|
tab = new ImageView(parent.getContext());
|
||||||
|
tab.setBackgroundResource(tabId);
|
||||||
|
tab.setScaleType(ScaleType.CENTER);
|
||||||
|
tab.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
|
||||||
|
LayoutParams.WRAP_CONTENT));
|
||||||
|
|
||||||
|
// Create hint TextView
|
||||||
|
text = new TextView(parent.getContext());
|
||||||
|
text.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
|
||||||
|
LayoutParams.FILL_PARENT));
|
||||||
|
text.setBackgroundResource(barId);
|
||||||
|
text.setTextAppearance(parent.getContext(), R.style.TextAppearance_SlidingTabNormal);
|
||||||
|
// hint.setSingleLine(); // Hmm.. this causes the text to disappear off-screen
|
||||||
|
|
||||||
|
// Create target
|
||||||
|
target = new ImageView(parent.getContext());
|
||||||
|
target.setImageResource(targetId);
|
||||||
|
target.setScaleType(ScaleType.CENTER);
|
||||||
|
target.setLayoutParams(
|
||||||
|
new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
|
||||||
|
target.setVisibility(View.INVISIBLE);
|
||||||
|
|
||||||
|
parent.addView(target); // this needs to be first - relies on painter's algorithm
|
||||||
|
parent.addView(tab);
|
||||||
|
parent.addView(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setIcon(int iconId) {
|
||||||
|
tab.setImageResource(iconId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTabBackgroundResource(int tabId) {
|
||||||
|
tab.setBackgroundResource(tabId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBarBackgroundResource(int barId) {
|
||||||
|
text.setBackgroundResource(barId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setHintText(int resId) {
|
||||||
|
// TODO: Text should be blank if widget is vertical
|
||||||
|
text.setText(resId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hide() {
|
||||||
|
// TODO: Animate off the screen
|
||||||
|
text.setVisibility(View.INVISIBLE);
|
||||||
|
tab.setVisibility(View.INVISIBLE);
|
||||||
|
target.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setState(int state) {
|
||||||
|
text.setPressed(state == STATE_PRESSED);
|
||||||
|
tab.setPressed(state == STATE_PRESSED);
|
||||||
|
if (state == STATE_ACTIVE) {
|
||||||
|
final int[] activeState = new int[] {com.android.internal.R.attr.state_active};
|
||||||
|
if (text.getBackground().isStateful()) {
|
||||||
|
text.getBackground().setState(activeState);
|
||||||
|
}
|
||||||
|
if (tab.getBackground().isStateful()) {
|
||||||
|
tab.getBackground().setState(activeState);
|
||||||
|
}
|
||||||
|
text.setTextAppearance(text.getContext(), R.style.TextAppearance_SlidingTabActive);
|
||||||
|
} else {
|
||||||
|
text.setTextAppearance(text.getContext(), R.style.TextAppearance_SlidingTabNormal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void showTarget() {
|
||||||
|
target.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
setState(STATE_NORMAL);
|
||||||
|
text.setVisibility(View.VISIBLE);
|
||||||
|
text.setTextAppearance(text.getContext(), R.style.TextAppearance_SlidingTabNormal);
|
||||||
|
tab.setVisibility(View.VISIBLE);
|
||||||
|
target.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTarget(int targetId) {
|
||||||
|
target.setImageResource(targetId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Layout the given widgets within the parent.
|
||||||
|
*
|
||||||
|
* @param l the parent's left border
|
||||||
|
* @param t the parent's top border
|
||||||
|
* @param r the parent's right border
|
||||||
|
* @param b the parent's bottom border
|
||||||
|
* @param alignment which side to align the widget to
|
||||||
|
*/
|
||||||
|
void layout(int l, int t, int r, int b, int alignment) {
|
||||||
|
final int handleWidth = tab.getBackground().getIntrinsicWidth();
|
||||||
|
final int handleHeight = tab.getBackground().getIntrinsicHeight();
|
||||||
|
final int targetWidth = target.getDrawable().getIntrinsicWidth();
|
||||||
|
final int targetHeight = target.getDrawable().getIntrinsicHeight();
|
||||||
|
final int parentWidth = r - l;
|
||||||
|
final int parentHeight = b - t;
|
||||||
|
|
||||||
|
final int leftTarget = (int) (TARGET_ZONE * parentWidth) - targetWidth + handleWidth / 2;
|
||||||
|
final int rightTarget = (int) ((1.0f - TARGET_ZONE) * parentWidth) - handleWidth / 2;
|
||||||
|
final int left = (parentWidth - handleWidth) / 2;
|
||||||
|
final int right = left + handleWidth;
|
||||||
|
|
||||||
|
if (alignment == ALIGN_LEFT || alignment == ALIGN_RIGHT) {
|
||||||
|
// horizontal
|
||||||
|
final int targetTop = (parentHeight - targetHeight) / 2;
|
||||||
|
final int targetBottom = targetTop + targetHeight;
|
||||||
|
final int top = (parentHeight - handleHeight) / 2;
|
||||||
|
final int bottom = (parentHeight + handleHeight) / 2;
|
||||||
|
if (alignment == ALIGN_LEFT) {
|
||||||
|
tab.layout(0, top, handleWidth, bottom);
|
||||||
|
text.layout(0 - parentWidth, top, 0, bottom);
|
||||||
|
text.setGravity(Gravity.RIGHT);
|
||||||
|
target.layout(leftTarget, targetTop, leftTarget + targetWidth, targetBottom);
|
||||||
|
} else {
|
||||||
|
tab.layout(parentWidth - handleWidth, top, parentWidth, bottom);
|
||||||
|
text.layout(parentWidth, top, parentWidth + parentWidth, bottom);
|
||||||
|
target.layout(rightTarget, targetTop, rightTarget + targetWidth, targetBottom);
|
||||||
|
text.setGravity(Gravity.TOP);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// vertical
|
||||||
|
final int targetLeft = (parentWidth - targetWidth) / 2;
|
||||||
|
final int targetRight = (parentWidth + targetWidth) / 2;
|
||||||
|
final int top = (int) (TARGET_ZONE * parentHeight) + handleHeight / 2 - targetHeight;
|
||||||
|
final int bottom = (int) ((1.0f - TARGET_ZONE) * parentHeight) - handleHeight / 2;
|
||||||
|
if (alignment == ALIGN_TOP) {
|
||||||
|
tab.layout(left, 0, right, handleHeight);
|
||||||
|
text.layout(left, 0 - parentHeight, right, 0);
|
||||||
|
target.layout(targetLeft, top, targetRight, top + targetHeight);
|
||||||
|
} else {
|
||||||
|
tab.layout(left, parentHeight - handleHeight, right, parentHeight);
|
||||||
|
text.layout(left, parentHeight, right, parentHeight + parentHeight);
|
||||||
|
target.layout(targetLeft, bottom, targetRight, bottom + targetHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTabWidth() {
|
||||||
|
return tab.getDrawable().getIntrinsicWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTabHeight() {
|
||||||
|
return tab.getDrawable().getIntrinsicHeight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SlidingTab(Context context) {
|
||||||
|
this(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor used when this widget is created from a layout file.
|
||||||
|
*/
|
||||||
|
public SlidingTab(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
|
||||||
|
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SlidingTab);
|
||||||
|
mOrientation = a.getInt(R.styleable.SlidingTab_orientation, HORIZONTAL);
|
||||||
|
a.recycle();
|
||||||
|
|
||||||
|
Resources r = getResources();
|
||||||
|
mDensity = r.getDisplayMetrics().density;
|
||||||
|
if (DBG) log("- Density: " + mDensity);
|
||||||
|
|
||||||
|
mLeftSlider = new Slider(this,
|
||||||
|
R.drawable.jog_tab_left_generic,
|
||||||
|
R.drawable.jog_tab_bar_left_generic,
|
||||||
|
R.drawable.jog_tab_target_gray);
|
||||||
|
mRightSlider = new Slider(this,
|
||||||
|
R.drawable.jog_tab_right_generic,
|
||||||
|
R.drawable.jog_tab_bar_right_generic,
|
||||||
|
R.drawable.jog_tab_target_gray);
|
||||||
|
|
||||||
|
// setBackgroundColor(0x80808080);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
|
||||||
|
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
|
||||||
|
|
||||||
|
int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
|
||||||
|
int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
|
||||||
|
|
||||||
|
if (widthSpecMode == MeasureSpec.UNSPECIFIED || heightSpecMode == MeasureSpec.UNSPECIFIED) {
|
||||||
|
throw new RuntimeException(LOG_TAG + " cannot have UNSPECIFIED dimensions");
|
||||||
|
}
|
||||||
|
|
||||||
|
final int leftTabWidth = (int) (mDensity * mLeftSlider.getTabWidth() + 0.5f);
|
||||||
|
final int rightTabWidth = (int) (mDensity * mRightSlider.getTabWidth() + 0.5f);
|
||||||
|
final int leftTabHeight = (int) (mDensity * mLeftSlider.getTabHeight() + 0.5f);
|
||||||
|
final int rightTabHeight = (int) (mDensity * mRightSlider.getTabHeight() + 0.5f);
|
||||||
|
final int width;
|
||||||
|
final int height;
|
||||||
|
if (isHorizontal()) {
|
||||||
|
width = Math.max(widthSpecSize, leftTabWidth + rightTabWidth);
|
||||||
|
height = Math.max(leftTabHeight, rightTabHeight);
|
||||||
|
} else {
|
||||||
|
width = Math.max(leftTabWidth, rightTabHeight);
|
||||||
|
height = Math.max(heightSpecSize, leftTabHeight + rightTabHeight);
|
||||||
|
}
|
||||||
|
setMeasuredDimension(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onInterceptTouchEvent(MotionEvent event) {
|
||||||
|
final int action = event.getAction();
|
||||||
|
final float x = event.getX();
|
||||||
|
final float y = event.getY();
|
||||||
|
|
||||||
|
final Rect frame = new Rect();
|
||||||
|
|
||||||
|
if (mAnimating) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
View leftHandle = mLeftSlider.tab;
|
||||||
|
leftHandle.getHitRect(frame);
|
||||||
|
boolean leftHit = frame.contains((int) x, (int) y);
|
||||||
|
|
||||||
|
View rightHandle = mRightSlider.tab;
|
||||||
|
rightHandle.getHitRect(frame);
|
||||||
|
boolean rightHit = frame.contains((int)x, (int) y);
|
||||||
|
|
||||||
|
if (!mTracking && !(leftHit || rightHit)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case MotionEvent.ACTION_DOWN: {
|
||||||
|
mTracking = true;
|
||||||
|
mTriggered = false;
|
||||||
|
vibrate(VIBRATE_SHORT);
|
||||||
|
if (leftHit) {
|
||||||
|
mCurrentSlider = mLeftSlider;
|
||||||
|
mOtherSlider = mRightSlider;
|
||||||
|
mTargetZone = isHorizontal() ? TARGET_ZONE : 1.0f - TARGET_ZONE;
|
||||||
|
setGrabbedState(OnTriggerListener.LEFT_HANDLE);
|
||||||
|
} else {
|
||||||
|
mCurrentSlider = mRightSlider;
|
||||||
|
mOtherSlider = mLeftSlider;
|
||||||
|
mTargetZone = isHorizontal() ? 1.0f - TARGET_ZONE : TARGET_ZONE;
|
||||||
|
setGrabbedState(OnTriggerListener.RIGHT_HANDLE);
|
||||||
|
}
|
||||||
|
mCurrentSlider.setState(Slider.STATE_PRESSED);
|
||||||
|
mCurrentSlider.showTarget();
|
||||||
|
mOtherSlider.hide();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
|
if (mTracking) {
|
||||||
|
final int action = event.getAction();
|
||||||
|
final float x = event.getX();
|
||||||
|
final float y = event.getY();
|
||||||
|
final View handle = mCurrentSlider.tab;
|
||||||
|
switch (action) {
|
||||||
|
case MotionEvent.ACTION_MOVE:
|
||||||
|
moveHandle(x, y);
|
||||||
|
float position = isHorizontal() ? x : y;
|
||||||
|
float target = mTargetZone * (isHorizontal() ? getWidth() : getHeight());
|
||||||
|
boolean targetZoneReached;
|
||||||
|
if (isHorizontal()) {
|
||||||
|
targetZoneReached = mCurrentSlider == mLeftSlider ?
|
||||||
|
position > target : position < target;
|
||||||
|
} else {
|
||||||
|
targetZoneReached = mCurrentSlider == mLeftSlider ?
|
||||||
|
position < target : position > target;
|
||||||
|
}
|
||||||
|
if (!mTriggered && targetZoneReached) {
|
||||||
|
mTriggered = true;
|
||||||
|
mTracking = false;
|
||||||
|
mCurrentSlider.setState(Slider.STATE_ACTIVE);
|
||||||
|
dispatchTriggerEvent(mCurrentSlider == mLeftSlider ?
|
||||||
|
OnTriggerListener.LEFT_HANDLE : OnTriggerListener.RIGHT_HANDLE);
|
||||||
|
|
||||||
|
// TODO: This is a place holder for the real animation. It just holds
|
||||||
|
// the screen for 500ms.
|
||||||
|
mAnimating = true;
|
||||||
|
mHandler.postDelayed(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
resetView();
|
||||||
|
mAnimating = false;
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isHorizontal() && (y <= handle.getBottom() && y >= handle.getTop()) ||
|
||||||
|
!isHorizontal() && (x >= handle.getLeft() && x <= handle.getRight()) ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Intentionally fall through - we're outside tracking rectangle
|
||||||
|
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
case MotionEvent.ACTION_CANCEL:
|
||||||
|
mTracking = false;
|
||||||
|
mTriggered = false;
|
||||||
|
resetView();
|
||||||
|
setGrabbedState(OnTriggerListener.NO_HANDLE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mTracking || super.onTouchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isHorizontal() {
|
||||||
|
return mOrientation == HORIZONTAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetView() {
|
||||||
|
mLeftSlider.reset();
|
||||||
|
mRightSlider.reset();
|
||||||
|
onLayout(true, getLeft(), getTop(), getLeft() + getWidth(), getTop() + getHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||||
|
if (!changed) return;
|
||||||
|
|
||||||
|
// Center the widgets in the view
|
||||||
|
mLeftSlider.layout(l, t, r, b, isHorizontal() ? Slider.ALIGN_LEFT : Slider.ALIGN_BOTTOM);
|
||||||
|
mRightSlider.layout(l, t, r, b, isHorizontal() ? Slider.ALIGN_RIGHT : Slider.ALIGN_TOP);
|
||||||
|
|
||||||
|
invalidate(); // TODO: be more conservative about what we're invalidating
|
||||||
|
}
|
||||||
|
|
||||||
|
private void moveHandle(float x, float y) {
|
||||||
|
final View handle = mCurrentSlider.tab;
|
||||||
|
final View content = mCurrentSlider.text;
|
||||||
|
if (isHorizontal()) {
|
||||||
|
int deltaX = (int) x - handle.getLeft() - (handle.getWidth() / 2);
|
||||||
|
handle.offsetLeftAndRight(deltaX);
|
||||||
|
content.offsetLeftAndRight(deltaX);
|
||||||
|
} else {
|
||||||
|
int deltaY = (int) y - handle.getTop() - (handle.getHeight() / 2);
|
||||||
|
handle.offsetTopAndBottom(deltaY);
|
||||||
|
content.offsetTopAndBottom(deltaY);
|
||||||
|
}
|
||||||
|
invalidate(); // TODO: be more conservative about what we're invalidating
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the left handle icon to a given resource.
|
||||||
|
*
|
||||||
|
* The resource should refer to a Drawable object, or use 0 to remove
|
||||||
|
* the icon.
|
||||||
|
*
|
||||||
|
* @param iconId the resource ID of the icon drawable
|
||||||
|
* @param targetId the resource of the target drawable
|
||||||
|
* @param barId the resource of the bar drawable (stateful)
|
||||||
|
* @param tabId the resource of the
|
||||||
|
*/
|
||||||
|
public void setLeftTabResources(int iconId, int targetId, int barId, int tabId) {
|
||||||
|
mLeftSlider.setIcon(iconId);
|
||||||
|
mLeftSlider.setTarget(targetId);
|
||||||
|
mLeftSlider.setBarBackgroundResource(barId);
|
||||||
|
mLeftSlider.setTabBackgroundResource(tabId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the left handle hint text to a given resource string.
|
||||||
|
*
|
||||||
|
* @param resId
|
||||||
|
*/
|
||||||
|
public void setLeftHintText(int resId) {
|
||||||
|
mLeftSlider.setHintText(resId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the right handle icon to a given resource.
|
||||||
|
*
|
||||||
|
* The resource should refer to a Drawable object, or use 0 to remove
|
||||||
|
* the icon.
|
||||||
|
*
|
||||||
|
* @param iconId the resource ID of the icon drawable
|
||||||
|
* @param targetId the resource of the target drawable
|
||||||
|
* @param barId the resource of the bar drawable (stateful)
|
||||||
|
* @param tabId the resource of the
|
||||||
|
*/
|
||||||
|
public void setRightTabResources(int iconId, int targetId, int barId, int tabId) {
|
||||||
|
mRightSlider.setIcon(iconId);
|
||||||
|
mRightSlider.setTarget(targetId);
|
||||||
|
mRightSlider.setBarBackgroundResource(barId);
|
||||||
|
mRightSlider.setTabBackgroundResource(tabId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the left handle hint text to a given resource string.
|
||||||
|
*
|
||||||
|
* @param resId
|
||||||
|
*/
|
||||||
|
public void setRightHintText(int resId) {
|
||||||
|
mRightSlider.setHintText(resId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggers haptic feedback.
|
||||||
|
*/
|
||||||
|
private synchronized void vibrate(long duration) {
|
||||||
|
if (mVibrator == null) {
|
||||||
|
mVibrator = (android.os.Vibrator)
|
||||||
|
getContext().getSystemService(Context.VIBRATOR_SERVICE);
|
||||||
|
}
|
||||||
|
mVibrator.vibrate(duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a callback to be invoked when the user triggers an event.
|
||||||
|
*
|
||||||
|
* @param listener the OnDialTriggerListener to attach to this view
|
||||||
|
*/
|
||||||
|
public void setOnTriggerListener(OnTriggerListener listener) {
|
||||||
|
mOnTriggerListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatches a trigger event to listener. Ignored if a listener is not set.
|
||||||
|
* @param whichHandle the handle that triggered the event.
|
||||||
|
*/
|
||||||
|
private void dispatchTriggerEvent(int whichHandle) {
|
||||||
|
vibrate(VIBRATE_LONG);
|
||||||
|
if (mOnTriggerListener != null) {
|
||||||
|
mOnTriggerListener.onTrigger(this, whichHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current grabbed state, and dispatches a grabbed state change
|
||||||
|
* event to our listener.
|
||||||
|
*/
|
||||||
|
private void setGrabbedState(int newState) {
|
||||||
|
if (newState != mGrabbedState) {
|
||||||
|
mGrabbedState = newState;
|
||||||
|
if (mOnTriggerListener != null) {
|
||||||
|
mOnTriggerListener.onGrabbedStateChange(this, mGrabbedState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SlidingTabHandler extends Handler {
|
||||||
|
public void handleMessage(Message m) {
|
||||||
|
switch (m.what) {
|
||||||
|
case MSG_ANIMATE:
|
||||||
|
doAnimation();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doAnimation() {
|
||||||
|
if (mAnimating) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void log(String msg) {
|
||||||
|
Log.d(LOG_TAG, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
core/res/res/drawable-hdpi/jog_tab_bar_confirm_gray.9.png
Normal file
|
After Width: | Height: | Size: 390 B |
BIN
core/res/res/drawable-hdpi/jog_tab_bar_confirm_green.9.png
Normal file
|
After Width: | Height: | Size: 470 B |
BIN
core/res/res/drawable-hdpi/jog_tab_bar_confirm_red.9.png
Normal file
|
After Width: | Height: | Size: 463 B |
BIN
core/res/res/drawable-hdpi/jog_tab_bar_confirm_yellow.9.png
Normal file
|
After Width: | Height: | Size: 476 B |
BIN
core/res/res/drawable-hdpi/jog_tab_bar_normal.9.png
Normal file
|
After Width: | Height: | Size: 492 B |
BIN
core/res/res/drawable-hdpi/jog_tab_bar_pressed.9.png
Normal file
|
After Width: | Height: | Size: 462 B |
BIN
core/res/res/drawable-hdpi/jog_tab_left_confirm_gray.png
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
BIN
core/res/res/drawable-hdpi/jog_tab_left_confirm_green.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
core/res/res/drawable-hdpi/jog_tab_left_confirm_red.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
core/res/res/drawable-hdpi/jog_tab_left_confirm_yellow.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
core/res/res/drawable-hdpi/jog_tab_left_normal.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
core/res/res/drawable-hdpi/jog_tab_left_pressed.png
Normal file
|
After Width: | Height: | Size: 9.7 KiB |
BIN
core/res/res/drawable-hdpi/jog_tab_right_confirm_gray.png
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
core/res/res/drawable-hdpi/jog_tab_right_confirm_green.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
core/res/res/drawable-hdpi/jog_tab_right_confirm_red.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
core/res/res/drawable-hdpi/jog_tab_right_confirm_yellow.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
core/res/res/drawable-hdpi/jog_tab_right_normal.png
Normal file
|
After Width: | Height: | Size: 9.5 KiB |
BIN
core/res/res/drawable-hdpi/jog_tab_right_pressed.png
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
core/res/res/drawable-hdpi/jog_tab_target_gray.png
Normal file
|
After Width: | Height: | Size: 931 B |
BIN
core/res/res/drawable-hdpi/jog_tab_target_green.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
core/res/res/drawable-hdpi/jog_tab_target_red.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
core/res/res/drawable-hdpi/jog_tab_target_yellow.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
core/res/res/drawable-land-hdpi/btn_lock_normal.9.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
core/res/res/drawable-land-hdpi/ic_jog_dial_sound_off.png
Executable file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
core/res/res/drawable-land-hdpi/ic_jog_dial_sound_on.png
Executable file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
core/res/res/drawable-land-hdpi/ic_jog_dial_unlock.png
Executable file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
core/res/res/drawable-land-hdpi/jog_tab_bar_confirm_gray.9.png
Normal file
|
After Width: | Height: | Size: 491 B |
BIN
core/res/res/drawable-land-hdpi/jog_tab_bar_confirm_green.9.png
Normal file
|
After Width: | Height: | Size: 561 B |
BIN
core/res/res/drawable-land-hdpi/jog_tab_bar_confirm_red.9.png
Normal file
|
After Width: | Height: | Size: 560 B |
BIN
core/res/res/drawable-land-hdpi/jog_tab_bar_confirm_yellow.9.png
Normal file
|
After Width: | Height: | Size: 569 B |
BIN
core/res/res/drawable-land-hdpi/jog_tab_bar_normal.9.png
Normal file
|
After Width: | Height: | Size: 586 B |
BIN
core/res/res/drawable-land-hdpi/jog_tab_bar_pressed.9.png
Normal file
|
After Width: | Height: | Size: 554 B |
BIN
core/res/res/drawable-land-hdpi/jog_tab_left_confirm_gray.png
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
BIN
core/res/res/drawable-land-hdpi/jog_tab_left_confirm_green.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
core/res/res/drawable-land-hdpi/jog_tab_left_confirm_red.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
core/res/res/drawable-land-hdpi/jog_tab_left_confirm_yellow.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
core/res/res/drawable-land-hdpi/jog_tab_left_normal.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
core/res/res/drawable-land-hdpi/jog_tab_left_pressed.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
core/res/res/drawable-land-hdpi/jog_tab_right_confirm_gray.png
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
BIN
core/res/res/drawable-land-hdpi/jog_tab_right_confirm_green.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
core/res/res/drawable-land-hdpi/jog_tab_right_confirm_red.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
core/res/res/drawable-land-hdpi/jog_tab_right_confirm_yellow.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
core/res/res/drawable-land-hdpi/jog_tab_right_normal.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
core/res/res/drawable-land-hdpi/jog_tab_right_pressed.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
core/res/res/drawable-land-hdpi/jog_tab_target_gray.png
Normal file
|
After Width: | Height: | Size: 959 B |
BIN
core/res/res/drawable-land-hdpi/jog_tab_target_green.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
core/res/res/drawable-land-hdpi/jog_tab_target_red.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
core/res/res/drawable-land-hdpi/jog_tab_target_yellow.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
28
core/res/res/drawable/jog_tab_bar_left_generic.xml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- StateListDrawable used for buttons in the in-call onscreen touch UI. -->
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_pressed="true"
|
||||||
|
android:drawable="@drawable/jog_tab_bar_pressed" />
|
||||||
|
|
||||||
|
<item android:state_enabled="true"
|
||||||
|
android:drawable="@drawable/jog_tab_bar_normal" />
|
||||||
|
|
||||||
|
<item android:state_active="true"
|
||||||
|
android:drawable="@drawable/jog_tab_bar_confirm_gray" />
|
||||||
|
|
||||||
|
</selector>
|
||||||
28
core/res/res/drawable/jog_tab_bar_left_unlock.xml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- StateListDrawable used for buttons in the in-call onscreen touch UI. -->
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_pressed="true"
|
||||||
|
android:drawable="@drawable/jog_tab_bar_pressed" />
|
||||||
|
|
||||||
|
<item android:state_enabled="true"
|
||||||
|
android:drawable="@drawable/jog_tab_bar_normal" />
|
||||||
|
|
||||||
|
<item android:state_active="true"
|
||||||
|
android:drawable="@drawable/jog_tab_bar_confirm_green" />
|
||||||
|
|
||||||
|
</selector>
|
||||||
28
core/res/res/drawable/jog_tab_bar_right_generic.xml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- StateListDrawable used for buttons in the in-call onscreen touch UI. -->
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_pressed="true"
|
||||||
|
android:drawable="@drawable/jog_tab_bar_pressed" />
|
||||||
|
|
||||||
|
<item android:state_enabled="true"
|
||||||
|
android:drawable="@drawable/jog_tab_bar_normal" />
|
||||||
|
|
||||||
|
<item android:state_active="true"
|
||||||
|
android:drawable="@drawable/jog_tab_bar_confirm_gray" />
|
||||||
|
|
||||||
|
</selector>
|
||||||
28
core/res/res/drawable/jog_tab_bar_right_sound_off.xml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- StateListDrawable used for buttons in the in-call onscreen touch UI. -->
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_pressed="true"
|
||||||
|
android:drawable="@drawable/jog_tab_bar_pressed" />
|
||||||
|
|
||||||
|
<item android:state_enabled="true"
|
||||||
|
android:drawable="@drawable/jog_tab_bar_normal" />
|
||||||
|
|
||||||
|
<item android:state_active="true"
|
||||||
|
android:drawable="@drawable/jog_tab_bar_confirm_gray" />
|
||||||
|
|
||||||
|
</selector>
|
||||||
28
core/res/res/drawable/jog_tab_bar_right_sound_on.xml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- StateListDrawable used for buttons in the in-call onscreen touch UI. -->
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_pressed="true"
|
||||||
|
android:drawable="@drawable/jog_tab_bar_pressed" />
|
||||||
|
|
||||||
|
<item android:state_enabled="true"
|
||||||
|
android:drawable="@drawable/jog_tab_bar_normal" />
|
||||||
|
|
||||||
|
<item android:state_active="true"
|
||||||
|
android:drawable="@drawable/jog_tab_bar_confirm_yellow" />
|
||||||
|
|
||||||
|
</selector>
|
||||||
28
core/res/res/drawable/jog_tab_left_generic.xml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- StateListDrawable used for buttons in the in-call onscreen touch UI. -->
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_pressed="true"
|
||||||
|
android:drawable="@drawable/jog_tab_left_pressed" />
|
||||||
|
|
||||||
|
<item android:state_enabled="true"
|
||||||
|
android:drawable="@drawable/jog_tab_left_normal" />
|
||||||
|
|
||||||
|
<item android:state_active="true"
|
||||||
|
android:drawable="@drawable/jog_tab_left_confirm_gray" />
|
||||||
|
|
||||||
|
</selector>
|
||||||
28
core/res/res/drawable/jog_tab_left_unlock.xml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- StateListDrawable used for buttons in the in-call onscreen touch UI. -->
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_pressed="true"
|
||||||
|
android:drawable="@drawable/jog_tab_left_pressed" />
|
||||||
|
|
||||||
|
<item android:state_enabled="true"
|
||||||
|
android:drawable="@drawable/jog_tab_left_normal" />
|
||||||
|
|
||||||
|
<item android:state_active="true"
|
||||||
|
android:drawable="@drawable/jog_tab_left_confirm_green" />
|
||||||
|
|
||||||
|
</selector>
|
||||||
28
core/res/res/drawable/jog_tab_right_generic.xml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- StateListDrawable used for buttons in the in-call onscreen touch UI. -->
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_pressed="true"
|
||||||
|
android:drawable="@drawable/jog_tab_right_pressed" />
|
||||||
|
|
||||||
|
<item android:state_enabled="true"
|
||||||
|
android:drawable="@drawable/jog_tab_right_normal" />
|
||||||
|
|
||||||
|
<item android:state_active="true"
|
||||||
|
android:drawable="@drawable/jog_tab_right_confirm_gray" />
|
||||||
|
|
||||||
|
</selector>
|
||||||
28
core/res/res/drawable/jog_tab_right_sound_off.xml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- StateListDrawable used for buttons in the in-call onscreen touch UI. -->
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_pressed="true"
|
||||||
|
android:drawable="@drawable/jog_tab_right_pressed" />
|
||||||
|
|
||||||
|
<item android:state_enabled="true"
|
||||||
|
android:drawable="@drawable/jog_tab_right_normal" />
|
||||||
|
|
||||||
|
<item android:state_active="true"
|
||||||
|
android:drawable="@drawable/jog_tab_right_confirm_gray" />
|
||||||
|
|
||||||
|
</selector>
|
||||||
28
core/res/res/drawable/jog_tab_right_sound_on.xml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- StateListDrawable used for buttons in the in-call onscreen touch UI. -->
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_pressed="true"
|
||||||
|
android:drawable="@drawable/jog_tab_right_pressed" />
|
||||||
|
|
||||||
|
<item android:state_enabled="true"
|
||||||
|
android:drawable="@drawable/jog_tab_right_normal" />
|
||||||
|
|
||||||
|
<item android:state_active="true"
|
||||||
|
android:drawable="@drawable/jog_tab_right_confirm_yellow" />
|
||||||
|
|
||||||
|
</selector>
|
||||||
129
core/res/res/layout/keyguard_screen_tab_unlock.xml
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
<?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. It is the same for landscape
|
||||||
|
and portrait.-->
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tabunlock="http://schemas.android.com/apk/res/com.android.tabunlock"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:id="@+id/root">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:background="#70000000"
|
||||||
|
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_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_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_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_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_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:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
|
android:gravity="center"
|
||||||
|
android:layout_marginTop="12dip"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<com.android.internal.widget.SlidingTab
|
||||||
|
android:id="@+id/tab_selector"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_marginBottom="50dip"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 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_marginTop="24dip"
|
||||||
|
android:drawableLeft="@drawable/ic_emergency"
|
||||||
|
android:drawablePadding="8dip"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
130
core/res/res/layout/keyguard_screen_tab_unlock_land.xml
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
<?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.-->
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tabunlock="http://schemas.android.com/apk/res/com.android.tabunlock"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:background="#70000000"
|
||||||
|
android:id="@+id/root">
|
||||||
|
|
||||||
|
<!-- left side -->
|
||||||
|
<RelativeLayout
|
||||||
|
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_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_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_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_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_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: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_marginTop="24dip"
|
||||||
|
android:drawableLeft="@drawable/ic_emergency"
|
||||||
|
android:drawablePadding="8dip"
|
||||||
|
/>
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<!-- right side -->
|
||||||
|
<com.android.internal.widget.SlidingTab
|
||||||
|
android:id="@+id/tab_selector"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_marginBottom="50dip"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@@ -3559,4 +3559,14 @@
|
|||||||
<attr name="detailSocialSummary" format="boolean" />
|
<attr name="detailSocialSummary" format="boolean" />
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
|
|
||||||
|
<!-- =============================== -->
|
||||||
|
<!-- TabSelector class attributes -->
|
||||||
|
<!-- =============================== -->
|
||||||
|
<eat-comment />
|
||||||
|
|
||||||
|
<declare-styleable name="SlidingTab">
|
||||||
|
<!-- Use "horizontal" for a row, "vertical" for a column. The default is horizontal. -->
|
||||||
|
<attr name="orientation" />
|
||||||
|
</declare-styleable>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -84,6 +84,10 @@
|
|||||||
<color name="search_url_text_selected">@android:color/black</color>
|
<color name="search_url_text_selected">@android:color/black</color>
|
||||||
<color name="search_url_text_pressed">@android:color/black</color>
|
<color name="search_url_text_pressed">@android:color/black</color>
|
||||||
<color name="search_widget_corpus_item_background">@android:color/lighter_gray</color>
|
<color name="search_widget_corpus_item_background">@android:color/lighter_gray</color>
|
||||||
|
|
||||||
|
<!-- SlidingTab -->
|
||||||
|
<color name="sliding_tab_text_color_active">@android:color/black</color>
|
||||||
|
<color name="sliding_tab_text_color_shadow">@android:color/black</color>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
||||||
|
|||||||
@@ -1434,6 +1434,10 @@
|
|||||||
|
|
||||||
<!-- Displayed in a progress dialog while a username and password are being checked. -->
|
<!-- Displayed in a progress dialog while a username and password are being checked. -->
|
||||||
<string name="lockscreen_glogin_checking_password">Checking...</string>
|
<string name="lockscreen_glogin_checking_password">Checking...</string>
|
||||||
|
<!-- Displayed on lock screen's left tab - unlock -->
|
||||||
|
<string name="lockscreen_unlock_label">Unlock</string>
|
||||||
|
<!-- Displayed on lock screen's right tab - mute/unmute -->
|
||||||
|
<string name="lockscreen_mute_unmute_label">Sound</string>
|
||||||
|
|
||||||
<!-- A format string for 12-hour time of day, just the hour, not the minute, with lower-case "am" or "pm" (example: "3pm"). -->
|
<!-- A format string for 12-hour time of day, just the hour, not the minute, with lower-case "am" or "pm" (example: "3pm"). -->
|
||||||
<string name="hour_ampm">"<xliff:g id="hour" example="3">%-l</xliff:g><xliff:g id="ampm" example="pm">%P</xliff:g>"</string>
|
<string name="hour_ampm">"<xliff:g id="hour" example="3">%-l</xliff:g><xliff:g id="ampm" example="pm">%P</xliff:g>"</string>
|
||||||
|
|||||||
@@ -676,6 +676,25 @@
|
|||||||
<style name="TextAppearance.Widget.TextView.SpinnerItem">
|
<style name="TextAppearance.Widget.TextView.SpinnerItem">
|
||||||
<item name="android:textColor">@android:color/primary_text_light_disable_only</item>
|
<item name="android:textColor">@android:color/primary_text_light_disable_only</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<!-- @hide -->
|
||||||
|
<style name="TextAppearance.SlidingTabNormal"
|
||||||
|
parent="@android:attr/textAppearanceMedium">
|
||||||
|
<item name="android:textColor">?android:attr/textColorTertiary</item>
|
||||||
|
<item name="android:textSize">28sp</item>
|
||||||
|
<item name="android:shadowColor">@android:color/sliding_tab_text_color_shadow</item>
|
||||||
|
<item name="android:shadowDx">0.0</item>
|
||||||
|
<item name="android:shadowDy">1.0</item>
|
||||||
|
<item name="android:shadowRadius">5.0</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- @hide -->
|
||||||
|
<style name="TextAppearance.SlidingTabActive"
|
||||||
|
parent="@android:attr/textAppearanceMedium">
|
||||||
|
<item name="android:textColor">@android:color/sliding_tab_text_color_active</item>
|
||||||
|
<item name="android:textSize">28sp</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
<!-- @hide -->
|
<!-- @hide -->
|
||||||
<style name="TextAppearance.SearchResult">
|
<style name="TextAppearance.SearchResult">
|
||||||
|
|||||||