Package net.sf.latexdraw.glib.ui

Source Code of net.sf.latexdraw.glib.ui.LMagneticGrid

package net.sf.latexdraw.glib.ui;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.Objects;

import net.sf.latexdraw.glib.models.ShapeFactory;
import net.sf.latexdraw.glib.models.interfaces.shape.IPoint;
import net.sf.latexdraw.glib.views.pst.PSTricksConstants;
import net.sf.latexdraw.ui.ScaleRuler;
import net.sf.latexdraw.ui.ScaleRuler.Unit;
import net.sf.latexdraw.util.LNamespace;
import net.sf.latexdraw.util.LPath;
import net.sf.latexdraw.util.LResources;

import org.malai.preferences.Preferenciable;
import org.malai.properties.Modifiable;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
* This class defines a magnetic grid.<br>
* <br>
* This file is part of LaTeXDraw<br>
* Copyright (c) 2005-2014 Arnaud BLOUIN<br>
* <br>
*  LaTeXDraw is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.<br>
* <br>
*  LaTeXDraw is distributed without any warranty; without even the
*  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
*  PURPOSE. See the GNU General Public License for more details.<br>
* <br>
* 01/21/08<br>
* @author Arnaud BLOUIN
* @version 3.0
*/
public class LMagneticGrid implements Preferenciable, Modifiable {
  /**
   * This enumeration contains the different style
   * of a magnetic grid.
   */
  public enum GridStyle {
    CUSTOMISED {
      @Override
      public String getLabel() {
        return LResources.LABEL_DISPLAY_PERSO_GRID;
      }
    },
    STANDARD {
      @Override
      public String getLabel() {
        return LResources.LABEL_DISPLAY_GRID;
      }
    },
    NONE {
      @Override
      public String getLabel() {
        return "None"; //$NON-NLS-1$
      }
    };

    /**
     * @return The label of the style.
     * @since 3.0
     */
    public abstract String getLabel();


    /**
     * Searches the style which label matches the given name.
     * @param name The name of the style to find.
     * @return The found style or null.
     * @since 3.0
     */
    public static GridStyle getStylefromName(final String name) {
      for(final GridStyle style : values())
        if(style.toString().equals(name))
          return style;
      return null;
    }

    /**
     * Searches the style which label matches the given label. Warning,
     * labels change depending on the language.
     * @param label The label of the style to find.
     * @return The found style or null.
     * @since 3.0
     */
    public static GridStyle getStyleFromLabel(final String label) {
      for(final GridStyle style : values())
        if(style.getLabel().equals(label))
          return style;
      return null;
    }
  }

  /** The stroke of the grid. */
  public static final BasicStroke STROKE = new BasicStroke(0, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER);

  /** Allows to know if the grid is magnetic or not. */
  protected boolean isMagnetic;

  /** defines the spacing between the lines of the grid. */
  protected int gridSpacing;

  /** The style of the grid. */
  protected GridStyle style;

  /** The canvas that paints the grid. */
  protected ICanvas canvas;

  /** Defined if the canvas has been modified. */
  protected boolean modified;


  /**
   * Creates the magnetic grid.
   * @param canvas The canvas in which the grid will work.
   * @throws NullPointerException if the given parameters are not valid.
   * @since 3.1
   */
  public LMagneticGrid(final ICanvas canvas) {
    super();
    modified = false;
    this.canvas  = Objects.requireNonNull(canvas);
    reinitGrid();
  }


  /**
   * Paints the magnetic grid is activated.
   * @param graph The graphics in which the grid will be drawn.
   * @since 3.0
   */
  public void paint(final Graphics2D graph) {
    if(!isGridDisplayed()) return;
    final Rectangle clip = graph.getClipBounds();
    if(clip==null) return;

    graph.setColor(Color.BLACK);
    graph.setStroke(STROKE);

    switch(style) {
      case STANDARD:
        double ppc = canvas.getPPCDrawing();
        if(ScaleRuler.getUnit()==Unit.INCH)
          ppc*=PSTricksConstants.INCH_VAL_CM;

        paintSubLines(graph, clip);
        paintMainLines(graph, ppc, clip);
        break;
      case CUSTOMISED:
        paintMainLines(graph, gridSpacing, clip);
        break;
      case NONE: break;
    }
  }



