| /******************************************************************************* |
| * 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, |
| * Olivier L. Larouche - initial API and implementation |
| * |
| * SPDX-License-Identifier: EPL-1.0 |
| *******************************************************************************/ |
| package org.eclipse.apogy.core.programs.controllers.ui.composite; |
| |
| import org.eclipse.apogy.common.emf.ApogyCommonEMFPackage; |
| import org.eclipse.apogy.common.ui.composites.NoContentComposite; |
| import org.eclipse.apogy.core.programs.controllers.BindedEDataTypeArgument; |
| import org.eclipse.apogy.core.programs.controllers.ControllerValueSource; |
| import org.eclipse.apogy.core.programs.controllers.OperationCallControllerBinding; |
| import org.eclipse.emf.common.notify.Adapter; |
| import org.eclipse.emf.common.notify.Notification; |
| import org.eclipse.emf.common.notify.impl.AdapterImpl; |
| import org.eclipse.jface.viewers.ISelection; |
| 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.layout.FillLayout; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.ui.forms.widgets.ExpandableComposite; |
| import org.eclipse.ui.forms.widgets.FormToolkit; |
| import org.eclipse.ui.forms.widgets.Section; |
| |
| public class BindedArgumentComposite extends ScrolledComposite { |
| |
| private final FormToolkit toolkit = new FormToolkit(Display.getCurrent()); |
| |
| private final Composite composite; |
| |
| private final ValueSourceComposite compositeValueSource; |
| private Label startedLabel; |
| |
| private final Section sectionConditioning; |
| private Composite compositeConditioning; |
| |
| private BindedEDataTypeArgument bindedEDataTypeArgument; |
| |
| private Adapter adapter; |
| |
| /** |
| * Create the parentComposite. |
| * |
| * @param parent Reference to the parent parentComposite. |
| * @param style Composite style. |
| */ |
| public BindedArgumentComposite(Composite parent, int style) { |
| super(parent, style); |
| this.computeSize(1, 1); |
| setExpandHorizontal(true); |
| setExpandVertical(true); |
| addDisposeListener(new DisposeListener() { |
| |
| @Override |
| public void widgetDisposed(DisposeEvent e) { |
| if (BindedArgumentComposite.this.bindedEDataTypeArgument != null |
| && BindedArgumentComposite.this.bindedEDataTypeArgument.getOperationCall() != null) { |
| BindedArgumentComposite.this.bindedEDataTypeArgument.getOperationCall().eAdapters() |
| .remove(getAdapter()); |
| } |
| BindedArgumentComposite.this.toolkit.dispose(); |
| } |
| }); |
| |
| this.composite = new Composite(this, SWT.None); |
| this.composite.setLayout(new GridLayout(2, true)); |
| |
| /** |
| * Value source |
| */ |
| this.compositeValueSource = new ValueSourceComposite(this.composite, SWT.None) { |
| @Override |
| protected void newSelection(ISelection selection) { |
| BindedArgumentComposite.this.newSelection(selection); |
| updateCompositeConditioning(); |
| } |
| }; |
| this.compositeValueSource.setLayout(new FillLayout()); |
| this.compositeValueSource.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); |
| this.compositeValueSource.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); |
| this.compositeValueSource.setBackgroundMode(SWT.INHERIT_FORCE); |
| |
| /** |
| * Conditioning |
| */ |
| this.sectionConditioning = this.toolkit.createSection(this.composite, |
| ExpandableComposite.EXPANDED | ExpandableComposite.TITLE_BAR); |
| this.sectionConditioning.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); |
| this.sectionConditioning.setLayout(new FillLayout()); |
| this.sectionConditioning.setText("Conditioning"); |
| this.compositeConditioning = getNoContentComposite(this.sectionConditioning); |
| |
| setContent(this.composite); |
| setMinSize(this.composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); |
| |
| } |
| |
| /** |
| * Binds the {@link BindedEDataTypeArgument} with the UI components. |
| * |
| * @param bindedEDataTypeArgument Reference to the |
| * {@link BindedEDataTypeArgument}. |
| */ |
| public void setBindedEDataTypeArgument(BindedEDataTypeArgument bindedEDataTypeArgument) { |
| if (this.bindedEDataTypeArgument != null && this.bindedEDataTypeArgument.getOperationCall() != null) { |
| this.bindedEDataTypeArgument.getOperationCall().eAdapters().remove(getAdapter()); |
| } |
| |
| this.bindedEDataTypeArgument = bindedEDataTypeArgument; |
| |
| this.compositeValueSource.setBindedEDataTypeArgument(bindedEDataTypeArgument); |
| updateCompositeConditioning(); |
| |
| if (this.bindedEDataTypeArgument.getOperationCall() != null) { |
| setEnabled(!((OperationCallControllerBinding) this.bindedEDataTypeArgument.getOperationCall()).isStarted()); |
| this.bindedEDataTypeArgument.getOperationCall().eAdapters().add(getAdapter()); |
| } |
| } |
| |
| /** |
| * Updates the conditioning composite depending on the selected argument. |
| */ |
| private void updateCompositeConditioning() { |
| if (this.compositeConditioning != null) { |
| this.compositeConditioning.dispose(); |
| } |
| |
| if (this.bindedEDataTypeArgument != null |
| && this.bindedEDataTypeArgument.getValueSource() instanceof ControllerValueSource) { |
| this.compositeConditioning = new ConditioningComposite(this.sectionConditioning, SWT.NO_SCROLL) { |
| @Override |
| protected void newSelection(ISelection selection) { |
| BindedArgumentComposite.this.newSelection(selection); |
| } |
| }; |
| ((ConditioningComposite) this.compositeConditioning).setAbstractInputConditioning( |
| ((ControllerValueSource) this.bindedEDataTypeArgument.getValueSource()).getConditioning()); |
| |
| if (((ControllerValueSource) this.bindedEDataTypeArgument.getValueSource()) |
| .getEComponentQualifier() != null) { |
| ((ConditioningComposite) this.compositeConditioning) |
| .setEComponentQualifier(((ControllerValueSource) this.bindedEDataTypeArgument.getValueSource()) |
| .getEComponentQualifier()); |
| } |
| |
| this.compositeConditioning.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); |
| } else { |
| this.compositeConditioning = getNoContentComposite(this.sectionConditioning); |
| } |
| |
| this.sectionConditioning.setClient(this.compositeConditioning); |
| this.sectionConditioning.layout(); |
| layout(); |
| } |
| |
| /** |
| * Returns a {@link NoContentComposite} if a detail section is not applicable. |
| * |
| * @param section The parent {@link Section}. |
| * @return Reference to the {@link NoContentComposite}. |
| */ |
| private Composite getNoContentComposite(Composite parent) { |
| NoContentComposite composite = new NoContentComposite(parent, SWT.None) { |
| @Override |
| protected String getMessage() { |
| return "No compatible selection"; |
| } |
| }; |
| composite.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); |
| composite.setBackgroundMode(SWT.INHERIT_FORCE); |
| return composite; |
| } |
| |
| /** |
| * This method is called when a new selection is made . |
| * |
| * @param selection Reference to the selection. |
| */ |
| protected void newSelection(ISelection selection) { |
| } |
| |
| private Adapter getAdapter() { |
| if (this.adapter == null) { |
| this.adapter = new AdapterImpl() { |
| @Override |
| public void notifyChanged(Notification msg) { |
| if (msg.getFeature() == ApogyCommonEMFPackage.Literals.STARTABLE__STARTED) { |
| setEnableUI(!msg.getNewBooleanValue()); |
| } |
| } |
| }; |
| } |
| return this.adapter; |
| } |
| |
| /** |
| * Enables and disables the UI. This is used to be sure that the arguments don't |
| * change while executing. |
| */ |
| private void setEnableUI(boolean value) { |
| if (value) { |
| if (this.startedLabel != null && !this.startedLabel.isDisposed()) { |
| /** Remove the label */ |
| this.startedLabel.dispose(); |
| |
| this.compositeValueSource.moveAbove(this.sectionConditioning); |
| this.sectionConditioning.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); |
| } |
| } else { |
| if (this.startedLabel == null || this.startedLabel.isDisposed()) { |
| /** Add a label */ |
| this.startedLabel = new Label(this.composite, SWT.WRAP); |
| this.startedLabel.setText("Controller active, deactivate to edit"); |
| this.startedLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1)); |
| |
| this.sectionConditioning.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 2)); |
| this.sectionConditioning.moveAbove(this.compositeValueSource); |
| this.startedLabel.moveAbove(this.sectionConditioning); |
| } |
| } |
| |
| if (this.compositeValueSource.isEnabled() != value) { |
| this.compositeValueSource.setEnabled(value); |
| } |
| |
| this.composite.layout(); |
| } |
| |
| } |