X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.district.network.ui%2Fsrc%2Forg%2Fsimantics%2Fdistrict%2Fnetwork%2Fui%2FDistrictPanZoomRotateHandler.java;h=ac0d22e3df34bb79b8ec17f07d44f25fb86d13ae;hb=2430e12577de9c1f984c873d7184795bb2dd29eb;hp=1a4f83d8aaea80ddee799f399d4a0f68084bbbe3;hpb=ac6ad8ff2b20a10e85e7b12c1af670500daebdd4;p=simantics%2Fdistrict.git diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictPanZoomRotateHandler.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictPanZoomRotateHandler.java index 1a4f83d8..ac0d22e3 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictPanZoomRotateHandler.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictPanZoomRotateHandler.java @@ -1,23 +1,154 @@ package org.simantics.district.network.ui; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency; +import org.simantics.g2d.canvas.impl.DependencyReflection.Reference; +import org.simantics.g2d.diagram.DiagramHints; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.diagram.participant.Selection; +import org.simantics.g2d.element.ElementUtils; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.participant.CanvasBoundsParticipant; import org.simantics.g2d.participant.PanZoomRotateHandler; +import org.simantics.maps.MapScalingTransform; +import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler; import org.simantics.scenegraph.g2d.events.MouseEvent.MouseWheelMovedEvent; +import org.simantics.scenegraph.g2d.events.command.Command; +import org.simantics.scenegraph.g2d.events.command.CommandEvent; +import org.simantics.scenegraph.g2d.events.command.Commands; import org.simantics.scenegraph.g2d.nodes.NavigationNode; public class DistrictPanZoomRotateHandler extends PanZoomRotateHandler { + public static final int DISTRICT_TRANSLATE_AMOUNT = 2; + + @Dependency DistrictTransformUtil util; + @Reference Selection selection; + public DistrictPanZoomRotateHandler() { } + + @Override + public void addedToContext(ICanvasContext ctx) { + super.addedToContext(ctx); + setHint(KEY_TRANSLATE_AMOUNT, DISTRICT_TRANSLATE_AMOUNT); + } @Override protected Class getNavigationNodeClass() { return DistrictNavigationNode.class; } + @Override + public double getTranslateAmount() { + return 15 * super.getTranslateAmount(); + } + + @Override + public double limitScaleFactor(double scaleFactor) { + return scaleFactor; + } + + @Override + @EventHandler(priority = 1) + public boolean handleEvent(CommandEvent e) { + super.update(); + Command c = e.command; + boolean zoomDisabled = Boolean.TRUE.equals(getHint(KEY_DISABLE_ZOOM)) ? true : false; + // custom handling of zoom to fit & selection + if (Commands.ZOOM_TO_FIT.equals(c) && !zoomDisabled) { + boolean result = zoomToFit(); + if (!result) + result = zoomToPage(); + return result; + } + if (Commands.ZOOM_TO_PAGE.equals(c) && !zoomDisabled) { + return zoomToPage(); + } + if (Commands.ZOOM_TO_SELECTION.equals(c) && !zoomDisabled) { + return zoomToSelection(); + } + return super.handleEvent(e); + } + + private boolean zoomToFit() { + CanvasBoundsParticipant boundsParticipant = getContext().getAtMostOneItemOfClass(CanvasBoundsParticipant.class); + if (boundsParticipant == null) + return false; + + final Rectangle2D controlBounds = boundsParticipant.getControlBounds().getFrame(); + if (controlBounds == null || controlBounds.isEmpty()) + return false; + + IDiagram d = getHint(DiagramHints.KEY_DIAGRAM); + if (d == null) + return false; + + Rectangle2D diagramRect = ElementUtils.getSurroundingElementBoundsOnDiagram(getMapElements(d.getElements())); + if (diagramRect == null) + return false; + if (diagramRect.isEmpty()) + return false; + + org.simantics.scenegraph.utils.GeometryUtils.expandRectangle(diagramRect, 1); + + // System.out.println("zoomToFit(" + controlArea + ", " + diagramRect + ")"); + util.fitArea(controlBounds, diagramRect, null); + + return true; + } + + protected static List getMapElements(Collection elements) { + List justMapElements = elements.stream() + .filter(e -> "DistrictNetworkEdgeElement".equals(e.getElementClass().getId()) + || "DistrictNetworkVertexElement".equals(e.getElementClass().getId())) + .collect(Collectors.toList()); + return justMapElements; + } + + private boolean zoomToPage() { + util.setTransform(new AffineTransform(2,0,0,2,270,270)); + return true; + } + + private boolean zoomToSelection() { + CanvasBoundsParticipant boundsParticipant = getContext().getAtMostOneItemOfClass(CanvasBoundsParticipant.class); + if (boundsParticipant == null) + return false; + + final Rectangle2D controlBounds = boundsParticipant.getControlBounds().getFrame(); + if (controlBounds == null || controlBounds.isEmpty()) + return false; + + Set selections = selection.getAllSelections(); + if (selections == null || selections.isEmpty()) { + // no can do, + return zoomToPage(); + } + Rectangle2D diagramRect = ElementUtils.getSurroundingElementBoundsOnDiagram(getMapElements(selections)); + + // Make sure that even empty bounds can be zoomed into. + org.simantics.scenegraph.utils.GeometryUtils.expandRectangle(diagramRect, 1); + + util.fitArea(controlBounds, diagramRect, null); + return true; + } + public static class DistrictNavigationNode extends NavigationNode { private static final long serialVersionUID = 5452897272925816875L; + public DistrictNavigationNode() { + setAdaptViewportToResizedControl(false); + } + @Override public Double getZoomInLimit() { return super.getZoomInLimit(); @@ -28,22 +159,47 @@ public class DistrictPanZoomRotateHandler extends PanZoomRotateHandler { return super.getZoomOutLimit(); } + @Override + public void setAdaptViewportToResizedControl(Boolean adapt) { + super.setAdaptViewportToResizedControl(false); + // no op + } + + @Override + public boolean getAdaptViewportToResizedControl() { + return false; + } + @Override public boolean mouseWheelMoved(MouseWheelMovedEvent me) { if (navigationEnabled && zoomEnabled) { - double scroll = Math.min(0.9, -me.wheelRotation / 20.0); - double z = 1 - scroll; - double dx = (me.controlPosition.getX() - transform.getTranslateX()) / transform.getScaleX(); - double dy = (me.controlPosition.getY() - transform.getTranslateY()) / transform.getScaleY(); - dx = dx * (1 - z); - dy = dy * (1 - z); - double limitedScale = limitScaleFactor(z); - if (limitedScale != 1.0) { - translate(dx, dy); - scale(z, z); - transformChanged(); - dropQuality(); - repaint(); + // check if min/max zoom already + AffineTransform transform = getTransform(); + int zoomLevel = MapScalingTransform.zoomLevel(transform); + + if (0 < zoomLevel && zoomLevel < 20 || (zoomLevel == 0 && me.wheelRotation > 0) || (zoomLevel == 20 && me.wheelRotation < 0)) { + double z; + if (me.wheelRotation > 0) { + z = DISTRICT_TRANSLATE_AMOUNT; + } else { + z = 1.0d / DISTRICT_TRANSLATE_AMOUNT; + } + //double scroll = Math.min(0.9, -me.wheelRotation / 20.0); + //double z = 1 - scroll; + double dx = (me.controlPosition.getX() - transform.getTranslateX()) / transform.getScaleX(); + double dy = (me.controlPosition.getY() - transform.getTranslateY()) / transform.getScaleY(); + dx = dx * (1 - z); + dy = dy * (1 - z); +// double limitedScale = limitScaleFactor(z); +// if (limitedScale != 1.0) { + translate(dx, dy); + scale(z, z); + transformChanged(); + dropQuality(); + repaint(); +// } + } else { + // max zoom level reached } } return false;