Package com.mxgraph.swing.handler

Source Code of com.mxgraph.swing.handler.mxMovePreview

/**
* $Id: mxMovePreview.java,v 1.8 2011-03-18 16:10:49 gaudenz Exp $
* Copyright (c) 2008, Gaudenz Alder
*/
package com.mxgraph.swing.handler;

import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.util.Collection;
import java.util.LinkedList;

import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.swing.view.mxCellStatePreview;
import com.mxgraph.util.mxConstants;
import com.mxgraph.util.mxEvent;
import com.mxgraph.util.mxEventObject;
import com.mxgraph.util.mxEventSource;
import com.mxgraph.util.mxRectangle;
import com.mxgraph.view.mxCellState;
import com.mxgraph.view.mxGraph;

/**
* Connection handler creates new connections between cells. This control is used to display the connector
* icon, while the preview is used to draw the line.
*/
public class mxMovePreview extends mxEventSource
{
  /**
   *
   */
  protected mxGraphComponent graphComponent;

  /**
   * Maximum number of cells to preview individually. Default is 200.
   */
  protected int threshold = 200;

  /**
   * Specifies if the placeholder rectangle should be used for all
   * previews. Default is false. This overrides all other preview
   * settings if true.
   */
  protected boolean placeholderPreview = false;

  /**
   * Specifies if the preview should use clones of the original shapes.
   * Default is true.
   */
  protected boolean clonePreview = true;

  /**
   * Specifies if connected, unselected edges should be included in the
   * preview. Default is true. This should not be used if cloning is
   * enabled.
   */
  protected boolean contextPreview = true;

  /**
   * Specifies if the selection cells handler should be hidden while the
   * preview is visible. Default is false.
   */
  protected boolean hideSelectionHandler = false;

  /**
   *
   */
  protected transient mxCellState startState;

  /**
   *
   */
  protected transient mxCellState[] previewStates;

  /**
   *
   */
  protected transient Object[] movingCells;

  /**
   *
   */
  protected transient Rectangle initialPlaceholder;

  /**
   *
   */
  protected transient Rectangle placeholder;

  /**
   *
   */
  protected transient mxRectangle lastDirty;

  /**
   *
   */
  protected transient mxCellStatePreview preview;

  /**
   * Constructs a new rubberband selection for the given graph component.
   *
   * @param graphComponent Component that contains the rubberband.
   */
  public mxMovePreview(mxGraphComponent graphComponent)
  {
    this.graphComponent = graphComponent;

    // Installs the paint handler
    graphComponent.addListener(mxEvent.AFTER_PAINT, new mxIEventListener()
    {
      public void invoke(Object sender, mxEventObject evt)
      {
        Graphics g = (Graphics) evt.getProperty("g");
        paint(g);
      }
    });
  }

  /**
   *
   */
  public int getThreshold()
  {
    return threshold;
  }

  /**
   *
   */
  public void setThreshold(int value)
  {
    threshold = value;
  }

  /**
   *
   */
  public boolean isPlaceholderPreview()
  {
    return placeholderPreview;
  }

  /**
   *
   */
  public void setPlaceholderPreview(boolean value)
  {
    placeholderPreview = value;
  }

  /**
   *
   */
  public boolean isClonePreview()
  {
    return clonePreview;
  }

  /**
   *
   */
  public void setClonePreview(boolean value)
  {
    clonePreview = value;
  }

  /**
   *
   */
  public boolean isContextPreview()
  {
    return contextPreview;
  }

  /**
   *
   */
  public void setContextPreview(boolean value)
  {
    contextPreview = value;
  }

  /**
   *
   */
  public boolean isHideSelectionHandler()
  {
    return hideSelectionHandler;
  }

  /**
   *
   */
  public void setHideSelectionHandler(boolean value)
  {
    hideSelectionHandler = value;
  }

  /**
   *
   */
  public boolean isActive()
  {
    return startState != null;
  }

  /**
   * FIXME: Cells should be assigned outside of getPreviewStates
   */
  public Object[] getMovingCells()
  {
    return movingCells;
  }

  /**
   *
   */
  public Object[] getCells(mxCellState initialState)
  {
    mxGraph graph = graphComponent.getGraph();

    return graph.getMovableCells(graph.getSelectionCells());
  }

  /**
   * Returns the states that are affected by the move operation.
   */
  protected mxCellState[] getPreviewStates()
  {
    mxGraph graph = graphComponent.getGraph();
    Collection<mxCellState> result = new LinkedList<mxCellState>();

    for (Object cell : movingCells)
    {
      mxCellState cellState = graph.getView().getState(cell);

      if (cellState != null)
      {
        result.add(cellState);

        // Terminates early if too many cells
        if (result.size() >= threshold)
        {
          return null;
        }

        if (isContextPreview())
        {
          Object[] edges = graph.getAllEdges(new Object[] { cell });

          for (Object edge : edges)
          {
            if (!graph.isCellSelected(edge))
            {
              mxCellState edgeState = graph.getView().getState(
                  edge);

              if (edgeState != null)
              {
                // Terminates early if too many cells
                if (result.size() >= threshold)
                {
                  return null;
                }

                result.add(edgeState);
              }
            }
          }
        }
      }
    }

    return result.toArray(new mxCellState[result.size()]);
  }

