1 package org.simantics.diagram.profile;
\r
3 import java.awt.Graphics2D;
\r
4 import java.awt.geom.AffineTransform;
\r
5 import java.awt.geom.Point2D;
\r
6 import java.awt.geom.Rectangle2D;
\r
8 import org.simantics.datatypes.literal.RGB;
\r
9 import org.simantics.datatypes.literal.Vec2d;
\r
10 import org.simantics.diagram.elements.DiagramNodeUtil;
\r
11 import org.simantics.diagram.internal.Activator;
\r
12 import org.simantics.diagram.profile.ButtonResult.A;
\r
13 import org.simantics.diagram.profile.ButtonResult.B;
\r
14 import org.simantics.scenegraph.g2d.G2DNode;
\r
15 import org.simantics.scenegraph.g2d.events.EventTypes;
\r
16 import org.simantics.scenegraph.g2d.events.MouseEvent;
\r
17 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent;
\r
18 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonReleasedEvent;
\r
19 import org.simantics.scenegraph.g2d.nodes.SVGNode;
\r
20 import org.simantics.scenegraph.utils.NodeUtil;
\r
21 import org.simantics.scl.runtime.function.Function1;
\r
23 public class ButtonNode extends IconButtonNode {
\r
25 private static final long serialVersionUID = -1963362069190362275L;
\r
28 private boolean isDown = false;
\r
29 private Function1<Boolean, Boolean> pressed;
\r
31 private static SVGNode ON = new SVGNode();
\r
32 private static SVGNode OFF = new SVGNode();
\r
33 private static boolean initialized = false;
\r
35 Rectangle2D EMPTY = new Rectangle2D.Double(0, 0, 0, 0);
\r
37 private SVGNode current = OFF;
\r
38 private Rectangle2D lastBounds = EMPTY;
\r
40 public void staticInit() {
\r
42 ON.setData(createSVG("BUTTON_ON"));
\r
43 OFF.setData(createSVG("BUTTON_OFF"));
\r
49 public void init() {
\r
51 addEventHandler(this);
\r
55 public void cleanup() {
\r
56 removeEventHandler(this);
\r
60 private void setValue(double value) {
\r
62 // Value does not affect LATCH buttons
\r
63 if(ButtonMode.LATCH.equals(config.mode)) return;
\r
73 private void setConfig(B config) {
\r
75 if(this.config == config) return;
\r
76 this.config = config;
\r
80 public void setA(A data) {
\r
82 setConfig(data.config);
\r
83 setValue(data.value);
\r
88 public void render(Graphics2D g2d) {
\r
90 AffineTransform ot = null;
\r
91 if (!transform.isIdentity()) {
\r
92 ot = g2d.getTransform();
\r
93 g2d.transform(transform);
\r
96 current.render(g2d);
\r
97 lastBounds = current.getBounds();
\r
100 g2d.setTransform(ot);
\r
105 public Rectangle2D getBoundsInLocal() {
\r
110 void setData(IconButtonResult state) {
\r
111 ButtonResult br = (ButtonResult)state;
\r
113 pressed = br.getPressed();
\r
116 private boolean hitTest(MouseEvent event) {
\r
117 Rectangle2D bounds = getBounds();
\r
118 if (bounds == null)
\r
120 Point2D localPos = NodeUtil.worldToLocal(this, event.controlPosition, new Point2D.Double());
\r
121 double x = localPos.getX();
\r
122 double y = localPos.getY();
\r
123 return bounds.contains(x, y);
\r
127 protected boolean mouseButtonPressed(MouseButtonPressedEvent e) {
\r
128 if(!e.hasAnyButton(MouseEvent.LEFT_BUTTON)) return false;
\r
129 if(!hitTest(e)) return false;
\r
130 if(pressed != null) {
\r
131 pressed.apply(true);
\r
133 if(ButtonMode.LATCH.equals(config.mode)) {
\r
135 DiagramNodeUtil.getCanvasContext((G2DNode)this).getContentContext().setDirty();
\r
142 protected boolean mouseButtonReleased(MouseButtonReleasedEvent e) {
\r
143 if(e.hasAnyButton(MouseEvent.LEFT_BUTTON)) return false;
\r
144 if(!hitTest(e) && !isDown) return false;
\r
145 if(pressed != null) {
\r
146 pressed.apply(false);
\r
148 if(ButtonMode.LATCH.equals(config.mode)) {
\r
150 DiagramNodeUtil.getCanvasContext((G2DNode)this).getContentContext().setDirty();
\r
157 public int getEventMask() {
\r
158 return EventTypes.MouseButtonPressedMask
\r
159 | EventTypes.MouseButtonReleasedMask
\r
163 public String createSVG(String iconName) {
\r
164 return Activator.ICON_PROVIDER.apply(iconName, new RGB.Integer(0, 0, 0), new Vec2d(1,1));
\r