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