  /**
   *
   */
  protected boolean isCellOpaque(Object cell)
  {
    return startState != null && startState.getCell() == cell;
  }

  /**
   * Sets the translation of the preview.
   */
  public void start(MouseEvent e, mxCellState state)
  {
    startState = state;
    movingCells = getCells(state);
    previewStates = (!placeholderPreview) ? getPreviewStates() : null;

    if (previewStates == null || previewStates.length >= threshold)
    {
      placeholder = getPlaceholderBounds(startState).getRectangle();
      initialPlaceholder = new Rectangle(placeholder);
      graphComponent.getGraphControl().repaint(placeholder);
    }

    fireEvent(new mxEventObject(mxEvent.START, "event", e, "state",
        startState));
  }

  /**
   *
   */
  protected mxRectangle getPlaceholderBounds(mxCellState startState)
  {
    mxGraph graph = graphComponent.getGraph();

    return graph.getView().getBounds(graph.getSelectionCells());
  }

  /**
   *
   */
  public mxCellStatePreview createCellStatePreview()
  {
    return new mxCellStatePreview(graphComponent, isClonePreview())
    {
      protected float getOpacityForCell(Object cell)
      {
        if (isCellOpaque(cell))
        {
          return 1;
        }

        return super.getOpacityForCell(cell);
      }
    };
  }

  /**
   * Sets the translation of the preview.
   */
  public void update(MouseEvent e, double dx, double dy, boolean clone)
  {
    mxGraph graph = graphComponent.getGraph();

    if (placeholder != null)
    {
      Rectangle tmp = new Rectangle(placeholder);
      placeholder.x = initialPlaceholder.x + (int) dx;
      placeholder.y = initialPlaceholder.x + (int) dy;
      tmp.add(placeholder);
      graphComponent.getGraphControl().repaint(tmp);
    }
    else if (previewStates != null)
    {
      preview = createCellStatePreview();
      preview.setOpacity(graphComponent.getPreviewAlpha());

      // Combines the layout result with the move preview
      for (mxCellState previewState : previewStates)
      {
        preview.moveState(previewState, dx, dy, false, false);

        // FIXME: Move into show-handler?
        boolean visible = true;

        if ((dx != 0 || dy != 0) && clone && isContextPreview())
        {
          visible = false;
          Object tmp = previewState.getCell();

          while (!visible && tmp != null)
          {
            visible = graph.isCellSelected(tmp);
            tmp = graph.getModel().getParent(tmp);
          }
        }
      }

      mxRectangle dirty = lastDirty;

      lastDirty = preview.show();

      if (dirty != null)
      {
        dirty.add(lastDirty);
      }
      else
      {
        dirty = lastDirty;
      }

      if (dirty != null)
      {
        repaint(dirty);
      }
    }

    if (isHideSelectionHandler())
    {
      graphComponent.getSelectionCellsHandler().setVisible(false);
    }

    fireEvent(new mxEventObject(mxEvent.CONTINUE, "event", e, "dx", dx,
        "dy", dy));
  }

  /**
   *
   */
  protected void repaint(mxRectangle dirty)
  {
    if (dirty != null)
    {
      graphComponent.getGraphControl().repaint(dirty.getRectangle());
    }
    else
    {
      graphComponent.getGraphControl().repaint();
    }
  }

  /**
   *
   */
  protected void reset()
  {
    mxGraph graph = graphComponent.getGraph();

    if (placeholder != null)
    {
      Rectangle tmp = placeholder;
      placeholder = null;
      graphComponent.getGraphControl().repaint(tmp);
    }

    if (isHideSelectionHandler())
    {
      graphComponent.getSelectionCellsHandler().setVisible(true);
    }

    // Revalidates the screen
    // TODO: Should only revalidate moved cells
    if (!isClonePreview() && previewStates != null)
    {
      graph.getView().revalidate();
    }

    previewStates = null;
    movingCells = null;
    startState = null;
    preview = null;

    if (lastDirty != null)
    {
      graphComponent.getGraphControl().repaint(lastDirty.getRectangle());
      lastDirty = null;
    }
  }

  /**
   *
   */
  public Object[] stop(boolean commit, MouseEvent e, double dx, double dy,
      boolean clone, Object target)
  {
    Object[] cells = movingCells;
    reset();

    mxGraph graph = graphComponent.getGraph();
    graph.getModel().beginUpdate();
    try
    {
      if (commit)
      {
        double s = graph.getView().getScale();
        cells = graph.moveCells(cells, dx / s, dy / s, clone, target,
            e.getPoint());
      }

      fireEvent(new mxEventObject(mxEvent.STOP, "event", e, "commit",
          commit));
    }
    finally
    {
      graph.getModel().endUpdate();
    }

    return cells;
  }

  /**
   *
   */
  public void paint(Graphics g)
  {
    if (placeholder != null)
    {
      mxConstants.PREVIEW_BORDER.paintBorder(graphComponent, g,
          placeholder.x, placeholder.y, placeholder.width,
          placeholder.height);
    }

    if (preview != null)
    {
      preview.paint(g);
    }
  }

}
TOP

Related Classes of com.mxgraph.swing.handler.mxMovePreview

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.