Fix property editor
This commit is contained in:
parent
43362f51f5
commit
eeec89f0e6
@ -37,4 +37,9 @@ apiValidation {
|
|||||||
ignoredPackages.add("info.laht.threekt")
|
ignoredPackages.add("info.laht.threekt")
|
||||||
}
|
}
|
||||||
|
|
||||||
readme.readmeTemplate = file("docs/templates/README-TEMPLATE.md")
|
readme.readmeTemplate = file("docs/templates/README-TEMPLATE.md")
|
||||||
|
|
||||||
|
|
||||||
|
//rootProject.extensions.configure<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension> {
|
||||||
|
// versions.webpackCli.version = "4.10.0"
|
||||||
|
//}
|
@ -12,6 +12,7 @@ pluginManagement {
|
|||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
|
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
|
||||||
}
|
}
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
|
@ -5,7 +5,7 @@ import react.RBuilder
|
|||||||
import react.dom.client.createRoot
|
import react.dom.client.createRoot
|
||||||
import react.key
|
import react.key
|
||||||
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
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.Vision
|
||||||
import space.kscience.visionforge.getStyle
|
import space.kscience.visionforge.getStyle
|
||||||
import space.kscience.visionforge.react.EditorPropertyState
|
import space.kscience.visionforge.react.EditorPropertyState
|
||||||
@ -23,17 +23,18 @@ public fun RBuilder.visionPropertyEditor(
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
card("Properties") {
|
card("Properties") {
|
||||||
child(PropertyEditor){
|
child(PropertyEditor) {
|
||||||
attrs{
|
attrs {
|
||||||
this.key = key?.toString()
|
this.key = key?.toString()
|
||||||
this.meta = vision.properties.root()
|
this.meta = vision.properties.root()
|
||||||
this.updates = vision.properties.changes
|
this.updates = vision.properties.changes
|
||||||
this.descriptor = descriptor
|
this.descriptor = descriptor
|
||||||
this.scope = vision.manager?.context ?: error("Orphan vision could not be observed")
|
this.scope = vision.manager?.context ?: error("Orphan vision could not be observed")
|
||||||
this.getPropertyState = {name->
|
this.getPropertyState = { name ->
|
||||||
if(vision.properties.own?.get(name)!= null){
|
val ownMeta = vision.properties.own?.getMeta(name)
|
||||||
|
if (ownMeta != null && !ownMeta.isEmpty()) {
|
||||||
EditorPropertyState.Defined
|
EditorPropertyState.Defined
|
||||||
} else if(vision.properties.root()[name] != null){
|
} else if (vision.properties.root().getValue(name) != null) {
|
||||||
// TODO differentiate
|
// TODO differentiate
|
||||||
EditorPropertyState.Default()
|
EditorPropertyState.Default()
|
||||||
} else {
|
} else {
|
||||||
|
@ -8,8 +8,4 @@ dependencies{
|
|||||||
api("org.jetbrains.kotlin-wrappers:kotlin-react-dom")
|
api("org.jetbrains.kotlin-wrappers:kotlin-react-dom")
|
||||||
// implementation(npm("react-select","4.3.0"))
|
// implementation(npm("react-select","4.3.0"))
|
||||||
implementation(project(":visionforge-threejs"))
|
implementation(project(":visionforge-threejs"))
|
||||||
}
|
|
||||||
|
|
||||||
rootProject.extensions.configure<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension> {
|
|
||||||
versions.webpackCli.version = "4.10.0"
|
|
||||||
}
|
}
|
@ -19,13 +19,13 @@ public val MultiSelectChooser: FC<ValueChooserProps> = fc("MultiSelectChooser")
|
|||||||
val onChange: (Event) -> Unit = { event: Event ->
|
val onChange: (Event) -> Unit = { event: Event ->
|
||||||
val newSelected = (event.target as HTMLSelectElement).selectedOptions.asList()
|
val newSelected = (event.target as HTMLSelectElement).selectedOptions.asList()
|
||||||
.map { (it as HTMLOptionElement).value.asValue() }
|
.map { (it as HTMLOptionElement).value.asValue() }
|
||||||
props.meta.value = newSelected.asValue()
|
props.onValueChange(newSelected.asValue())
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
attrs {
|
attrs {
|
||||||
multiple = true
|
multiple = true
|
||||||
values = (props.meta.value?.list ?: emptyList()).mapTo(HashSet()) { it.string }
|
values = (props.value?.list ?: emptyList()).mapTo(HashSet()) { it.string }
|
||||||
onChangeFunction = onChange
|
onChangeFunction = onChange
|
||||||
}
|
}
|
||||||
props.descriptor?.allowedValues?.forEach { optionValue ->
|
props.descriptor?.allowedValues?.forEach { optionValue ->
|
||||||
|
@ -73,8 +73,8 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) {
|
|||||||
var expanded: Boolean by useState { props.expanded ?: true }
|
var expanded: Boolean by useState { props.expanded ?: true }
|
||||||
val descriptor: MetaDescriptor? = useMemo(props.descriptor, props.name) { props.descriptor?.get(props.name) }
|
val descriptor: MetaDescriptor? = useMemo(props.descriptor, props.name) { props.descriptor?.get(props.name) }
|
||||||
var property: MutableMeta by useState { props.meta.getOrCreate(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) {
|
val keys = useMemo(descriptor) {
|
||||||
buildSet {
|
buildSet {
|
||||||
@ -91,6 +91,7 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) {
|
|||||||
|
|
||||||
fun update() {
|
fun update() {
|
||||||
property = props.meta.getOrCreate(props.name)
|
property = props.meta.getOrCreate(props.name)
|
||||||
|
editorPropertyState = props.getPropertyState(props.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(props.meta) {
|
useEffect(props.meta) {
|
||||||
@ -136,7 +137,7 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) {
|
|||||||
styledSpan {
|
styledSpan {
|
||||||
css {
|
css {
|
||||||
+TreeStyles.treeLabel
|
+TreeStyles.treeLabel
|
||||||
if (!defined) {
|
if (editorPropertyState != EditorPropertyState.Defined) {
|
||||||
+TreeStyles.treeLabelInactive
|
+TreeStyles.treeLabelInactive
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -152,8 +153,12 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) {
|
|||||||
ValueChooser {
|
ValueChooser {
|
||||||
attrs {
|
attrs {
|
||||||
this.descriptor = descriptor
|
this.descriptor = descriptor
|
||||||
this.meta = property
|
this.state = editorPropertyState
|
||||||
this.state = props.getPropertyState(props.name)
|
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"
|
+"\u00D7"
|
||||||
attrs {
|
attrs {
|
||||||
if (!defined) {
|
if (editorPropertyState!= EditorPropertyState.Defined) {
|
||||||
disabled = true
|
disabled = true
|
||||||
} else {
|
} else {
|
||||||
onClickFunction = removeClick
|
onClickFunction = removeClick
|
||||||
|
@ -20,22 +20,24 @@ import styled.styledInput
|
|||||||
|
|
||||||
@JsExport
|
@JsExport
|
||||||
public val RangeValueChooser: FC<ValueChooserProps> = fc("RangeValueChooser") { props ->
|
public val RangeValueChooser: FC<ValueChooserProps> = fc("RangeValueChooser") { props ->
|
||||||
var innerValue by useState(props.meta.double)
|
var innerValue by useState(props.value?.double)
|
||||||
var rangeDisabled: Boolean by useState(props.meta.value == null)
|
var rangeDisabled: Boolean by useState(props.state != EditorPropertyState.Defined)
|
||||||
|
|
||||||
val handleDisable: (Event) -> Unit = {
|
val handleDisable: (Event) -> Unit = {
|
||||||
val checkBoxValue = (it.target as HTMLInputElement).checked
|
val checkBoxValue = (it.target as HTMLInputElement).checked
|
||||||
rangeDisabled = !checkBoxValue
|
rangeDisabled = !checkBoxValue
|
||||||
props.meta.value = if (!checkBoxValue) {
|
props.onValueChange(
|
||||||
null
|
if (!checkBoxValue) {
|
||||||
} else {
|
null
|
||||||
innerValue?.asValue()
|
} else {
|
||||||
}
|
innerValue?.asValue()
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val handleChange: (Event) -> Unit = {
|
val handleChange: (Event) -> Unit = {
|
||||||
val newValue = (it.target as HTMLInputElement).value
|
val newValue = (it.target as HTMLInputElement).value
|
||||||
props.meta.value = newValue.toDoubleOrNull()?.asValue()
|
props.onValueChange(newValue.toDoubleOrNull()?.asValue())
|
||||||
innerValue = newValue.toDoubleOrNull()
|
innerValue = newValue.toDoubleOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,17 +27,18 @@ import styled.styledSelect
|
|||||||
|
|
||||||
public external interface ValueChooserProps : Props {
|
public external interface ValueChooserProps : Props {
|
||||||
public var descriptor: MetaDescriptor?
|
public var descriptor: MetaDescriptor?
|
||||||
public var meta: MutableMeta
|
|
||||||
public var state: EditorPropertyState
|
public var state: EditorPropertyState
|
||||||
|
public var value: Value?
|
||||||
|
public var onValueChange: (Value?) -> Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsExport
|
@JsExport
|
||||||
public val StringValueChooser: FC<ValueChooserProps> = fc("StringValueChooser") { props ->
|
public val StringValueChooser: FC<ValueChooserProps> = fc("StringValueChooser") { props ->
|
||||||
var value by useState(props.meta.string ?: "")
|
var value by useState(props.value?.string ?: "")
|
||||||
val keyDown: (Event) -> Unit = { event ->
|
val keyDown: (Event) -> Unit = { event ->
|
||||||
if (event.type == "keydown" && event.asDynamic().key == "Enter") {
|
if (event.type == "keydown" && event.asDynamic().key == "Enter") {
|
||||||
value = (event.target as HTMLInputElement).value
|
value = (event.target as HTMLInputElement).value
|
||||||
props.meta.value = value.asValue()
|
props.onValueChange(value.asValue())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val handleChange: (Event) -> Unit = {
|
val handleChange: (Event) -> Unit = {
|
||||||
@ -59,7 +60,7 @@ public val StringValueChooser: FC<ValueChooserProps> = fc("StringValueChooser")
|
|||||||
public val BooleanValueChooser: FC<ValueChooserProps> = fc("BooleanValueChooser") { props ->
|
public val BooleanValueChooser: FC<ValueChooserProps> = fc("BooleanValueChooser") { props ->
|
||||||
val handleChange: (Event) -> Unit = {
|
val handleChange: (Event) -> Unit = {
|
||||||
val newValue = (it.target as HTMLInputElement).checked
|
val newValue = (it.target as HTMLInputElement).checked
|
||||||
props.meta.value = newValue.asValue()
|
props.onValueChange(newValue.asValue())
|
||||||
}
|
}
|
||||||
styledInput(type = InputType.checkBox) {
|
styledInput(type = InputType.checkBox) {
|
||||||
css {
|
css {
|
||||||
@ -67,7 +68,7 @@ public val BooleanValueChooser: FC<ValueChooserProps> = fc("BooleanValueChooser"
|
|||||||
}
|
}
|
||||||
attrs {
|
attrs {
|
||||||
//this.attributes["indeterminate"] = (props.item == null).toString()
|
//this.attributes["indeterminate"] = (props.item == null).toString()
|
||||||
checked = props.meta.boolean ?: false
|
checked = props.value?.boolean ?: false
|
||||||
onChangeFunction = handleChange
|
onChangeFunction = handleChange
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,7 +76,7 @@ public val BooleanValueChooser: FC<ValueChooserProps> = fc("BooleanValueChooser"
|
|||||||
|
|
||||||
@JsExport
|
@JsExport
|
||||||
public val NumberValueChooser: FC<ValueChooserProps> = fc("NumberValueChooser") { props ->
|
public val NumberValueChooser: FC<ValueChooserProps> = fc("NumberValueChooser") { props ->
|
||||||
var innerValue by useState(props.meta.string ?: "")
|
var innerValue by useState(props.value?.string ?: "")
|
||||||
val keyDown: (Event) -> Unit = { event ->
|
val keyDown: (Event) -> Unit = { event ->
|
||||||
if (event.type == "keydown" && event.asDynamic().key == "Enter") {
|
if (event.type == "keydown" && event.asDynamic().key == "Enter") {
|
||||||
innerValue = (event.target as HTMLInputElement).value
|
innerValue = (event.target as HTMLInputElement).value
|
||||||
@ -83,7 +84,7 @@ public val NumberValueChooser: FC<ValueChooserProps> = fc("NumberValueChooser")
|
|||||||
if (number == null) {
|
if (number == null) {
|
||||||
console.error("The input value $innerValue is not a number")
|
console.error("The input value $innerValue is not a number")
|
||||||
} else {
|
} else {
|
||||||
props.meta.value = number.asValue()
|
props.onValueChange(number.asValue())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,10 +114,10 @@ public val NumberValueChooser: FC<ValueChooserProps> = fc("NumberValueChooser")
|
|||||||
|
|
||||||
@JsExport
|
@JsExport
|
||||||
public val ComboValueChooser: FC<ValueChooserProps> = fc("ComboValueChooser") { props ->
|
public val ComboValueChooser: FC<ValueChooserProps> = fc("ComboValueChooser") { props ->
|
||||||
var selected by useState(props.meta.string ?: "")
|
var selected by useState(props.value?.string ?: "")
|
||||||
val handleChange: (Event) -> Unit = {
|
val handleChange: (Event) -> Unit = {
|
||||||
selected = (it.target as HTMLSelectElement).value
|
selected = (it.target as HTMLSelectElement).value
|
||||||
props.meta.value = selected.asValue()
|
props.onValueChange(selected.asValue())
|
||||||
}
|
}
|
||||||
styledSelect {
|
styledSelect {
|
||||||
css {
|
css {
|
||||||
@ -128,7 +129,7 @@ public val ComboValueChooser: FC<ValueChooserProps> = fc("ComboValueChooser") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
attrs {
|
attrs {
|
||||||
this.value = props.meta.string ?: ""
|
this.value = props.value?.string ?: ""
|
||||||
multiple = false
|
multiple = false
|
||||||
onChangeFunction = handleChange
|
onChangeFunction = handleChange
|
||||||
}
|
}
|
||||||
@ -138,7 +139,7 @@ public val ComboValueChooser: FC<ValueChooserProps> = fc("ComboValueChooser") {
|
|||||||
@JsExport
|
@JsExport
|
||||||
public val ColorValueChooser: FC<ValueChooserProps> = fc("ColorValueChooser") { props ->
|
public val ColorValueChooser: FC<ValueChooserProps> = fc("ColorValueChooser") { props ->
|
||||||
val handleChange: (Event) -> Unit = {
|
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) {
|
styledInput(type = InputType.color) {
|
||||||
css {
|
css {
|
||||||
@ -146,7 +147,7 @@ public val ColorValueChooser: FC<ValueChooserProps> = fc("ColorValueChooser") {
|
|||||||
margin(0.px)
|
margin(0.px)
|
||||||
}
|
}
|
||||||
attrs {
|
attrs {
|
||||||
this.value = props.meta.value?.let { value ->
|
this.value = props.value?.let { value ->
|
||||||
if (value.type == ValueType.NUMBER) Colors.rgbToString(value.int)
|
if (value.type == ValueType.NUMBER) Colors.rgbToString(value.int)
|
||||||
else value.string
|
else value.string
|
||||||
} ?: "#000000"
|
} ?: "#000000"
|
||||||
|
@ -183,9 +183,11 @@ public val ThreeCanvasWithControls: FC<ThreeCanvasWithControlsProps> = fc("Three
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p {
|
vision.styles.takeIf { it.isNotEmpty() }?.let { styles ->
|
||||||
b { +"Styles: " }
|
p {
|
||||||
+vision.styles.joinToString(separator = ", ")
|
b { +"Styles: " }
|
||||||
|
+styles.joinToString(separator = ", ")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ public object ThreeCanvasLabelFactory : ThreeFactory<SolidLabel> {
|
|||||||
val canvas = document.createElement("canvas") as HTMLCanvasElement
|
val canvas = document.createElement("canvas") as HTMLCanvasElement
|
||||||
val context = canvas.getContext("2d") as CanvasRenderingContext2D
|
val context = canvas.getContext("2d") as CanvasRenderingContext2D
|
||||||
context.font = "Bold ${obj.fontSize}pt ${obj.fontFamily}"
|
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
|
context.textBaseline = CanvasTextBaseline.MIDDLE
|
||||||
val metrics = context.measureText(obj.text)
|
val metrics = context.measureText(obj.text)
|
||||||
//canvas.width = metrics.width.toInt()
|
//canvas.width = metrics.width.toInt()
|
||||||
|
Loading…
Reference in New Issue
Block a user