]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/SingleElementNode.java
Render elements using custom color filters
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / g2d / nodes / SingleElementNode.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.Composite;
16 import java.awt.Graphics2D;
17 import java.awt.geom.Point2D;
18 import java.awt.geom.Rectangle2D;
19 import java.util.Map;
20
21 import org.simantics.scenegraph.INode;
22 import org.simantics.scenegraph.g2d.G2DRenderingHints;
23 import org.simantics.scenegraph.g2d.IG2DNode;
24 import org.simantics.scenegraph.g2d.color.ColorFilter;
25 import org.simantics.scenegraph.g2d.color.Graphics2DWithColorFilter;
26 import org.simantics.scenegraph.g2d.events.EventTypes;
27 import org.simantics.scenegraph.g2d.events.MouseEvent;
28 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDragBegin;
29 import org.simantics.scenegraph.utils.InitValueSupport;
30 import org.simantics.scenegraph.utils.NodeUtil;
31
32 public class SingleElementNode extends TransformNode implements InitValueSupport {
33
34     private static final long serialVersionUID = -4982578347433716440L;
35
36     private TransferableProvider transferableProvider;
37     protected Composite composite;
38     private ColorFilter colorFilter;
39     protected Boolean visible = Boolean.TRUE;
40     protected Boolean hidden = Boolean.FALSE;
41     private transient Object key;
42     private transient String typeClass;
43     private transient Map<String, Object> parameters;
44
45     public void setKey(Object key) {
46         this.key = key;
47     }
48
49     public void setTypeClass(String typeClass) {
50         this.typeClass = typeClass;
51     }
52
53     public Object getKey() {
54         return key;
55     }
56
57     public String getTypeClass() {
58         return typeClass;
59     }
60
61     public void setParameters(Map<String,Object> parameters) {
62         this.parameters = parameters;
63     }
64
65     public <T> T getParameter(String key) {
66         if (parameters != null) {
67             @SuppressWarnings("unchecked")
68             T t = (T) parameters.get(key);
69             if(t != null) return t;
70         }
71         INode parent = NodeUtil.getNearestParentOfType(this, SingleElementNode.class);
72         if (parent instanceof SingleElementNode) {
73             return ((SingleElementNode)parent).getParameter(key);
74         }
75         return null;
76     }
77
78     public void setTransferableProvider(TransferableProvider transferableProvider) {
79         if (transferableProvider != this.transferableProvider) {
80             if (this.transferableProvider != null)
81                 removeEventHandler(this);
82             if (transferableProvider != null)
83                 addEventHandler(this);
84             this.transferableProvider = transferableProvider;
85         }
86     }
87
88     @Override
89     public boolean validate() {
90         return visible && !hidden;
91     }
92
93     @SyncField("composite")
94     public void setComposite(Composite composite) {
95         this.composite = composite;
96     }
97     
98     public void setColorFilter(ColorFilter colorFilter) {
99         this.colorFilter = colorFilter;
100     }
101
102     @SyncField("visible")
103     public void setVisible(Boolean visible) {
104         this.visible = visible;
105     }
106
107     public boolean isVisible() {
108         return visible;
109     }
110
111     @SyncField("hidden")
112     public void setHidden(Boolean hidden) {
113         this.hidden = hidden;
114     }
115
116     public boolean isHidden() {
117         return hidden;
118     }
119
120     @Override
121     public void render(Graphics2D g2d) {
122         if (!visible || hidden)
123             return;
124
125         Graphics2D g;
126         if (colorFilter != null) {
127             g = new Graphics2DWithColorFilter(g2d, colorFilter);
128             g.setRenderingHint(G2DRenderingHints.KEY_COLOR_FILTER, colorFilter);
129         } else {
130             g = g2d;
131         }
132
133         Composite oldComposite = null;
134         if(composite != null) {
135             oldComposite = g.getComposite();
136             g.setComposite(composite);
137         }
138         if(alphaComposite != null) {
139             if (oldComposite == null)
140                 oldComposite = g.getComposite();
141             g.setComposite(alphaComposite);
142         }
143
144         super.render(g);
145
146         if (oldComposite != null)
147             g.setComposite(oldComposite);
148
149         if (colorFilter != null) {
150             g.setRenderingHint(G2DRenderingHints.KEY_COLOR_FILTER, null);
151         }
152     }
153
154     @Override
155     public String toString() {
156         StringBuilder sb = new StringBuilder();
157         sb.append(super.toString());
158         sb.append(" [");
159         if (composite != null) {
160             sb.append("composite=(");
161             AlphaComposite ac = (AlphaComposite) composite;
162             sb.append(ac.getRule());
163             sb.append(", ");
164             sb.append(ac.getAlpha());
165             sb.append("), ");
166         }
167         sb.append("visible=");
168         sb.append(visible);
169         sb.append("]");
170         return sb.toString();
171     }
172
173     protected Composite alphaComposite = null;
174
175     @PropertySetter("alpha")
176     @SyncField("alphaComposite")
177     public void setAlphaComposite(Composite alphaComposite) {
178         this.alphaComposite = alphaComposite;
179     }
180
181     @Override
182     public void initValues() {
183         alphaComposite = null;
184         for (IG2DNode node : getSortedNodes()) {
185             if (node instanceof InitValueSupport) {
186                 ((InitValueSupport) node).initValues();
187             }
188         }
189     }
190
191     @Override
192     public void cleanup() {
193         if (transferableProvider != null) {
194             removeEventHandler(this);
195             transferableProvider = null;
196         }
197         super.cleanup();
198     }
199
200     protected boolean isDragStartEvent(MouseEvent e) {
201         return e.isControlDown();
202     }
203
204     protected boolean hitTest(MouseEvent event) {
205         Rectangle2D bounds = super.getBoundsInLocal(true);
206         if (bounds == null)
207             return false;
208         Point2D localPos = NodeUtil.worldToLocal(this, event.controlPosition, new Point2D.Double());
209         double x = localPos.getX();
210         double y = localPos.getY();
211         boolean hit = bounds.contains(x, y);
212         return hit;
213     }
214
215     @Override
216     protected boolean mouseDragged(MouseDragBegin e) {
217         if (transferableProvider == null
218                 || !isDragStartEvent(e)
219                 || !hitTest(e))
220             return false;
221         e.transferable = transferableProvider.create();
222         return e.transferable != null;
223     }
224
225     @Override
226     public int getEventMask() {
227         return EventTypes.MouseDragBeginMask;
228     }
229
230     public void beforeRender(Graphics2D g) {
231         g.setRenderingHint(G2DRenderingHints.KEY_BEGIN_ELEMENT, "definedElement");
232     }
233
234     public void afterRender(Graphics2D g) {
235         g.setRenderingHint(G2DRenderingHints.KEY_END_ELEMENT, "definedElement");
236     }
237
238 }