Package org.rascalmpl.library.vis.swt.applet

Source Code of org.rascalmpl.library.vis.swt.applet.FigureSWTApplet

/*******************************************************************************
* Copyright (c) 2009-2013 CWI
* 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:

*   * Bert Lisser - Bert.Lisser@cwi.nl (CWI)
*   * Paul Klint - Paul.Klint@cwi.nl - CWI
*******************************************************************************/
package org.rascalmpl.library.vis.swt.applet;

import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.eclipse.imp.pdb.facts.IConstructor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.rascalmpl.interpreter.IEvaluatorContext;
import org.rascalmpl.library.vis.figure.Figure;
import org.rascalmpl.library.vis.figure.FigureFactory;
import org.rascalmpl.library.vis.figure.combine.Overlap;
import org.rascalmpl.library.vis.figure.combine.containers.WhiteSpace;
import org.rascalmpl.library.vis.graphics.SWTGraphicsContext;
import org.rascalmpl.library.vis.properties.IRunTimePropertyChanges;
import org.rascalmpl.library.vis.properties.PropertyManager;
import org.rascalmpl.library.vis.swt.Animation;
import org.rascalmpl.library.vis.swt.FigureExecutionEnvironment;
import org.rascalmpl.library.vis.swt.ICallbackEnv;
import org.rascalmpl.library.vis.swt.IFigureConstructionEnv;
import org.rascalmpl.library.vis.util.vector.Coordinate;
import org.rascalmpl.library.vis.util.vector.Rectangle;

