blob: 0f3196c0cf5d75929c5f0738761dd31711c97b5e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2017 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.swt.custom;
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;
/**
* A control for showing progress feedback for a long running operation.
*
* @deprecated As of Eclipse 2.1, use ProgressBar with the style SWT.INDETERMINATE
*
* <dl>
* <dt><b>Styles:</b><dd>VERTICAL, HORIZONTAL, BORDER
* </dl>
*
* @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
*/
@Deprecated
public class AnimatedProgress extends Canvas {
static final int SLEEP = 70;
static final int DEFAULT_WIDTH = 160;
static final int DEFAULT_HEIGHT = 18;
boolean active = false;
boolean showStripes = false;
int value;
int orientation = SWT.HORIZONTAL;
boolean showBorder = false;
/**
* Constructs a new instance of this class given its parent
* and a style value describing its behavior and appearance.
* <p>
* The style value is either one of the style constants defined in
* class <code>SWT</code> which is applicable to instances of this
* class, or must be built by <em>bitwise OR</em>'ing together
* (that is, using the <code>int</code> "|" operator) two or more
* of those <code>SWT</code> style constants. The class description
* lists the style constants that are applicable to the class.
* Style bits are also inherited from superclasses.
* </p>
*
* @param parent a widget which will be the parent of the new instance (cannot be null)
* @param style the style of widget to construct
*
* @exception IllegalArgumentException <ul>
* <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
* </ul>
* @exception SWTException <ul>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
* </ul>
*
* @see SWT#VERTICAL
* @see SWT#HORIZONTAL
* @see SWT#BORDER
* @see #getStyle()
*/
public AnimatedProgress(Composite parent, int style) {
super(parent, checkStyle(style));
if ((style & SWT.VERTICAL) != 0) {
orientation = SWT.VERTICAL;
}
showBorder = (style & SWT.BORDER) != 0;
addControlListener(ControlListener.controlResizedAdapter(e -> redraw()));
addPaintListener(this::paint);
addDisposeListener(e -> stop());
}
private static int checkStyle (int style) {
int mask = SWT.NONE;
return style & mask;
}
/**
* Stop the animation if it is not already stopped and
* reset the presentation to a blank appearance.
*
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
* </ul>
*/
public synchronized void clear(){
checkWidget();
if (active) stop();
showStripes = false;
redraw();
}
@Override
public Point computeSize(int wHint, int hHint, boolean changed) {
checkWidget();
Point size = null;
if (orientation == SWT.HORIZONTAL) {
size = new Point(DEFAULT_WIDTH, DEFAULT_HEIGHT);
} else {
size = new Point(DEFAULT_HEIGHT, DEFAULT_WIDTH);
}
if (wHint != SWT.DEFAULT) size.x = wHint;
if (hHint != SWT.DEFAULT) size.y = hHint;
return size;
}
private void drawBevelRect(GC gc, int x, int y, int w, int h, Color topleft, Color bottomright) {
gc.setForeground(topleft);
gc.drawLine(x, y, x+w-1, y);
gc.drawLine(x, y, x, y+h-1);
gc.setForeground(bottomright);
gc.drawLine(x+w, y, x+w, y+h);
gc.drawLine(x, y+h, x+w, y+h);
}
void paint(PaintEvent event) {
GC gc = event.gc;
Display disp= getDisplay();
Rectangle rect= getClientArea();
gc.fillRectangle(rect);
if (showBorder) {
drawBevelRect(gc, rect.x, rect.y, rect.width-1, rect.height-1,
disp.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW),
disp.getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW));
}
paintStripes(gc);
}
void paintStripes(GC gc) {
if (!showStripes) return;
Rectangle rect= getClientArea();
// Subtracted border painted by paint.
rect = new Rectangle(rect.x+2, rect.y+2, rect.width-4, rect.height-4);
gc.setLineWidth(2);
gc.setClipping(rect);
Color color = getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION);
gc.setBackground(color);
gc.fillRectangle(rect);
gc.setForeground(this.getBackground());
int step = 12;
int foregroundValue = value == 0 ? step - 2 : value - 2;
if (orientation == SWT.HORIZONTAL) {
int y = rect.y - 1;
int w = rect.width;
int h = rect.height + 2;
for (int i= 0; i < w; i+= step) {
int x = i + foregroundValue;
gc.drawLine(x, y, x, h);
}
} else {
int x = rect.x - 1;
int w = rect.width + 2;
int h = rect.height;
for (int i= 0; i < h; i+= step) {
int y = i + foregroundValue;
gc.drawLine(x, y, w, y);
}
}
if (active) {
value = (value + 2) % step;
}
}
/**
* Start the animation.
*
* @exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
* </ul>
*/
public synchronized void start() {
checkWidget();
if (active) return;
active = true;
showStripes = true;
final Display display = getDisplay();
final Runnable [] timer = new Runnable [1];
timer [0] = () -> {
if (!active) return;
GC gc = new GC(AnimatedProgress.this);
paintStripes(gc);
gc.dispose();
display.timerExec (SLEEP, timer [0]);
};
display.timerExec (SLEEP, timer [0]);
}
/**
* Stop the animation. Freeze the presentation at its current appearance.
*/
public synchronized void stop() {
//checkWidget();
active = false;
}
}