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