1/*
2 * Copyright (C) 2015 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 */
16package android.support.v17.leanback.graphics;
17
18import android.graphics.Rect;
19
20/**
21 * This class contains the rules for updating the bounds of a
22 * {@link CompositeDrawable.ChildDrawable}. It contains four rules, one for each value of the
23 * rectangular bound - left/top/right/bottom.
24 */
25public class BoundsRule {
26
27    /**
28     * This class represents individual rules for updating the bounds.
29     */
30    public final static class ValueRule {
31        float mFraction;
32        int mAbsoluteValue;
33
34        /**
35         * Creates ValueRule using a fraction of parent size.
36         *
37         * @param fraction Percentage of parent.
38         * @return Newly created ValueRule.
39         */
40        public static ValueRule inheritFromParent(float fraction) {
41            return new ValueRule(0, fraction);
42        }
43
44        /**
45         * Creates ValueRule using an absolute value.
46         *
47         * @param absoluteValue Absolute value.
48         * @return Newly created ValueRule.
49         */
50        public static ValueRule absoluteValue(int absoluteValue) {
51            return new ValueRule(absoluteValue, 0);
52        }
53
54        /**
55         * Creates ValueRule of fraction and offset.
56         *
57         * @param fraction Percentage of parent.
58         * @param value    Offset
59         * @return Newly created ValueRule.
60         */
61        public static ValueRule inheritFromParentWithOffset(float fraction, int value) {
62            return new ValueRule(value, fraction);
63        }
64
65        ValueRule(int absoluteValue, float fraction) {
66            this.mAbsoluteValue = absoluteValue;
67            this.mFraction = fraction;
68        }
69
70        ValueRule(ValueRule rule) {
71            this.mFraction = rule.mFraction;
72            this.mAbsoluteValue = rule.mAbsoluteValue;
73        }
74
75        /**
76         * Sets the fractional value (percentage of parent) for this rule.
77         *
78         * @param fraction Percentage of parent.
79         */
80        public void setFraction(float fraction) {
81            this.mFraction = fraction;
82        }
83
84        /**
85         * @return The current fractional value.
86         */
87        public float getFraction() {
88            return mFraction;
89        }
90
91        /**
92         * Sets the absolute/offset value for rule.
93         *
94         * @param absoluteValue Absolute value.
95         */
96        public void setAbsoluteValue(int absoluteValue) {
97            this.mAbsoluteValue = absoluteValue;
98        }
99
100        /**
101         * @return The current absolute/offset value forrule.
102         */
103        public int getAbsoluteValue() {
104            return mAbsoluteValue;
105        }
106
107    }
108
109    /**
110     * Takes in the current bounds and sets the final values based on the individual rules in the
111     * result object.
112     *
113     * @param rect Represents the current bounds.
114     * @param result Represents the final bounds.
115     */
116    public void calculateBounds(Rect rect, Rect result) {
117        if (left == null) {
118            result.left = rect.left;
119        } else {
120            result.left = doCalculate(rect.left, left, rect.width());
121        }
122
123        if (right == null) {
124            result.right = rect.right;
125        } else {
126            result.right = doCalculate(rect.left, right, rect.width());
127        }
128
129        if (top == null) {
130            result.top = rect.top;
131        } else {
132            result.top = doCalculate(rect.top, top, rect.height());
133        }
134
135        if (bottom == null) {
136            result.bottom = rect.bottom;
137        } else {
138            result.bottom = doCalculate(rect.top, bottom, rect.height());
139        }
140    }
141
142    public BoundsRule() {}
143
144    public BoundsRule(BoundsRule boundsRule) {
145        this.left = boundsRule.left != null ? new ValueRule(boundsRule.left) : null;
146        this.right = boundsRule.right != null ? new ValueRule(boundsRule.right) : null;
147        this.top = boundsRule.top != null ? new ValueRule(boundsRule.top) : null;
148        this.bottom = boundsRule.bottom != null ? new ValueRule(boundsRule.bottom) : null;
149    }
150
151    private int doCalculate(int value, ValueRule rule, int size) {
152        return value + rule.mAbsoluteValue + (int) (rule.mFraction * size);
153    }
154
155    /** {@link ValueRule} for left attribute of {@link BoundsRule} */
156    public ValueRule left;
157
158    /** {@link ValueRule} for top attribute of {@link BoundsRule} */
159    public ValueRule top;
160
161    /** {@link ValueRule} for right attribute of {@link BoundsRule} */
162    public ValueRule right;
163
164    /** {@link ValueRule} for bottom attribute of {@link BoundsRule} */
165    public ValueRule bottom;
166}
167