Package org.gvt

Source Code of org.gvt.GraphAnimation

/*******************************************************************************
* Copyright (c) 2003, 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
*******************************************************************************/
package org.gvt;

import org.eclipse.draw2d.Connection;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Viewport;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer;
import org.gvt.editpart.ChsRootEditPart;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
* This class is taken from Flow example to add animation ability to Chisio and
* used originally, it is not changed.
*
* Only run() method is added to start the animation when it is needed.
*
* @author hudsonr,   Created on Apr 28, 2003
* @author Cihan Kucukkececi (modified by)
*/
public class GraphAnimation
{
  static final long DURATION = 400;

  static long current;

  static double progress;

  static long start = -1;

  static long finish;

  static Viewport viewport;

  static boolean PLAYBACK;

  static boolean RECORDING;

  static Map initialStates;

  static Map finalStates;

  public static void end()
  {
    Iterator iter = initialStates.keySet().iterator();
    while (iter.hasNext())
    {
      IFigure f = ((IFigure) iter.next());
      f.revalidate();
      f.setVisible(true);
    }
    //$TODO instead of performing a final normal layout, what about setting progress=1.0?
    initialStates = null;
    finalStates = null;
    PLAYBACK = false;
//  trackMe = null;
//  showMe = null;
    viewport = null;
  }

  public static boolean captureLayout(IFigure root)
  {

    RECORDING = true;

    while (!(root instanceof Viewport))
      root = root.getParent();
    viewport = (Viewport) root;
    while (root.getParent() != null)
      root = root.getParent();

    initialStates = new HashMap();
    finalStates = new HashMap();

    //This part records all layout results.
    root.validate();
    Iterator iter = initialStates.keySet().iterator();
    if (!iter.hasNext())
    {
      //Nothing layed out, so abort the animation
      RECORDING = false;
      return false;
    }
    while (iter.hasNext())
      recordFinalState((IFigure) iter.next());

    start = System.currentTimeMillis();
    finish = start + DURATION;
    current = start + 20;

    RECORDING = false;
    PLAYBACK = true;
    return true;
  }

  public static boolean playbackState(Connection conn)
  {
    if (!PLAYBACK)
      return false;

    PointList list1 = (PointList) initialStates.get(conn);
    PointList list2 = (PointList) finalStates.get(conn);
    if (list1 == null)
    {
      conn.setVisible(false);
      return true;
    }
    if (list1.size() == list2.size())
    {
      Point pt1 = new Point(), pt2 = new Point();
      PointList points = conn.getPoints();
      points.removeAllPoints();
      for (int i = 0; i < list1.size(); i++)
      {
        list1.getPoint(pt2, i);
        list2.getPoint(pt1, i);
        pt1.x = (int) Math
          .round(pt1.x * progress + (1 - progress) * pt2.x);
        pt1.y = (int) Math
          .round(pt1.y * progress + (1 - progress) * pt2.y);
        points.addPoint(pt1);
      }
      conn.setPoints(points);
    }
    return true;
  }

  public static boolean playbackState(IFigure container)
  {
    if (!PLAYBACK)
      return false;

    List children = container.getChildren();
    Rectangle rect1, rect2;
    for (int i = 0; i < children.size(); i++)
    {
      IFigure child = (IFigure) children.get(i);
      rect1 = (Rectangle) initialStates.get(child);
      rect2 = (Rectangle) finalStates.get(child);
      if (rect2 == null)
        continue;
      child.setBounds(new Rectangle(
        (int) Math.round(progress * rect2.x + (1 - progress) * rect1.x),
        (int) Math.round(progress * rect2.y + (1 - progress) * rect1.y),
        (int) Math.round(
          progress * rect2.width + (1 - progress) * rect1.width),
        (int) Math.round(
          progress * rect2.height + (1 - progress) * rect1.height)
      ));
//    child.invalidate();
    }
    return true;
  }

