Skip to content

Commit

Permalink
🦄 refactor: add findPropertyControl
Browse files Browse the repository at this point in the history
  • Loading branch information
xiangechen committed Dec 7, 2024
1 parent 43d668b commit d3810fd
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 74 deletions.
2 changes: 1 addition & 1 deletion packages/chili-ui/src/components/expander/expander.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import style from "./expander.module.css";

export class Expander extends HTMLElement {
private _isExpanded = true;
private expanderIcon: SVGSVGElement;
private readonly expanderIcon: SVGSVGElement;
private readonly headerPanel = div({ className: style.headerPanel });
readonly contenxtPanel = div({ className: style.contextPanel });

Expand Down
9 changes: 5 additions & 4 deletions packages/chili-ui/src/property/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@ export class InputProperty extends PropertyBase {
readonly document: IDocument,
objects: any[],
readonly property: Property,
converter?: IConverter,
) {
super(objects);
this.converter = property.converter ?? this.getConverter();
this.converter = converter ?? this.getConverter();
let arrayConverter = new ArrayValueConverter(objects, property, this.converter);
this.append(
div(
Expand Down Expand Up @@ -104,19 +105,19 @@ export class InputProperty extends PropertyBase {
);
}

private handleBlur = (e: FocusEvent) => {
private readonly handleBlur = (e: FocusEvent) => {
this.setValue(e.target as HTMLInputElement);
};

private handleKeyDown = (e: KeyboardEvent) => {
private readonly handleKeyDown = (e: KeyboardEvent) => {
e.stopPropagation();
if (this.converter === undefined) return;
if (e.key === "Enter") {
this.setValue(e.target as HTMLInputElement);
}
};

private setValue = (input: HTMLInputElement) => {
private readonly setValue = (input: HTMLInputElement) => {
let newValue = this.converter?.convertBack?.(input.value);
if (!newValue?.isOk) {
PubSub.default.pub("showToast", "error.default");
Expand Down
27 changes: 10 additions & 17 deletions packages/chili-ui/src/property/material/materialEditor.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
// Copyright 2022-2023 the Chili authors. All rights reserved. AGPL-3.0 license.

import { Binding, IConverter, Material, PathBinding, Property, PubSub, Result, Texture } from "chili-core";
import { Binding, IConverter, Material, PathBinding, Property, PubSub, Result } from "chili-core";
import { button, collection, div, localize, span, svg } from "../../components";
import { ColorConverter } from "../../converters";
import { appendProperty } from "../utils";
import { findPropertyControl } from "../utils";
import { MaterialDataContent } from "./materialDataContent";
import style from "./materialEditor.module.css";
import { UrlStringConverter } from "./urlConverter";
import { TextureEditor } from "./textureEditor";

class ActiveStyleConverter implements IConverter<Material> {
constructor(readonly material: Material) {}
Expand Down Expand Up @@ -127,27 +126,21 @@ export class MaterialEditor extends HTMLElement {
};

private initEditingControl(material: Material) {
let container = div({
className: style.properties,
});
this.editingControl.appendChild(
div(
{
className: style.editing,
},
container,
div(
{
className: style.properties,
},
...Property.getProperties(material).map((x) =>
findPropertyControl(this.dataContent.document, [material], x),
),
),
),
);

Property.getProperties(material).forEach((x) => {
let value = (material as any)[x.name];
if (value instanceof Texture) {
container.append(new TextureEditor(this.dataContent.document, x.display, value));
return;
}

appendProperty(container, this.dataContent.document, [material], x);
});
}
}

Expand Down
20 changes: 10 additions & 10 deletions packages/chili-ui/src/property/material/textureEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

import { I18nKeys, IDocument, PathBinding, Property, readFileAsync, Texture } from "chili-core";
import { div, Expander, img, svg } from "../../components";
import { appendProperty } from "../utils";
import { findPropertyControl } from "../utils";
import style from "./textureEditor.module.css";
import { UrlStringConverter } from "./urlConverter";

export class TextureEditor extends Expander {
export class TextureProperty extends Expander {
constructor(
readonly document: IDocument,
display: I18nKeys,
Expand All @@ -18,17 +18,17 @@ export class TextureEditor extends Expander {
}

private render() {
let properties = div({ className: style.properties });
Property.getProperties(this.texture).forEach((x) => {
if ((x.name as keyof Texture) === "image") return;
appendProperty(properties, this.document, [this.texture], x);
});

return div(
{
className: style.expander,
},
properties,
div(
{ className: style.properties },
...Property.getProperties(this.texture).map((x) => {
if ((x.name as keyof Texture) === "image") return "";
return findPropertyControl(this.document, [this.texture], x);
}),
),
div(
{
className: style.image,
Expand Down Expand Up @@ -56,4 +56,4 @@ export class TextureEditor extends Expander {
};
}

customElements.define("texture-editor", TextureEditor);
customElements.define("texture-editor", TextureProperty);
4 changes: 3 additions & 1 deletion packages/chili-ui/src/property/materialProperty.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ export class MaterialProperty extends PropertyBase {
button.textContent = material.name;
Transaction.excute(this.document, "change material", () => {
this.objects.forEach((x) => {
x[this.property.name] = material.id;
if (this.property.name in x) {
x[this.property.name] = material.id;
}
});
});
this.document.visual.update();
Expand Down
45 changes: 26 additions & 19 deletions packages/chili-ui/src/property/propertyView.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
// Copyright 2022-2023 the Chili authors. All rights reserved. AGPL-3.0 license.

import {
GeometryNode,
I18nKeys,
IConverter,
IDocument,
INode,
IView,
Node,
NodeLinkedList,
ParameterShapeNode,
Property,
PubSub,
VisualNode,
} from "chili-core";
import { Expander, div, label, localize } from "../components";
import { MatrixConverter } from "./matrixConverter";
import style from "./propertyView.module.css";
import { appendProperty } from "./utils";
import { findPropertyControl } from "./utils";

export class PropertyView extends HTMLElement {
private readonly panel = div({ className: style.panel });
Expand Down Expand Up @@ -59,18 +57,18 @@ export class PropertyView extends HTMLElement {
private addModel(document: IDocument, nodes: INode[]) {
if (nodes.length === 0) return;

let properties = div({ className: style.rootProperties });
let controls: any[] = [];
if (nodes[0] instanceof NodeLinkedList) {
Property.getProperties(Object.getPrototypeOf(nodes[0])).forEach((x) => {
appendProperty(properties, document, nodes, x);
controls = Property.getProperties(Object.getPrototypeOf(nodes[0])).map((x) => {
return findPropertyControl(document, nodes, x);
});
} else if (nodes[0] instanceof Node) {
Property.getOwnProperties(Node.prototype).forEach((x) => {
appendProperty(properties, document, nodes, x);
controls = Property.getOwnProperties(Node.prototype).map((x) => {
return findPropertyControl(document, nodes, x);
});
}

this.panel.append(properties);
this.panel.append(div({ className: style.rootProperties }, ...controls));
}

private addGeometry(nodes: INode[], document: IDocument) {
Expand All @@ -82,17 +80,24 @@ export class PropertyView extends HTMLElement {

private addTransform(document: IDocument, geometries: VisualNode[]) {
let matrix = new Expander("common.matrix");
// 这部分代码有问题,待完善
let converters = MatrixConverter.init();
this.panel.append(matrix);

const addMatrix = (display: I18nKeys, converter: IConverter) => {
appendProperty(matrix, document, geometries, {
name: "transform",
display: display,
converter,
});
matrix.contenxtPanel.append(
findPropertyControl(
document,
geometries,
{
name: "transform",
display: display,
},
converter,
),
);
};
// 这部分代码有问题,待完善
let converters = MatrixConverter.init();

addMatrix("transform.translation", converters.translation);
addMatrix("transform.scale", converters.scale);
addMatrix("transform.rotation", converters.rotate);
Expand All @@ -102,10 +107,12 @@ export class PropertyView extends HTMLElement {
let entities = geometries.filter((x) => x instanceof VisualNode);
if (entities.length === 0 || !this.isAllElementsOfTypeFirstElement(entities)) return;
let parameters = new Expander(entities[0].display());
parameters.contenxtPanel.append(
...Property.getProperties(Object.getPrototypeOf(entities[0]), Node.prototype).map((x) => {
return findPropertyControl(document, entities, x);
}),
);
this.panel.append(parameters);
Property.getProperties(Object.getPrototypeOf(entities[0]), Node.prototype).forEach((x) => {
appendProperty(parameters.contenxtPanel, document, entities, x);
});
}

private isAllElementsOfTypeFirstElement(arr: any[]): boolean {
Expand Down
51 changes: 29 additions & 22 deletions packages/chili-ui/src/property/utils.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,41 @@
// Copyright 2022-2023 the Chili authors. All rights reserved. AGPL-3.0 license.

import { GeometryNode, IDocument, Property, VisualNode } from "chili-core";
import { IConverter, IDocument, Logger, Property, Texture } from "chili-core";
import { CheckProperty } from "./check";
import { ColorProperty } from "./colorProperty";
import { InputProperty } from "./input";
import { TextureProperty } from "./material/textureEditor";
import { MaterialProperty } from "./materialProperty";

export function appendProperty(container: HTMLElement, document: IDocument, objs: any[], prop?: Property) {
if (prop === undefined || objs.length === 0) return;
if (!(prop.name in objs[0])) {
alert(`Property ${prop.name} not found in ${Object.getPrototypeOf(objs[0]).constructor.name}`);
return;
export function findPropertyControl(
document: IDocument,
objs: any[],
prop: Property,
converter?: IConverter,
) {
if (prop === undefined || objs.length === 0) return "";

if (prop.type === "color") {
return new ColorProperty(document, objs, prop);
}

const propValue = (objs[0] as unknown as any)[prop.name];
const type = typeof propValue;
if (prop.type === "materialId") {
return new MaterialProperty(document, objs, prop);
}

if (prop.type === "color") {
container.append(new ColorProperty(document, objs, prop));
} else if (prop.type === "materialId") {
container.append(
new MaterialProperty(
document,
objs.filter((x) => "materialId" in x),
prop,
),
);
} else if (type === "object" || type === "string" || type === "number") {
container.append(new InputProperty(document, objs, prop));
} else if (type === "boolean") {
container.append(new CheckProperty(objs, prop));
const value = objs[0][prop.name];
if (value instanceof Texture) {
return new TextureProperty(document, prop.display, value);
}

if (["object", "string", "number"].includes(typeof value)) {
return new InputProperty(document, objs, prop, converter);
}

if (typeof value === "boolean") {
return new CheckProperty(objs, prop);
}

Logger.warn(`Property ${prop.name} not found in ${Object.getPrototypeOf(objs[0]).constructor.name}`);
return "";
}

0 comments on commit d3810fd

Please sign in to comment.