/******************************************************************************* * Copyright (c) 2006, 2009 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 * Stefan Mucke - fix for Bug 156456 *******************************************************************************/ package org.eclipse.ui.internal.forms.widgets; //import java.io.IOException; import java.net.URL; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.resource.ImageDescriptor; 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.Label; import org.eclipse.swt.widgets.Composite; //import org.eclipse.swt.widgets.Display; import org.osgi.framework.Bundle; // RAP [rh] Changed class hierarchy: now extends Label instead of Canvas // public final class BusyIndicator extends Canvas { public final class BusyIndicator extends Label { private static final int MARGIN = 0; // RAP [rh] instead of manually animating 8 png images, RAP uses one animated gif // private static final int IMAGE_COUNT = 8; private static final int IMAGE_COUNT = 1; // private static final int MILLISECONDS_OF_DELAY = 180; private Image[] imageCache; private Image image; // private Display dpy; // private Runnable timer; private boolean busy; // private int imageIndex; /** * BusyWidget constructor comment. * * @param parent * org.eclipse.swt.widgets.Composite * @param style * int */ public BusyIndicator(Composite parent, int style) { super(parent, style | SWT.DOUBLE_BUFFERED); // dpy = getDisplay(); // timer = new Runnable() { // public void run () { // if (isDisposed()) return; // redraw(); // if (!BusyIndicator.this.busy) return; // update(); // if (isDisposed()) return; // imageIndex = (imageIndex + 1) % IMAGE_COUNT; // dpy.timerExec(MILLISECONDS_OF_DELAY, this); // } // }; // addPaintListener(new PaintListener() { // public void paintControl(PaintEvent event) { // onPaint(event); // } // }); addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { clearImages(); } }); } public Point computeSize(int wHint, int hHint, boolean changed) { // checkWidget(); Point size = new Point(0, 0); if (image != null) { Rectangle ibounds = image.getBounds(); size.x = ibounds.width; size.y = ibounds.height; } if (isBusy()) { Rectangle bounds = getImage(0).getBounds(); size.x = Math.max(size.x, bounds.width); size.y = Math.max(size.y, bounds.height); } size.x += MARGIN + MARGIN; size.y += MARGIN + MARGIN; return size; } /* (non-Javadoc) * @see org.eclipse.swt.widgets.Control#forceFocus() */ public boolean forceFocus() { return false; } /** * Return the image or <code>null</code>. */ public Image getImage() { // RAP [rh] // return image; return isBusy() ? getImage( 0 ) : image; } /** * Returns true if it is currently busy. * * @return boolean */ public boolean isBusy() { return busy; } // /* // * Process the paint event // */ // protected void onPaint(PaintEvent event) { // if (animationImage != null && animationImage.isDisposed()) { // animationImage = null; // } // Rectangle rect = getClientArea(); // if (rect.width == 0 || rect.height == 0) // return; // // GC gc = event.gc; // Image activeImage = animationImage != null ? animationImage : image; // if (activeImage != null) { // Rectangle ibounds = activeImage.getBounds(); // gc.drawImage(activeImage, rect.width / 2 - ibounds.width / 2, // rect.height / 2 - ibounds.height / 2); // } // } /** * Sets the indicators busy count up (true) or down (false) one. * * @param busy * boolean */ public synchronized void setBusy(boolean busy) { if (this.busy == busy) return; this.busy = busy; // imageIndex = 0; // dpy.asyncExec(timer); } /** * Set the image. The value <code>null</code> clears it. */ public void setImage(Image image) { if (image != this.image && !isDisposed()) { this.image = image; redraw(); } } private ImageDescriptor createImageDescriptor(String relativePath) { // RAP [rh] changes: bundle name; don't pass file URL to URLImageDescriptor // Bundle bundle = Platform.getBundle("org.eclipse.ui.forms"); //$NON-NLS-1$ // URL url = FileLocator.find(bundle, new Path(relativePath),null); // if (url == null) return null; // try { // url = FileLocator.resolve(url); // return ImageDescriptor.createFromURL(url); // } catch (IOException e) { // return null; // } Bundle bundle = Platform.getBundle("org.eclipse.rap.ui.forms"); //$NON-NLS-1$ URL url = FileLocator.find(bundle, new Path(relativePath),null); if (url == null) return null; return ImageDescriptor.createFromURL(url); } private Image getImage(int index) { if (imageCache == null) { imageCache = new Image[IMAGE_COUNT]; } if (imageCache[index] == null){ // RAP [rh] always return the same animated gif // ImageDescriptor descriptor = createImageDescriptor("$nl$/icons/progress/ani/" + (index + 1) + ".png"); //$NON-NLS-1$ //$NON-NLS-2$ ImageDescriptor descriptor = createImageDescriptor("$nl$/icons/progress/ani/progress.gif" ); //$NON-NLS-1$ imageCache[index] = descriptor.createImage(); } return imageCache[index]; } private void clearImages() { if (imageCache != null) { for (int index = 0; index < IMAGE_COUNT; index++) { if (imageCache[index] != null /* && !imageCache[index].isDisposed()*/) { // imageCache[index].dispose(); imageCache[index] = null; } } } } }