/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * 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: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.scenegraph.g2d.nodes; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import org.simantics.scenegraph.g2d.G2DNode; import org.simantics.scenegraph.g2d.snap.ISnapAdvisor; import org.simantics.scenegraph.utils.GridUtils; /** * @author Tuukka Lehtonen */ public class GridNode extends G2DNode { /** * Used for naming and identifying (see {@link #setLookupId(String)}) * GridNode instances in scene graphs. */ public static final String GRID_NODE_ID = "grid"; private static final long serialVersionUID = -624916761394994358L; protected Boolean enabled = true; protected Color gridColor = new Color(0.9f, 0.9f, 0.9f); protected double gridSize = 1.0; protected ISnapAdvisor snapAdvisor; private transient final BasicStroke stroke = new BasicStroke(1); @SyncField("enabled") public void setEnabled(Boolean enabled) { this.enabled = enabled; } @SyncField("gridColor") public void setGridColor(Color color) { this.gridColor = color; } @SyncField("gridSize") public void setGridSize(double gridSize) { if (gridSize < 1e-6) gridSize = 1e-6; this.gridSize = gridSize; } @SyncField("snapAdvisor") public void setSnapAdvisor(ISnapAdvisor snapAdvisor) { this.snapAdvisor = snapAdvisor; } public double getGridSize() { return gridSize; } public ISnapAdvisor getSnapAdvisor() { return snapAdvisor; } @Override public void render(Graphics2D g2d) { if (!enabled) return; AffineTransform ot = g2d.getTransform(); double scaleX = Math.abs(ot.getScaleX()); double scaleY = Math.abs(ot.getScaleY()); if (scaleX <= 0 || scaleY <= 0) { // Make sure that we don't end up in an eternal loop below. return; } double offsetX = ot.getTranslateX(); double offsetY = ot.getTranslateY(); g2d.setTransform(new AffineTransform()); //g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setStroke(stroke); if (gridColor != null) g2d.setColor(gridColor); Rectangle2D bounds = g2d.getClipBounds(); if (bounds == null) return; // FIXME double stepX = 50; double stepY = 50; //System.out.println("scales : " + scaleX + ", " + scaleY); stepX = GridUtils.limitedEvenGridSpacing(stepX, scaleX, 100, gridSize, true); stepY = GridUtils.limitedEvenGridSpacing(stepY, scaleY, 100, gridSize, true); //System.out.println("steps 1: " + stepX + ", " + stepY); while(stepX * scaleX < 50) stepX *= 2; while(stepY * scaleY < 50) stepY *= 2; //System.out.println("steps 2: " + stepX + ", " + stepY); if (stepX < gridSize*5) stepX = gridSize*5; if (stepY < gridSize*5) stepY = gridSize*5; //System.out.println("steps 2.1: " + stepX + ", " + stepY); stepX *= scaleX; stepY *= scaleY; //System.out.println("steps 3: " + stepX + ", " + stepY); stepX /= 5; stepY /= 5; //System.out.println("steps 4: " + stepX + ", " + stepY); for(double x = offsetX%stepX; x < bounds.getMaxX(); x+=stepX) { g2d.drawLine((int)x, (int)bounds.getMinY(), (int)x, (int)bounds.getMaxY()); } for(double y = offsetY%stepY; y < bounds.getMaxY(); y+=stepY) { g2d.drawLine((int)bounds.getMinX(), (int)y, (int)bounds.getMaxX(), (int)y); } g2d.setTransform(ot); } @Override public Rectangle2D getBoundsInLocal() { return null; } }