diff --git a/build.gradle.kts b/build.gradle.kts index 57e42d2b..5e015498 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -11,7 +11,7 @@ val dataforgeVersion by extra("0.7.1") allprojects { group = "space.kscience" - version = "0.3.0-RC" + version = "0.3.0" } subprojects { diff --git a/visionforge-core/api/visionforge-core.api b/visionforge-core/api/visionforge-core.api index 0cd2b904..89e926ec 100644 --- a/visionforge-core/api/visionforge-core.api +++ b/visionforge-core/api/visionforge-core.api @@ -225,6 +225,8 @@ public abstract interface class space/kscience/visionforge/ControlVision : space public final class space/kscience/visionforge/ControlVisionKt { public static final fun VisionClickEvent (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;)Lspace/kscience/visionforge/VisionClickEvent; public static synthetic fun VisionClickEvent$default (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;ILjava/lang/Object;)Lspace/kscience/visionforge/VisionClickEvent; + public static final fun VisionInputEvent (Lspace/kscience/dataforge/meta/Value;Lspace/kscience/dataforge/names/Name;)Lspace/kscience/visionforge/VisionInputEvent; + public static synthetic fun VisionInputEvent$default (Lspace/kscience/dataforge/meta/Value;Lspace/kscience/dataforge/names/Name;ILjava/lang/Object;)Lspace/kscience/visionforge/VisionInputEvent; public static final fun VisionValueChangeEvent (Lspace/kscience/dataforge/meta/Value;Lspace/kscience/dataforge/names/Name;)Lspace/kscience/visionforge/VisionValueChangeEvent; public static synthetic fun VisionValueChangeEvent$default (Lspace/kscience/dataforge/meta/Value;Lspace/kscience/dataforge/names/Name;ILjava/lang/Object;)Lspace/kscience/visionforge/VisionValueChangeEvent; public static final fun onClick (Lspace/kscience/visionforge/ClickControl;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/Job; @@ -495,6 +497,7 @@ public final class space/kscience/visionforge/VisionClientKt { public static final fun notifyPropertyChanged (Lspace/kscience/visionforge/VisionClient;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Ljava/lang/String;)V public static final fun notifyPropertyChanged (Lspace/kscience/visionforge/VisionClient;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;)V public static final fun notifyPropertyChanged (Lspace/kscience/visionforge/VisionClient;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Z)V + public static final fun sendEventAsync (Lspace/kscience/visionforge/VisionClient;Lspace/kscience/dataforge/names/Name;Lspace/kscience/visionforge/VisionEvent;)Lkotlinx/coroutines/Job; } public abstract interface class space/kscience/visionforge/VisionContainer { @@ -560,6 +563,30 @@ public final class space/kscience/visionforge/VisionGroupKt { public static synthetic fun group$default (Lspace/kscience/visionforge/MutableVisionContainer;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/visionforge/SimpleVisionGroup; } +public final class space/kscience/visionforge/VisionInputEvent : space/kscience/visionforge/VisionControlEvent { + public static final field Companion Lspace/kscience/visionforge/VisionInputEvent$Companion; + public fun (Lspace/kscience/dataforge/meta/Meta;)V + public fun getMeta ()Lspace/kscience/dataforge/meta/Meta; + public final fun getName ()Lspace/kscience/dataforge/names/Name; + public final fun getValue ()Lspace/kscience/dataforge/meta/Value; + public fun toString ()Ljava/lang/String; +} + +public final class space/kscience/visionforge/VisionInputEvent$$serializer : kotlinx/serialization/internal/GeneratedSerializer { + public static final field INSTANCE Lspace/kscience/visionforge/VisionInputEvent$$serializer; + public fun childSerializers ()[Lkotlinx/serialization/KSerializer; + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/visionforge/VisionInputEvent; + public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V + public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/visionforge/VisionInputEvent;)V + public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; +} + +public final class space/kscience/visionforge/VisionInputEvent$Companion { + public final fun serializer ()Lkotlinx/serialization/KSerializer; +} + public final class space/kscience/visionforge/VisionKt { public static final fun getVisible (Lspace/kscience/visionforge/Vision;)Ljava/lang/Boolean; public static final fun onPropertyChange (Lspace/kscience/visionforge/Vision;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/Job; @@ -649,8 +676,8 @@ public final class space/kscience/visionforge/VisionPropertiesKt { public static final fun get (Lspace/kscience/visionforge/VisionProperties;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Boolean;)Lspace/kscience/dataforge/meta/Meta; public static synthetic fun get$default (Lspace/kscience/visionforge/MutableVisionProperties;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Boolean;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/MutableMeta; public static synthetic fun get$default (Lspace/kscience/visionforge/VisionProperties;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Boolean;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/Meta; - public static final fun getValue (Lspace/kscience/visionforge/VisionProperties;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Boolean;)Lspace/kscience/dataforge/meta/Value; - public static synthetic fun getValue$default (Lspace/kscience/visionforge/VisionProperties;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Boolean;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/Value; + public static final fun getValue (Lspace/kscience/visionforge/VisionProperties;Ljava/lang/String;ZLjava/lang/Boolean;)Lspace/kscience/dataforge/meta/Value; + public static synthetic fun getValue$default (Lspace/kscience/visionforge/VisionProperties;Ljava/lang/String;ZLjava/lang/Boolean;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/Value; public static final fun invoke (Lspace/kscience/visionforge/MutableVisionProperties;Lkotlin/jvm/functions/Function1;)V public static final fun remove (Lspace/kscience/visionforge/MutableVisionProperties;Ljava/lang/String;)V public static final fun remove (Lspace/kscience/visionforge/MutableVisionProperties;Lspace/kscience/dataforge/names/Name;)V @@ -781,8 +808,8 @@ public abstract class space/kscience/visionforge/html/VisionOfHtml : space/kscie public static final field Companion Lspace/kscience/visionforge/html/VisionOfHtml$Companion; public fun ()V public synthetic fun (ILspace/kscience/dataforge/meta/MutableMeta;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V - public final fun getClasses ()Ljava/util/List; - public final fun setClasses (Ljava/util/List;)V + public final fun getClasses ()Ljava/util/Set; + public final fun setClasses (Ljava/util/Set;)V public static final synthetic fun write$Self (Lspace/kscience/visionforge/html/VisionOfHtml;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V } @@ -813,9 +840,16 @@ public final class space/kscience/visionforge/html/VisionOfHtmlButton$Companion } public abstract class space/kscience/visionforge/html/VisionOfHtmlControl : space/kscience/visionforge/html/VisionOfHtml, space/kscience/visionforge/ControlVision { + public static final field Companion Lspace/kscience/visionforge/html/VisionOfHtmlControl$Companion; public fun ()V + public synthetic fun (ILspace/kscience/dataforge/meta/MutableMeta;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V public fun dispatchControlEvent (Lspace/kscience/visionforge/VisionControlEvent;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun getControlEventFlow ()Lkotlinx/coroutines/flow/SharedFlow; + public static final synthetic fun write$Self (Lspace/kscience/visionforge/html/VisionOfHtmlControl;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V +} + +public final class space/kscience/visionforge/html/VisionOfHtmlControl$Companion { + public final fun serializer ()Lkotlinx/serialization/KSerializer; } public final class space/kscience/visionforge/html/VisionOfHtmlForm : space/kscience/visionforge/html/VisionOfHtmlControl { @@ -849,11 +883,9 @@ public final class space/kscience/visionforge/html/VisionOfHtmlFormKt { public class space/kscience/visionforge/html/VisionOfHtmlInput : space/kscience/visionforge/html/VisionOfHtmlControl { public static final field Companion Lspace/kscience/visionforge/html/VisionOfHtmlInput$Companion; - public synthetic fun (ILjava/lang/String;Lspace/kscience/visionforge/html/InputFeedbackMode;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V - public fun (Ljava/lang/String;Lspace/kscience/visionforge/html/InputFeedbackMode;)V - public synthetic fun (Ljava/lang/String;Lspace/kscience/visionforge/html/InputFeedbackMode;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun (ILspace/kscience/dataforge/meta/MutableMeta;Ljava/lang/String;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V + public fun (Ljava/lang/String;)V public final fun getDisabled ()Z - public final fun getFeedbackMode ()Lspace/kscience/visionforge/html/InputFeedbackMode; public final fun getFieldName ()Ljava/lang/String; public final fun getInputType ()Ljava/lang/String; public final fun getValue ()Lspace/kscience/dataforge/meta/Value; @@ -891,6 +923,8 @@ public final class space/kscience/visionforge/html/VisionOfHtmlKt { public static synthetic fun htmlRangeField$default (Lspace/kscience/visionforge/html/VisionOutput;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/visionforge/html/VisionOfRangeField; public static final fun htmlTextField (Lspace/kscience/visionforge/html/VisionOutput;Lkotlin/jvm/functions/Function1;)Lspace/kscience/visionforge/html/VisionOfTextField; public static synthetic fun htmlTextField$default (Lspace/kscience/visionforge/html/VisionOutput;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/visionforge/html/VisionOfTextField; + public static final fun onInput (Lspace/kscience/visionforge/html/VisionOfHtmlInput;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/Job; + public static synthetic fun onInput$default (Lspace/kscience/visionforge/html/VisionOfHtmlInput;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/Job; public static final fun onValueChange (Lspace/kscience/visionforge/html/VisionOfHtmlInput;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/Job; public static synthetic fun onValueChange$default (Lspace/kscience/visionforge/html/VisionOfHtmlInput;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/Job; } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/ControlVision.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/ControlVision.kt index dc27662f..627a2aa1 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/ControlVision.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/ControlVision.kt @@ -83,9 +83,32 @@ public class VisionValueChangeEvent(override val meta: Meta) : VisionControlEven override fun toString(): String = meta.toString() } + public fun VisionValueChangeEvent(value: Value?, name: Name? = null): VisionValueChangeEvent = VisionValueChangeEvent( Meta { this.value = value name?.let { set("name", it.toString()) } } ) + + +@Serializable +@SerialName("control.input") +public class VisionInputEvent(override val meta: Meta) : VisionControlEvent() { + + public val value: Value? get() = meta.value + + /** + * The name of a control that fired the event + */ + public val name: Name? get() = meta["name"]?.string?.parseAsName() + + override fun toString(): String = meta.toString() +} + +public fun VisionInputEvent(value: Value?, name: Name? = null): VisionInputEvent = VisionInputEvent( + Meta { + this.value = value + name?.let { set("name", it.toString()) } + } +) diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionClient.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionClient.kt index 7a62de7d..2d77dfd0 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionClient.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionClient.kt @@ -1,5 +1,7 @@ package space.kscience.visionforge +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch import space.kscience.dataforge.context.Plugin import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.names.Name @@ -16,6 +18,10 @@ public interface VisionClient: Plugin { public fun notifyPropertyChanged(visionName: Name, propertyName: Name, item: Meta?) } +public fun VisionClient.sendEventAsync(targetName: Name, event: VisionEvent): Job = context.launch { + sendEvent(targetName, event) +} + public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Meta?) { notifyPropertyChanged(visionName, propertyName.parseAsName(true), item) } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt index 9b5a21ac..84ed8286 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt @@ -85,6 +85,7 @@ public class VisionManager(meta: Meta) : AbstractPlugin(meta), MutableVisionCont subclass(VisionMetaEvent.serializer()) subclass(VisionClickEvent.serializer()) subclass(VisionValueChangeEvent.serializer()) + subclass(VisionInputEvent.serializer()) } } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt index 3c375c62..b7a66625 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt @@ -265,14 +265,14 @@ public abstract class AbstractVisionProperties( public fun VisionProperties.getValue( name: String, - inherit: Boolean? = null, + inherit: Boolean, includeStyles: Boolean? = null, ): Value? = getValue(name.parseAsName(), inherit, includeStyles) /** * Get [Vision] property using key as a String */ -public fun VisionProperties.get( +public operator fun VisionProperties.get( name: String, inherit: Boolean? = null, includeStyles: Boolean? = null, @@ -292,7 +292,7 @@ public fun MutableVisionProperties.root( /** * Get [Vision] property using key as a String */ -public fun MutableVisionProperties.get( +public operator fun MutableVisionProperties.get( name: String, inherit: Boolean? = null, includeStyles: Boolean? = null, diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtml.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtml.kt index 0738ddc6..2bd7b9de 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtml.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtml.kt @@ -12,15 +12,16 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.Transient import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.asName -import space.kscience.visionforge.AbstractVision -import space.kscience.visionforge.ControlVision -import space.kscience.visionforge.VisionControlEvent -import space.kscience.visionforge.VisionValueChangeEvent +import space.kscience.visionforge.* @Serializable public abstract class VisionOfHtml : AbstractVision() { - public var classes: List by properties.stringList(*emptyArray()) + public var classes: Set + get() = properties.get(::classes.name,false).stringList?.toSet() ?: emptySet() + set(value) { + properties[::classes.name] = value.map { it.asValue() } + } } @Serializable @@ -58,6 +59,7 @@ public enum class InputFeedbackMode { NONE } +@Serializable public abstract class VisionOfHtmlControl: VisionOfHtml(), ControlVision{ @Transient @@ -76,7 +78,6 @@ public abstract class VisionOfHtmlControl: VisionOfHtml(), ControlVision{ @SerialName("html.input") public open class VisionOfHtmlInput( public val inputType: String, - public val feedbackMode: InputFeedbackMode = InputFeedbackMode.ONCHANGE, ) : VisionOfHtmlControl() { public var value: Value? by properties.value() public var disabled: Boolean by properties.boolean { false } @@ -92,6 +93,11 @@ public fun VisionOfHtmlInput.onValueChange( callback: suspend VisionValueChangeEvent.() -> Unit, ): Job = controlEventFlow.filterIsInstance().onEach(callback).launchIn(scope) +public fun VisionOfHtmlInput.onInput( + scope: CoroutineScope = manager?.context ?: error("Coroutine context is not resolved for $this"), + callback: suspend VisionInputEvent.() -> Unit, +): Job = controlEventFlow.filterIsInstance().onEach(callback).launchIn(scope) + @Suppress("UnusedReceiverParameter") public inline fun VisionOutput.htmlInput( inputType: String, diff --git a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt index b1ca970a..e8ebe406 100644 --- a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt +++ b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt @@ -40,7 +40,7 @@ internal class VisionPropertyTest { @Test fun testPropertyEdit() { val vision = manager.group() - vision.properties.get("fff.ddd").apply { + vision.properties["fff.ddd"].apply { value = 2.asValue() } assertEquals(2, vision.properties.getValue("fff.ddd")?.int) @@ -50,7 +50,7 @@ internal class VisionPropertyTest { @Test fun testPropertyUpdate() { val vision = manager.group() - vision.properties.get("fff").updateWith(TestScheme) { + vision.properties["fff"].updateWith(TestScheme) { ddd = 2 } assertEquals(2, vision.properties.getValue("fff.ddd")?.int) diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt index 4112370a..3deb00da 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt @@ -1,18 +1,14 @@ package space.kscience.visionforge -import kotlinx.coroutines.launch import kotlinx.dom.clear import kotlinx.html.InputType import kotlinx.html.div import kotlinx.html.js.input import org.w3c.dom.HTMLElement import org.w3c.dom.HTMLInputElement -import org.w3c.dom.events.Event -import space.kscience.dataforge.meta.Value import space.kscience.dataforge.meta.asValue import space.kscience.dataforge.meta.double import space.kscience.dataforge.meta.string -import space.kscience.dataforge.names.Name import space.kscience.visionforge.html.* /** @@ -26,13 +22,6 @@ internal fun HTMLElement.subscribeToVision(vision: VisionOfHtml) { } } - -private fun VisionClient.sendInputEvent(name: Name, value: Value?) { - context.launch { - sendEvent(name, VisionValueChangeEvent(value, name)) - } -} - /** * Subscribes the HTML input element to a given vision. * @@ -62,16 +51,13 @@ internal val inputVisionRenderer: ElementVisionRenderer = ElementVisionRenderer< input { type = InputType.text }.also { htmlInputElement -> - val onEvent: (Event) -> Unit = { - client.sendInputEvent(name, htmlInputElement.value.asValue()) - } - - when (vision.feedbackMode) { - InputFeedbackMode.ONCHANGE -> htmlInputElement.onchange = onEvent + htmlInputElement.onchange = { + client.sendEventAsync(name, VisionValueChangeEvent(htmlInputElement.value.asValue(), name)) + } - InputFeedbackMode.ONINPUT -> htmlInputElement.oninput = onEvent - InputFeedbackMode.NONE -> {} + htmlInputElement.oninput = { + client.sendEventAsync(name, VisionInputEvent(htmlInputElement.value.asValue(), name)) } htmlInputElement.subscribeToInput(vision) @@ -86,18 +72,16 @@ internal val checkboxVisionRenderer: ElementVisionRenderer = input { type = InputType.checkBox }.also { htmlInputElement -> - val onEvent: (Event) -> Unit = { - client.sendInputEvent(name, htmlInputElement.checked.asValue()) - } - - when (vision.feedbackMode) { - InputFeedbackMode.ONCHANGE -> htmlInputElement.onchange = onEvent + htmlInputElement.onchange = { + client.sendEventAsync(name, VisionValueChangeEvent(htmlInputElement.value.asValue(), name)) + } - InputFeedbackMode.ONINPUT -> htmlInputElement.oninput = onEvent - InputFeedbackMode.NONE -> {} + htmlInputElement.oninput = { + client.sendEventAsync(name, VisionInputEvent(htmlInputElement.value.asValue(), name)) } + htmlInputElement.subscribeToInput(vision) vision.useProperty(VisionOfCheckbox::checked) { htmlInputElement.checked = it ?: false @@ -110,16 +94,13 @@ internal val textVisionRenderer: ElementVisionRenderer = input { type = InputType.text }.also { htmlInputElement -> - val onEvent: (Event) -> Unit = { - client.sendInputEvent(name, htmlInputElement.value.asValue()) - } + htmlInputElement.onchange = { + client.sendEventAsync(name, VisionValueChangeEvent(htmlInputElement.value.asValue(), name)) + } - when (vision.feedbackMode) { - InputFeedbackMode.ONCHANGE -> htmlInputElement.onchange = onEvent - - InputFeedbackMode.ONINPUT -> htmlInputElement.oninput = onEvent - InputFeedbackMode.NONE -> {} + htmlInputElement.oninput = { + client.sendEventAsync(name, VisionInputEvent(htmlInputElement.value.asValue(), name)) } htmlInputElement.subscribeToInput(vision) @@ -135,18 +116,19 @@ internal val numberVisionRenderer: ElementVisionRenderer = type = InputType.number }.also { htmlInputElement -> - val onEvent: (Event) -> Unit = { + htmlInputElement.onchange = { htmlInputElement.value.toDoubleOrNull()?.let { - client.sendInputEvent(name, htmlInputElement.value.asValue()) + client.sendEventAsync(name, VisionValueChangeEvent(it.asValue(), name)) } } - when (vision.feedbackMode) { - InputFeedbackMode.ONCHANGE -> htmlInputElement.onchange = onEvent - - InputFeedbackMode.ONINPUT -> htmlInputElement.oninput = onEvent - InputFeedbackMode.NONE -> {} + htmlInputElement.oninput = { + htmlInputElement.value.toDoubleOrNull()?.let { + client.sendEventAsync(name, VisionInputEvent(it.asValue(), name)) + } } + + htmlInputElement.subscribeToInput(vision) vision.useProperty(VisionOfNumberField::value) { htmlInputElement.valueAsNumber = it?.double ?: 0.0 @@ -163,18 +145,18 @@ internal val rangeVisionRenderer: ElementVisionRenderer = step = vision.step.toString() }.also { htmlInputElement -> - val onEvent: (Event) -> Unit = { + htmlInputElement.onchange = { htmlInputElement.value.toDoubleOrNull()?.let { - client.sendInputEvent(name, htmlInputElement.value.asValue()) + client.sendEventAsync(name, VisionValueChangeEvent(it.asValue(), name)) } } - when (vision.feedbackMode) { - InputFeedbackMode.ONCHANGE -> htmlInputElement.onchange = onEvent - - InputFeedbackMode.ONINPUT -> htmlInputElement.oninput = onEvent - InputFeedbackMode.NONE -> {} + htmlInputElement.oninput = { + htmlInputElement.value.toDoubleOrNull()?.let { + client.sendEventAsync(name, VisionInputEvent(it.asValue(), name)) + } } + htmlInputElement.subscribeToInput(vision) vision.useProperty(VisionOfRangeField::value) { htmlInputElement.valueAsNumber = it?.double ?: 0.0 diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt index 4991c12d..7b559ab7 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt @@ -4,6 +4,7 @@ import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.delay import kotlinx.coroutines.test.runTest +import space.kscience.dataforge.meta.getValue import space.kscience.dataforge.meta.int import space.kscience.dataforge.meta.set import space.kscience.dataforge.meta.string