1e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato/* 2e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * Copyright (C) 2010 The Android Open Source Project 3e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * 4e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * Licensed under the Apache License, Version 2.0 (the "License"); 5e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * you may not use this file except in compliance with the License. 6e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * You may obtain a copy of the License at 7e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * 8e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * http://www.apache.org/licenses/LICENSE-2.0 9e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * 10e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * Unless required by applicable law or agreed to in writing, software 11e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * distributed under the License is distributed on an "AS IS" BASIS, 12e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * See the License for the specific language governing permissions and 14e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * limitations under the License. 15e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato */ 16e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 17e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratopackage com.android.internal.policy.impl; 18e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 19e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.content.Context; 20e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.Canvas; 21e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.Rect; 22e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.drawable.Drawable; 23e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.util.AttributeSet; 24e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.util.Log; 25e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.view.Gravity; 26e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.view.View; 27e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.widget.LinearLayout; 28e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 29e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato/** 30e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * A vertical linear layout. However, instead of drawing the background 31e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * behnd the items, it draws the background outside the items based on the 32e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * padding. If there isn't enough room to draw both, it clips the background 33e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * instead of the contents. 34e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato */ 35e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratopublic class RecentApplicationsBackground extends LinearLayout { 36e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private static final String TAG = "RecentApplicationsBackground"; 37e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 38e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private boolean mBackgroundSizeChanged; 39e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private Drawable mBackground; 40e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private Rect mTmp0 = new Rect(); 41e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private Rect mTmp1 = new Rect(); 42e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 43e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato public RecentApplicationsBackground(Context context) { 44e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato this(context, null); 45e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato init(); 46e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 47e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 48e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato public RecentApplicationsBackground(Context context, AttributeSet attrs) { 49e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato super(context, attrs); 50e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato init(); 51e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 52e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 53e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private void init() { 54e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato mBackground = getBackground(); 55e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato setBackgroundDrawable(null); 56e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato setPadding(0, 0, 0, 0); 57e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato setGravity(Gravity.CENTER); 58e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 59e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 60e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato @Override 61e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato protected boolean setFrame(int left, int top, int right, int bottom) { 62e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato setWillNotDraw(false); 63e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato if (mLeft != left || mRight != right || mTop != top || mBottom != bottom) { 64e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato mBackgroundSizeChanged = true; 65e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 66e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato return super.setFrame(left, top, right, bottom); 67e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 68e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 69e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato @Override 70e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato protected boolean verifyDrawable(Drawable who) { 71e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato return who == mBackground || super.verifyDrawable(who); 72e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 73e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 74e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato @Override 75e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn public void jumpDrawablesToCurrentState() { 76e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn super.jumpDrawablesToCurrentState(); 77e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn if (mBackground != null) mBackground.jumpToCurrentState(); 78e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn } 79e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn 80e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn @Override 81e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato protected void drawableStateChanged() { 82e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato Drawable d = mBackground; 83e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato if (d != null && d.isStateful()) { 84e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato d.setState(getDrawableState()); 85e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 86e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato super.drawableStateChanged(); 87e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 88e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 89e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato @Override 90e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato public void draw(Canvas canvas) { 91e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato final Drawable background = mBackground; 92e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato if (background != null) { 93e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato if (mBackgroundSizeChanged) { 94e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato mBackgroundSizeChanged = false; 95e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato Rect chld = mTmp0; 96e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato Rect bkg = mTmp1; 97e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato mBackground.getPadding(bkg); 98e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato getChildBounds(chld); 99e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato // This doesn't clamp to this view's bounds, which is what we want, 100e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato // so that the drawing is clipped. 101e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato final int top = chld.top - bkg.top; 102e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato final int bottom = chld.bottom + bkg.bottom; 103e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato // The background here is a gradient that wants to 104e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato // extend the full width of the screen (whatever that 105e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato // may be). 106e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato int left, right; 107e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato if (false) { 108e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato // This limits the width of the drawable. 109e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato left = chld.left - bkg.left; 110e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato right = chld.right + bkg.right; 111e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } else { 112e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato // This expands it to full width. 113e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato left = 0; 114e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato right = getRight(); 115e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 116e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato background.setBounds(left, top, right, bottom); 117e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 118e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 119e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato mBackground.draw(canvas); 120e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 121e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato if (false) { 122e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato android.graphics.Paint p = new android.graphics.Paint(); 123e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato p.setColor(0x88ffff00); 124e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato canvas.drawRect(background.getBounds(), p); 125e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 126e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato canvas.drawARGB((int)(0.75*0xff), 0, 0, 0); 127e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 128e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato super.draw(canvas); 129e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 130e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 131e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato @Override 132e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato protected void onAttachedToWindow() { 133e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato super.onAttachedToWindow(); 134e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato mBackground.setCallback(this); 135e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato setWillNotDraw(false); 136e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 137e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 138e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato @Override 139e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato protected void onDetachedFromWindow() { 140e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato super.onDetachedFromWindow(); 141e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato mBackground.setCallback(null); 142e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 143e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 144e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private void getChildBounds(Rect r) { 145e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato r.left = r.top = Integer.MAX_VALUE; 146e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato r.bottom = r.right = Integer.MIN_VALUE; 147e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato final int N = getChildCount(); 148e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato for (int i=0; i<N; i++) { 149e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato View v = getChildAt(i); 150e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato if (v.getVisibility() == View.VISIBLE) { 151e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato r.left = Math.min(r.left, v.getLeft()); 152e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato r.top = Math.min(r.top, v.getTop()); 153e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato r.right = Math.max(r.right, v.getRight()); 154e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato r.bottom = Math.max(r.bottom, v.getBottom()); 155e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 156e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 157e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 158e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato} 159