1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.example.android.apis.graphics;
18 
19 import android.content.Context;
20 import android.graphics.Canvas;
21 import android.graphics.Picture;
22 import android.graphics.Rect;
23 import android.graphics.drawable.Drawable;
24 import android.util.AttributeSet;
25 import android.view.View;
26 import android.view.ViewGroup;
27 import android.view.ViewParent;
28 
29 public class PictureLayout extends ViewGroup {
30     private final Picture mPicture = new Picture();
31 
PictureLayout(Context context)32     public PictureLayout(Context context) {
33         super(context);
34     }
35 
PictureLayout(Context context, AttributeSet attrs)36     public PictureLayout(Context context, AttributeSet attrs) {
37         super(context, attrs);
38     }
39 
40     @Override
addView(View child)41     public void addView(View child) {
42         if (getChildCount() > 1) {
43             throw new IllegalStateException("PictureLayout can host only one direct child");
44         }
45 
46         super.addView(child);
47     }
48 
49     @Override
addView(View child, int index)50     public void addView(View child, int index) {
51         if (getChildCount() > 1) {
52             throw new IllegalStateException("PictureLayout can host only one direct child");
53         }
54 
55         super.addView(child, index);
56     }
57 
58     @Override
addView(View child, LayoutParams params)59     public void addView(View child, LayoutParams params) {
60         if (getChildCount() > 1) {
61             throw new IllegalStateException("PictureLayout can host only one direct child");
62         }
63 
64         super.addView(child, params);
65     }
66 
67     @Override
addView(View child, int index, LayoutParams params)68     public void addView(View child, int index, LayoutParams params) {
69         if (getChildCount() > 1) {
70             throw new IllegalStateException("PictureLayout can host only one direct child");
71         }
72 
73         super.addView(child, index, params);
74     }
75 
76     @Override
generateDefaultLayoutParams()77     protected LayoutParams generateDefaultLayoutParams() {
78         return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
79     }
80 
81     @Override
onMeasure(int widthMeasureSpec, int heightMeasureSpec)82     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
83         final int count = getChildCount();
84 
85         int maxHeight = 0;
86         int maxWidth = 0;
87 
88         for (int i = 0; i < count; i++) {
89             final View child = getChildAt(i);
90             if (child.getVisibility() != GONE) {
91                 measureChild(child, widthMeasureSpec, heightMeasureSpec);
92             }
93         }
94 
95         maxWidth += getPaddingLeft() + getPaddingRight();
96         maxHeight += getPaddingTop() + getPaddingBottom();
97 
98         Drawable drawable = getBackground();
99         if (drawable != null) {
100             maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
101             maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
102         }
103 
104         setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
105                 resolveSize(maxHeight, heightMeasureSpec));
106     }
107 
drawPict(Canvas canvas, int x, int y, int w, int h, float sx, float sy)108     private void drawPict(Canvas canvas, int x, int y, int w, int h,
109                           float sx, float sy) {
110         canvas.save();
111         canvas.translate(x, y);
112         canvas.clipRect(0, 0, w, h);
113         canvas.scale(0.5f, 0.5f);
114         canvas.scale(sx, sy, w, h);
115         canvas.drawPicture(mPicture);
116         canvas.restore();
117     }
118 
119     @Override
dispatchDraw(Canvas canvas)120     protected void dispatchDraw(Canvas canvas) {
121         super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight()));
122         mPicture.endRecording();
123 
124         int x = getWidth()/2;
125         int y = getHeight()/2;
126 
127         if (false) {
128             canvas.drawPicture(mPicture);
129         } else {
130             drawPict(canvas, 0, 0, x, y,  1,  1);
131             drawPict(canvas, x, 0, x, y, -1,  1);
132             drawPict(canvas, 0, y, x, y,  1, -1);
133             drawPict(canvas, x, y, x, y, -1, -1);
134         }
135     }
136 
137     @Override
invalidateChildInParent(int[] location, Rect dirty)138     public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
139         location[0] = getLeft();
140         location[1] = getTop();
141         dirty.set(0, 0, getWidth(), getHeight());
142         return getParent();
143     }
144 
145     @Override
onLayout(boolean changed, int l, int t, int r, int b)146     protected void onLayout(boolean changed, int l, int t, int r, int b) {
147         final int count = super.getChildCount();
148 
149         for (int i = 0; i < count; i++) {
150             final View child = getChildAt(i);
151             if (child.getVisibility() != GONE) {
152                 final int childLeft = getPaddingLeft();
153                 final int childTop = getPaddingTop();
154                 child.layout(childLeft, childTop,
155                         childLeft + child.getMeasuredWidth(),
156                         childTop + child.getMeasuredHeight());
157 
158             }
159         }
160     }
161 }
162