blob: 023a75bb0937865746d2d111072ad8edc1d64daf [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 - initial API and implementation
*
* SPDX-License-Identifier: EPL-1.0
*
*******************************************************************************/
package org.eclipse.apogy.common.io.jinput.ui.composites;
import java.util.Arrays;
import java.util.List;
import org.eclipse.apogy.common.emf.transaction.ApogyCommonTransactionFacade;
import org.eclipse.apogy.common.io.jinput.Activator;
import org.eclipse.apogy.common.io.jinput.ApogyCommonIOJInputFacade;
import org.eclipse.apogy.common.io.jinput.ApogyCommonIOJInputPackage;
import org.eclipse.apogy.common.io.jinput.EComponentQualifier;
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.databinding.EMFProperties;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Color;
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.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
public class AutomaticControllerSelectionComposite extends Composite {
final String CLICK_PROMPT = "Click here to bind the controller";
private final Text controllerText;
private final Text componentText;
private boolean selectionStarted = false;
private Listener listener;
private EComponentQualifier eComponentQualifier;
private String initialControllerName;
private String initialComponentName;
private DataBindingContext m_bindingContext;
/**
* Create the parentComposite.
*
* @param parent Reference to the parent parentComposite.
* @param style Composite style.
*/
public AutomaticControllerSelectionComposite(Composite parent, int style) {
super(parent, style);
setLayout(new GridLayout(2, false));
addFocusListener(new FocusListener() {
@Override
public void focusLost(FocusEvent e) {
if (AutomaticControllerSelectionComposite.this.selectionStarted) {
stopSelection();
}
}
@Override
public void focusGained(FocusEvent e) {
}
});
Label controllerLabel = new Label(this, SWT.None);
controllerLabel.setText("Controller : ");
controllerLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
this.controllerText = new Text(this, SWT.BORDER);
this.controllerText.setText(this.CLICK_PROMPT);
this.controllerText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
this.controllerText.addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {
if (!AutomaticControllerSelectionComposite.this.selectionStarted) {
startSelection();
}
}
});
this.controllerText.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
if (AutomaticControllerSelectionComposite.this.selectionStarted) {
stopSelection();
}
}
});
Label componentLabel = new Label(this, SWT.None);
componentLabel.setText("Component : ");
componentLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
this.componentText = new Text(this, SWT.BORDER);
this.componentText.setText(this.CLICK_PROMPT);
this.componentText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
this.componentText.addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {
if (!AutomaticControllerSelectionComposite.this.selectionStarted) {
startSelection();
}
}
});
this.componentText.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
if (AutomaticControllerSelectionComposite.this.selectionStarted) {
stopSelection();
}
}
});
// Dispose
addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
if (AutomaticControllerSelectionComposite.this.m_bindingContext != null)
AutomaticControllerSelectionComposite.this.m_bindingContext.dispose();
}
});
}
/**
* Starts the controller selection.
*/
private void startSelection() {
if (!ApogyCommonIOJInputFacade.INSTANCE.isSelectingComponent()) {
/** Start the selection */
this.selectionStarted = true;
if (this.eComponentQualifier != null) {
this.initialControllerName = this.eComponentQualifier.getEControllerName();
this.initialComponentName = this.eComponentQualifier.getEComponentName();
}
ApogyCommonIOJInputFacade.INSTANCE.startSelectComponent(this.eComponentQualifier);
}
this.controllerText.setBackground(getTextsBackgroundColor());
this.componentText.setBackground(getTextsBackgroundColor());
/** Changes the traverse listener of the shell */
List<Listener> listeners = Arrays.asList(getShell().getListeners(SWT.Traverse));
for (Listener listener : listeners) {
getShell().removeListener(SWT.Traverse, listener);
}
getShell().addListener(SWT.Traverse, getListener());
for (Listener listener : listeners) {
getShell().addListener(SWT.Traverse, listener);
}
}
/**
* {@link Listener} that cancels the selection if the user presses escape and
* confirms the selection if the user presses enter
*
* @return {@link Listener}
*/
private Listener getListener() {
if (this.listener == null) {
this.listener = new Listener() {
@Override
public void handleEvent(Event event) {
if (event.detail == SWT.TRAVERSE_ESCAPE || event.detail == SWT.TRAVERSE_RETURN) {
stopSelection();
if (event.detail == SWT.TRAVERSE_ESCAPE
&& AutomaticControllerSelectionComposite.this.eComponentQualifier != null) {
if (ApogyCommonTransactionFacade.INSTANCE.getTransactionalEditingDomain(
AutomaticControllerSelectionComposite.this.eComponentQualifier) != null) {
ApogyCommonTransactionFacade.INSTANCE.basicSet(
AutomaticControllerSelectionComposite.this.eComponentQualifier,
ApogyCommonIOJInputPackage.Literals.ECOMPONENT_QUALIFIER__ECONTROLLER_NAME,
AutomaticControllerSelectionComposite.this.initialControllerName);
ApogyCommonTransactionFacade.INSTANCE.basicSet(
AutomaticControllerSelectionComposite.this.eComponentQualifier,
ApogyCommonIOJInputPackage.Literals.ECOMPONENT_QUALIFIER__ECOMPONENT_NAME,
AutomaticControllerSelectionComposite.this.initialComponentName);
} else {
AutomaticControllerSelectionComposite.this.eComponentQualifier.setEControllerName(
AutomaticControllerSelectionComposite.this.initialControllerName);
AutomaticControllerSelectionComposite.this.eComponentQualifier.setEComponentName(
AutomaticControllerSelectionComposite.this.initialComponentName);
}
}
event.doit = false;
}
}
};
}
return this.listener;
}
/**
* Stops the controller selection.
*/
private void stopSelection() {
ApogyCommonIOJInputFacade.INSTANCE.stopSelectComponent(this.eComponentQualifier);
this.selectionStarted = false;
this.controllerText.setBackground(getTextsBackgroundColor());
this.componentText.setBackground(getTextsBackgroundColor());
newSelection(null);
getShell().removeListener(SWT.Traverse, getListener());
}
/**
* Binds the {@link EComponentQualifier} with the UI components.
*
* @param eComponentQualifier Reference to the {@link EComponentQualifier}.
*/
public void setEComponentQualifier(EComponentQualifier eComponentQualifier) {
if (this.m_bindingContext != null) {
this.m_bindingContext.dispose();
}
this.eComponentQualifier = eComponentQualifier;
if (eComponentQualifier != null) {
initDataBindingsCustom();
if (eComponentQualifier.getEControllerName() != null) {
this.controllerText.setText(eComponentQualifier.getEControllerName());
}
if (eComponentQualifier.getEComponentName() != null) {
this.componentText.setText(eComponentQualifier.getEComponentName());
}
}
this.controllerText.setBackground(getTextsBackgroundColor());
this.componentText.setBackground(getTextsBackgroundColor());
}
protected void newSelection(ISelection selection) {
}
/**
* Returns yellow if the selection is activated. Returns red is the
* {@link EComponentQualifier} is not valid. Returns red is the
* {@link EComponentQualifier} is valid.
*
* @return {@link Color}
*/
private Color getTextsBackgroundColor() {
if (this.selectionStarted) {
return Display.getCurrent().getSystemColor(SWT.COLOR_YELLOW);
}
if (Activator.getEControllerEnvironment().resolveEComponent(this.eComponentQualifier) != null) {
return Display.getCurrent().getSystemColor(SWT.COLOR_GREEN);
} else {
return Display.getCurrent().getSystemColor(SWT.COLOR_RED);
}
}
protected DataBindingContext initDataBindingsCustom() {
this.m_bindingContext = new DataBindingContext();
@SuppressWarnings("unchecked")
IObservableValue<?> observeEComponentQualifierControllerName = EMFProperties
.value(ApogyCommonIOJInputPackage.Literals.ECOMPONENT_QUALIFIER__ECONTROLLER_NAME)
.observe(this.eComponentQualifier);
IObservableValue<?> observeControllerTextText = WidgetProperties.text().observe(this.controllerText);
IObservableValue<?> observeControllerTextBackground = WidgetProperties.background()
.observe(this.controllerText);
/** Controller name binding */
this.m_bindingContext.bindValue(observeControllerTextText, observeEComponentQualifierControllerName,
new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER),
new UpdateValueStrategy().setConverter(new Converter(String.class, String.class) {
@Override
public Object convert(Object fromObject) {
newSelection(null);
return fromObject == null ? AutomaticControllerSelectionComposite.this.CLICK_PROMPT
: fromObject;
}
}));
/** Controller background binding */
this.m_bindingContext.bindValue(observeControllerTextBackground, observeEComponentQualifierControllerName,
new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER),
new UpdateValueStrategy().setConverter(new Converter(String.class, Color.class) {
@Override
public Object convert(Object fromObject) {
return getTextsBackgroundColor();
}
}));
@SuppressWarnings("unchecked")
IObservableValue<?> observeEComponentQualifierComponentName = EMFProperties
.value(ApogyCommonIOJInputPackage.Literals.ECOMPONENT_QUALIFIER__ECOMPONENT_NAME)
.observe(this.eComponentQualifier);
IObservableValue<?> observeComponentTextText = WidgetProperties.text().observe(this.componentText);
IObservableValue<?> observeComponentTextBackground = WidgetProperties.background().observe(this.controllerText);
/** Component name binding */
this.m_bindingContext.bindValue(observeComponentTextText, observeEComponentQualifierComponentName,
new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER),
new UpdateValueStrategy().setConverter(new Converter(String.class, String.class) {
@Override
public Object convert(Object fromObject) {
newSelection(null);
return fromObject == null ? AutomaticControllerSelectionComposite.this.CLICK_PROMPT
: fromObject;
}
}));
/** Component background binding */
this.m_bindingContext.bindValue(observeComponentTextBackground, observeEComponentQualifierComponentName,
new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER),
new UpdateValueStrategy().setConverter(new Converter(String.class, Color.class) {
@Override
public Object convert(Object fromObject) {
return getTextsBackgroundColor();
}
}));
return this.m_bindingContext;
}
}