1/*
2 * Copyright (C) 2014 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
17package android.support.v4.view;
18
19import android.content.res.ColorStateList;
20import android.graphics.PorterDuff;
21import android.view.View;
22import android.view.ViewParent;
23
24import java.lang.reflect.Field;
25
26class ViewCompatBase {
27
28    private static final String TAG = "ViewCompatBase";
29
30    private static Field sMinWidthField;
31    private static boolean sMinWidthFieldFetched;
32    private static Field sMinHeightField;
33    private static boolean sMinHeightFieldFetched;
34
35    static ColorStateList getBackgroundTintList(View view) {
36        return (view instanceof TintableBackgroundView)
37                ? ((TintableBackgroundView) view).getSupportBackgroundTintList()
38                : null;
39    }
40
41    static void setBackgroundTintList(View view, ColorStateList tintList) {
42        if (view instanceof TintableBackgroundView) {
43            ((TintableBackgroundView) view).setSupportBackgroundTintList(tintList);
44        }
45    }
46
47    static PorterDuff.Mode getBackgroundTintMode(View view) {
48        return (view instanceof TintableBackgroundView)
49                ? ((TintableBackgroundView) view).getSupportBackgroundTintMode()
50                : null;
51    }
52
53    static void setBackgroundTintMode(View view, PorterDuff.Mode mode) {
54        if (view instanceof TintableBackgroundView) {
55            ((TintableBackgroundView) view).setSupportBackgroundTintMode(mode);
56        }
57    }
58
59    static boolean isLaidOut(View view) {
60        return view.getWidth() > 0 && view.getHeight() > 0;
61    }
62
63    static int getMinimumWidth(View view) {
64        if (!sMinWidthFieldFetched) {
65            try {
66                sMinWidthField = View.class.getDeclaredField("mMinWidth");
67                sMinWidthField.setAccessible(true);
68            } catch (NoSuchFieldException e) {
69                // Couldn't find the field. Abort!
70            }
71            sMinWidthFieldFetched = true;
72        }
73
74        if (sMinWidthField != null) {
75            try {
76                return (int) sMinWidthField.get(view);
77            } catch (Exception e) {
78                // Field get failed. Oh well...
79            }
80        }
81
82        // We failed, return 0
83        return 0;
84    }
85
86    static int getMinimumHeight(View view) {
87        if (!sMinHeightFieldFetched) {
88            try {
89                sMinHeightField = View.class.getDeclaredField("mMinHeight");
90                sMinHeightField.setAccessible(true);
91            } catch (NoSuchFieldException e) {
92                // Couldn't find the field. Abort!
93            }
94            sMinHeightFieldFetched = true;
95        }
96
97        if (sMinHeightField != null) {
98            try {
99                return (int) sMinHeightField.get(view);
100            } catch (Exception e) {
101                // Field get failed. Oh well...
102            }
103        }
104
105        // We failed, return 0
106        return 0;
107    }
108
109    static boolean isAttachedToWindow(View view) {
110        return view.getWindowToken() != null;
111    }
112
113    static void offsetTopAndBottom(View view, int offset) {
114        final int currentTop = view.getTop();
115        view.offsetTopAndBottom(offset);
116
117        if (offset != 0) {
118            // We need to manually invalidate pre-honeycomb
119            final ViewParent parent = view.getParent();
120            if (parent instanceof View) {
121                final int absOffset = Math.abs(offset);
122                ((View) parent).invalidate(
123                        view.getLeft(),
124                        currentTop - absOffset,
125                        view.getRight(),
126                        currentTop + view.getHeight() + absOffset);
127            } else {
128                view.invalidate();
129            }
130        }
131    }
132
133    static void offsetLeftAndRight(View view, int offset) {
134        final int currentLeft = view.getLeft();
135        view.offsetLeftAndRight(offset);
136
137        if (offset != 0) {
138            // We need to manually invalidate pre-honeycomb
139            final ViewParent parent = view.getParent();
140            if (parent instanceof View) {
141                final int absOffset = Math.abs(offset);
142                ((View) parent).invalidate(
143                        currentLeft - absOffset,
144                        view.getTop(),
145                        currentLeft + view.getWidth() + absOffset,
146                        view.getBottom());
147            } else {
148                view.invalidate();
149            }
150        }
151    }
152}
153