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