  protected void paintSubLines(final Graphics2D graph, final Rectangle clip) {
    double pixPerCm10 = canvas.getPPCDrawing()*canvas.getZoom()/10.;
    if(ScaleRuler.getUnit()==Unit.INCH)
      pixPerCm10*=PSTricksConstants.INCH_VAL_CM;

    if(Double.compare(pixPerCm10, 4.)>0) {
      final Line2D line = new Line2D.Double();
      final double xMinclip = Math.floor(clip.getMinX()/pixPerCm10)*pixPerCm10-clip.getMinX();
      final double yMinclip = Math.floor(clip.getMinY()/pixPerCm10)*pixPerCm10-clip.getMinY();
      final double xMaxclip = clip.getMaxX();
      final double yMaxclip = clip.getMaxY();
      final double minX     = clip.getMinX();
      final double minY    = clip.getMinY();

        for(double i=pixPerCm10-1+xMinclip+minX+canvas.getOrigin().getX()%pixPerCm10; i<xMaxclip; i+=pixPerCm10) {
        line.setLine(i, minY, i, yMaxclip);
        graph.draw(line);
      }

        for(double i=pixPerCm10-1+yMinclip+minY+canvas.getOrigin().getY()%pixPerCm10; i<yMaxclip; i+=pixPerCm10) {
        line.setLine(minX, i, xMaxclip, i);
        graph.draw(line);
      }
      }
  }



  protected void paintMainLines(final Graphics2D graph, final double gap, final Rectangle clip) {
    final double gap2     = gap*canvas.getZoom();
    final double xMinclip = Math.floor(clip.getMinX()/gap2)*gap2-clip.getMinX();
    final double yMinclip = Math.floor(clip.getMinY()/gap2)*gap2-clip.getMinY();
    final double xMaxclip = clip.getMaxX();
    final double yMaxclip = clip.getMaxY();
    final double minX     = clip.getMinX();
    final double minY    = clip.getMinY();
    final Line2D line     = new Line2D.Double();

    for(double i=gap2-1+xMinclip+minX+canvas.getOrigin().getX()%gap2; i<xMaxclip; i+=gap2) {
      line.setLine(i, minY, i, yMaxclip);
      graph.draw(line);
    }

    for(double j=gap2-1+yMinclip+minY+canvas.getOrigin().getY()%gap2; j<yMaxclip; j+=gap2) {
      line.setLine(minX, j, xMaxclip, j);
      graph.draw(line);
    }
  }


  /**
   * Transform a point to another "stick" to the magnetic grid.
   * @since 1.8
   * @param pt The point to transform.
   * @return The transformed point or if there is no magnetic grid, a clone of the given point.
   */
  public IPoint getTransformedPointToGrid(final Point2D pt) {
       if(isMagnetic() && isGridDisplayed()) {
         final IPoint point  = ShapeFactory.createPoint(pt.getX(), pt.getY());
        final double modulo = getMagneticGridGap();
        double x     = point.getX();
        double y     = point.getY();
        int base     = (int)((int)(x/modulo)*modulo);

        if(x>modulo) x %= (int) modulo;

        double res = modulo-x;
        x = base;

        if(res<modulo/2.) x+=modulo;

        point.setX((int)x);
        base = (int)((int)(point.getY()/modulo)*modulo);

        if(y>modulo) y %= (int) modulo;

        res = modulo-y;
        y = base;

        if(res<modulo/2.) y+=modulo;

        point.setY((int)y);

        return point;
      }

       return ShapeFactory.createPoint(pt.getX(), pt.getY());
  }



  /**
   * @return The gap between the lines of the magnetic grid.
   * @since 1.9
   */
  public double getMagneticGridGap() {
    double gap;

    if(isPersonalGrid())
      gap = getGridSpacing();
    else {
      final double ppc = canvas.getPPCDrawing();
      gap = ScaleRuler.getUnit()==Unit.CM ? ppc/10. : ppc*PSTricksConstants.INCH_VAL_CM/10.;
      gap = gap-(int)gap>0.5? (int)gap+1 : (int)gap;
    }

    return gap;
  }


  /**
   * Reinitialises the magnetic grid.
   * @since 3.0
   */
  public void reinitGrid() {
    setStyle(GridStyle.CUSTOMISED);
    setGridSpacing(20);
    setMagnetic(true);
  }


