1package com.android.launcher3;
2
3import android.content.Context;
4import android.content.res.TypedArray;
5import android.graphics.Rect;
6import android.util.AttributeSet;
7import android.view.View;
8import android.view.ViewDebug;
9import android.view.ViewGroup;
10import android.widget.FrameLayout;
11
12import com.android.launcher3.allapps.AllAppsContainerView;
13import com.android.launcher3.config.FeatureFlags;
14
15public class InsettableFrameLayout extends FrameLayout implements
16    ViewGroup.OnHierarchyChangeListener, Insettable {
17
18    @ViewDebug.ExportedProperty(category = "launcher")
19    protected Rect mInsets = new Rect();
20
21    public Rect getInsets() {
22        return mInsets;
23    }
24
25    public InsettableFrameLayout(Context context, AttributeSet attrs) {
26        super(context, attrs);
27        setOnHierarchyChangeListener(this);
28    }
29
30    public void setFrameLayoutChildInsets(View child, Rect newInsets, Rect oldInsets) {
31        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
32
33        if (child instanceof Insettable) {
34            ((Insettable) child).setInsets(newInsets);
35        } else if (!lp.ignoreInsets) {
36            lp.topMargin += (newInsets.top - oldInsets.top);
37            lp.leftMargin += (newInsets.left - oldInsets.left);
38            lp.rightMargin += (newInsets.right - oldInsets.right);
39            lp.bottomMargin += (newInsets.bottom - oldInsets.bottom);
40        }
41        child.setLayoutParams(lp);
42    }
43
44    @Override
45    public void setInsets(Rect insets) {
46        // If the insets haven't changed, this is a no-op. Avoid unnecessary layout caused by
47        // modifying child layout params.
48        if (insets.equals(mInsets)) return;
49
50        final int n = getChildCount();
51        for (int i = 0; i < n; i++) {
52            final View child = getChildAt(i);
53            setFrameLayoutChildInsets(child, insets, mInsets);
54        }
55        mInsets.set(insets);
56    }
57
58    @Override
59    public LayoutParams generateLayoutParams(AttributeSet attrs) {
60        return new InsettableFrameLayout.LayoutParams(getContext(), attrs);
61    }
62
63    @Override
64    protected LayoutParams generateDefaultLayoutParams() {
65        return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
66    }
67
68    // Override to allow type-checking of LayoutParams.
69    @Override
70    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
71        return p instanceof InsettableFrameLayout.LayoutParams;
72    }
73
74    @Override
75    protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
76        return new LayoutParams(p);
77    }
78
79    public static class LayoutParams extends FrameLayout.LayoutParams {
80        boolean ignoreInsets = false;
81
82        public LayoutParams(Context c, AttributeSet attrs) {
83            super(c, attrs);
84            TypedArray a = c.obtainStyledAttributes(attrs,
85                    R.styleable.InsettableFrameLayout_Layout);
86            ignoreInsets = a.getBoolean(
87                    R.styleable.InsettableFrameLayout_Layout_layout_ignoreInsets, false);
88            a.recycle();
89        }
90
91        public LayoutParams(int width, int height) {
92            super(width, height);
93        }
94
95        public LayoutParams(ViewGroup.LayoutParams lp) {
96            super(lp);
97        }
98    }
99
100    @Override
101    public void onChildViewAdded(View parent, View child) {
102        setFrameLayoutChildInsets(child, mInsets, new Rect());
103    }
104
105    @Override
106    public void onChildViewRemoved(View parent, View child) {
107    }
108
109}
110