]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/SelectionNode.java
445a66fe3e9b5a7d431042c677f7323f12ee1ba5
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / g2d / nodes / SelectionNode.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.utils.GeometryUtils;
22
23 public class SelectionNode extends G2DNode implements Decoration {
24     /**
25      * 
26      */
27     private static final long serialVersionUID = -2879575230419873230L;
28
29     public transient static final BasicStroke SELECTION_STROKE = new BasicStroke(1.0f,
30             BasicStroke.CAP_SQUARE, BasicStroke.CAP_SQUARE, 10.0f,
31             new float[] { 5.0f, 5.0f }, 0.0f);
32
33     protected Rectangle2D bounds = null;
34     protected Color color = null;
35     protected transient Rectangle2D rect;
36     protected transient BasicStroke scaledStroke;
37     protected transient double previousScaleRecip = Double.NaN;
38     private boolean ignore = false;
39
40     public void setIgnore(boolean value) {
41         ignore = value;
42     }
43   
44     @SyncField({"transform", "bounds", "color"})
45     public void init(AffineTransform transform, Rectangle2D bounds, Color color) {
46         this.transform = transform;
47         this.bounds = bounds;
48         this.color = color;
49     }
50
51     @Override
52     public void render(Graphics2D g) {
53         if (bounds == null) return;
54         
55         if (ignore) return;
56
57         // Prevent exceptions during rendering.
58         if (transform.getDeterminant() == 0)
59             return;
60
61         AffineTransform ot = g.getTransform();
62
63         g.setColor(color);
64         g.transform(transform);
65
66         AffineTransform tx = g.getTransform();
67         //System.out.println("tx: " + tx);
68         double scale = GeometryUtils.getScale(tx);
69         //System.out.println("scale: " + scale);
70         double scaleRecip = 1.0 / scale;
71         //System.out.println("scale: " + scaleRecip);
72
73         // Prevent stroke reallocation while panning.
74         // Zooming will trigger reallocation.
75         if (scaledStroke == null || scaleRecip != previousScaleRecip) {
76             scaledStroke = GeometryUtils.scaleStroke( SELECTION_STROKE, (float) scaleRecip);
77             previousScaleRecip = scaleRecip;
78         }
79         g.setStroke(scaledStroke);
80
81         double padding = 5.0 * scaleRecip;
82         double paddingX = padding;
83         double paddingY = padding;
84
85         if (rect == null)
86             rect = new Rectangle2D.Double();
87         rect.setFrame(bounds.getMinX() - paddingX, bounds.getMinY() - paddingY,
88                 bounds.getWidth() + 2.0*paddingX, bounds.getHeight() + 2.0*paddingY);
89         g.draw(rect);
90         
91         g.setTransform(ot);
92
93     }
94     
95     public Rectangle2D getRect() {
96         return transform.createTransformedShape(rect).getBounds2D();
97     }
98
99     @Override
100     public Rectangle2D getBoundsInLocal() {
101         return bounds;
102     }
103 }