  /**
   * @return True: the grid is magnetic.
   * @since 2.0.0
   */
  public boolean isMagnetic() {
    return isMagnetic;
  }


  /**
   * @param isMagnetic True: the grid will be magnetic.
   * @since 2.0.0
   */
  public void setMagnetic(final boolean isMagnetic) {
    if(this.isMagnetic!=isMagnetic) {
      this.isMagnetic = isMagnetic;
      setModified(true);
    }
  }


  /**
   * @return The new spacing between lines of the personal grid.
   * @since 3.0
   */
  public int getGridSpacing() {
    return gridSpacing;
  }


  /**
   * @param gridSpacing The new spacing between lines of the personal grid.
   * @since 3.0
   */
  public void setGridSpacing(final int gridSpacing) {
    if(gridSpacing>1 && this.gridSpacing!=gridSpacing) {
      this.gridSpacing = gridSpacing;
      setModified(true);
    }
  }


  /**
   * @return True: the grid is magnetic.
   * @since 2.0.0
   */
  public boolean isPersonalGrid() {
    return style==GridStyle.CUSTOMISED;
  }


  /**
   * @return The style of the magnetic grid.
   * @since 2.0.0
   */
  public GridStyle getStyle() {
    return style;
  }


  /**
   * @param style The new style of the grid. If null, nothing is performed.
   * @since 3.0
   */
  public void setStyle(final GridStyle style) {
    if(style!=null && style!=this.style) {
      this.style = style;
      setModified(true);
    }
  }


  /**
   * @return True: The magnetic grid must be displayed.
   * @since 2.0.0
   */
  public boolean isGridDisplayed() {
    return style!=GridStyle.NONE;
  }

  @Override
  public void setModified(final boolean modified) {
    this.modified = modified;
  }

  @Override
  public boolean isModified() {
    return modified;
  }

  @Override
  public void save(final boolean generalPreferences, final String nsURI, final Document document, final Element root) {
    if(document==null || root==null) return ;

    final String ns = generalPreferences ? "" : LPath.INSTANCE.getNormaliseNamespaceURI(nsURI); //$NON-NLS-1$
    Element elt = document.createElement(ns + LNamespace.XML_MAGNETIC_GRID_STYLE);
        elt.setTextContent(getStyle().toString());
        root.appendChild(elt);
        elt = document.createElement(ns + LNamespace.XML_GRID_GAP);
        elt.setTextContent(String.valueOf(getGridSpacing()));
        root.appendChild(elt);
        elt = document.createElement(ns + LNamespace.XML_MAGNETIC_GRID);
        elt.setTextContent(String.valueOf(isMagnetic()));
        root.appendChild(elt);
  }


  @Override
  public void load(final boolean generalPreferences, final String nsURI, final Element meta) {
    final NodeList nl = meta.getChildNodes();
    final String uri = nsURI==null ? "" : nsURI; //$NON-NLS-1$
    Node node;
    String name;

    for(int i=0, size=nl.getLength(); i<size; i++) {
      node = nl.item(i);

      // Must be a latexdraw tag.
      if(node!=null && uri.equals(node.getNamespaceURI())) {
        name = node.getNodeName();

        if(name.endsWith(LNamespace.XML_GRID_GAP))
          setGridSpacing(Integer.parseInt(node.getTextContent()));
        else if(name.endsWith(LNamespace.XML_MAGNETIC_GRID))
          setMagnetic(Boolean.parseBoolean(node.getTextContent()));
        else if(name.endsWith(LNamespace.XML_MAGNETIC_GRID_STYLE))
          setStyle(GridStyle.getStylefromName(node.getTextContent()));
        // To keep compatibility with latexdraw 2.0
        //TODO to remove with these tokens in a future release (in a couple of years).
        else if(name.endsWith(LNamespace.XML_DISPLAY_GRID)) {
          if(!Boolean.parseBoolean(node.getTextContent()))
            setStyle(GridStyle.NONE);
        } else if(name.endsWith(LNamespace.XML_CLASSIC_GRID))
          setStyle(Boolean.parseBoolean(node.getTextContent()) ? GridStyle.STANDARD : GridStyle.CUSTOMISED);
      }
    }
  }
}
TOP

Related Classes of net.sf.latexdraw.glib.ui.LMagneticGrid

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.