  static void recordFinalState(Connection conn)
  {
    //$TODO
    PointList points1 = (PointList) initialStates.get(conn);
    PointList points2 = conn.getPoints().getCopy();

    if (points1 != null && points1.size() != points2.size())
    {
      Point p = new Point(), q = new Point();

      int size1 = points1.size() - 1;
      int size2 = points2.size() - 1;

      int i1 = size1;
      int i2 = size2;

      double current1 = 1.0;
      double current2 = 1.0;

      double prev1 = 1.0;
      double prev2 = 1.0;

      while (i1 > 0 || i2 > 0)
      {
        if (Math.abs(current1 - current2) < 0.1
          && i1 > 0 && i2 > 0)
        {
          //Both points are the same, use them and go on;
          prev1 = current1;
          prev2 = current2;
          i1--;
          i2--;
          current1 = (double) i1 / size1;
          current2 = (double) i2 / size2;
        }
        else if (current1 < current2)
        {
          //2 needs to catch up
          // current1 < current2 < prev1
          points1.getPoint(p, i1);
          points1.getPoint(q, i1 + 1);

          p.x = (int) ((
            (q.x * (current2 - current1) + p.x * (prev1 - current2))
              / (prev1 - current1)));
          p.y = (int) ((
            (q.y * (current2 - current1) + p.y * (prev1 - current2))
              / (prev1 - current1)));

          points1.insertPoint(p, i1 + 1);

          prev1 = prev2 = current2;
          i2--;
          current2 = (double) i2 / size2;

        }
        else
        {
          //1 needs to catch up
          // current2< current1 < prev2

          points2.getPoint(p, i2);
          points2.getPoint(q, i2 + 1);

          p.x = (int) ((
            (q.x * (current1 - current2) + p.x * (prev2 - current1))
              / (prev2 - current2)));
          p.y = (int) ((
            (q.y * (current1 - current2) + p.y * (prev2 - current1))
              / (prev2 - current2)));

          points2.insertPoint(p, i2 + 1);

          prev2 = prev1 = current1;
          i1--;
          current1 = (double) i1 / size1;
        }
      }
    }
    finalStates.put(conn, points2);
  }

  static void recordFinalState(IFigure child)
  {
    if (child instanceof Connection)
    {
      recordFinalState((Connection) child);
      return;
    }
    Rectangle rect2 = child.getBounds().getCopy();
    Rectangle rect1 = (Rectangle) initialStates.get(child);
    if (rect1.isEmpty())
    {
      rect1.x = rect2.x;
      rect1.y = rect2.y;
      rect1.width = rect2.width;
    }
    finalStates.put(child, rect2);
  }

  public static void recordInitialState(Connection connection)
  {
    if (!RECORDING)
      return;
    PointList points = connection.getPoints().getCopy();
    if (points.size() == 2
      && points.getPoint(0).equals(Point.SINGLETON.setLocation(0, 0))
      && points.getPoint(1).equals(Point.SINGLETON.setLocation(100, 100)))
      initialStates.put(connection, null);
    else
      initialStates.put(connection, points);
  }

  public static void recordInitialState(IFigure container)
  {
    if (!RECORDING)
      return;

    List children = container.getChildren();
    IFigure child;
    for (int i = 0; i < children.size(); i++)
    {
      child = (IFigure) children.get(i);
      initialStates.put(child, child.getBounds().getCopy());
    }
  }

  static void swap()
  {
    Map temp = finalStates;
    finalStates = initialStates;
    initialStates = temp;
  }

  public static boolean step()
  {
    current = System.currentTimeMillis() + 30;
    progress = (double) (current - start) / (finish - start);
    progress = Math.min(progress, 0.999);
    Iterator iter = initialStates.keySet().iterator();

    while (iter.hasNext())
      ((IFigure) iter.next()).revalidate();
    viewport.validate();

    //  Point loc = viewport.getViewLocation();
    //  loc.translate(trackMe.getBounds().getLocation().getDifference(trackLocation));
    //  viewport.setViewLocation(loc);
    //  trackLocation = trackMe.getBounds().getLocation();

    return current < finish;
  }

  public static void run(ScrollingGraphicalViewer viewer)
  {
    ChsRootEditPart root = (ChsRootEditPart)
      viewer.getRootEditPart().getRoot().getChildren().get(0);

    IFigure fig = root.getFigure();

    GraphAnimation.captureLayout(fig);
    while (GraphAnimation.step())
      fig.getUpdateManager().performUpdate();
    GraphAnimation.end();
  }
}
TOP

Related Classes of org.gvt.GraphAnimation

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.