/******************************************************************************* * Copyright (c) 2006 IBM Corporation and others. * 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 * * Contributors: * IBM Corporation - initial API and implementation ******************************************************************************/ package org.eclipse.ui.internal; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.jface.util.Geometry; import org.eclipse.swt.SWT; 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.Rectangle; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; /** * @since 3.3 * */ public class ImageAnimationFeedback extends DefaultAnimationFeedback { private class ImageCanvas extends Canvas { private Image image; /** * @param parent * @param style */ public ImageCanvas(Composite parent, int style, Image image) { super(parent, style); this.image = image; addPaintListener(new PaintListener() { public void paintControl(PaintEvent e) { paintImage(e.gc); } }); } /** * @param gc */ protected void paintImage(GC gc) { gc.drawImage(image, 0, 0, image.getBounds().width, image.getBounds().height, 0, 0, getBounds().width, getBounds().height); } /* (non-Javadoc) * @see org.eclipse.swt.widgets.Widget#dispose() */ public void dispose() { super.dispose(); image.dispose(); } } private Display display; private Shell theShell; private List startRects = new ArrayList(); private List endRects = new ArrayList(); private List controls = new ArrayList(); private Image backingStore; /** * Creates an animation effect where the interpolated rectangles are displayed using Canvas * controls that show an image of the bits that were originally occupied by the various * 'start' rectangles. */ public ImageAnimationFeedback() {} /** * @param parentShell */ public void initialize(Shell parentShell, Rectangle startRect, Rectangle endRect) { display = parentShell.getDisplay(); Rectangle psRect = parentShell.getBounds(); theShell = new Shell(parentShell, SWT.NO_TRIM | SWT.ON_TOP); theShell.setBounds(parentShell.getBounds()); addStartRect(startRect); addEndRect(endRect); // Capture the background image backingStore = new Image(theShell.getDisplay(), psRect); GC gc = new GC(display); gc.copyArea(backingStore, psRect.x, psRect.y); gc.dispose(); theShell.setBackgroundImage(backingStore); theShell.setVisible(true); display.update(); } public void addStartRect(Rectangle rect) { if (rect != null) { Rectangle start = Geometry.toControl(theShell, rect); startRects.add(start); Image image = new Image(display, rect.width, rect.height); GC gc = new GC(display); gc.copyArea(image, rect.x, rect.y); gc.dispose(); ImageCanvas canvas = new ImageCanvas(theShell, SWT.BORDER | SWT.NO_BACKGROUND, image); controls.add(canvas); } } public void addEndRect(Rectangle rect) { if (rect != null) { Rectangle end = Geometry.toControl(theShell, rect); endRects.add(end); } } public void renderStep(double amount) { // Move the controls to the new interpolation position Iterator startIter = startRects.iterator(); Iterator endIter = endRects.iterator(); Iterator ctrlIter = controls.iterator(); while (startIter.hasNext()) { Rectangle start = (Rectangle) startIter.next(); Rectangle end = (Rectangle) endIter.next(); ImageCanvas canvas = (ImageCanvas) ctrlIter.next(); // Get the bounds of the interpolated rect Rectangle curRect = RectangleAnimation.interpolate(start, end, amount); canvas.setBounds(curRect); } display.update(); } public void jobInit() { } /** * */ public void dispose() { backingStore.dispose(); for (Iterator ctrlIter = controls.iterator(); ctrlIter.hasNext();) { ImageCanvas canvas = (ImageCanvas) ctrlIter.next(); canvas.dispose(); } theShell.setVisible(false); theShell.dispose(); } }