// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2009-2011 Google, All Rights reserved
// Copyright 2011-2012 MIT, All rights reserved
// Released under the Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0
package com.google.appinventor.components.runtime;
import com.google.appinventor.components.annotations.DesignerComponent;
import com.google.appinventor.components.annotations.DesignerProperty;
import com.google.appinventor.components.annotations.PropertyCategory;
import com.google.appinventor.components.annotations.SimpleObject;
import com.google.appinventor.components.annotations.SimpleProperty;
import com.google.appinventor.components.common.ComponentCategory;
import com.google.appinventor.components.common.PropertyTypeConstants;
import com.google.appinventor.components.common.YaVersion;
import com.google.appinventor.components.runtime.util.PaintUtil;
import android.graphics.Canvas;
import android.graphics.Paint;
/**
* Simple ball, based on Sprite implementation.
*
*/
@DesignerComponent(version = YaVersion.BALL_COMPONENT_VERSION,
description = "<p>A round 'sprite' that can be placed on a " +
"<code>Canvas</code>, where it can react to touches and drags, " +
"interact with other sprites (<code>ImageSprite</code>s and other " +
"<code>Ball</code>s) and the edge of the Canvas, and move according " +
"to its property values.</p>" +
"<p>For example, to have a <code>Ball</code> move 4 pixels toward the " +
"top of a <code>Canvas</code> every 500 milliseconds (half second), " +
"you would set the <code>Speed</code> property to 4 [pixels], the " +
"<code>Interval</code> property to 500 [milliseconds], the " +
"<code>Heading</code> property to 90 [degrees], and the " +
"<code>Enabled</code> property to <code>True</code>. These and its " +
"other properties can be changed at any time.</p>" +
"<p>The difference between a Ball and an <code>ImageSprite</code> is " +
"that the latter can get its appearance from an image file, while a " +
"Ball's appearance can only be changed by varying its " +
"<code>PaintColor</code> and <code>Radius</code> properties.</p>",
category = ComponentCategory.ANIMATION)
@SimpleObject
public final class Ball extends Sprite {
private int radius;
private int paintColor;
private Paint paint;
static final int DEFAULT_RADIUS = 5;
public Ball(ComponentContainer container) {
super(container);
paint = new Paint();
// Set default properties.
PaintColor(Component.COLOR_BLACK);
Radius(DEFAULT_RADIUS);
}
// Implement or override methods
@Override
protected void onDraw(Canvas canvas) {
if (visible) {
float correctedXLeft = (float)(xLeft * form.deviceDensity());
float correctedYTop = (float)(yTop * form.deviceDensity());
float correctedRadius = radius * form.deviceDensity();
canvas.drawCircle(correctedXLeft + correctedRadius, correctedYTop +
correctedRadius, correctedRadius, paint);
}
}
// The following four methods are required by abstract superclass
// VisibleComponent. Because we don't want to expose them to the Simple
// programmer, we omit the SimpleProperty and DesignerProperty pragmas.
@Override
public int Height() {
return 2 * radius;
}
@Override
public void Height(int height) {
// ignored
}
@Override
public void HeightPercent(int pCent) {
// ignored
}
@Override
public int Width() {
return 2 * radius;
}
@Override
public void Width(int width) {
// ignored
}
@Override
public void WidthPercent(int pCent) {
// ignored
}
@Override
public boolean containsPoint(double qx, double qy) {
double xCenter = xLeft + radius;
double yCenter = yTop + radius;
return ((qx - xCenter) * (qx - xCenter) + (qy - yCenter) * (qy - yCenter))
<= radius * radius;
}
// Additional properties
@DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_NON_NEGATIVE_INTEGER,
defaultValue = "5")
@SimpleProperty(
// Kind of both categories: APPEARANCE and BEHAVIOR
category = PropertyCategory.APPEARANCE)
public void Radius(int radius) {
this.radius = radius;
registerChange();
}
@SimpleProperty
public int Radius() {
return radius;
}
/**
* PaintColor property getter method.
*
* @return paint RGB color with alpha
*/
@SimpleProperty(
category = PropertyCategory.APPEARANCE)
public int PaintColor() {
return paintColor;
}
/**
* PaintColor property setter method.
*
* @param argb paint RGB color with alpha
*/
@DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_COLOR,
defaultValue = Component.DEFAULT_VALUE_COLOR_BLACK)
@SimpleProperty
public void PaintColor(int argb) {
paintColor = argb;
if (argb != Component.COLOR_DEFAULT) {
PaintUtil.changePaint(paint, argb);
} else {
// The default paint color is black.
PaintUtil.changePaint(paint, Component.COLOR_BLACK);
}
registerChange();
}
}