/******************************************************************************* * Copyright (c) 2010 Oak Ridge National Laboratory. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html ******************************************************************************/ package org.csstudio.ui.util.widgets; import java.io.FileInputStream; import java.io.InputStream; import org.csstudio.ui.util.dialogs.ExceptionDetailsErrorDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Composite; /** Widget that displays an image. * * <p>Similar to a Label with image, but image is resized to fit the widget. * * <p>Image can be provided as {@link InputStream}. * * <p>As a shortcut, the widget can also read a file. * * <p>Setting the {@link Image} directly is not supported * to avoid issues with ownership and disposal of such an image. * * @author Kay Kasemir */ @SuppressWarnings("nls") public class ImagePreview extends Canvas implements DisposeListener, PaintListener { /** Image or <code>null</code> */ private Image image = null; /** Additional short message or <code>null</code> */ private String message = null; /** Initialize empty * @param parent Parent widget */ public ImagePreview(final Composite parent) { super(parent, 0); addDisposeListener(this); addPaintListener(this); } /** Set image to display * @param image_filename Full path to image file or <code>null</code> for no image */ public void setImage(final String image_filename) { if (image_filename == null) setImage((InputStream) null); else { try { setImage(new FileInputStream(image_filename)); } catch (Exception ex) { ExceptionDetailsErrorDialog.openError(getShell(), "Error", ex); } } } /** Set image to display * @param image_stream Image stream */ public void setImage(final InputStream image_stream) { // Remove previous image, if there was one if (image != null) { image.dispose(); image = null; setToolTipText(""); } if (image_stream == null) return; image = new Image(getDisplay(), image_stream); redraw(); } /** Set a message that is displayed on top of the image * @param message Message to display or <code>null</code> */ public void setMessage(final String message) { this.message = message; redraw(); } // Note that this is supported by Canvas // public void setToolTipText(final String tooltip); /** @see Control */ @Override public Point computeSize(final int wHint, final int hHint) { if (image == null) return new Point(1, 1); return new Point(200, 200); } /** @see PaintListener */ @Override public void paintControl(final PaintEvent e) { final Rectangle bounds = getBounds(); final GC gc = e.gc; if (image != null) { // Draw image to fit widget bounds, maintaining // aspect ratio final Rectangle img = image.getBounds(); // Start with original size int width = img.width; int height = img.height; int destX = 0; int destY = 0; if (width > bounds.width) { // Too wide? width = bounds.width; height = width * img.height / img.width; } if (height > bounds.height) { // Too high? height = bounds.height; width = height * img.width / img.height; } destX = (bounds.width - width) / 2; destY = (bounds.height - height) / 2; gc.drawImage(image, 0, 0, img.width, img.height, destX, destY, width, height); } if (message != null) { // Show message final Point extend = gc.textExtent(message, SWT.DRAW_DELIMITER); final int x = (bounds.width - extend.x) / 2; final int y = (bounds.height - extend.y) / 2; gc.drawText(message, x, y, SWT.DRAW_DELIMITER | SWT.DRAW_TRANSPARENT); return; } } /** @see DisposeListener */ @Override public void widgetDisposed(final DisposeEvent e) { if (image != null) image.dispose(); } }