]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.district.network.ui/src/org/simantics/district/network/ui/DistrictPanZoomRotateHandler.java
More sensible caching for connection lines.
[simantics/district.git] / org.simantics.district.network.ui / src / org / simantics / district / network / ui / DistrictPanZoomRotateHandler.java
1 package org.simantics.district.network.ui;
2
3 import java.awt.geom.AffineTransform;
4 import java.awt.geom.Rectangle2D;
5 import java.util.Set;
6
7 import org.simantics.g2d.canvas.ICanvasContext;
8 import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;
9 import org.simantics.g2d.canvas.impl.DependencyReflection.Reference;
10 import org.simantics.g2d.diagram.DiagramHints;
11 import org.simantics.g2d.diagram.DiagramUtils;
12 import org.simantics.g2d.diagram.IDiagram;
13 import org.simantics.g2d.diagram.participant.Selection;
14 import org.simantics.g2d.element.ElementUtils;
15 import org.simantics.g2d.element.IElement;
16 import org.simantics.g2d.participant.CanvasBoundsParticipant;
17 import org.simantics.g2d.participant.PanZoomRotateHandler;
18 import org.simantics.maps.MapScalingTransform;
19 import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;
20 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseWheelMovedEvent;
21 import org.simantics.scenegraph.g2d.events.command.Command;
22 import org.simantics.scenegraph.g2d.events.command.CommandEvent;
23 import org.simantics.scenegraph.g2d.events.command.Commands;
24 import org.simantics.scenegraph.g2d.nodes.NavigationNode;
25
26 public class DistrictPanZoomRotateHandler extends PanZoomRotateHandler {
27
28     public static final int DISTRICT_TRANSLATE_AMOUNT = 2;
29
30     @Dependency DistrictTransformUtil util;
31     @Reference  Selection selection;
32
33     public DistrictPanZoomRotateHandler() {
34     }
35     
36     @Override
37     public void addedToContext(ICanvasContext ctx) {
38         super.addedToContext(ctx);
39         setHint(KEY_TRANSLATE_AMOUNT, DISTRICT_TRANSLATE_AMOUNT);
40     }
41
42     @Override
43     protected Class<? extends NavigationNode> getNavigationNodeClass() {
44         return DistrictNavigationNode.class;
45     }
46
47     @Override
48     public double getTranslateAmount() {
49         return 15 * super.getTranslateAmount();
50     }
51     
52     @Override
53     public double limitScaleFactor(double scaleFactor) {
54         return scaleFactor;
55     }
56     
57     @Override
58     @EventHandler(priority = 1)
59     public boolean handleEvent(CommandEvent e) {
60         super.update();
61         Command c = e.command;
62         boolean zoomDisabled = Boolean.TRUE.equals(getHint(KEY_DISABLE_ZOOM)) ? true : false;
63         // custom handling of zoom to fit & selection
64         if (Commands.ZOOM_TO_FIT.equals(c) && !zoomDisabled) {
65             boolean result = zoomToFit();
66             if (!result)
67                 result = zoomToPage();
68             return result;
69         }
70         if (Commands.ZOOM_TO_PAGE.equals(c) && !zoomDisabled) {
71             return zoomToPage();
72         }
73         if (Commands.ZOOM_TO_SELECTION.equals(c) && !zoomDisabled) {
74             return zoomToSelection();
75         }
76         return super.handleEvent(e);
77     }
78
79     private boolean zoomToFit() {
80         CanvasBoundsParticipant boundsParticipant = getContext().getAtMostOneItemOfClass(CanvasBoundsParticipant.class);
81         if (boundsParticipant == null)
82             return false;
83
84         final Rectangle2D controlBounds = boundsParticipant.getControlBounds().getFrame();
85         if (controlBounds == null || controlBounds.isEmpty())
86             return false;
87
88         IDiagram d = getHint(DiagramHints.KEY_DIAGRAM);
89         if (d == null)
90             return false;
91
92         Rectangle2D diagramRect = DiagramUtils.getContentRect(d);
93         if (diagramRect == null)
94             return false;
95         if (diagramRect.isEmpty())
96             return false;
97
98         org.simantics.scenegraph.utils.GeometryUtils.expandRectangle(diagramRect, 1);
99         
100         // System.out.println("zoomToFit(" + controlArea + ", " + diagramRect + ")");
101         util.fitArea(controlBounds, diagramRect, null);
102
103         return true;
104     }
105
106     private boolean zoomToPage() {
107         int currentZoomLevel = MapScalingTransform.zoomLevel(util.getTransform());
108         
109         util.setTransform(new AffineTransform(2,0,0,2,270,270));
110         return true;
111     }
112     
113     private boolean zoomToSelection() {
114         CanvasBoundsParticipant boundsParticipant = getContext().getAtMostOneItemOfClass(CanvasBoundsParticipant.class);
115         if (boundsParticipant == null)
116             return false;
117
118         final Rectangle2D controlBounds = boundsParticipant.getControlBounds().getFrame();
119         if (controlBounds == null || controlBounds.isEmpty())
120             return false;
121         
122         Set<IElement> selections = selection.getAllSelections();
123         if (selections == null || selections.isEmpty()) {
124             // no can do, 
125             return zoomToPage();
126         }
127         Rectangle2D diagramRect = ElementUtils.getSurroundingElementBoundsOnDiagram(selections);
128         
129         // Make sure that even empty bounds can be zoomed into.
130         org.simantics.scenegraph.utils.GeometryUtils.expandRectangle(diagramRect, 1);
131         
132         util.fitArea(controlBounds, diagramRect, null);
133         return true;
134     }
135
136     public static class DistrictNavigationNode extends NavigationNode {
137
138         private static final long serialVersionUID = 5452897272925816875L;
139
140         public DistrictNavigationNode() {
141             setAdaptViewportToResizedControl(false);
142         }
143
144         @Override
145         public Double getZoomInLimit() {
146             return super.getZoomInLimit();
147         }
148
149         @Override
150         public Double getZoomOutLimit() {
151             return super.getZoomOutLimit();
152         }
153
154         @Override
155         public void setAdaptViewportToResizedControl(Boolean adapt) {
156             super.setAdaptViewportToResizedControl(false);
157             // no op
158         }
159
160         @Override
161         public boolean getAdaptViewportToResizedControl() {
162             return false;
163         }
164
165         @Override
166         public boolean mouseWheelMoved(MouseWheelMovedEvent me) {
167             if (navigationEnabled && zoomEnabled) {
168                 // check if min/max zoom already
169                 AffineTransform transform = getTransform();
170                 int zoomLevel = MapScalingTransform.zoomLevel(transform);
171                 
172                 if (0 < zoomLevel && zoomLevel < 20 || (zoomLevel == 0 && me.wheelRotation > 0) || (zoomLevel == 20 && me.wheelRotation < 0)) {
173                     double z;
174                     if (me.wheelRotation > 0) {
175                         z = DISTRICT_TRANSLATE_AMOUNT;
176                     } else {
177                         z = 1.0d / DISTRICT_TRANSLATE_AMOUNT;
178                     }
179                     //double scroll = Math.min(0.9, -me.wheelRotation / 20.0);
180                     //double z = 1 - scroll;
181                     double dx = (me.controlPosition.getX() - transform.getTranslateX()) / transform.getScaleX();
182                     double dy = (me.controlPosition.getY() - transform.getTranslateY()) / transform.getScaleY();
183                     dx = dx * (1 - z);
184                     dy = dy * (1 - z);
185 //                    double limitedScale = limitScaleFactor(z);
186 //                    if (limitedScale != 1.0) {
187                         translate(dx, dy);
188                         scale(z, z);
189                         transformChanged();
190                         dropQuality();
191                         repaint();
192 //                    }
193                 } else {
194                     // max zoom level reached
195                 }
196             }
197             return false;
198         }
199
200     }
201 }