Package rinde.sim.ui

Source Code of rinde.sim.ui.View$Builder

/**
*
*/
package rinde.sim.ui;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Maps.newHashMap;
import static java.util.Arrays.asList;

import java.util.List;
import java.util.Map;

import javax.annotation.Nullable;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Monitor;
import org.eclipse.swt.widgets.Shell;

import rinde.sim.core.Simulator;
import rinde.sim.core.TickListener;
import rinde.sim.core.TimeLapse;
import rinde.sim.event.Event;
import rinde.sim.event.Listener;
import rinde.sim.ui.renderers.Renderer;

/**
* The view class is the main GUI class. For creating a view, see
* {@link #create(Simulator)}.
* @author Rinde van Lon (rinde.vanlon@cs.kuleuven.be)
* @author Bartosz Michalik <bartosz.michalik@cs.kuleuven.be>
* @since 2.0
*/
public final class View {

  private View() {}

  /**
   * Creates a {@link View.Builder} for a specific simulator. The returned
   * builder allows to configure the visualization.
   * @param simulator The {@link Simulator} to create the view for.
   * @return The {@link View.Builder}.
   */
  public static Builder create(Simulator simulator) {
    return new Builder(simulator);
  }

  /**
   * A builder that creates a visualization for {@link Simulator} instances.
   * @author Rinde van Lon <rinde.vanlon@cs.kuleuven.be>
   */
  public static class Builder {
    /**
     * The default window size: 800x600.
     */
    public static final Point DEFAULT_WINDOW_SIZE = new Point(800, 600);

    Simulator simulator;
    boolean autoPlay;
    boolean autoClose;
    boolean allowResize;
    boolean fullScreen;
    boolean async;
    int speedUp;
    long stopTime;
    long sleep;
    @Nullable
    Display display;
    String title;
    Point screenSize;
    @Nullable
    Monitor monitor;
    final List<Renderer> rendererList;
    Map<MenuItems, Integer> accelerators;

    Listener callback;

    Builder(Simulator s) {
      simulator = s;
      autoPlay = false;
      autoClose = false;
      allowResize = true;
      fullScreen = false;
      title = "Simulator";
      speedUp = 1;
      stopTime = -1;
      screenSize = DEFAULT_WINDOW_SIZE;
      rendererList = newArrayList();
      accelerators = newHashMap();
      accelerators.putAll(MenuItems.QWERTY_ACCELERATORS);
    }

    /**
     * @param renderers The {@link Renderer}s to add to the view.
     * @return This as per the builder pattern.
     */
    public Builder with(Renderer... renderers) {
      rendererList.addAll(asList(renderers));
      return this;
    }

    /**
     * When <i>auto play</i> is enabled the {@link Simulator} will be started
     * directly when {@link #show()} is called. Default: <code>disabled</code>.
     * @return This as per the builder pattern.
     */
    public Builder enableAutoPlay() {
      autoPlay = true;
      return this;
    }

    /**
     * When <i>auto close</i> is enabled the view will be closed as soon as the
     * {@link Simulator} is stopped. This is useful for creating automated GUIs.
     * Default: <code>disabled</code>.
     * @return This as per the builder pattern.
     */
    public Builder enableAutoClose() {
      autoClose = true;
      return this;
    }

    /**
     * Stops the simulator at the specified time.
     * @param simulationTime The time to stop, must be positive.
     * @return This as per the builder pattern.
     */
    public Builder stopSimulatorAtTime(long simulationTime) {
      checkArgument(simulationTime > 0);
      stopTime = simulationTime;
      return this;
    }

    /**
     * Speed up defines the simulation time between to respective GUI draw
     * operations. Default: <code>1</code>.
     * @param speed The speed to use.
     * @return This as per the builder pattern.
     */
    public Builder setSpeedUp(int speed) {
      speedUp = speed;
      return this;
    }

    /**
     * Should be used in case there is already an SWT application running that
     * was launched from the same VM as the current GUI that is created.
     * @param d The existing {@link Display} to use as display for the view.
     * @return This as per the builder pattern.
     */
    public Builder setDisplay(Display d) {
      display = d;
      return this;
    }

    /**
     * Changes the title appendix of the view. The default title is <i>RinSim -
     * Simulator</i>, the title appendix is everything after the dash.
     * @param titleAppendix The new appendix to use.
     * @return This as per the builder pattern.
     */
    public Builder setTitleAppendix(String titleAppendix) {
      title = titleAppendix;
      return this;
    }

    /**
     * Don't allow the user to resize the application window. Default:
     * <i>allowed</i>.
     * @return This as per the builder pattern.
     */
    public Builder disallowResizing() {
      allowResize = false;
      return this;
    }

