/* Copyright (c) 2002-2011 by XMLVM.org
*
* Project Info: http://www.xmlvm.org
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*/
package android.graphics.drawable;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.internal.Assert;
public class DrawableContainer extends Drawable {
private int currentIndex = -1;
private Drawable currentDrawable = null;
private DrawableContainerState drawableContainerState;
protected void setConstantState(DrawableContainerState state) {
drawableContainerState = state;
}
@Override
public int getIntrinsicWidth() {
if (drawableContainerState.isConstantSize()) {
return drawableContainerState.getConstantWidth();
}
return currentDrawable != null ? currentDrawable.getIntrinsicWidth() : -1;
}
@Override
public int getIntrinsicHeight() {
if (drawableContainerState.isConstantSize()) {
return drawableContainerState.getConstantHeight();
}
return currentDrawable != null ? currentDrawable.getIntrinsicHeight() : -1;
}
@Override
public int getMinimumWidth() {
if (drawableContainerState.isConstantSize()) {
return drawableContainerState.getConstantMinimumWidth();
}
return currentDrawable != null ? currentDrawable.getMinimumWidth() : 0;
}
@Override
public int getMinimumHeight() {
if (drawableContainerState.isConstantSize()) {
return drawableContainerState.getConstantMinimumHeight();
}
return currentDrawable != null ? currentDrawable.getMinimumHeight() : 0;
}
@Override
public boolean isStateful() {
return drawableContainerState.isStateful();
}
public boolean selectDrawable(int idx) {
if (idx == currentIndex) {
return false;
}
if (idx >= 0 && idx < drawableContainerState.numChildren) {
Drawable d = drawableContainerState.drawables[idx];
if (currentDrawable != null) {
// currentDrawable.setVisible(false, false);
}
currentDrawable = d;
currentIndex = idx;
if (d != null) {
// d.setVisible(isVisible(), true);
// d.setAlpha(mAlpha);
// d.setDither(mDither);
// d.setColorFilter(mColorFilter);
// d.setState(getState());
// d.setLevel(getLevel());
d.setBounds(getBounds());
}
} else {
if (currentDrawable != null) {
// currentDrawable.setVisible(false, false);
}
currentDrawable = null;
currentIndex = -1;
}
// invalidateSelf();
return true;
}
@Override
public Drawable getCurrent() {
return currentDrawable;
}
// TODO: Padding is probably not working by now
@Override
public boolean getPadding(Rect padding) {
final Rect r = drawableContainerState.getConstantPadding();
if (r != null) {
padding.set(r);
return true;
}
if (currentDrawable != null) {
return currentDrawable.getPadding(padding);
} else {
return super.getPadding(padding);
}
}
@Override
protected void onBoundsChange(Rect bounds) {
if (currentDrawable != null) {
currentDrawable.setBounds(bounds);
}
}
public abstract static class DrawableContainerState extends ConstantState {
protected static final int INIT_SIZE = 10;
//private final DrawableContainer owner;
private boolean constantSize = false;
private boolean computedConstantSize = false;
private int constantWidth;
private int constantHeight;
private int constantMinimumWidth;
private boolean variablePadding = false;
private Rect constantPadding = null;
private int constantMinimumHeight;
private boolean paddingChecked = false;
private int numChildren;
protected Drawable[] drawables = new Drawable[INIT_SIZE];
DrawableContainerState(DrawableContainerState orig, DrawableContainer owner) {
//TODO this.owner is not used. If that ever changes, it should be made a WeakReference
//this.owner = owner;
if (orig != null) {
Assert.NOT_IMPLEMENTED();
}
}
public final int addChild(Drawable dr) {
final int pos = numChildren;
if (pos >= drawables.length) {
growArray(pos, pos + 10);
}
drawables[pos] = dr;
numChildren++;
return pos;
}
public final int getChildCount() {
return numChildren;
}
public final Drawable[] getChildren() {
return drawables;
}
@Override
public int getChangingConfigurations() {
Assert.NOT_IMPLEMENTED();
return 0;
}
public void growArray(int oldSize, int newSize) {
Drawable[] newDrawables = new Drawable[newSize];
System.arraycopy(drawables, 0, newDrawables, 0, oldSize);
drawables = newDrawables;
}
public final boolean isStateful() {
return true;
}
public final int getConstantWidth() {
if (!computedConstantSize) {
computeConstantSize();
}
return constantWidth;
}
public final int getConstantHeight() {
if (!computedConstantSize) {
computeConstantSize();
}
return constantHeight;
}
public final int getConstantMinimumWidth() {
if (!computedConstantSize) {
computeConstantSize();
}
return constantMinimumWidth;
}
public final int getConstantMinimumHeight() {
if (!computedConstantSize) {
computeConstantSize();
}
return constantMinimumHeight;
}
private void computeConstantSize() {
computedConstantSize = true;
final int N = getChildCount();
final Drawable[] drawables = this.drawables;
constantWidth = constantHeight = 0;
constantMinimumWidth = constantMinimumHeight = 0;
for (int i = 0; i < N; i++) {
Drawable dr = drawables[i];
int s = dr.getIntrinsicWidth();
if (s > constantWidth)
constantWidth = s;
s = dr.getIntrinsicHeight();
if (s > constantHeight)
constantHeight = s;
s = dr.getMinimumWidth();
if (s > constantMinimumWidth)
constantMinimumWidth = s;
s = dr.getMinimumHeight();
if (s > constantMinimumHeight)
constantMinimumHeight = s;
}
}
public final boolean isConstantSize() {
return constantSize;
}
public final Rect getConstantPadding() {
if (variablePadding) {
return null;
}
if (constantPadding != null || paddingChecked) {
return constantPadding;
}
Rect r = null;
final Rect t = new Rect();
final int N = getChildCount();
final Drawable[] drawables = this.drawables;
for (int i = 0; i < N; i++) {
if (drawables[i].getPadding(t)) {
if (r == null)
r = new Rect(0, 0, 0, 0);
if (t.left > r.left)
r.left = t.left;
if (t.top > r.top)
r.top = t.top;
if (t.right > r.right)
r.right = t.right;
if (t.bottom > r.bottom)
r.bottom = t.bottom;
}
}
paddingChecked = true;
return (constantPadding = r);
}
}
@Override
public void draw(Canvas canvas) {
if (currentDrawable != null) {
currentDrawable.draw(canvas);
}
}
}