diff --git a/packages/chili-core/src/i18n/en.ts b/packages/chili-core/src/i18n/en.ts index 7db618cd..91c54ac1 100644 --- a/packages/chili-core/src/i18n/en.ts +++ b/packages/chili-core/src/i18n/en.ts @@ -102,7 +102,7 @@ export default { "prompt.select.noModelSelected": "No model selected", "prompt.saveDocument{0}": "Do you want to save the changes to {0}?", "prompt.deleteDocument{0}": "Do you want to delete {0}?", - "error.default": "", + "error.default": "error", "error.input.unsupportedInputs": "Exceeds the maximum number of inputs", "error.input.invalidNumber": "Please enter a valid number, separated by ,", "error.input.threeNumberCanBeInput": "Reference point is empty, only 3 numbers can be entered", diff --git a/packages/chili-core/src/i18n/zh-cn.ts b/packages/chili-core/src/i18n/zh-cn.ts index 880af644..17d471c2 100644 --- a/packages/chili-core/src/i18n/zh-cn.ts +++ b/packages/chili-core/src/i18n/zh-cn.ts @@ -101,7 +101,7 @@ export default { "prompt.select.noModelSelected": "未选择任何模型", "prompt.saveDocument{0}": "是否保存对 {0} 的更改?", "prompt.deleteDocument{0}": "是否删除 {0} ?", - "error.default": "", + "error.default": "错误", "error.input.unsupportedInputs": "超过最大输入数", "error.input.invalidNumber": "输入错误,请输入有效的数字,以,分开", "error.input.threeNumberCanBeInput": "参照点为空,只能输入 3 个数", diff --git a/packages/chili-ui/src/property/input.module.css b/packages/chili-ui/src/property/input.module.css index 78cbc690..ab21d4dc 100644 --- a/packages/chili-ui/src/property/input.module.css +++ b/packages/chili-ui/src/property/input.module.css @@ -1,13 +1,3 @@ -.error { - font-size: x-small; - color: red; - position: absolute; -} - -.hidden { - display: none; -} - .readonly { opacity: 0.56; } diff --git a/packages/chili-ui/src/property/input.ts b/packages/chili-ui/src/property/input.ts index b03909db..a07a99e8 100644 --- a/packages/chili-ui/src/property/input.ts +++ b/packages/chili-ui/src/property/input.ts @@ -1,28 +1,60 @@ // Copyright 2022-2023 the Chili authors. All rights reserved. AGPL-3.0 license. import { - I18n, IConverter, IDocument, - IPropertyChanged, NumberConverter, Property, + PubSub, Quaternion, QuaternionConverter, + Result, StringConverter, Transaction, XYZ, XYZConverter, } from "chili-core"; -import { div, input, span } from "../controls"; +import { div, input, localize, span } from "../controls"; import commonStyle from "./common.module.css"; import style from "./input.module.css"; import { PropertyBase } from "./propertyBase"; +class ArrayValueConverter implements IConverter { + constructor( + readonly objects: any[], + readonly property: Property, + readonly converter?: IConverter, + ) {} + + convert(value: any): Result { + return Result.success(this.getDefaultValue()); + } + + convertBack?(value: string): Result { + throw new Error("Method not implemented."); + } + + private getValueString(obj: any): string { + let value = obj[this.property.name]; + let cvalue = this.converter?.convert(value); + return cvalue?.success ? cvalue.value : String(value); + } + + private getDefaultValue() { + let value = this.getValueString(this.objects[0]); + for (let index = 1; index < this.objects.length; index++) { + const testValue = this.getValueString(this.objects[index]); + if (value !== testValue) { + value = ""; + break; + } + } + return value; + } +} + export class InputProperty extends PropertyBase { - readonly valueBox: HTMLInputElement; - readonly error: HTMLSpanElement; readonly converter: IConverter | undefined; constructor( @@ -33,47 +65,26 @@ export class InputProperty extends PropertyBase { ) { super(objects); this.converter = property.converter ?? this.getConverter(); - this.valueBox = input({ - className: style.box, - value: this.getDefaultValue(), - readOnly: this.isReadOnly(), - onkeydown: this.handleKeyDown, - }); - this.error = span({ - classList: `${style.error} ${style.hidden}`, - textContent: I18n.translate("error.default"), - }); + let arrayConverter = new ArrayValueConverter(objects, property, this.converter); this.append( div( { className: commonStyle.panel }, showTitle ? span({ className: commonStyle.propertyName, - textContent: I18n.translate(property.display), + textContent: localize(property.display), }) : "", - this.valueBox, + input({ + className: style.box, + value: this.bind(objects[0], property.name, arrayConverter), + readOnly: this.isReadOnly(), + onkeydown: this.handleKeyDown, + }), ), - this.error, ); } - override connectedCallback(): void { - super.connectedCallback(); - (this.objects.at(0) as IPropertyChanged)?.onPropertyChanged(this.handlePropertyChanged); - } - - override disconnectedCallback(): void { - super.disconnectedCallback(); - (this.objects.at(0) as IPropertyChanged)?.removePropertyChanged(this.handlePropertyChanged); - } - - private handlePropertyChanged = (property: string) => { - if (property === this.property.name) { - this.valueBox.value = this.getValueString(this.objects[0]); - } - }; - private isReadOnly(): boolean { let des = Object.getOwnPropertyDescriptor(this.objects[0], this.property.name); if (des === undefined) { @@ -90,46 +101,13 @@ export class InputProperty extends PropertyBase { ); } - private getConverter(): IConverter | undefined { - let name = this.objects[0][this.property.name].constructor.name; - if (name === XYZ.name) { - return new XYZConverter(); - } else if (name === Quaternion.name) { - return new QuaternionConverter(); - } else if (name === String.name) { - return new StringConverter(); - } else if (name === Number.name) { - return new NumberConverter(); - } - return undefined; - } - - private getValueString(obj: any): string { - let value = obj[this.property.name]; - let cvalue = this.converter?.convert(value); - return cvalue?.success ? cvalue.value : String(value); - } - - private getDefaultValue() { - let value = this.getValueString(this.objects[0]); - for (let index = 1; index < this.objects.length; index++) { - const testValue = this.getValueString(this.objects[1]); - if (value !== testValue) { - value = ""; - break; - } - } - return value; - } - private handleKeyDown = (e: KeyboardEvent) => { e.stopPropagation(); if (this.converter === undefined) return; if (e.key === "Enter") { - let newValue = this.converter.convertBack?.(this.valueBox.value); + let newValue = this.converter.convertBack?.((e.target as HTMLInputElement).value); if (!newValue?.success) { - this.error.textContent = newValue?.error ?? "error"; - this.error.classList.add(style.hidden); + PubSub.default.pub("showToast", "error.default"); return; } Transaction.excute(this.document, "modify property", () => { @@ -138,10 +116,22 @@ export class InputProperty extends PropertyBase { }); this.document.visual.viewer.update(); }); - } else { - this.error.classList.add(style.hidden); } }; + + private getConverter(): IConverter | undefined { + let name = this.objects[0][this.property.name].constructor.name; + if (name === XYZ.name) { + return new XYZConverter(); + } else if (name === Quaternion.name) { + return new QuaternionConverter(); + } else if (name === String.name) { + return new StringConverter(); + } else if (name === Number.name) { + return new NumberConverter(); + } + return undefined; + } } customElements.define("chili-input-property", InputProperty); diff --git a/packages/chili-ui/src/property/propertyView.ts b/packages/chili-ui/src/property/propertyView.ts index 54767dfa..cb6d1c4d 100644 --- a/packages/chili-ui/src/property/propertyView.ts +++ b/packages/chili-ui/src/property/propertyView.ts @@ -22,6 +22,7 @@ import style from "./propertyView.module.css"; export class PropertyView extends BindableElement { private panel = div({ className: style.panel }); + constructor(props: { className: string }) { super(); this.classList.add(props.className, style.root);