From eeec89f0e678b9fffb42c3f208484745da8dd5e4 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sun, 14 Aug 2022 10:47:36 +0300 Subject: [PATCH] Fix property editor --- build.gradle.kts | 7 +++++- settings.gradle.kts | 1 + .../bootstrap/visionPropertyEditor.kt | 13 +++++----- ui/react/build.gradle.kts | 4 --- .../visionforge/react/MultiSelectChooser.kt | 4 +-- .../visionforge/react/PropertyEditor.kt | 15 +++++++---- .../visionforge/react/RangeValueChooser.kt | 18 +++++++------ .../visionforge/react/valueChooser.kt | 25 ++++++++++--------- .../ThreeViewWithControls.kt | 8 +++--- .../solid/three/ThreeCanvasLabelFactory.kt | 2 +- 10 files changed, 55 insertions(+), 42 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index f2c4e6d5..4c76b98f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -37,4 +37,9 @@ apiValidation { ignoredPackages.add("info.laht.threekt") } -readme.readmeTemplate = file("docs/templates/README-TEMPLATE.md") \ No newline at end of file +readme.readmeTemplate = file("docs/templates/README-TEMPLATE.md") + + +//rootProject.extensions.configure { +// versions.webpackCli.version = "4.10.0" +//} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 4215d150..9bdf544a 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -12,6 +12,7 @@ pluginManagement { maven("https://repo.kotlin.link") mavenCentral() gradlePluginPortal() + maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") } plugins { diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt index b82d48fe..5e30f838 100644 --- a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt +++ b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt @@ -5,7 +5,7 @@ import react.RBuilder import react.dom.client.createRoot import react.key import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.dataforge.meta.get +import space.kscience.dataforge.meta.isEmpty import space.kscience.visionforge.Vision import space.kscience.visionforge.getStyle import space.kscience.visionforge.react.EditorPropertyState @@ -23,17 +23,18 @@ public fun RBuilder.visionPropertyEditor( ) { card("Properties") { - child(PropertyEditor){ - attrs{ + child(PropertyEditor) { + attrs { this.key = key?.toString() this.meta = vision.properties.root() this.updates = vision.properties.changes this.descriptor = descriptor this.scope = vision.manager?.context ?: error("Orphan vision could not be observed") - this.getPropertyState = {name-> - if(vision.properties.own?.get(name)!= null){ + this.getPropertyState = { name -> + val ownMeta = vision.properties.own?.getMeta(name) + if (ownMeta != null && !ownMeta.isEmpty()) { EditorPropertyState.Defined - } else if(vision.properties.root()[name] != null){ + } else if (vision.properties.root().getValue(name) != null) { // TODO differentiate EditorPropertyState.Default() } else { diff --git a/ui/react/build.gradle.kts b/ui/react/build.gradle.kts index 1a58d333..acbe40cb 100644 --- a/ui/react/build.gradle.kts +++ b/ui/react/build.gradle.kts @@ -8,8 +8,4 @@ dependencies{ api("org.jetbrains.kotlin-wrappers:kotlin-react-dom") // implementation(npm("react-select","4.3.0")) implementation(project(":visionforge-threejs")) -} - -rootProject.extensions.configure { - versions.webpackCli.version = "4.10.0" } \ No newline at end of file diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt index fb339429..fc635d21 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt @@ -19,13 +19,13 @@ public val MultiSelectChooser: FC = fc("MultiSelectChooser") val onChange: (Event) -> Unit = { event: Event -> val newSelected = (event.target as HTMLSelectElement).selectedOptions.asList() .map { (it as HTMLOptionElement).value.asValue() } - props.meta.value = newSelected.asValue() + props.onValueChange(newSelected.asValue()) } select { attrs { multiple = true - values = (props.meta.value?.list ?: emptyList()).mapTo(HashSet()) { it.string } + values = (props.value?.list ?: emptyList()).mapTo(HashSet()) { it.string } onChangeFunction = onChange } props.descriptor?.allowedValues?.forEach { optionValue -> diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt index ca64fd07..f5d28f19 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt @@ -73,8 +73,8 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { var expanded: Boolean by useState { props.expanded ?: true } val descriptor: MetaDescriptor? = useMemo(props.descriptor, props.name) { props.descriptor?.get(props.name) } var property: MutableMeta by useState { props.meta.getOrCreate(props.name) } + var editorPropertyState: EditorPropertyState by useState { props.getPropertyState(props.name) } - val defined = props.getPropertyState(props.name) == EditorPropertyState.Defined val keys = useMemo(descriptor) { buildSet { @@ -91,6 +91,7 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { fun update() { property = props.meta.getOrCreate(props.name) + editorPropertyState = props.getPropertyState(props.name) } useEffect(props.meta) { @@ -136,7 +137,7 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { styledSpan { css { +TreeStyles.treeLabel - if (!defined) { + if (editorPropertyState != EditorPropertyState.Defined) { +TreeStyles.treeLabelInactive } } @@ -152,8 +153,12 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { ValueChooser { attrs { this.descriptor = descriptor - this.meta = property - this.state = props.getPropertyState(props.name) + this.state = editorPropertyState + this.value = property.value + this.onValueChange = { + property.value = it + editorPropertyState = props.getPropertyState(props.name) + } } } } @@ -177,7 +182,7 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { } +"\u00D7" attrs { - if (!defined) { + if (editorPropertyState!= EditorPropertyState.Defined) { disabled = true } else { onClickFunction = removeClick diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt index ae6386d9..309e4b7f 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt @@ -20,22 +20,24 @@ import styled.styledInput @JsExport public val RangeValueChooser: FC = fc("RangeValueChooser") { props -> - var innerValue by useState(props.meta.double) - var rangeDisabled: Boolean by useState(props.meta.value == null) + var innerValue by useState(props.value?.double) + var rangeDisabled: Boolean by useState(props.state != EditorPropertyState.Defined) val handleDisable: (Event) -> Unit = { val checkBoxValue = (it.target as HTMLInputElement).checked rangeDisabled = !checkBoxValue - props.meta.value = if (!checkBoxValue) { - null - } else { - innerValue?.asValue() - } + props.onValueChange( + if (!checkBoxValue) { + null + } else { + innerValue?.asValue() + } + ) } val handleChange: (Event) -> Unit = { val newValue = (it.target as HTMLInputElement).value - props.meta.value = newValue.toDoubleOrNull()?.asValue() + props.onValueChange(newValue.toDoubleOrNull()?.asValue()) innerValue = newValue.toDoubleOrNull() } diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt index 75cd3a0c..7ba72e1c 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt @@ -27,17 +27,18 @@ import styled.styledSelect public external interface ValueChooserProps : Props { public var descriptor: MetaDescriptor? - public var meta: MutableMeta public var state: EditorPropertyState + public var value: Value? + public var onValueChange: (Value?) -> Unit } @JsExport public val StringValueChooser: FC = fc("StringValueChooser") { props -> - var value by useState(props.meta.string ?: "") + var value by useState(props.value?.string ?: "") val keyDown: (Event) -> Unit = { event -> if (event.type == "keydown" && event.asDynamic().key == "Enter") { value = (event.target as HTMLInputElement).value - props.meta.value = value.asValue() + props.onValueChange(value.asValue()) } } val handleChange: (Event) -> Unit = { @@ -59,7 +60,7 @@ public val StringValueChooser: FC = fc("StringValueChooser") public val BooleanValueChooser: FC = fc("BooleanValueChooser") { props -> val handleChange: (Event) -> Unit = { val newValue = (it.target as HTMLInputElement).checked - props.meta.value = newValue.asValue() + props.onValueChange(newValue.asValue()) } styledInput(type = InputType.checkBox) { css { @@ -67,7 +68,7 @@ public val BooleanValueChooser: FC = fc("BooleanValueChooser" } attrs { //this.attributes["indeterminate"] = (props.item == null).toString() - checked = props.meta.boolean ?: false + checked = props.value?.boolean ?: false onChangeFunction = handleChange } } @@ -75,7 +76,7 @@ public val BooleanValueChooser: FC = fc("BooleanValueChooser" @JsExport public val NumberValueChooser: FC = fc("NumberValueChooser") { props -> - var innerValue by useState(props.meta.string ?: "") + var innerValue by useState(props.value?.string ?: "") val keyDown: (Event) -> Unit = { event -> if (event.type == "keydown" && event.asDynamic().key == "Enter") { innerValue = (event.target as HTMLInputElement).value @@ -83,7 +84,7 @@ public val NumberValueChooser: FC = fc("NumberValueChooser") if (number == null) { console.error("The input value $innerValue is not a number") } else { - props.meta.value = number.asValue() + props.onValueChange(number.asValue()) } } } @@ -113,10 +114,10 @@ public val NumberValueChooser: FC = fc("NumberValueChooser") @JsExport public val ComboValueChooser: FC = fc("ComboValueChooser") { props -> - var selected by useState(props.meta.string ?: "") + var selected by useState(props.value?.string ?: "") val handleChange: (Event) -> Unit = { selected = (it.target as HTMLSelectElement).value - props.meta.value = selected.asValue() + props.onValueChange(selected.asValue()) } styledSelect { css { @@ -128,7 +129,7 @@ public val ComboValueChooser: FC = fc("ComboValueChooser") { } } attrs { - this.value = props.meta.string ?: "" + this.value = props.value?.string ?: "" multiple = false onChangeFunction = handleChange } @@ -138,7 +139,7 @@ public val ComboValueChooser: FC = fc("ComboValueChooser") { @JsExport public val ColorValueChooser: FC = fc("ColorValueChooser") { props -> val handleChange: (Event) -> Unit = { - props.meta.value = (it.target as HTMLInputElement).value.asValue() + props.onValueChange((it.target as HTMLInputElement).value.asValue()) } styledInput(type = InputType.color) { css { @@ -146,7 +147,7 @@ public val ColorValueChooser: FC = fc("ColorValueChooser") { margin(0.px) } attrs { - this.value = props.meta.value?.let { value -> + this.value = props.value?.let { value -> if (value.type == ValueType.NUMBER) Colors.rgbToString(value.int) else value.string } ?: "#000000" diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt index 883b621d..c1344569 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt @@ -183,9 +183,11 @@ public val ThreeCanvasWithControls: FC = fc("Three } } } - p { - b { +"Styles: " } - +vision.styles.joinToString(separator = ", ") + vision.styles.takeIf { it.isNotEmpty() }?.let { styles -> + p { + b { +"Styles: " } + +styles.joinToString(separator = ", ") + } } } } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt index d33c7e79..8b4e823b 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt @@ -26,7 +26,7 @@ public object ThreeCanvasLabelFactory : ThreeFactory { val canvas = document.createElement("canvas") as HTMLCanvasElement val context = canvas.getContext("2d") as CanvasRenderingContext2D context.font = "Bold ${obj.fontSize}pt ${obj.fontFamily}" - context.fillStyle = obj.properties.getProperty(SolidMaterial.MATERIAL_COLOR_KEY).value ?: "black" + context.fillStyle = obj.properties.getValue(SolidMaterial.MATERIAL_COLOR_KEY, false, true)?.value ?: "black" context.textBaseline = CanvasTextBaseline.MIDDLE val metrics = context.measureText(obj.text) //canvas.width = metrics.width.toInt()