1
14 package demo.module;
15
16 import y.base.Edge;
17 import y.layout.Layouter;
18 import y.layout.router.ChannelEdgeRouter;
19 import y.layout.router.OrthogonalPatternEdgeRouter;
20 import y.layout.router.OrthogonalSegmentDistributionStage;
21 import y.module.LayoutModule;
22 import y.option.ConstraintManager;
23 import y.option.OptionGroup;
24 import y.option.OptionHandler;
25 import y.util.DataProviderAdapter;
26 import y.view.Graph2D;
27 import y.view.hierarchy.GroupLayoutConfigurator;
28
29
34 public class ChannelEdgeRouterModule extends LayoutModule {
35 private static final String NAME = "CHANNEL_EDGE_ROUTER";
36
37 private ChannelEdgeRouter router;
38 private static final String PATHFINDER = "PATHFINDER";
39
40 private static final String SCOPE = "SCOPE";
41 private static final String SCOPE_AT_SELECTED_NODES = "SCOPE_AT_SELECTED_NODES";
42 private static final String SCOPE_SELECTED_EDGES = "SCOPE_SELECTED_EDGES";
43 private static final String LAYOUT_OPTIONS = "LAYOUT_OPTIONS";
44 private static final String SCOPE_ALL_EDGES = "SCOPE_ALL_EDGES";
45 private static final String COST = "COST";
46 private static final String EDGE_CROSSING_COST = "EDGE_CROSSING_COST";
47 private static final String NODE_CROSSING_COST = "NODE_CROSSING_COST";
48 private static final String BEND_COST = "BEND_COST_FACTOR";
49 private static final String MINIMUM_DISTANCE = "MINIMUM_DISTANCE";
50 private static final String ACTIVATE_GRID_ROUTING = "ACTIVATE_GRID_ROUTING";
51 private static final String GRID_SPACING = "GRID_SPACING";
52 private static final String ORTHOGONAL_PATTERN_PATH_FINDER = "ORTHOGONAL_PATTERN_PATH_FINDER";
53 private static final String ORTHOGONAL_SHORTESTPATH_PATH_FINDER = "ORTHOGONAL_SHORTESTPATH_PATH_FINDER";
54
55
56
59 public ChannelEdgeRouterModule() {
60 super(NAME, "yFiles Layout Team", "Routes edges orthogonally.");
61 setPortIntersectionCalculatorEnabled(true);
62 }
63
64
65 protected void init() {
66 instantiateRouter();
67 configure(router);
68
69 final Graph2D graph = getGraph2D();
70 OptionHandler oh = getOptionHandler();
71
72 if (oh.get(SCOPE).equals(SCOPE_ALL_EDGES)) {
74 graph.addDataProvider(ChannelEdgeRouter.AFFECTED_EDGES, new DataProviderAdapter() {
75 public boolean getBool(Object dataHolder) {
76 return true;
77 }
78 });
79 } else if (oh.get(SCOPE).equals(SCOPE_SELECTED_EDGES)) {
80 graph.addDataProvider(ChannelEdgeRouter.AFFECTED_EDGES, new DataProviderAdapter() {
81 public boolean getBool(Object dataHolder) {
82 return graph.isSelected((Edge) dataHolder);
83 }
84 });
85 } else {
86 graph.addDataProvider(ChannelEdgeRouter.AFFECTED_EDGES, new DataProviderAdapter() {
87 public boolean getBool(Object dataHolder) {
88 return graph.isSelected(((Edge) dataHolder).source()) || graph.isSelected(((Edge) dataHolder).target());
89 }
90 });
91 }
92 }
93
94 private void instantiateRouter() {
98 if (router != null) {
99 return;
100 }
101 router = new ChannelEdgeRouter();
102 }
103
104
110 public void configure(Layouter layouter) {
111 if (layouter instanceof ChannelEdgeRouter) {
112 ChannelEdgeRouter edgeRouter = (ChannelEdgeRouter) layouter;
113 OptionHandler oh = getOptionHandler();
114
115
116 Layouter pathFinder;
117 if (oh.get(PATHFINDER).equals(ORTHOGONAL_PATTERN_PATH_FINDER)) {
118 OrthogonalPatternEdgeRouter orthogonalPatternEdgeRouter = new OrthogonalPatternEdgeRouter();
119 orthogonalPatternEdgeRouter.setAffectedEdgesDPKey(ChannelEdgeRouter.AFFECTED_EDGES);
120 orthogonalPatternEdgeRouter.setMinimumDistance(oh.getDouble(MINIMUM_DISTANCE));
121
122 orthogonalPatternEdgeRouter.setGridRoutingEnabled(oh.getBool(ACTIVATE_GRID_ROUTING));
123 orthogonalPatternEdgeRouter.setGridWidth(oh.getDouble(GRID_SPACING));
124
125 orthogonalPatternEdgeRouter.setBendCost(oh.getDouble(BEND_COST));
126 orthogonalPatternEdgeRouter.setEdgeCrossingCost(oh.getDouble(EDGE_CROSSING_COST));
127 orthogonalPatternEdgeRouter.setNodeCrossingCost(oh.getDouble(NODE_CROSSING_COST));
128
129 orthogonalPatternEdgeRouter.setEdgeOverlapCost(0.0);
131 pathFinder = orthogonalPatternEdgeRouter;
132 } else {
133 ChannelEdgeRouter.OrthogonalShortestPathPathFinder orthogonalShortestPathPathFinder = new ChannelEdgeRouter.OrthogonalShortestPathPathFinder();
134 orthogonalShortestPathPathFinder.setAffectedEdgesDPKey(ChannelEdgeRouter.AFFECTED_EDGES);
135 orthogonalShortestPathPathFinder.setMinimumDistance((int) oh.getDouble(MINIMUM_DISTANCE));
136
137 orthogonalShortestPathPathFinder.setGridRoutingEnabled(oh.getBool(ACTIVATE_GRID_ROUTING));
138 orthogonalShortestPathPathFinder.setGridSpacing((int) oh.getDouble(GRID_SPACING));
139
140 orthogonalShortestPathPathFinder.setCrossingCost(oh.getDouble(EDGE_CROSSING_COST));
141 pathFinder = orthogonalShortestPathPathFinder;
142 }
143 edgeRouter.setPathFinderStrategy(pathFinder);
144
145 OrthogonalSegmentDistributionStage segmentDistributionStage = new OrthogonalSegmentDistributionStage();
146 segmentDistributionStage.setAffectedEdgesDPKey(ChannelEdgeRouter.AFFECTED_EDGES);
147 segmentDistributionStage.setPreferredDistance(oh.getDouble(MINIMUM_DISTANCE));
148 segmentDistributionStage.setGridEnabled(oh.getBool(ACTIVATE_GRID_ROUTING));
149 segmentDistributionStage.setGridWidth(oh.getDouble(GRID_SPACING));
150
151 edgeRouter.setEdgeDistributionStrategy(segmentDistributionStage);
152 } else {
153 throw new IllegalArgumentException("argument must be of type y.layout.router.ChannelEdgeRouter");
154 }
155 }
156
157
162 public void initOptionHandler(Layouter layouter) {
163 OptionHandler oh = getOptionHandler();
164 initOptionHandler(oh, layouter);
165 }
166
167 void initOptionHandler(OptionHandler oh, Layouter layouter) {
168 oh.clear();
169 if (layouter == null || ! (layouter instanceof ChannelEdgeRouter) ) {
170 layouter = new ChannelEdgeRouter();
171 }
172 ChannelEdgeRouter cer = (ChannelEdgeRouter) layouter;
173
174 OptionGroup og = new OptionGroup();
175 og.setAttribute(OptionGroup.ATTRIBUTE_TITLE, LAYOUT_OPTIONS);
176 String[] pathFinderEnum = {ORTHOGONAL_PATTERN_PATH_FINDER, ORTHOGONAL_SHORTESTPATH_PATH_FINDER};
177
178 if(cer.getPathFinderStrategy() instanceof OrthogonalPatternEdgeRouter){
179 OrthogonalPatternEdgeRouter oper = (OrthogonalPatternEdgeRouter) cer.getPathFinderStrategy();
180 og.addItem(oh.addEnum(PATHFINDER, pathFinderEnum, 0));
181
182 String[] affectedEnum = {SCOPE_ALL_EDGES, SCOPE_SELECTED_EDGES, SCOPE_AT_SELECTED_NODES};
183 og.addItem(oh.addEnum(SCOPE, affectedEnum, 0));
184
185 og.addItem(oh.addDouble(MINIMUM_DISTANCE, oper.getMinimumDistance()));
186 og.addItem(oh.addBool(ACTIVATE_GRID_ROUTING, oper.isGridRoutingEnabled()));
187 og.addItem(oh.addDouble(GRID_SPACING, oper.getGridWidth()));
188
189 ConstraintManager cm = new ConstraintManager(oh);
190 cm.setEnabledOnValueEquals(ACTIVATE_GRID_ROUTING, Boolean.TRUE, GRID_SPACING);
191
192 og = new OptionGroup();
193 og.setAttribute(OptionGroup.ATTRIBUTE_TITLE, COST);
194 og.addItem(oh.addDouble(BEND_COST, oper.getBendCost()));
195 cm.setEnabledOnValueEquals(PATHFINDER, ORTHOGONAL_PATTERN_PATH_FINDER, BEND_COST);
196 og.addItem(oh.addDouble(EDGE_CROSSING_COST, oper.getEdgeCrossingCost()));
197 cm.setEnabledOnValueEquals(PATHFINDER, ORTHOGONAL_PATTERN_PATH_FINDER, EDGE_CROSSING_COST);
198 og.addItem(oh.addDouble(NODE_CROSSING_COST, oper.getNodeCrossingCost()));
199 cm.setEnabledOnValueEquals(PATHFINDER, ORTHOGONAL_PATTERN_PATH_FINDER, NODE_CROSSING_COST);
200 } else if(cer.getPathFinderStrategy() instanceof ChannelEdgeRouter.OrthogonalShortestPathPathFinder){
201 ChannelEdgeRouter.OrthogonalShortestPathPathFinder osppf =
202 (ChannelEdgeRouter.OrthogonalShortestPathPathFinder) cer.getPathFinderStrategy();
203 og.addItem(oh.addEnum(PATHFINDER, pathFinderEnum, 1));
204
205 String[] affectedEnum = {SCOPE_ALL_EDGES, SCOPE_SELECTED_EDGES, SCOPE_AT_SELECTED_NODES};
206 og.addItem(oh.addEnum(SCOPE, affectedEnum, 0));
207
208 og.addItem(oh.addDouble(MINIMUM_DISTANCE, osppf.getMinimumDistance()));
209 og.addItem(oh.addBool(ACTIVATE_GRID_ROUTING, osppf.isGridRoutingEnabled()));
210 og.addItem(oh.addDouble(GRID_SPACING, osppf.getGridSpacing()));
211
212 ConstraintManager cm = new ConstraintManager(oh);
213 cm.setEnabledOnValueEquals(ACTIVATE_GRID_ROUTING, Boolean.TRUE, GRID_SPACING);
214
215 og = new OptionGroup();
216 og.setAttribute(OptionGroup.ATTRIBUTE_TITLE, COST);
217 og.addItem(oh.addDouble(BEND_COST, 1));
218 cm.setEnabledOnValueEquals(PATHFINDER, ORTHOGONAL_PATTERN_PATH_FINDER, BEND_COST);
219 og.addItem(oh.addDouble(EDGE_CROSSING_COST, 5));
220 cm.setEnabledOnValueEquals(PATHFINDER, ORTHOGONAL_PATTERN_PATH_FINDER, EDGE_CROSSING_COST);
221 og.addItem(oh.addDouble(NODE_CROSSING_COST, 50));
222 cm.setEnabledOnValueEquals(PATHFINDER, ORTHOGONAL_PATTERN_PATH_FINDER, NODE_CROSSING_COST);
223 } else { og.addItem(oh.addEnum(PATHFINDER, pathFinderEnum, 0));
225
226 String[] affectedEnum = {SCOPE_ALL_EDGES, SCOPE_SELECTED_EDGES, SCOPE_AT_SELECTED_NODES};
227 og.addItem(oh.addEnum(SCOPE, affectedEnum, 0));
228
229 og.addItem(oh.addDouble(MINIMUM_DISTANCE, 10.0));
230 og.addItem(oh.addBool(ACTIVATE_GRID_ROUTING, true));
231 og.addItem(oh.addDouble(GRID_SPACING, 20.0));
232 ConstraintManager cm = new ConstraintManager(oh);
233 cm.setEnabledOnValueEquals(ACTIVATE_GRID_ROUTING, Boolean.TRUE, GRID_SPACING);
234
235 og = new OptionGroup();
236 og.setAttribute(OptionGroup.ATTRIBUTE_TITLE, COST);
237 og.addItem(oh.addDouble(BEND_COST, 1.0));
238 cm.setEnabledOnValueEquals(PATHFINDER, ORTHOGONAL_PATTERN_PATH_FINDER, BEND_COST);
239 og.addItem(oh.addDouble(EDGE_CROSSING_COST, 5.0));
240 cm.setEnabledOnValueEquals(PATHFINDER, ORTHOGONAL_PATTERN_PATH_FINDER, EDGE_CROSSING_COST);
241 og.addItem(oh.addDouble(NODE_CROSSING_COST, 50.0));
242 cm.setEnabledOnValueEquals(PATHFINDER, ORTHOGONAL_PATTERN_PATH_FINDER, NODE_CROSSING_COST);
243 }
244 }
245
246 protected void dispose() {
247 router = null;
248 }
249
250
254 protected OptionHandler createOptionHandler() {
255 OptionHandler oh = new OptionHandler(getModuleName());
256 initOptionHandler(oh, null);
257 return oh;
258 }
259
260 protected void mainrun() {
261 GroupLayoutConfigurator glc = new GroupLayoutConfigurator(getGraph2D());
263 try {
264 glc.prepareAll();
266 launchLayouter(router);
268 } finally {
269 glc.restoreAll();
271 }
272
273 }
274 }
275