    /**
     * This takes precedence over any calls to {@link #setResolution(int, int)}.
     * @return This, as per the builder pattern.
     */
    public Builder setFullScreen() {
      fullScreen = true;
      return this;
    }

    /**
     * Change the resolution of the window. Default resolution:
     * {@link #DEFAULT_WINDOW_SIZE}.
     * @param width The new width to use.
     * @param height The new height to use.
     * @return This, as per the builder pattern.
     */
    public Builder setResolution(int width, int height) {
      checkArgument(width > 0 && height > 0,
          "Only positive dimensions are allowed, input: %s x %s.", width,
          height);
      screenSize = new Point(width, height);
      return this;
    }

    /**
     * Specify on which monitor the application should be positioned. If this
     * method is not called SWT decides where the screen is positioned, usually
     * on the primary monitor.
     * @param m The monitor.
     * @return This, as per the builder pattern.
     */
    public Builder displayOnMonitor(Monitor m) {
      monitor = m;
      return this;
    }

    /**
     * Allows to change the accelerators (aka shortcuts) of the menu items. Each
     * accelerator is set to its respective menu item via
     * {@link org.eclipse.swt.widgets.MenuItem#setAccelerator(int)}. By default
     * the {@link MenuItems#QWERTY_ACCELERATORS} are used.
     * @param acc The accelerators to set.
     * @return This, as per the builder pattern.
     */
    public Builder setAccelerators(Map<MenuItems, Integer> acc) {
      accelerators.putAll(acc);
      return this;
    }

    public Builder setAsync() {
      async = true;
      return this;
    }

    public Builder setCallback(Listener l) {
      callback = l;
      return this;
    }

    public Builder setSleep(long ms) {
      sleep = ms;
      throw new UnsupportedOperationException("not yet implemented");
    }

    /**
     * Show the view.
     */
    public void show() {
      checkState(
          simulator.isConfigured(),
          "Simulator needs to be configured before it can be visualized, see Simulator.configure()");

      checkArgument(!rendererList.isEmpty(),
          "At least one renderer needs to be defined.");

      Display.setAppName("RinSim");
      final Display d = display != null ? display : Display.getCurrent();
      final boolean isDisplayOwner = d == null;
      final Display disp = isDisplayOwner ? new Display() : Display
          .getCurrent();

      int shellArgs = SWT.TITLE | SWT.CLOSE;
      if (allowResize) {
        shellArgs = shellArgs | SWT.RESIZE;
      }
      final Shell shell = new Shell(disp, shellArgs);
      if (monitor != null) {
        shell.setLocation(monitor.getBounds().x, monitor.getBounds().y);
      }

      shell.setText("RinSim - " + title);
      if (fullScreen) {
        shell.setFullScreen(true);
        shell.setMaximized(true);
      } else {
        shell.setSize(screenSize);
      }

      if (stopTime > 0) {
        simulator.addTickListener(new TickListener() {
          @Override
          public void tick(TimeLapse time) {}

          @Override
          public void afterTick(TimeLapse time) {
            if (time.getTime() >= stopTime) {
              simulator.stop();
            }
          }
        });
      }

      if (autoClose) {

        final Listener list = callback;

        simulator.getEventAPI().addListener(new Listener() {
          @Override
          public void handleEvent(final Event arg0) {
            if (!shell.isDisposed()) {
              disp.asyncExec(new Runnable() {
                @Override
                public void run() {
                  shell.close();
                }
              });
            }
            if (list != null) {
              list.handleEvent(arg0);
            }
          }
        }, Simulator.SimulatorEventType.STOPPED);
      }

      shell.addListener(SWT.Close, new org.eclipse.swt.widgets.Listener() {
        @SuppressWarnings("synthetic-access")
        @Override
        public void handleEvent(@Nullable org.eclipse.swt.widgets.Event event) {
          simulator.stop();
          while (simulator.isPlaying()) {
            // wait until simulator actually stops (it finishes its
            // current tick first).
          }
          if (isDisplayOwner && !disp.isDisposed()) {
            disp.dispose();
          } else if (!isDisplayOwner && !shell.isDisposed()) {
            shell.dispose();
          }
        }
      });

      // simulator viewer is run in here
      new SimulationViewer(shell, simulator, speedUp, autoPlay, rendererList,
          accelerators);
      shell.open();
      if (!async) {
        while (!shell.isDisposed()) {
          if (!disp.readAndDispatch()) {
            disp.sleep();
          }
        }
        if (shell.isDisposed()) {
          simulator.stop();
        }
      }
    }
  }

}
TOP

Related Classes of rinde.sim.ui.View$Builder

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.