From 5b520af5f5abeb53b5edc026c50d50df0067f5f2 Mon Sep 17 00:00:00 2001 From: miettinen Date: Tue, 29 Oct 2013 08:14:21 +0000 Subject: [PATCH] Mouse click (for rename) on Sysdyn diagram more intuitive (refs #4484). Allow Valve terminals to be generic Shapes, we need something other (i.e. Polygon) shape to define a Valve than Rectangle (refs #4482). git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@28142 ac1ea38d-2e2b-0410-8846-a27921b304fc --- .../ui/editor/routing/DependencyRouter.java | 19 ++--- .../sysdyn/ui/elements/HoverTextNode.java | 75 +++++++++++++++++++ .../sysdyn/ui/elements/ValveFactory.java | 3 +- .../sysdyn/ui/elements/ValveOutline.java | 27 +++++++ .../sysdyn/ui/elements/connections/Arcs.java | 42 +++++------ .../elements/connections/DependencyNode.java | 15 ++-- .../ui/preferences/SolverPreferencePage.java | 2 +- 7 files changed, 143 insertions(+), 40 deletions(-) create mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveOutline.java diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/DependencyRouter.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/DependencyRouter.java index 1b2bf60d..dc2e29fe 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/DependencyRouter.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/DependencyRouter.java @@ -1,5 +1,6 @@ package org.simantics.sysdyn.ui.editor.routing; +import java.awt.Shape; import java.awt.geom.Arc2D; import java.awt.geom.Path2D; import java.awt.geom.Point2D; @@ -59,11 +60,11 @@ public class DependencyRouter implements IRouter2 { return shape; } - public static Arc2D createArc(Arc2D arc, Rectangle2D tail, Rectangle2D head, double angle) { - double x0 = tail.getCenterX(); - double y0 = tail.getCenterY(); - double x1 = head.getCenterX(); - double y1 = head.getCenterY(); + public static Arc2D createArc(Arc2D arc, Shape beginBounds, Shape endBounds, double angle) { + double x0 = beginBounds.getBounds2D().getCenterX(); + double y0 = beginBounds.getBounds2D().getCenterY(); + double x1 = endBounds.getBounds2D().getCenterX(); + double y1 = endBounds.getBounds2D().getCenterY(); // System.out.println("createArrowShape " + x0 + " " + y0 + " " + x1 + " " + y1); @@ -84,10 +85,10 @@ public class DependencyRouter implements IRouter2 { // Rectangle2D bounds = new Rectangle2D.Double(); // tail.getBounds(bounds); double angle0 = Arcs.nextIntersectingAngle(cx, cy, r, - Math.atan2(-dy0, dx0), tail, angle < 0.0); + Math.atan2(-dy0, dx0), beginBounds, angle < 0.0); // head.getBounds(bounds); double angle1 = Arcs.nextIntersectingAngle(cx, cy, r, - Math.atan2(-dy1, dx1), head, angle > 0.0); + Math.atan2(-dy1, dx1), endBounds, angle > 0.0); double extent = angle1-angle0; //double arcAngle = angle0; if(angle < 0.0) { @@ -131,12 +132,12 @@ public class DependencyRouter implements IRouter2 { } - public static Pair createArrowShape(Pair shapes, Rectangle2D tail, Rectangle2D head, double angle) { + public static Pair createArrowShape(Pair shapes, Shape beginBounds, Shape endBounds, double angle) { if(shapes == null || shapes.first == null || shapes.second == null) { shapes = new Pair(new Arc2D.Double(), new Path2D.Double()); } - createArc(shapes.first, tail, head, angle); + createArc(shapes.first, beginBounds, endBounds, angle); double angle0 = Math.toRadians(shapes.first.getAngleStart()); double angle1 = Math.toRadians(shapes.first.getAngleStart() + shapes.first.getAngleExtent()); diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/HoverTextNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/HoverTextNode.java index 27bf2808..be323011 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/HoverTextNode.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/HoverTextNode.java @@ -15,12 +15,19 @@ import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; +import org.simantics.diagram.elements.DiagramNodeUtil; import org.simantics.diagram.elements.TextNode; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.element.IElement; import org.simantics.scenegraph.ISelectionPainterNode; import org.simantics.scenegraph.g2d.events.EventTypes; import org.simantics.scenegraph.g2d.events.FocusEvent; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseClickEvent; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDoubleClickedEvent; import org.simantics.scenegraph.utils.NodeUtil; public class HoverTextNode extends TextNode implements ISelectionPainterNode { @@ -83,4 +90,72 @@ public class HoverTextNode extends TextNode implements ISelectionPainterNode { return false; } + @Override + protected boolean mouseClicked(MouseClickEvent event) { + if (event.button != MouseClickEvent.LEFT_BUTTON) + return false; + + if (hitTest(event, 0)) { + hoverClick++; + if (hoverClick < 2) + return false; + ICanvasContext ctx = DiagramNodeUtil.getCanvasContext(this); + // FIXME: needed only because eventdelegator registrations are done before adding node to scene graph. + if (ctx == null) + return false; + IElement e = DiagramNodeUtil.getElement(ctx, this); + if (!isEditMode()) { + if (Boolean.TRUE.equals(setEditMode(true))) { + editActivation = activateEdit(0, e, ctx); + repaint(); + } + } + } else { + hoverClick = 0; + if (isEditMode()) { + fireTextEditingEnded(); + } + } + return false; + } + + @Override + protected boolean mouseDoubleClicked(MouseDoubleClickedEvent event) { + if (event.button != MouseClickEvent.LEFT_BUTTON) + return false; + + if (hitTest(event, 0)) { + ICanvasContext ctx = DiagramNodeUtil.getCanvasContext(this); + // FIXME: needed only because eventdelegator registrations are done before adding node to scene graph. + if (ctx == null) + return false; + + if (text != null) { + // Select the whole text. + setCaret(0, false); + setCaret(text.length(), true); + repaint(); + } + } + return false; + } + + @Override + protected boolean mouseButtonPressed(MouseButtonPressedEvent event) { + if (!isShiftDown(event)) { + return super.mouseButtonPressed(event); + } + + // Select text if shift is down. + if (!isEditMode()) + return false; + + Point2D local = controlToLocal( event.controlPosition ); + // FIXME: once the event coordinate systems are cleared up, remove this workaround + local = parentToLocal(local); + if (hover && this.containsLocal(local)) { + setCaret(local, true); + } + return false; + } } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveFactory.java index b3c2d6fc..25890ac0 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveFactory.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveFactory.java @@ -31,7 +31,6 @@ import org.simantics.g2d.element.IElement; import org.simantics.g2d.element.SceneGraphNodeKey; import org.simantics.g2d.element.handler.HandleMouseEvent; import org.simantics.g2d.element.handler.InternalSize; -import org.simantics.g2d.element.handler.impl.BoundsOutline; import org.simantics.g2d.element.handler.impl.DefaultTransform; import org.simantics.g2d.element.handler.impl.HoverImpl; import org.simantics.g2d.element.handler.impl.ObjectTerminal; @@ -81,7 +80,7 @@ public class ValveFactory extends SysdynElementFactory { StaticSymbolImageInitializer.INSTANCE, HoverImpl.INSTANCE, ValveSceneGraph.INSTANCE, - BoundsOutline.INSTANCE, + ValveOutline.INSTANCE, Orientation.INSTANCE, ValveTextLocation.INSTANCE, new WholeElementTerminals(terminals) diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveOutline.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveOutline.java new file mode 100644 index 00000000..8e35e695 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveOutline.java @@ -0,0 +1,27 @@ +package org.simantics.sysdyn.ui.elements; + +import java.awt.Polygon; +import java.awt.Shape; + +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.impl.BoundsOutline; + +public class ValveOutline extends BoundsOutline { + + public static final BoundsOutline INSTANCE = new ValveOutline(); + + private static final long serialVersionUID = 5544256245734478634L; + + public ValveOutline() { + super(); + } + + @Override + public Shape getElementShape(IElement e) { + return super.getElementShape(e); + /*int[] xs = {-5,5,5,20,20,-20,-20,-5}; + int[] ys = {-5,-5,5,5,15,15,5,5}; + Polygon poly = new Polygon(xs, ys, 8); + return poly;*/ + } +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/Arcs.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/Arcs.java index f9768fed..602796de 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/Arcs.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/Arcs.java @@ -11,7 +11,7 @@ *******************************************************************************/ package org.simantics.sysdyn.ui.elements.connections; -import java.awt.geom.Rectangle2D; +import java.awt.Shape; public class Arcs { @@ -84,11 +84,11 @@ public class Arcs { } public static double nextIntersectingAngle(double cx, double cy, double r, - double curAngle, Rectangle2D rect, boolean dir) { + double curAngle, Shape endBounds, boolean dir) { if(!dir) { double bestAngle = curAngle + PI2; { - double dx = rect.getMinX() - cx; + double dx = endBounds.getBounds2D().getMinX() - cx; if(Math.abs(dx) < r) { double angle = normalizeAngle(Math.acos(dx / r)); bestAngle = updateBestNextAngle(curAngle, bestAngle, angle); @@ -96,7 +96,7 @@ public class Arcs { } } { - double dx = rect.getMaxX() - cx; + double dx = endBounds.getBounds2D().getMaxX() - cx; if(Math.abs(dx) < r) { double angle = normalizeAngle(Math.acos(dx / r)); bestAngle = updateBestNextAngle(curAngle, bestAngle, angle); @@ -104,7 +104,7 @@ public class Arcs { } } { - double dy = cy - rect.getMinY(); + double dy = cy - endBounds.getBounds2D().getMinY(); if(Math.abs(dy) < r) { double angle = Math.asin(dy / r); bestAngle = updateBestNextAngle(curAngle, bestAngle, angle); @@ -113,7 +113,7 @@ public class Arcs { } } { - double dy = cy - rect.getMaxY(); + double dy = cy - endBounds.getBounds2D().getMaxY(); if(Math.abs(dy) < r) { double angle = Math.asin(dy / r); bestAngle = updateBestNextAngle(curAngle, bestAngle, angle); @@ -126,7 +126,7 @@ public class Arcs { else { double bestAngle = curAngle - PI2; { - double dx = rect.getMinX() - cx; + double dx = endBounds.getBounds2D().getMinX() - cx; if(Math.abs(dx) < r) { double angle = normalizeAngle(Math.acos(dx / r)); bestAngle = updateBestPrevAngle(curAngle, bestAngle, angle); @@ -134,7 +134,7 @@ public class Arcs { } } { - double dx = rect.getMaxX() - cx; + double dx = endBounds.getBounds2D().getMaxX() - cx; if(Math.abs(dx) < r) { double angle = normalizeAngle(Math.acos(dx / r)); bestAngle = updateBestPrevAngle(curAngle, bestAngle, angle); @@ -142,7 +142,7 @@ public class Arcs { } } { - double dy = cy - rect.getMinY(); + double dy = cy - endBounds.getBounds2D().getMinY(); if(Math.abs(dy) < r) { double angle = Math.asin(dy / r); bestAngle = updateBestPrevAngle(curAngle, bestAngle, angle); @@ -151,7 +151,7 @@ public class Arcs { } } { - double dy = cy - rect.getMaxY(); + double dy = cy - endBounds.getBounds2D().getMaxY(); if(Math.abs(dy) < r) { double angle = Math.asin(dy / r); bestAngle = updateBestPrevAngle(curAngle, bestAngle, angle); @@ -163,14 +163,14 @@ public class Arcs { } } - public static boolean hitTest(Rectangle2D beginBounds, Rectangle2D endBounds, double angle, double x, double y, double tolerance) { + public static boolean hitTest(Shape beginBounds, Shape endBounds, double angle, double x, double y, double tolerance) { boolean clockWise = angle > 0; - double x0 = beginBounds.getCenterX(); - double y0 = beginBounds.getCenterY(); - double x1 = endBounds.getCenterX(); - double y1 = endBounds.getCenterY(); + double x0 = beginBounds.getBounds2D().getCenterX(); + double y0 = beginBounds.getBounds2D().getCenterY(); + double x1 = endBounds.getBounds2D().getCenterX(); + double y1 = endBounds.getBounds2D().getCenterY(); double offset = Math.abs(angle) < 1.0e-6 @@ -219,15 +219,15 @@ public class Arcs { * @return The radial distance between the the arc and (x,y); Double.NaN if the * distance is not real. */ - public static double getRadialDistance(Rectangle2D beginBounds, - Rectangle2D endBounds, double angle, double x, double y) { + public static double getRadialDistance(Shape beginBounds, + Shape endBounds, double angle, double x, double y) { boolean clockWise = angle > 0; - double x0 = beginBounds.getCenterX(); - double y0 = beginBounds.getCenterY(); - double x1 = endBounds.getCenterX(); - double y1 = endBounds.getCenterY(); + double x0 = beginBounds.getBounds2D().getCenterX(); + double y0 = beginBounds.getBounds2D().getCenterY(); + double x1 = endBounds.getBounds2D().getCenterX(); + double y1 = endBounds.getBounds2D().getCenterY(); double offset = Math.abs(angle) < 1.0e-6 diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyNode.java index 0eacd1b7..c1609423 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyNode.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyNode.java @@ -15,6 +15,7 @@ import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; +import java.awt.Shape; import java.awt.Stroke; import java.awt.geom.Arc2D; import java.awt.geom.Path2D; @@ -57,8 +58,8 @@ public class DependencyNode extends TextNode implements ISelectionPainterNode { private Color color; private Stroke stroke; - private Rectangle2D beginBounds; - private Rectangle2D endBounds; + private Shape beginBounds; + private Shape endBounds; private double angle = 0.1; private String side; private transient Pair shapes = new Pair(new Arc2D.Double(), new Path2D.Double()); @@ -155,11 +156,11 @@ public class DependencyNode extends TextNode implements ISelectionPainterNode { return stroke; } - public Rectangle2D getBeginBounds() { + public Shape getBeginBounds() { return beginBounds; } - public Rectangle2D getEndBounds() { + public Shape getEndBounds() { return endBounds; } @@ -236,7 +237,7 @@ public class DependencyNode extends TextNode implements ISelectionPainterNode { boolean pressHit = false; - private boolean hitTest(org.simantics.scenegraph.g2d.events.MouseEvent event, double tolerance) { + protected boolean hitTest(org.simantics.scenegraph.g2d.events.MouseEvent event, double tolerance) { if(beginBounds == null || endBounds == null) return false; Point2D localPos = NodeUtil.worldToLocal(this, event.controlPosition, new Point2D.Double()); return Arcs.hitTest(beginBounds, endBounds, angle, localPos.getX(), localPos.getY(), tolerance); @@ -268,9 +269,9 @@ public class DependencyNode extends TextNode implements ISelectionPainterNode { Point2D localPos = NodeUtil.worldToLocal(this, event.controlPosition, new Point2D.Double()); setAngle(Arcs.angleOfArc( - beginBounds.getCenterX(), beginBounds.getCenterY(), + beginBounds.getBounds2D().getCenterX(), beginBounds.getBounds2D().getCenterY(), localPos.getX(), localPos.getY(), - endBounds.getCenterX(), endBounds.getCenterY())); + endBounds.getBounds2D().getCenterX(), endBounds.getBounds2D().getCenterY())); repaint(); } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SolverPreferencePage.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SolverPreferencePage.java index f0289829..3cd3f059 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SolverPreferencePage.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SolverPreferencePage.java @@ -29,7 +29,7 @@ public class SolverPreferencePage extends FieldEditorPreferencePage implements solverEditor = new RadioGroupFieldEditor(SolverSettings.SOLVER_TYPE, "Solver type", 1, new String[][] { { "Internal", SolverSettings.SOLVER_TYPE_INTERNAL }, - { "Open Modelica", SolverSettings.SOLVER_TYPE_OPENMODELICA } + { "OpenModelica", SolverSettings.SOLVER_TYPE_OPENMODELICA } }, getFieldEditorParent()); addField(solverEditor); } -- 2.47.1