package org.simantics.diagram.profile; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import org.simantics.datatypes.literal.RGB; import org.simantics.datatypes.literal.Vec2d; import org.simantics.diagram.elements.SVGNode; import org.simantics.diagram.internal.Activator; import org.simantics.diagram.profile.IconResult.A; import org.simantics.diagram.profile.IconResult.B; public class IconNode extends IconButtonNode { enum Blink { NO, INCREASE, DECREASE } private B config; private SVGNode lo = new SVGNode(); private SVGNode mid = new SVGNode(); private SVGNode hi = new SVGNode(); private SVGNode current; private static final long serialVersionUID = -7850188341977866325L; private IconNode.Blink blink = Blink.NO; private double previousValue = Double.NaN; private long previousValueTime = System.nanoTime(); private void setBlink(IconNode.Blink blink) { // Was turned off if(Blink.NO == blink && Blink.NO != this.blink) Updater.getInstance().unregister(this); // Was turned on if(Blink.NO != blink && Blink.NO == this.blink) Updater.getInstance().register(this); // Record state this.blink = blink; } private void setValue(double value) { if(value < config.loValue) { current = lo; setBlink(Blink.NO); } else if (value > config.hiValue) { current = hi; setBlink(Blink.NO); } else { current = mid; if(value-previousValue > 1e-6) setBlink(Blink.INCREASE); else if(previousValue-value > 1e-6) setBlink(Blink.DECREASE); else setBlink(Blink.NO); } previousValue = value; previousValueTime = System.nanoTime(); } private void setConfig(B config) { if(this.config == config) return; if(config.loColor != null) { String loIcon = createSVG(config.iconName, config.loColor, config.size); lo.setData(loIcon); } if(config.midColor != null) { String midIcon = createSVG(config.iconName, config.midColor, config.size); mid.setData(midIcon); } if(config.hiColor != null) { String hiIcon = createSVG(config.iconName, config.hiColor, config.size); hi.setData(hiIcon); } this.config = config; } public void setA(A data) { setConfig(data.config); setValue(data.value); } @Override public void cleanup() { Updater.getInstance().unregister(this); super.cleanup(); } @Override public void render(Graphics2D g2d) { AffineTransform ot = null; if (!transform.isIdentity()) { ot = g2d.getTransform(); g2d.transform(transform); } if(Blink.NO == blink) { current.render(g2d); } else { long time = Updater.getInstance().getTime(); // Sanity check: turn blink of when no data for 2 seconds. if(time-previousValueTime > 2000000000L) { mid.render(g2d); setBlink(Blink.NO); } else { long halfSeconds = time / 500000000L; if((halfSeconds & 1) == 0) { mid.render(g2d); } else { if(Blink.INCREASE == blink) { hi.render(g2d); } else { lo.render(g2d); } } } } if (ot != null) g2d.setTransform(ot); } Rectangle2D EMPTY = new Rectangle2D.Double(0, 0, 0, 0); @Override public Rectangle2D getBoundsInLocal() { return EMPTY; } @Override void setData(IconButtonResult data) { IconResult ir = (IconResult)data; setA(ir.getA()); } public String createSVG(String iconName, RGB.Integer rgb, Vec2d scale) { return Activator.ICON_PROVIDER.apply(iconName, rgb, scale); } }