/*
* Copyright (c) 2004-2009 XMLVM --- An XML-based Programming Language
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program 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 General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 675 Mass
* Ave, Cambridge, MA 02139, USA.
*
* For more information, visit the XMLVM Home Page at http://www.xmlvm.org
*/
package android.widget;
import org.xmlvm.iphone.CGRect;
import org.xmlvm.iphone.UIImage;
import org.xmlvm.iphone.UIImageView;
import org.xmlvm.iphone.UIView;
import org.xmlvm.iphone.UIViewContentMode;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.internal.Assert;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsoluteLayout.LayoutParams;
public class ImageView extends View {
/**
* Options for scaling the bounds of an image to the bounds of this view.
* <p>
* <i>(This enum is taken from Android's source code.)</i>
*/
public enum ScaleType {
/**
* Scale using the image matrix when drawing. The image matrix can be
* set using {@link ImageView#setImageMatrix(Matrix)}. From XML, use
* this syntax: <code>android:scaleType="matrix"</code>.
*/
MATRIX(0),
/**
* Scale the image using {@link Matrix.ScaleToFit#FILL}. From XML, use
* this syntax: <code>android:scaleType="fitXY"</code>.
*/
FIT_XY(1),
/**
* Scale the image using {@link Matrix.ScaleToFit#START}. From XML, use
* this syntax: <code>android:scaleType="fitStart"</code>.
*/
FIT_START(2),
/**
* Scale the image using {@link Matrix.ScaleToFit#CENTER}. From XML, use
* this syntax: <code>android:scaleType="fitCenter"</code>.
*/
FIT_CENTER(3),
/**
* Scale the image using {@link Matrix.ScaleToFit#END}. From XML, use
* this syntax: <code>android:scaleType="fitEnd"</code>.
*/
FIT_END(4),
/**
* Center the image in the view, but perform no scaling. From XML, use
* this syntax: <code>android:scaleType="center"</code>.
*/
CENTER(5),
/**
* Scale the image uniformly (maintain the image's aspect ratio) so that
* both dimensions (width and height) of the image will be equal to or
* larger than the corresponding dimension of the view (minus padding).
* The image is then centered in the view. From XML, use this syntax:
* <code>android:scaleType="centerCrop"</code>.
*/
CENTER_CROP(6),
/**
* Scale the image uniformly (maintain the image's aspect ratio) so that
* both dimensions (width and height) of the image will be equal to or
* less than the corresponding dimension of the view (minus padding).
* The image is then centered in the view. From XML, use this syntax:
* <code>android:scaleType="centerInside"</code>.
*/
CENTER_INSIDE(7);
ScaleType(int ni) {
nativeInt = ni;
}
final int nativeInt;
}
protected Drawable drawable;
public ImageView(Context c) {
super(c);
initImageView(c, null);
}
public ImageView(Context c, AttributeSet attrs) {
super(c, attrs);
initImageView(c, attrs);
}
public ImageView(Context c, AttributeSet attrs, int defStyle) {
super(c, attrs, defStyle);
Assert.NOT_IMPLEMENTED();
}
private void initImageView(Context c, AttributeSet attrs) {
setScaleType(ScaleType.CENTER);
if (attrs != null && attrs.getAttributeCount() > 0) {
parseImageViewAttributes(attrs);
}
}
public void setImageResource(int resId) {
Drawable d = getContext().getResources().getDrawable(resId);
setImageDrawable(d);
}
public void setImageDrawable(Drawable drawable) {
this.drawable = drawable;
if (drawable instanceof BitmapDrawable) {
getUIImageView().setImage(((BitmapDrawable) drawable).xmlvmGetImage());
} else if (drawable instanceof StateListDrawable) {
refreshImageStateDrawable();
} else {
Assert.NOT_IMPLEMENTED();
}
requestLayout();
}
@Override
public void setLayoutParams(ViewGroup.LayoutParams l) {
layoutParams = l;
int width = l.width;
int height = l.height;
if (width == LayoutParams.WRAP_CONTENT) {
width = getUIImageView().getImage() != null ? (int) getUIImageView().getImage()
.getSize().width : 0;
}
if (height == LayoutParams.WRAP_CONTENT) {
height = getUIImageView().getImage() != null ? (int) getUIImageView().getImage()
.getSize().height : 0;
}
int x = l instanceof AbsoluteLayout.LayoutParams ? ((AbsoluteLayout.LayoutParams) l).x : 0;
int y = l instanceof AbsoluteLayout.LayoutParams ? ((AbsoluteLayout.LayoutParams) l).y : 0;
getUIImageView().setFrame(new CGRect(x, y, width, height));
}
public void setScaleType(ScaleType type) {
UIView view = xmlvmGetUIView();
switch (type) {
case CENTER:
view.setContentMode(UIViewContentMode.Center);
break;
case CENTER_CROP:
view.setContentMode(UIViewContentMode.ScaleAspectFill);
break;
case CENTER_INSIDE:
view.setContentMode(UIViewContentMode.ScaleAspectFit);
break;
case FIT_CENTER:
view.setContentMode(UIViewContentMode.ScaleAspectFill);
break;
case FIT_END:
Assert.NOT_IMPLEMENTED();
break;
case FIT_START:
Assert.NOT_IMPLEMENTED();
break;
case FIT_XY:
view.setContentMode(UIViewContentMode.ScaleToFill);
break;
case MATRIX:
Assert.NOT_IMPLEMENTED();
break;
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = 0;
int height = 0;
if (drawable != null) {
Rect r = drawable.getBounds();
width = r.width();
height = r.height();
}
width = Math.max(getSuggestedMinimumWidth(), width + paddingLeft + paddingRight);
height = Math.max(getSuggestedMinimumHeight(), height + paddingTop + paddingBottom);
setMeasuredDimension(width, height);
}
private void parseImageViewAttributes(AttributeSet attrs) {
setIgnoreRequestLayout(true);
String str = attrs.getAttributeValue(null, "src");
// Resolve drawable background
if (str != null) {
int srcId = attrs.getAttributeResourceValue(null, "src", -1);
if (srcId != -1) {
setImageResource(srcId);
}
}
setIgnoreRequestLayout(false);
}
@Override
protected UIView xmlvmCreateUIView(AttributeSet attrs) {
return new UIImageView(new CGRect(0, 0, 0, 0));
}
protected UIImageView getUIImageView() {
return (UIImageView) xmlvmGetUIView();
}
@Override
protected void xmlvmSetDrawableState(int[] drawableState) {
super.xmlvmSetDrawableState(drawableState);
refreshImageStateDrawable();
}
private void refreshImageStateDrawable() {
if (drawable instanceof StateListDrawable) {
StateListDrawable d = (StateListDrawable) drawable;
int i = d.getStateDrawableIndex(getDrawableState());
d.selectDrawable(i);
Drawable currentStateDrawable = d.getStateDrawable(i);
UIImage newImg = ((BitmapDrawable) currentStateDrawable).xmlvmGetImage();
UIImage currentImg = getUIImageView().getImage();
if (currentImg != newImg) {
boolean relayout = currentImg != null && newImg != null
&& !currentImg.getSize().equals(newImg.getSize());
getUIImageView().setImage(newImg);
if (relayout) {
requestLayout();
}
}
}
}
}