1
14 package demo.view.layout.organic;
15
16 import demo.view.DemoBase;
17 import y.algo.Bfs;
18 import y.anim.AnimationFactory;
19 import y.anim.AnimationObject;
20 import y.anim.AnimationPlayer;
21 import y.base.Node;
22 import y.base.NodeCursor;
23 import y.base.NodeList;
24 import y.base.NodeMap;
25 import y.geom.YPoint;
26 import y.io.IOHandler;
27 import y.io.YGFIOHandler;
28 import y.layout.CopiedLayoutGraph;
29 import y.layout.LayoutTool;
30 import y.layout.organic.InteractiveOrganicLayouter;
31 import y.util.D;
32 import y.util.DefaultMutableValue2D;
33 import y.util.GraphHider;
34 import y.view.DefaultGraph2DRenderer;
35 import y.view.EditMode;
36 import y.view.Graph2DViewRepaintManager;
37 import y.view.NodeRealizer;
38 import y.view.ViewAnimationFactory;
39
40 import javax.swing.Action;
41 import javax.swing.SwingUtilities;
42 import java.awt.event.ActionEvent;
43 import java.io.IOException;
44
45
59 public class NavigationDemo extends DemoBase {
60 protected static final long PREFERRED_DURATION = 1000;
61
62
65 protected InteractiveOrganicLayouter layouter;
66
69 protected Node centerNode;
70
71 protected GraphHider graphHider;
72
73
76 protected AnimationPlayer animationPlayer;
77 protected ViewAnimationFactory factory;
78 private Thread layoutThread;
79
80 public static void main( String[] args ) {
81 initLnF();
82 final NavigationDemo navigationDemo = new NavigationDemo();
83 navigationDemo.start( "Navigation Demo" );
84 }
85
86 public NavigationDemo() {
87 SwingUtilities.invokeLater( new Runnable() {
88 public void run() {
89 moveFirstNodeToCenter();
90 }
91 } );
92 }
93
94 protected void initialize() {
95 ( ( DefaultGraph2DRenderer ) view.getGraph2DRenderer() ).setDrawEdgesFirst( true );
96
97 Graph2DViewRepaintManager repaintManager = new Graph2DViewRepaintManager( view );
98 factory = new ViewAnimationFactory( repaintManager );
99 factory.setQuality( ViewAnimationFactory.HIGH_PERFORMANCE );
100 animationPlayer = factory.createConfiguredPlayer();
101 animationPlayer.setFps( 25 );
102
103 graphHider = new GraphHider( view.getGraph2D() );
104 graphHider.setFireGraphEventsEnabled( true );
105
106 loadInitialGraph();
107
108 initLayouter();
109 initUpdater( repaintManager );
110 }
111
112 public void dispose() {
113 if ( animationPlayer != null ) {
114 animationPlayer.stop();
115 }
116 if ( layoutThread != null ) {
117 layoutThread.interrupt();
118 }
119 }
120
121 protected EditMode createEditMode() {
122 EditMode editMode = new EditMode() {
123 protected void nodeClicked( Node v ) {
124 moveToCenter( v, true );
125 }
126 };
127 editMode.allowBendCreation( false );
128 editMode.allowEdgeCreation( false );
129 editMode.allowMoveLabels( false );
130 editMode.allowMovePorts( false );
131 editMode.allowNodeCreation( false );
132 editMode.allowNodeEditing( false );
133 editMode.allowResizeNodes( false );
134 editMode.setMoveSelectionMode( new InteractiveMoveSelectionMode( layouter ) );
135 return editMode;
136 }
137
138 protected void moveFirstNodeToCenter() {
139 if ( view.getGraph2D().nodeCount() > 0 ) {
140 moveToCenter( view.getGraph2D().firstNode(), false );
141 }
142 }
143
144
149 protected void initUpdater( final Graph2DViewRepaintManager repaintManager ) {
150 final AnimationObject updater = new AnimationObject() {
152 public long preferredDuration() {
153 return Long.MAX_VALUE;
154 }
155
156 public void calcFrame( double time ) {
157 if ( updatePositions() ) {
158 repaintManager.invalidate();
159 }
160 }
161
162 public void initAnimation() {
163 }
164
165 public void disposeAnimation() {
166 }
167 };
168 animationPlayer.animate( updater );
169 }
170
171
174 protected void loadInitialGraph() {
175 loadGraph( "resource/peopleNav.ygf" );
176 LayoutTool.resetPaths( view.getGraph2D() );
177 view.updateView();
178 }
179
180
184 protected void initLayouter() {
185 layouter = new InteractiveOrganicLayouter();
186
187 layouter.setMaxTime( 2000 );
189
190 layoutThread = new Thread( new Runnable() {
192 public void run() {
193 layouter.doLayout( new CopiedLayoutGraph( view.getGraph2D() ) );
195 }
196 } );
197 layoutThread.setPriority( Thread.MIN_PRIORITY );
198 layoutThread.start();
199 }
200
201
210 protected boolean updatePositions() {
211 if ( layouter == null || !layouter.isRunning() ) return false;
212 double maxMovement = layouter.commitPositionsSmoothly( 50, 0.15 );
213 return maxMovement > 0;
214 }
215
216
222 protected void moveToCenter( final Node newCenterNode, boolean animated ) {
223 if ( centerNode != null ) {
227 layouter.setInertia( centerNode, 0 );
229 }
230 centerNode = newCenterNode;
231
232 layouter.setInertia( newCenterNode, 1 );
234
235 NodeList hiddenNodes = new NodeList( graphHider.hiddenNodes() );
236
237 graphHider.unhideAll();
238
239 NodeList toHide = new NodeList( view.getGraph2D().nodes() );
240 NodeMap nodeMap = view.getGraph2D().createNodeMap();
241 NodeList[] layers = Bfs.getLayers( view.getGraph2D(), new NodeList( centerNode ), false, nodeMap, 3 );
242 view.getGraph2D().disposeNodeMap( nodeMap );
243 for ( int i = 0; i < layers.length; i++ ) {
244 NodeList layer = layers[ i ];
245 toHide.removeAll( layer );
246 }
247
248 graphHider.hide( toHide );
249
250 double centerX = view.getGraph2D().getCenterX( newCenterNode );
252 double centerY = view.getGraph2D().getCenterY( newCenterNode );
253 for ( NodeCursor nc = hiddenNodes.nodes(); nc.ok(); nc.next() ) {
254 if ( view.getGraph2D().contains( nc.node() ) ) {
255 view.getGraph2D().setCenter( nc.node(), centerX, centerY );
256 layouter.setCenter( nc.node(), centerX, centerY );
257 }
258 }
259
260 layouter.wakeUp();
261
262 double x;
264 double y;
265 YPoint point = layouter.getCenter( newCenterNode );
266 if ( point != null ) {
267 x = point.getX();
268 y = point.getY();
269 } else {
270 NodeRealizer realizer = view.getGraph2D().getRealizer( newCenterNode );
271 x = realizer.getX();
272 y = realizer.getY();
273 }
274
275 if ( animated ) {
276 AnimationObject animationObject = factory.moveCamera( DefaultMutableValue2D.create( x, y ), PREFERRED_DURATION );
278 AnimationObject easedAnimation = AnimationFactory.createEasedAnimation( animationObject, 0.15, 0.25 );
279 animationPlayer.animate( easedAnimation );
280 } else {
281 view.setCenter( x, y );
282 }
283
284 layouter.syncStructure();
286 layouter.wakeUp();
287 }
288
289
292 protected void setPosition( Node node, double x, double y ) {
293 if ( layouter == null || !layouter.isRunning() ) return;
294 layouter.setCenter( node, x, y );
295 }
296
297
298 protected Action createLoadAction() {
299 return new DemoBase.LoadAction() {
300 public void actionPerformed( ActionEvent e ) {
301 layouter.stop();
302 centerNode = null;
303 super.actionPerformed( e );
304 graphHider = new GraphHider( view.getGraph2D() );
305 LayoutTool.resetPaths( view.getGraph2D() );
306
307 initLayouter();
308
309 moveFirstNodeToCenter();
310 }
311 };
312 }
313
314 protected boolean isDeletionEnabled() {
315 return false;
316 }
317 }