blob: 3b283c08cf9f4d61ea5404d50d090f45e2c60bb2 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2018 Agence spatiale canadienne / Canadian Space Agency
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pierre Allard,
* Regent L'Archeveque,
* Sebastien Gemme - initial API and implementation
* SPDX-License-Identifier: EPL-1.0
*
*******************************************************************************/
package org.eclipse.apogy.addons.ros.ui.composites;
import org.eclipse.apogy.addons.ros.ROSInterface;
import org.eclipse.apogy.addons.ros.ROSListener;
import org.eclipse.apogy.addons.ros.ROSListenerState;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableColorProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.ui.PlatformUI;
public class ROSListenerListComposite extends Composite {
private ROSInterface rosInterface;
private ROSListener<?> selectedROSListener = null;
private final Tree tree;
private final TreeViewer treeViewer;
private final AdapterFactory adapterFactory = new ComposedAdapterFactory(
ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
private DataBindingContext m_bindingContext;
private Adapter listenerAdapter;
public ROSListenerListComposite(Composite parent, int style) {
super(parent, style);
setLayout(new GridLayout(1, false));
this.treeViewer = new TreeViewer(this,
SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.MULTI);
this.tree = this.treeViewer.getTree();
GridData gd_tree = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
gd_tree.widthHint = 200;
gd_tree.minimumWidth = 200;
this.tree.setHeaderVisible(true);
this.tree.setLinesVisible(true);
this.tree.setLayoutData(gd_tree);
TreeViewerColumn treeViewerColumnItem_TopicState = new TreeViewerColumn(this.treeViewer, SWT.NONE);
TreeColumn trclmnState = treeViewerColumnItem_TopicState.getColumn();
trclmnState.setWidth(150);
trclmnState.setText("State");
TreeViewerColumn treeViewerColumnItem_TopicName = new TreeViewerColumn(this.treeViewer, SWT.NONE);
TreeColumn trclmnItem = treeViewerColumnItem_TopicName.getColumn();
trclmnItem.setWidth(350);
trclmnItem.setText("Topic Name");
TreeViewerColumn treeViewerColumnItem_TopicType = new TreeViewerColumn(this.treeViewer, SWT.NONE);
TreeColumn trclmnType = treeViewerColumnItem_TopicType.getColumn();
trclmnType.setWidth(350);
trclmnType.setText("Type");
this.treeViewer.setContentProvider(new CustomContentProvider());
this.treeViewer.setLabelProvider(new CustomLabelProvider(this.adapterFactory));
this.treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
ROSListenerListComposite.this.selectedROSListener = (ROSListener<?>) ((IStructuredSelection) event
.getSelection()).getFirstElement();
newROSListenerSelected(ROSListenerListComposite.this.selectedROSListener);
}
});
this.addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
if (ROSListenerListComposite.this.m_bindingContext != null)
ROSListenerListComposite.this.m_bindingContext.dispose();
}
});
}
public ROSInterface getROSInterface() {
return this.rosInterface;
}
public void setROSInterface(ROSInterface rosInterface) {
if (this.m_bindingContext != null) {
this.m_bindingContext.dispose();
}
// Uregister from previous listeners.
if (this.rosInterface != null && this.rosInterface.getTopicLauncher() != null) {
for (ROSListener<?> listener : this.rosInterface.getTopicLauncher().getListenerList()) {
listener.eAdapters().remove(getListenerdapter());
}
}
this.rosInterface = rosInterface;
if (rosInterface != null) {
this.m_bindingContext = customInitDataBindings();
this.treeViewer.setInput(rosInterface);
// Selects the first EarthSurfaceWorksite found.
this.selectedROSListener = getFirstROSListener(rosInterface);
if (this.selectedROSListener != null)
this.treeViewer.setSelection(new StructuredSelection(this.selectedROSListener), true);
newROSListenerSelected(this.selectedROSListener);
// Register to listeners.
if (this.rosInterface.getTopicLauncher() != null) {
for (ROSListener<?> listener : this.rosInterface.getTopicLauncher().getListenerList()) {
listener.eAdapters().add(getListenerdapter());
}
}
} else {
this.treeViewer.setInput(null);
this.treeViewer.setSelection(null, true);
newROSListenerSelected(null);
}
}
protected void newROSListenerSelected(ROSListener<?> rosListener) {
}
protected DataBindingContext customInitDataBindings() {
DataBindingContext bindingContext = new DataBindingContext();
// IObservableValue<?> observeSingleSelectionViewer =
// ViewerProperties.singleSelection().observe(treeViewer);
return bindingContext;
}
protected ROSListener<?> getFirstROSListener(ROSInterface rosInterface) {
if (rosInterface.getTopicLauncher() != null && !rosInterface.getTopicLauncher().getListenerList().isEmpty()) {
return rosInterface.getTopicLauncher().getListenerList().get(0);
} else {
return null;
}
}
private class CustomContentProvider implements ITreeContentProvider {
@Override
public void dispose() {
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
@Override
public Object[] getElements(Object inputElement) {
if (inputElement instanceof ROSInterface) {
ROSInterface rosInterface = (ROSInterface) inputElement;
if (rosInterface.getTopicLauncher() != null) {
return rosInterface.getTopicLauncher().getListenerList().toArray();
}
}
return new Object[] {};
}
@Override
public Object[] getChildren(Object parentElement) {
if (parentElement instanceof ROSInterface) {
ROSInterface rosInterface = (ROSInterface) parentElement;
if (rosInterface.getTopicLauncher() != null) {
return rosInterface.getTopicLauncher().getListenerList().toArray();
}
}
return new Object[] {};
}
@Override
public Object getParent(Object element) {
return null;
}
@Override
public boolean hasChildren(Object element) {
return false;
}
}
/**
*
* Label Provider.
*
*/
private class CustomLabelProvider extends AdapterFactoryLabelProvider
implements ITableLabelProvider, ITableColorProvider {
private final static int TOPIC_STATE_COLUMN_ID = 0;
private final static int TOPIC_NAME_COLUMN_ID = 1;
private final static int TOPIC_TYPE_COLUMN_ID = 2;
public CustomLabelProvider(AdapterFactory adapterFactory) {
super(adapterFactory);
}
@SuppressWarnings("rawtypes")
@Override
public String getColumnText(Object object, int columnIndex) {
String str = "<undefined>";
switch (columnIndex) {
case TOPIC_NAME_COLUMN_ID:
if (object instanceof ROSListener) {
ROSListener rosListener = (ROSListener) object;
str = rosListener.getTopicName();
}
break;
case TOPIC_STATE_COLUMN_ID:
str = "";
if (object instanceof ROSListener) {
ROSListener rosListener = (ROSListener) object;
str = rosListener.getListenerState().getLiteral();
}
break;
case TOPIC_TYPE_COLUMN_ID:
if (object instanceof ROSListener) {
ROSListener rosListener = (ROSListener) object;
str = rosListener.getMessageType();
}
break;
default:
break;
}
return str;
}
@Override
public Image getColumnImage(Object object, int columnIndex) {
return null;
}
@Override
public Color getBackground(Object object, int columnIndex) {
Color color = super.getBackground(object, columnIndex);
if (object instanceof ROSListener<?>) {
ROSListener<?> rosListener = (ROSListener<?>) object;
switch (rosListener.getListenerState().getValue()) {
case ROSListenerState.CONNECTING_VALUE:
color = PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_YELLOW);
break;
case ROSListenerState.CONNECTED_VALUE:
color = PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_GREEN);
break;
case ROSListenerState.STOPPED_VALUE:
color = PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_RED);
break;
default:
break;
}
}
return color;
}
}
private Adapter getListenerdapter() {
if (this.listenerAdapter == null) {
this.listenerAdapter = new AdapterImpl() {
@Override
public void notifyChanged(Notification msg) {
if (!ROSListenerListComposite.this.treeViewer.isBusy()) {
ROSListenerListComposite.this.treeViewer.getTree().getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
ROSListenerListComposite.this.treeViewer.refresh(true);
}
});
}
}
};
}
return this.listenerAdapter;
}
}