diff options
author | Torsten Sommer | 2013-05-17 17:51:00 +0000 |
---|---|---|
committer | Torsten Sommer | 2013-05-17 17:51:00 +0000 |
commit | 46410356c80d6e354914add57b0438d88f8cc86a (patch) | |
tree | ca23bc87d3c3820979f3ca1f88c616e94d2df7d9 | |
parent | 228107c8760b8daafe0adcb2a1ce5155c2c113c4 (diff) | |
download | org.eclipse.efxclipse-46410356c80d6e354914add57b0438d88f8cc86a.tar.gz org.eclipse.efxclipse-46410356c80d6e354914add57b0438d88f8cc86a.tar.xz org.eclipse.efxclipse-46410356c80d6e354914add57b0438d88f8cc86a.zip |
Controls changed to Java FX properties.
18 files changed, 613 insertions, 532 deletions
diff --git a/.gitignore b/.gitignore index 9d89fa03f..392e95cd9 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /org.eclipse.osgi +bin/ diff --git a/bundles/runtime/org.eclipse.fx.ecp.ui/META-INF/MANIFEST.MF b/bundles/runtime/org.eclipse.fx.ecp.ui/META-INF/MANIFEST.MF index be2db9508..b8047efa9 100644 --- a/bundles/runtime/org.eclipse.fx.ecp.ui/META-INF/MANIFEST.MF +++ b/bundles/runtime/org.eclipse.fx.ecp.ui/META-INF/MANIFEST.MF @@ -12,7 +12,8 @@ Require-Bundle: org.eclipse.core.runtime, com.google.guava;bundle-version="10.0.1", org.eclipse.fx.emf.edit.ui;bundle-version="0.8.1", org.eclipse.fx.ecp.dummy;bundle-version="1.0.0", - org.eclipse.e4.ui.workbench;bundle-version="0.11.0" + org.eclipse.e4.ui.workbench;bundle-version="0.11.0", + org.eclipse.fx.emf.databinding;bundle-version="0.8.1" Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.fx.ecp.ui Service-Component: OSGI-INF/modelElementOpener.xml diff --git a/bundles/runtime/org.eclipse.fx.ecp.ui/plugin.xml b/bundles/runtime/org.eclipse.fx.ecp.ui/plugin.xml index b1fd96fb4..7ca30d9e9 100644 --- a/bundles/runtime/org.eclipse.fx.ecp.ui/plugin.xml +++ b/bundles/runtime/org.eclipse.fx.ecp.ui/plugin.xml @@ -22,6 +22,7 @@ <factory class="org.eclipse.fx.ecp.ui.controls.CheckBoxControl$Factory" + multi="false" id="org.eclipse.fx.ecp.ui.controls.checkBox" showLabel="true"> <staticTest @@ -33,6 +34,7 @@ <factory class="org.eclipse.fx.ecp.ui.controls.TextFieldControl$Factory" + multi="false" id="org.eclipse.fx.ecp.ui.controls.textField" showLabel="true"> @@ -90,6 +92,7 @@ </factory> <factory class="org.eclipse.fx.ecp.ui.controls.EnumControl$Factory" + multi="false" id="org.eclipse.fx.ecp.ui.controls.enumCombo" showLabel="true"> <staticTest @@ -100,6 +103,7 @@ </factory> <factory class="org.eclipse.fx.ecp.ui.controls.MultiControl$Factory" + multi="true" id="org.eclipse.fx.ecp.ui.controls.multiText" showLabel="true"> <staticTest diff --git a/bundles/runtime/org.eclipse.fx.ecp.ui/schema/controls.exsd b/bundles/runtime/org.eclipse.fx.ecp.ui/schema/controls.exsd index 3e485d237..714c2dc74 100644 --- a/bundles/runtime/org.eclipse.fx.ecp.ui/schema/controls.exsd +++ b/bundles/runtime/org.eclipse.fx.ecp.ui/schema/controls.exsd @@ -55,7 +55,6 @@ </annotation> <complexType> <choice> - <element ref="dynamicTest"/> <element ref="staticTest" minOccurs="1" maxOccurs="unbounded"/> </choice> <attribute name="id" type="string" use="required"> @@ -82,24 +81,11 @@ </documentation> </annotation> </attribute> - </complexType> - </element> - - <element name="dynamicTest"> - <annotation> - <documentation> - A dynamic test simply provides an implementation of the org.eclipse.emf.ecp.edit.util.ECPApplicableTester interface. - </documentation> - </annotation> - <complexType> - <attribute name="testClass" type="string" use="required"> + <attribute name="multi" type="boolean" use="required"> <annotation> <documentation> - The implementation of the tester. The Class must extend the org.eclipse.emf.ecp.edit.util.ECPApplicableTester. + Whether the control can be embedded into a multi-control. The default is true. </documentation> - <appinfo> - <meta.attribute kind="java" basedOn=":org.eclipse.emf.ecp.edit.util.ECPApplicableTester"/> - </appinfo> </annotation> </attribute> </complexType> diff --git a/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/Control.java b/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/Control.java index ba2b6b12d..2cca18e63 100644 --- a/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/Control.java +++ b/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/Control.java @@ -2,51 +2,62 @@ package org.eclipse.fx.ecp.ui; import java.util.Set; +import javafx.beans.property.Property; + import org.eclipse.emf.common.util.Diagnostic; import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecp.edit.ECPControlContext; -import org.eclipse.emf.ecp.edit.util.ECPApplicableTester; -import org.eclipse.emf.edit.provider.IItemPropertyDescriptor; import org.eclipse.fx.ecp.ui.impl.ControlFactoryRegistryImpl; +@SuppressWarnings("restriction") public interface Control { - + void handleValidation(Diagnostic diagnostic); - + void resetValidation(); interface Factory { - - Control createControl(IItemPropertyDescriptor itemPropertyDescriptor, ECPControlContext context); - + + Control createControl(Property<?> property, EStructuralFeature feature, ECPControlContext context); + interface Descriptor { - + /** * Creates a factory and returns it. * <p> - * An implementation may and usually does choose to create only one instance, - * which it returns for each call. + * An implementation may and usually does choose to create only one instance, which it returns for + * each call. * </p> + * * @return a factory. */ Factory createFactory(); - + String getID(); - + boolean showLabel(); - - Set<ECPApplicableTester> getTesters(); - + + Set<ApplicableTester> getTesters(); + } - + interface Registry { - + Registry INSTANCE = new ControlFactoryRegistryImpl(); - - Factory getFactory(Class<?> controlClass, IItemPropertyDescriptor propertyDescriptor, EObject modelElement); - + + Factory getFactory(EStructuralFeature feature, EObject modelElement, boolean multi); + } - + + } + + public interface ApplicableTester { + + int NOT_APPLICABLE = -1; + + int isApplicable(EStructuralFeature feature, EObject eObject); + } } diff --git a/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/DummyControlFactory.java b/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/DummyControlFactory.java deleted file mode 100644 index 3e3621c82..000000000 --- a/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/DummyControlFactory.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.eclipse.fx.ecp.ui; - -import org.eclipse.emf.ecp.edit.ECPControlContext; -import org.eclipse.emf.edit.provider.IItemPropertyDescriptor; - -@SuppressWarnings("restriction") -public class DummyControlFactory implements Control.Factory { - - @Override - public Control createControl(IItemPropertyDescriptor itemPropertyDescriptor, ECPControlContext context) { - return null; - } - -} diff --git a/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/CheckBoxControl.java b/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/CheckBoxControl.java index 1a11b1673..43037771c 100644 --- a/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/CheckBoxControl.java +++ b/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/CheckBoxControl.java @@ -1,32 +1,17 @@ package org.eclipse.fx.ecp.ui.controls; +import javafx.beans.property.Property; import javafx.scene.control.CheckBox; -import javafx.scene.layout.VBox; import org.eclipse.emf.common.util.Diagnostic; -import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecp.edit.ECPControlContext; -import org.eclipse.emf.edit.provider.IItemPropertyDescriptor; import org.eclipse.fx.ecp.ui.Control; -@SuppressWarnings("restriction") -public class CheckBoxControl extends VBox implements Control { +public class CheckBoxControl extends CheckBox implements Control { - public CheckBoxControl(IItemPropertyDescriptor propertyDescriptor, ECPControlContext context) { - getStyleClass().add("formControl"); - - EObject modelElement = context.getModelElement(); - - EStructuralFeature feature = (EStructuralFeature) propertyDescriptor.getFeature(modelElement); - Object val = modelElement.eGet(feature); - - CheckBox checkBox = new CheckBox(); - checkBox.setSelected((Boolean) val); - - getChildren().add(checkBox); - - getChildren().add(new ValidationMessage()); + public CheckBoxControl(Property<Boolean> property, ECPControlContext context) { + selectedProperty().bindBidirectional(property); } @Override @@ -44,8 +29,8 @@ public class CheckBoxControl extends VBox implements Control { public static class Factory implements Control.Factory { @Override - public Control createControl(IItemPropertyDescriptor itemPropertyDescriptor, ECPControlContext context) { - return new CheckBoxControl(itemPropertyDescriptor, context); + public Control createControl(Property<?> property, EStructuralFeature feature, ECPControlContext context) { + return new CheckBoxControl((Property<Boolean>) property, context); } } diff --git a/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/DummyControl.java b/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/DummyControl.java index ca3ef987f..52607d297 100644 --- a/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/DummyControl.java +++ b/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/DummyControl.java @@ -1,38 +1,20 @@ package org.eclipse.fx.ecp.ui.controls; -import javafx.scene.control.Label; +import javafx.beans.property.Property; import javafx.scene.control.TextField; -import javafx.scene.layout.HBox; -import javafx.scene.layout.Priority; import org.eclipse.emf.common.util.Diagnostic; -import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecp.edit.ECPControlContext; -import org.eclipse.emf.edit.provider.IItemPropertyDescriptor; import org.eclipse.fx.ecp.ui.Control; @SuppressWarnings("restriction") -public class DummyControl extends HBox implements Control { +public class DummyControl extends TextField implements Control { - public DummyControl(IItemPropertyDescriptor propertyDescriptor, ECPControlContext context) { - EObject modelElement = context.getModelElement(); - - String displayName = propertyDescriptor.getDisplayName(modelElement); - Label label = new Label(displayName); - label.getStyleClass().add(IControlConstants.CONTROL_LABEL_CLASS); - getChildren().add(label); - - EStructuralFeature feature = (EStructuralFeature) propertyDescriptor.getFeature(modelElement); - Object val = modelElement.eGet(feature); - - TextField textField = new TextField(); - textField.setText(val.toString()); - textField.setDisable(true); - HBox.setHgrow(textField, Priority.ALWAYS); - - getChildren().add(textField); + public DummyControl(Property<?> property, ECPControlContext context) { + setText(property.getValue().toString()); + setDisable(true); } @Override @@ -48,8 +30,8 @@ public class DummyControl extends HBox implements Control { public static class Factory implements Control.Factory { @Override - public Control createControl(IItemPropertyDescriptor itemPropertyDescriptor, ECPControlContext context) { - return new DummyControl(itemPropertyDescriptor, context); + public Control createControl(Property<?> property, EStructuralFeature feature, ECPControlContext context) { + return new DummyControl(property, context); } } diff --git a/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/EnumControl.java b/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/EnumControl.java index 82752ae07..67576b13d 100644 --- a/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/EnumControl.java +++ b/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/EnumControl.java @@ -1,7 +1,9 @@ package org.eclipse.fx.ecp.ui.controls; import java.util.ArrayList; +import java.util.Collection; +import javafx.beans.property.Property; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.scene.control.ChoiceBox; @@ -24,106 +26,53 @@ import org.eclipse.emf.edit.provider.IItemPropertyDescriptor; import org.eclipse.fx.ecp.ui.Control; @SuppressWarnings("restriction") -public class EnumControl extends VBox implements Control { +public class EnumControl extends ChoiceBox<Enumerator> implements Control { - private ValidationMessage validationMessage; + public EnumControl(final Property<Enumerator> property, Collection<Enumerator> values, ECPControlContext context) { - public EnumControl(IItemPropertyDescriptor propertyDescriptor, ECPControlContext context) { - final EObject modelElement = context.getModelElement(); - final EditingDomain editingDomain = context.getEditingDomain(); + getItems().addAll(values); - final EStructuralFeature feature = (EStructuralFeature) propertyDescriptor.getFeature(modelElement); + SingleSelectionModel<Enumerator> selectionModel = getSelectionModel(); - ChoiceBox<Enumerator> choiceBox = new ChoiceBox<>(); - - EClassifier type = feature.getEType(); - - EEnum eEnum = (EEnum) type; - - EList<EEnumLiteral> enumLiterals = eEnum.getELiterals(); - - ArrayList<Enumerator> values = new ArrayList<Enumerator>(); - - if (!feature.isRequired()) - values.add(null); - - for (EEnumLiteral literal : enumLiterals) - values.add(literal.getInstance()); - - choiceBox.getItems().addAll(values); - - SingleSelectionModel<Enumerator> selectionModel = choiceBox.getSelectionModel(); - - Enumerator val = (Enumerator) modelElement.eGet(feature); - - selectionModel.select(val); - - getChildren().add(choiceBox); + selectionModel.select(property.getValue()); selectionModel.selectedItemProperty().addListener(new ChangeListener<Enumerator>() { @Override public void changed(ObservableValue<? extends Enumerator> observableValue, Enumerator oldValue, Enumerator newValue) { - Command command = SetCommand.create(editingDomain, modelElement, feature, newValue); - if (command.canExecute()) - editingDomain.getCommandStack().execute(command); - - if(newValue == null) { - validationMessage.setMessage("A value must be selected"); - } else { - validationMessage.setMessage(null); - } + property.setValue(newValue); } }); - validationMessage = new ValidationMessage(); - getChildren().add(validationMessage); } @Override public void handleValidation(Diagnostic diagnostic) { -// if (diagnostic.getSeverity() != Diagnostic.OK) { -// -// validationMessage.setMessage(diagnostic.getMessage()); -// -//// validationLabel.setText(diagnostic.getMessage()); -// -// // Timeline timeline = new Timeline(); -// // -// // timeline.getKeyFrames().addAll( -// // new KeyFrame(Duration.ZERO, new -// // KeyValue(rectangle.heightProperty(), 0, Interpolator.EASE_BOTH)), -// // new KeyFrame(Duration.millis(300), new -// // KeyValue(rectangle.heightProperty(), 50, Interpolator.EASE_BOTH)) -// // ); -// // -// // timeline.play(); -// -// // ScaleTransition transition = ScaleTransitionBuilder.create() -// // .node(validationLabel) -// // .duration(Duration.seconds(2)) -// // .fromY(0) -// // .toY(1) -// // .build(); -// // transition.play(); -// -// } else { -// resetValidation(); -// } + } @Override public void resetValidation() { -// validationLabel.setText(null); - + } public static class Factory implements Control.Factory { @Override - public Control createControl(IItemPropertyDescriptor itemPropertyDescriptor, ECPControlContext context) { - return new EnumControl(itemPropertyDescriptor, context); + public Control createControl(Property<?> property, EStructuralFeature feature, ECPControlContext context) { + EClassifier type = feature.getEType(); + EEnum eEnum = (EEnum) type; + EList<EEnumLiteral> enumLiterals = eEnum.getELiterals(); + ArrayList<Enumerator> values = new ArrayList<Enumerator>(); + + if (!feature.isRequired()) + values.add(null); + + for (EEnumLiteral literal : enumLiterals) + values.add(literal.getInstance()); + + return new EnumControl((Property<Enumerator>) property, values, context); } } diff --git a/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/FormControlFactory.java b/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/FormControlFactory.java deleted file mode 100644 index 8fa899e7e..000000000 --- a/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/FormControlFactory.java +++ /dev/null @@ -1,52 +0,0 @@ -//package at.bestsolution.efxclipse.ecp.ui.controls; -// -//import javafx.scene.Node; -// -//import org.eclipse.emf.ecore.EAttribute; -//import org.eclipse.emf.ecore.EClassifier; -//import org.eclipse.emf.ecore.EDataType; -//import org.eclipse.emf.ecore.EEnum; -//import org.eclipse.emf.ecore.EObject; -//import org.eclipse.emf.ecore.EReference; -//import org.eclipse.emf.ecore.EStructuralFeature; -//import org.eclipse.emf.ecore.EcorePackage; -//import org.eclipse.emf.ecp.edit.ECPControlContext; -//import org.eclipse.emf.edit.provider.IItemPropertyDescriptor; -// -//public class FormControlFactory { -// -// public Node createFormControl(IItemPropertyDescriptor propertyDescriptor, ECPControlContext context) { -// -// EObject modelElement = context.getModelElement(); -// EStructuralFeature feature = (EStructuralFeature) propertyDescriptor.getFeature(modelElement); -// -// EClassifier type = feature.getEType(); -// -// if (feature.isMany()) { -// if (type == EcorePackage.Literals.ESTRING) { -// return new MultiTextControl(propertyDescriptor, context); -// } -// if (feature instanceof EReference) { -// return new MultiReferenceControl(propertyDescriptor, context); -// } -// } else { -// -// if (type == EcorePackage.Literals.EBOOLEAN) { -// return new CheckBoxControl(propertyDescriptor, context); -// } else if (type instanceof EEnum) { -// return new EnumControl(propertyDescriptor, context); -// } else if (feature instanceof EAttribute) { -// TextFieldControl textFieldControl = new TextFieldControl(propertyDescriptor, context); -// if (type instanceof EDataType && textFieldControl.isControlFor((EDataType) type)) -// return textFieldControl; -// } else if (feature instanceof EReference) { -// return new ReferenceControl(propertyDescriptor, context); -// } -// -// } -// -// return new DummyControl(propertyDescriptor, context); -// -// } -// -//} diff --git a/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/MultiControl.java b/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/MultiControl.java index 21b6d7617..b27ba5f73 100644 --- a/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/MultiControl.java +++ b/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/MultiControl.java @@ -1,18 +1,19 @@ package org.eclipse.fx.ecp.ui.controls; -import java.io.InputStream; import java.net.URL; -import java.util.List; import java.util.Objects; +import javafx.beans.property.Property; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.event.EventHandler; -import javafx.geometry.Pos; import javafx.scene.Node; import javafx.scene.control.Button; -import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.scene.image.ImageView; +import javafx.scene.input.InputMethodEvent; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; import javafx.scene.layout.VBox; @@ -27,15 +28,16 @@ import org.eclipse.emf.common.util.Diagnostic; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.ecp.edit.ECPControlContext; -import org.eclipse.emf.edit.command.DeleteCommand; +import org.eclipse.emf.edit.command.AddCommand; import org.eclipse.emf.edit.command.MoveCommand; import org.eclipse.emf.edit.command.RemoveCommand; import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.emf.edit.provider.IItemPropertyDescriptor; import org.eclipse.fx.ecp.ui.Control; import org.eclipse.fx.ecp.ui.ECPUIPlugin; +import org.eclipse.fx.emf.databinding.edit.EMFEditFXProperties; +import org.eclipse.fx.emf.databinding.edit.EMFEditFXProperties.EListItemProperty; import org.osgi.framework.Bundle; @SuppressWarnings("all") @@ -47,13 +49,20 @@ public class MultiControl extends VBox implements Control { private EditingDomain editingDomain; private EList<?> values; private VBox controlsBox; - - public MultiControl(IItemPropertyDescriptor propertyDescriptor, ECPControlContext context) { + private Button addButton; + private TextField addTextField; + private Command addCommand; + private final ECPControlContext context; + + public MultiControl(final EStructuralFeature feature, final ECPControlContext context) { + this.feature = feature; + this.context = context; modelElement = context.getModelElement(); editingDomain = context.getEditingDomain(); - feature = (EStructuralFeature) propertyDescriptor.getFeature(modelElement); values = (EList<?>) modelElement.eGet(feature); + setSpacing(4); + controlsBox = new VBox(); getChildren().add(controlsBox); controlsBox.setSpacing(4); @@ -61,8 +70,42 @@ public class MultiControl extends VBox implements Control { for (int i = 0; i < values.size(); i++) { controlsBox.getChildren().add(new ControlWrapper(i)); } + + HBox hBox = new HBox(); + getChildren().add(hBox); + + addTextField = new TextField(); + hBox.getChildren().add(addTextField); +// addTextField.setText(feature.getDefaultValue().toString()); + addTextField.setPromptText("Enter a value"); + addTextField.setStyle("-fx-background-radius: 3 0 0 3, 2 0 0 2; -fx-background-insets: 0 0 1 0, 1 1 2 1;"); + addTextField.setMaxWidth(Double.MAX_VALUE); + HBox.setHgrow(addTextField, Priority.ALWAYS); + addTextField.textProperty().addListener(new ChangeListener<String>() { + + @Override + public void changed(ObservableValue<? extends String> arg0, String arg1, String arg2) { + updateAddButton(); + } + - getChildren().add(new Button(null, getImage("icons/add.png"))); + }); + + addButton = new Button(null, getImage("icons/add.png")); + hBox.getChildren().add(addButton); + addButton.getStyleClass().add("right-pill"); + addButton.setOnAction(new EventHandler<ActionEvent>() { + + @Override + public void handle(ActionEvent arg0) { + if(addCommand != null && addCommand.canExecute()) { + editingDomain.getCommandStack().execute(addCommand); + addTextField.setText(null); + addTextField.requestFocus(); + } + } + + }); modelElement.eAdapters().add(new AdapterImpl() { @@ -72,34 +115,51 @@ public class MultiControl extends VBox implements Control { if (Objects.equals(msg.getFeature(), feature)) { final int position = msg.getPosition(); - + + final ObservableList<Node> children = controlsBox.getChildren(); + switch (msg.getEventType()) { case Notification.REMOVE: - controlsBox.getChildren().remove(position); + children.remove(position); break; case Notification.MOVE: int oldIndex = ((Integer) msg.getOldValue()).intValue(); - ControlWrapper controlWrapper = (ControlWrapper) controlsBox.getChildren().remove(oldIndex); - controlsBox.getChildren().add(position, controlWrapper); + ControlWrapper controlWrapper = (ControlWrapper) children.remove(oldIndex); + children.add(position, controlWrapper); controlWrapper.setIndex(position); break; - } - - for (Node node : controlsBox.getChildren()) { - if(node instanceof ControlWrapper) - ((ControlWrapper) node).updateButtons(); + case Notification.ADD: + controlsBox.getChildren().add(new ControlWrapper(position)); } + for (int i = 0; i < children.size(); i++) + ((ControlWrapper) children.get(i)).setIndex(i); + + updateButtons(children); + + updateAddButton(); } } }); + + updateAddButton(); validationMessage = new ValidationMessage(); getChildren().add(validationMessage); } + private void updateAddButton() { + addCommand = AddCommand.create(editingDomain, modelElement, feature, addTextField.getText()); + addButton.setDisable(!addCommand.canExecute()); + } + + private void updateButtons(final ObservableList<Node> children) { + for (Node node : children) + ((ControlWrapper) node).updateButtons(); + } + public static ImageView getImage(String resourcePath) { Bundle bundle = Platform.getBundle(ECPUIPlugin.PLUGIN_ID); Path path = new Path(resourcePath); @@ -124,8 +184,8 @@ public class MultiControl extends VBox implements Control { public static class Factory implements Control.Factory { @Override - public Control createControl(IItemPropertyDescriptor itemPropertyDescriptor, ECPControlContext context) { - return new MultiControl(itemPropertyDescriptor, context); + public Control createControl(Property<?> property, EStructuralFeature feature, ECPControlContext context) { + return new MultiControl(feature, context); } } @@ -138,13 +198,32 @@ public class MultiControl extends VBox implements Control { public ControlWrapper(int initialIndex) { index = initialIndex; - + setFillHeight(true); - TextField label = new TextField(values.get(initialIndex).toString()); - label.setMaxWidth(Double.MAX_VALUE); - HBox.setHgrow(label, Priority.ALWAYS); - label.setStyle("-fx-background-radius: 3 0 0 3, 2 0 0 2; -fx-background-insets: 0 0 1 0, 1 1 2 1;"); - getChildren().add(label); + Object value = values.get(initialIndex); + + org.eclipse.fx.ecp.ui.Control.Factory factory = Control.Factory.Registry.INSTANCE.getFactory(feature, modelElement, false); + + +// TextField label = new TextField(); + + try { + Property<?> property = EMFEditFXProperties.listItem(editingDomain, modelElement, feature, initialIndex); + Node control = (Node) factory.createControl(property, feature, context); + getChildren().add(control); +// label.textProperty().bindBidirectional((Property<String>) property); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + +// if(value != null) +// label.setText(value.toString()); +// label.setPromptText("Please enter a value"); +// label.setMaxWidth(Double.MAX_VALUE); +// HBox.setHgrow(label, Priority.ALWAYS); +// label.setStyle("-fx-background-radius: 3 0 0 3, 2 0 0 2; -fx-background-insets: 0 0 1 0, 1 1 2 1;"); +// getChildren().add(label); if (feature.isOrdered()) { @@ -191,10 +270,9 @@ public class MultiControl extends VBox implements Control { } }); - + updateButtons(); } - public void setIndex(int index) { this.index = index; diff --git a/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/MultiTextControl.java b/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/MultiTextControl.java index 79531191d..f29e147dd 100644 --- a/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/MultiTextControl.java +++ b/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/MultiTextControl.java @@ -1,67 +1,67 @@ -package org.eclipse.fx.ecp.ui.controls; - -import java.util.List; - -import javafx.collections.FXCollections; -import javafx.scene.control.ListView; -import javafx.scene.layout.VBox; - -import org.eclipse.emf.common.util.Diagnostic; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.ecp.edit.ECPControlContext; -import org.eclipse.emf.edit.domain.EditingDomain; -import org.eclipse.emf.edit.provider.IItemPropertyDescriptor; -import org.eclipse.fx.ecp.ui.Control; - -@SuppressWarnings("restriction") -public class MultiTextControl extends VBox implements Control { - - private ValidationMessage validationMessage = null; - - public MultiTextControl(IItemPropertyDescriptor propertyDescriptor, ECPControlContext context) { - final EObject modelElement = context.getModelElement(); - final EditingDomain editingDomain = context.getEditingDomain(); - - getStyleClass().add("multiTextControl"); - - final EStructuralFeature feature = (EStructuralFeature) propertyDescriptor.getFeature(modelElement); - - ListView<Object> listView = new ListView<>(); - - List<Object> values = (List<Object>) modelElement.eGet(feature); - - listView.setItems(FXCollections.observableList(values)); - - getChildren().add(listView); - - listView.setDisable(true); - - validationMessage = new ValidationMessage(); - getChildren().add(validationMessage); - } - - @Override - public void handleValidation(Diagnostic diagnostic) { - if (diagnostic.getSeverity() != Diagnostic.OK) { - validationMessage.setMessage(diagnostic.getMessage()); - } else { - resetValidation(); - } - } - - @Override - public void resetValidation() { - validationMessage.setMessage(null); - } - - public static class Factory implements Control.Factory { - - @Override - public Control createControl(IItemPropertyDescriptor itemPropertyDescriptor, ECPControlContext context) { - return new MultiTextControl(itemPropertyDescriptor, context); - } - - } - -} +//package org.eclipse.fx.ecp.ui.controls; +// +//import java.util.List; +// +//import javafx.collections.FXCollections; +//import javafx.scene.control.ListView; +//import javafx.scene.layout.VBox; +// +//import org.eclipse.emf.common.util.Diagnostic; +//import org.eclipse.emf.ecore.EObject; +//import org.eclipse.emf.ecore.EStructuralFeature; +//import org.eclipse.emf.ecp.edit.ECPControlContext; +//import org.eclipse.emf.edit.domain.EditingDomain; +//import org.eclipse.emf.edit.provider.IItemPropertyDescriptor; +//import org.eclipse.fx.ecp.ui.Control; +// +//@SuppressWarnings("restriction") +//public class MultiTextControl extends VBox implements Control { +// +// private ValidationMessage validationMessage = null; +// +// public MultiTextControl(IItemPropertyDescriptor propertyDescriptor, ECPControlContext context) { +// final EObject modelElement = context.getModelElement(); +// final EditingDomain editingDomain = context.getEditingDomain(); +// +// getStyleClass().add("multiTextControl"); +// +// final EStructuralFeature feature = (EStructuralFeature) propertyDescriptor.getFeature(modelElement); +// +// ListView<Object> listView = new ListView<>(); +// +// List<Object> values = (List<Object>) modelElement.eGet(feature); +// +// listView.setItems(FXCollections.observableList(values)); +// +// getChildren().add(listView); +// +// listView.setDisable(true); +// +// validationMessage = new ValidationMessage(); +// getChildren().add(validationMessage); +// } +// +// @Override +// public void handleValidation(Diagnostic diagnostic) { +// if (diagnostic.getSeverity() != Diagnostic.OK) { +// validationMessage.setMessage(diagnostic.getMessage()); +// } else { +// resetValidation(); +// } +// } +// +// @Override +// public void resetValidation() { +// validationMessage.setMessage(null); +// } +// +// public static class Factory implements Control.Factory { +// +// @Override +// public Control createControl(IItemPropertyDescriptor itemPropertyDescriptor, ECPControlContext context) { +// return new MultiTextControl(itemPropertyDescriptor, context); +// } +// +// } +// +//} diff --git a/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/TextFieldControl.java b/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/TextFieldControl.java index c31a96bbf..1549b8b87 100644 --- a/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/TextFieldControl.java +++ b/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/controls/TextFieldControl.java @@ -1,113 +1,68 @@ package org.eclipse.fx.ecp.ui.controls; -import java.util.Objects; - +import javafx.beans.property.Property; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; -import javafx.collections.ObservableList; import javafx.scene.control.TextField; -import javafx.scene.layout.VBox; -import org.eclipse.emf.common.command.Command; import org.eclipse.emf.common.util.Diagnostic; import org.eclipse.emf.ecore.EDataType; -import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.util.Diagnostician; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.ecp.edit.ECPControlContext; -import org.eclipse.emf.edit.command.SetCommand; -import org.eclipse.emf.edit.domain.EditingDomain; -import org.eclipse.emf.edit.provider.IItemPropertyDescriptor; import org.eclipse.fx.ecp.ui.Control; @SuppressWarnings("restriction") -public class TextFieldControl extends VBox implements Control { - - private TextField textField; - private ValidationMessage validationMessage = null; - - public TextFieldControl(IItemPropertyDescriptor propertyDescriptor, ECPControlContext context) { +public class TextFieldControl extends TextField implements Control { - final EObject modelElement = context.getModelElement(); - final EditingDomain editingDomain = context.getEditingDomain(); - - final EStructuralFeature feature = (EStructuralFeature) propertyDescriptor.getFeature(modelElement); + public TextFieldControl(final Property<Object> property, EStructuralFeature feature, ECPControlContext context) { final EDataTypeValueHandler valueHandler = new EDataTypeValueHandler((EDataType) feature.getEType()); - Object value = modelElement.eGet(feature); - - textField = new TextField(valueHandler.toString(value)); + setText(valueHandler.toString(property.getValue())); - textField.textProperty().addListener(new ChangeListener<String>() { + property.addListener(new ChangeListener<Object>() { @Override - public void changed(ObservableValue<? extends String> observableValue, String oldText, String newText) { - final String message = valueHandler.isValid(newText); - ObservableList<String> styleClass = textField.getStyleClass(); - if (message == null) { - styleClass.remove(IControlConstants.INVALID_CLASS); - } else { - if (!styleClass.contains(IControlConstants.INVALID_CLASS)) - styleClass.add(IControlConstants.INVALID_CLASS); - } - validationMessage.setMessage(message); + public void changed(ObservableValue<? extends Object> arg0, Object arg1, Object arg2) { + String text = valueHandler.toString(arg2); + setText(text); } }); - textField.focusedProperty().addListener(new ChangeListener<Boolean>() { + textProperty().addListener(new ChangeListener<String>() { @Override - public void changed(ObservableValue<? extends Boolean> observableValue, Boolean oldFocused, Boolean newFocused) { - if (!newFocused) { - Object oldValue = modelElement.eGet(feature); - String text = textField.getText(); - String message = valueHandler.isValid(text); - - if (message == null) { - Object newValue = valueHandler.toValue(text); - - // only commit if the value has changed - if (!Objects.equals(oldValue, newValue)) { - Command command = SetCommand.create(editingDomain, modelElement, feature, newValue); - if (command.canExecute()) - editingDomain.getCommandStack().execute(command); - } - } else { - System.err.println(message); - } + public void changed(ObservableValue<? extends String> arg0, String arg1, String arg2) { + try { + Object value = valueHandler.toValue(arg2); + property.setValue(value); + } catch (NumberFormatException e) { + // TODO Auto-generated catch block + e.printStackTrace(); } } }); - - getChildren().add(textField); - - validationMessage = new ValidationMessage(); - getChildren().add(validationMessage); } @Override public void handleValidation(Diagnostic diagnostic) { - if (diagnostic.getSeverity() != Diagnostic.OK) { - validationMessage.setMessage(diagnostic.getMessage()); - } else { - resetValidation(); - } + } @Override public void resetValidation() { - validationMessage.setMessage(null); + } public static class Factory implements Control.Factory { @Override - public Control createControl(IItemPropertyDescriptor itemPropertyDescriptor, ECPControlContext context) { - return new TextFieldControl(itemPropertyDescriptor, context); + public Control createControl(Property<?> property, EStructuralFeature feature, ECPControlContext context) { + return new TextFieldControl((Property<Object>) property, feature, context); } } diff --git a/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/impl/ControlFactoryDescriptor.java b/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/impl/ControlFactoryDescriptor.java index a960345cc..71a06154b 100644 --- a/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/impl/ControlFactoryDescriptor.java +++ b/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/impl/ControlFactoryDescriptor.java @@ -2,8 +2,8 @@ package org.eclipse.fx.ecp.ui.impl; import java.util.Set; -import org.eclipse.emf.ecp.edit.util.ECPApplicableTester; import org.eclipse.fx.ecp.ui.Control; +import org.eclipse.fx.ecp.ui.Control.ApplicableTester; import org.eclipse.fx.ecp.ui.Control.Factory; public class ControlFactoryDescriptor implements Control.Factory.Descriptor { @@ -11,13 +11,15 @@ public class ControlFactoryDescriptor implements Control.Factory.Descriptor { private final String id; private final Factory factoryInstance; private final boolean showLabel; - private final Set<ECPApplicableTester> applicableTesters; + private final Set<ApplicableTester> applicableTesters; + private final boolean multi; - public ControlFactoryDescriptor(String id, Factory factoryInstance, boolean showLabel, Set<ECPApplicableTester> applicableTesters) { + public ControlFactoryDescriptor(String id, Factory factoryInstance, boolean showLabel, Set<ApplicableTester> applicableTesters, boolean multi) { this.id = id; this.factoryInstance = factoryInstance; this.showLabel = showLabel; this.applicableTesters = applicableTesters; + this.multi = multi; } public Factory createFactory() { @@ -32,8 +34,12 @@ public class ControlFactoryDescriptor implements Control.Factory.Descriptor { return showLabel; } - public Set<ECPApplicableTester> getTesters() { + public Set<ApplicableTester> getTesters() { return applicableTesters; } + + public boolean isMulti() { + return multi; + } } diff --git a/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/impl/ControlFactoryRegistryImpl.java b/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/impl/ControlFactoryRegistryImpl.java index 5297973a4..ddeedf573 100644 --- a/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/impl/ControlFactoryRegistryImpl.java +++ b/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/impl/ControlFactoryRegistryImpl.java @@ -7,10 +7,9 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.Platform; import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecp.edit.util.ECPApplicableTester; -import org.eclipse.emf.ecp.edit.util.StaticApplicableTester; -import org.eclipse.emf.edit.provider.IItemPropertyDescriptor; +import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.fx.ecp.ui.Control; +import org.eclipse.fx.ecp.ui.Control.ApplicableTester; import org.eclipse.fx.ecp.ui.Control.Factory; import org.osgi.framework.Bundle; @@ -20,8 +19,9 @@ public class ControlFactoryRegistryImpl implements Control.Factory.Registry { private static final String CLASS_ATTRIBUTE = "class"; private static final String CONTROL_ID = "id"; - private static final String CONTROL_CLASS_ATTRIBUTE = "controlClass"; private static final String LABEL_ATTRIBUTE = "showLabel"; + private static final String CONTROL_EMBEDDABLE = "embeddable"; + private static final String CONTROL_MULTI = "multi"; private static final String TEST_DYNAMIC = "dynamicTest"; private static final String CONTROL_TESTER = "testClass"; @@ -31,7 +31,6 @@ public class ControlFactoryRegistryImpl implements Control.Factory.Registry { private static final String TESTER_CLASSTYPE = "supportedClassType"; private static final String TESTER_EOBJECT = "supportedEObject"; private static final String TESTER_FEATURE = "supportedFeature"; - private static final String TESTER_SINGLEVALUE = "singleValue"; private final Set<ControlFactoryDescriptor> controlDescriptors = new HashSet<ControlFactoryDescriptor>(); @@ -39,33 +38,29 @@ public class ControlFactoryRegistryImpl implements Control.Factory.Registry { readExtensionPoint(); } - public Factory getFactory(Class<?> controlClass, IItemPropertyDescriptor propertyDescriptor, EObject modelElement) { - ControlFactoryDescriptor factoryDescriptor = getControlFactoryCandidate(controlClass, propertyDescriptor, - modelElement); + public Factory getFactory(EStructuralFeature feature, EObject modelElement, boolean multi) { + ControlFactoryDescriptor factoryDescriptor = getControlFactoryCandidate(feature, modelElement, multi); return factoryDescriptor != null ? factoryDescriptor.createFactory() : null; } private void readExtensionPoint() { - IConfigurationElement[] configurationElements = Platform.getExtensionRegistry().getConfigurationElementsFor( - CONTROL_EXTENSION); + IConfigurationElement[] configurationElements = Platform.getExtensionRegistry().getConfigurationElementsFor(CONTROL_EXTENSION); for (IConfigurationElement configurationElement : configurationElements) { try { String id = configurationElement.getAttribute(CONTROL_ID); - Control.Factory factory = (Control.Factory) configurationElement - .createExecutableExtension(CLASS_ATTRIBUTE); + Control.Factory factory = (Control.Factory) configurationElement.createExecutableExtension(CLASS_ATTRIBUTE); + boolean showLabel = Boolean.parseBoolean(configurationElement.getAttribute(LABEL_ATTRIBUTE)); - String controlClass = configurationElement.getAttribute(CONTROL_CLASS_ATTRIBUTE); -// Class<?> resolvedWidgetClass = loadClass(configurationElement.getContributor().getName(), controlClass); + boolean multi = Boolean.parseBoolean(configurationElement.getAttribute(CONTROL_MULTI)); - Set<ECPApplicableTester> testers = new HashSet<ECPApplicableTester>(); + Set<ApplicableTester> testers = new HashSet<ApplicableTester>(); for (IConfigurationElement testerExtension : configurationElement.getChildren()) { if (TEST_DYNAMIC.equals(testerExtension.getName())) { - testers.add((ECPApplicableTester) testerExtension.createExecutableExtension(CONTROL_TESTER)); + testers.add((ApplicableTester) testerExtension.createExecutableExtension(CONTROL_TESTER)); } else if (TEST_STATIC.equals(testerExtension.getName())) { - boolean singleValue = Boolean.parseBoolean(testerExtension.getAttribute(TESTER_SINGLEVALUE)); int priority = Integer.parseInt(testerExtension.getAttribute(TESTER_PRIORITY)); String type = testerExtension.getAttribute(TESTER_CLASSTYPE); @@ -76,18 +71,17 @@ public class ControlFactoryRegistryImpl implements Control.Factory.Registry { if (eObject == null) eObject = "org.eclipse.emf.ecore.EObject"; - Class<? extends EObject> supportedEObject = loadClass(testerExtension.getContributor() - .getName(), eObject); + Class<? extends EObject> supportedEObject = loadClass(testerExtension.getContributor().getName(), eObject); String supportedFeature = testerExtension.getAttribute(TESTER_FEATURE); - testers.add(new StaticApplicableTester(singleValue, priority, supportedClassType, - supportedEObject, supportedFeature)); + testers.add(new StaticApplicableTester(priority, supportedClassType, supportedEObject, + supportedFeature)); } } - controlDescriptors.add(new ControlFactoryDescriptor(id, factory, showLabel, testers)); + controlDescriptors.add(new ControlFactoryDescriptor(id, factory, showLabel, testers, multi)); } catch (ClassNotFoundException e1) { // TODO log exception e1.printStackTrace(); @@ -103,23 +97,24 @@ public class ControlFactoryRegistryImpl implements Control.Factory.Registry { Bundle bundle = Platform.getBundle(bundleName); if (bundle == null) { // TODO externalize strings - throw new ClassNotFoundException(clazz + " cannot be loaded because bundle " + bundleName - + " cannot be resolved"); + throw new ClassNotFoundException(clazz + " cannot be loaded because bundle " + bundleName + " cannot be resolved"); } return (Class<T>) bundle.loadClass(clazz); } - private ControlFactoryDescriptor getControlFactoryCandidate(Class<?> clazz, - IItemPropertyDescriptor itemPropertyDescriptor, EObject modelElement) { + private ControlFactoryDescriptor getControlFactoryCandidate(EStructuralFeature feature, EObject modelElement, boolean multi) { int highestPriority = -1; ControlFactoryDescriptor bestCandidate = null; for (ControlFactoryDescriptor descriptor : controlDescriptors) { + if(descriptor.isMulti() != multi) + continue; + int currentPriority = -1; - for (ECPApplicableTester tester : descriptor.getTesters()) { - int testerPriority = tester.isApplicable(itemPropertyDescriptor, modelElement); + for (ApplicableTester tester : descriptor.getTesters()) { + int testerPriority = tester.isApplicable(feature, modelElement); if (testerPriority > currentPriority) currentPriority = testerPriority; } diff --git a/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/impl/StaticApplicableTester.java b/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/impl/StaticApplicableTester.java new file mode 100644 index 000000000..51bbaceef --- /dev/null +++ b/bundles/runtime/org.eclipse.fx.ecp.ui/src/org/eclipse/fx/ecp/ui/impl/StaticApplicableTester.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright (c) 2011-2013 EclipseSource Muenchen GmbH and others. + * + * 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: + * Eugen Neufeld - initial API and implementation + * + *******************************************************************************/ +package org.eclipse.fx.ecp.ui.impl; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.fx.ecp.ui.Control.ApplicableTester; + +public class StaticApplicableTester implements ApplicableTester { + + private final int priority; + private final Class<?> supportedClassType; + private final Class<? extends EObject> supportedEObject; + private final String supportedFeature; + + public StaticApplicableTester(int priority, Class<?> supportedClassType, + Class<? extends EObject> supportedEObject, String supportedFeature) { + this.priority = priority; + this.supportedClassType = supportedClassType; + this.supportedEObject = supportedEObject; + this.supportedFeature = supportedFeature; + } + + public int isApplicable(EStructuralFeature feature, EObject eObject) { + + // if the feature is a multiValue and the description is a singlevalue continue +// if (isSingleValue() == feature.isMany()) { +// return NOT_APPLICABLE; +// } + + // if we have an attribute + if (EAttribute.class.isInstance(feature)) { + Class<?> instanceClass = ((EAttribute) feature).getEAttributeType().getInstanceClass(); + // if the attribute class is an primitive test the primitive types + if (instanceClass.isPrimitive()) { + try { + Class<?> primitive = (Class<?>) getSupportedClassType().getField("TYPE").get(null); //$NON-NLS-1$ + if (!primitive.equals(instanceClass)) { + return NOT_APPLICABLE; + } + + } catch (IllegalArgumentException e) { + return NOT_APPLICABLE; + } catch (SecurityException e) { + return NOT_APPLICABLE; + } catch (IllegalAccessException e) { + return NOT_APPLICABLE; + } catch (NoSuchFieldException e) { + return NOT_APPLICABLE; + } + } + // otherwise test the classes itself + else if (!getSupportedClassType().isAssignableFrom(instanceClass)) { + return NOT_APPLICABLE; + } + } + // if we have an reference the the classes + else if (EReference.class.isInstance(feature)) { + Class<?> instanceClass = feature.getEType().getInstanceClass(); + if (!getSupportedClassType().isAssignableFrom(instanceClass)) { + return NOT_APPLICABLE; + } + } + // if the supported eobject is assignable from the current eobject and the supported feature is either + // null or equals the current one + if (getSupportedEObject().isInstance(eObject) + && (getSupportedFeature() == null || eObject.eClass().getEStructuralFeature(getSupportedFeature()).equals(feature))) { + return getPriority(); + } + + return NOT_APPLICABLE; + } + + /** + * The static priority of the corresponding control. + * + * @return the priority + */ + public int getPriority() { + return priority; + } + + /** + * The eobejct which is supported by the corresponding control. + * + * @return the class of the supported eobejct + */ + public Class<? extends EObject> getSupportedEObject() { + return supportedEObject; + } + + /** + * The name of the feature the corresponding control supports. + * + * @return the name of the supported feature + */ + public String getSupportedFeature() { + return supportedFeature; + } + + /** + * The class of the type the corresponding control supports. + * + * @return the class of the supported type + */ + public Class<?> getSupportedClassType() { + return supportedClassType; + } + +} diff --git a/bundles/runtime/org.eclipse.fx.emf.databinding/src/org/eclipse/fx/emf/databinding/edit/EMFEditFXProperties.java b/bundles/runtime/org.eclipse.fx.emf.databinding/src/org/eclipse/fx/emf/databinding/edit/EMFEditFXProperties.java index 52163a619..5c7c230da 100755 --- a/bundles/runtime/org.eclipse.fx.emf.databinding/src/org/eclipse/fx/emf/databinding/edit/EMFEditFXProperties.java +++ b/bundles/runtime/org.eclipse.fx.emf.databinding/src/org/eclipse/fx/emf/databinding/edit/EMFEditFXProperties.java @@ -1,112 +1,181 @@ -/**
- * Copyright (c) 2012 TESIS DYNAware GmbH and others.
- * 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:
- * Torsten Sommer <torsten.sommer@tesis.de> - initial API and implementation
- */
-package org.eclipse.fx.emf.databinding.edit;
-
-import javafx.beans.property.ListPropertyBase;
-import javafx.beans.property.ObjectPropertyBase;
-import javafx.beans.property.Property;
-import javafx.collections.ObservableList;
-
-import org.eclipse.emf.common.command.Command;
-import org.eclipse.emf.common.notify.Notification;
-import org.eclipse.emf.common.notify.Notifier;
-import org.eclipse.emf.common.notify.impl.AdapterImpl;
-import org.eclipse.emf.common.util.EList;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.emf.edit.command.SetCommand;
-import org.eclipse.emf.edit.domain.EditingDomain;
-
-public class EMFEditFXProperties {
-
- /**
- * Returns a {@link Property} for the given {@link EStructuralFeature}
- *
- * @param editingDomain the editing domain
- * @param feature the feature instance the property is created for
- * @return a value property for the given {@link EStructuralFeature}
- */
- public static <T> Property<T> value(EditingDomain editingDomain, EObject eObject, EStructuralFeature feature) {
- return new EObjectProperty<>(editingDomain, eObject, feature);
- }
-
- public static <T> ObservableList<T> list(EditingDomain editingDomain, Notifier owner, EList<T> list) {
- throw new UnsupportedOperationException("Not implemented");
- }
-
- public static <T> ObservableList<T> list(EditingDomain editingDomain, EObject eObject, EStructuralFeature feature) {
- throw new UnsupportedOperationException("Not implemented");
- }
-
- static class EObjectObservableList<T> extends ListPropertyBase<T> {
-
- EObject eObject;
- EStructuralFeature feature;
- EditingDomain editingDomain;
-
- public Object getBean() {
- return eObject;
- }
-
- public String getName() {
- return feature.getName();
- }
-
- }
-
- static class EObjectProperty<T> extends ObjectPropertyBase<T> {
-
- EObject eObject;
- EStructuralFeature feature;
- EditingDomain editingDomain;
-
- public EObjectProperty(EditingDomain editingDomain, EObject eObject, EStructuralFeature feature) {
- super();
- this.eObject = eObject;
- this.feature = feature;
- this.editingDomain = editingDomain;
-
- eObject.eAdapters().add(new AdapterImpl() {
- @Override
- public void notifyChanged(Notification msg) {
- fireValueChangedEvent();
- }
- });
- }
-
- public void setEObject(EObject eObject) {
- this.eObject = eObject;
- }
-
- @Override
- public void setValue(T newValue) {
- Command command = SetCommand.create(editingDomain, eObject, feature, newValue);
- if (command.canExecute())
- editingDomain.getCommandStack().execute(command);
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public T getValue() {
- return (T) eObject.eGet(feature);
- }
-
- public Object getBean() {
- return eObject;
- }
-
- public String getName() {
- return feature.getName();
- }
-
- }
-
-}
+/** + * Copyright (c) 2012 TESIS DYNAware GmbH and others. + * 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: + * Torsten Sommer <torsten.sommer@tesis.de> - initial API and implementation + */ +package org.eclipse.fx.emf.databinding.edit; + +import javafx.beans.property.ObjectPropertyBase; +import javafx.beans.property.Property; + +import org.eclipse.emf.common.command.Command; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.impl.AdapterImpl; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.edit.command.SetCommand; +import org.eclipse.emf.edit.domain.EditingDomain; + +public class EMFEditFXProperties { + + /** + * Returns a {@link Property} for the given {@link EStructuralFeature} + * + * @param editingDomain the editing domain + * @param feature the feature instance the property is created for + * @return a value property for the given {@link EStructuralFeature} + */ + public static <T> Property<T> value(EditingDomain editingDomain, EObject eObject, EStructuralFeature feature) { + return new EObjectProperty<>(editingDomain, eObject, feature); + } + + public static <T> EListItemProperty<T> listItem(EditingDomain editingDomain, EObject eObject, EStructuralFeature feature, int index) { + return new EListItemProperty<>(editingDomain, eObject, feature, index); + } + + private static class EObjectProperty<T> extends ObjectPropertyBase<T> { + + final private EObject eObject; + final private EStructuralFeature feature; + final private EditingDomain editingDomain; + + private EObjectProperty(EditingDomain editingDomain, EObject eObject, EStructuralFeature feature) { + super(); + this.eObject = eObject; + this.feature = feature; + this.editingDomain = editingDomain; + + eObject.eAdapters().add(new AdapterImpl() { + @Override + public void notifyChanged(Notification msg) { + fireValueChangedEvent(); + } + }); + } + + @Override + public void setValue(T newValue) { + Command command = SetCommand.create(editingDomain, eObject, feature, newValue); + if (command.canExecute()) + editingDomain.getCommandStack().execute(command); + } + + @Override + @SuppressWarnings("unchecked") + public T getValue() { + return (T) eObject.eGet(feature); + } + + @Override + public Object getBean() { + return eObject; + } + + @Override + public String getName() { + return feature.getName(); + } + + } + + public static class EListItemProperty<T> extends ObjectPropertyBase<T> { + + final private EObject eObject; + final private EStructuralFeature feature; + final private EditingDomain editingDomain; + final private EList<T> eList; + private int index; + + @SuppressWarnings("unchecked") + private EListItemProperty(EditingDomain editingDomain, final EObject eObject, final EStructuralFeature feature, int initialIndex) { + super(); + this.eObject = eObject; + this.feature = feature; + this.editingDomain = editingDomain; + this.eList = (EList<T>) eObject.eGet(feature); + this.index = initialIndex; + + eObject.eAdapters().add(new AdapterImpl() { + @Override + public void notifyChanged(Notification msg) { + if (msg.getFeature() == feature) { + + switch (msg.getEventType()) { + case Notification.ADD: + break; + case Notification.MOVE: { + int oldIndex = ((Integer) msg.getOldValue()).intValue(); + int position = msg.getPosition(); + if (oldIndex == index) + index = position; + else if (oldIndex > index && position <= index) + index++; + else if (oldIndex < index && position >= index) + index--; + break; + } + case Notification.REMOVE: + int position = msg.getPosition(); + if (index == position) { + index = -1; + eObject.eAdapters().remove(this); + } else if (index > position) { + index--; + } + break; + case Notification.ADD_MANY: + throw new RuntimeException("ADD_MANY is currently not supported"); + case Notification.REMOVE_MANY: + throw new RuntimeException("REMOVE_MANY is currently not supported"); + } + + fireValueChangedEvent(); + + } + + } + }); + } + + @Override + public void setValue(T newValue) { + Command command = SetCommand.create(editingDomain, eObject, feature, newValue, index); + if (command.canExecute()) + editingDomain.getCommandStack().execute(command); + } + + @Override + public T getValue() { + if (index >= 0 && index <= eList.size()) + return (T) eList.get(index); + else + return null; + } + + @Override + public Object getBean() { + return eObject; + } + + @Override + public String getName() { + return feature.getName(); + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + + } + +} diff --git a/demos/org.eclipse.fx.ecp.app/src/org/eclipse/fx/ecp/ModelEditorPart.java b/demos/org.eclipse.fx.ecp.app/src/org/eclipse/fx/ecp/ModelEditorPart.java index 39c494a49..38dd69df6 100644 --- a/demos/org.eclipse.fx.ecp.app/src/org/eclipse/fx/ecp/ModelEditorPart.java +++ b/demos/org.eclipse.fx.ecp.app/src/org/eclipse/fx/ecp/ModelEditorPart.java @@ -15,6 +15,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import javafx.beans.property.Property; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.VPos; @@ -43,6 +44,7 @@ import org.eclipse.fx.ecp.ui.Control; import org.eclipse.fx.ecp.ui.ModelElementEditor; import org.eclipse.fx.ecp.ui.Control.Factory; import org.eclipse.fx.ecp.ui.Control.Factory.Registry; +import org.eclipse.fx.emf.databinding.edit.EMFEditFXProperties; @SuppressWarnings("restriction") @@ -122,12 +124,13 @@ public class ModelEditorPart implements ModelElementEditor { GridPane.setValignment(label, VPos.TOP); gridPane.add(label, 0, i); - Factory factory = registry.getFactory(Node.class, propertyDescriptor, modelElement); - EStructuralFeature feature = (EStructuralFeature) propertyDescriptor.getFeature(modelElement); + + Factory factory = registry.getFactory(feature, modelElement, feature.isMany()); if (factory != null) { - Control control = factory.createControl(propertyDescriptor, modelElementContext); + Property<?> property = EMFEditFXProperties.value(modelElementContext.getEditingDomain(), modelElementContext.getModelElement(), feature); + Control control = factory.createControl(property, feature, modelElementContext); Node node = (Node) control; gridPane.add(node, 1, i); GridPane.setHgrow(node, Priority.ALWAYS); |