CompositeDrawable.java revision 44ece5ceaaee232f9139ccbde40ac4a5e642bdee
1df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata/*
2df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata * Copyright (C) 2015 The Android Open Source Project
3df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata *
4df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata * Licensed under the Apache License, Version 2.0 (the "License");
5df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata * you may not use this file except in compliance with the License.
6df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata * You may obtain a copy of the License at
7df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata *
8df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata *      http://www.apache.org/licenses/LICENSE-2.0
9df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata *
10df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata * Unless required by applicable law or agreed to in writing, software
11df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata * distributed under the License is distributed on an "AS IS" BASIS,
12df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata * See the License for the specific language governing permissions and
14df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata * limitations under the License.
15df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata */
16df64e524a2bad079e6b0aa2d22c287f2c62aed82susnatapackage android.support.v17.leanback.graphics;
17df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata
183d9017263a760990ba79d5ebf3d1b6587e0bd311susnataimport android.annotation.TargetApi;
1900f780c9e3cca0b2e364c61e936147e09877c43fDake Guimport android.content.res.Resources;
20df64e524a2bad079e6b0aa2d22c287f2c62aed82susnataimport android.graphics.Canvas;
21df64e524a2bad079e6b0aa2d22c287f2c62aed82susnataimport android.graphics.ColorFilter;
22df64e524a2bad079e6b0aa2d22c287f2c62aed82susnataimport android.graphics.PixelFormat;
23df64e524a2bad079e6b0aa2d22c287f2c62aed82susnataimport android.graphics.Rect;
24df64e524a2bad079e6b0aa2d22c287f2c62aed82susnataimport android.graphics.drawable.Drawable;
253d9017263a760990ba79d5ebf3d1b6587e0bd311susnataimport android.os.Build;
2600f780c9e3cca0b2e364c61e936147e09877c43fDake Guimport android.support.annotation.NonNull;
2700f780c9e3cca0b2e364c61e936147e09877c43fDake Guimport android.support.v4.graphics.drawable.DrawableCompat;
283d9017263a760990ba79d5ebf3d1b6587e0bd311susnataimport android.util.Property;
29df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata
30df64e524a2bad079e6b0aa2d22c287f2c62aed82susnataimport java.util.ArrayList;
31df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata
32df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata/**
333d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * Generic drawable class that can be composed of multiple children. Whenever the bounds changes
3444ece5ceaaee232f9139ccbde40ac4a5e642bdeeChristophe Beyls * for this class, it updates those of its children.
35fe4317c9f0492c67e2ee48e3d135f649f5f1fc5cDake Gu * @hide
36df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata */
373d9017263a760990ba79d5ebf3d1b6587e0bd311susnata@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
383d9017263a760990ba79d5ebf3d1b6587e0bd311susnatapublic class CompositeDrawable extends Drawable implements Drawable.Callback {
3900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu
4000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    static class CompositeState extends Drawable.ConstantState {
4100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu
4200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        final ArrayList<ChildDrawable> mChildren;
4300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu
4400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        CompositeState() {
4500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            mChildren = new ArrayList<ChildDrawable>();
4600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        }
4700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu
4800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        CompositeState(CompositeState other, CompositeDrawable parent, Resources res) {
4900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            final int n = other.mChildren.size();
5000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            mChildren = new ArrayList<ChildDrawable>(n);
5100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            for (int k = 0; k < n; k++) {
5200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu                mChildren.add(new ChildDrawable(other.mChildren.get(k), parent, res));
5300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            }
5400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        }
5500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu
5600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        @NonNull
5700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        @Override
5800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        public Drawable newDrawable() {
5900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            return new CompositeDrawable(this);
6000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        }
6100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu
6200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        @Override
6300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        public int getChangingConfigurations() {
6400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            return 0;
6500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        }
6600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu
6700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    }
6800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu
6900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    CompositeState mState;
7000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    boolean mMutated = false;
7100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu
7200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    public CompositeDrawable() {
7300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        mState = new CompositeState();
7400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    }
7500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu
7600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    CompositeDrawable(CompositeState state) {
7700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        mState = state;
7800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    }
7900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu
8000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    @Override
8100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    public ConstantState getConstantState() {
8200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        return mState;
8300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    }
8400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu
8500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    @Override
8600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    public Drawable mutate() {
8700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        if (!mMutated && super.mutate() == this) {
8800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            mState = new CompositeState(mState, this, null);
8900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            final ArrayList<ChildDrawable> children = mState.mChildren;
9000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            for (int i = 0, n = children.size(); i < n; i++) {
9100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu                final Drawable dr = children.get(i).mDrawable;
9200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu                if (dr != null) {
9300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu                    dr.mutate();
9400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu                }
9500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            }
9600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            mMutated = true;
9700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        }
9800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        return this;
9900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    }
100df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata
101df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    /**
102df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata     * Adds the supplied region.
103df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata     */
1043d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    public void addChildDrawable(Drawable drawable) {
10500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        mState.mChildren.add(new ChildDrawable(drawable, this));
106df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    }
107df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata
108df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    /**
1093d9017263a760990ba79d5ebf3d1b6587e0bd311susnata     * Returns the {@link Drawable} for the given index.
110df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata     */
1113d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    public Drawable getDrawable(int index) {
11200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        return mState.mChildren.get(index).mDrawable;
113df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    }
114df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata
115df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    /**
1163d9017263a760990ba79d5ebf3d1b6587e0bd311susnata     * Returns the {@link ChildDrawable} at the given index.
117df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata     */
1183d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    public ChildDrawable getChildAt(int index) {
11900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        return mState.mChildren.get(index);
1203d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    }
1213d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
1223d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    /**
1233d9017263a760990ba79d5ebf3d1b6587e0bd311susnata     * Removes the child corresponding to the given index.
1243d9017263a760990ba79d5ebf3d1b6587e0bd311susnata     */
1253d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    public void removeChild(int index) {
12600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        mState.mChildren.remove(index);
127df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    }
128df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata
129df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    /**
130df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata     * Removes the given region.
131df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata     */
1323d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    public void removeDrawable(Drawable drawable) {
13300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        final ArrayList<ChildDrawable> children = mState.mChildren;
1343d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        for (int i = 0; i < children.size(); i++) {
1353d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            if (drawable == children.get(i).mDrawable) {
1363d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                children.get(i).mDrawable.setCallback(null);
1373d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                children.remove(i);
1383d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                return;
1393d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            }
1403d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        }
141df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    }
142df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata
143df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    /**
1443d9017263a760990ba79d5ebf3d1b6587e0bd311susnata     * Returns the total number of children.
145df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata     */
1463d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    public int getChildCount() {
14700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        return mState.mChildren.size();
148df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    }
149df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata
150df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    @Override
151df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    public void draw(Canvas canvas) {
15200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        final ArrayList<ChildDrawable> children = mState.mChildren;
1533d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        for (int i = 0; i < children.size(); i++) {
1543d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            children.get(i).mDrawable.draw(canvas);
155df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata        }
156df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    }
157df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata
158df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    @Override
159df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    protected void onBoundsChange(Rect bounds) {
160df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata        super.onBoundsChange(bounds);
1613d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        updateBounds(bounds);
162df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    }
163df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata
164df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    @Override
165df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    public void setColorFilter(ColorFilter colorFilter) {
16600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        final ArrayList<ChildDrawable> children = mState.mChildren;
1673d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        for (int i = 0; i < children.size(); i++) {
1683d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            children.get(i).mDrawable.setColorFilter(colorFilter);
169df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata        }
170df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    }
171df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata
172df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    @Override
173df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    public int getOpacity() {
174df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata        return PixelFormat.UNKNOWN;
175df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    }
176df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata
177df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    @Override
178df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    public void setAlpha(int alpha) {
17900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        final ArrayList<ChildDrawable> children = mState.mChildren;
1803d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        for (int i = 0; i < children.size(); i++) {
1813d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            children.get(i).mDrawable.setAlpha(alpha);
1823d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        }
1833d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    }
1843d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
18500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    /**
18600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu     * @return Alpha value between 0(inclusive) and 255(inclusive)
18700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu     */
18800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    public int getAlpha() {
18900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        final Drawable dr = getFirstNonNullDrawable();
19000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        if (dr != null) {
19100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            return DrawableCompat.getAlpha(dr);
19200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        } else {
19300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            return 0xFF;
19400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        }
19500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    }
19600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu
19700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    final Drawable getFirstNonNullDrawable() {
19800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        final ArrayList<ChildDrawable> children = mState.mChildren;
19900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        for (int i = 0, n = children.size(); i < n; i++) {
20000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            final Drawable dr = children.get(i).mDrawable;
20100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            if (dr != null) {
20200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu                return dr;
20300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            }
20400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        }
20500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        return null;
20600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu    }
20700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu
2083d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    @Override
2093d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    public void invalidateDrawable(Drawable who) {
2103d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        invalidateSelf();
2113d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    }
2123d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
2133d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    @Override
2143d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    public void scheduleDrawable(Drawable who, Runnable what, long when) {
2153d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        scheduleSelf(what, when);
2163d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    }
2173d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
2183d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    @Override
2193d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    public void unscheduleDrawable(Drawable who, Runnable what) {
2203d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        unscheduleSelf(what);
2213d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    }
2223d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
2233d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    /**
2243d9017263a760990ba79d5ebf3d1b6587e0bd311susnata     * Updates the bounds based on the {@link BoundsRule}.
2253d9017263a760990ba79d5ebf3d1b6587e0bd311susnata     */
2263d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    void updateBounds(Rect bounds) {
22700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        final ArrayList<ChildDrawable> children = mState.mChildren;
2283d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        for (int i = 0; i < children.size(); i++) {
2293d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            ChildDrawable childDrawable = children.get(i);
2303d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            childDrawable.updateBounds(bounds);
2313d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        }
2323d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    }
2333d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
2343d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    /**
2353d9017263a760990ba79d5ebf3d1b6587e0bd311susnata     * Wrapper class holding a drawable object and {@link BoundsRule} to update drawable bounds
2363d9017263a760990ba79d5ebf3d1b6587e0bd311susnata     * when parent bound changes.
2373d9017263a760990ba79d5ebf3d1b6587e0bd311susnata     */
2383d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
2393d9017263a760990ba79d5ebf3d1b6587e0bd311susnata    public static final class ChildDrawable {
240450fe7ab2d8a911ecdc335d55c60dfbae70f2407susnata        private final BoundsRule mBoundsRule;
2413d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        private final Drawable mDrawable;
2423d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        private final Rect adjustedBounds = new Rect();
243738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu        final CompositeDrawable mParent;
2443d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
2453d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        public ChildDrawable(Drawable drawable, CompositeDrawable parent) {
2463d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            this.mDrawable = drawable;
2473d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            this.mParent = parent;
248450fe7ab2d8a911ecdc335d55c60dfbae70f2407susnata            this.mBoundsRule = new BoundsRule();
24900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            drawable.setCallback(parent);
25000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        }
25100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu
25200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu        ChildDrawable(ChildDrawable orig, CompositeDrawable parent, Resources res) {
25300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            final Drawable dr = orig.mDrawable;
25400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            final Drawable clone;
25500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            if (dr != null) {
25600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu                final ConstantState cs = dr.getConstantState();
25700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu                if (res != null) {
25800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu                    clone = cs.newDrawable(res);
25900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu                } else {
26000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu                    clone = cs.newDrawable();
26100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu                }
26200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu                clone.setCallback(parent);
26300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu                DrawableCompat.setLayoutDirection(clone, DrawableCompat.getLayoutDirection(dr));
26400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu                clone.setBounds(dr.getBounds());
26500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu                clone.setLevel(dr.getLevel());
26600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            } else {
26700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu                clone = null;
26800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            }
269450fe7ab2d8a911ecdc335d55c60dfbae70f2407susnata            if (orig.mBoundsRule != null) {
270450fe7ab2d8a911ecdc335d55c60dfbae70f2407susnata                this.mBoundsRule = new BoundsRule(orig.mBoundsRule);
271450fe7ab2d8a911ecdc335d55c60dfbae70f2407susnata            } else {
272450fe7ab2d8a911ecdc335d55c60dfbae70f2407susnata                this.mBoundsRule = new BoundsRule();
273450fe7ab2d8a911ecdc335d55c60dfbae70f2407susnata            }
27400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            mDrawable = clone;
27500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu            mParent = parent;
2763d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        }
2773d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
2783d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        /**
2793d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * Returns the instance of {@link BoundsRule}.
2803d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         */
2813d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        public BoundsRule getBoundsRule() {
282450fe7ab2d8a911ecdc335d55c60dfbae70f2407susnata            return this.mBoundsRule;
2833d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        }
2843d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
2853d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        /**
2863d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * Returns the {@link Drawable}.
2873d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         */
2883d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        public Drawable getDrawable() {
2893d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            return mDrawable;
2903d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        }
2913d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
2923d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        /**
2933d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * Updates the bounds based on the {@link BoundsRule}.
2943d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         */
2953d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        void updateBounds(Rect bounds) {
296450fe7ab2d8a911ecdc335d55c60dfbae70f2407susnata            mBoundsRule.calculateBounds(bounds, adjustedBounds);
2973d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            mDrawable.setBounds(adjustedBounds);
2983d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        }
2993d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
300e464e5647326c000d2bd48e7d4369a279894f360susnata        /**
301e464e5647326c000d2bd48e7d4369a279894f360susnata         * After changing the {@link BoundsRule}, user should call this function
302e464e5647326c000d2bd48e7d4369a279894f360susnata         * for the drawable to recalculate its bounds.
303e464e5647326c000d2bd48e7d4369a279894f360susnata         */
304e464e5647326c000d2bd48e7d4369a279894f360susnata        public void recomputeBounds() {
3053d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            updateBounds(mParent.getBounds());
306df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata        }
3073d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
3083d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        /**
3093d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * Implementation of {@link Property} for overrideTop attribute.
3103d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         */
3113103f63e99d47573823957f7aa34308555873221Aurimas Liutikas        public static final Property<CompositeDrawable.ChildDrawable, Integer> TOP_ABSOLUTE =
3123103f63e99d47573823957f7aa34308555873221Aurimas Liutikas                new Property<CompositeDrawable.ChildDrawable, Integer>(
3133103f63e99d47573823957f7aa34308555873221Aurimas Liutikas                        Integer.class, "absoluteTop") {
3143d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            @Override
3153d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            public void set(CompositeDrawable.ChildDrawable obj, Integer value) {
3163d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                if (obj.getBoundsRule().mTop == null) {
3173d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                    obj.getBoundsRule().mTop = BoundsRule.absoluteValue(value);
3183d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                } else {
3193d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                    obj.getBoundsRule().mTop.setAbsoluteValue(value);
3203d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                }
3213d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
3223d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                obj.recomputeBounds();
3233d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            }
3243d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
3253d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            @Override
3263d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            public Integer get(CompositeDrawable.ChildDrawable obj) {
327738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu                if (obj.getBoundsRule().mTop == null) {
328738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu                    return obj.mParent.getBounds().top;
329738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu                }
3303d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                return obj.getBoundsRule().mTop.getAbsoluteValue();
3313d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            }
3323d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        };
3333d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
3343d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        /**
3353d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * Implementation of {@link Property} for overrideBottom attribute.
3363d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         */
3373103f63e99d47573823957f7aa34308555873221Aurimas Liutikas        public static final Property<CompositeDrawable.ChildDrawable, Integer> BOTTOM_ABSOLUTE =
3383103f63e99d47573823957f7aa34308555873221Aurimas Liutikas                new Property<CompositeDrawable.ChildDrawable, Integer>(
3393103f63e99d47573823957f7aa34308555873221Aurimas Liutikas                        Integer.class, "absoluteBottom") {
3403d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            @Override
3413d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            public void set(CompositeDrawable.ChildDrawable obj, Integer value) {
3423d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                if (obj.getBoundsRule().mBottom == null) {
3433d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                    obj.getBoundsRule().mBottom = BoundsRule.absoluteValue(value);
3443d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                } else {
3453d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                    obj.getBoundsRule().mBottom.setAbsoluteValue(value);
3463d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                }
3473d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
3483d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                obj.recomputeBounds();
3493d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            }
3503d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
3513d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            @Override
3523d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            public Integer get(CompositeDrawable.ChildDrawable obj) {
353738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu                if (obj.getBoundsRule().mBottom == null) {
354738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu                    return obj.mParent.getBounds().bottom;
355738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu                }
3563d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                return obj.getBoundsRule().mBottom.getAbsoluteValue();
3573d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            }
3583d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        };
3593d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
3603d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
3613d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        /**
3623d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * Implementation of {@link Property} for overrideLeft attribute.
3633d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         */
3643103f63e99d47573823957f7aa34308555873221Aurimas Liutikas        public static final Property<CompositeDrawable.ChildDrawable, Integer> LEFT_ABSOLUTE =
3653103f63e99d47573823957f7aa34308555873221Aurimas Liutikas                new Property<CompositeDrawable.ChildDrawable, Integer>(
3663103f63e99d47573823957f7aa34308555873221Aurimas Liutikas                        Integer.class, "absoluteLeft") {
3673d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            @Override
3683d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            public void set(CompositeDrawable.ChildDrawable obj, Integer value) {
3693d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                if (obj.getBoundsRule().mLeft == null) {
3703d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                    obj.getBoundsRule().mLeft = BoundsRule.absoluteValue(value);
3713d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                } else {
3723d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                    obj.getBoundsRule().mLeft.setAbsoluteValue(value);
3733d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                }
3743d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
3753d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                obj.recomputeBounds();
3763d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            }
3773d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
3783d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            @Override
3793d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            public Integer get(CompositeDrawable.ChildDrawable obj) {
380738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu                if (obj.getBoundsRule().mLeft == null) {
381738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu                    return obj.mParent.getBounds().left;
382738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu                }
3833d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                return obj.getBoundsRule().mLeft.getAbsoluteValue();
3843d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            }
3853d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        };
3863d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
3873d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        /**
3883d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * Implementation of {@link Property} for overrideRight attribute.
3893d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         */
3903103f63e99d47573823957f7aa34308555873221Aurimas Liutikas        public static final Property<CompositeDrawable.ChildDrawable, Integer> RIGHT_ABSOLUTE =
3913103f63e99d47573823957f7aa34308555873221Aurimas Liutikas                new Property<CompositeDrawable.ChildDrawable, Integer>(
3923103f63e99d47573823957f7aa34308555873221Aurimas Liutikas                        Integer.class, "absoluteRight") {
3933d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            @Override
3943d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            public void set(CompositeDrawable.ChildDrawable obj, Integer value) {
3953d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                if (obj.getBoundsRule().mRight == null) {
3963d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                    obj.getBoundsRule().mRight = BoundsRule.absoluteValue(value);
3973d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                } else {
3983d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                    obj.getBoundsRule().mRight.setAbsoluteValue(value);
3993d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                }
4003d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
4013d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                obj.recomputeBounds();
4023d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            }
4033d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
4043d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            @Override
4053d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            public Integer get(CompositeDrawable.ChildDrawable obj) {
406738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu                if (obj.getBoundsRule().mRight == null) {
407738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu                    return obj.mParent.getBounds().right;
408738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu                }
4093d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                return obj.getBoundsRule().mRight.getAbsoluteValue();
4103d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            }
4113d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        };
4123d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
4133d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        /**
4143d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * Implementation of {@link Property} for overwriting the bottom attribute of
4153d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * {@link BoundsRule} associated with this {@link ChildDrawable}. This allows users to
4163d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * change the bounds rules as a percentage of parent size. This is preferable over
4173d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * {@see PROPERTY_TOP_ABSOLUTE} when the exact start/end position of scroll movement
4183d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * isn't available at compile time.
4193d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         */
4203103f63e99d47573823957f7aa34308555873221Aurimas Liutikas        public static final Property<CompositeDrawable.ChildDrawable, Float> TOP_FRACTION =
4213103f63e99d47573823957f7aa34308555873221Aurimas Liutikas                new Property<CompositeDrawable.ChildDrawable, Float>(Float.class, "fractionTop") {
4223d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            @Override
4233d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            public void set(CompositeDrawable.ChildDrawable obj, Float value) {
4243d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                if (obj.getBoundsRule().mTop == null) {
4253d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                    obj.getBoundsRule().mTop = BoundsRule.inheritFromParent(value);
4263d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                } else {
4273d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                    obj.getBoundsRule().mTop.setFraction(value);
4283d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                }
4293d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
4303d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                obj.recomputeBounds();
4313d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            }
4323d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
4333d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            @Override
4343d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            public Float get(CompositeDrawable.ChildDrawable obj) {
435738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu                if (obj.getBoundsRule().mTop == null) {
436738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu                    return 0f;
437738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu                }
4383d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                return obj.getBoundsRule().mTop.getFraction();
4393d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            }
4403d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        };
4413d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
4423d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        /**
4433d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * Implementation of {@link Property} for overwriting the bottom attribute of
4443d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * {@link BoundsRule} associated with this {@link ChildDrawable}. This allows users to
4453d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * change the bounds rules as a percentage of parent size. This is preferable over
4463d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * {@see PROPERTY_BOTTOM_ABSOLUTE} when the exact start/end position of scroll movement
4473d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * isn't available at compile time.
4483d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         */
4493103f63e99d47573823957f7aa34308555873221Aurimas Liutikas        public static final Property<CompositeDrawable.ChildDrawable, Float> BOTTOM_FRACTION =
4503103f63e99d47573823957f7aa34308555873221Aurimas Liutikas                new Property<CompositeDrawable.ChildDrawable, Float>(
4513103f63e99d47573823957f7aa34308555873221Aurimas Liutikas                        Float.class, "fractionBottom") {
4523d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            @Override
4533d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            public void set(CompositeDrawable.ChildDrawable obj, Float value) {
4543d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                if (obj.getBoundsRule().mBottom == null) {
4553d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                    obj.getBoundsRule().mBottom = BoundsRule.inheritFromParent(value);
4563d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                } else {
4573d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                    obj.getBoundsRule().mBottom.setFraction(value);
4583d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                }
4593d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
4603d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                obj.recomputeBounds();
4613d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            }
4623d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
4633d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            @Override
4643d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            public Float get(CompositeDrawable.ChildDrawable obj) {
465738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu                if (obj.getBoundsRule().mBottom == null) {
466738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu                    return 1f;
467738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu                }
4683d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                return obj.getBoundsRule().mBottom.getFraction();
4693d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            }
4703d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        };
4713d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
4723d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        /**
4733d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * Implementation of {@link Property} for overwriting the bottom attribute of
4743d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * {@link BoundsRule} associated with this {@link ChildDrawable}. This allows users to
4753d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * change the bounds rules as a percentage of parent size. This is preferable over
4763d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * {@see PROPERTY_LEFT_ABSOLUTE} when the exact start/end position of scroll movement
4773d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * isn't available at compile time.
4783d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         */
4793103f63e99d47573823957f7aa34308555873221Aurimas Liutikas        public static final Property<CompositeDrawable.ChildDrawable, Float> LEFT_FRACTION =
4803103f63e99d47573823957f7aa34308555873221Aurimas Liutikas                new Property<CompositeDrawable.ChildDrawable, Float>(Float.class, "fractionLeft") {
4813d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            @Override
4823d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            public void set(CompositeDrawable.ChildDrawable obj, Float value) {
4833d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                if (obj.getBoundsRule().mLeft == null) {
4843d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                    obj.getBoundsRule().mLeft = BoundsRule.inheritFromParent(value);
4853d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                } else {
4863d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                    obj.getBoundsRule().mLeft.setFraction(value);
4873d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                }
4883d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
4893d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                obj.recomputeBounds();
4903d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            }
4913d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
4923d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            @Override
4933d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            public Float get(CompositeDrawable.ChildDrawable obj) {
494738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu                if (obj.getBoundsRule().mLeft == null) {
495738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu                    return 0f;
496738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu                }
4973d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                return obj.getBoundsRule().mLeft.getFraction();
4983d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            }
4993d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        };
5003d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
5013d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        /**
5023d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * Implementation of {@link Property} for overwriting the bottom attribute of
5033d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * {@link BoundsRule} associated with this {@link ChildDrawable}. This allows users to
5043d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * change the bounds rules as a percentage of parent size. This is preferable over
5053d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * {@see PROPERTY_RIGHT_ABSOLUTE} when the exact start/end position of scroll movement
5063d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         * isn't available at compile time.
5073d9017263a760990ba79d5ebf3d1b6587e0bd311susnata         */
5083103f63e99d47573823957f7aa34308555873221Aurimas Liutikas        public static final Property<CompositeDrawable.ChildDrawable, Float> RIGHT_FRACTION =
5093103f63e99d47573823957f7aa34308555873221Aurimas Liutikas                new Property<CompositeDrawable.ChildDrawable, Float>(Float.class, "fractoinRight") {
5103d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            @Override
5113d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            public void set(CompositeDrawable.ChildDrawable obj, Float value) {
5123d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                if (obj.getBoundsRule().mRight == null) {
5133d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                    obj.getBoundsRule().mRight = BoundsRule.inheritFromParent(value);
5143d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                } else {
5153d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                    obj.getBoundsRule().mRight.setFraction(value);
5163d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                }
5173d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
5183d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                obj.recomputeBounds();
5193d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            }
5203d9017263a760990ba79d5ebf3d1b6587e0bd311susnata
5213d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            @Override
5223d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            public Float get(CompositeDrawable.ChildDrawable obj) {
523738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu                if (obj.getBoundsRule().mRight == null) {
524738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu                    return 1f;
525738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu                }
5263d9017263a760990ba79d5ebf3d1b6587e0bd311susnata                return obj.getBoundsRule().mRight.getFraction();
5273d9017263a760990ba79d5ebf3d1b6587e0bd311susnata            }
5283d9017263a760990ba79d5ebf3d1b6587e0bd311susnata        };
529df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata    }
530df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata}
531