getBody();
+
+} // SliderDescription
diff --git a/packages/sirius-web/backend/sirius-web-customwidgets/src/main/java/org/eclipse/sirius/web/customwidgets/impl/CustomwidgetsFactoryImpl.java b/packages/sirius-web/backend/sirius-web-customwidgets/src/main/java/org/eclipse/sirius/web/customwidgets/impl/CustomwidgetsFactoryImpl.java
new file mode 100644
index 0000000000..eb6e07b4db
--- /dev/null
+++ b/packages/sirius-web/backend/sirius-web-customwidgets/src/main/java/org/eclipse/sirius/web/customwidgets/impl/CustomwidgetsFactoryImpl.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.web.customwidgets.impl;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.impl.EFactoryImpl;
+import org.eclipse.emf.ecore.plugin.EcorePlugin;
+import org.eclipse.sirius.web.customwidgets.CustomwidgetsFactory;
+import org.eclipse.sirius.web.customwidgets.CustomwidgetsPackage;
+import org.eclipse.sirius.web.customwidgets.SliderDescription;
+
+/**
+ *
+ * An implementation of the model Factory.
+ *
+ * @generated
+ */
+public class CustomwidgetsFactoryImpl extends EFactoryImpl implements CustomwidgetsFactory {
+ /**
+ * Creates the default factory implementation.
+ *
+ *
+ * @generated
+ */
+ public static CustomwidgetsFactory init() {
+ try {
+ CustomwidgetsFactory theCustomwidgetsFactory = (CustomwidgetsFactory)EPackage.Registry.INSTANCE.getEFactory(CustomwidgetsPackage.eNS_URI);
+ if (theCustomwidgetsFactory != null) {
+ return theCustomwidgetsFactory;
+ }
+ }
+ catch (Exception exception) {
+ EcorePlugin.INSTANCE.log(exception);
+ }
+ return new CustomwidgetsFactoryImpl();
+ }
+
+ /**
+ * Creates an instance of the factory.
+ *
+ *
+ * @generated
+ */
+ public CustomwidgetsFactoryImpl() {
+ super();
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ public EObject create(EClass eClass) {
+ switch (eClass.getClassifierID()) {
+ case CustomwidgetsPackage.SLIDER_DESCRIPTION: return this.createSliderDescription();
+ default:
+ throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier");
+ }
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ public SliderDescription createSliderDescription() {
+ SliderDescriptionImpl sliderDescription = new SliderDescriptionImpl();
+ return sliderDescription;
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ public CustomwidgetsPackage getCustomwidgetsPackage() {
+ return (CustomwidgetsPackage)this.getEPackage();
+ }
+
+ /**
+ *
+ *
+ * @deprecated
+ * @generated
+ */
+ @Deprecated
+ public static CustomwidgetsPackage getPackage() {
+ return CustomwidgetsPackage.eINSTANCE;
+ }
+
+} //CustomwidgetsFactoryImpl
diff --git a/packages/sirius-web/backend/sirius-web-customwidgets/src/main/java/org/eclipse/sirius/web/customwidgets/impl/CustomwidgetsPackageImpl.java b/packages/sirius-web/backend/sirius-web-customwidgets/src/main/java/org/eclipse/sirius/web/customwidgets/impl/CustomwidgetsPackageImpl.java
new file mode 100644
index 0000000000..3570c18453
--- /dev/null
+++ b/packages/sirius-web/backend/sirius-web-customwidgets/src/main/java/org/eclipse/sirius/web/customwidgets/impl/CustomwidgetsPackageImpl.java
@@ -0,0 +1,232 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.web.customwidgets.impl;
+
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.impl.EPackageImpl;
+import org.eclipse.sirius.components.view.ViewPackage;
+import org.eclipse.sirius.web.customwidgets.CustomwidgetsFactory;
+import org.eclipse.sirius.web.customwidgets.CustomwidgetsPackage;
+import org.eclipse.sirius.web.customwidgets.SliderDescription;
+
+/**
+ *
+ * An implementation of the model Package.
+ *
+ * @generated
+ */
+public class CustomwidgetsPackageImpl extends EPackageImpl implements CustomwidgetsPackage {
+ /**
+ *
+ *
+ * @generated
+ */
+ private EClass sliderDescriptionEClass = null;
+
+ /**
+ * Creates an instance of the model Package, registered with
+ * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package
+ * package URI value.
+ * Note: the correct way to create the package is via the static
+ * factory method {@link #init init()}, which also performs
+ * initialization of the package, or returns the registered package,
+ * if one already exists.
+ *
+ *
+ * @see org.eclipse.emf.ecore.EPackage.Registry
+ * @see org.eclipse.sirius.web.customwidgets.CustomwidgetsPackage#eNS_URI
+ * @see #init()
+ * @generated
+ */
+ private CustomwidgetsPackageImpl() {
+ super(eNS_URI, CustomwidgetsFactory.eINSTANCE);
+ }
+ /**
+ *
+ *
+ * @generated
+ */
+ private static boolean isInited = false;
+
+ /**
+ * Creates, registers, and initializes the Package for this model, and for any others upon which it depends.
+ *
+ *
This method is used to initialize {@link CustomwidgetsPackage#eINSTANCE} when that field is accessed.
+ * Clients should not invoke it directly. Instead, they should simply access that field to obtain the package.
+ *
+ *
+ * @see #eNS_URI
+ * @see #createPackageContents()
+ * @see #initializePackageContents()
+ * @generated
+ */
+ public static CustomwidgetsPackage init() {
+ if (isInited) return (CustomwidgetsPackage)EPackage.Registry.INSTANCE.getEPackage(CustomwidgetsPackage.eNS_URI);
+
+ // Obtain or create and register package
+ Object registeredCustomwidgetsPackage = EPackage.Registry.INSTANCE.get(eNS_URI);
+ CustomwidgetsPackageImpl theCustomwidgetsPackage = registeredCustomwidgetsPackage instanceof CustomwidgetsPackageImpl ? (CustomwidgetsPackageImpl)registeredCustomwidgetsPackage : new CustomwidgetsPackageImpl();
+
+ isInited = true;
+
+ // Initialize simple dependencies
+ ViewPackage.eINSTANCE.eClass();
+
+ // Create package meta-data objects
+ theCustomwidgetsPackage.createPackageContents();
+
+ // Initialize created meta-data
+ theCustomwidgetsPackage.initializePackageContents();
+
+ // Mark meta-data to indicate it can't be changed
+ theCustomwidgetsPackage.freeze();
+
+ // Update the registry and return the package
+ EPackage.Registry.INSTANCE.put(CustomwidgetsPackage.eNS_URI, theCustomwidgetsPackage);
+ return theCustomwidgetsPackage;
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ public EClass getSliderDescription() {
+ return this.sliderDescriptionEClass;
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ public EAttribute getSliderDescription_MinValueExpression() {
+ return (EAttribute)this.sliderDescriptionEClass.getEStructuralFeatures().get(0);
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ public EAttribute getSliderDescription_MaxValueExpression() {
+ return (EAttribute)this.sliderDescriptionEClass.getEStructuralFeatures().get(1);
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ public EAttribute getSliderDescription_CurrentValueExpression() {
+ return (EAttribute)this.sliderDescriptionEClass.getEStructuralFeatures().get(2);
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ public EReference getSliderDescription_Body() {
+ return (EReference)this.sliderDescriptionEClass.getEStructuralFeatures().get(3);
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ public CustomwidgetsFactory getCustomwidgetsFactory() {
+ return (CustomwidgetsFactory)this.getEFactoryInstance();
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ private boolean isCreated = false;
+
+ /**
+ * Creates the meta-model objects for the package. This method is
+ * guarded to have no affect on any invocation but its first.
+ *
+ *
+ * @generated
+ */
+ public void createPackageContents() {
+ if (this.isCreated) return;
+ this.isCreated = true;
+
+ // Create classes and their features
+ this.sliderDescriptionEClass = this.createEClass(SLIDER_DESCRIPTION);
+ this.createEAttribute(this.sliderDescriptionEClass, SLIDER_DESCRIPTION__MIN_VALUE_EXPRESSION);
+ this.createEAttribute(this.sliderDescriptionEClass, SLIDER_DESCRIPTION__MAX_VALUE_EXPRESSION);
+ this.createEAttribute(this.sliderDescriptionEClass, SLIDER_DESCRIPTION__CURRENT_VALUE_EXPRESSION);
+ this.createEReference(this.sliderDescriptionEClass, SLIDER_DESCRIPTION__BODY);
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ private boolean isInitialized = false;
+
+ /**
+ * Complete the initialization of the package and its meta-model. This
+ * method is guarded to have no affect on any invocation but its first.
+ *
+ *
+ * @generated
+ */
+ public void initializePackageContents() {
+ if (this.isInitialized) return;
+ this.isInitialized = true;
+
+ // Initialize package
+ this.setName(eNAME);
+ this.setNsPrefix(eNS_PREFIX);
+ this.setNsURI(eNS_URI);
+
+ // Obtain other dependent packages
+ ViewPackage theViewPackage = (ViewPackage)EPackage.Registry.INSTANCE.getEPackage(ViewPackage.eNS_URI);
+
+ // Create type parameters
+
+ // Set bounds for type parameters
+
+ // Add supertypes to classes
+ this.sliderDescriptionEClass.getESuperTypes().add(theViewPackage.getWidgetDescription());
+
+ // Initialize classes, features, and operations; add parameters
+ this.initEClass(this.sliderDescriptionEClass, SliderDescription.class, "SliderDescription", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
+ this.initEAttribute(this.getSliderDescription_MinValueExpression(), theViewPackage.getInterpretedExpression(), "minValueExpression", null, 1, 1, SliderDescription.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+ this.initEAttribute(this.getSliderDescription_MaxValueExpression(), theViewPackage.getInterpretedExpression(), "maxValueExpression", null, 1, 1, SliderDescription.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+ this.initEAttribute(this.getSliderDescription_CurrentValueExpression(), theViewPackage.getInterpretedExpression(), "currentValueExpression", null, 1, 1, SliderDescription.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+ this.initEReference(this.getSliderDescription_Body(), theViewPackage.getOperation(), null, "body", null, 0, -1, SliderDescription.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+
+ // Create resource
+ this.createResource(eNS_URI);
+ }
+
+} //CustomwidgetsPackageImpl
diff --git a/packages/sirius-web/backend/sirius-web-customwidgets/src/main/java/org/eclipse/sirius/web/customwidgets/impl/SliderDescriptionImpl.java b/packages/sirius-web/backend/sirius-web-customwidgets/src/main/java/org/eclipse/sirius/web/customwidgets/impl/SliderDescriptionImpl.java
new file mode 100644
index 0000000000..1e7c038e4a
--- /dev/null
+++ b/packages/sirius-web/backend/sirius-web-customwidgets/src/main/java/org/eclipse/sirius/web/customwidgets/impl/SliderDescriptionImpl.java
@@ -0,0 +1,342 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.web.customwidgets.impl;
+
+import java.util.Collection;
+
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.NotificationChain;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
+import org.eclipse.emf.ecore.util.EObjectContainmentEList;
+import org.eclipse.emf.ecore.util.InternalEList;
+import org.eclipse.sirius.components.view.Operation;
+import org.eclipse.sirius.components.view.impl.WidgetDescriptionImpl;
+import org.eclipse.sirius.web.customwidgets.CustomwidgetsPackage;
+import org.eclipse.sirius.web.customwidgets.SliderDescription;
+
+/**
+ *
+ * An implementation of the model object 'Slider Description'.
+ *
+ *
+ * The following features are implemented:
+ *
+ *
+ * - {@link org.eclipse.sirius.web.customwidgets.impl.SliderDescriptionImpl#getMinValueExpression Min Value Expression}
+ * - {@link org.eclipse.sirius.web.customwidgets.impl.SliderDescriptionImpl#getMaxValueExpression Max Value Expression}
+ * - {@link org.eclipse.sirius.web.customwidgets.impl.SliderDescriptionImpl#getCurrentValueExpression Current Value Expression}
+ * - {@link org.eclipse.sirius.web.customwidgets.impl.SliderDescriptionImpl#getBody Body}
+ *
+ *
+ * @generated
+ */
+public class SliderDescriptionImpl extends WidgetDescriptionImpl implements SliderDescription {
+ /**
+ * The default value of the '{@link #getMinValueExpression() Min Value Expression}' attribute.
+ *
+ *
+ * @see #getMinValueExpression()
+ * @generated
+ * @ordered
+ */
+ protected static final String MIN_VALUE_EXPRESSION_EDEFAULT = null;
+
+ /**
+ * The cached value of the '{@link #getMinValueExpression() Min Value Expression}' attribute.
+ *
+ *
+ * @see #getMinValueExpression()
+ * @generated
+ * @ordered
+ */
+ protected String minValueExpression = MIN_VALUE_EXPRESSION_EDEFAULT;
+
+ /**
+ * The default value of the '{@link #getMaxValueExpression() Max Value Expression}' attribute.
+ *
+ *
+ * @see #getMaxValueExpression()
+ * @generated
+ * @ordered
+ */
+ protected static final String MAX_VALUE_EXPRESSION_EDEFAULT = null;
+
+ /**
+ * The cached value of the '{@link #getMaxValueExpression() Max Value Expression}' attribute.
+ *
+ *
+ * @see #getMaxValueExpression()
+ * @generated
+ * @ordered
+ */
+ protected String maxValueExpression = MAX_VALUE_EXPRESSION_EDEFAULT;
+
+ /**
+ * The default value of the '{@link #getCurrentValueExpression() Current Value Expression}' attribute.
+ *
+ *
+ * @see #getCurrentValueExpression()
+ * @generated
+ * @ordered
+ */
+ protected static final String CURRENT_VALUE_EXPRESSION_EDEFAULT = null;
+
+ /**
+ * The cached value of the '{@link #getCurrentValueExpression() Current Value Expression}' attribute.
+ *
+ *
+ * @see #getCurrentValueExpression()
+ * @generated
+ * @ordered
+ */
+ protected String currentValueExpression = CURRENT_VALUE_EXPRESSION_EDEFAULT;
+
+ /**
+ * The cached value of the '{@link #getBody() Body}' containment reference list.
+ *
+ *
+ * @see #getBody()
+ * @generated
+ * @ordered
+ */
+ protected EList body;
+
+ /**
+ *
+ *
+ * @generated
+ */
+ protected SliderDescriptionImpl() {
+ super();
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ protected EClass eStaticClass() {
+ return CustomwidgetsPackage.Literals.SLIDER_DESCRIPTION;
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ public String getMinValueExpression() {
+ return this.minValueExpression;
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ public void setMinValueExpression(String newMinValueExpression) {
+ String oldMinValueExpression = this.minValueExpression;
+ this.minValueExpression = newMinValueExpression;
+ if (this.eNotificationRequired())
+ this.eNotify(new ENotificationImpl(this, Notification.SET, CustomwidgetsPackage.SLIDER_DESCRIPTION__MIN_VALUE_EXPRESSION, oldMinValueExpression, this.minValueExpression));
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ public String getMaxValueExpression() {
+ return this.maxValueExpression;
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ public void setMaxValueExpression(String newMaxValueExpression) {
+ String oldMaxValueExpression = this.maxValueExpression;
+ this.maxValueExpression = newMaxValueExpression;
+ if (this.eNotificationRequired())
+ this.eNotify(new ENotificationImpl(this, Notification.SET, CustomwidgetsPackage.SLIDER_DESCRIPTION__MAX_VALUE_EXPRESSION, oldMaxValueExpression, this.maxValueExpression));
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ public String getCurrentValueExpression() {
+ return this.currentValueExpression;
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ public void setCurrentValueExpression(String newCurrentValueExpression) {
+ String oldCurrentValueExpression = this.currentValueExpression;
+ this.currentValueExpression = newCurrentValueExpression;
+ if (this.eNotificationRequired())
+ this.eNotify(new ENotificationImpl(this, Notification.SET, CustomwidgetsPackage.SLIDER_DESCRIPTION__CURRENT_VALUE_EXPRESSION, oldCurrentValueExpression, this.currentValueExpression));
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ public EList getBody() {
+ if (this.body == null) {
+ this.body = new EObjectContainmentEList<>(Operation.class, this, CustomwidgetsPackage.SLIDER_DESCRIPTION__BODY);
+ }
+ return this.body;
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
+ switch (featureID) {
+ case CustomwidgetsPackage.SLIDER_DESCRIPTION__BODY:
+ return ((InternalEList>)this.getBody()).basicRemove(otherEnd, msgs);
+ }
+ return super.eInverseRemove(otherEnd, featureID, msgs);
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ public Object eGet(int featureID, boolean resolve, boolean coreType) {
+ switch (featureID) {
+ case CustomwidgetsPackage.SLIDER_DESCRIPTION__MIN_VALUE_EXPRESSION:
+ return this.getMinValueExpression();
+ case CustomwidgetsPackage.SLIDER_DESCRIPTION__MAX_VALUE_EXPRESSION:
+ return this.getMaxValueExpression();
+ case CustomwidgetsPackage.SLIDER_DESCRIPTION__CURRENT_VALUE_EXPRESSION:
+ return this.getCurrentValueExpression();
+ case CustomwidgetsPackage.SLIDER_DESCRIPTION__BODY:
+ return this.getBody();
+ }
+ return super.eGet(featureID, resolve, coreType);
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public void eSet(int featureID, Object newValue) {
+ switch (featureID) {
+ case CustomwidgetsPackage.SLIDER_DESCRIPTION__MIN_VALUE_EXPRESSION:
+ this.setMinValueExpression((String)newValue);
+ return;
+ case CustomwidgetsPackage.SLIDER_DESCRIPTION__MAX_VALUE_EXPRESSION:
+ this.setMaxValueExpression((String)newValue);
+ return;
+ case CustomwidgetsPackage.SLIDER_DESCRIPTION__CURRENT_VALUE_EXPRESSION:
+ this.setCurrentValueExpression((String)newValue);
+ return;
+ case CustomwidgetsPackage.SLIDER_DESCRIPTION__BODY:
+ this.getBody().clear();
+ this.getBody().addAll((Collection extends Operation>)newValue);
+ return;
+ }
+ super.eSet(featureID, newValue);
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ public void eUnset(int featureID) {
+ switch (featureID) {
+ case CustomwidgetsPackage.SLIDER_DESCRIPTION__MIN_VALUE_EXPRESSION:
+ this.setMinValueExpression(MIN_VALUE_EXPRESSION_EDEFAULT);
+ return;
+ case CustomwidgetsPackage.SLIDER_DESCRIPTION__MAX_VALUE_EXPRESSION:
+ this.setMaxValueExpression(MAX_VALUE_EXPRESSION_EDEFAULT);
+ return;
+ case CustomwidgetsPackage.SLIDER_DESCRIPTION__CURRENT_VALUE_EXPRESSION:
+ this.setCurrentValueExpression(CURRENT_VALUE_EXPRESSION_EDEFAULT);
+ return;
+ case CustomwidgetsPackage.SLIDER_DESCRIPTION__BODY:
+ this.getBody().clear();
+ return;
+ }
+ super.eUnset(featureID);
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ public boolean eIsSet(int featureID) {
+ switch (featureID) {
+ case CustomwidgetsPackage.SLIDER_DESCRIPTION__MIN_VALUE_EXPRESSION:
+ return MIN_VALUE_EXPRESSION_EDEFAULT == null ? this.minValueExpression != null : !MIN_VALUE_EXPRESSION_EDEFAULT.equals(this.minValueExpression);
+ case CustomwidgetsPackage.SLIDER_DESCRIPTION__MAX_VALUE_EXPRESSION:
+ return MAX_VALUE_EXPRESSION_EDEFAULT == null ? this.maxValueExpression != null : !MAX_VALUE_EXPRESSION_EDEFAULT.equals(this.maxValueExpression);
+ case CustomwidgetsPackage.SLIDER_DESCRIPTION__CURRENT_VALUE_EXPRESSION:
+ return CURRENT_VALUE_EXPRESSION_EDEFAULT == null ? this.currentValueExpression != null : !CURRENT_VALUE_EXPRESSION_EDEFAULT.equals(this.currentValueExpression);
+ case CustomwidgetsPackage.SLIDER_DESCRIPTION__BODY:
+ return this.body != null && !this.body.isEmpty();
+ }
+ return super.eIsSet(featureID);
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ public String toString() {
+ if (this.eIsProxy()) return super.toString();
+
+ StringBuilder result = new StringBuilder(super.toString());
+ result.append(" (minValueExpression: ");
+ result.append(this.minValueExpression);
+ result.append(", maxValueExpression: ");
+ result.append(this.maxValueExpression);
+ result.append(", currentValueExpression: ");
+ result.append(this.currentValueExpression);
+ result.append(')');
+ return result.toString();
+ }
+
+} //SliderDescriptionImpl
diff --git a/packages/sirius-web/backend/sirius-web-customwidgets/src/main/java/org/eclipse/sirius/web/customwidgets/util/CustomwidgetsAdapterFactory.java b/packages/sirius-web/backend/sirius-web-customwidgets/src/main/java/org/eclipse/sirius/web/customwidgets/util/CustomwidgetsAdapterFactory.java
new file mode 100644
index 0000000000..60ba606ab1
--- /dev/null
+++ b/packages/sirius-web/backend/sirius-web-customwidgets/src/main/java/org/eclipse/sirius/web/customwidgets/util/CustomwidgetsAdapterFactory.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.web.customwidgets.util;
+
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.sirius.components.view.WidgetDescription;
+import org.eclipse.sirius.web.customwidgets.CustomwidgetsPackage;
+import org.eclipse.sirius.web.customwidgets.SliderDescription;
+
+/**
+ *
+ * The Adapter Factory for the model.
+ * It provides an adapter createXXX
method for each class of the model.
+ *
+ * @see org.eclipse.sirius.web.customwidgets.CustomwidgetsPackage
+ * @generated
+ */
+public class CustomwidgetsAdapterFactory extends AdapterFactoryImpl {
+ /**
+ * The cached model package.
+ *
+ *
+ * @generated
+ */
+ protected static CustomwidgetsPackage modelPackage;
+
+ /**
+ * Creates an instance of the adapter factory.
+ *
+ *
+ * @generated
+ */
+ public CustomwidgetsAdapterFactory() {
+ if (modelPackage == null) {
+ modelPackage = CustomwidgetsPackage.eINSTANCE;
+ }
+ }
+
+ /**
+ * Returns whether this factory is applicable for the type of the object.
+ *
+ * This implementation returns true
if the object is either the model's package or is an instance object of the model.
+ *
+ * @return whether this factory is applicable for the type of the object.
+ * @generated
+ */
+ @Override
+ public boolean isFactoryForType(Object object) {
+ if (object == modelPackage) {
+ return true;
+ }
+ if (object instanceof EObject) {
+ return ((EObject)object).eClass().getEPackage() == modelPackage;
+ }
+ return false;
+ }
+
+ /**
+ * The switch that delegates to the createXXX
methods.
+ *
+ *
+ * @generated
+ */
+ protected CustomwidgetsSwitch modelSwitch =
+ new CustomwidgetsSwitch<>() {
+ @Override
+ public Adapter caseSliderDescription(SliderDescription object) {
+ return CustomwidgetsAdapterFactory.this.createSliderDescriptionAdapter();
+ }
+ @Override
+ public Adapter caseWidgetDescription(WidgetDescription object) {
+ return CustomwidgetsAdapterFactory.this.createWidgetDescriptionAdapter();
+ }
+ @Override
+ public Adapter defaultCase(EObject object) {
+ return CustomwidgetsAdapterFactory.this.createEObjectAdapter();
+ }
+ };
+
+ /**
+ * Creates an adapter for the target
.
+ *
+ *
+ * @param target the object to adapt.
+ * @return the adapter for the target
.
+ * @generated
+ */
+ @Override
+ public Adapter createAdapter(Notifier target) {
+ return this.modelSwitch.doSwitch((EObject)target);
+ }
+
+
+ /**
+ * Creates a new adapter for an object of class '{@link org.eclipse.sirius.web.customwidgets.SliderDescription Slider Description}'.
+ *
+ * This default implementation returns null so that we can easily ignore cases;
+ * it's useful to ignore a case when inheritance will catch all the cases anyway.
+ *
+ * @return the new adapter.
+ * @see org.eclipse.sirius.web.customwidgets.SliderDescription
+ * @generated
+ */
+ public Adapter createSliderDescriptionAdapter() {
+ return null;
+ }
+
+ /**
+ * Creates a new adapter for an object of class '{@link org.eclipse.sirius.components.view.WidgetDescription Widget Description}'.
+ *
+ * This default implementation returns null so that we can easily ignore cases;
+ * it's useful to ignore a case when inheritance will catch all the cases anyway.
+ *
+ * @return the new adapter.
+ * @see org.eclipse.sirius.components.view.WidgetDescription
+ * @generated
+ */
+ public Adapter createWidgetDescriptionAdapter() {
+ return null;
+ }
+
+ /**
+ * Creates a new adapter for the default case.
+ *
+ * This default implementation returns null.
+ *
+ * @return the new adapter.
+ * @generated
+ */
+ public Adapter createEObjectAdapter() {
+ return null;
+ }
+
+} //CustomwidgetsAdapterFactory
diff --git a/packages/sirius-web/backend/sirius-web-customwidgets/src/main/java/org/eclipse/sirius/web/customwidgets/util/CustomwidgetsSwitch.java b/packages/sirius-web/backend/sirius-web-customwidgets/src/main/java/org/eclipse/sirius/web/customwidgets/util/CustomwidgetsSwitch.java
new file mode 100644
index 0000000000..166452a815
--- /dev/null
+++ b/packages/sirius-web/backend/sirius-web-customwidgets/src/main/java/org/eclipse/sirius/web/customwidgets/util/CustomwidgetsSwitch.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.web.customwidgets.util;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.util.Switch;
+import org.eclipse.sirius.components.view.WidgetDescription;
+import org.eclipse.sirius.web.customwidgets.CustomwidgetsPackage;
+import org.eclipse.sirius.web.customwidgets.SliderDescription;
+
+/**
+ *
+ * The Switch for the model's inheritance hierarchy.
+ * It supports the call {@link #doSwitch(EObject) doSwitch(object)}
+ * to invoke the caseXXX
method for each class of the model,
+ * starting with the actual class of the object
+ * and proceeding up the inheritance hierarchy
+ * until a non-null result is returned,
+ * which is the result of the switch.
+ *
+ * @see org.eclipse.sirius.web.customwidgets.CustomwidgetsPackage
+ * @generated
+ */
+public class CustomwidgetsSwitch extends Switch {
+ /**
+ * The cached model package
+ *
+ *
+ * @generated
+ */
+ protected static CustomwidgetsPackage modelPackage;
+
+ /**
+ * Creates an instance of the switch.
+ *
+ *
+ * @generated
+ */
+ public CustomwidgetsSwitch() {
+ if (modelPackage == null) {
+ modelPackage = CustomwidgetsPackage.eINSTANCE;
+ }
+ }
+
+ /**
+ * Checks whether this is a switch for the given package.
+ *
+ *
+ * @param ePackage the package in question.
+ * @return whether this is a switch for the given package.
+ * @generated
+ */
+ @Override
+ protected boolean isSwitchFor(EPackage ePackage) {
+ return ePackage == modelPackage;
+ }
+
+ /**
+ * Calls caseXXX
for each class of the model until one returns a non null result; it yields that result.
+ *
+ *
+ * @return the first non-null result returned by a caseXXX
call.
+ * @generated
+ */
+ @Override
+ protected T doSwitch(int classifierID, EObject theEObject) {
+ switch (classifierID) {
+ case CustomwidgetsPackage.SLIDER_DESCRIPTION: {
+ SliderDescription sliderDescription = (SliderDescription)theEObject;
+ T result = this.caseSliderDescription(sliderDescription);
+ if (result == null) result = this.caseWidgetDescription(sliderDescription);
+ if (result == null) result = this.defaultCase(theEObject);
+ return result;
+ }
+ default: return this.defaultCase(theEObject);
+ }
+ }
+
+ /**
+ * Returns the result of interpreting the object as an instance of 'Slider Description'.
+ *
+ * This implementation returns null;
+ * returning a non-null result will terminate the switch.
+ *
+ * @param object the target of the switch.
+ * @return the result of interpreting the object as an instance of 'Slider Description'.
+ * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+ * @generated
+ */
+ public T caseSliderDescription(SliderDescription object) {
+ return null;
+ }
+
+ /**
+ * Returns the result of interpreting the object as an instance of 'Widget Description'.
+ *
+ * This implementation returns null;
+ * returning a non-null result will terminate the switch.
+ *
+ * @param object the target of the switch.
+ * @return the result of interpreting the object as an instance of 'Widget Description'.
+ * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+ * @generated
+ */
+ public T caseWidgetDescription(WidgetDescription object) {
+ return null;
+ }
+
+ /**
+ * Returns the result of interpreting the object as an instance of 'EObject'.
+ *
+ * This implementation returns null;
+ * returning a non-null result will terminate the switch, but this is the last case anyway.
+ *
+ * @param object the target of the switch.
+ * @return the result of interpreting the object as an instance of 'EObject'.
+ * @see #doSwitch(org.eclipse.emf.ecore.EObject)
+ * @generated
+ */
+ @Override
+ public T defaultCase(EObject object) {
+ return null;
+ }
+
+} //CustomwidgetsSwitch
diff --git a/packages/sirius-web/backend/sirius-web-customwidgets/src/main/resources/model/customwidgets.ecore b/packages/sirius-web/backend/sirius-web-customwidgets/src/main/resources/model/customwidgets.ecore
new file mode 100644
index 0000000000..a3dd4b85af
--- /dev/null
+++ b/packages/sirius-web/backend/sirius-web-customwidgets/src/main/resources/model/customwidgets.ecore
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/packages/sirius-web/backend/sirius-web-customwidgets/src/main/resources/model/customwidgets.genmodel b/packages/sirius-web/backend/sirius-web-customwidgets/src/main/resources/model/customwidgets.genmodel
new file mode 100644
index 0000000000..92988c0e28
--- /dev/null
+++ b/packages/sirius-web/backend/sirius-web-customwidgets/src/main/resources/model/customwidgets.genmodel
@@ -0,0 +1,20 @@
+
+
+ customwidgets.ecore
+
+
+
+
+
+
+
+
+
diff --git a/packages/sirius-web/backend/sirius-web-sample-application/pom.xml b/packages/sirius-web/backend/sirius-web-sample-application/pom.xml
index 8d9d757805..7d19f62875 100644
--- a/packages/sirius-web/backend/sirius-web-sample-application/pom.xml
+++ b/packages/sirius-web/backend/sirius-web-sample-application/pom.xml
@@ -169,6 +169,16 @@
org.eclipse.eef.common
${eef.version}
+
+ org.eclipse.sirius
+ sirius-web-customwidgets
+ 2023.4.0
+
+
+ org.eclipse.sirius
+ sirius-web-customwidgets-edit
+ 2023.4.0
+
org.eclipse.sirius
sirius-components-forms-tests
2023.4.0
diff --git a/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/configuration/SampleEMFConfiguration.java b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/configuration/SampleEMFConfiguration.java
index ddfb5db62f..d70d0e7080 100644
--- a/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/configuration/SampleEMFConfiguration.java
+++ b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/configuration/SampleEMFConfiguration.java
@@ -15,14 +15,20 @@
import fr.obeo.dsl.designer.sample.flow.FlowPackage;
import fr.obeo.dsl.designer.sample.flow.provider.FlowItemProviderAdapterFactory;
+import java.util.List;
+
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.edit.EMFEditPlugin;
+import org.eclipse.emf.edit.provider.IChildCreationExtender;
import org.eclipse.sirius.components.domain.DomainPackage;
import org.eclipse.sirius.components.domain.provider.DomainItemProviderAdapterFactory;
import org.eclipse.sirius.components.emf.services.ILabelFeatureProvider;
import org.eclipse.sirius.components.emf.services.LabelFeatureProvider;
import org.eclipse.sirius.components.view.ViewPackage;
import org.eclipse.sirius.components.view.provider.ViewItemProviderAdapterFactory;
+import org.eclipse.sirius.web.customwidgets.CustomwidgetsPackage;
+import org.eclipse.sirius.web.customwidgets.provider.CustomwidgetsItemProviderAdapterFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -72,4 +78,18 @@ public EPackage viewEPackage() {
public AdapterFactory viewAdapterFactory() {
return new ViewItemProviderAdapterFactory();
}
+
+ @Bean
+ @ConditionalOnProperty(prefix = "org.eclipse.sirius.web.features", name = "studioDefinition")
+ public EPackage customWidgetsEPackage() {
+ return CustomwidgetsPackage.eINSTANCE;
+ }
+
+ @Bean
+ @ConditionalOnProperty(prefix = "org.eclipse.sirius.web.features", name = "studioDefinition")
+ public AdapterFactory customWidgetsAdapterFactory() {
+ var childExtenderRegistry = (IChildCreationExtender.Descriptor.Registry.Impl) EMFEditPlugin.getChildCreationExtenderDescriptorRegistry();
+ childExtenderRegistry.put(ViewPackage.eNS_URI, List.of(CustomwidgetsItemProviderAdapterFactory.ViewChildCreationExtender::new));
+ return new CustomwidgetsItemProviderAdapterFactory();
+ }
}
diff --git a/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/EditSliderInput.java b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/EditSliderInput.java
new file mode 100644
index 0000000000..90df25a902
--- /dev/null
+++ b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/EditSliderInput.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.web.sample.slider;
+
+import java.util.UUID;
+
+import org.eclipse.sirius.components.collaborative.forms.api.IFormInput;
+
+/**
+ * Object for the slider edition mutation.
+ *
+ * @author pcdavid
+ */
+public record EditSliderInput(UUID id, String editingContextId, String representationId, String sliderId, int newValue) implements IFormInput {
+
+}
diff --git a/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/EditSliderValueEventHandler.java b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/EditSliderValueEventHandler.java
new file mode 100644
index 0000000000..c042a64df7
--- /dev/null
+++ b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/EditSliderValueEventHandler.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.web.sample.slider;
+
+import java.util.Objects;
+
+import org.eclipse.sirius.components.collaborative.api.ChangeDescription;
+import org.eclipse.sirius.components.collaborative.api.ChangeKind;
+import org.eclipse.sirius.components.collaborative.api.Monitoring;
+import org.eclipse.sirius.components.collaborative.forms.api.IFormEventHandler;
+import org.eclipse.sirius.components.collaborative.forms.api.IFormInput;
+import org.eclipse.sirius.components.collaborative.forms.api.IFormQueryService;
+import org.eclipse.sirius.components.collaborative.forms.messages.ICollaborativeFormMessageService;
+import org.eclipse.sirius.components.core.api.ErrorPayload;
+import org.eclipse.sirius.components.core.api.IEditingContext;
+import org.eclipse.sirius.components.core.api.IPayload;
+import org.eclipse.sirius.components.core.api.SuccessPayload;
+import org.eclipse.sirius.components.forms.Form;
+import org.eclipse.sirius.components.representations.Failure;
+import org.eclipse.sirius.components.representations.IStatus;
+import org.eclipse.sirius.components.representations.Success;
+import org.springframework.stereotype.Service;
+
+import io.micrometer.core.instrument.Counter;
+import io.micrometer.core.instrument.MeterRegistry;
+import reactor.core.publisher.Sinks.Many;
+import reactor.core.publisher.Sinks.One;
+
+/**
+ * Handler invoked when the end-user edits the value of a slider widget.
+ *
+ * @author pcdavid
+ */
+@Service
+public class EditSliderValueEventHandler implements IFormEventHandler {
+ private final IFormQueryService formQueryService;
+
+ private final ICollaborativeFormMessageService messageService;
+
+ private final Counter counter;
+
+ public EditSliderValueEventHandler(IFormQueryService formQueryService, ICollaborativeFormMessageService messageService, MeterRegistry meterRegistry) {
+ this.formQueryService = Objects.requireNonNull(formQueryService);
+ this.messageService = Objects.requireNonNull(messageService);
+
+ // @formatter:off
+ this.counter = Counter.builder(Monitoring.EVENT_HANDLER)
+ .tag(Monitoring.NAME, this.getClass().getSimpleName())
+ .register(meterRegistry);
+ // @formatter:on
+ }
+
+ @Override
+ public boolean canHandle(IFormInput formInput) {
+ return formInput instanceof EditSliderInput;
+ }
+
+ @Override
+ public void handle(One payloadSink, Many changeDescriptionSink, IEditingContext editingContext, Form form, IFormInput formInput) {
+ this.counter.increment();
+ String message = this.messageService.invalidInput(formInput.getClass().getSimpleName(), EditSliderInput.class.getSimpleName());
+ IPayload payload = new ErrorPayload(formInput.id(), message);
+ ChangeDescription changeDescription = new ChangeDescription(ChangeKind.NOTHING, formInput.representationId(), formInput);
+
+ if (formInput instanceof EditSliderInput) {
+ EditSliderInput input = (EditSliderInput) formInput;
+
+ // @formatter:off
+ var optionalSlider = this.formQueryService.findWidget(form, input.sliderId())
+ .filter(Slider.class::isInstance)
+ .map(Slider.class::cast);
+
+ IStatus status = optionalSlider.map(Slider::getNewValueHandler)
+ .map(handler -> {
+ return handler.apply(Integer.valueOf(input.newValue()));
+ })
+ .orElse(new Failure(""));
+ // @formatter:on
+
+ if (status instanceof Success) {
+ payload = new SuccessPayload(formInput.id());
+ changeDescription = new ChangeDescription(ChangeKind.SEMANTIC_CHANGE, formInput.representationId(), formInput);
+ } else if (status instanceof Failure) {
+ payload = new ErrorPayload(formInput.id(), ((Failure) status).getMessage());
+ }
+ }
+
+ changeDescriptionSink.tryEmitNext(changeDescription);
+ payloadSink.tryEmitValue(payload);
+ }
+
+}
diff --git a/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/MutationEditSliderDataFetcher.java b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/MutationEditSliderDataFetcher.java
new file mode 100644
index 0000000000..4dc1258f07
--- /dev/null
+++ b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/MutationEditSliderDataFetcher.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.web.sample.slider;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
+
+import org.eclipse.sirius.components.annotations.spring.graphql.MutationDataFetcher;
+import org.eclipse.sirius.components.core.api.IPayload;
+import org.eclipse.sirius.components.graphql.api.IDataFetcherWithFieldCoordinates;
+import org.eclipse.sirius.components.graphql.api.IEditingContextDispatcher;
+import org.eclipse.sirius.components.graphql.api.IExceptionWrapper;
+
+import graphql.schema.DataFetchingEnvironment;
+
+/**
+ * The data fetcher used to edit a slider.
+ *
+ * @author pcdavid
+ */
+@MutationDataFetcher(type = "Mutation", field = "editSlider")
+public class MutationEditSliderDataFetcher implements IDataFetcherWithFieldCoordinates> {
+ private static final String INPUT_ARGUMENT = "input";
+
+ private final ObjectMapper objectMapper;
+
+ private final IExceptionWrapper exceptionWrapper;
+
+ private final IEditingContextDispatcher editingContextDispatcher;
+
+ public MutationEditSliderDataFetcher(ObjectMapper objectMapper, IExceptionWrapper exceptionWrapper, IEditingContextDispatcher editingContextDispatcher) {
+ this.objectMapper = Objects.requireNonNull(objectMapper);
+ this.exceptionWrapper = Objects.requireNonNull(exceptionWrapper);
+ this.editingContextDispatcher = Objects.requireNonNull(editingContextDispatcher);
+ }
+
+ @Override
+ public CompletableFuture get(DataFetchingEnvironment environment) throws Exception {
+ Object argument = environment.getArgument(INPUT_ARGUMENT);
+ var input = this.objectMapper.convertValue(argument, EditSliderInput.class);
+
+ return this.exceptionWrapper.wrapMono(() -> this.editingContextDispatcher.dispatchMutation(input.editingContextId(), input), input).toFuture();
+ }
+}
diff --git a/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/Slider.java b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/Slider.java
new file mode 100644
index 0000000000..712bdff7d1
--- /dev/null
+++ b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/Slider.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.web.sample.slider;
+
+import java.text.MessageFormat;
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Function;
+
+import org.eclipse.sirius.components.annotations.Immutable;
+import org.eclipse.sirius.components.forms.AbstractWidget;
+import org.eclipse.sirius.components.forms.validation.Diagnostic;
+import org.eclipse.sirius.components.representations.IStatus;
+
+/**
+ * A simple Slider widget to edit an integer value inside a given range.
+ *
+ * @author pcdavid
+ */
+@Immutable
+public final class Slider extends AbstractWidget {
+ private int minValue;
+
+ private int maxValue;
+
+ private int currentValue;
+
+ private Function newValueHandler;
+
+ private Slider() {
+ // Prevent instantiation
+ }
+
+ public int getMinValue() {
+ return this.minValue;
+ }
+
+ public int getMaxValue() {
+ return this.maxValue;
+ }
+
+ public int getCurrentValue() {
+ return this.currentValue;
+ }
+
+ public Function getNewValueHandler() {
+ return this.newValueHandler;
+ }
+
+ @Override
+ public String toString() {
+ String pattern = "{0} '{'minValue: {1}, maxValue: {2}, currentValue: {3}, newValue: {4}'}'";
+ return MessageFormat.format(pattern, this.getClass().getSimpleName(), this.getMinValue(), this.getMaxValue(), this.getCurrentValue(), this.getNewValueHandler());
+ }
+
+ public static Builder newSlider(String id) {
+ return new Builder(id);
+ }
+
+ /**
+ * Builder used to create the Slider.
+ */
+ @SuppressWarnings("checkstyle:HiddenField")
+ public static final class Builder {
+ private String id;
+
+ private String label;
+
+ private String iconURL;
+
+ private List diagnostics;
+
+ private int minValue;
+
+ private int maxValue;
+
+ private int currentValue;
+
+ private Function newValueHandler;
+ private Builder(String id) {
+ this.id = Objects.requireNonNull(id);
+ }
+ public Builder label(String label) {
+ this.label = Objects.requireNonNull(label);
+ return this;
+ }
+
+ public Builder iconURL(String iconURL) {
+ this.iconURL = Objects.requireNonNull(iconURL);
+ return this;
+ }
+ public Builder diagnostics(List diagnostics) {
+ this.diagnostics = Objects.requireNonNull(diagnostics);
+ return this;
+ }
+ public Builder minValue(int minValue) {
+ this.minValue = Objects.requireNonNull(minValue);
+ return this;
+ }
+
+ public Builder maxValue(int maxValue) {
+ this.maxValue = Objects.requireNonNull(maxValue);
+ return this;
+ }
+
+ public Builder currentValue(int currentValue) {
+ this.currentValue = Objects.requireNonNull(currentValue);
+ return this;
+ }
+
+ public Builder newValueHandler(Function newValueHandler) {
+ this.newValueHandler = Objects.requireNonNull(newValueHandler);
+ return this;
+ }
+
+ public Slider build() {
+ Slider slider = new Slider();
+ slider.id = Objects.requireNonNull(this.id);
+ slider.label = Objects.requireNonNull(this.label);
+ slider.iconURL = this.iconURL;
+ slider.minValue = Objects.requireNonNull(this.minValue);
+ slider.maxValue = Objects.requireNonNull(this.maxValue);
+ slider.currentValue = Objects.requireNonNull(this.currentValue);
+ slider.newValueHandler = Objects.requireNonNull(this.newValueHandler);
+ slider.diagnostics = Objects.requireNonNull(this.diagnostics);
+ return slider;
+ }
+ }
+
+}
diff --git a/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/SliderComponent.java b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/SliderComponent.java
new file mode 100644
index 0000000000..4f5d578726
--- /dev/null
+++ b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/SliderComponent.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.web.sample.slider;
+
+import java.util.Objects;
+import java.util.function.Function;
+
+import org.eclipse.sirius.components.representations.Element;
+import org.eclipse.sirius.components.representations.IComponent;
+import org.eclipse.sirius.components.representations.IStatus;
+import org.eclipse.sirius.components.representations.VariableManager;
+import org.eclipse.sirius.web.sample.slider.SliderElementProps.Builder;
+
+/**
+ * The component to render a slider.
+ *
+ * @author pcdavid
+ */
+public class SliderComponent implements IComponent {
+ private final SliderComponentProps props;
+
+ public SliderComponent(SliderComponentProps props) {
+ this.props = Objects.requireNonNull(props);
+ }
+
+ @Override
+ public Element render() {
+ VariableManager variableManager = this.props.getVariableManager();
+ SliderDescription sliderDescription = this.props.getSliderDescription();
+
+ String id = sliderDescription.getIdProvider().apply(variableManager);
+ String label = sliderDescription.getLabelProvider().apply(variableManager);
+ String iconURL = sliderDescription.getIconURLProvider().apply(variableManager);
+ int minValue = sliderDescription.getMinValueProvider().apply(variableManager);
+ int maxValue = sliderDescription.getMaxValueProvider().apply(variableManager);
+ int currentValue = sliderDescription.getCurrentValueProvider().apply(variableManager);
+ Function newValueHandler = sliderDescription.getNewValueHandler();
+ Function specializedHandler = (newValue) -> {
+ var childVariableManager = variableManager.createChild();
+ childVariableManager.put("newValue", newValue);
+ return newValueHandler.apply(childVariableManager);
+ };
+
+ // @formatter:off
+ Builder sliderElementPropsBuilder = SliderElementProps.newSliderElementProps(id)
+ .label(label)
+ .minValue(minValue)
+ .maxValue(maxValue)
+ .currentValue(currentValue)
+ .newValueHandler(specializedHandler);
+ // @formatter:on
+ if (iconURL != null) {
+ sliderElementPropsBuilder.iconURL(iconURL);
+ }
+
+ SliderElementProps sliderElementProps = sliderElementPropsBuilder.build();
+
+ return new Element(SliderElementProps.TYPE, sliderElementProps);
+ }
+}
diff --git a/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/SliderComponentProps.java b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/SliderComponentProps.java
new file mode 100644
index 0000000000..99066d6ef7
--- /dev/null
+++ b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/SliderComponentProps.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.web.sample.slider;
+
+import java.util.Objects;
+
+import org.eclipse.sirius.components.representations.IProps;
+import org.eclipse.sirius.components.representations.VariableManager;
+
+/**
+ * The properties of the slider component.
+ * @author pcdavid
+ */
+public class SliderComponentProps implements IProps {
+ private final VariableManager variableManager;
+
+ private final SliderDescription sliderDescription;
+
+ public SliderComponentProps(VariableManager variableManager, SliderDescription sliderDescription) {
+ this.variableManager = Objects.requireNonNull(variableManager);
+ this.sliderDescription = Objects.requireNonNull(sliderDescription);
+ }
+
+ public VariableManager getVariableManager() {
+ return this.variableManager;
+ }
+
+ public SliderDescription getSliderDescription() {
+ return this.sliderDescription;
+ }
+}
diff --git a/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/SliderDescription.java b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/SliderDescription.java
new file mode 100644
index 0000000000..db5ed5d50a
--- /dev/null
+++ b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/SliderDescription.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.web.sample.slider;
+
+import java.text.MessageFormat;
+import java.util.Objects;
+import java.util.function.Function;
+
+import org.eclipse.sirius.components.annotations.Immutable;
+import org.eclipse.sirius.components.forms.description.AbstractWidgetDescription;
+import org.eclipse.sirius.components.representations.IStatus;
+import org.eclipse.sirius.components.representations.VariableManager;
+
+/**
+ * Custom slider widget description.
+ *
+ * @author pcdavid
+ */
+@Immutable
+public final class SliderDescription extends AbstractWidgetDescription {
+ private Function idProvider;
+
+ private Function labelProvider;
+
+ private Function iconURLProvider;
+
+ private Function minValueProvider;
+
+ private Function maxValueProvider;
+
+ private Function currentValueProvider;
+
+ private Function newValueHandler;
+
+ private SliderDescription() {
+ // Prevent instantiation
+ }
+
+ public Function getIdProvider() {
+ return this.idProvider;
+ }
+
+ public Function getLabelProvider() {
+ return this.labelProvider;
+ }
+
+ public Function getIconURLProvider() {
+ return this.iconURLProvider;
+ }
+
+ public Function getMinValueProvider() {
+ return this.minValueProvider;
+ }
+
+ public Function getMaxValueProvider() {
+ return this.maxValueProvider;
+ }
+
+ public Function getCurrentValueProvider() {
+ return this.currentValueProvider;
+ }
+
+ public Function getNewValueHandler() {
+ return this.newValueHandler;
+ }
+
+ @Override
+ public String toString() {
+ String pattern = "{0} '{'idProvider: {1}, labelProvider: {2}, iconURLProvider: {3}, minValueProvider: {4}, maxValueProvider: {5}, currentValueProvider: {6}, newValueHandler: {7}'}'";
+ return MessageFormat.format(pattern, this.getClass().getSimpleName(), this.getIdProvider(), this.getLabelProvider(), this.getIconURLProvider(), this.getMinValueProvider(),
+ this.getMaxValueProvider(), this.getCurrentValueProvider(), this.getNewValueHandler());
+ }
+
+ public static Builder newSliderDescription(String id) {
+ return new Builder(id);
+ }
+
+ /**
+ * Builder used to create the SliderDescription.
+ */
+ @SuppressWarnings("checkstyle:HiddenField")
+ public static final class Builder {
+ private final String id;
+ private Function idProvider;
+
+ private Function labelProvider;
+
+ private Function iconURLProvider = variableManager -> null;
+
+ private Function minValueProvider;
+
+ private Function maxValueProvider;
+
+ private Function currentValueProvider;
+
+ private Function newValueHandler;
+ private Builder(String id) {
+ this.id = Objects.requireNonNull(id);
+ }
+ public Builder idProvider(Function idProvider) {
+ this.idProvider = Objects.requireNonNull(idProvider);
+ return this;
+ }
+
+ public Builder labelProvider(Function labelProvider) {
+ this.labelProvider = Objects.requireNonNull(labelProvider);
+ return this;
+ }
+
+ public Builder iconURLProvider(Function iconURLProvider) {
+ this.iconURLProvider = Objects.requireNonNull(iconURLProvider);
+ return this;
+ }
+
+ public Builder minValueProvider(Function minValueProvider) {
+ this.minValueProvider = Objects.requireNonNull(minValueProvider);
+ return this;
+ }
+
+ public Builder maxValueProvider(Function maxValueProvider) {
+ this.maxValueProvider = Objects.requireNonNull(maxValueProvider);
+ return this;
+ }
+
+ public Builder currentValueProvider(Function currentValueProvider) {
+ this.currentValueProvider = Objects.requireNonNull(currentValueProvider);
+ return this;
+ }
+
+ public Builder newValueHandler(Function newValueHandler) {
+ this.newValueHandler = Objects.requireNonNull(newValueHandler);
+ return this;
+ }
+
+ public SliderDescription build() {
+ SliderDescription sliderDescription = new SliderDescription();
+ sliderDescription.id = Objects.requireNonNull(this.id);
+ sliderDescription.idProvider = Objects.requireNonNull(this.idProvider);
+ sliderDescription.labelProvider = Objects.requireNonNull(this.labelProvider);
+ sliderDescription.iconURLProvider = this.iconURLProvider;
+ sliderDescription.minValueProvider = Objects.requireNonNull(this.minValueProvider);
+ sliderDescription.maxValueProvider = Objects.requireNonNull(this.maxValueProvider);
+ sliderDescription.currentValueProvider = Objects.requireNonNull(this.currentValueProvider);
+ sliderDescription.newValueHandler = Objects.requireNonNull(this.newValueHandler);
+ return sliderDescription;
+ }
+ }
+
+}
diff --git a/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/SliderDescriptionConverterProvider.java b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/SliderDescriptionConverterProvider.java
new file mode 100644
index 0000000000..09dcc5eda1
--- /dev/null
+++ b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/SliderDescriptionConverterProvider.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.web.sample.slider;
+
+import org.eclipse.emf.ecore.util.Switch;
+import org.eclipse.sirius.components.core.api.IEditService;
+import org.eclipse.sirius.components.core.api.IObjectService;
+import org.eclipse.sirius.components.forms.description.AbstractWidgetDescription;
+import org.eclipse.sirius.components.interpreter.AQLInterpreter;
+import org.eclipse.sirius.components.view.emf.form.IWidgetConverterProvider;
+import org.springframework.stereotype.Service;
+
+/**
+ * Provides the widget converter needed for the Slider widget.
+ *
+ * @author pcdavid
+ */
+@Service
+public class SliderDescriptionConverterProvider implements IWidgetConverterProvider {
+ @Override
+ public Switch getWidgetConverter(AQLInterpreter interpreter, IEditService editService, IObjectService objectService) {
+ return new SliderDescriptionConverterSwitch(interpreter, editService);
+ }
+}
diff --git a/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/SliderDescriptionConverterSwitch.java b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/SliderDescriptionConverterSwitch.java
new file mode 100644
index 0000000000..355238843f
--- /dev/null
+++ b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/SliderDescriptionConverterSwitch.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.web.sample.slider;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.function.Function;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.sirius.components.compatibility.forms.WidgetIdProvider;
+import org.eclipse.sirius.components.compatibility.utils.StringValueProvider;
+import org.eclipse.sirius.components.core.api.IEditService;
+import org.eclipse.sirius.components.forms.description.AbstractWidgetDescription;
+import org.eclipse.sirius.components.interpreter.AQLInterpreter;
+import org.eclipse.sirius.components.interpreter.Result;
+import org.eclipse.sirius.components.representations.Failure;
+import org.eclipse.sirius.components.representations.IStatus;
+import org.eclipse.sirius.components.representations.Success;
+import org.eclipse.sirius.components.representations.VariableManager;
+import org.eclipse.sirius.components.view.Operation;
+import org.eclipse.sirius.components.view.emf.OperationInterpreter;
+import org.eclipse.sirius.web.customwidgets.SliderDescription;
+import org.eclipse.sirius.web.customwidgets.util.CustomwidgetsSwitch;
+
+/**
+ * Converts a modeled Slider Description into its API equivalent.
+ *
+ * @author pcdavid
+ */
+public class SliderDescriptionConverterSwitch extends CustomwidgetsSwitch {
+ private final AQLInterpreter interpreter;
+
+ private final IEditService editService;
+
+ public SliderDescriptionConverterSwitch(AQLInterpreter interpreter, IEditService editService) {
+ this.interpreter = Objects.requireNonNull(interpreter);
+ this.editService = Objects.requireNonNull(editService);
+ }
+
+ @Override
+ public AbstractWidgetDescription caseSliderDescription(SliderDescription viewSliderDescription) {
+ String descriptionId = this.getDescriptionId(viewSliderDescription);
+ WidgetIdProvider idProvider = new WidgetIdProvider();
+ StringValueProvider labelProvider = this.getStringValueProvider(viewSliderDescription.getLabelExpression());
+ Function minValueProvider = this.getIntValueProvider(viewSliderDescription.getMinValueExpression());
+ Function maxValueProvider = this.getIntValueProvider(viewSliderDescription.getMaxValueExpression());
+ Function currentValueProvider = this.getIntValueProvider(viewSliderDescription.getCurrentValueExpression());
+ Function newValueHandler = this.getOperationsHandler(viewSliderDescription.getBody());
+
+ // @formatter:off
+ return org.eclipse.sirius.web.sample.slider.SliderDescription.newSliderDescription(descriptionId)
+ .idProvider(idProvider)
+ .labelProvider(labelProvider)
+ .minValueProvider(minValueProvider)
+ .maxValueProvider(maxValueProvider)
+ .currentValueProvider(currentValueProvider)
+ .newValueHandler(newValueHandler)
+ .build();
+ // @formatter:on
+ }
+
+ private Function getIntValueProvider(String intValueExpression) {
+ String safeValueExpression = Optional.ofNullable(intValueExpression).orElse("");
+ return variableManager -> {
+ if (!safeValueExpression.isBlank()) {
+ Result result = this.interpreter.evaluateExpression(variableManager.getVariables(), safeValueExpression);
+ return result.asInt().orElse(0);
+ }
+ return 0;
+ };
+ }
+
+ private Function getOperationsHandler(List operations) {
+ return variableManager -> {
+ OperationInterpreter operationInterpreter = new OperationInterpreter(this.interpreter, this.editService);
+ Optional optionalVariableManager = operationInterpreter.executeOperations(operations, variableManager);
+ if (optionalVariableManager.isEmpty()) {
+ return new Failure("Something went wrong while handling the widget operations execution.");
+ } else {
+ return new Success();
+ }
+ };
+ }
+
+ private StringValueProvider getStringValueProvider(String valueExpression) {
+ String safeValueExpression = Optional.ofNullable(valueExpression).orElse("");
+ return new StringValueProvider(this.interpreter, safeValueExpression);
+ }
+
+ private String getDescriptionId(EObject description) {
+ String descriptionURI = EcoreUtil.getURI(description).toString();
+ return UUID.nameUUIDFromBytes(descriptionURI.getBytes()).toString();
+ }
+}
diff --git a/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/SliderElementProps.java b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/SliderElementProps.java
new file mode 100644
index 0000000000..84de0d68e0
--- /dev/null
+++ b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/SliderElementProps.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.web.sample.slider;
+
+import java.text.MessageFormat;
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Function;
+
+import org.eclipse.sirius.components.annotations.Immutable;
+import org.eclipse.sirius.components.forms.validation.Diagnostic;
+import org.eclipse.sirius.components.representations.IProps;
+import org.eclipse.sirius.components.representations.IStatus;
+
+/**
+ * The properties for the Slider element.
+ *
+ * @author pcdavid
+ */
+@Immutable
+public final class SliderElementProps implements IProps {
+ public static final String TYPE = "Slider";
+
+ private String id;
+
+ private String label;
+
+ private String iconURL;
+
+ private int minValue;
+
+ private int maxValue;
+
+ private int currentValue;
+
+ private Function newValueHandler;
+
+ private SliderElementProps() {
+ // Prevent instantiation
+ }
+
+ public String getId() {
+ return this.id;
+ }
+
+ public String getLabel() {
+ return this.label;
+ }
+
+ public String getIconURL() {
+ return this.iconURL;
+ }
+
+ public int getMinValue() {
+ return this.minValue;
+ }
+
+ public int getMaxValue() {
+ return this.maxValue;
+ }
+
+ public int getCurrentValue() {
+ return this.currentValue;
+ }
+
+ public Function getNewValueHandler() {
+ return this.newValueHandler;
+ }
+
+ public static Builder newSliderElementProps(String id) {
+ return new Builder(id);
+ }
+
+ @Override
+ public String toString() {
+ String pattern = "{0} '{'id: {1}, label: {2}, minValue: {3}, maxValue: {4}, currentValue: {5}'}'";
+ return MessageFormat.format(pattern, this.getClass().getSimpleName(), this.id, this.label, this.minValue, this.maxValue, this.currentValue);
+ }
+
+ /**
+ * The builder of the slider element props.
+ *
+ * @author pcdavid
+ */
+ @SuppressWarnings("checkstyle:HiddenField")
+ public static final class Builder {
+ private String id;
+
+ private String label;
+
+ private String iconURL;
+
+ private List diagnostics;
+
+ private int minValue;
+
+ private int maxValue;
+
+ private int currentValue;
+
+ private Function newValueHandler;
+
+ private Builder(String id) {
+ this.id = Objects.requireNonNull(id);
+ }
+
+ public Builder label(String label) {
+ this.label = Objects.requireNonNull(label);
+ return this;
+ }
+
+ public Builder iconURL(String iconURL) {
+ this.iconURL = Objects.requireNonNull(iconURL);
+ return this;
+ }
+
+ public Builder minValue(int minValue) {
+ this.minValue = minValue;
+ return this;
+ }
+
+ public Builder maxValue(int maxValue) {
+ this.maxValue = maxValue;
+ return this;
+ }
+
+ public Builder currentValue(int currentValue) {
+ this.currentValue = currentValue;
+ return this;
+ }
+
+ public Builder newValueHandler(Function newValueHandler) {
+ this.newValueHandler = Objects.requireNonNull(newValueHandler);
+ return this;
+ }
+
+ public Builder diagnostics(List diagnostics) {
+ this.diagnostics = Objects.requireNonNull(diagnostics);
+ return this;
+ }
+
+ public SliderElementProps build() {
+ SliderElementProps sliderElementProps = new SliderElementProps();
+ sliderElementProps.id = Objects.requireNonNull(this.id);
+ sliderElementProps.label = Objects.requireNonNull(this.label);
+ sliderElementProps.iconURL = this.iconURL;
+ sliderElementProps.minValue = this.minValue;
+ sliderElementProps.maxValue = this.maxValue;
+ sliderElementProps.currentValue = this.currentValue;
+ sliderElementProps.newValueHandler = Objects.requireNonNull(this.newValueHandler);
+ return sliderElementProps;
+ }
+ }
+}
diff --git a/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/SliderWidgetDescriptor.java b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/SliderWidgetDescriptor.java
new file mode 100644
index 0000000000..08decab0f3
--- /dev/null
+++ b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/SliderWidgetDescriptor.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.web.sample.slider;
+
+import java.util.List;
+import java.util.Optional;
+
+import org.eclipse.sirius.components.forms.description.AbstractWidgetDescription;
+import org.eclipse.sirius.components.forms.renderer.IWidgetDescriptor;
+import org.eclipse.sirius.components.representations.Element;
+import org.eclipse.sirius.components.representations.IComponent;
+import org.eclipse.sirius.components.representations.IProps;
+import org.eclipse.sirius.components.representations.VariableManager;
+import org.springframework.stereotype.Component;
+
+/**
+ * Widget descriptor for the Slider custom widget.
+ *
+ * @author pcdavid
+ */
+@Component
+public class SliderWidgetDescriptor implements IWidgetDescriptor {
+ public static final String TYPE = "Slider";
+
+ @Override
+ public String getWidgetType() {
+ return TYPE;
+ }
+
+ @Override
+ public Class extends IComponent> getComponentClass() {
+ return SliderComponent.class;
+ }
+
+ @Override
+ public Class extends IProps> getInstancePropsClass() {
+ return SliderElementProps.class;
+ }
+
+ @Override
+ public Class extends IProps> getComponentPropsClass() {
+ return SliderComponentProps.class;
+ }
+
+ @Override
+ public Optional