X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=bundles%2Forg.simantics.scenegraph%2Fsrc%2Forg%2Fsimantics%2Fscenegraph%2Fg2d%2Fnodes%2Fconnection%2FHighlightActionPointsAction.java;h=7f7bd3cd9b99f434f16c68b6a55adfcd2ab3b357;hb=7684bae;hp=04d08e3ec155242b1b6d58fad89f62adbab6e3d7;hpb=091591094efd9ad65f51f3cc64616ed0c167a1ab;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/connection/HighlightActionPointsAction.java b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/connection/HighlightActionPointsAction.java index 04d08e3ec..7f7bd3cd9 100644 --- a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/connection/HighlightActionPointsAction.java +++ b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/connection/HighlightActionPointsAction.java @@ -13,23 +13,23 @@ package org.simantics.scenegraph.g2d.nodes.connection; import java.awt.AlphaComposite; import java.awt.BasicStroke; +import java.awt.Color; import java.awt.Composite; import java.awt.Graphics2D; +import java.awt.Shape; import java.awt.Stroke; import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.net.URL; import java.util.ArrayList; import java.util.Collection; -import javax.imageio.ImageIO; - import org.simantics.diagram.connection.RouteGraph; import org.simantics.diagram.connection.RouteLineHalf; import org.simantics.diagram.connection.actions.IAction; import org.simantics.diagram.connection.rendering.IRouteGraphRenderer; +import org.simantics.scenegraph.utils.Quality; +import org.simantics.scenegraph.utils.QualityHints; /** * @author Tuukka Lehtonen @@ -67,26 +67,25 @@ public class HighlightActionPointsAction implements IAction { } } - static BufferedImage cross; - static BufferedImage cut; + private static final Shape CROSS_SHAPE = ActionShapes.CROSS_SHAPE; + private static final Shape SCISSOR_SHAPE = ActionShapes.transformShape(ActionShapes.SCISSOR_SHAPE, 1, 1, 0, 0, -Math.PI/2); - static { - cross = safeReadImage("cross.png"); - cut = safeReadImage("cut.png"); - } + private static final Color CROSS_COLOR = new Color(0xe4, 0x40, 0x61); + private static final Color SCISSOR_COLOR = new Color(20, 20, 20); public static final Stroke STROKE = new BasicStroke(0.1f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); - public static final AlphaComposite COMPOSITE = AlphaComposite.SrcOver.derive(0.6f); + public static final AlphaComposite NO_HIT_COMPOSITE = AlphaComposite.SrcOver.derive(0.8f); + public static final AlphaComposite HIT_COMPOSITE = AlphaComposite.SrcOver.derive(0.2f); public static final double DEGENERATED_LINE_LENGTH = 1; - public static final double CUT_DIST_FROM_END = 0.5; + public static final double CUT_DIST_FROM_END = 0.75; RouteGraph rg; transient Collection lhs = new ArrayList(); transient AffineTransform transform = new AffineTransform(); - transient AffineTransform transform2 = new AffineTransform(); transient Rectangle2D rect = new Rectangle2D.Double(); + transient Point2D point = new Point2D.Double(); public HighlightActionPointsAction(RouteGraph rg) { this.rg = rg; @@ -98,94 +97,73 @@ public class HighlightActionPointsAction implements IAction { @Override public void render(Graphics2D g, IRouteGraphRenderer renderer, double mouseX, double mouseY) { - // Cannot perform cut or delete segment actions on connections between 2 - // terminals. + // Cannot perform cut or delete segment actions + // on connections between 2 terminals. boolean simpleConnection = (rg.isSimpleConnection() || rg.getTerminals().size() <= 2); boolean branchedConnection = rg.getTerminals().size() > 2; + if (!branchedConnection || simpleConnection) + return; + + AffineTransform preTr = g.getTransform(); + double realViewScale = 1.0 / getScale(preTr); + //System.out.println(realViewScale); + // Don't render any of the actions if they could not be seen anyway. + if (realViewScale > 0.7) + return; lhs.clear(); rg.getLineHalves(lhs); - AffineTransform preTr = g.getTransform(); - double viewScale = 1.0 / getScale(preTr); - transform2.setToScale(viewScale, viewScale); + Pick pick = pickAction(rg, lhs, preTr, mouseX, mouseY); + Composite originalComposite = g.getComposite(); - g.setComposite(COMPOSITE); + Composite basicComposite = pick.action != null ? HIT_COMPOSITE : NO_HIT_COMPOSITE; + g.setComposite(basicComposite); - Pick pick = pickAction(rg, lhs, preTr, mouseX, mouseY); + // Always render these in high quality because otherwise the shapes + // will render with ugly artifacts when zoom level is a bit higher. + QualityHints origQualityHints = QualityHints.getQuality(g); + QualityHints.getHints(Quality.HIGH).setQuality(g); + // Render line removal markers if (!simpleConnection) { - double crossW = cross.getWidth()*viewScale*.5; - double crossH = cross.getHeight()*viewScale*.5; - - // Render line removal markers + g.setPaint(CROSS_COLOR); for (RouteLineHalf lh : lhs) { -// if (lh.getLine().getLength() < DEGENERATED_LINE_LENGTH) -// continue; -// if (!lh.getLine().isTransient()) -// continue; - if (lh.getLine().getTerminal() == null) + if (removeLocation(lh, point) == null) continue; - double x = lh.getLink().getX(); - double y = lh.getLink().getY(); - if (lh.getLine().isHorizontal()) { - x = (lh.getLine().getBegin().getX() + lh.getLine().getEnd().getX()) * .5; - } else { - y = (lh.getLine().getBegin().getY() + lh.getLine().getEnd().getY()) * .5; - } - boolean hit = pick.matches(Action.REMOVE, lh); - if (hit) g.setComposite(originalComposite); - transform.setToTranslation(x-crossW, y-crossH); - g.transform(transform); - g.drawImage(cross, transform2, null); + g.translate(point.getX(), point.getY()); + g.fill(CROSS_SHAPE); g.setTransform(preTr); if (hit) - g.setComposite(COMPOSITE); + g.setComposite(basicComposite); } } // Render reconnection markers if the connection is branched. if (branchedConnection) { - double cutW = cut.getWidth()*viewScale*.5; - double cutH = cut.getHeight()*viewScale*.5; - - final double dist = CUT_DIST_FROM_END; + g.setPaint(SCISSOR_COLOR); for (RouteLineHalf lh : lhs) { - if (lh.getLine().getLength() < DEGENERATED_LINE_LENGTH*3) + if (reconnectLocation(lh, point) == null) continue; - double x = lh.getLink().getX(); - double y = lh.getLink().getY(); - if (lh.getLine().isHorizontal()) { - if (lh.getLink() == lh.getLine().getBegin()) - x += dist*2; - else - x -= dist*2; - } else { - if (lh.getLink() == lh.getLine().getBegin()) - y += dist*2; - else - y -= dist*2; - } - boolean hit = pick.matches(Action.RECONNECT, lh); - if (hit) g.setComposite(originalComposite); - transform.setToTranslation(x-cutW, y-cutH); - if (!lh.getLine().isHorizontal()) { - transform.rotate(Math.PI/2, cutW, cutH); - } + transform.setToTranslation(point.getX(), point.getY()); + if (!lh.getLine().isHorizontal()) + transform.rotate(Math.PI/2); + transform.translate(0, 0.35); g.transform(transform); - g.drawImage(cut, transform2, null); + g.fill(SCISSOR_SHAPE); g.setTransform(preTr); if (hit) - g.setComposite(COMPOSITE); + g.setComposite(basicComposite); } } + origQualityHints.setQuality(g); g.setComposite(originalComposite); } @@ -205,35 +183,23 @@ public class HighlightActionPointsAction implements IAction { if (!branchedConnection || simpleConnection || viewTr == null) return Pick.MISS; - lhs.clear(); - rg.getLineHalves(lhs); + double viewScale = 1.0 / getScale(viewTr); + if (viewScale > 0.7) + return Pick.MISS; + double nearest = Double.MAX_VALUE; RouteLineHalf selected = null; Action selectedAction = null; - double nearest = Double.MAX_VALUE; - double viewScale = 1.0 / getScale(viewTr); + // Pick line removal markers if (!simpleConnection) { - double crossW = cross.getWidth()*viewScale*.5; - double crossH = cross.getHeight()*viewScale*.5; - - // Render line removal markers + double s = ActionShapes.CROSS_WIDTH * 0.25; for (RouteLineHalf lh : lhs) { -// if (lh.getLine().getLength() < DEGENERATED_LINE_LENGTH) -// continue; -// if (!lh.getLine().isTransient()) -// continue; - if (lh.getLine().getTerminal() == null) + if (removeLocation(lh, point) == null) continue; - double x = lh.getLink().getX(); - double y = lh.getLink().getY(); - if (lh.getLine().isHorizontal()) { - x = (lh.getLine().getBegin().getX() + lh.getLine().getEnd().getX()) * .5; - } else { - y = (lh.getLine().getBegin().getY() + lh.getLine().getEnd().getY()) * .5; - } - - rect.setFrameFromCenter(x, y, x-crossW, y-crossH); + double x = point.getX(); + double y = point.getY(); + rect.setFrameFromCenter(x, y, x-s, y-s); boolean hit = rect.contains(mouseX, mouseY); if (hit) { double distSq = distSq(x, y, mouseX, mouseY); @@ -246,35 +212,21 @@ public class HighlightActionPointsAction implements IAction { } } - // Render reconnection markers if the connection is branched. + // Pick reconnection markers if the connection is branched. if (branchedConnection) { - double cutW = cut.getWidth()*viewScale*.5; - double cutH = cut.getHeight()*viewScale*.5; - - final double dist = CUT_DIST_FROM_END; + double w = ActionShapes.SCISSOR_HEIGHT * 0.4; + double h = ActionShapes.SCISSOR_WIDTH * 0.3; for (RouteLineHalf lh : lhs) { - if (lh.getLine().getLength() < DEGENERATED_LINE_LENGTH*3) + if (reconnectLocation(lh, point) == null) continue; - double x = lh.getLink().getX(); - double y = lh.getLink().getY(); - if (lh.getLine().isHorizontal()) { - if (lh.getLink() == lh.getLine().getBegin()) - x += dist*2; - else - x -= dist*2; - } else { - if (lh.getLink() == lh.getLine().getBegin()) - y += dist*2; - else - y -= dist*2; - } - - rect.setFrameFromCenter(x, y, x-cutW, y-cutH); + double x = point.getX(); + double y = point.getY(); + rect.setFrameFromCenter(x, y, x-w, y-h); boolean hit = rect.contains(mouseX, mouseY); if (hit) { double distSq = distSq(x, y, mouseX, mouseY); if (distSq < nearest) { - nearest = dist; + nearest = distSq; selected = lh; selectedAction = Action.RECONNECT; } @@ -285,6 +237,43 @@ public class HighlightActionPointsAction implements IAction { return selected == null ? Pick.MISS : new Pick(selectedAction, selected); } + private static Point2D removeLocation(RouteLineHalf lh, Point2D p) { + if (lh.getLine().getTerminal() == null) + return null; + + double x = lh.getLink().getX(); + double y = lh.getLink().getY(); + if (lh.getLine().isHorizontal()) { + x = (lh.getLine().getBegin().getX() + lh.getLine().getEnd().getX()) * .5; + } else { + y = (lh.getLine().getBegin().getY() + lh.getLine().getEnd().getY()) * .5; + } + p.setLocation(x, y); + return p; + } + + private static Point2D reconnectLocation(RouteLineHalf lh, Point2D p) { + if (lh.getLine().getLength() < DEGENERATED_LINE_LENGTH*3) + return null; + + final double dist = CUT_DIST_FROM_END; + double x = lh.getLink().getX(); + double y = lh.getLink().getY(); + if (lh.getLine().isHorizontal()) { + if (lh.getLink() == lh.getLine().getBegin()) + x += dist*2; + else + x -= dist*2; + } else { + if (lh.getLink() == lh.getLine().getBegin()) + y += dist*2; + else + y -= dist*2; + } + p.setLocation(x, y); + return p; + } + private static double distSq(double x1, double y1, double x2, double y2) { double dx = x2 - x1; double dy = y2 - y1; @@ -301,13 +290,4 @@ public class HighlightActionPointsAction implements IAction { return Math.sqrt(Math.abs(m00*m11 - m10*m01)); } - private static BufferedImage safeReadImage(String name) { - try { - URL url = HighlightActionPointsAction.class.getResource(name); - return ImageIO.read(url); - } catch (IOException e) { - return null; - } - } - }