public class FigureSWTApplet extends Composite
  implements IFigureConstructionEnv, DisposeListener{

  public static final double ANIMATION_TARGET_FPS = 50;
  public static final int ANIMATION_DELAY = (int)(1000.0/ANIMATION_TARGET_FPS);

  private static final int SWT_FLAGS = SWT.BORDER | SWT.NO_BACKGROUND | SWT.NO_MERGE_PAINTS ;
  private List<FigureSWTApplet> children;
  private Figure figure;
  private FigureExecutionEnvironment env;
  private InputHandler inputHandler;
  private ViewPortHandler viewPortHandler;
  private RunTimePropertyAdjuster runTimePropertyAdjuster;
  private List<Overlap> overlapFigures; // shared by inputhandler and viewport handler
  private boolean redrawRequested;
  private boolean busy;
  private int computeClock = -1;
  private Set<Animation> animations;
 
  public FigureSWTApplet(Composite parent, IConstructor cfig, FigureExecutionEnvironment env){
    this(parent,cfig,env,true,true);
  }
 
  static int getFlags(boolean hscroll,boolean vscroll){
    int result = SWT_FLAGS;
    if(hscroll) {
      result = result | SWT.H_SCROLL;
    }
    if(vscroll){
      result = result | SWT.V_SCROLL;
    }
    return result;
  }
 
  public FigureSWTApplet(Composite parent, IConstructor cfig, FigureExecutionEnvironment env,boolean hscroll,boolean vscroll) {
    super(parent, getFlags(hscroll,vscroll));
    this.env = env;
    runTimePropertyAdjuster = new RunTimePropertyAdjuster(this);
    children = new ArrayList<FigureSWTApplet>();
    overlapFigures = new LinkedList<Overlap>();
 
    Figure fig = FigureFactory.make(this, cfig, null, null);
    if(!fig.widthDependsOnHeight()){
      fig = new WhiteSpace( fig, new PropertyManager());
    }
    this.figure = fig;
    inputHandler = new InputHandler(this, overlapFigures);
    viewPortHandler = new ViewPortHandler(this,overlapFigures);
    animations = new HashSet<Animation>();
    addPaintListener(viewPortHandler);
    addControlListener(viewPortHandler);
    addMouseListener(inputHandler);
    addMouseMoveListener(inputHandler);
    addMouseTrackListener(inputHandler);
    addKeyListener(inputHandler);
    triggerRecompute();
  }
 
  public boolean isUpToDate(){
    return computeClock == env.getComputeClock();
  }
 
 
  public void animate(){
    List<Animation> remove = new ArrayList<Animation>();
    for(Animation a : animations){
      if(!a.moreFrames()){
        remove.add(a);
      }
    }
    for(Animation a : remove){
      unregisterAnimation(a);
    }
    if(animations.isEmpty()){
      return;
    }
    getDisplay().timerExec(ANIMATION_DELAY, new Runnable() {

      @Override
      public void run() {
        for(Animation a : animations){
          System.out.printf("Animating %d!\n", animations.size());
          a.animate();
        }
       
        try {
          redraw();
          for(FigureSWTApplet app : children){
            app.redraw();
          }
        }
        catch (SWTException e) {
          if (e.code != SWT.ERROR_WIDGET_DISPOSED) {
            throw e; // rethrow if its unexpected
          }
          // otherwise the window was closed before the animation ended
        }
      }
     
    });

  }
 
  public void triggerRecompute(){
    redrawRequested = false;
    busy = true;
    viewPortHandler.beforeInitialise();
    overlapFigures.clear();
    for(FigureSWTApplet child : children){
      child.triggerRecompute();
    }
    figure.registerIds(this, env.getNameResolver());
    figure.registerConverts(env.getNameResolver());
    figure.init(this, env.getNameResolver(), null, false, true);
    viewPortHandler.notifyFigureChanged()
  }

  public void notifyLayoutChanged(){
    inputHandler.notifyFigureChanged();
    runTimePropertyAdjuster.notifyFigureChanged();
    computeClock = env.getComputeClock();
    busy = false;
    if(redrawRequested){
      redraw();
    }
  }

  public void requestRedraw() {
    if(busy){
      redrawRequested = true;
    } else {
      if(!isDisposed()){
        redraw();
      }
    }
  }
 
  public void handleNonCapturedKeyPress(KeyEvent e){
    runTimePropertyAdjuster.handleKeyPress(e);
    if(e.keyCode == SWT.PRINT_SCREEN){
      viewPortHandler.makeScreenShot();
    }
  }
 
  public void writeScreenshot(OutputStream to){
    viewPortHandler.writeScreenShot(to);
  }
 
  /**
   * Draw the figure to a new Image. This way the whole figure gets saved unlike with the writeScreenshot method which
   * only saves that part of the figure which is visible in the applet
   * 
   * @param to - the output stream to write the image data to
   */
  public void saveImage(OutputStream to) {;
    int figureWidth = (int)Math.ceil(figure.size.getX());
    int figureHeight = (int)Math.ceil(figure.size.getY());
   
    Image image = new Image(getDisplay(), figureWidth, figureHeight);
    GC gc = new GC(image);
    SWTGraphicsContext swtGC = new SWTGraphicsContext();
    swtGC.setGC(gc);
   
    gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE));

    figure.draw(new Coordinate(1.0, 1.0), swtGC, new Rectangle(0, 0, figureWidth, figureHeight), new SWTElementsVisibilityManager().getVisibleSWTElementsVector());
 
    ImageLoader il = new ImageLoader();
    il.data = new ImageData[] {image.getImageData()};
    il.save(to, SWT.IMAGE_PNG);
  }
 
  public FigureExecutionEnvironment getExectutionEnv(){
    return env;
  }

  @Override
  public void widgetDisposed(DisposeEvent e) {
    figure.destroy(this);
    viewPortHandler.dispose();
    inputHandler.dispose();
    runTimePropertyAdjuster.dispose();
    for(FigureSWTApplet child : children){
      child.dispose();
    }
  }
 
  public void registerChild(FigureSWTApplet child){
    System.out.printf("registering child %s\n", child);
    children.add(child);
  }

  @Override
  public FigureSWTApplet getSWTParent() {
    return this;
  }

  @Override
  public ICallbackEnv getCallBackEnv() {
    return env;
  }

  @Override
  public IEvaluatorContext getRascalContext() {
    return env.getRascalContext();
  }

  @Override
  public FigureExecutionEnvironment getFigureExecEnv() {
    return env;
  }
 
  public Figure getFigure(){
    return figure;
  }
 
  public void addOverlapFigure(Overlap overlap){
    overlapFigures.add(overlap);
  }
 
  public String toString(){
    return "FigureSWTApplet" + figure.toString();
  }

 

  @Override
  public IRunTimePropertyChanges getRunTimePropertyChanges() {
    return runTimePropertyAdjuster;
  }

  public void translateFromViewPortToFigure(Coordinate screenLocation) {
    viewPortHandler.translateFromViewPortToFigure(screenLocation);
  }
 
  public InputHandler getInputHandler(){
    return inputHandler;
  }



  public void mouseMove(MouseEvent e) {
    inputHandler.mouseMove(e);
  }

  @Override
  public void registerOverlap(Overlap o) {
    overlapFigures.add(o);
   
  }

  @Override
  public void unregisterOverlap(Overlap o) {
    overlapFigures.remove(o);
  }

  @Override
  public void addSWTElement(Control c) {
    viewPortHandler.addSWTElement(c);
   
  }

  @Override
  public void addAboveSWTElement(Figure fig) {
    viewPortHandler.addAboveSWTElement(fig);
   
  }

  public Image getFigureImage() {
    return viewPortHandler.getFigureImage();
  }

  public void registerAnimation(Animation a) {
    animations.add(a);
   
  }

  public void unregisterAnimation(Animation a) {
    animations.remove(a);
   
  }



  /*
  private void zoom(double factorX, double factorY){
    BoundingBox zoomFactors = new BoundingBox(factorX, factorY);
    BoundingBox oldFigureSize = new BoundingBox(figureSize);
    zoom.setWidth(zoom.getWidth() * factorX);
    zoom.setHeight(zoom.getHeight() * factorY);
    resize();
    for(boolean flip : Figure.BOTH_DIMENSIONS){
      if(zoomFactors.getWidth(flip) != 1.0  && oldFigureSize.getWidth(flip) == figureSize.getWidth(flip)){
        zoom.setWidth(flip,zoom.getWidth(flip) / zoomFactors.getWidth(flip));
      }
    }
    if(factorX != 1.0 && factorY != 1.0 &&
        (oldFigureSize.getWidth() == figureSize.getWidth()
            || oldFigureSize.getHeight() == figureSize.getHeight())){
      for(boolean flip : Figure.BOTH_DIMENSIONS){
          zoom.setWidth(flip,zoom.getWidth(flip) / factorX);
      }
    } else {
      for(boolean flip : Figure.BOTH_DIMENSIONS){
        if(zoomFactors.getWidth(flip) != 1.0  && oldFigureSize.getWidth(flip) == figureSize.getWidth(flip)){
          zoom.setWidth(flip,zoom.getWidth(flip) / zoomFactors.getWidth(flip));
        }
      }
    }
    for(boolean flip : Figure.BOTH_DIMENSIONS){
      double diff = figureSize.getWidth(flip) - viewPortSize.getWidth(flip);
      viewPortLocation.setX(flip,(viewPortLocation.getX(flip) + mouseLocation.getX(flip)) *  zoomFactors.getWidth(flip) - mouseLocation.getX(flip));
      viewPortLocation.setX(flip,Math.max(0,Math.min(diff,viewPortLocation.getX(flip))));
    }
   
    if(!oldFigureSize.isEq(figureSize)){
      redraw();
    }
  } */

 
  /*
  private void scrollOnMouseDrag() {
    double factor = 1.0;
    if(!mouseDown){
      long newTime = System.nanoTime();
      long diff = newTime - lastTime;
      factor = (double)diff / 10000000;
      lastTime = newTime;
    }
    for(boolean flip : Figure.BOTH_DIMENSIONS){
      double diff = figureSize.getWidth(flip) - viewPortSize.getWidth(flip);
      viewPortLocation.addX(flip, -(mouseSpeed.getX(flip) * factor));
     
      if(viewPortLocation.getX(flip) > diff || viewPortLocation.getX(flip) < 0){
        mouseSpeed.setX(flip,-mouseSpeed.getX(flip));
      }
      viewPortLocation.capXBelow(flip, diff);
     
      viewPortLocation.capXAbove(flip,0);
    }
    getHorizontalBar().setSelection((int)viewPortLocation.getX());
    getVerticalBar().setSelection((int)viewPortLocation.getY());
    redraw();
  }
  */
TOP

Related Classes of org.rascalmpl.library.vis.swt.applet.FigureSWTApplet

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.