152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project/* 252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * 452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * you may not use this file except in compliance with the License. 652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * You may obtain a copy of the License at 752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * 852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * 1052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * See the License for the specific language governing permissions and 1452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * limitations under the License. 1552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project */ 1652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 1752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectpackage com.example.android.apis.graphics; 1852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 1952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.content.Context; 2052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.graphics.Canvas; 2152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.graphics.Picture; 2252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.graphics.Rect; 2352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.graphics.drawable.Drawable; 2452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.util.AttributeSet; 2552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.view.View; 2652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.view.ViewGroup; 2752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.view.ViewParent; 2852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 2952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectpublic class PictureLayout extends ViewGroup { 3052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project private final Picture mPicture = new Picture(); 3152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 3252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project public PictureLayout(Context context) { 3352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project super(context); 3452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 3552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 3652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project public PictureLayout(Context context, AttributeSet attrs) { 3752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project super(context, attrs); 3862e92d7a2a3fd2798901ec2e7c452ff0e4067163Christian Mehlmauer } 3952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 4052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project @Override 4152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project public void addView(View child) { 4252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project if (getChildCount() > 1) { 4352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project throw new IllegalStateException("PictureLayout can host only one direct child"); 4452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 4552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 4652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project super.addView(child); 4752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 4852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 4952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project @Override 5052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project public void addView(View child, int index) { 5152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project if (getChildCount() > 1) { 5252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project throw new IllegalStateException("PictureLayout can host only one direct child"); 5352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 5452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 5552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project super.addView(child, index); 5652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 5752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 5852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project @Override 5952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project public void addView(View child, LayoutParams params) { 6052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project if (getChildCount() > 1) { 6152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project throw new IllegalStateException("PictureLayout can host only one direct child"); 6252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 6352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 6452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project super.addView(child, params); 6552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 6652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 6752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project @Override 6852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project public void addView(View child, int index, LayoutParams params) { 6952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project if (getChildCount() > 1) { 7052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project throw new IllegalStateException("PictureLayout can host only one direct child"); 7152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 7252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 7352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project super.addView(child, index, params); 7452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 7552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 7652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project @Override 7752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project protected LayoutParams generateDefaultLayoutParams() { 7874192eafec8408417114d77784cd35eda5df573cRomain Guy return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 7952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 8052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 8152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project @Override 8252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 8352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project final int count = getChildCount(); 8452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 8552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project int maxHeight = 0; 8652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project int maxWidth = 0; 8752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 8852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project for (int i = 0; i < count; i++) { 8952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project final View child = getChildAt(i); 9052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project if (child.getVisibility() != GONE) { 9152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project measureChild(child, widthMeasureSpec, heightMeasureSpec); 9252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 9352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 9452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 9552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project maxWidth += getPaddingLeft() + getPaddingRight(); 9652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project maxHeight += getPaddingTop() + getPaddingBottom(); 9752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 9852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project Drawable drawable = getBackground(); 9952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project if (drawable != null) { 10052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project maxHeight = Math.max(maxHeight, drawable.getMinimumHeight()); 10152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project maxWidth = Math.max(maxWidth, drawable.getMinimumWidth()); 10252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 10352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 10452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec), 10552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project resolveSize(maxHeight, heightMeasureSpec)); 10652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 10762e92d7a2a3fd2798901ec2e7c452ff0e4067163Christian Mehlmauer 10852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project private void drawPict(Canvas canvas, int x, int y, int w, int h, 10952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project float sx, float sy) { 11052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project canvas.save(); 11152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project canvas.translate(x, y); 11252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project canvas.clipRect(0, 0, w, h); 11352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project canvas.scale(0.5f, 0.5f); 11452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project canvas.scale(sx, sy, w, h); 11552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project canvas.drawPicture(mPicture); 11652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project canvas.restore(); 11752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 11852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 11952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project @Override 12052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project protected void dispatchDraw(Canvas canvas) { 12152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight())); 12252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mPicture.endRecording(); 12362e92d7a2a3fd2798901ec2e7c452ff0e4067163Christian Mehlmauer 12452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project int x = getWidth()/2; 12552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project int y = getHeight()/2; 12662e92d7a2a3fd2798901ec2e7c452ff0e4067163Christian Mehlmauer 12752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project if (false) { 12852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project canvas.drawPicture(mPicture); 12952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } else { 13052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project drawPict(canvas, 0, 0, x, y, 1, 1); 13152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project drawPict(canvas, x, 0, x, y, -1, 1); 13252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project drawPict(canvas, 0, y, x, y, 1, -1); 13352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project drawPict(canvas, x, y, x, y, -1, -1); 13452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 13552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 13652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 13752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project @Override 13852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project public ViewParent invalidateChildInParent(int[] location, Rect dirty) { 13952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project location[0] = getLeft(); 14052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project location[1] = getTop(); 14152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project dirty.set(0, 0, getWidth(), getHeight()); 14252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project return getParent(); 14352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 14452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 14552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project @Override 14652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project protected void onLayout(boolean changed, int l, int t, int r, int b) { 14752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project final int count = super.getChildCount(); 14852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 14952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project for (int i = 0; i < count; i++) { 15052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project final View child = getChildAt(i); 15152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project if (child.getVisibility() != GONE) { 15252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project final int childLeft = getPaddingLeft(); 15352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project final int childTop = getPaddingTop(); 15452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project child.layout(childLeft, childTop, 15552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project childLeft + child.getMeasuredWidth(), 15652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project childTop + child.getMeasuredHeight()); 15752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 15852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 15952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 16052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 16152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project} 162