| /******************************************************************************* |
| * 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 - initial API and implementation |
| * Regent L'Archeveque |
| * |
| * SPDX-License-Identifier: EPL-1.0 |
| *******************************************************************************/ |
| package org.eclipse.apogy.addons.sensors.imaging.camera.composites; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.apogy.addons.sensors.imaging.camera.ApogyAddonsSensorsImagingCameraPackage; |
| import org.eclipse.apogy.addons.sensors.imaging.camera.CameraViewConfiguration; |
| import org.eclipse.apogy.addons.sensors.imaging.camera.ImageFilter; |
| import org.eclipse.apogy.common.emf.ApogyCommonEMFPackage; |
| import org.eclipse.apogy.common.emf.FeaturePathAdapter; |
| import org.eclipse.apogy.common.emf.impl.FeaturePathAdapterCustomImpl; |
| import org.eclipse.apogy.common.emf.transaction.ApogyCommonTransactionFacade; |
| import org.eclipse.apogy.common.emf.ui.ApogyCommonEMFUIFactory; |
| import org.eclipse.apogy.common.emf.ui.NamedSetting; |
| import org.eclipse.apogy.common.emf.ui.emfforms.ApogyCommonEMFUiEMFFormsFacade; |
| import org.eclipse.apogy.common.emf.ui.wizards.ApogyEObjectWizard; |
| import org.eclipse.core.databinding.DataBindingContext; |
| import org.eclipse.core.databinding.UpdateValueStrategy; |
| import org.eclipse.core.databinding.conversion.Converter; |
| import org.eclipse.core.databinding.observable.value.IObservableValue; |
| import org.eclipse.emf.common.notify.Notification; |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.emf.edit.provider.ComposedAdapterFactory; |
| import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider; |
| import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider; |
| import org.eclipse.jface.databinding.swt.WidgetProperties; |
| import org.eclipse.jface.databinding.viewers.ViewerProperties; |
| import org.eclipse.jface.viewers.ISelectionChangedListener; |
| import org.eclipse.jface.viewers.SelectionChangedEvent; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.jface.wizard.Wizard; |
| import org.eclipse.jface.wizard.WizardDialog; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.custom.ScrolledComposite; |
| import org.eclipse.swt.events.DisposeEvent; |
| import org.eclipse.swt.events.DisposeListener; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Label; |
| |
| public class FiltersListComposite extends Composite { |
| |
| private final ComposedAdapterFactory adapterFactory = new ComposedAdapterFactory( |
| ComposedAdapterFactory.Descriptor.Registry.INSTANCE); |
| |
| private final TreeViewer treeViewer; |
| private final Composite emfFormsComposite; |
| private final ScrolledComposite scrolledComposite; |
| private final Button btnNew; |
| private final Button btnDelete; |
| |
| private final Button btnUp; |
| private final Button btnDown; |
| |
| private final Button btnVisible; |
| |
| private DataBindingContext m_bindingContext; |
| |
| private CameraViewConfiguration cameraViewConfiguration; |
| private List<FeaturePathAdapter> featurePathAdapters; |
| |
| public FiltersListComposite(Composite parent, int style) { |
| super(parent, style); |
| setLayout(new GridLayout(4, false)); |
| this.setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); |
| this.setBackgroundMode(SWT.INHERIT_FORCE); |
| addDisposeListener(new DisposeListener() { |
| |
| @Override |
| public void widgetDisposed(DisposeEvent e) { |
| dispose(); |
| } |
| }); |
| |
| this.treeViewer = new TreeViewer(this); |
| this.treeViewer.addSelectionChangedListener(new ISelectionChangedListener() { |
| |
| @Override |
| public void selectionChanged(SelectionChangedEvent event) { |
| FiltersListComposite.this.newSelection(); |
| updateEMFForms(); |
| |
| if (FiltersListComposite.this.btnVisible != null) { |
| FiltersListComposite.this.btnVisible.setVisible(getSelectedFilter() != null); |
| } |
| } |
| |
| }); |
| this.treeViewer.setLabelProvider(getLabelProvider()); |
| this.treeViewer.setContentProvider(getContentProvider()); |
| this.treeViewer.getTree().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 2)); |
| |
| Composite buttonComposite = new Composite(this, SWT.None); |
| buttonComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, true, 1, 2)); |
| buttonComposite.setLayout(new GridLayout(1, false)); |
| |
| this.btnNew = new Button(buttonComposite, SWT.None); |
| this.btnNew.setText("New"); |
| this.btnNew.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); |
| this.btnNew.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| NamedSetting namedSettings = ApogyCommonEMFUIFactory.eINSTANCE.createNamedSetting(); |
| namedSettings.setParent(getCameraViewConfiguration().getFilterList()); |
| namedSettings.setContainingFeature( |
| ApogyAddonsSensorsImagingCameraPackage.Literals.FILTER_LIST__IMAGE_FILTERS); |
| |
| Wizard wizard = new ApogyEObjectWizard( |
| ApogyAddonsSensorsImagingCameraPackage.Literals.FILTER_LIST__IMAGE_FILTERS, |
| getCameraViewConfiguration().getFilterList(), namedSettings, null); |
| WizardDialog dialog = new WizardDialog(getShell(), wizard); |
| dialog.open(); |
| |
| FiltersListComposite.this.treeViewer.refresh(); |
| updateEMFForms(); |
| } |
| }); |
| |
| this.btnDelete = new Button(buttonComposite, SWT.None); |
| this.btnDelete.setText("Delete"); |
| this.btnDelete.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); |
| this.btnDelete.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| if (getSelectedFilter() != null) { |
| ApogyCommonTransactionFacade.INSTANCE.basicRemove(getCameraViewConfiguration().getFilterList(), |
| ApogyAddonsSensorsImagingCameraPackage.Literals.FILTER_LIST__IMAGE_FILTERS, |
| getSelectedFilter()); |
| } |
| } |
| }); |
| |
| this.btnUp = new Button(buttonComposite, SWT.NONE); |
| this.btnUp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); |
| this.btnUp.setSize(74, 29); |
| this.btnUp.setText("Up"); |
| this.btnUp.setEnabled(false); |
| this.btnUp.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent event) { |
| if (getSelectedFilter() != null) { |
| ImageFilter imageFilter = getSelectedFilter(); |
| |
| int index = getCameraViewConfiguration().getFilterList().getImageFilters().indexOf(imageFilter); |
| |
| if (index > 0) { |
| getCameraViewConfiguration().getFilterList().getImageFilters().move(index - 1, index); |
| |
| // Forces the viewer to refresh its input. |
| if (!FiltersListComposite.this.treeViewer.isBusy()) { |
| FiltersListComposite.this.treeViewer.refresh(); |
| } |
| } |
| } |
| } |
| }); |
| |
| this.btnDown = new Button(buttonComposite, SWT.NONE); |
| this.btnDown.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); |
| this.btnDown.setSize(74, 29); |
| this.btnDown.setText("Down"); |
| this.btnDown.setEnabled(false); |
| this.btnDown.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent event) { |
| if (getSelectedFilter() != null) { |
| ImageFilter imageFilter = getSelectedFilter(); |
| |
| int listSize = getCameraViewConfiguration().getFilterList().getImageFilters().size(); |
| int index = getCameraViewConfiguration().getFilterList().getImageFilters().indexOf(imageFilter); |
| |
| if (index < (listSize - 1)) { |
| getCameraViewConfiguration().getFilterList().getImageFilters().move(index + 1, index); |
| |
| // Forces the viewer to refresh its input. |
| if (!FiltersListComposite.this.treeViewer.isBusy()) { |
| FiltersListComposite.this.treeViewer.refresh(); |
| } |
| } |
| } |
| } |
| }); |
| |
| Label separator = new Label(this, SWT.SEPARATOR); |
| separator.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true, 1, 2)); |
| |
| Composite toggleVisibleComposite = new Composite(this, SWT.None); |
| toggleVisibleComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1)); |
| toggleVisibleComposite.setLayout(new GridLayout(1, false)); |
| |
| this.btnVisible = new Button(toggleVisibleComposite, SWT.None); |
| this.btnVisible.setText("Toggle Active"); |
| this.btnVisible.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, true, 1, 1)); |
| this.btnVisible.setVisible(false); |
| this.btnVisible.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| if (getSelectedFilter() != null) { |
| ApogyCommonTransactionFacade.INSTANCE.basicSet(getSelectedFilter(), |
| ApogyAddonsSensorsImagingCameraPackage.Literals.IMAGE_FILTER__ENABLED, |
| !getSelectedFilter().isEnabled()); |
| } |
| } |
| }); |
| |
| this.scrolledComposite = new ScrolledComposite(this, SWT.H_SCROLL | SWT.V_SCROLL); |
| this.scrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); |
| this.scrolledComposite.setExpandHorizontal(true); |
| this.scrolledComposite.setExpandVertical(true); |
| |
| this.emfFormsComposite = new Composite(this.scrolledComposite, SWT.None); |
| this.scrolledComposite.setContent(this.emfFormsComposite); |
| this.scrolledComposite.setMinSize(this.emfFormsComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); |
| |
| updateEMFForms(); |
| |
| addDisposeListener(new DisposeListener() { |
| |
| @Override |
| public void widgetDisposed(DisposeEvent e) { |
| if (FiltersListComposite.this.cameraViewConfiguration != null) { |
| for (FeaturePathAdapter adapter : getFeaturePathAdapter()) { |
| adapter.dispose(); |
| } |
| } |
| |
| if (FiltersListComposite.this.m_bindingContext != null) |
| FiltersListComposite.this.m_bindingContext.dispose(); |
| } |
| }); |
| |
| } |
| |
| /** |
| * Updates the EMFForms displaying the image annotation selected. |
| */ |
| private void updateEMFForms() { |
| if (!this.emfFormsComposite.isDisposed()) { |
| for (Control control : this.emfFormsComposite.getChildren()) { |
| if (!control.isDisposed()) |
| control.dispose(); |
| } |
| |
| ApogyCommonEMFUiEMFFormsFacade.INSTANCE.createEMFForms(this.emfFormsComposite, getSelectedFilter(), |
| "No compatible selection"); |
| |
| if (!this.scrolledComposite.isDisposed()) |
| this.scrolledComposite.setMinSize(this.emfFormsComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); |
| } |
| } |
| |
| protected void newSelection() { |
| |
| } |
| |
| public ImageFilter getSelectedFilter() { |
| if (this.treeViewer.getStructuredSelection() != null |
| && this.treeViewer.getStructuredSelection().getFirstElement() != null) { |
| Object object = this.treeViewer.getStructuredSelection().getFirstElement(); |
| |
| if (object instanceof ImageFilter) { |
| return (ImageFilter) object; |
| } |
| } |
| return null; |
| } |
| |
| public CameraViewConfiguration getCameraViewConfiguration() { |
| return this.cameraViewConfiguration; |
| } |
| |
| public void setCameraViewConfiguration(CameraViewConfiguration cameraViewConfiguration) { |
| if (this.m_bindingContext != null) |
| this.m_bindingContext.dispose(); |
| |
| if (this.cameraViewConfiguration != null) { |
| for (FeaturePathAdapter adapter : getFeaturePathAdapter()) { |
| adapter.dispose(); |
| } |
| } |
| this.cameraViewConfiguration = cameraViewConfiguration; |
| |
| if (cameraViewConfiguration != null) { |
| this.treeViewer.setInput(this.cameraViewConfiguration.getFilterList()); |
| |
| for (FeaturePathAdapter adapter : getFeaturePathAdapter()) { |
| adapter.init(this.cameraViewConfiguration); |
| } |
| |
| this.m_bindingContext = customInitDataBindings(); |
| |
| this.btnNew.setEnabled(true); |
| this.btnDelete.setEnabled(true); |
| } else { |
| this.treeViewer.setInput(null); |
| |
| this.btnNew.setEnabled(false); |
| this.btnDelete.setEnabled(false); |
| } |
| } |
| |
| private List<FeaturePathAdapter> getFeaturePathAdapter() { |
| if (this.featurePathAdapters == null) { |
| this.featurePathAdapters = new ArrayList<FeaturePathAdapter>(); |
| |
| this.featurePathAdapters.add(new FeaturePathAdapterCustomImpl() { |
| |
| @Override |
| public List<? extends EStructuralFeature> getFeatureList() { |
| List<EStructuralFeature> list = new ArrayList<EStructuralFeature>(); |
| |
| list.add(ApogyAddonsSensorsImagingCameraPackage.Literals.CAMERA_VIEW_CONFIGURATION__FILTER_LIST); |
| list.add(ApogyAddonsSensorsImagingCameraPackage.Literals.FILTER_LIST__IMAGE_FILTERS); |
| list.add(ApogyCommonEMFPackage.Literals.NAMED__NAME); |
| |
| return list; |
| } |
| |
| @Override |
| public void notifyChanged(Notification msg) { |
| FiltersListComposite.this.treeViewer.refresh(); |
| } |
| }); |
| this.featurePathAdapters.add(new FeaturePathAdapterCustomImpl() { |
| |
| @Override |
| public List<? extends EStructuralFeature> getFeatureList() { |
| List<EStructuralFeature> list = new ArrayList<EStructuralFeature>(); |
| |
| list.add(ApogyAddonsSensorsImagingCameraPackage.Literals.CAMERA_VIEW_CONFIGURATION__FILTER_LIST); |
| list.add(ApogyAddonsSensorsImagingCameraPackage.Literals.FILTER_LIST__IMAGE_FILTERS); |
| list.add(ApogyAddonsSensorsImagingCameraPackage.Literals.IMAGE_FILTER__ENABLED); |
| |
| return list; |
| } |
| |
| @Override |
| public void notifyChanged(Notification msg) { |
| FiltersListComposite.this.treeViewer.refresh(); |
| } |
| }); |
| } |
| return this.featurePathAdapters; |
| } |
| |
| protected AdapterFactoryContentProvider getContentProvider() { |
| return new AdapterFactoryContentProvider(this.adapterFactory) { |
| @Override |
| public Object[] getElements(Object object) { |
| if (FiltersListComposite.this.cameraViewConfiguration != null |
| && FiltersListComposite.this.cameraViewConfiguration.getFilterList() != null |
| && FiltersListComposite.this.cameraViewConfiguration.getFilterList() |
| .getImageFilters() != null) { |
| |
| return FiltersListComposite.this.cameraViewConfiguration.getFilterList().getImageFilters() |
| .toArray(); |
| } |
| return null; |
| } |
| |
| @Override |
| public Object[] getChildren(Object object) { |
| return null; |
| } |
| }; |
| } |
| |
| protected AdapterFactoryLabelProvider getLabelProvider() { |
| return new AdapterFactoryLabelProvider(this.adapterFactory) { |
| @Override |
| public String getText(Object object) { |
| if (object instanceof ImageFilter) { |
| ImageFilter filter = ((ImageFilter) object); |
| String label = filter.getName(); |
| |
| if (filter.isEnabled()) { |
| label += " <enabled>"; |
| } |
| return label; |
| } |
| return ""; |
| } |
| |
| @Override |
| public Image getImage(Object object) { |
| return null; |
| } |
| }; |
| } |
| |
| protected DataBindingContext customInitDataBindings() { |
| DataBindingContext bindingContext = new DataBindingContext(); |
| |
| IObservableValue<?> observeSingleSelectionViewer = ViewerProperties.singleSelection().observe(this.treeViewer); |
| |
| /* Up Button Enabled Binding. */ |
| IObservableValue<?> observeBtnUpObserveWidget = WidgetProperties.enabled().observe(this.btnUp); |
| bindingContext.bindValue(observeBtnUpObserveWidget, observeSingleSelectionViewer, null, |
| new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE) |
| .setConverter(new Converter(Object.class, Boolean.class) { |
| @Override |
| public Object convert(Object fromObject) { |
| return fromObject != null; |
| } |
| })); |
| |
| /* Down Button Enabled Binding. */ |
| IObservableValue<?> observeBtnDownObserveWidget = WidgetProperties.enabled().observe(this.btnDown); |
| bindingContext.bindValue(observeBtnDownObserveWidget, observeSingleSelectionViewer, null, |
| new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE) |
| .setConverter(new Converter(Object.class, Boolean.class) { |
| @Override |
| public Object convert(Object fromObject) { |
| return fromObject != null; |
| } |
| })); |
| |
| return bindingContext; |
| } |
| |
| } |