package org.radrails.rails.internal.ui.railsplugins;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
import org.radrails.rails.ui.RailsUIPlugin;
abstract class RatingImage
{
private static final float MAX_STARS = 5.0f;
private static Image empty;
private static Image filled;
private static Set<Image> fgImages = new HashSet<Image>();
public static void init(Display display)
{
dispose();
empty = RailsUIPlugin.getImageDescriptor("icons/unrated.png").createImage();
filled = RailsUIPlugin.getImageDescriptor("icons/rated.png").createImage();
fgImages = new HashSet<Image>();
}
public static void dispose()
{
if (fgImages != null)
{
for (Image image : fgImages)
{
image.dispose();
}
fgImages.clear();
fgImages = null;
}
if (empty != null)
{
empty.dispose();
}
if (filled != null)
{
filled.dispose();
}
empty = null;
filled = null;
}
// FIXME Share images with same number of stars!
public static Image createRatingImage(float rating, Display display)
{
if (filled == null || empty == null)
return null;
rating = forceWithinRange(rating, 0, MAX_STARS);
if (rating == MAX_STARS)
return copyImage(filled, display);
if (rating == 0.0)
return copyImage(empty, display);
try
{
int fullWidth = filled.getBounds().width;
float ratingInStars = rating / MAX_STARS;
int widthToFill = (int) (ratingInStars * fullWidth);
if (widthToFill <= 0)
return copyImage(empty, display);
return overlay(filled, empty, widthToFill, display);
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
/**
* Assumes src and dest images are same size. Copies pixels from src on top of dest from left to right, starting at
* 0 and proceeding until widthToFill.
*
* @param src
* @param dest
* @param widthToFill
* @param display
* @return The combined image
*/
private static Image overlay(Image src, Image dest, int widthToFill, Display display)
{
Rectangle bounds = src.getBounds();
ImageData destData = dest.getImageData();
ImageData srcData = src.getImageData();
for (int y = 0; y < bounds.height; y++)
{ // for each row of pixels
byte[] alphas = new byte[widthToFill]; // copy over alpha values
srcData.getAlphas(0, y, widthToFill, alphas, 0);
destData.setAlphas(0, y, widthToFill, alphas, 0);
int[] pixels = new int[widthToFill]; // copy over rgb values
srcData.getPixels(0, y, widthToFill, pixels, 0);
destData.setPixels(0, y, widthToFill, pixels, 0);
}
Image image = new Image(display, destData);
fgImages.add(image);
return image;
}
private static Image copyImage(Image image, Display display)
{
Image created = new Image(display, image, SWT.IMAGE_COPY);
fgImages.add(created);
return created;
}
private static float forceWithinRange(float rating, float min, float max)
{
if (rating < min)
return min;
if (rating > max)
return max;
return rating;
}
}