diff org.eclipse.draw2d/src/org/eclipse/draw2d/LayoutAnimator.d @ 12:bc29606a740c

Added dwt-addons in original directory structure of eclipse.org
author Frank Benoit <benoit@tionex.de>
date Sat, 14 Mar 2009 18:23:29 +0100
parents
children dbfb303e8fb0
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.eclipse.draw2d/src/org/eclipse/draw2d/LayoutAnimator.d	Sat Mar 14 18:23:29 2009 +0100
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+module org.eclipse.draw2d.LayoutAnimator;
+
+import java.lang.all;
+
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.draw2d.Animator;
+import org.eclipse.draw2d.LayoutListener;
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.Animation;
+
+/**
+ * Animates the layout of a figure's children. The animator will capture the effects of a
+ * layout manager, and then play back the placement of children using linear interpolation
+ * for each child's start and end locations.
+ * <P>
+ * To use an animator, hook it as a layout listener for the figure whose layout is to
+ * be animated, by calling {@link IFigure#addLayoutListener(LayoutListener)}. It is not
+ * necessary to have an animator for every figure in a composition that is undergoing
+ * animation. For example, if a figure without an animator moves during the animation, it
+ * will continue to move and layout its children normally during each step of the
+ * animation.
+ * <P>
+ * Animator must be used in conjunction with layouts. If figures are placed manually using
+ * <code>setBounds()</code>, the animator may not be able to track and playback the
+ * changes that occur.
+ *
+ * @since 3.2
+ */
+public class LayoutAnimator : Animator , LayoutListener {
+
+private static LayoutAnimator INSTANCE_;
+static LayoutAnimator INSTANCE(){
+    if( INSTANCE_ is null ){
+        synchronized( LayoutAnimator.classinfo ){
+            if( INSTANCE_ is null ){
+                INSTANCE_ = new LayoutAnimator();
+            }
+        }
+    }
+    assert(INSTANCE_);
+    return INSTANCE_;
+}
+
+/**
+ * Constructs a new Animator. The default instance ({@link #getDefault()}) can be used on
+ * all figures being animated.
+ *
+ * @since 3.2
+ */
+protected this() { }
+
+/**
+ * Returns an object encapsulating the placement of children in a container. This method
+ * is called to capture both the initial and final states.
+ * @param container the container figure
+ * @return the current state
+ * @since 3.2
+ */
+protected Object getCurrentState(IFigure container) {
+    Map locations = new HashMap();
+    List children = container.getChildren();
+    IFigure child;
+    for (int i = 0; i < children.size(); i++) {
+        child = cast(IFigure)children.get(i);
+        locations.put(cast(Object)child, child.getBounds().getCopy());
+    }
+    return cast(Object)locations;
+}
+
+/**
+ * Returns the default instance.
+ * @return the default instance
+ * @since 3.2
+ */
+public static LayoutAnimator getDefault() {
+    return INSTANCE;
+}
+
+/**
+ * Hooks invalidation in case animation is in progress.
+ * @see LayoutListener#invalidate(IFigure)
+ */
+public final void invalidate(IFigure container) {
+    if (Animation.isInitialRecording())
+        Animation.hookAnimator(container, this);
+}
+
+/**
+ * Hooks layout in case animation is in progress.
+ * @see org.eclipse.draw2d.LayoutListener#layout(org.eclipse.draw2d.IFigure)
+ */
+public final bool layout(IFigure container) {
+    if (Animation.isAnimating())
+        return Animation.hookPlayback(container, this);
+    return false;
+}
+
+/**
+ * Plays back the animated layout.
+ * @see Animator#playback(IFigure)
+ */
+protected bool playback(IFigure container) {
+    Map initial = cast(Map) Animation.getInitialState(this, container);
+    Map ending = cast(Map) Animation.getFinalState(this, container);
+    if (initial is null)
+        return false;
+    List children = container.getChildren();
+
+    float progress = Animation.getProgress();
+    float ssergorp = 1 - progress;
+
+    Rectangle rect1, rect2;
+
+    for (int i = 0; i < children.size(); i++) {
+        IFigure child = cast(IFigure) children.get(i);
+        rect1 = cast(Rectangle)initial.get(cast(Object)child);
+        rect2 = cast(Rectangle)ending.get(cast(Object)child);
+
+        //TODO need to change this to hide the figure until the end.
+        if (rect1 is null)
+            continue;
+        child.setBounds(new Rectangle(
+            cast(int)Math.round(progress * rect2.x + ssergorp * rect1.x),
+            cast(int)Math.round(progress * rect2.y + ssergorp * rect1.y),
+            cast(int)Math.round(progress * rect2.width + ssergorp * rect1.width),
+            cast(int)Math.round(progress * rect2.height + ssergorp * rect1.height)
+        ));
+    }
+    return true;
+}
+
+/**
+ * Hooks post layout in case animation is in progress.
+ * @see LayoutListener#postLayout(IFigure)
+ */
+public final void postLayout(IFigure container) {
+    if (Animation.isFinalRecording())
+        Animation.hookNeedsCapture(container, this);
+}
+
+/**
+ * This callback is unused. Reserved for possible future use.
+ * @see LayoutListener#remove(IFigure)
+ */
+public final void remove(IFigure child) { }
+
+/**
+ * This callback is unused. Reserved for possible future use.
+ * @see LayoutListener#setConstraint(IFigure, Object)
+ */
+public final void setConstraint(IFigure child, Object constraint) { }
+
+}