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