/*******************************************************************************
* Copyright (c) 2009 Paul VanderLei, Simon Archer, Jeff McAffer and others. All
* rights reserved. This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0 and Eclipse Distribution License
* v1.0 which accompanies this distribution. The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License
* is available at http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Paul VanderLei, Simon Archer, Jeff McAffer - initial API and implementation
*******************************************************************************/
package org.eclipse.examples.toast.crust.shell;
import java.io.InputStream;
import org.eclipse.examples.toast.core.LogUtility;
import org.eclipse.examples.toast.crust.widgets.ImageButton;
import org.eclipse.examples.toast.crust.widgets.ImageProgressBar;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.graphics.Region;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Layout;
public class ScaledWidgetFactory {
private Class clazz;
private int screenWidth;
private int screenHeight;
private int referenceHeight;
private int referenceWidth;
public ScaledWidgetFactory(Class clazz, Point size, int referenceHeight, int referenceWidth) {
this.clazz = clazz;
this.screenWidth = size.x;
this.screenHeight = size.y;
this.referenceHeight = referenceHeight;
this.referenceWidth = referenceWidth;
}
public ScaledWidgetFactory(Class clazz) {
this.clazz = clazz;
}
public Image getSizedImageForWidget(String filename, Control control) {
if (filename == null)
return null;
InputStream stream = clazz.getResourceAsStream(filename);
if (stream == null)
throw new RuntimeException(filename + " not found");
Point size = control.getSize();
int width = size.x;
int height = size.y;
ImageData data = new ImageData(stream);
if (width != 0 && height != 0 && data.width != width || data.height != height) {
LogUtility.logDebug("ScaledWidgetFactory", "scaling image for " + filename);
data = data.scaledTo(width, height);
}
return new Image(Display.getCurrent(), data);
}
public Image getSizedImage(String filename, int width, int height) {
if (filename == null)
return null;
InputStream stream = clazz.getResourceAsStream(filename);
if (stream == null)
throw new RuntimeException(filename + " not found");
ImageData data = new ImageData(stream);
if (width != 0 && height != 0 && data.width != width || data.height != height) {
LogUtility.logDebug("ScaledWidgetFactory", "scaling image for " + filename);
data = data.scaledTo(width, height);
}
return new Image(Display.getCurrent(), data);
}
public ImageButton createImageButton(Composite parent, int flags, int x, int y, int width, int height) {
return createImageButton(parent, flags, x, y, width, height, null, null, null, false, null, null);
}
public ImageButton createImageButton(Composite parent, int flags, int x, int y, int width, int height, String imageUpFileName, String imageDownFileName, boolean setRegion, SelectionListener listener) {
return createImageButton(parent, flags, x, y, width, height, imageUpFileName, imageDownFileName, null, setRegion, listener, null);
}
public ImageButton createImageButton(Composite parent, int flags, int x, int y, int width, int height, String imageUpFileName, String imageDownFileName, boolean setRegion, SelectionListener listener, Font font) {
return createImageButton(parent, flags, x, y, width, height, imageUpFileName, imageDownFileName, null, setRegion, listener, font);
}
public ImageButton createImageButton(Composite parent, int flags, int x, int y, int width, int height, String imageUpFileName, String imageDownFileName, String extraImageFileName, boolean setRegion, SelectionListener listener) {
return createImageButton(parent, flags, x, y, width, height, imageUpFileName, imageDownFileName, extraImageFileName, setRegion, listener, null);
}
public ImageButton createImageButton(Composite parent, int flags, int x, int y, int width, int height, String imageUpFileName, String imageDownFileName, String extraImageFileName, boolean setRegion, SelectionListener listener, Font font) {
ImageButton imageButton = new ImageButton(parent, flags);
imageButton.setBounds(getScaledBounds(x, y, width, height));
imageButton.setImages(getSizedImageForWidget(imageUpFileName, imageButton), getSizedImageForWidget(imageDownFileName, imageButton), getSizedImageForWidget(extraImageFileName, imageButton));
if (setRegion)
imageButton.setRegionFromImage();
if (font != null)
imageButton.setFont(font);
if (listener != null)
imageButton.addSelectionListener(listener);
return imageButton;
}
public void disposeImageButtonImages(ImageButton imageButton) {
disposeRegion(imageButton);
Image[] images = imageButton.getImages();
imageButton.setImages(null, null, null);
for (int i = 0; i < images.length; i++) {
if (images[i] != null)
images[i].dispose();
}
}
public ImageProgressBar createImageProgressBar(Composite parent, int flags, int x, int y, int width, int height, String imageFileName) {
ImageProgressBar slider = new ImageProgressBar(parent, flags);
slider.setBounds(getScaledBounds(x, y, width, height));
slider.setImage(getSizedImageForWidget(imageFileName, slider));
return slider;
}
public void disposeImageProgressBarImage(ImageProgressBar imageProgressBar) {
disposeRegion(imageProgressBar);
Image image = imageProgressBar.getImage();
if (image != null) {
imageProgressBar.setImage(null);
image.dispose();
}
}
public Label createLabel(Composite parent, int flags, int x, int y, int width, int height, Font font) {
return createLabel(parent, flags, x, y, width, height, font, null);
}
public Label createLabel(Composite parent, int flags, int x, int y, int width, int height, Font font, String text) {
Label label = new Label(parent, flags);
if (font != null)
label.setFont(font);
if (text != null)
label.setText(text);
label.setBounds(getScaledBounds(x, y, width, height));
return label;
}
public void disposeLabelImage(Label label) {
disposeRegion(label);
Image image = label.getImage();
if (image != null) {
label.setImage(null);
image.dispose();
}
}
public Composite createComposite(Composite parent, int flags, int x, int y, int width, int height) {
return createComposite(parent, flags, x, y, width, height, null, null);
}
public Composite createComposite(Composite parent, int flags, int x, int y, int width, int height, String imagefileName, Layout layout) {
Composite composite = new Composite(parent, flags);
composite.setBounds(getScaledBounds(x, y, width, height));
if (imagefileName != null) {
composite.setBackgroundImage(getSizedImageForWidget(imagefileName, composite));
composite.setBackgroundMode(SWT.INHERIT_FORCE);
}
if (layout != null)
composite.setLayout(layout);
return composite;
}
public void disposeCompositeImage(Composite composite) {
disposeRegion(composite);
// background Images are special if there is no background on a given
// composite
// it appears that its parents background image will be given, that
// image CANNOT
// be disposed so we have to check for that case
Image image = composite.getBackgroundImage();
Image parentImage = composite.getParent().getBackgroundImage();
if (image != null && parentImage != image) {
composite.setBackgroundImage(null);
image.dispose();
}
}
public Button createButton(Composite parent, int flags, int x, int y, int width, int height, String imageFileName, SelectionListener listener, Font font, String text) {
Button button = new Button(parent, flags);
button.setBounds(getScaledBounds(x, y, width, height));
if (imageFileName != null) {
button.setImage(getSizedImageForWidget(imageFileName, button));
}
if (font != null)
button.setFont(font);
if (listener != null)
button.addSelectionListener(listener);
if (text != null)
button.setText(text);
return button;
}
public void disposeButtonImage(Button button) {
disposeRegion(button);
Image image = button.getImage();
if (image != null) {
button.setImage(null);
image.dispose();
}
}
public Region getRegion(Image image) {
Region region = new Region();
final ImageData imageData = image.getImageData();
if (imageData.alphaData != null) {
Rectangle pixel = new Rectangle(0, 0, 1, 1);
for (int y = 0; y < imageData.height; y++) {
for (int x = 0; x < imageData.width; x++) {
if (imageData.getAlpha(x, y) == 255) {
pixel.x = imageData.x + x;
pixel.y = imageData.y + y;
region.add(pixel);
}
}
}
} else {
ImageData mask = imageData.getTransparencyMask();
Rectangle pixel = new Rectangle(0, 0, 1, 1);
for (int y = 0; y < mask.height; y++) {
for (int x = 0; x < mask.width; x++) {
if (mask.getPixel(x, y) != 0) {
pixel.x = imageData.x + x;
pixel.y = imageData.y + y;
region.add(pixel);
}
}
}
}
return region;
}
public Rectangle getScaledBounds(int x, int y, int width, int height) {
if (referenceWidth == screenWidth && referenceHeight == screenHeight) {
return new Rectangle(x, y, width, height);
}
return new Rectangle(x(x), y(y), x(width), y(height));
}
private int x(int xToScale) {
return xToScale * screenWidth / referenceWidth;
}
private int y(int yToScale) {
return yToScale * screenHeight / referenceHeight;
}
private void disposeRegion(Control control) {
Region region = control.getRegion();
if (region != null) {
control.setRegion(null);
region.dispose();
}
}
}