/* 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); } } }