]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/GridNode.java
G2DParentNode handles "undefined" child bounds separately
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / g2d / nodes / GridNode.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.scenegraph.g2d.nodes;
13
14 import java.awt.BasicStroke;
15 import java.awt.Color;
16 import java.awt.Graphics2D;
17 import java.awt.geom.AffineTransform;
18 import java.awt.geom.Rectangle2D;
19
20 import org.simantics.scenegraph.g2d.G2DNode;
21 import org.simantics.scenegraph.g2d.snap.ISnapAdvisor;
22 import org.simantics.scenegraph.utils.GridUtils;
23
24 /**
25  * @author Tuukka Lehtonen
26  */
27 public class GridNode extends G2DNode {
28
29     /**
30      * Used for naming and identifying (see {@link #setLookupId(String)})
31      * GridNode instances in scene graphs.
32      */
33     public static final String          GRID_NODE_ID     = "grid";
34     
35     private static final long           serialVersionUID = -624916761394994358L;
36
37     protected Boolean                   enabled          = true;
38
39     protected Color                     gridColor        = new Color(0.9f, 0.9f, 0.9f);
40
41     protected double                    gridSize         = 1.0;
42
43     protected ISnapAdvisor              snapAdvisor;
44
45     private transient final BasicStroke stroke           = new BasicStroke(1);
46
47     @SyncField("enabled")
48     public void setEnabled(Boolean enabled) {
49         this.enabled = enabled;
50     }
51
52     @SyncField("gridColor")
53     public void setGridColor(Color color) {
54         this.gridColor = color;
55     }
56
57     @SyncField("gridSize")
58     public void setGridSize(double gridSize) {
59         if (gridSize < 1e-6)
60             gridSize = 1e-6;
61         this.gridSize = gridSize;
62     }
63
64     @SyncField("snapAdvisor")
65     public void setSnapAdvisor(ISnapAdvisor snapAdvisor) {
66         this.snapAdvisor = snapAdvisor;
67     }
68
69     public double getGridSize() {
70         return gridSize;
71     }
72
73     public ISnapAdvisor getSnapAdvisor() {
74         return snapAdvisor;
75     }
76
77     @Override
78     public void render(Graphics2D g2d) {
79         if (!enabled)
80             return;
81
82         AffineTransform ot = g2d.getTransform();
83         
84         double scaleX = Math.abs(ot.getScaleX());
85         double scaleY = Math.abs(ot.getScaleY());
86         if (scaleX <= 0 || scaleY <= 0) {
87             // Make sure that we don't end up in an eternal loop below.
88             return;
89         }
90
91         double offsetX = ot.getTranslateX();
92         double offsetY = ot.getTranslateY();
93         g2d.setTransform(new AffineTransform());
94
95         //g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
96         g2d.setStroke(stroke);
97         if (gridColor != null)
98             g2d.setColor(gridColor);
99
100         Rectangle2D bounds = g2d.getClipBounds();
101         if (bounds == null)
102             return; // FIXME
103
104         double stepX = 50;
105         double stepY = 50;
106
107         //System.out.println("scales : " + scaleX + ", " + scaleY);
108
109         stepX = GridUtils.limitedEvenGridSpacing(stepX, scaleX, 100, gridSize, true);
110         stepY = GridUtils.limitedEvenGridSpacing(stepY, scaleY, 100, gridSize, true);
111
112         //System.out.println("steps 1: " + stepX + ", " + stepY);
113
114         while(stepX * scaleX < 50) stepX *= 2;
115         while(stepY * scaleY < 50) stepY *= 2;
116
117         //System.out.println("steps 2: " + stepX + ", " + stepY);
118
119         if (stepX < gridSize*5)
120             stepX = gridSize*5;
121         if (stepY < gridSize*5)
122             stepY = gridSize*5;
123
124         //System.out.println("steps 2.1: " + stepX + ", " + stepY);
125
126         stepX *= scaleX;
127         stepY *= scaleY;
128
129         //System.out.println("steps 3: " + stepX + ", " + stepY);
130
131         stepX /= 5;
132         stepY /= 5;
133
134         //System.out.println("steps 4: " + stepX + ", " + stepY);
135
136         for(double x = offsetX%stepX; x < bounds.getMaxX(); x+=stepX) {
137             g2d.drawLine((int)x, (int)bounds.getMinY(), (int)x, (int)bounds.getMaxY());
138         }
139
140         for(double y = offsetY%stepY; y < bounds.getMaxY(); y+=stepY) {
141             g2d.drawLine((int)bounds.getMinX(), (int)y, (int)bounds.getMaxX(), (int)y);
142         }
143
144         g2d.setTransform(ot);
145     }
146
147     @Override
148     public Rectangle2D getBoundsInLocal() {
149         return null;
150     }
151
152 }