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.view.Gravity; 25e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.view.View; 26e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.widget.LinearLayout; 27e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 28e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato/** 29e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * A vertical linear layout. However, instead of drawing the background 30e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * behnd the items, it draws the background outside the items based on the 31e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * padding. If there isn't enough room to draw both, it clips the background 32e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * instead of the contents. 33e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato */ 34e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratopublic class RecentApplicationsBackground extends LinearLayout { 35e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private static final String TAG = "RecentApplicationsBackground"; 36e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 37e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private boolean mBackgroundSizeChanged; 38e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private Drawable mBackground; 39e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private Rect mTmp0 = new Rect(); 40e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private Rect mTmp1 = new Rect(); 41e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 42e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato public RecentApplicationsBackground(Context context) { 43e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato this(context, null); 44e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato init(); 45e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 46e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 47e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato public RecentApplicationsBackground(Context context, AttributeSet attrs) { 48e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato super(context, attrs); 49e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato init(); 50e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 51e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 52e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private void init() { 53e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato mBackground = getBackground(); 54e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato setBackgroundDrawable(null); 55e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato setPadding(0, 0, 0, 0); 56e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato setGravity(Gravity.CENTER); 57e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 58e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 59e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato @Override 60e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato protected boolean setFrame(int left, int top, int right, int bottom) { 61e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato setWillNotDraw(false); 62e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato if (mLeft != left || mRight != right || mTop != top || mBottom != bottom) { 63e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato mBackgroundSizeChanged = true; 64e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 65e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato return super.setFrame(left, top, right, bottom); 66e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 67e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 68e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato @Override 69e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato protected boolean verifyDrawable(Drawable who) { 70e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato return who == mBackground || super.verifyDrawable(who); 71e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 72e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 73e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato @Override 74e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn public void jumpDrawablesToCurrentState() { 75e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn super.jumpDrawablesToCurrentState(); 76e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn if (mBackground != null) mBackground.jumpToCurrentState(); 77e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn } 78e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn 79e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn @Override 80e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato protected void drawableStateChanged() { 81e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato Drawable d = mBackground; 82e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato if (d != null && d.isStateful()) { 83e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato d.setState(getDrawableState()); 84e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 85e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato super.drawableStateChanged(); 86e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 87e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 88e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato @Override 89e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato public void draw(Canvas canvas) { 90e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato final Drawable background = mBackground; 91e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato if (background != null) { 92e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato if (mBackgroundSizeChanged) { 93e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato mBackgroundSizeChanged = false; 94e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato Rect chld = mTmp0; 95e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato Rect bkg = mTmp1; 96e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato mBackground.getPadding(bkg); 97e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato getChildBounds(chld); 98e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato // This doesn't clamp to this view's bounds, which is what we want, 99e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato // so that the drawing is clipped. 100e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato final int top = chld.top - bkg.top; 101e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato final int bottom = chld.bottom + bkg.bottom; 102e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato // The background here is a gradient that wants to 103e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato // extend the full width of the screen (whatever that 104e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato // may be). 105e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato int left, right; 106e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato if (false) { 107e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato // This limits the width of the drawable. 108e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato left = chld.left - bkg.left; 109e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato right = chld.right + bkg.right; 110e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } else { 111e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato // This expands it to full width. 112e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato left = 0; 113e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato right = getRight(); 114e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 115e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato background.setBounds(left, top, right, bottom); 116e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 117e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 118e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato mBackground.draw(canvas); 119e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 120e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato if (false) { 121e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato android.graphics.Paint p = new android.graphics.Paint(); 122e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato p.setColor(0x88ffff00); 123e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato canvas.drawRect(background.getBounds(), p); 124e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 125e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato canvas.drawARGB((int)(0.75*0xff), 0, 0, 0); 126e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 127e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato super.draw(canvas); 128e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 129e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 130e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato @Override 131e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato protected void onAttachedToWindow() { 132e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato super.onAttachedToWindow(); 133e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato mBackground.setCallback(this); 134e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato setWillNotDraw(false); 135e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 136e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 137e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato @Override 138e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato protected void onDetachedFromWindow() { 139e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato super.onDetachedFromWindow(); 140e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato mBackground.setCallback(null); 141e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 142e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato 143e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato private void getChildBounds(Rect r) { 144e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato r.left = r.top = Integer.MAX_VALUE; 145e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato r.bottom = r.right = Integer.MIN_VALUE; 146e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato final int N = getChildCount(); 147e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato for (int i=0; i<N; i++) { 148e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato View v = getChildAt(i); 149e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato if (v.getVisibility() == View.VISIBLE) { 150e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato r.left = Math.min(r.left, v.getLeft()); 151e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato r.top = Math.min(r.top, v.getTop()); 152e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato r.right = Math.max(r.right, v.getRight()); 153e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato r.bottom = Math.max(r.bottom, v.getBottom()); 154e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 155e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 156e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato } 157e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato} 158