/**
* CreateImageVGField.java
*
* Copyright � 1998-2011 Research In Motion Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Note: For the sake of simplicity, this sample application may not leverage
* resource bundles and resource strings. However, it is STRONGLY recommended
* that application developers make use of the localization features available
* within the BlackBerry development platform to ensure a seamless application
* experience across a variety of languages and geographies. For more information
* on localizing your application, please refer to the BlackBerry Java Development
* Environment Development Guide associated with this release.
*/
package com.rim.samples.device.openvgdemo;
import net.rim.device.api.animation.AnimatedScalar;
import net.rim.device.api.animation.Animation;
import net.rim.device.api.animation.Animator;
import net.rim.device.api.openvg.VG;
import net.rim.device.api.openvg.VG10;
import net.rim.device.api.openvg.VG11;
import net.rim.device.api.openvg.VGField;
import net.rim.device.api.openvg.VGUtils;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.Display;
import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.FontSpec;
import net.rim.device.api.ui.XYRect;
/**
* A VGField class that demonstrates displaying a series of icon images
* contained in a single image file in an circular animated fashion. The class
* also uses Open VG to draw a textual description on the screen.
*/
public class CreateImageVGField extends VGField {
private static final int TARGET_FRAME_RATE = 60;
private static final int NUM_ICONS = 13;
private static final int NUM_COLUMNS = 3;
private static final int ICON_WIDTH = 27;
private static final int ICON_HEIGHT = 27;
private static final int TEXT_OFFSET = 30;
private static final float[] MY_CLEAR_COLOR = new float[] { 0.6f, 0.8f,
1.0f, 1.0f };
private static final float RADIUS = 52.0f;
private static final float ROTATE = -360.0f / NUM_ICONS;
private final int[] _imageHandles = new int[NUM_ICONS];
private int _textImage;
private int _displayHeight;
private float _xScreenCenter;
private float _yScreenCenter;
private Animator _animator;
private final AnimatedScalar _mainRotation = new AnimatedScalar(0.0f);
/**
* Creates a new CreateImageVGField object
*/
public CreateImageVGField() {
super(VGField.VERSION_1_1);
// Set the target frame rate for calling update()
setTargetFrameRate(TARGET_FRAME_RATE);
}
/**
* @see net.rim.device.api.openvg.VGField#initialize(VG)
*/
protected void initialize(final VG g) {
final VG11 vg = (VG11) g;
vg.vgSetfv(VG10.VG_CLEAR_COLOR, 4, MY_CLEAR_COLOR, 0);
final XYRect rect = new XYRect();
// Create the bitmap from bundled resource "icons.png"
final Bitmap bitmap = Bitmap.getBitmapResource("icons.png");
// Create the image for all the icons
for (int i = 0; i < _imageHandles.length; i++) {
// Update the XYRect in which the image will be displayed
updateRect(rect, i);
_imageHandles[i] =
VGUtils.vgCreateImage(vg, bitmap, true,
VG10.VG_IMAGE_QUALITY_BETTER, rect);
}
// Get the default font and its FontSpec
final Font font = Font.getDefault();
final FontSpec fontSpec = font.getFontSpec();
// Create text image
_textImage =
VGUtils.vgCreateTextAsImage(vg, fontSpec,
"Tap or click to swap screens", null, null);
// Set up the animation. The animation will animate a scalar float value
// (_mainRotation) from 360 to 0 over 3 seconds and will repeat
// indefinitely.
_animator = new Animator(0);
final Animation animation =
_animator.addAnimationFromTo(_mainRotation,
AnimatedScalar.ANIMATION_PROPERTY_SCALAR, 360.0f, 0.0f,
Animation.EASINGCURVE_LINEAR, 3000L);
animation.setRepeatCount(Animation.REPEAT_COUNT_INDEFINITE);
_animator.begin(0L);
}
/**
* Updates the XYRect where the icons will be displayed and places the icons
* in a circle.
*
* @param rect
* XYRect that will be updated
* @param position
* The icon's position in the bitmap
*/
private void updateRect(final XYRect rect, final int position) {
final int x = position % NUM_COLUMNS * ICON_WIDTH;
final int y = position / NUM_COLUMNS * ICON_HEIGHT;
rect.set(x, y, ICON_WIDTH, ICON_HEIGHT);
}
/**
* @see net.rim.device.api.openvg.VGField#render(VG)
*/
protected void render(final VG g) {
final VG11 vg = (VG11) g;
// Clear the display
vg.vgClear(0, 0, getWidth(), getHeight());
vg.vgSeti(VG10.VG_MATRIX_MODE, VG10.VG_MATRIX_IMAGE_USER_TO_SURFACE);
// Shifting bits by >> 1 is equivalent to division by 2
final float halfIconWidth = ICON_WIDTH >> 1;
// Go through all the images and rotate them
// around the center of the screen.
for (int i = 0; i < _imageHandles.length; i++) {
// Load clean Identity matrix
vg.vgLoadIdentity();
// Translate to the center of the display
vg.vgTranslate(_xScreenCenter, _yScreenCenter);
// Rotate the image
vg.vgRotate(_mainRotation.getFloat() + ROTATE * i);
// Translate the image half of the icon's width
vg.vgTranslate(-halfIconWidth, RADIUS);
// Draw the rotated, translated image
vg.vgDrawImage(_imageHandles[i]);
}
// Draw the text image on this field
drawText(vg);
}
/**
* Draws text at the top of the VGField
*
* @param vg
* The object that will be used to render the text
*/
public void drawText(final VG11 vg) {
vg.vgSeti(VG10.VG_MATRIX_MODE, VG10.VG_MATRIX_IMAGE_USER_TO_SURFACE);
// Load a clean identity matrix
vg.vgLoadIdentity();
// Translate to the next drawing location
vg.vgTranslate(0.0f, _displayHeight - TEXT_OFFSET);
// Draw the text on the display
vg.vgDrawImage(_textImage);
}
/**
* @see net.rim.device.api.openvg.VGField#update()
*/
public void update() {
_animator.update();
}
/**
* @see net.rim.device.api.openvg.VGField#layout(int, int)
*/
protected void layout(final int width, final int height) {
final int displayWidth = Display.getWidth();
_displayHeight = Display.getHeight();
// Shifting bits by >> 1 is equivalent to division by 2
_xScreenCenter = (displayWidth >> 1);
_yScreenCenter = (_displayHeight >> 1);
setExtent(Math.min(displayWidth, width), Math.min(_displayHeight,
height));
}
}