-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.g2d.diagram.participant;\r
-\r
-import java.awt.BasicStroke;\r
-import java.awt.Color;\r
-import java.awt.Shape;\r
-import java.awt.Stroke;\r
-import java.awt.geom.AffineTransform;\r
-import java.awt.geom.Path2D;\r
-import java.awt.geom.Rectangle2D;\r
-import java.util.Collection;\r
-import java.util.List;\r
-\r
-import org.simantics.g2d.canvas.ICanvasContext;\r
-import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;\r
-import org.simantics.g2d.canvas.impl.SGNodeReflection.SGCleanup;\r
-import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;\r
-import org.simantics.g2d.diagram.IDiagram;\r
-import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor;\r
-import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil;\r
-import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil.TerminalInfo;\r
-import org.simantics.g2d.participant.MouseUtil;\r
-import org.simantics.g2d.participant.TransformUtil;\r
-import org.simantics.g2d.participant.MouseUtil.MouseInfo;\r
-import org.simantics.g2d.utils.GeometryUtils;\r
-import org.simantics.scenegraph.g2d.G2DParentNode;\r
-import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;\r
-import org.simantics.scenegraph.g2d.nodes.ShapeNode;\r
-import org.simantics.scenegraph.utils.ColorUtil;\r
-import org.simantics.utils.datastructures.hints.HintListenerAdapter;\r
-import org.simantics.utils.datastructures.hints.IHintListener;\r
-import org.simantics.utils.datastructures.hints.IHintObservable;\r
-import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
-import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;\r
-\r
-/**\r
- * Paints terminals of elements.\r
- *\r
- * @author Toni Kalajainen\r
- */\r
-public class TerminalPainter extends AbstractDiagramParticipant {\r
-\r
- public static final int PAINT_PRIORITY = ElementPainter.ELEMENT_PAINT_PRIORITY + 10;\r
-\r
- public interface TerminalHoverStrategy {\r
- /**\r
- * \r
- * @return <code>true</code> if highlighting is enabled at the moment in\r
- * general. This may depend on the current modifier key state\r
- * for example.\r
- */\r
- boolean highlightEnabled();\r
-\r
- /**\r
- * Checks whether the specified terminal should be highlighted at the\r
- * moment or not. Whether to highlight or not may depend for example on\r
- * the current modifier key state.\r
- * \r
- * @param ti\r
- * @return\r
- */\r
- boolean highlight(TerminalInfo ti);\r
- };\r
-\r
- public static abstract class ChainedHoverStrategy implements TerminalHoverStrategy {\r
- TerminalHoverStrategy orig;\r
- public ChainedHoverStrategy(TerminalHoverStrategy orig) {\r
- this.orig = orig;\r
- }\r
- @Override\r
- public boolean highlightEnabled() {\r
- return orig == null ? false : orig.highlightEnabled();\r
- }\r
- @Override\r
- public final boolean highlight(TerminalInfo ti) {\r
- boolean ret = canHighlight(ti);\r
- return (ret || orig == null) ? ret : orig.highlight(ti);\r
- }\r
- public abstract boolean canHighlight(TerminalInfo ti);\r
- }\r
-\r
- /**\r
- * If this hint is set to a Callable<Boolean>, the terminal painter will use\r
- * the callable to evaluate whether it should highlight terminal hovers or\r
- * not.\r
- */\r
- public static final Key TERMINAL_HOVER_STRATEGY = new KeyOf(TerminalHoverStrategy.class);\r
-\r
-// private static final Stroke STROKE1 = new BasicStroke(1.0f);\r
-// private static final Stroke STROKE15 = new BasicStroke(1.5f);\r
- private static final Stroke STROKE25 = new BasicStroke(2.5f);\r
-\r
-// private final static Stroke TERMINAL_STROKE = new BasicStroke(1.0f);\r
- public static final Shape TERMINAL_SHAPE;\r
-\r
- @Dependency\r
- protected TransformUtil util;\r
- @Dependency\r
- protected MouseUtil mice;\r
- \r
- @Dependency\r
- protected PointerInteractor pointerInteractor;\r
-\r
- protected boolean paintPointTerminals;\r
- protected boolean paintAreaTerminals;\r
- protected boolean paintHoverPointTerminals;\r
- protected boolean paintHoverAreaTerminals;\r
-\r
- public TerminalPainter(boolean paintPointTerminals, boolean paintHoverPointTerminals, boolean paintAreaTerminals, boolean paintHoverAreaTerminals)\r
- {\r
- this.paintAreaTerminals = paintAreaTerminals;\r
- this.paintPointTerminals = paintPointTerminals;\r
- this.paintHoverAreaTerminals = paintHoverAreaTerminals;\r
- this.paintHoverPointTerminals = paintHoverPointTerminals;\r
- }\r
-\r
- @Override\r
- public void addedToContext(ICanvasContext ctx) {\r
- super.addedToContext(ctx);\r
-\r
- ctx.getHintStack().addKeyHintListener(getContext().getThreadAccess(), TERMINAL_HOVER_STRATEGY, hoverStrategyListener);\r
- }\r
-\r
- @Override\r
- public void removedFromContext(ICanvasContext ctx) {\r
- ctx.getHintStack().removeKeyHintListener(getContext().getThreadAccess(), TERMINAL_HOVER_STRATEGY, hoverStrategyListener);\r
-\r
- super.removedFromContext(ctx);\r
- }\r
-\r
- public boolean highlightEnabled() {\r
- TerminalHoverStrategy strategy = getHint(TERMINAL_HOVER_STRATEGY);\r
- return strategy != null ? strategy.highlightEnabled() : true;\r
- }\r
-\r
- public boolean highlightTerminal(TerminalInfo ti) {\r
- TerminalHoverStrategy strategy = getHint(TERMINAL_HOVER_STRATEGY);\r
- return strategy != null ? strategy.highlight(ti) : true;\r
- }\r
-\r
- @EventHandler(priority = 0)\r
- public boolean handleMove(MouseMovedEvent me) {\r
- if ( (paintHoverAreaTerminals && paintAreaTerminals) ||\r
- (paintHoverPointTerminals && paintPointTerminals) ) {\r
- update(highlightEnabled());\r
- }\r
- return false;\r
- }\r
-\r
- protected G2DParentNode node = null;\r
-\r
- @SGInit\r
- public void initSG(G2DParentNode parent) {\r
- node = parent.addNode("hovering terminals", G2DParentNode.class);\r
- node.setZIndex(PAINT_PRIORITY);\r
- }\r
-\r
- @SGCleanup\r
- public void cleanupSG() {\r
- node.remove();\r
- node = null;\r
- }\r
-\r
- public void update(boolean enabled) {\r
- if (isRemoved())\r
- return;\r
-\r
- boolean repaint = false;\r
- if(node == null) return;\r
- if(node.getNodeCount() > 0) {\r
- node.removeNodes();\r
- repaint = true;\r
- }\r
- if (enabled) {\r
-\r
- // Paint terminals normally\r
- if (paintAreaTerminals || paintPointTerminals) {\r
- List<TerminalInfo> pickedTerminals = TerminalUtil.pickTerminals(diagram, null, paintPointTerminals, paintAreaTerminals);\r
- paintTerminals(node, Color.BLUE, diagram, null, pickedTerminals, null);\r
- if(pickedTerminals.size() > 0) repaint = true;\r
- }\r
-\r
- if (paintHoverAreaTerminals || paintHoverPointTerminals) {\r
- TerminalHoverStrategy strategy = getHint(TERMINAL_HOVER_STRATEGY);\r
-\r
- AffineTransform invTx = util.getInverseTransform();\r
- if (invTx == null) {\r
- System.err.println("NO CANVAS TRANSFORM INVERSE AVAILABLE, CANVAS TRANSFORM IS: " + util.getTransform());\r
- return;\r
- }\r
-\r
- // Pick terminals\r
- for (MouseInfo mi : mice.getMiceInfo().values()) {\r
- Rectangle2D controlPickRect = getPickRectangle(mi.controlPosition.getX(), mi.controlPosition.getY());\r
- Shape canvasPickRect = GeometryUtils.transformShape(controlPickRect, invTx);\r
-\r
- List<TerminalInfo> tis = TerminalUtil.pickTerminals(diagram, canvasPickRect, paintHoverAreaTerminals, paintHoverPointTerminals);\r
- paintTerminals(node, Color.RED, diagram, canvasPickRect.getBounds2D(), tis, strategy);\r
- if(tis.size() > 0) repaint = true;\r
- }\r
- }\r
- }\r
- if (repaint) {\r
- setDirty();\r
- }\r
- }\r
-\r
- public void paintTerminals(G2DParentNode parent, Color color, IDiagram diagram, Rectangle2D pickRect, Collection<TerminalInfo> tis, TerminalHoverStrategy strategy) {\r
- if (tis.isEmpty()) {\r
- return;\r
- }\r
- G2DParentNode node = parent.getOrCreateNode(""+tis.hashCode(), G2DParentNode.class);\r
-\r
- double minDist = Double.MAX_VALUE;\r
- double maxDist = 0;\r
- TerminalInfo nearest = null;\r
- if (pickRect != null) {\r
- for (TerminalInfo ti : tis) {\r
- double dx = ti.posDia.getTranslateX() - pickRect.getCenterX();\r
- double dy = ti.posDia.getTranslateY() - pickRect.getCenterY();\r
- double dist = Math.sqrt(dx*dx+dy*dy);\r
- if (dist > maxDist) {\r
- maxDist = dist;\r
- }\r
- if (dist < minDist) {\r
- minDist = dist;\r
- nearest = ti;\r
- }\r
- }\r
- }\r
-\r
- for (TerminalInfo ti : tis) {\r
- if (strategy != null && !strategy.highlight(ti))\r
- continue;\r
- Shape shape = ti.shape != null ? ti.shape : getTerminalShape();\r
- //System.out.println("painting terminal " + ti + ": " + shape);\r
- ShapeNode sn = node.getOrCreateNode("terminal_"+ti.hashCode(), ShapeNode.class);\r
- sn.setShape(shape);\r
- sn.setStroke(STROKE25);\r
- sn.setScaleStroke(true);\r
- if (pickRect != null) {\r
- Color blendedColor = color;\r
- if (ti != nearest) {\r
- double dx = ti.posDia.getTranslateX() - pickRect.getCenterX();\r
- double dy = ti.posDia.getTranslateY() - pickRect.getCenterY();\r
- double dist = Math.sqrt(dx*dx+dy*dy);\r
- double normalizedDistance = dist / maxDist;\r
- final double maxFade = 0.5;\r
- float alpha = (float)(1 - normalizedDistance*maxFade);\r
- blendedColor = ColorUtil.withAlpha(ColorUtil.blend(color, Color.WHITE, normalizedDistance*maxFade), alpha);\r
- }\r
- sn.setColor(blendedColor);\r
- } else {\r
- sn.setColor(color);\r
- }\r
- sn.setTransform(ti.posDia);\r
- sn.setFill(false);\r
- }\r
- }\r
- \r
- public Rectangle2D getTerminalShape() {\r
- double pickDist = pointerInteractor.getPickDistance();\r
- return new Rectangle2D.Double(-pickDist - 0.5, -pickDist - 0.5, pickDist * 2 + 1, pickDist * 2 + 1);\r
- }\r
- \r
- public Rectangle2D getPickRectangle(double x, double y) {\r
- double pickDist = pointerInteractor.getPickDistance();\r
- Rectangle2D controlPickRect = new Rectangle2D.Double(x-pickDist, y-pickDist, pickDist*2+1, pickDist*2+1);\r
- return controlPickRect;\r
- }\r
-\r
- static {\r
- Path2D.Double cross = new Path2D.Double();\r
- double s = 2;\r
- cross.moveTo(-s, -s);\r
- cross.lineTo(s, s);\r
- cross.moveTo(-s, s);\r
- cross.lineTo(s, -s);\r
- TERMINAL_SHAPE = cross;\r
- }\r
-\r
- IHintListener hoverStrategyListener = new HintListenerAdapter() {\r
- @Override\r
- public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {\r
- hoverStrategyChanged((TerminalHoverStrategy) newValue);\r
- }\r
- };\r
-\r
- protected void hoverStrategyChanged(TerminalHoverStrategy strategy) {\r
- update(strategy != null ? strategy.highlightEnabled() : false);\r
- }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.g2d.diagram.participant;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Path2D;
+import java.awt.geom.Rectangle2D;
+import java.util.Collection;
+import java.util.List;
+
+import org.simantics.g2d.canvas.ICanvasContext;
+import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;
+import org.simantics.g2d.canvas.impl.SGNodeReflection.SGCleanup;
+import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;
+import org.simantics.g2d.diagram.IDiagram;
+import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor;
+import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil;
+import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil.TerminalInfo;
+import org.simantics.g2d.participant.MouseUtil;
+import org.simantics.g2d.participant.TransformUtil;
+import org.simantics.g2d.participant.MouseUtil.MouseInfo;
+import org.simantics.g2d.utils.GeometryUtils;
+import org.simantics.scenegraph.g2d.G2DParentNode;
+import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;
+import org.simantics.scenegraph.g2d.nodes.ShapeNode;
+import org.simantics.scenegraph.utils.ColorUtil;
+import org.simantics.utils.datastructures.hints.HintListenerAdapter;
+import org.simantics.utils.datastructures.hints.IHintListener;
+import org.simantics.utils.datastructures.hints.IHintObservable;
+import org.simantics.utils.datastructures.hints.IHintContext.Key;
+import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Paints terminals of elements.
+ *
+ * @author Toni Kalajainen
+ */
+public class TerminalPainter extends AbstractDiagramParticipant {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(TerminalPainter.class);
+ public static final int PAINT_PRIORITY = ElementPainter.ELEMENT_PAINT_PRIORITY + 10;
+
+ public interface TerminalHoverStrategy {
+ /**
+ *
+ * @return <code>true</code> if highlighting is enabled at the moment in
+ * general. This may depend on the current modifier key state
+ * for example.
+ */
+ boolean highlightEnabled();
+
+ /**
+ * Checks whether the specified terminal should be highlighted at the
+ * moment or not. Whether to highlight or not may depend for example on
+ * the current modifier key state.
+ *
+ * @param ti
+ * @return
+ */
+ boolean highlight(TerminalInfo ti);
+ };
+
+ public static abstract class ChainedHoverStrategy implements TerminalHoverStrategy {
+ TerminalHoverStrategy orig;
+ public ChainedHoverStrategy(TerminalHoverStrategy orig) {
+ this.orig = orig;
+ }
+ @Override
+ public boolean highlightEnabled() {
+ return orig == null ? false : orig.highlightEnabled();
+ }
+ @Override
+ public final boolean highlight(TerminalInfo ti) {
+ boolean ret = canHighlight(ti);
+ return (ret || orig == null) ? ret : orig.highlight(ti);
+ }
+ public abstract boolean canHighlight(TerminalInfo ti);
+ }
+
+ /**
+ * If this hint is set to a Callable<Boolean>, the terminal painter will use
+ * the callable to evaluate whether it should highlight terminal hovers or
+ * not.
+ */
+ public static final Key TERMINAL_HOVER_STRATEGY = new KeyOf(TerminalHoverStrategy.class);
+
+// private static final Stroke STROKE1 = new BasicStroke(1.0f);
+// private static final Stroke STROKE15 = new BasicStroke(1.5f);
+ private static final Stroke STROKE25 = new BasicStroke(2.5f);
+
+// private final static Stroke TERMINAL_STROKE = new BasicStroke(1.0f);
+ public static final Shape TERMINAL_SHAPE;
+
+ @Dependency
+ protected TransformUtil util;
+ @Dependency
+ protected MouseUtil mice;
+
+ @Dependency
+ protected PointerInteractor pointerInteractor;
+
+ protected boolean paintPointTerminals;
+ protected boolean paintAreaTerminals;
+ protected boolean paintHoverPointTerminals;
+ protected boolean paintHoverAreaTerminals;
+
+ public TerminalPainter(boolean paintPointTerminals, boolean paintHoverPointTerminals, boolean paintAreaTerminals, boolean paintHoverAreaTerminals)
+ {
+ this.paintAreaTerminals = paintAreaTerminals;
+ this.paintPointTerminals = paintPointTerminals;
+ this.paintHoverAreaTerminals = paintHoverAreaTerminals;
+ this.paintHoverPointTerminals = paintHoverPointTerminals;
+ }
+
+ @Override
+ public void addedToContext(ICanvasContext ctx) {
+ super.addedToContext(ctx);
+
+ ctx.getHintStack().addKeyHintListener(getContext().getThreadAccess(), TERMINAL_HOVER_STRATEGY, hoverStrategyListener);
+ }
+
+ @Override
+ public void removedFromContext(ICanvasContext ctx) {
+ ctx.getHintStack().removeKeyHintListener(getContext().getThreadAccess(), TERMINAL_HOVER_STRATEGY, hoverStrategyListener);
+
+ super.removedFromContext(ctx);
+ }
+
+ public boolean highlightEnabled() {
+ TerminalHoverStrategy strategy = getHint(TERMINAL_HOVER_STRATEGY);
+ return strategy != null ? strategy.highlightEnabled() : true;
+ }
+
+ public boolean highlightTerminal(TerminalInfo ti) {
+ TerminalHoverStrategy strategy = getHint(TERMINAL_HOVER_STRATEGY);
+ return strategy != null ? strategy.highlight(ti) : true;
+ }
+
+ @EventHandler(priority = 0)
+ public boolean handleMove(MouseMovedEvent me) {
+ if ( (paintHoverAreaTerminals && paintAreaTerminals) ||
+ (paintHoverPointTerminals && paintPointTerminals) ) {
+ update(highlightEnabled());
+ }
+ return false;
+ }
+
+ protected G2DParentNode node = null;
+
+ @SGInit
+ public void initSG(G2DParentNode parent) {
+ node = parent.addNode("hovering terminals", G2DParentNode.class);
+ node.setZIndex(PAINT_PRIORITY);
+ }
+
+ @SGCleanup
+ public void cleanupSG() {
+ node.remove();
+ node = null;
+ }
+
+ public void update(boolean enabled) {
+ if (isRemoved())
+ return;
+
+ boolean repaint = false;
+ if(node == null) return;
+ if(node.getNodeCount() > 0) {
+ node.removeNodes();
+ repaint = true;
+ }
+ if (enabled) {
+
+ // Paint terminals normally
+ if (paintAreaTerminals || paintPointTerminals) {
+ List<TerminalInfo> pickedTerminals = TerminalUtil.pickTerminals(getContext(), diagram, null, paintPointTerminals, paintAreaTerminals);
+ paintTerminals(node, Color.BLUE, diagram, null, pickedTerminals, null);
+ if(pickedTerminals.size() > 0) repaint = true;
+ }
+
+ if (paintHoverAreaTerminals || paintHoverPointTerminals) {
+ TerminalHoverStrategy strategy = getHint(TERMINAL_HOVER_STRATEGY);
+
+ AffineTransform invTx = util.getInverseTransform();
+ if (invTx == null) {
+ LOGGER.warn("NO CANVAS TRANSFORM INVERSE AVAILABLE, CANVAS TRANSFORM IS: " + util.getTransform());
+ return;
+ }
+
+ // Pick terminals
+ for (MouseInfo mi : mice.getMiceInfo().values()) {
+ Rectangle2D controlPickRect = getPickRectangle(mi.controlPosition.getX(), mi.controlPosition.getY());
+ Shape canvasPickRect = GeometryUtils.transformShape(controlPickRect, invTx);
+
+ List<TerminalInfo> tis = TerminalUtil.pickTerminals(getContext(), diagram, canvasPickRect, paintHoverAreaTerminals, paintHoverPointTerminals);
+ paintTerminals(node, Color.RED, diagram, canvasPickRect.getBounds2D(), tis, strategy);
+ if(tis.size() > 0) repaint = true;
+ }
+ }
+ }
+ if (repaint) {
+ setDirty();
+ }
+ }
+
+ public void paintTerminals(G2DParentNode parent, Color color, IDiagram diagram, Rectangle2D pickRect, Collection<TerminalInfo> tis, TerminalHoverStrategy strategy) {
+ if (tis.isEmpty()) {
+ return;
+ }
+ G2DParentNode node = parent.getOrCreateNode(""+tis.hashCode(), G2DParentNode.class);
+
+ double minDist = Double.MAX_VALUE;
+ double maxDist = 0;
+ TerminalInfo nearest = null;
+ if (pickRect != null) {
+ for (TerminalInfo ti : tis) {
+ double dx = ti.posDia.getTranslateX() - pickRect.getCenterX();
+ double dy = ti.posDia.getTranslateY() - pickRect.getCenterY();
+ double dist = Math.sqrt(dx*dx+dy*dy);
+ if (dist > maxDist) {
+ maxDist = dist;
+ }
+ if (dist < minDist) {
+ minDist = dist;
+ nearest = ti;
+ }
+ }
+ }
+
+ for (TerminalInfo ti : tis) {
+ if (strategy != null && !strategy.highlight(ti))
+ continue;
+ Shape shape = ti.shape != null ? ti.shape : getTerminalShape();
+ //System.out.println("painting terminal " + ti + ": " + shape);
+ ShapeNode sn = node.getOrCreateNode("terminal_"+ti.hashCode(), ShapeNode.class);
+ sn.setShape(shape);
+ sn.setStroke(STROKE25);
+ sn.setScaleStroke(true);
+ if (pickRect != null) {
+ Color blendedColor = color;
+ if (ti != nearest) {
+ double dx = ti.posDia.getTranslateX() - pickRect.getCenterX();
+ double dy = ti.posDia.getTranslateY() - pickRect.getCenterY();
+ double dist = Math.sqrt(dx*dx+dy*dy);
+ double normalizedDistance = dist / maxDist;
+ final double maxFade = 0.5;
+ float alpha = (float)(1 - normalizedDistance*maxFade);
+ blendedColor = ColorUtil.withAlpha(ColorUtil.blend(color, Color.WHITE, normalizedDistance*maxFade), alpha);
+ }
+ sn.setColor(blendedColor);
+ } else {
+ sn.setColor(color);
+ }
+ sn.setTransform(ti.posDia);
+ sn.setFill(false);
+ }
+ }
+
+ public Rectangle2D getTerminalShape() {
+ double pickDist = pointerInteractor.getPickDistance();
+ return new Rectangle2D.Double(-pickDist - 0.5, -pickDist - 0.5, pickDist * 2 + 1, pickDist * 2 + 1);
+ }
+
+ public Rectangle2D getPickRectangle(double x, double y) {
+ double pickDist = pointerInteractor.getPickDistance();
+ Rectangle2D controlPickRect = new Rectangle2D.Double(x-pickDist, y-pickDist, pickDist*2+1, pickDist*2+1);
+ return controlPickRect;
+ }
+
+ static {
+ Path2D.Double cross = new Path2D.Double();
+ double s = 2;
+ cross.moveTo(-s, -s);
+ cross.lineTo(s, s);
+ cross.moveTo(-s, s);
+ cross.lineTo(s, -s);
+ TERMINAL_SHAPE = cross;
+ }
+
+ IHintListener hoverStrategyListener = new HintListenerAdapter() {
+ @Override
+ public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {
+ hoverStrategyChanged((TerminalHoverStrategy) newValue);
+ }
+ };
+
+ protected void hoverStrategyChanged(TerminalHoverStrategy strategy) {
+ update(strategy != null ? strategy.highlightEnabled() : false);
+ }
+
+}