Skip to content

Commit

Permalink
🦄 refactor: refactor InputProperty
Browse files Browse the repository at this point in the history
  • Loading branch information
xiangechen committed Jan 30, 2024
1 parent 1a69daa commit 72d3e4c
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 83 deletions.
2 changes: 1 addition & 1 deletion packages/chili-core/src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion packages/chili-core/src/i18n/zh-cn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 个数",
Expand Down
10 changes: 0 additions & 10 deletions packages/chili-ui/src/property/input.module.css
Original file line number Diff line number Diff line change
@@ -1,13 +1,3 @@
.error {
font-size: x-small;
color: red;
position: absolute;
}

.hidden {
display: none;
}

.readonly {
opacity: 0.56;
}
Expand Down
132 changes: 61 additions & 71 deletions packages/chili-ui/src/property/input.ts
Original file line number Diff line number Diff line change
@@ -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<string> {
return Result.success(this.getDefaultValue());
}

convertBack?(value: string): Result<any> {
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(
Expand All @@ -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) {
Expand All @@ -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", () => {
Expand All @@ -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);
1 change: 1 addition & 0 deletions packages/chili-ui/src/property/propertyView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 72d3e4c

Please sign in to comment.