diff options
| author | Lars Vogel | 2020-06-09 05:41:10 +0000 |
|---|---|---|
| committer | Lars Vogel | 2020-06-09 05:42:07 +0000 |
| commit | 26b77c47da73b873a9534701b909cbeef238c599 (patch) | |
| tree | 5c3fe57565442e1546f1a12823bea9ebc0e6119e | |
| parent | 16afd68da1dd91b2210acd585e03cf132bfd9ed9 (diff) | |
| download | eclipse.platform.ui-26b77c47da73b873a9534701b909cbeef238c599.tar.gz eclipse.platform.ui-26b77c47da73b873a9534701b909cbeef238c599.tar.xz eclipse.platform.ui-26b77c47da73b873a9534701b909cbeef238c599.zip | |
Revert "Bug 563471 - Removes animations from UI"
This reverts commit 30fd26980c09d07eba5ed4cd251361cf73382ce5.
Reason for revert: <INSERT REASONING HERE>
Change-Id: I3c73f5b289a253c621c953d91b4f5d4498d4ad81
22 files changed, 1352 insertions, 3 deletions
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IWorkbenchPreferenceConstants.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IWorkbenchPreferenceConstants.java index 8cf10ae22ae..702d43193f0 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IWorkbenchPreferenceConstants.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IWorkbenchPreferenceConstants.java @@ -372,10 +372,7 @@ public interface IWorkbenchPreferenceConstants { * </p> * * @since 3.1 - * - * @deprecated not supported by the platform anymore */ - @Deprecated String ENABLE_ANIMATIONS = "ENABLE_ANIMATIONS"; //$NON-NLS-1$ /** diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/AnimatedTabFeedback.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/AnimatedTabFeedback.java new file mode 100644 index 00000000000..045a73826d7 --- /dev/null +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/AnimatedTabFeedback.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2007, 2015 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.ui.internal; + +import org.eclipse.swt.custom.CTabItem; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Shell; + +public class AnimatedTabFeedback extends ImageCycleFeedbackBase { + + private CTabItem tabItem; + + public AnimatedTabFeedback(Shell parentShell) { + super(parentShell); + } + + public AnimatedTabFeedback(Shell parentShell, CTabItem item, Image[] images) { + super(parentShell, images); + tabItem = item; + } + + @Override + public void initialize(AnimationEngine engine) { + background = tabItem.getParent().getBackground(); + display = tabItem.getParent().getDisplay(); + } + + @Override + public void saveStoppedImage() { + stoppedImage = tabItem.getImage(); + } + + @Override + public void setStoppedImage(Image image) { + tabItem.setImage(image); + } + + @Override + public void showImage(Image image) { + if (tabItem.isDisposed()) { + return; + } + tabItem.setImage(image); + } + +} diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/AnimationEngine.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/AnimationEngine.java new file mode 100644 index 00000000000..aefc6b269a3 --- /dev/null +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/AnimationEngine.java @@ -0,0 +1,219 @@ +/******************************************************************************* + * Copyright (c) 2007, 2015 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.ui.internal; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchPreferenceConstants; +import org.eclipse.ui.internal.tweaklets.Animations; +import org.eclipse.ui.internal.tweaklets.Tweaklets; +import org.eclipse.ui.internal.util.PrefUtil; + +/** + * This job creates an Animation Engine that uses an Animation Feedback to + * render the animation. To begin the animation, instantiate this object then + * call schedule(). + * + * @since 3.3 + * + */ +public class AnimationEngine extends Job { + public static final int TICK_TIMER = 1; + public static final int FRAME_COUNT = 2; + public static final int unlimitedDuration = -1; + + private boolean enableAnimations; + private long startTime; + private long curTime; + private long prevTime; + private int timingStyle = TICK_TIMER; + private long frameCount; + private boolean animationCanceled = false; + private long sleepAmount; + + private Display display; + private AnimationFeedbackBase feedbackRenderer; + private int duration; + + public AnimationEngine(AnimationFeedbackBase animationFeedback, int durationIn) { + this(animationFeedback, durationIn, 0); + } + + /** + * Creates an Animation that will run for the given number of milliseconds. + * + * @param animationFeedback provides renderStep(), initialize() and jobInit() + * methods + * @param durationIn number of milliseconds over which the animation will + * run + * @param sleepAmountIn number of milliseconds to slow/delay the animation + */ + public AnimationEngine(AnimationFeedbackBase animationFeedback, int durationIn, long sleepAmountIn) { + super(WorkbenchMessages.RectangleAnimation_Animating_Rectangle); + sleepAmount = sleepAmountIn; + feedbackRenderer = animationFeedback; + duration = durationIn; + + // if animations aren't on this is a NO-OP + IPreferenceStore preferenceStore = PrefUtil.getAPIPreferenceStore(); + enableAnimations = preferenceStore.getBoolean(IWorkbenchPreferenceConstants.ENABLE_ANIMATIONS); + if (!enableAnimations) { + return; + } + + animationCanceled = false; + + // Capture parameters + display = feedbackRenderer.getAnimationShell().getDisplay(); + + animationFeedback.getAnimationShell().addDisposeListener(e -> cancelAnimation()); + + // Don't show the job in monitors + setSystem(true); + + // Set it up + feedbackRenderer.initialize(this); + + // Set the animation's initial state + curTime = startTime = System.currentTimeMillis(); + + } + + /** + * @return The current renderer + */ + public AnimationFeedbackBase getFeedback() { + return feedbackRenderer; + } + + private Runnable animationStep = () -> { + if (animationCanceled) + return; + + // Capture time + prevTime = curTime; + curTime = System.currentTimeMillis(); + + if (isUpdateStep()) { + updateDisplay(); + frameCount++; + } + }; + + protected void updateDisplay() { + if (animationCanceled) + return; + + feedbackRenderer.renderStep(this); + } + + protected boolean isUpdateStep() { + if (duration == unlimitedDuration || timingStyle == FRAME_COUNT) { + return true; + } + + // Default to 'TICK_TIMER', update when the system timer changes + return prevTime != curTime; + } + + private boolean done() { + return animationCanceled || amount() >= 1.0; + } + + public double amount() { + if (duration == unlimitedDuration) { + return 0; + } + double amount = 0.0; + switch (timingStyle) { + case TICK_TIMER: + amount = (double) (curTime - startTime) / (double) duration; + break; + + // For testing purposes + case FRAME_COUNT: + amount = (double) frameCount / (double) duration; + } + + if (amount > 1.0) + amount = 1.0; + + return amount; + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + // We use preference value to indicate that the animation should be skipped on + // this platform. + if (!enableAnimations) { + return Status.OK_STATUS; + } + + // We're starting, initialize + display.syncExec(() -> { + // 'jobInit' returns 'false' if it doesn't want to run... + if (!animationCanceled) + animationCanceled = !feedbackRenderer.jobInit(AnimationEngine.this); + }); + + if (animationCanceled) + return Status.CANCEL_STATUS; + + // Only start the animation timer -after- we've initialized + curTime = startTime = System.currentTimeMillis(); + + while (!done() && !animationCanceled) { + display.syncExec(animationStep); + + // Don't pin the CPU + try { + Thread.sleep(sleepAmount); + } catch (InterruptedException e) { + } + } + + if (animationCanceled) + return Status.CANCEL_STATUS; + + // We're done, clean up + display.syncExec(() -> feedbackRenderer.dispose()); + + return Status.OK_STATUS; + } + + public void cancelAnimation() { + animationCanceled = true; + feedbackRenderer.dispose(); + cancel(); + } + + public long getFrameCount() { + return frameCount; + } + + public static void createTweakedAnimation(Shell shell, int duration, Rectangle start, Rectangle end) { + RectangleAnimationFeedbackBase feedback = ((Animations) Tweaklets.get(Animations.KEY)).createFeedback(shell); + feedback.addStartRect(start); + feedback.addEndRect(end); + + AnimationEngine animation = new AnimationEngine(feedback, 400); + animation.schedule(); + } +} diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/AnimationFeedbackBase.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/AnimationFeedbackBase.java new file mode 100644 index 00000000000..22ac646cdc5 --- /dev/null +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/AnimationFeedbackBase.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2007, 2015 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.ui.internal; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Shell; + +/** + * AnimationFeedBackBase is an abstract class which provides renderStep(), + * jobInit() and initialize() methods for AnimationEngine. Its the base class + * for all the animationFeedbacks + * + * @since 3.3 + * + */ +public abstract class AnimationFeedbackBase { + private AnimationEngine engine; + private Shell baseShell; + private Shell animationShell = null; + + /** + * Creates an AnimationFeedback + * + * @param parentShell specifies the composite where the animation will be drawn + */ + public AnimationFeedbackBase(Shell parentShell) { + baseShell = parentShell; + + baseShell.addDisposeListener(e -> { + if (engine != null) + engine.cancelAnimation(); + }); + } + + /** + * Perform any initialization you want to do -prior- to the Job actually gets + * scheduled. + * + * @param animationEngine The engine we're hosted in. + */ + public abstract void initialize(AnimationEngine animationEngine); + + /** + * Its a draw method. All the code to render an animation goes in this method. + * + * @param engine + */ + public abstract void renderStep(AnimationEngine engine); + + /** + * Perform any initialization you want to have happen -before- the animation + * starts. Subclasses may subclass but not override (i.e. you have to call + * super). + * + * @param engine The AnimationEngine hosting the feedback + * @return 'true' iff the animation is capable of running + */ + public boolean jobInit(AnimationEngine engine) { + this.engine = engine; + return engine != null; + } + + /** + * Dispose any locally created resources + */ + public void dispose() { + if (animationShell != null && !animationShell.isDisposed()) + animationShell.dispose(); + } + + /** + * @return The shell this animation is being rendered 'on' + */ + public Shell getBaseShell() { + return baseShell; + } + + /** + * @return A shell that can be used to render the animation on + */ + public Shell getAnimationShell() { + if (animationShell == null) { + animationShell = new Shell(getBaseShell(), SWT.NO_TRIM | SWT.ON_TOP); + + animationShell.addDisposeListener(e -> { + if (engine != null) + engine.cancelAnimation(); + }); + } + + return animationShell; + } + +} diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/FaderAnimationFeedback.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/FaderAnimationFeedback.java new file mode 100644 index 00000000000..07130fd9780 --- /dev/null +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/FaderAnimationFeedback.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2007, 2015 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.ui.internal; + +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * Creates an animation effect where the Shell's image is captured and over-lain + * (in its own shell) on top of the real one. This image masks the changes to + * the 'real' shell and then the covering image fades to transparent, revealing + * the new state. + * + * This provides a nice cross-fade effect for operations like a perspective + * change (where the overall effect on the shell is large. + * + * @since 3.3 + * + */ +public class FaderAnimationFeedback extends AnimationFeedbackBase { + private Image backingStore; + + public FaderAnimationFeedback(Shell parentShell) { + super(parentShell); + } + + @Override + public void dispose() { + super.dispose(); + + if (!backingStore.isDisposed()) + backingStore.dispose(); + } + + @Override + public void initialize(AnimationEngine engine) { + Rectangle psRect = getBaseShell().getBounds(); + getAnimationShell().setBounds(psRect); + + // Capture the background image + Display display = getBaseShell().getDisplay(); + backingStore = new Image(display, psRect); + GC gc = new GC(display); + // gc.copyArea(backingStore, psRect.x, psRect.y); + gc.copyArea(backingStore, psRect.x, psRect.y); + gc.dispose(); + + getAnimationShell().setAlpha(254); + getAnimationShell().setBackgroundImage(backingStore); + getAnimationShell().setVisible(true); + } + + @Override + public void renderStep(AnimationEngine engine) { + getAnimationShell().setAlpha((int) (255 - (engine.amount() * 255))); + } + +} diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ImageCycleFeedbackBase.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ImageCycleFeedbackBase.java new file mode 100644 index 00000000000..76e8eaeddbf --- /dev/null +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ImageCycleFeedbackBase.java @@ -0,0 +1,160 @@ +/******************************************************************************* + * Copyright (c) 2007, 2016 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 + * Friederike Schertel <friederike@schertel.org> - Bug 478336 + ******************************************************************************/ + +package org.eclipse.ui.internal; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.internal.misc.StatusUtil; +import org.eclipse.ui.statushandlers.StatusManager; + +/** + * Base class for Cyclic animations. + * + * @since 3.3 + * + */ +public abstract class ImageCycleFeedbackBase extends AnimationFeedbackBase { + protected Image[] images; + protected Image stoppedImage; + private Image offScreenImage; + private GC offScreenImageGC; + private int imageDataIndex; + private Image image; + private ImageData imageData; + protected Display display; + protected Color background; + + /** + * @param parentShell + */ + public ImageCycleFeedbackBase(Shell parentShell) { + super(parentShell); + // TODO Auto-generated constructor stub + } + + /** + * + * @param parentShell + * @param images : an array of images + */ + public ImageCycleFeedbackBase(Shell parentShell, Image[] images) { + super(parentShell); + this.images = images; + } + + /** + * Set the image during progress without caching. + * + * @param image + */ + public abstract void showImage(Image image); + + /** + * Save initial Image which would be stoppedImage + * + */ + public abstract void saveStoppedImage(); + + /** + * Set the stopped Image upon animation completion + * + * @param image + */ + public abstract void setStoppedImage(Image image); + + @Override + public void dispose() { + if (stoppedImage == null || stoppedImage.isDisposed()) + return; + setStoppedImage(stoppedImage); + + if (offScreenImageGC != null && !offScreenImageGC.isDisposed()) + offScreenImageGC.dispose(); + + if (offScreenImage != null && !offScreenImage.isDisposed()) + offScreenImage.dispose(); + } + + @Override + public boolean jobInit(AnimationEngine engine) { + return super.jobInit(engine); + } + + @Override + public void renderStep(AnimationEngine engine) { + if (offScreenImage == null) { + offScreenImage = getOffscreenImage(); + } + + try { + imageDataIndex = (imageDataIndex + 1) % images.length; + image = images[imageDataIndex]; + imageData = image.getImageData(); + + offScreenImageGC.drawImage(image, 0, 0, imageData.width, imageData.height, imageData.x, imageData.y, + imageData.width, imageData.height); + + final Image finalImage = image; + + display.syncExec(() -> showImage(finalImage)); + + /* + * Sleep for the specified delay time (adding commonly-used slow-down fudge + * factors). + */ + // try { + // Thread.sleep(30); + // } catch (InterruptedException e) { + // } + if (images == null) + return; + } catch (SWTException ex) { + IStatus status = StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH, ex); + StatusManager.getManager().handle(status); + } + } + + private Image getOffscreenImage() { + saveStoppedImage(); + imageDataIndex = 0; + image = images[imageDataIndex]; + imageData = image.getImageData(); + /* + * Create an off-screen image to draw on, and fill it with the shell background. + */ + offScreenImage = new Image(display, imageData.width, imageData.height); + + offScreenImageGC = new GC(offScreenImage); + offScreenImageGC.setBackground(background); + offScreenImageGC.fillRectangle(0, 0, imageData.width, imageData.height); + + /* + * Create the first image and draw it on the off-screen image. + */ + + offScreenImageGC.drawImage(image, 0, 0, imageData.width, imageData.height, imageData.x, imageData.y, + imageData.width, imageData.height); + + return offScreenImage; + } + +} diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/LegacyAnimationFeedback.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/LegacyAnimationFeedback.java new file mode 100644 index 00000000000..d75d6d2e3a5 --- /dev/null +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/LegacyAnimationFeedback.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright (c) 2007, 2015 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.ui.internal; + +import java.util.Iterator; + +import org.eclipse.jface.util.Geometry; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.graphics.Region; +import org.eclipse.swt.widgets.Shell; + +/** + * Creates an animation feedback that will morph the start rectangle to the end + * rectangle for AnimationEngine. + * + * @since 3.3 + * + */ +public class LegacyAnimationFeedback extends RectangleAnimationFeedbackBase { + private static final int LINE_WIDTH = 1; + + private Region shellRegion; + + public LegacyAnimationFeedback(Shell parentShell, Rectangle start, Rectangle end) { + super(parentShell, start, end); + } + + @Override + public void renderStep(AnimationEngine engine) { + if (shellRegion != null) { + shellRegion.dispose(); + shellRegion = new Region(getAnimationShell().getDisplay()); + } + + // Iterate across the set of start/end rects + Iterator currentRects = getCurrentRects(engine.amount()).iterator(); + while (currentRects.hasNext()) { + Rectangle curRect = (Rectangle) currentRects.next(); + Rectangle rect = Geometry.toControl(getAnimationShell(), curRect); + shellRegion.add(rect); + rect.x += LINE_WIDTH; + rect.y += LINE_WIDTH; + rect.width = Math.max(0, rect.width - 2 * LINE_WIDTH); + rect.height = Math.max(0, rect.height - 2 * LINE_WIDTH); + + shellRegion.subtract(rect); + } + + getAnimationShell().setRegion(shellRegion); + getAnimationShell().getDisplay().update(); + } + + @Override + public void initialize(AnimationEngine engine) { + Color color = getAnimationShell().getDisplay().getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW); + getAnimationShell().setBackground(color); + + // Ensure that the background won't show on the initial display + shellRegion = new Region(getAnimationShell().getDisplay()); + getAnimationShell().setRegion(shellRegion); + } + + @Override + public void dispose() { + super.dispose(); + + if (!shellRegion.isDisposed()) + shellRegion.dispose(); + } + + /** + * Perform any initialization you want to have happen -before- the amination + * starts + */ + @Override + public boolean jobInit(AnimationEngine engine) { + if (!super.jobInit(engine)) + return false; + + // Compute the shell's bounds + Rectangle shellBounds = Geometry.copy((Rectangle) getStartRects().get(0)); + Iterator startIter = getStartRects().iterator(); + Iterator endIter = getEndRects().iterator(); + while (startIter.hasNext()) { + shellBounds.add((Rectangle) startIter.next()); + shellBounds.add((Rectangle) endIter.next()); + } + getAnimationShell().setBounds(shellBounds); + // Making the shell visible will be slow on old video cards, so only start + // the timer once it is visible. + getAnimationShell().setVisible(true); + + return true; // OK to go... + } + +} diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/RectangleAnimationFeedbackBase.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/RectangleAnimationFeedbackBase.java new file mode 100644 index 00000000000..9b7af6a9cf9 --- /dev/null +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/RectangleAnimationFeedbackBase.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright (c) 2007, 2015 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.ui.internal; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import org.eclipse.jface.util.Geometry; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; + +/** + * RectangleAnimationFeedbackBase is an abstract base class for all the + * rectangle animations. + * + * @since 3.3 + * + */ +public abstract class RectangleAnimationFeedbackBase extends AnimationFeedbackBase { + + private List startRects = new ArrayList(); + private List endRects = new ArrayList(); + + /** + * Creates a Rectangle Animation Feedback + * + * @param parentShell specifies the composite where the animation will be drawn + * @param start initial rectangle (display coordinates) + * @param end final rectangle (display coordinates) + */ + public RectangleAnimationFeedbackBase(Shell parentShell, Rectangle start, Rectangle end) { + super(parentShell); + addStartRect(start); + addEndRect(end); + } + + @Override + public boolean jobInit(AnimationEngine engine) { + if (!super.jobInit(engine)) + return false; + + return startRects.size() > 0 && startRects.size() == endRects.size(); + } + + public void addStartRect(Rectangle rect) { + if (rect != null) { + startRects.add(rect); + } + } + + public void addEndRect(Rectangle rect) { + if (rect != null) { + endRects.add(rect); + } + } + + public void addStartRect(Control ctrl) { + Rectangle ctrlBounds = ctrl.getBounds(); + Rectangle startRect = Geometry.toDisplay(ctrl.getParent(), ctrlBounds); + addStartRect(startRect); + } + + public void addEndRect(Control ctrl) { + Rectangle ctrlBounds = ctrl.getBounds(); + Rectangle endRect = Geometry.toDisplay(ctrl.getParent(), ctrlBounds); + addEndRect(endRect); + } + + public static Rectangle interpolate(Rectangle start, Rectangle end, double amount) { + double initialWeight = 1.0 - amount; + + return new Rectangle((int) (start.x * initialWeight + end.x * amount), + (int) (start.y * initialWeight + end.y * amount), + (int) (start.width * initialWeight + end.width * amount), + (int) (start.height * initialWeight + end.height * amount)); + } + + public List getStartRects() { + return startRects; + } + + public List getEndRects() { + return endRects; + } + + public List getCurrentRects(double amount) { + List currentRects = new ArrayList(); + Iterator startIter = getStartRects().iterator(); + Iterator endIter = getEndRects().iterator(); + while (startIter.hasNext()) { + Rectangle start = (Rectangle) startIter.next(); + Rectangle end = (Rectangle) endIter.next(); + + // Get the bounds of the interpolated rect + Rectangle curRect = interpolate(start, end, amount); + currentRects.add(curRect); + } + return currentRects; + } + +} diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/RectangleAnimationImageFeedback.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/RectangleAnimationImageFeedback.java new file mode 100644 index 00000000000..84062e93a72 --- /dev/null +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/RectangleAnimationImageFeedback.java @@ -0,0 +1,175 @@ +/******************************************************************************* + * Copyright (c) 2007, 2015 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.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.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; + +/** + * 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. + * + * @since 3.3 + * + */ +public class RectangleAnimationImageFeedback extends RectangleAnimationFeedbackBase { + private static 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(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); + } + + @Override + public void dispose() { + super.dispose(); + image.dispose(); + } + } + + private Image backingStore; + private Shell theShell; + private Display display; + private List controls = new ArrayList(); + + public RectangleAnimationImageFeedback(Shell parentShell, Rectangle start, Rectangle end) { + super(parentShell, start, end); + } + + @Override + public void dispose() { + backingStore.dispose(); + for (Iterator ctrlIter = controls.iterator(); ctrlIter.hasNext();) { + ImageCanvas canvas = (ImageCanvas) ctrlIter.next(); + canvas.dispose(); + } + + theShell.setVisible(false); + theShell.dispose(); + } + + @Override + public void initialize(AnimationEngine engine) { + display = getAnimationShell().getDisplay(); + + Rectangle psRect = getAnimationShell().getBounds(); + theShell = new Shell(getAnimationShell(), SWT.NO_TRIM | SWT.ON_TOP); + theShell.setBounds(getAnimationShell().getBounds()); + + // Capture the background image + backingStore = new Image(theShell.getDisplay(), psRect); + GC gc = new GC(display); + gc.copyArea(backingStore, psRect.x, psRect.y); + gc.dispose(); +// changeCoordinates(); +// captureImages(); + theShell.setBackgroundImage(backingStore); + theShell.setVisible(true); + display.update(); + + } + + @Override + public boolean jobInit(AnimationEngine engine) { + changeCoordinates(); + captureImages(); + return super.jobInit(engine); + } + + @Override + public void addStartRect(Rectangle rect) { + if (rect == null) + return; + + // Rectangle start = Geometry.toControl(getAnimationShell(), rect); + super.addStartRect(rect); + + } + + @Override + public void addEndRect(Rectangle rect) { + if (rect != null) { + // Rectangle end = Geometry.toControl(getAnimationShell(), rect); + super.addEndRect(rect); + } + } + + @Override + public void renderStep(AnimationEngine engine) { + Iterator ctrlIter = controls.iterator(); + Iterator currentRects = getCurrentRects(engine.amount()).iterator(); + while (currentRects.hasNext()) { + ImageCanvas canvas = (ImageCanvas) ctrlIter.next(); + canvas.setBounds((Rectangle) currentRects.next()); + } + display.update(); + + } + + public void changeCoordinates() { + Iterator startRectIter = getStartRects().iterator(); + Iterator endRectIter = getEndRects().iterator(); + while (startRectIter.hasNext()) { + Rectangle startRect = (Rectangle) startRectIter.next(); + Rectangle mapStartRect = Geometry.toControl(theShell, startRect); + startRect.x = mapStartRect.x; + startRect.y = mapStartRect.y; + Rectangle endRect = (Rectangle) endRectIter.next(); + Rectangle mapEndRect = Geometry.toControl(theShell, endRect); + endRect.x = mapEndRect.x; + endRect.y = mapEndRect.y; + } + } + + private void captureImages() { + + for (Iterator iterator = getStartRects().iterator(); iterator.hasNext();) { + Rectangle rect = (Rectangle) iterator.next(); + Image image = new Image(display, rect.width, rect.height); + GC gc = new GC(backingStore); + gc.copyArea(image, rect.x, rect.y); + gc.dispose(); + ImageCanvas canvas = new ImageCanvas(theShell, SWT.BORDER | SWT.NO_BACKGROUND, image); + controls.add(canvas); + + } + } + +} diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/ProgressManagerUtil.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/ProgressManagerUtil.java index 66ff73596d1..1bb73bbb9ee 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/ProgressManagerUtil.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/ProgressManagerUtil.java @@ -28,13 +28,17 @@ import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.jface.window.IShellProvider; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.internal.AnimationEngine; import org.eclipse.ui.internal.WorkbenchPlugin; +import org.eclipse.ui.internal.WorkbenchWindow; import org.eclipse.ui.internal.misc.StatusUtil; import org.eclipse.ui.internal.util.BundleUtility; import org.eclipse.ui.progress.IProgressConstants; @@ -519,6 +523,58 @@ public class ProgressManagerUtil { return null; } + /** + * Animate the closing of a window given the start position down to the progress + * region. + * + * @param startPosition Rectangle. The position to start drawing from. + */ + public static void animateDown(Rectangle startPosition) { + IWorkbenchWindow currentWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (currentWindow == null) { + return; + } + WorkbenchWindow internalWindow = (WorkbenchWindow) currentWindow; + + ProgressRegion progressRegion = internalWindow.getProgressRegion(); + if (progressRegion == null) { + return; + } + Rectangle endPosition = progressRegion.getControl().getBounds(); + + Point windowLocation = internalWindow.getShell().getLocation(); + endPosition.x += windowLocation.x; + endPosition.y += windowLocation.y; + + // animate the progress dialog's removal + AnimationEngine.createTweakedAnimation(internalWindow.getShell(), 400, startPosition, endPosition); + } + + /** + * Animate the opening of a window given the start position down to the progress + * region. + * + * @param endPosition Rectangle. The position to end drawing at. + */ + public static void animateUp(Rectangle endPosition) { + IWorkbenchWindow currentWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (currentWindow == null) { + return; + } + WorkbenchWindow internalWindow = (WorkbenchWindow) currentWindow; + Point windowLocation = internalWindow.getShell().getLocation(); + + ProgressRegion progressRegion = internalWindow.getProgressRegion(); + if (progressRegion == null) { + return; + } + Rectangle startPosition = progressRegion.getControl().getBounds(); + startPosition.x += windowLocation.x; + startPosition.y += windowLocation.y; + + // animate the progress dialog's arrival + AnimationEngine.createTweakedAnimation(internalWindow.getShell(), 400, startPosition, endPosition); + } /** * Get the shell provider to use in the progress support dialogs. This provider diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/ProgressMonitorFocusJobDialog.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/ProgressMonitorFocusJobDialog.java index 70e7f805d87..9554cb27713 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/ProgressMonitorFocusJobDialog.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/ProgressMonitorFocusJobDialog.java @@ -29,6 +29,7 @@ import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.operation.ProgressMonitorUtil; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.BusyIndicator; +import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; @@ -88,8 +89,10 @@ public class ProgressMonitorFocusJobDialog extends ProgressMonitorJobsDialog { Button runInWorkspace = createButton(parent, IDialogConstants.CLOSE_ID, ProgressMessages.ProgressMonitorFocusJobDialog_RunInBackgroundButton, true); runInWorkspace.addSelectionListener(widgetSelectedAdapter(e -> { + Rectangle shellPosition = getShell().getBounds(); job.setProperty(IProgressConstants.PROPERTY_IN_DIALOG, Boolean.FALSE); finishedRun(); + ProgressManagerUtil.animateDown(shellPosition); })); runInWorkspace.setCursor(arrowCursor); diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/statushandlers/IStatusDialogConstants.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/statushandlers/IStatusDialogConstants.java index 091fa75eb96..6d803b424ba 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/statushandlers/IStatusDialogConstants.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/statushandlers/IStatusDialogConstants.java @@ -168,5 +168,12 @@ public interface IStatusDialogConstants { */ Object MODALITY_SWITCH = new Object(); + /** + * This flag controls animations. It is for testing purposes only. If it set to + * false, animations will not be created. Animation means shell closing/opening + * animation. + */ + Object ANIMATION = new Object(); + Object MANAGER_IMPL = WorkbenchStatusDialogManagerImpl.class; } diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/statushandlers/InternalDialog.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/statushandlers/InternalDialog.java index 00a1e0a1208..d0469e0c4a5 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/statushandlers/InternalDialog.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/statushandlers/InternalDialog.java @@ -307,6 +307,11 @@ public class InternalDialog extends TrayDialog { if (getBooleanValue(IStatusDialogConstants.TRAY_OPENED)) { openTray(); } + } else { + if (getBooleanValue(IStatusDialogConstants.ANIMATION)) { + Rectangle shellPosition = getShell().getBounds(); + ProgressManagerUtil.animateUp(shellPosition); + } } return result; } @@ -649,6 +654,9 @@ public class InternalDialog extends TrayDialog { dialogState.put(IStatusDialogConstants.SHELL_BOUNDS, getShell().getBounds()); statusListViewer = null; boolean result = super.close(); + if (!modalitySwitch && getBooleanValue(IStatusDialogConstants.ANIMATION)) { + ProgressManagerUtil.animateDown(getShellBounds()); + } return result; } diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/statushandlers/WorkbenchStatusDialogManagerImpl.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/statushandlers/WorkbenchStatusDialogManagerImpl.java index d598ec621b1..768ac5bfe11 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/statushandlers/WorkbenchStatusDialogManagerImpl.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/statushandlers/WorkbenchStatusDialogManagerImpl.java @@ -154,6 +154,7 @@ public class WorkbenchStatusDialogManagerImpl implements KeptJobsListener { dialogState.put(IStatusDialogConstants.STATUS_MODALS, new HashMap<>()); dialogState.put(IStatusDialogConstants.LABEL_PROVIDER, new LabelProviderWrapper(dialogState)); dialogState.put(IStatusDialogConstants.MODALITY_SWITCH, Boolean.FALSE); + dialogState.put(IStatusDialogConstants.ANIMATION, Boolean.TRUE); return dialogState; } diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/tweaklets/Animations.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/tweaklets/Animations.java new file mode 100644 index 00000000000..811df011994 --- /dev/null +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/tweaklets/Animations.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2007, 2015 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.ui.internal.tweaklets; + +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.internal.RectangleAnimationFeedbackBase; +import org.eclipse.ui.internal.tweaklets.Tweaklets.TweakKey; + +/** + * Animation tweaklet base class. Create (and register) a tweaklet extension + * derived from this class to provide alternate animation behavior. Currently + * only affects animations produced by the new min / max behavior. + * + * @since 3.3 + * + */ +public abstract class Animations { + public static TweakKey KEY = new Tweaklets.TweakKey(Animations.class); + + static { + Tweaklets.setDefault(Animations.KEY, new LegacyAnimations()); + } + + /** Default c'tor */ + public Animations() { + } + + /** + * Create and return the animation feedback you want to use. + * + * @param shell The shell that the animation will be in + * @return The feedback renderer to use. + */ + public abstract RectangleAnimationFeedbackBase createFeedback(Shell shell); +} diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/tweaklets/ImageAnimationTweak.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/tweaklets/ImageAnimationTweak.java new file mode 100644 index 00000000000..e40aa8573ad --- /dev/null +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/tweaklets/ImageAnimationTweak.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2007, 2015 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.ui.internal.tweaklets; + +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.internal.RectangleAnimationFeedbackBase; +import org.eclipse.ui.internal.RectangleAnimationImageFeedback; + +/** + * Return an animation feedback that uses images. + * + * @since 3.3 + * + */ +public class ImageAnimationTweak extends Animations { + /** Default c'tor */ + public ImageAnimationTweak() { + } + + @Override + public RectangleAnimationFeedbackBase createFeedback(Shell shell) { + return new RectangleAnimationImageFeedback(shell, null, null); + } + +} diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/tweaklets/LegacyAnimations.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/tweaklets/LegacyAnimations.java new file mode 100644 index 00000000000..fba250a74e8 --- /dev/null +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/tweaklets/LegacyAnimations.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2007, 2015 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.ui.internal.tweaklets; + +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.internal.LegacyAnimationFeedback; +import org.eclipse.ui.internal.RectangleAnimationFeedbackBase; + +/** + * Return the default (legacy) animation. + * + * @since 3.3 + * + */ +public class LegacyAnimations extends Animations { + /** Default c'tor */ + public LegacyAnimations() { + } + + @Override + public RectangleAnimationFeedbackBase createFeedback(Shell shell) { + return new LegacyAnimationFeedback(shell, null, null); + } + +} diff --git a/tests/org.eclipse.ui.tests.rcp/Eclipse RCP Tests/org/eclipse/ui/tests/rcp/WorkbenchAdvisorTest.java b/tests/org.eclipse.ui.tests.rcp/Eclipse RCP Tests/org/eclipse/ui/tests/rcp/WorkbenchAdvisorTest.java index d5097c161a2..de5efaf95e7 100644 --- a/tests/org.eclipse.ui.tests.rcp/Eclipse RCP Tests/org/eclipse/ui/tests/rcp/WorkbenchAdvisorTest.java +++ b/tests/org.eclipse.ui.tests.rcp/Eclipse RCP Tests/org/eclipse/ui/tests/rcp/WorkbenchAdvisorTest.java @@ -19,7 +19,9 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IWindowListener; @@ -30,6 +32,7 @@ import org.eclipse.ui.application.IActionBarConfigurer; import org.eclipse.ui.application.IWorkbenchConfigurer; import org.eclipse.ui.application.IWorkbenchWindowConfigurer; import org.eclipse.ui.application.WorkbenchAdvisor; +import org.eclipse.ui.internal.progress.ProgressManagerUtil; import org.eclipse.ui.tests.rcp.util.WorkbenchAdvisorObserver; import org.junit.After; import org.junit.Before; @@ -288,6 +291,18 @@ public class WorkbenchAdvisorTest { super.preWindowOpen(configurer); configurer.setShowProgressIndicator(false); } + + @Override + public void postWindowOpen(IWorkbenchWindowConfigurer configurer) { + try { + ProgressManagerUtil.animateUp(new Rectangle(0, 0, 100, 50)); + } + catch (NullPointerException e) { + // we shouldn't get here + fail(e.getMessage()); + } + } + }; int code = PlatformUI.createAndRunWorkbench(display, wa); diff --git a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/internal/AnimationEngineTest.java b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/internal/AnimationEngineTest.java new file mode 100644 index 00000000000..b1ee891a2a3 --- /dev/null +++ b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/internal/AnimationEngineTest.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright (c) 2008, 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.ui.tests.internal; + +import static org.junit.Assert.assertTrue; + +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.preference.PreferenceMemento; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchPreferenceConstants; +import org.eclipse.ui.internal.AnimationEngine; +import org.eclipse.ui.internal.AnimationFeedbackBase; +import org.eclipse.ui.internal.util.PrefUtil; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * @since 3.5 + * + */ +public class AnimationEngineTest { + + private class TestFeedback extends AnimationFeedbackBase { + /** + * @param parentShell + */ + public TestFeedback(Shell parentShell) { + super(parentShell); + } + + public int count = 0; + public int initCalled = -1; + public int renderCalled = -1; + public int disposeCalled = -1; + + @Override + public void dispose() { + disposeCalled = count++; + } + + @Override + public void initialize(AnimationEngine animationEngine) { + initCalled = count++; + } + + @Override + public void renderStep(AnimationEngine engine) { + if(renderCalled == -1) { + renderCalled = count++; + } + } + + } + + Shell shell; + TestFeedback feedback; + AnimationEngine engine; + private PreferenceMemento memento; + + @Before + public void doSetUp() { + shell = new Shell(Display.getCurrent()); + memento = new PreferenceMemento(); + } + + @After + public void doTearDown() { + memento.resetPreferences(); + shell.dispose(); + shell = null; + } + + /** + * Ensure that the protocol expected by the animation implementations works + * as defined: + * <ol> + * <li>The feedback's initialize gets called on creation of the engine</li> + * <li>The feedback's renderStep gets called at least once</li> + * <li>The feedback's dispose gets called at least once (after a render)</li> + * </ol> + * @throws InterruptedException + */ + @Test + public void testAnimationEngine() throws InterruptedException { + // Ensure that animations are turned on + memento.setValue(PrefUtil.getAPIPreferenceStore(), IWorkbenchPreferenceConstants.ENABLE_ANIMATIONS, + true); + + feedback = new TestFeedback(shell); + engine = new AnimationEngine(feedback, 250, 0); + + // ensure that the init method gets called on construction + assertTrue("'initialize' was not called", feedback.initCalled == 0); + + // Run the animation + engine.schedule(); + + // Wait for the animation to finish + Display display = shell.getDisplay(); + while(engine.getState() != Job.NONE) { + while (display.readAndDispatch()) { + } + Thread.sleep(20); + } + + // Make sure all methods were called...and in the correct order + assertTrue("'render' was not called", feedback.renderCalled >= 0); + assertTrue("'dispose' was not called", feedback.disposeCalled >= 0); + + //...in the correct order + assertTrue("'dispose' called before 'render", feedback.renderCalled < feedback.disposeCalled); + } +} diff --git a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/internal/InternalTestSuite.java b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/internal/InternalTestSuite.java index c4538cf7e11..728e5eea2fc 100644 --- a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/internal/InternalTestSuite.java +++ b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/internal/InternalTestSuite.java @@ -31,6 +31,7 @@ import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses({ + AnimationEngineTest.class, EditorActionBarsTest.class, ActionSetExpressionTest.class, PopupMenuExpressionTest.class, diff --git a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/statushandlers/StatusDialogManagerTest.java b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/statushandlers/StatusDialogManagerTest.java index 8c76a1e72d9..7fd80024921 100644 --- a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/statushandlers/StatusDialogManagerTest.java +++ b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/statushandlers/StatusDialogManagerTest.java @@ -95,6 +95,7 @@ public class StatusDialogManagerTest { automatedMode = ErrorDialog.AUTOMATED_MODE; wsdm = new WorkbenchStatusDialogManager(null); ErrorDialog.AUTOMATED_MODE = false; + wsdm.setProperty(IStatusDialogConstants.ANIMATION, Boolean.FALSE); FreezeMonitor.expectCompletionIn(60_000); } diff --git a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/statushandlers/WorkbenchStatusDialogManagerImplTest.java b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/statushandlers/WorkbenchStatusDialogManagerImplTest.java index adc43e7bf71..b14b58f038b 100644 --- a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/statushandlers/WorkbenchStatusDialogManagerImplTest.java +++ b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/statushandlers/WorkbenchStatusDialogManagerImplTest.java @@ -40,6 +40,7 @@ public class WorkbenchStatusDialogManagerImplTest { @Before public void setUp() throws Exception { mgr = new WorkbenchStatusDialogManagerImpl(0xFFFFFF, null); + mgr.setProperty(IStatusDialogConstants.ANIMATION, Boolean.FALSE); } @After |
