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 */ 16ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.leanback.graphics; 17df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata 1800f780c9e3cca0b2e364c61e936147e09877c43fDake Guimport android.content.res.Resources; 19df64e524a2bad079e6b0aa2d22c287f2c62aed82susnataimport android.graphics.Canvas; 20df64e524a2bad079e6b0aa2d22c287f2c62aed82susnataimport android.graphics.ColorFilter; 21df64e524a2bad079e6b0aa2d22c287f2c62aed82susnataimport android.graphics.PixelFormat; 22df64e524a2bad079e6b0aa2d22c287f2c62aed82susnataimport android.graphics.Rect; 23df64e524a2bad079e6b0aa2d22c287f2c62aed82susnataimport android.graphics.drawable.Drawable; 248619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport android.util.Property; 258619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikas 26ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.annotation.NonNull; 27ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.core.graphics.drawable.DrawableCompat; 288619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport androidx.leanback.graphics.BoundsRule.ValueRule; 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. 35df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata */ 363d9017263a760990ba79d5ebf3d1b6587e0bd311susnatapublic class CompositeDrawable extends Drawable implements Drawable.Callback { 3700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu 3800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu static class CompositeState extends Drawable.ConstantState { 3900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu 4000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu final ArrayList<ChildDrawable> mChildren; 4100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu 4200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu CompositeState() { 4300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu mChildren = new ArrayList<ChildDrawable>(); 4400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu } 4500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu 4600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu CompositeState(CompositeState other, CompositeDrawable parent, Resources res) { 4700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu final int n = other.mChildren.size(); 4800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu mChildren = new ArrayList<ChildDrawable>(n); 4900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu for (int k = 0; k < n; k++) { 5000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu mChildren.add(new ChildDrawable(other.mChildren.get(k), parent, res)); 5100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu } 5200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu } 5300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu 5400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu @NonNull 5500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu @Override 5600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu public Drawable newDrawable() { 5700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu return new CompositeDrawable(this); 5800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu } 5900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu 6000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu @Override 6100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu public int getChangingConfigurations() { 6200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu return 0; 6300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu } 6400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu 6500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu } 6600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu 6700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu CompositeState mState; 6800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu boolean mMutated = false; 6900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu 7000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu public CompositeDrawable() { 7100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu mState = new CompositeState(); 7200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu } 7300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu 7400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu CompositeDrawable(CompositeState state) { 7500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu mState = state; 7600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu } 7700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu 7800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu @Override 7900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu public ConstantState getConstantState() { 8000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu return mState; 8100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu } 8200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu 8300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu @Override 8400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu public Drawable mutate() { 8500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu if (!mMutated && super.mutate() == this) { 8600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu mState = new CompositeState(mState, this, null); 8700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu final ArrayList<ChildDrawable> children = mState.mChildren; 8800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu for (int i = 0, n = children.size(); i < n; i++) { 8900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu final Drawable dr = children.get(i).mDrawable; 9000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu if (dr != null) { 9100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu dr.mutate(); 9200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu } 9300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu } 9400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu mMutated = true; 9500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu } 9600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu return this; 9700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu } 98df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata 99df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata /** 100df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata * Adds the supplied region. 101df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata */ 1023d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public void addChildDrawable(Drawable drawable) { 10300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu mState.mChildren.add(new ChildDrawable(drawable, this)); 104df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata } 105df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata 106df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata /** 107e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu * Sets the supplied region at given index. 108e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu */ 109e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu public void setChildDrawableAt(int index, Drawable drawable) { 110e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu mState.mChildren.set(index, new ChildDrawable(drawable, this)); 111e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu } 112e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu 113e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu /** 1143d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * Returns the {@link Drawable} for the given index. 115df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata */ 1163d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public Drawable getDrawable(int index) { 11700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu return mState.mChildren.get(index).mDrawable; 118df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata } 119df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata 120df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata /** 1213d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * Returns the {@link ChildDrawable} at the given index. 122df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata */ 1233d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public ChildDrawable getChildAt(int index) { 12400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu return mState.mChildren.get(index); 1253d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 1263d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 1273d9017263a760990ba79d5ebf3d1b6587e0bd311susnata /** 1283d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * Removes the child corresponding to the given index. 1293d9017263a760990ba79d5ebf3d1b6587e0bd311susnata */ 1303d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public void removeChild(int index) { 13100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu mState.mChildren.remove(index); 132df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata } 133df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata 134df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata /** 135df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata * Removes the given region. 136df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata */ 1373d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public void removeDrawable(Drawable drawable) { 13800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu final ArrayList<ChildDrawable> children = mState.mChildren; 1393d9017263a760990ba79d5ebf3d1b6587e0bd311susnata for (int i = 0; i < children.size(); i++) { 1403d9017263a760990ba79d5ebf3d1b6587e0bd311susnata if (drawable == children.get(i).mDrawable) { 1413d9017263a760990ba79d5ebf3d1b6587e0bd311susnata children.get(i).mDrawable.setCallback(null); 1423d9017263a760990ba79d5ebf3d1b6587e0bd311susnata children.remove(i); 1433d9017263a760990ba79d5ebf3d1b6587e0bd311susnata return; 1443d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 1453d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 146df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata } 147df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata 148df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata /** 1493d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * Returns the total number of children. 150df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata */ 1513d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public int getChildCount() { 15200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu return mState.mChildren.size(); 153df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata } 154df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata 155df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata @Override 156df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata public void draw(Canvas canvas) { 15700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu final ArrayList<ChildDrawable> children = mState.mChildren; 1583d9017263a760990ba79d5ebf3d1b6587e0bd311susnata for (int i = 0; i < children.size(); i++) { 1593d9017263a760990ba79d5ebf3d1b6587e0bd311susnata children.get(i).mDrawable.draw(canvas); 160df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata } 161df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata } 162df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata 163df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata @Override 164df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata protected void onBoundsChange(Rect bounds) { 165df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata super.onBoundsChange(bounds); 1663d9017263a760990ba79d5ebf3d1b6587e0bd311susnata updateBounds(bounds); 167df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata } 168df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata 169df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata @Override 170df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata public void setColorFilter(ColorFilter colorFilter) { 17100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu final ArrayList<ChildDrawable> children = mState.mChildren; 1723d9017263a760990ba79d5ebf3d1b6587e0bd311susnata for (int i = 0; i < children.size(); i++) { 1733d9017263a760990ba79d5ebf3d1b6587e0bd311susnata children.get(i).mDrawable.setColorFilter(colorFilter); 174df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata } 175df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata } 176df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata 177df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata @Override 178df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata public int getOpacity() { 179df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata return PixelFormat.UNKNOWN; 180df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata } 181df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata 182df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata @Override 183df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata public void setAlpha(int alpha) { 18400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu final ArrayList<ChildDrawable> children = mState.mChildren; 1853d9017263a760990ba79d5ebf3d1b6587e0bd311susnata for (int i = 0; i < children.size(); i++) { 1863d9017263a760990ba79d5ebf3d1b6587e0bd311susnata children.get(i).mDrawable.setAlpha(alpha); 1873d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 1883d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 1893d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 19000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu /** 19100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu * @return Alpha value between 0(inclusive) and 255(inclusive) 19200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu */ 193e2104f4b5c8e3ad63570306a25e61502dfe4c418Aurimas Liutikas @Override 19400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu public int getAlpha() { 19500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu final Drawable dr = getFirstNonNullDrawable(); 19600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu if (dr != null) { 19700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu return DrawableCompat.getAlpha(dr); 19800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu } else { 19900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu return 0xFF; 20000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu } 20100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu } 20200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu 20300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu final Drawable getFirstNonNullDrawable() { 20400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu final ArrayList<ChildDrawable> children = mState.mChildren; 20500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu for (int i = 0, n = children.size(); i < n; i++) { 20600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu final Drawable dr = children.get(i).mDrawable; 20700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu if (dr != null) { 20800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu return dr; 20900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu } 21000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu } 21100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu return null; 21200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu } 21300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu 2143d9017263a760990ba79d5ebf3d1b6587e0bd311susnata @Override 2153d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public void invalidateDrawable(Drawable who) { 2163d9017263a760990ba79d5ebf3d1b6587e0bd311susnata invalidateSelf(); 2173d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 2183d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 2193d9017263a760990ba79d5ebf3d1b6587e0bd311susnata @Override 2203d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public void scheduleDrawable(Drawable who, Runnable what, long when) { 2213d9017263a760990ba79d5ebf3d1b6587e0bd311susnata scheduleSelf(what, when); 2223d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 2233d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 2243d9017263a760990ba79d5ebf3d1b6587e0bd311susnata @Override 2253d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public void unscheduleDrawable(Drawable who, Runnable what) { 2263d9017263a760990ba79d5ebf3d1b6587e0bd311susnata unscheduleSelf(what); 2273d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 2283d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 2293d9017263a760990ba79d5ebf3d1b6587e0bd311susnata /** 2303d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * Updates the bounds based on the {@link BoundsRule}. 2313d9017263a760990ba79d5ebf3d1b6587e0bd311susnata */ 2323d9017263a760990ba79d5ebf3d1b6587e0bd311susnata void updateBounds(Rect bounds) { 23300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu final ArrayList<ChildDrawable> children = mState.mChildren; 2343d9017263a760990ba79d5ebf3d1b6587e0bd311susnata for (int i = 0; i < children.size(); i++) { 2353d9017263a760990ba79d5ebf3d1b6587e0bd311susnata ChildDrawable childDrawable = children.get(i); 2363d9017263a760990ba79d5ebf3d1b6587e0bd311susnata childDrawable.updateBounds(bounds); 2373d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 2383d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 2393d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 2403d9017263a760990ba79d5ebf3d1b6587e0bd311susnata /** 2413d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * Wrapper class holding a drawable object and {@link BoundsRule} to update drawable bounds 2423d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * when parent bound changes. 2433d9017263a760990ba79d5ebf3d1b6587e0bd311susnata */ 2443d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public static final class ChildDrawable { 245450fe7ab2d8a911ecdc335d55c60dfbae70f2407susnata private final BoundsRule mBoundsRule; 2463d9017263a760990ba79d5ebf3d1b6587e0bd311susnata private final Drawable mDrawable; 2473d9017263a760990ba79d5ebf3d1b6587e0bd311susnata private final Rect adjustedBounds = new Rect(); 248738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu final CompositeDrawable mParent; 2493d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 2503d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public ChildDrawable(Drawable drawable, CompositeDrawable parent) { 2513d9017263a760990ba79d5ebf3d1b6587e0bd311susnata this.mDrawable = drawable; 2523d9017263a760990ba79d5ebf3d1b6587e0bd311susnata this.mParent = parent; 253450fe7ab2d8a911ecdc335d55c60dfbae70f2407susnata this.mBoundsRule = new BoundsRule(); 25400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu drawable.setCallback(parent); 25500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu } 25600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu 25700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu ChildDrawable(ChildDrawable orig, CompositeDrawable parent, Resources res) { 25800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu final Drawable dr = orig.mDrawable; 25900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu final Drawable clone; 26000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu if (dr != null) { 26100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu final ConstantState cs = dr.getConstantState(); 26200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu if (res != null) { 26300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu clone = cs.newDrawable(res); 26400f780c9e3cca0b2e364c61e936147e09877c43fDake Gu } else { 26500f780c9e3cca0b2e364c61e936147e09877c43fDake Gu clone = cs.newDrawable(); 26600f780c9e3cca0b2e364c61e936147e09877c43fDake Gu } 26700f780c9e3cca0b2e364c61e936147e09877c43fDake Gu clone.setCallback(parent); 26800f780c9e3cca0b2e364c61e936147e09877c43fDake Gu DrawableCompat.setLayoutDirection(clone, DrawableCompat.getLayoutDirection(dr)); 26900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu clone.setBounds(dr.getBounds()); 27000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu clone.setLevel(dr.getLevel()); 27100f780c9e3cca0b2e364c61e936147e09877c43fDake Gu } else { 27200f780c9e3cca0b2e364c61e936147e09877c43fDake Gu clone = null; 27300f780c9e3cca0b2e364c61e936147e09877c43fDake Gu } 274450fe7ab2d8a911ecdc335d55c60dfbae70f2407susnata if (orig.mBoundsRule != null) { 275450fe7ab2d8a911ecdc335d55c60dfbae70f2407susnata this.mBoundsRule = new BoundsRule(orig.mBoundsRule); 276450fe7ab2d8a911ecdc335d55c60dfbae70f2407susnata } else { 277450fe7ab2d8a911ecdc335d55c60dfbae70f2407susnata this.mBoundsRule = new BoundsRule(); 278450fe7ab2d8a911ecdc335d55c60dfbae70f2407susnata } 27900f780c9e3cca0b2e364c61e936147e09877c43fDake Gu mDrawable = clone; 28000f780c9e3cca0b2e364c61e936147e09877c43fDake Gu mParent = parent; 2813d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 2823d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 2833d9017263a760990ba79d5ebf3d1b6587e0bd311susnata /** 2843d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * Returns the instance of {@link BoundsRule}. 2853d9017263a760990ba79d5ebf3d1b6587e0bd311susnata */ 2863d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public BoundsRule getBoundsRule() { 287450fe7ab2d8a911ecdc335d55c60dfbae70f2407susnata return this.mBoundsRule; 2883d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 2893d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 2903d9017263a760990ba79d5ebf3d1b6587e0bd311susnata /** 2913d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * Returns the {@link Drawable}. 2923d9017263a760990ba79d5ebf3d1b6587e0bd311susnata */ 2933d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public Drawable getDrawable() { 2943d9017263a760990ba79d5ebf3d1b6587e0bd311susnata return mDrawable; 2953d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 2963d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 2973d9017263a760990ba79d5ebf3d1b6587e0bd311susnata /** 2983d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * Updates the bounds based on the {@link BoundsRule}. 2993d9017263a760990ba79d5ebf3d1b6587e0bd311susnata */ 3003d9017263a760990ba79d5ebf3d1b6587e0bd311susnata void updateBounds(Rect bounds) { 301450fe7ab2d8a911ecdc335d55c60dfbae70f2407susnata mBoundsRule.calculateBounds(bounds, adjustedBounds); 3023d9017263a760990ba79d5ebf3d1b6587e0bd311susnata mDrawable.setBounds(adjustedBounds); 3033d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 3043d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 305e464e5647326c000d2bd48e7d4369a279894f360susnata /** 306e464e5647326c000d2bd48e7d4369a279894f360susnata * After changing the {@link BoundsRule}, user should call this function 307e464e5647326c000d2bd48e7d4369a279894f360susnata * for the drawable to recalculate its bounds. 308e464e5647326c000d2bd48e7d4369a279894f360susnata */ 309e464e5647326c000d2bd48e7d4369a279894f360susnata public void recomputeBounds() { 3103d9017263a760990ba79d5ebf3d1b6587e0bd311susnata updateBounds(mParent.getBounds()); 311df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata } 3123d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 3133d9017263a760990ba79d5ebf3d1b6587e0bd311susnata /** 3143d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * Implementation of {@link Property} for overrideTop attribute. 3153d9017263a760990ba79d5ebf3d1b6587e0bd311susnata */ 3163103f63e99d47573823957f7aa34308555873221Aurimas Liutikas public static final Property<CompositeDrawable.ChildDrawable, Integer> TOP_ABSOLUTE = 3173103f63e99d47573823957f7aa34308555873221Aurimas Liutikas new Property<CompositeDrawable.ChildDrawable, Integer>( 3183103f63e99d47573823957f7aa34308555873221Aurimas Liutikas Integer.class, "absoluteTop") { 3193d9017263a760990ba79d5ebf3d1b6587e0bd311susnata @Override 3203d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public void set(CompositeDrawable.ChildDrawable obj, Integer value) { 321e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (obj.getBoundsRule().top == null) { 322bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu obj.getBoundsRule().top = ValueRule.absoluteValue(value); 3233d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } else { 324e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu obj.getBoundsRule().top.setAbsoluteValue(value); 3253d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 3263d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 3273d9017263a760990ba79d5ebf3d1b6587e0bd311susnata obj.recomputeBounds(); 3283d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 3293d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 3303d9017263a760990ba79d5ebf3d1b6587e0bd311susnata @Override 3313d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public Integer get(CompositeDrawable.ChildDrawable obj) { 332e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (obj.getBoundsRule().top == null) { 333738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu return obj.mParent.getBounds().top; 334738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu } 335e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu return obj.getBoundsRule().top.getAbsoluteValue(); 3363d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 3373d9017263a760990ba79d5ebf3d1b6587e0bd311susnata }; 3383d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 3393d9017263a760990ba79d5ebf3d1b6587e0bd311susnata /** 3403d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * Implementation of {@link Property} for overrideBottom attribute. 3413d9017263a760990ba79d5ebf3d1b6587e0bd311susnata */ 3423103f63e99d47573823957f7aa34308555873221Aurimas Liutikas public static final Property<CompositeDrawable.ChildDrawable, Integer> BOTTOM_ABSOLUTE = 3433103f63e99d47573823957f7aa34308555873221Aurimas Liutikas new Property<CompositeDrawable.ChildDrawable, Integer>( 3443103f63e99d47573823957f7aa34308555873221Aurimas Liutikas Integer.class, "absoluteBottom") { 3453d9017263a760990ba79d5ebf3d1b6587e0bd311susnata @Override 3463d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public void set(CompositeDrawable.ChildDrawable obj, Integer value) { 347e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (obj.getBoundsRule().bottom == null) { 348bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu obj.getBoundsRule().bottom = ValueRule.absoluteValue(value); 3493d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } else { 350e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu obj.getBoundsRule().bottom.setAbsoluteValue(value); 3513d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 3523d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 3533d9017263a760990ba79d5ebf3d1b6587e0bd311susnata obj.recomputeBounds(); 3543d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 3553d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 3563d9017263a760990ba79d5ebf3d1b6587e0bd311susnata @Override 3573d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public Integer get(CompositeDrawable.ChildDrawable obj) { 358e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (obj.getBoundsRule().bottom == null) { 359738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu return obj.mParent.getBounds().bottom; 360738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu } 361e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu return obj.getBoundsRule().bottom.getAbsoluteValue(); 3623d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 3633d9017263a760990ba79d5ebf3d1b6587e0bd311susnata }; 3643d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 3653d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 3663d9017263a760990ba79d5ebf3d1b6587e0bd311susnata /** 3673d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * Implementation of {@link Property} for overrideLeft attribute. 3683d9017263a760990ba79d5ebf3d1b6587e0bd311susnata */ 3693103f63e99d47573823957f7aa34308555873221Aurimas Liutikas public static final Property<CompositeDrawable.ChildDrawable, Integer> LEFT_ABSOLUTE = 3703103f63e99d47573823957f7aa34308555873221Aurimas Liutikas new Property<CompositeDrawable.ChildDrawable, Integer>( 3713103f63e99d47573823957f7aa34308555873221Aurimas Liutikas Integer.class, "absoluteLeft") { 3723d9017263a760990ba79d5ebf3d1b6587e0bd311susnata @Override 3733d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public void set(CompositeDrawable.ChildDrawable obj, Integer value) { 374e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (obj.getBoundsRule().left == null) { 375bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu obj.getBoundsRule().left = ValueRule.absoluteValue(value); 3763d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } else { 377e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu obj.getBoundsRule().left.setAbsoluteValue(value); 3783d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 3793d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 3803d9017263a760990ba79d5ebf3d1b6587e0bd311susnata obj.recomputeBounds(); 3813d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 3823d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 3833d9017263a760990ba79d5ebf3d1b6587e0bd311susnata @Override 3843d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public Integer get(CompositeDrawable.ChildDrawable obj) { 385e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (obj.getBoundsRule().left == null) { 386738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu return obj.mParent.getBounds().left; 387738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu } 388e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu return obj.getBoundsRule().left.getAbsoluteValue(); 3893d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 3903d9017263a760990ba79d5ebf3d1b6587e0bd311susnata }; 3913d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 3923d9017263a760990ba79d5ebf3d1b6587e0bd311susnata /** 3933d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * Implementation of {@link Property} for overrideRight attribute. 3943d9017263a760990ba79d5ebf3d1b6587e0bd311susnata */ 3953103f63e99d47573823957f7aa34308555873221Aurimas Liutikas public static final Property<CompositeDrawable.ChildDrawable, Integer> RIGHT_ABSOLUTE = 3963103f63e99d47573823957f7aa34308555873221Aurimas Liutikas new Property<CompositeDrawable.ChildDrawable, Integer>( 3973103f63e99d47573823957f7aa34308555873221Aurimas Liutikas Integer.class, "absoluteRight") { 3983d9017263a760990ba79d5ebf3d1b6587e0bd311susnata @Override 3993d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public void set(CompositeDrawable.ChildDrawable obj, Integer value) { 400e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (obj.getBoundsRule().right == null) { 401bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu obj.getBoundsRule().right = ValueRule.absoluteValue(value); 4023d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } else { 403e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu obj.getBoundsRule().right.setAbsoluteValue(value); 4043d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 4053d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 4063d9017263a760990ba79d5ebf3d1b6587e0bd311susnata obj.recomputeBounds(); 4073d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 4083d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 4093d9017263a760990ba79d5ebf3d1b6587e0bd311susnata @Override 4103d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public Integer get(CompositeDrawable.ChildDrawable obj) { 411e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (obj.getBoundsRule().right == null) { 412738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu return obj.mParent.getBounds().right; 413738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu } 414e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu return obj.getBoundsRule().right.getAbsoluteValue(); 4153d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 4163d9017263a760990ba79d5ebf3d1b6587e0bd311susnata }; 4173d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 4183d9017263a760990ba79d5ebf3d1b6587e0bd311susnata /** 4193d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * Implementation of {@link Property} for overwriting the bottom attribute of 4203d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * {@link BoundsRule} associated with this {@link ChildDrawable}. This allows users to 4213d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * change the bounds rules as a percentage of parent size. This is preferable over 4223d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * {@see PROPERTY_TOP_ABSOLUTE} when the exact start/end position of scroll movement 4233d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * isn't available at compile time. 4243d9017263a760990ba79d5ebf3d1b6587e0bd311susnata */ 4253103f63e99d47573823957f7aa34308555873221Aurimas Liutikas public static final Property<CompositeDrawable.ChildDrawable, Float> TOP_FRACTION = 4263103f63e99d47573823957f7aa34308555873221Aurimas Liutikas new Property<CompositeDrawable.ChildDrawable, Float>(Float.class, "fractionTop") { 4273d9017263a760990ba79d5ebf3d1b6587e0bd311susnata @Override 4283d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public void set(CompositeDrawable.ChildDrawable obj, Float value) { 429e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (obj.getBoundsRule().top == null) { 430bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu obj.getBoundsRule().top = ValueRule.inheritFromParent(value); 4313d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } else { 432e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu obj.getBoundsRule().top.setFraction(value); 4333d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 4343d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 4353d9017263a760990ba79d5ebf3d1b6587e0bd311susnata obj.recomputeBounds(); 4363d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 4373d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 4383d9017263a760990ba79d5ebf3d1b6587e0bd311susnata @Override 4393d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public Float get(CompositeDrawable.ChildDrawable obj) { 440e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (obj.getBoundsRule().top == null) { 441738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu return 0f; 442738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu } 443e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu return obj.getBoundsRule().top.getFraction(); 4443d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 4453d9017263a760990ba79d5ebf3d1b6587e0bd311susnata }; 4463d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 4473d9017263a760990ba79d5ebf3d1b6587e0bd311susnata /** 4483d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * Implementation of {@link Property} for overwriting the bottom attribute of 4493d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * {@link BoundsRule} associated with this {@link ChildDrawable}. This allows users to 4503d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * change the bounds rules as a percentage of parent size. This is preferable over 4513d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * {@see PROPERTY_BOTTOM_ABSOLUTE} when the exact start/end position of scroll movement 4523d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * isn't available at compile time. 4533d9017263a760990ba79d5ebf3d1b6587e0bd311susnata */ 4543103f63e99d47573823957f7aa34308555873221Aurimas Liutikas public static final Property<CompositeDrawable.ChildDrawable, Float> BOTTOM_FRACTION = 4553103f63e99d47573823957f7aa34308555873221Aurimas Liutikas new Property<CompositeDrawable.ChildDrawable, Float>( 4563103f63e99d47573823957f7aa34308555873221Aurimas Liutikas Float.class, "fractionBottom") { 4573d9017263a760990ba79d5ebf3d1b6587e0bd311susnata @Override 4583d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public void set(CompositeDrawable.ChildDrawable obj, Float value) { 459e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (obj.getBoundsRule().bottom == null) { 460bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu obj.getBoundsRule().bottom = ValueRule.inheritFromParent(value); 4613d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } else { 462e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu obj.getBoundsRule().bottom.setFraction(value); 4633d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 4643d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 4653d9017263a760990ba79d5ebf3d1b6587e0bd311susnata obj.recomputeBounds(); 4663d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 4673d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 4683d9017263a760990ba79d5ebf3d1b6587e0bd311susnata @Override 4693d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public Float get(CompositeDrawable.ChildDrawable obj) { 470e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (obj.getBoundsRule().bottom == null) { 471738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu return 1f; 472738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu } 473e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu return obj.getBoundsRule().bottom.getFraction(); 4743d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 4753d9017263a760990ba79d5ebf3d1b6587e0bd311susnata }; 4763d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 4773d9017263a760990ba79d5ebf3d1b6587e0bd311susnata /** 4783d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * Implementation of {@link Property} for overwriting the bottom attribute of 4793d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * {@link BoundsRule} associated with this {@link ChildDrawable}. This allows users to 4803d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * change the bounds rules as a percentage of parent size. This is preferable over 4813d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * {@see PROPERTY_LEFT_ABSOLUTE} when the exact start/end position of scroll movement 4823d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * isn't available at compile time. 4833d9017263a760990ba79d5ebf3d1b6587e0bd311susnata */ 4843103f63e99d47573823957f7aa34308555873221Aurimas Liutikas public static final Property<CompositeDrawable.ChildDrawable, Float> LEFT_FRACTION = 4853103f63e99d47573823957f7aa34308555873221Aurimas Liutikas new Property<CompositeDrawable.ChildDrawable, Float>(Float.class, "fractionLeft") { 4863d9017263a760990ba79d5ebf3d1b6587e0bd311susnata @Override 4873d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public void set(CompositeDrawable.ChildDrawable obj, Float value) { 488e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (obj.getBoundsRule().left == null) { 489bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu obj.getBoundsRule().left = ValueRule.inheritFromParent(value); 4903d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } else { 491e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu obj.getBoundsRule().left.setFraction(value); 4923d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 4933d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 4943d9017263a760990ba79d5ebf3d1b6587e0bd311susnata obj.recomputeBounds(); 4953d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 4963d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 4973d9017263a760990ba79d5ebf3d1b6587e0bd311susnata @Override 4983d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public Float get(CompositeDrawable.ChildDrawable obj) { 499e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (obj.getBoundsRule().left == null) { 500738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu return 0f; 501738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu } 502e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu return obj.getBoundsRule().left.getFraction(); 5033d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 5043d9017263a760990ba79d5ebf3d1b6587e0bd311susnata }; 5053d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 5063d9017263a760990ba79d5ebf3d1b6587e0bd311susnata /** 5073d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * Implementation of {@link Property} for overwriting the bottom attribute of 5083d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * {@link BoundsRule} associated with this {@link ChildDrawable}. This allows users to 5093d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * change the bounds rules as a percentage of parent size. This is preferable over 5103d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * {@see PROPERTY_RIGHT_ABSOLUTE} when the exact start/end position of scroll movement 5113d9017263a760990ba79d5ebf3d1b6587e0bd311susnata * isn't available at compile time. 5123d9017263a760990ba79d5ebf3d1b6587e0bd311susnata */ 5133103f63e99d47573823957f7aa34308555873221Aurimas Liutikas public static final Property<CompositeDrawable.ChildDrawable, Float> RIGHT_FRACTION = 514bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu new Property<CompositeDrawable.ChildDrawable, Float>(Float.class, "fractionRight") { 5153d9017263a760990ba79d5ebf3d1b6587e0bd311susnata @Override 5163d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public void set(CompositeDrawable.ChildDrawable obj, Float value) { 517e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (obj.getBoundsRule().right == null) { 518bf4318c67254bc11307796601b9fb4a8bbfe67b2Dake Gu obj.getBoundsRule().right = ValueRule.inheritFromParent(value); 5193d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } else { 520e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu obj.getBoundsRule().right.setFraction(value); 5213d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 5223d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 5233d9017263a760990ba79d5ebf3d1b6587e0bd311susnata obj.recomputeBounds(); 5243d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 5253d9017263a760990ba79d5ebf3d1b6587e0bd311susnata 5263d9017263a760990ba79d5ebf3d1b6587e0bd311susnata @Override 5273d9017263a760990ba79d5ebf3d1b6587e0bd311susnata public Float get(CompositeDrawable.ChildDrawable obj) { 528e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu if (obj.getBoundsRule().right == null) { 529738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu return 1f; 530738deb3f9c75ea32dff1bf335753703e40e87f39Dake Gu } 531e1cde4d4ac42a6e9e16aad2b4df970c7c7d0771cDake Gu return obj.getBoundsRule().right.getFraction(); 5323d9017263a760990ba79d5ebf3d1b6587e0bd311susnata } 5333d9017263a760990ba79d5ebf3d1b6587e0bd311susnata }; 534df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata } 535df64e524a2bad079e6b0aa2d22c287f2c62aed82susnata} 536