1f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell/*
2f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * Copyright (C) 2014 The Android Open Source Project
3f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell *
4f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * Licensed under the Apache License, Version 2.0 (the "License");
5f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * you may not use this file except in compliance with the License.
6f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * You may obtain a copy of the License at
7f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell *
8f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell *      http://www.apache.org/licenses/LICENSE-2.0
9f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell *
10f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * Unless required by applicable law or agreed to in writing, software
11f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * distributed under the License is distributed on an "AS IS" BASIS,
12f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * See the License for the specific language governing permissions and
14f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * limitations under the License.
15f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell */
16f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell
17f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell
18f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powellpackage com.android.internal.widget;
19f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell
20f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powellimport android.graphics.Canvas;
21f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powellimport android.graphics.PixelFormat;
22f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powellimport android.graphics.drawable.Drawable;
23f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powellimport android.view.View;
24f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powellimport android.view.ViewGroup;
25f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell
26f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell/**
27f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * Helper class for drawing a fallback background in framework decor layouts.
28f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * Useful for when an app has not set a window background but we're asked to draw
29f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell * an uncovered area.
30f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell */
31f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powellpublic class BackgroundFallback {
32f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell    private Drawable mBackgroundFallback;
33f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell
34f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell    public void setDrawable(Drawable d) {
35f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell        mBackgroundFallback = d;
36f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell    }
37f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell
38f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell    public boolean hasFallback() {
39f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell        return mBackgroundFallback != null;
40f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell    }
41f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell
42f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell    public void draw(ViewGroup root, Canvas c, View content) {
43f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell        if (!hasFallback()) {
44f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell            return;
45f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell        }
46f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell
47f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell        // Draw the fallback in the padding.
48f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell        final int width = root.getWidth();
49f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell        final int height = root.getHeight();
50f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell        int left = width;
51f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell        int top = height;
52f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell        int right = 0;
53f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell        int bottom = 0;
54f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell
55f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell        final int childCount = root.getChildCount();
56f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell        for (int i = 0; i < childCount; i++) {
57f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell            final View child = root.getChildAt(i);
58f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell            final Drawable childBg = child.getBackground();
59f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell            if (child == content) {
60f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell                // We always count the content view container unless it has no background
61f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell                // and no children.
62f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell                if (childBg == null && child instanceof ViewGroup &&
63f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell                        ((ViewGroup) child).getChildCount() == 0) {
64f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell                    continue;
65f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell                }
66f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell            } else if (child.getVisibility() != View.VISIBLE || childBg == null ||
67f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell                    childBg.getOpacity() != PixelFormat.OPAQUE) {
68f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell                // Potentially translucent or invisible children don't count, and we assume
69f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell                // the content view will cover the whole area if we're in a background
70f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell                // fallback situation.
71f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell                continue;
72f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell            }
73f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell            left = Math.min(left, child.getLeft());
74f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell            top = Math.min(top, child.getTop());
75f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell            right = Math.max(right, child.getRight());
76f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell            bottom = Math.max(bottom, child.getBottom());
77f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell        }
78f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell
79f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell        if (left >= right || top >= bottom) {
80f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell            // No valid area to draw in.
81f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell            return;
82f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell        }
83f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell
84f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell        if (top > 0) {
85f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell            mBackgroundFallback.setBounds(0, 0, width, top);
86f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell            mBackgroundFallback.draw(c);
87f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell        }
88f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell        if (left > 0) {
89f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell            mBackgroundFallback.setBounds(0, top, left, height);
90f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell            mBackgroundFallback.draw(c);
91f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell        }
92f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell        if (right < width) {
93f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell            mBackgroundFallback.setBounds(right, top, width, height);
94f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell            mBackgroundFallback.draw(c);
95f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell        }
96f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell        if (bottom < height) {
97f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell            mBackgroundFallback.setBounds(left, bottom, right, height);
98f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell            mBackgroundFallback.draw(c);
99f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell        }
100f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell    }
101f849a5e16d016fb6ae081a4575ce67f4ce688e3aAdam Powell}
102