186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato/* 286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato * Copyright (C) 2008 The Android Open Source Project 386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato * 486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato * Licensed under the Apache License, Version 2.0 (the "License"); 586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato * you may not use this file except in compliance with the License. 686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato * You may obtain a copy of the License at 786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato * 886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato * http://www.apache.org/licenses/LICENSE-2.0 986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato * 1086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato * Unless required by applicable law or agreed to in writing, software 1186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato * distributed under the License is distributed on an "AS IS" BASIS, 1286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato * See the License for the specific language governing permissions and 1486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato * limitations under the License. 1586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato */ 1686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 17fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratopackage com.android.systemui.statusbar.policy; 1886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 1989835ddf327ef256b44d91cf1fd1898c0599eb48John Spurlockimport android.animation.Animator; 20a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandlerimport android.animation.AnimatorSet; 21a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandlerimport android.animation.ObjectAnimator; 2286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.content.Context; 2386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.content.res.TypedArray; 24a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandlerimport android.graphics.Canvas; 25a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandlerimport android.graphics.RectF; 26de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockimport android.graphics.drawable.Drawable; 27ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.hardware.input.InputManager; 2886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.os.SystemClock; 2986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.util.AttributeSet; 3089835ddf327ef256b44d91cf1fd1898c0599eb48John Spurlockimport android.util.Log; 31804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandlerimport android.view.HapticFeedbackConstants; 32bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brownimport android.view.InputDevice; 336b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport android.view.KeyCharacterMap; 3486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.view.KeyEvent; 3586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.view.MotionEvent; 36aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandlerimport android.view.SoundEffectConstants; 37a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandlerimport android.view.View; 38804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandlerimport android.view.ViewConfiguration; 3956d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlockimport android.view.ViewDebug; 40de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockimport android.view.accessibility.AccessibilityEvent; 4186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport android.widget.ImageView; 4286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 4386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratoimport com.android.systemui.R; 4486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 4586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onoratopublic class KeyButtonView extends ImageView { 46fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato private static final String TAG = "StatusBar.KeyButtonView"; 4789835ddf327ef256b44d91cf1fd1898c0599eb48John Spurlock private static final boolean DEBUG = false; 48fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato 4996f4818ef41141649337d4dee09f837594e93d09Daniel Sandler final float GLOW_MAX_SCALE_FACTOR = 1.8f; 5089835ddf327ef256b44d91cf1fd1898c0599eb48John Spurlock public static final float DEFAULT_QUIESCENT_ALPHA = 0.70f; 5196f4818ef41141649337d4dee09f837594e93d09Daniel Sandler 5286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato long mDownTime; 5386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato int mCode; 54aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler int mTouchSlop; 55a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler Drawable mGlowBG; 563fd0e1a219e42db90b34b3512a6984d7dd2ebe2cDaniel Sandler int mGlowWidth, mGlowHeight; 5756d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock float mGlowAlpha = 0f, mGlowScale = 1f; 5856d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock @ViewDebug.ExportedProperty(category = "drawing") 5956d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock float mDrawingAlpha = 1f; 6056d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock @ViewDebug.ExportedProperty(category = "drawing") 6189835ddf327ef256b44d91cf1fd1898c0599eb48John Spurlock float mQuiescentAlpha = DEFAULT_QUIESCENT_ALPHA; 6244a4616bf780f131f8d78b46a075844800088860Daniel Sandler boolean mSupportsLongpress = true; 6356d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock RectF mRect = new RectF(); 6460bc69ef76c32b9a24c0901e6c6e452b50de0cdaMichael Jurka AnimatorSet mPressedAnim; 657edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock Animator mAnimateToQuiescent = new ObjectAnimator(); 66aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler 67804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler Runnable mCheckLongPress = new Runnable() { 68804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler public void run() { 69804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler if (isPressed()) { 70cd686b5b6d4166b510df8e32138479a9559bc117John Spurlock // Log.d("KeyButtonView", "longpressed: " + this); 71a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler if (mCode != 0) { 7298392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS); 73a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED); 74a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } else { 75a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler // Just an old-fashioned ImageView 76a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler performLongClick(); 77a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 78804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler } 79804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler } 80804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler }; 8186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 8286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato public KeyButtonView(Context context, AttributeSet attrs) { 8386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato this(context, attrs, 0); 8486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato } 8586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 8686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato public KeyButtonView(Context context, AttributeSet attrs, int defStyle) { 8786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato super(context, attrs); 8886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 8986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.KeyButtonView, 9086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato defStyle, 0); 9186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 9286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato mCode = a.getInteger(R.styleable.KeyButtonView_keyCode, 0); 93209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 9444a4616bf780f131f8d78b46a075844800088860Daniel Sandler mSupportsLongpress = a.getBoolean(R.styleable.KeyButtonView_keyRepeat, true); 95a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler 96a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler mGlowBG = a.getDrawable(R.styleable.KeyButtonView_glowBackground); 9756d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock setDrawingAlpha(mQuiescentAlpha); 98a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler if (mGlowBG != null) { 993fd0e1a219e42db90b34b3512a6984d7dd2ebe2cDaniel Sandler mGlowWidth = mGlowBG.getIntrinsicWidth(); 1003fd0e1a219e42db90b34b3512a6984d7dd2ebe2cDaniel Sandler mGlowHeight = mGlowBG.getIntrinsicHeight(); 10186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato } 102209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 10386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato a.recycle(); 10486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 105641bad449ba3b971500843c6bf7bf6f08363d09eJoe Onorato setClickable(true); 106aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); 10786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato } 10886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 109a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler @Override 110a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler protected void onDraw(Canvas canvas) { 111a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler if (mGlowBG != null) { 112a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler canvas.save(); 113a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler final int w = getWidth(); 114a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler final int h = getHeight(); 1153fd0e1a219e42db90b34b3512a6984d7dd2ebe2cDaniel Sandler final float aspect = (float)mGlowWidth / mGlowHeight; 1163fd0e1a219e42db90b34b3512a6984d7dd2ebe2cDaniel Sandler final int drawW = (int)(h*aspect); 1173fd0e1a219e42db90b34b3512a6984d7dd2ebe2cDaniel Sandler final int drawH = h; 1183fd0e1a219e42db90b34b3512a6984d7dd2ebe2cDaniel Sandler final int margin = (drawW-w)/2; 119a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler canvas.scale(mGlowScale, mGlowScale, w*0.5f, h*0.5f); 1203fd0e1a219e42db90b34b3512a6984d7dd2ebe2cDaniel Sandler mGlowBG.setBounds(-margin, 0, drawW-margin, drawH); 1210b6586649fe827d6e7ce39fa71e93fa582640a03Michael Jurka mGlowBG.setAlpha((int)(mDrawingAlpha * mGlowAlpha * 255)); 122a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler mGlowBG.draw(canvas); 123a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler canvas.restore(); 124c638c1eb1bbed67d7d8f0d43f39137d766366f54Daniel Sandler mRect.right = w; 125c638c1eb1bbed67d7d8f0d43f39137d766366f54Daniel Sandler mRect.bottom = h; 126a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 127a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler super.onDraw(canvas); 128a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 129a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler 1307edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock public void setQuiescentAlpha(float alpha, boolean animate) { 1317edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock mAnimateToQuiescent.cancel(); 13289835ddf327ef256b44d91cf1fd1898c0599eb48John Spurlock alpha = Math.min(Math.max(alpha, 0), 1); 13356d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock if (alpha == mQuiescentAlpha && alpha == mDrawingAlpha) return; 13489835ddf327ef256b44d91cf1fd1898c0599eb48John Spurlock mQuiescentAlpha = alpha; 13589835ddf327ef256b44d91cf1fd1898c0599eb48John Spurlock if (DEBUG) Log.d(TAG, "New quiescent alpha = " + mQuiescentAlpha); 13656d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock if (mGlowBG != null && animate) { 13756d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock mAnimateToQuiescent = animateToQuiescent(); 13856d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock mAnimateToQuiescent.start(); 13956d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock } else { 14056d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock setDrawingAlpha(mQuiescentAlpha); 14189835ddf327ef256b44d91cf1fd1898c0599eb48John Spurlock } 14289835ddf327ef256b44d91cf1fd1898c0599eb48John Spurlock } 14389835ddf327ef256b44d91cf1fd1898c0599eb48John Spurlock 1447edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock private ObjectAnimator animateToQuiescent() { 1457edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock return ObjectAnimator.ofFloat(this, "drawingAlpha", mQuiescentAlpha); 1467edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock } 1477edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock 14856d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock public float getQuiescentAlpha() { 14956d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock return mQuiescentAlpha; 15056d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock } 15156d007b99841f7f603e5d5bc5c23b94c010f1945John Spurlock 152a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler public float getDrawingAlpha() { 153a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler return mDrawingAlpha; 154a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 155a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler 156a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler public void setDrawingAlpha(float x) { 1570b6586649fe827d6e7ce39fa71e93fa582640a03Michael Jurka // Calling setAlpha(int), which is an ImageView-specific 1580b6586649fe827d6e7ce39fa71e93fa582640a03Michael Jurka // method that's different from setAlpha(float). This sets 1590b6586649fe827d6e7ce39fa71e93fa582640a03Michael Jurka // the alpha on this ImageView's drawable directly 1600b6586649fe827d6e7ce39fa71e93fa582640a03Michael Jurka setAlpha((int) (x * 255)); 161a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler mDrawingAlpha = x; 162a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 163a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler 164a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler public float getGlowAlpha() { 165a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler if (mGlowBG == null) return 0; 166a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler return mGlowAlpha; 167a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 168a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler 169a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler public void setGlowAlpha(float x) { 170a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler if (mGlowBG == null) return; 171a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler mGlowAlpha = x; 172a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler invalidate(); 173a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 174a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler 175a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler public float getGlowScale() { 176a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler if (mGlowBG == null) return 0; 177a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler return mGlowScale; 178a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 179a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler 180a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler public void setGlowScale(float x) { 181a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler if (mGlowBG == null) return; 182a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler mGlowScale = x; 183a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler final float w = getWidth(); 184a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler final float h = getHeight(); 18596f4818ef41141649337d4dee09f837594e93d09Daniel Sandler if (GLOW_MAX_SCALE_FACTOR <= 1.0f) { 18696f4818ef41141649337d4dee09f837594e93d09Daniel Sandler // this only works if we know the glow will never leave our bounds 187a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler invalidate(); 188a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } else { 18996f4818ef41141649337d4dee09f837594e93d09Daniel Sandler final float rx = (w * (GLOW_MAX_SCALE_FACTOR - 1.0f)) / 2.0f + 1.0f; 19096f4818ef41141649337d4dee09f837594e93d09Daniel Sandler final float ry = (h * (GLOW_MAX_SCALE_FACTOR - 1.0f)) / 2.0f + 1.0f; 191a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler com.android.systemui.SwipeHelper.invalidateGlobalRegion( 192a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler this, 1935298582717494098fcdf115d832c8e871340d0b5Daniel Sandler new RectF(getLeft() - rx, 1945298582717494098fcdf115d832c8e871340d0b5Daniel Sandler getTop() - ry, 1955298582717494098fcdf115d832c8e871340d0b5Daniel Sandler getRight() + rx, 1965298582717494098fcdf115d832c8e871340d0b5Daniel Sandler getBottom() + ry)); 19796f4818ef41141649337d4dee09f837594e93d09Daniel Sandler 19896f4818ef41141649337d4dee09f837594e93d09Daniel Sandler // also invalidate our immediate parent to help avoid situations where nearby glows 19996f4818ef41141649337d4dee09f837594e93d09Daniel Sandler // interfere 20096f4818ef41141649337d4dee09f837594e93d09Daniel Sandler ((View)getParent()).invalidate(); 201a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 202a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 203a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler 204a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler public void setPressed(boolean pressed) { 205a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler if (mGlowBG != null) { 206a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler if (pressed != isPressed()) { 20760bc69ef76c32b9a24c0901e6c6e452b50de0cdaMichael Jurka if (mPressedAnim != null && mPressedAnim.isRunning()) { 20860bc69ef76c32b9a24c0901e6c6e452b50de0cdaMichael Jurka mPressedAnim.cancel(); 20960bc69ef76c32b9a24c0901e6c6e452b50de0cdaMichael Jurka } 21060bc69ef76c32b9a24c0901e6c6e452b50de0cdaMichael Jurka final AnimatorSet as = mPressedAnim = new AnimatorSet(); 211a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler if (pressed) { 212209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock if (mGlowScale < GLOW_MAX_SCALE_FACTOR) 213bceff71b9231643090d0dad6e3f1e1aac6fda1a2Justin Ho mGlowScale = GLOW_MAX_SCALE_FACTOR; 21489835ddf327ef256b44d91cf1fd1898c0599eb48John Spurlock if (mGlowAlpha < mQuiescentAlpha) 21589835ddf327ef256b44d91cf1fd1898c0599eb48John Spurlock mGlowAlpha = mQuiescentAlpha; 216a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler setDrawingAlpha(1f); 217a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler as.playTogether( 218a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler ObjectAnimator.ofFloat(this, "glowAlpha", 1f), 21996f4818ef41141649337d4dee09f837594e93d09Daniel Sandler ObjectAnimator.ofFloat(this, "glowScale", GLOW_MAX_SCALE_FACTOR) 220a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler ); 221a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler as.setDuration(50); 222a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } else { 2237edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock mAnimateToQuiescent.cancel(); 2247edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock mAnimateToQuiescent = animateToQuiescent(); 225a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler as.playTogether( 226a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler ObjectAnimator.ofFloat(this, "glowAlpha", 0f), 227a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler ObjectAnimator.ofFloat(this, "glowScale", 1f), 2287edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock mAnimateToQuiescent 229a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler ); 230a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler as.setDuration(500); 231a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 232a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler as.start(); 233a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 234a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 235a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler super.setPressed(pressed); 236a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler } 237a375c94fca986d76d21f8cb9a3eb29f1ef88c4a8Daniel Sandler 23886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato public boolean onTouchEvent(MotionEvent ev) { 23986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato final int action = ev.getAction(); 24086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato int x, y; 24186f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 24286f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato switch (action) { 24386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato case MotionEvent.ACTION_DOWN: 244cd686b5b6d4166b510df8e32138479a9559bc117John Spurlock //Log.d("KeyButtonView", "press"); 24586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato mDownTime = SystemClock.uptimeMillis(); 24644a4616bf780f131f8d78b46a075844800088860Daniel Sandler setPressed(true); 24798392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown if (mCode != 0) { 24898392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown sendEvent(KeyEvent.ACTION_DOWN, 0, mDownTime); 24998392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown } else { 25098392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown // Provide the same haptic feedback that the system offers for virtual keys. 25198392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY); 25298392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown } 25344a4616bf780f131f8d78b46a075844800088860Daniel Sandler if (mSupportsLongpress) { 25444a4616bf780f131f8d78b46a075844800088860Daniel Sandler removeCallbacks(mCheckLongPress); 25544a4616bf780f131f8d78b46a075844800088860Daniel Sandler postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout()); 25644a4616bf780f131f8d78b46a075844800088860Daniel Sandler } 25786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato break; 25886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato case MotionEvent.ACTION_MOVE: 25998392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown x = (int)ev.getX(); 26098392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown y = (int)ev.getY(); 26198392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown setPressed(x >= -mTouchSlop 26298392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown && x < getWidth() + mTouchSlop 26398392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown && y >= -mTouchSlop 26498392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown && y < getHeight() + mTouchSlop); 26586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato break; 26686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato case MotionEvent.ACTION_CANCEL: 267804eb858348dbe2c8564aa930b6349a5571b5476Daniel Sandler setPressed(false); 26898392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown if (mCode != 0) { 26998392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED); 27098392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown } 27198392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown if (mSupportsLongpress) { 27298392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown removeCallbacks(mCheckLongPress); 273abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato } 274abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato break; 275abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato case MotionEvent.ACTION_UP: 276aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler final boolean doIt = isPressed(); 277abb27777f4763d057d37a58936232f8e17f57de1Joe Onorato setPressed(false); 27898392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown if (mCode != 0) { 27998392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown if (doIt) { 28098392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown sendEvent(KeyEvent.ACTION_UP, 0); 28198392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); 28298392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown playSoundEffect(SoundEffectConstants.CLICK); 2835ee1a3daf0fb274b2a5fdea797748b569495a621Patrick Dubroy } else { 28498392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED); 285aa051d66afa791872bfe362a94765dece07cd4c5Daniel Sandler } 28698392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown } else { 28798392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown // no key code, just a regular ImageView 28898392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown if (doIt) { 28998392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown performClick(); 29098392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown } 29198392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown } 29298392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown if (mSupportsLongpress) { 29398392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown removeCallbacks(mCheckLongPress); 29486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato } 29586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato break; 29686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato } 29786f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 29886f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato return true; 29986f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato } 30086f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 301bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown void sendEvent(int action, int flags) { 302bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown sendEvent(action, flags, SystemClock.uptimeMillis()); 30386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato } 30486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 305bbda99d2086d79ac70b403cad38a47c35af84adfJeff Brown void sendEvent(int action, int flags, long when) { 30698392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown final int repeatCount = (flags & KeyEvent.FLAG_LONG_PRESS) != 0 ? 1 : 0; 30798392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown final KeyEvent ev = new KeyEvent(mDownTime, when, action, mCode, repeatCount, 30898392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 30998392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown flags | KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY, 31098392efb24d8aac36a4cfa85106812e17d5984f9Jeff Brown InputDevice.SOURCE_KEYBOARD); 3119f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown InputManager.getInstance().injectInputEvent(ev, 3129f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); 31386f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato } 31486f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato} 31586f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 31686f9bd2fd054522e36f84776056cd07531ead9cfJoe Onorato 317