]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.district.route.ui/src/org/simantics/district/route/ui/RouteTree.java
Initial version of the district network Routes view.
[simantics/district.git] / org.simantics.district.route.ui / src / org / simantics / district / route / ui / RouteTree.java
1 package org.simantics.district.route.ui;
2
3 import java.util.List;
4 import java.util.concurrent.CompletableFuture;
5
6 import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
7 import org.eclipse.jface.layout.GridDataFactory;
8 import org.eclipse.jface.layout.GridLayoutFactory;
9 import org.eclipse.jface.resource.JFaceResources;
10 import org.eclipse.jface.resource.LocalResourceManager;
11 import org.eclipse.jface.viewers.ColumnLabelProvider;
12 import org.eclipse.jface.viewers.DoubleClickEvent;
13 import org.eclipse.jface.viewers.IDoubleClickListener;
14 import org.eclipse.jface.viewers.IStructuredSelection;
15 import org.eclipse.jface.viewers.ITreeContentProvider;
16 import org.eclipse.jface.viewers.SelectionChangedEvent;
17 import org.eclipse.jface.viewers.StructuredSelection;
18 import org.eclipse.jface.viewers.TreePath;
19 import org.eclipse.jface.viewers.TreeViewer;
20 import org.eclipse.jface.viewers.Viewer;
21 import org.eclipse.jface.viewers.ViewerCell;
22 import org.eclipse.osgi.util.NLS;
23 import org.eclipse.swt.SWT;
24 import org.eclipse.swt.widgets.Composite;
25 import org.simantics.db.Resource;
26 import org.simantics.district.route.Route;
27 import org.simantics.district.route.RouteEvent;
28 import org.simantics.district.route.RouteJob;
29 import org.simantics.district.route.RouteService;
30 import org.simantics.district.route.RouteServiceListener;
31 import org.simantics.district.route.Waypoint;
32 import org.simantics.district.route.ui.internal.Activator;
33 import org.simantics.utils.ui.SWTUtils;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37 /**
38  * @author Tuukka Lehtonen
39  * @since 6.09
40  */
41 public class RouteTree extends Composite {
42
43     private static final Logger LOGGER = LoggerFactory.getLogger(RouteTree.class);
44
45     ESelectionService selectionService;
46
47     private final LocalResourceManager resourceManager;
48
49     private TreeViewer tree;
50
51     public RouteTree(Composite parent, int style, ESelectionService selectionService) {
52         super(parent, style);
53         this.selectionService = selectionService;
54         this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), parent);
55         defaultInitializeUI();
56         trackRouteInput();
57     }
58
59     private RouteServiceListener routeServiceListener = e -> {
60         System.out.println("Route event: " + e);
61         switch (e.type) {
62             case RouteEvent.TYPE_ROUTE_DISCARDED:
63                 runUi(() -> tree.refresh());
64                 break;
65
66             case RouteEvent.TYPE_ROUTE_REGISTERED:
67                 runUi(() -> {
68                     tree.refresh();
69                     tree.setExpandedState(e.obj, true);
70                 });
71                 break;
72
73             case RouteEvent.TYPE_ROUTE_MODIFIED:
74                 runUi(() -> {
75                     tree.refresh(e.obj);
76                     tree.setExpandedState(e.obj, true);
77                 });
78                 break;
79
80             case RouteEvent.TYPE_ROUTE_RENAMED:
81                 runUi(() -> tree.refresh(e.obj));
82                 break;
83
84             case RouteEvent.TYPE_ROUTE_SOURCE_CHANGED:
85                 runUi(() -> tree.setInput(e.service.listRoutes()));
86                 break;
87         }
88     };
89
90     private void trackRouteInput() {
91         RouteService rs = Activator.getDefault().getRouteService();
92         if (rs != null) {
93             rs.addListener(routeServiceListener);
94             addDisposeListener(e -> rs.removeListener(routeServiceListener));
95             setInput(rs.listRoutes());
96         }
97     }
98
99     private void defaultInitializeUI() {
100         GridDataFactory.fillDefaults().grab(true, true).applyTo(this);
101         GridLayoutFactory.fillDefaults().numColumns(1).applyTo(this);
102
103         createTree(this);
104     }
105
106     private void createTree(Composite parent) {
107         tree = new TreeViewer(parent, SWT.SINGLE);
108         tree.setUseHashlookup(true);
109         GridDataFactory.fillDefaults().grab(true, true).applyTo(tree.getControl());
110         tree.setContentProvider(new ContentProvider());
111         tree.setLabelProvider(new LabelProvider());
112         tree.addSelectionChangedListener(this::treeSelectionChanged);
113         //tree.addPostSelectionChangedListener(this::treeSelectionChanged);
114         tree.addDoubleClickListener(this::itemDoubleClicked);
115         // TODO: add route renaming (F2), DnD reordering support
116     }
117
118     private void itemDoubleClicked(DoubleClickEvent e) {
119         // TODO: default action, i.e. highlight route?
120         LOGGER.info("double click {}", e);
121     }
122
123     private void treeSelectionChanged(SelectionChangedEvent e) {
124         selectionService.setSelection(e.getSelection());
125         /*
126         IStructuredSelection ss = (IStructuredSelection) e.getSelection();
127         Object[] arr = ss.toArray();
128         if (arr.length == 1) {
129             Object o = arr[0];
130             if (o instanceof Route) {
131                 CompletableFuture<List<Resource>> callback = new CompletableFuture<>();
132                 callback.thenAccept(dnElements -> {
133                     runUi(() -> selectionService.setSelection(new StructuredSelection(dnElements)));
134                 });
135                 new RouteJob((Route) o, callback).schedule();
136             } else if (o instanceof Waypoint) {
137                 selectionService.setSelection(new StructuredSelection(((Waypoint) o).<Object>getObject()));
138             }
139         }
140         */
141     }
142
143     protected void setInput(List<Route> result) {
144         runUi(() -> {
145             TreePath[] paths = tree.getExpandedTreePaths();
146             tree.setInput(result);
147             tree.setExpandedTreePaths(paths);
148         });
149     }
150
151     protected void runUi(Runnable r) {
152         SWTUtils.asyncExec(getDisplay(), () -> {
153             if (!tree.getControl().isDisposed())
154                 r.run();
155         });
156     }
157
158     private static class ContentProvider implements ITreeContentProvider {
159
160         private static final Object[] NONE = {};
161         @SuppressWarnings("unused")
162         private List<?> input;
163
164         @Override
165         public void dispose() {
166             input = null;
167         }
168
169         @Override
170         public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
171             input = newInput instanceof List ? (List<?>) newInput : null;
172         }
173
174         @Override
175         public Object[] getElements(Object inputElement) {
176             if (inputElement instanceof List)
177                 return ((List<?>) inputElement).toArray();
178             return NONE;
179         }
180
181         @Override
182         public Object[] getChildren(Object parentElement) {
183             if (parentElement instanceof Route) {
184                 return ((Route) parentElement).waypoints().toArray();
185             }
186             return NONE;
187         }
188
189         @Override
190         public Object getParent(Object element) {
191             return null;
192         }
193
194         @Override
195         public boolean hasChildren(Object element) {
196             if (element instanceof Route) {
197                 return !((Route) element).waypoints().isEmpty();
198             }
199             return false;
200         }
201
202     }
203
204     private static class LabelProvider extends ColumnLabelProvider {
205         @Override
206         public String getText(Object element) {
207             if (element instanceof Route) {
208                 Route r = (Route) element;
209                 return NLS.bind("{0} ({1} waypoints)", r.getName(), r.count());
210             } else if (element instanceof Waypoint) {
211             }
212             return element.toString();
213         }
214         @Override
215         public void update(ViewerCell cell) {
216             Object element = cell.getElement();
217             cell.setText(getText(element));
218         }
219     }
220
221 }