1
28 package demo.layout.organic;
29
30 import y.algo.Bfs;
31 import y.anim.AnimationFactory;
32 import y.anim.AnimationObject;
33 import y.base.Edge;
34 import y.base.EdgeCursor;
35 import y.base.EdgeList;
36 import y.base.EdgeMap;
37 import y.base.ListCell;
38 import y.base.Node;
39 import y.base.NodeCursor;
40 import y.base.NodeList;
41 import y.base.NodeMap;
42 import y.base.YList;
43 import y.geom.YPoint;
44 import y.util.DefaultMutableValue2D;
45 import y.util.Maps;
46 import y.view.Drawable;
47 import y.view.EdgeRealizer;
48 import y.view.Graph2D;
49 import y.view.NodeRealizer;
50 import y.view.ViewAnimationFactory;
51
52 import javax.swing.SwingUtilities;
53 import java.util.Locale;
54
55
65 public class AnimatedNavigationDemo extends NavigationDemo {
66 private NodeMap hiddenNodesMap;
67 private EdgeMap hiddenEdgesMap;
68
69 public static void main(String[] args) {
70 SwingUtilities.invokeLater(new Runnable() {
71 public void run() {
72 Locale.setDefault(Locale.ENGLISH);
73 initLnF();
74 final AnimatedNavigationDemo navigationDemo = new AnimatedNavigationDemo();
75 navigationDemo.start("Animated Navigation Demo");
76 navigationDemo.moveFirstNodeToCenter();
77 }
78 });
79 }
80
81 public AnimatedNavigationDemo() {
82 hiddenNodesMap = view.getGraph2D().createNodeMap();
84 hiddenEdgesMap = view.getGraph2D().createEdgeMap();
85 }
86
87
90 protected boolean isUndoRedoEnabled() {
91 return false;
92 }
93
94
97 protected boolean isClipboardEnabled() {
98 return false;
99 }
100
101
104 private YList history = new YList();
105
106 protected void moveToCenter(final Node newCenterNode, boolean animated) {
107 if (!SwingUtilities.isEventDispatchThread()) {
108 throw new IllegalStateException("not in dispatch thread");
109 }
110 this.centerNode = newCenterNode;
111
112 layouter.setInertia(newCenterNode, 1);
114 if (history.size() < 4) {
115 history.addFirst(newCenterNode);
116 } else {
117 ListCell lastCell = history.lastCell();
118 layouter.setInertia((Node) lastCell.getInfo(), 0);
120 history.removeCell(lastCell);
121 lastCell.setInfo(newCenterNode);
122 history.addFirstCell(lastCell);
123 }
124
125 NodeList fadeInNodes = new NodeList();
127 NodeList fadeOutNodes = new NodeList();
128 EdgeList fadeInEdges = new EdgeList();
129 EdgeList fadeOutEdges = new EdgeList();
130
131 final EdgeList hiddenEdges = new EdgeList();
133 final NodeList hiddenNodes = new NodeList();
134
135 final Graph2D graph = view.getGraph2D();
136
137 graphHider.unhideAll();
139
140 final int[] data = new int[graph.N()];
143 NodeMap layerMap = Maps.createIndexNodeMap(data);
144 NodeList[] layerLists = Bfs.getLayers(graph, new NodeList(newCenterNode), false, layerMap, 4);
146
147 for (int i = 0; i < Math.min(layerLists.length, 3); i++) {
149 for (NodeCursor nc = layerLists[i].nodes(); nc.ok(); nc.next()) {
150 final Node node = nc.node();
151 final boolean wasHidden = hiddenNodesMap.getBool(node);
152 if (wasHidden) {
153 fadeInNodes.add(node);
154 }
155 }
156 }
157
158 for (NodeCursor nc = graph.nodes(); nc.ok(); nc.next()) {
160 final Node node = nc.node();
161 final boolean wasHidden = hiddenNodesMap.getBool(node);
162 final int layer = layerMap.getInt(node);
163 if (layer >= 0 && layer < 3) {
164 if (wasHidden) {
166 hiddenNodesMap.setBool(node, false);
167 }
168 } else {
169 hiddenNodes.add(node);
170 if (!wasHidden) {
172 fadeOutNodes.add(node);
173 hiddenNodesMap.setBool(node, true);
174 }
175 }
176 }
177
178 for (EdgeCursor ec = graph.edges(); ec.ok(); ec.next()) {
180 final Edge edge = ec.edge();
181 final boolean wasHidden = hiddenEdgesMap.getBool(edge);
182 final boolean shouldBeHidden = hiddenNodesMap.getBool(edge.source()) || hiddenNodesMap.getBool(edge.target());
183 if (shouldBeHidden) {
184 hiddenEdges.add(edge);
185 if (!wasHidden) {
186 fadeOutEdges.add(edge);
187 hiddenEdgesMap.setBool(edge, true);
188 }
189 } else {
190 if (wasHidden) {
191 fadeInEdges.add(edge);
192 hiddenEdgesMap.setBool(edge, false);
193 }
194 }
195 }
196
197 double x;
199 double y;
200
201 YPoint location = layouter.getCenter(newCenterNode);
203 if (location != null) {
204 x = location.getX();
205 y = location.getY();
206 } else { NodeRealizer realizer = view.getGraph2D().getRealizer(newCenterNode);
208 x = realizer.getX();
209 y = realizer.getY();
210 }
211
212 if (animated) {
213 animateCamera(x, y);
216
217 fadeOutEdges(fadeOutEdges);
219 fadeOutNodes(fadeOutNodes);
220
221 fadeInEdges(fadeInEdges);
223 fadeInNodes(graph, layerMap, fadeInNodes);
224 } else {
225 view.setCenter(x, y);
226 }
227
228 graphHider.hide(hiddenEdges);
230
231 graphHider.hide(hiddenNodes);
233
234 this.layouter.syncStructure();
236 this.layouter.wakeUp();
237 }
238
239 private void animateCamera(double x, double y) {
240 AnimationObject animationObject = factory.moveCamera(DefaultMutableValue2D.create(x, y), PREFERRED_DURATION);
242 AnimationObject easedAnimation = AnimationFactory.createEasedAnimation(animationObject, 0.15, 0.25);
244 animationPlayer.animate(easedAnimation);
245 }
246
247 private void fadeOutNodes(NodeList fadeOutNodes) {
248 for (NodeCursor nc = fadeOutNodes.nodes(); nc.ok(); nc.next()) {
249 final Node node = nc.node();
250 NodeRealizer realizer = view.getGraph2D().getRealizer(node);
252 final Drawable nodeDrawable = ViewAnimationFactory.createDrawable(realizer);
253 animationPlayer.animate(factory.fadeOut(nodeDrawable, PREFERRED_DURATION));
254 }
255 }
256
257 private void fadeInNodes(Graph2D graph, NodeMap layerMap, NodeList fadeInNodes) {
258 for (NodeCursor nc = fadeInNodes.nodes(); nc.ok(); nc.next()) {
259 final Node node = nc.node();
260
261 final int myLayer = layerMap.getInt(node);
263 double posX = 0;
264 double posY = 0;
265
266 int count = 0;
268 for (NodeCursor nc2 = node.neighbors(); nc2.ok(); nc2.next()) {
269 final Node neighbour = nc2.node();
270 if (layerMap.getInt(neighbour) < myLayer) {
271 count++;
272 posX += graph.getCenterX(neighbour);
273 posY += graph.getCenterY(neighbour);
274 }
275 }
276
277 NodeRealizer nodeRealizer = view.getGraph2D().getRealizer(node);
279
280 if (count > 0) {
282 posX /= count;
283 posY /= count;
284 nodeRealizer.setCenter(posX, posY);
287 layouter.setCenter(node, posX, posY);
289 }
290
291 animationPlayer.animate(factory.fadeIn(nodeRealizer, PREFERRED_DURATION)); }
294 }
295
296 private void fadeOutEdges(EdgeList fadeOutEdges) {
297 for (EdgeCursor ec = fadeOutEdges.edges(); ec.ok(); ec.next()) {
298 final Edge edge = ec.edge();
299 EdgeRealizer realizer = view.getGraph2D().getRealizer(edge);
300 final Drawable edgeDrawable = ViewAnimationFactory.createDrawable(realizer);
301 animationPlayer.animate(factory.fadeOut(edgeDrawable, PREFERRED_DURATION)); }
303 }
304
305 private void fadeInEdges(EdgeList fadeInEdges) {
306 for (EdgeCursor ec = fadeInEdges.edges(); ec.ok(); ec.next()) {
307 final Edge edge = ec.edge();
308 EdgeRealizer edgeRealizer = view.getGraph2D().getRealizer(edge);
309 animationPlayer.animate(factory.fadeIn(edgeRealizer, PREFERRED_DURATION)); }
311 }
312 }
313