diff --git a/source/Component/AttrInput/AttrInput.tsx b/source/Component/AttrInput/AttrInput.tsx index c496140..03bbc77 100644 --- a/source/Component/AttrInput/AttrInput.tsx +++ b/source/Component/AttrInput/AttrInput.tsx @@ -24,6 +24,13 @@ class AttrInput extends Component { private value: string = ""; private error: ReactNode; + private numberTestReg = [/\.0*$/, /[1-9]+0+$/]; + + private numberTester(value: string) { + return isNaN((value as any) / 1) || + this.numberTestReg[0].test(value) || + this.numberTestReg[1].test(value); + } private check(value: string): ReactNode { @@ -37,7 +44,7 @@ class AttrInput extends Component { const praseNumber = (value as any) / 1; // 数字校验 - if (isNaN(praseNumber) || /\.0*$/.test(value)) { + if (this.numberTester(value)) { return } diff --git a/source/Component/ColorInput/ColorInput.scss b/source/Component/ColorInput/ColorInput.scss index 8f63de7..4ee5a79 100644 --- a/source/Component/ColorInput/ColorInput.scss +++ b/source/Component/ColorInput/ColorInput.scss @@ -37,6 +37,7 @@ div.color-input-root { div.color-box { width: 12px; height: 12px; + border-radius: 3px; } } diff --git a/source/Component/CommandBar/CommandBar.tsx b/source/Component/CommandBar/CommandBar.tsx index 98e6a14..1b25b6a 100644 --- a/source/Component/CommandBar/CommandBar.tsx +++ b/source/Component/CommandBar/CommandBar.tsx @@ -58,7 +58,13 @@ class CommandBar extends Component { + this.props.status ? this.props.status.newLabel() : undefined; + } + })} {this.getRenderButton({ iconName: "Camera", i18NKey: "Command.Bar.Camera.Info" })}
diff --git a/source/Component/Container/Container.tsx b/source/Component/Container/Container.tsx index 4b8981c..b60e1d5 100644 --- a/source/Component/Container/Container.tsx +++ b/source/Component/Container/Container.tsx @@ -34,11 +34,11 @@ class Container extends Component { /** * 渲染此 Tab 下的 ELE */ - private renderPanel(panles: string[], showBar: boolean, focus?: string) { + private renderPanel(panels: string[], showBar: boolean, focus?: string) { const classList: string[] = []; const theme: Themes = this.props.theme ?? Themes.dark; - const showPanelId = focus ?? panles[0]; + const showPanelId = focus ?? panels[0]; const showPanelInfo = getPanelInfoById(showPanelId as any); classList.push(theme === Themes.light ? "light" : "dark"); @@ -46,14 +46,14 @@ class Container extends Component { classList.push(`font-${FontLevel.Level3}`); classList.push("app-tab-header"); - const hasActivePanel = panles.some((id) => id === this.props.focusId); + const hasActivePanel = panels.some((id) => id === this.props.focusId); return <> {showBar ?
{ this.props.onFocusTab ? this.props.onFocusTab("") : undefined }}>{ - panles.map((panelId: string) => { + panels.map((panelId: string) => { const classList: string[] = ["app-tab-header-item"]; if (panelId === this.props.focusId) classList.push("active"); @@ -189,7 +189,7 @@ class Container extends Component { const items: [IContainerProps, IContainerProps] | undefined = props.items; const showBar: boolean = props.showBar ?? true; - const panles: string[] = props.panles ?? []; + const panels: string[] = props.panels ?? []; const layout: LayoutDirection = props.layout ?? LayoutDirection.Y; const scale: number = props.scale ?? 50; const isRoot: boolean = !!props.isRoot; @@ -201,7 +201,7 @@ class Container extends Component { classList.push(`background-${BackgroundLevel.Level4}`); classList.push(`font-${FontLevel.normal}`); classList.push("app-container"); - if (panles.length > 0 && !items) classList.push("end-containe"); + if (panels.length > 0 && !items) classList.push("end-containe"); return
{ onMouseUp={isRoot ? () => this.focusEdgeId = undefined : undefined} > {/* 渲染 Panel */} - {panles.length > 0 && !items ? this.renderPanel(panles, showBar, focusPanel) : null} + {panels.length > 0 && !items ? this.renderPanel(panels, showBar, focusPanel) : null} {/* 渲染第一部分 */} {items && items[0] ? this.renderContainer(items[0], scale, layout) : null} diff --git a/source/Component/ErrorMessage/ErrorMessage.scss b/source/Component/ErrorMessage/ErrorMessage.scss new file mode 100644 index 0000000..aa33898 --- /dev/null +++ b/source/Component/ErrorMessage/ErrorMessage.scss @@ -0,0 +1,3 @@ +div.panel-error-message { + padding-top: 5px; +} \ No newline at end of file diff --git a/source/Component/ErrorMessage/ErrorMessage.tsx b/source/Component/ErrorMessage/ErrorMessage.tsx new file mode 100644 index 0000000..d82ef9c --- /dev/null +++ b/source/Component/ErrorMessage/ErrorMessage.tsx @@ -0,0 +1,16 @@ +import { AllI18nKeys, Localization } from "@Component/Localization/Localization"; +import { FunctionComponent } from "react"; +import "./ErrorMessage.scss"; + +interface IErrorMessageProps { + i18nKey: AllI18nKeys; + options?: Record; +} + +const ErrorMessage: FunctionComponent = (props) => { + return
+ +
+} + +export { ErrorMessage }; \ No newline at end of file diff --git a/source/Component/LabelList/LabelList.scss b/source/Component/LabelList/LabelList.scss new file mode 100644 index 0000000..3964103 --- /dev/null +++ b/source/Component/LabelList/LabelList.scss @@ -0,0 +1,64 @@ +@import "../Theme/Theme.scss"; + +div.label { + width: auto; + height: auto; + display: inline-flex; + margin: 5px 5px; + justify-content: center; + vertical-align: middle; + align-items: stretch; + border-radius: 3px; + border: .5px solid transparent; + overflow: hidden; + user-select: none; + cursor: pointer; + + div.label-color { + width: 3px; + margin-right: 2px; + border-radius: 3px; + flex-shrink: 0; + } + + div.label-name { + padding: 2px 3px; + text-overflow: ellipsis; + overflow: hidden; + } + + div.delete-button { + padding: 2px 3px; + border-radius: 3px; + display: flex; + align-items: center; + user-select: none; + cursor: pointer; + } +} + +div.dark.label { + background-color: $lt-bg-color-lvl3-dark; + + div.label-color { + color: $lt-bg-color-lvl3-dark; + } + + div.delete-button:hover { + color: $lt-font-color-lvl2-dark; + background-color: $lt-bg-color-lvl2-dark; + } +} + +div.light.label { + background-color: $lt-bg-color-lvl3-light; + + div.label-color { + color: $lt-bg-color-lvl3-light; + } + + div.delete-button:hover { + color: $lt-font-color-lvl2-light; + background-color: $lt-bg-color-lvl2-light; + } +} \ No newline at end of file diff --git a/source/Component/LabelList/LabelList.tsx b/source/Component/LabelList/LabelList.tsx new file mode 100644 index 0000000..01ca9cf --- /dev/null +++ b/source/Component/LabelList/LabelList.tsx @@ -0,0 +1,56 @@ +import { Component } from "react"; +import { Label } from "@Model/Label"; +import { Icon } from "@fluentui/react"; +import { useSetting, IMixinSettingProps, Themes } from "@Context/Setting"; +import "./LabelList.scss"; + +interface ILabelListProps { + labels: Label[]; + canDelete?: boolean; +} + +interface ILabelListState { + focusLabel?: Label; +} + +@useSetting +class LabelList extends Component { + + public state: Readonly = { + focusLabel: undefined + }; + + private renderLabel(label: Label) { + + const theme = this.props.setting?.themes ?? Themes.dark; + const themeClassName = theme === Themes.dark ? "dark" : "light"; + const colorCss = `rgb(${label.color.join(",")})`; + + return
+
+
+ {label.name} +
+ { + this.props.canDelete ? +
+ +
: null + } +
+ } + + public render() { + return <> + { + this.props.labels.map((label) => { + return this.renderLabel(label); + }) + } + + } +} + +export { LabelList }; \ No newline at end of file diff --git a/source/Component/TogglesInput/TogglesInput.scss b/source/Component/TogglesInput/TogglesInput.scss new file mode 100644 index 0000000..88598f9 --- /dev/null +++ b/source/Component/TogglesInput/TogglesInput.scss @@ -0,0 +1,63 @@ +@import "../Theme/Theme.scss"; + +$line-min-height: 26px; + +div.toggles-input { + width: 100%; + display: flex; + min-height: $line-min-height; + padding: 5px 0; + + div.toggles-intro { + width: 50%; + height: 100%; + max-width: 220px; + display: flex; + align-items: center; + padding-right: 5px; + box-sizing: border-box; + } + + div.toggles-content { + width: 50%; + height: 100%; + max-width: 180px; + min-height: $line-min-height; + + div.checkbox { + width: $line-min-height; + height: $line-min-height; + overflow: hidden; + border-radius: 3px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + user-select: none; + } + } +} + +div.dark.toggles-input { + + div.toggles-content div.checkbox { + background-color: $lt-bg-color-lvl3-dark; + color: $lt-font-color-normal-dark; + } + + div.toggles-content div.checkbox:hover { + background-color: $lt-bg-color-lvl2-dark; + } +} + +div.light.toggles-input { + + div.toggles-content div.checkbox { + background-color: $lt-bg-color-lvl3-light; + color: $lt-font-color-normal-light; + } + + div.toggles-content div.checkbox:hover { + background-color: $lt-bg-color-lvl2-light; + } +} \ No newline at end of file diff --git a/source/Component/TogglesInput/TogglesInput.tsx b/source/Component/TogglesInput/TogglesInput.tsx new file mode 100644 index 0000000..0aa21c6 --- /dev/null +++ b/source/Component/TogglesInput/TogglesInput.tsx @@ -0,0 +1,45 @@ +import { AllI18nKeys, Localization } from "@Component/Localization/Localization"; +import { Theme } from "@Component/Theme/Theme"; +import { Icon } from "@fluentui/react"; +import { Component, ReactNode } from "react"; +import "./TogglesInput.scss"; + +interface ITogglesInputProps { + keyI18n: AllI18nKeys; + infoI18n?: AllI18nKeys; + value?: boolean; + disable?: boolean; + valueChange?: (color: boolean) => any; +} + +class TogglesInput extends Component { + public render(): ReactNode { + return +
+ +
+
+
{ + if (this.props.disable) { + return; + } + if (this.props.valueChange) { + this.props.valueChange(!this.props.value); + } + })} + > + +
+
+
+ } +} + +export { TogglesInput }; \ No newline at end of file diff --git a/source/Context/Status.tsx b/source/Context/Status.tsx index 0c9084f..8573ecd 100644 --- a/source/Context/Status.tsx +++ b/source/Context/Status.tsx @@ -8,12 +8,18 @@ import { ClassicRenderer, MouseMod } from "@GLRender/ClassicRenderer"; import { Setting } from "./Setting"; import { I18N } from "@Component/Localization/Localization"; -function randomColor() { - return [ +function randomColor(unNormal: boolean = false) { + const color = [ Math.random() * .8 + .2, Math.random() * .8 + .2, Math.random() * .8 + .2, 1 ] + if (unNormal) { + color[0] = Math.round(color[0] * 255), + color[1] = Math.round(color[1] * 255), + color[2] = Math.round(color[2] * 255) + } + return color; } interface IStatusEvent { @@ -34,6 +40,7 @@ class Status extends Emitter { * 对象命名 */ public objectNameIndex = 1; + public labelNameIndex = 1; /** * 渲染器 @@ -123,6 +130,17 @@ class Status extends Emitter { return range; } + public newLabel() { + const label = this.model.addLabel( + I18N(this.setting.language, "Object.List.New.Label", { + id: this.labelNameIndex.toString() + }) + ); + label.color = randomColor(true); + this.labelNameIndex ++; + return label; + } + public setMouseMod(mod: MouseMod) { this.mouseMod = mod; if (this.renderer instanceof ClassicRenderer) { diff --git a/source/Localization/EN-US.ts b/source/Localization/EN-US.ts index 2ab0d8c..39225ae 100644 --- a/source/Localization/EN-US.ts +++ b/source/Localization/EN-US.ts @@ -25,15 +25,18 @@ const EN_US = { "Input.Error.Length": "The length of the input content must be less than {num}", "Object.List.New.Group": "Group object {id}", "Object.List.New.Range": "Range object {id}", + "Object.List.New.Label": "Label {id}", "Object.List.No.Data": "There are no objects in the model, click the button to create it", "Panel.Title.Notfound": "{id}", "Panel.Info.Notfound": "This panel with id {id} can not found!", "Panel.Title.Render.View": "Live preview", "Panel.Info.Render.View": "Live simulation results preview", "Panel.Title.Object.List.View": "Object list", - "Panel.Info.Object.List.View": "Edit View All Object Properties", + "Panel.Info.Object.List.View": "Edit view all Object Properties", "Panel.Title.Range.Details.View": "Range attributes", - "Panel.Info.Range.Details.View": "Edit View Range attributes", + "Panel.Info.Range.Details.View": "Edit view range attributes", + "Panel.Title.Label.List.View": "Label list", + "Panel.Info.Label.List.View": "Edit view label attributes", "Common.Attr.Key.Display.Name": "Display name", "Common.Attr.Key.Position.X": "Position X", "Common.Attr.Key.Position.Y": "Position Y", @@ -42,6 +45,8 @@ const EN_US = { "Common.Attr.Key.Radius.Y": "Radius Y", "Common.Attr.Key.Radius.Z": "Radius Z", "Common.Attr.Key.Color": "Color", + "Common.Attr.Key.Display": "Display", + "Common.Attr.Key.Update": "Update", "Common.Attr.Key.Error.Multiple": "Multiple values", "Panel.Info.Range.Details.Attr.Error.Not.Range": "Object is not a Range", "Panel.Info.Range.Details.Attr.Error.Unspecified": "Unspecified range object", diff --git a/source/Localization/ZH-CN.ts b/source/Localization/ZH-CN.ts index 80753da..1aad911 100644 --- a/source/Localization/ZH-CN.ts +++ b/source/Localization/ZH-CN.ts @@ -25,8 +25,9 @@ const ZH_CN = { "Input.Error.Length": "输入内容长度须小于 {number}", "Object.List.New.Group": "组对象 {id}", "Object.List.New.Range": "范围对象 {id}", + "Object.List.New.Label": "标签 {id}", "Object.List.No.Data": "模型中没有任何对象,点击按钮以创建", - "Panel.Title.Notfound": "找不到面板: {id}", + "Panel.Title.Notfound": "{id}", "Panel.Info.Notfound": "这个编号为 {id} 的面板无法找到!", "Panel.Title.Render.View": "实时预览", "Panel.Info.Render.View": "实时仿真结果预览", @@ -34,6 +35,8 @@ const ZH_CN = { "Panel.Info.Object.List.View": "编辑查看全部对象属性", "Panel.Title.Range.Details.View": "范围属性", "Panel.Info.Range.Details.View": "编辑查看范围属性", + "Panel.Title.Label.List.View": "标签列表", + "Panel.Info.Label.List.View": "编辑查看标签属性", "Common.Attr.Key.Display.Name": "显示名称", "Common.Attr.Key.Position.X": "X 坐标", "Common.Attr.Key.Position.Y": "Y 坐标", @@ -42,6 +45,8 @@ const ZH_CN = { "Common.Attr.Key.Radius.Y": "Y 半径", "Common.Attr.Key.Radius.Z": "Z 半径", "Common.Attr.Key.Color": "颜色", + "Common.Attr.Key.Display": "显示", + "Common.Attr.Key.Update": "更新", "Common.Attr.Key.Error.Multiple": "多重数值", "Panel.Info.Range.Details.Attr.Error.Not.Range": "对象不是一个范围", "Panel.Info.Range.Details.Attr.Error.Unspecified": "未指定范围对象", diff --git a/source/Model/Label.ts b/source/Model/Label.ts index 13737e1..e9748c8 100644 --- a/source/Model/Label.ts +++ b/source/Model/Label.ts @@ -14,12 +14,12 @@ class Label { /** * 用户定义的名称 */ - public name?: string; + public name: string = ""; /** * CSS 颜色 */ - public color?: string; + public color: number[] = [0, 0, 0]; /** * 所属模型 @@ -31,10 +31,10 @@ class Label { * @param id 标签 ID * @param name 用户定义的名称 */ - public constructor(model:Model, id: ObjectID, name?: string) { + public constructor(model: Model, id: ObjectID, name?: string) { this.model = model; this.id = id; - this.name = name; + this.name = name ?? this.name; } /** diff --git a/source/Model/Layout.ts b/source/Model/Layout.ts index 4c14eba..9e5229a 100644 --- a/source/Model/Layout.ts +++ b/source/Model/Layout.ts @@ -7,7 +7,7 @@ enum LayoutDirection { class ILayout { items?: [ILayout, ILayout]; - panles?: string[]; + panels?: string[]; focusPanel?: string; layout?: LayoutDirection; scale?: number; @@ -51,8 +51,8 @@ class Layout extends Emitter { this.id = 0; this.map((layout) => { layout.id = this.id; - if (!layout.focusPanel && layout.panles && layout.panles.length > 0) { - layout.focusPanel = layout.panles[0] + if (!layout.focusPanel && layout.panels && layout.panels.length > 0) { + layout.focusPanel = layout.panels[0] } this.id ++; }); @@ -80,10 +80,10 @@ class Layout extends Emitter { } this.map((layout) => { - if (layout.panles && layout.panles.length > 0) { + if (layout.panels && layout.panels.length > 0) { let index = -1; - for (let i = 0; i < layout.panles.length; i++) { - if (layout.panles[i] === panelId) { + for (let i = 0; i < layout.panels.length; i++) { + if (layout.panels[i] === panelId) { index = i; break; } diff --git a/source/Model/Model.ts b/source/Model/Model.ts index cda7ccb..3448165 100644 --- a/source/Model/Model.ts +++ b/source/Model/Model.ts @@ -28,8 +28,8 @@ class Model extends Emitter { * 下一个需要分配的 ID */ private idIndex: number = 1; - public get nextId(): number { - return this.idIndex ++; + public nextId(label: string = "U"): string { + return `${label}-${this.idIndex ++}`; } /** @@ -55,7 +55,7 @@ class Model extends Emitter { */ public addLabel(name: string): Label { console.log(`Model: Creat label with id ${this.idIndex}`); - let label = new Label(this, this.nextId, name); + let label = new Label(this, this.nextId("L"), name); this.labelPool.push(label); this.emit("labelAdd", label); this.emit("labelChange", this.labelPool); @@ -95,7 +95,7 @@ class Model extends Emitter { */ public addGroup(): Group { console.log(`Model: Creat group with id ${this.idIndex}`); - let group = new Group(this, this.nextId); + let group = new Group(this, this.nextId("G")); this.objectPool.push(group); this.emit("groupAdd", group); this.emit("objectAdd", group); @@ -108,7 +108,7 @@ class Model extends Emitter { */ public addRange(): Range { console.log(`Model: Creat range with id ${this.idIndex}`); - let range = new Range(this, this.nextId); + let range = new Range(this, this.nextId("R")); this.objectPool.push(range); this.emit("rangeAdd", range); this.emit("objectAdd", range); diff --git a/source/Model/Renderer.ts b/source/Model/Renderer.ts index d9714f1..2c9ee64 100644 --- a/source/Model/Renderer.ts +++ b/source/Model/Renderer.ts @@ -35,7 +35,7 @@ interface ICommonParam { /** * 对象标识符 */ -type ObjectID = Symbol | string | number; +type ObjectID = string; /** * 接收的数据类型 diff --git a/source/Page/SimulatorWeb/SimulatorWeb.tsx b/source/Page/SimulatorWeb/SimulatorWeb.tsx index ebc510e..952dcbd 100644 --- a/source/Page/SimulatorWeb/SimulatorWeb.tsx +++ b/source/Page/SimulatorWeb/SimulatorWeb.tsx @@ -51,6 +51,8 @@ class SimulatorWeb extends Component { individual.position[2] = (Math.random() - .5) * 2; }) this.status.model.update(0); + this.status.newLabel().name = "New Label"; + this.status.newLabel().name = "Test Label 01"; } (window as any).s = this; @@ -61,9 +63,9 @@ class SimulatorWeb extends Component { items: [ { items: [ - {panles: ["RenderView", "Label Aa Bb", "Label aaa"]}, + {panels: ["RenderView", "Label Aa Bb", "Label aaa"]}, { - items: [{panles: ["Label b", "Label bbb"]}, {panles: ["C"]}], + items: [{panels: ["Label b", "Label bbb"]}, {panels: ["LabelList"]}], scale: 80, layout: LayoutDirection.X } @@ -73,9 +75,9 @@ class SimulatorWeb extends Component { }, { items: [{ - panles: ["ObjectList", "Test tab"] + panels: ["ObjectList", "Test tab"] }, { - panles: ["RangeDetails", "Label e"] + panels: ["RangeDetails", "Label e"] }], layout: LayoutDirection.Y } diff --git a/source/Panel/LabelList/LabelList.scss b/source/Panel/LabelList/LabelList.scss new file mode 100644 index 0000000..179597e --- /dev/null +++ b/source/Panel/LabelList/LabelList.scss @@ -0,0 +1,33 @@ +@import "../../Component/Theme/Theme.scss"; + +div.label-list-command-bar { + width: 100%; + height: 30px; + flex-shrink: 0; + display: flex; + + div.command-item { + width: 30px; + height: 100%; + display: flex; + flex-shrink: 0; + justify-content: center; + align-items: center; + user-select: none; + cursor: pointer; + } +} + +div.dark.label-list-command-bar { + + div.command-item:hover { + background-color: $lt-bg-color-lvl3-dark; + } +} + +div.light.label-list-command-bar { + + div.command-item:hover { + background-color: $lt-bg-color-lvl3-light; + } +} \ No newline at end of file diff --git a/source/Panel/LabelList/LabelList.tsx b/source/Panel/LabelList/LabelList.tsx new file mode 100644 index 0000000..07908b8 --- /dev/null +++ b/source/Panel/LabelList/LabelList.tsx @@ -0,0 +1,24 @@ +import { Theme } from "@Component/Theme/Theme"; +import { LabelList as LabelListComponent } from "@Component/LabelList/LabelList"; +import { Component } from "react"; +import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; +import { Label } from "@Model/Label"; +import "./LabelList.scss"; + +interface ILabelListProps { + +} + +@useStatusWithEvent("labelChange") +class LabelList extends Component { + + public render() { + let labels: Label[] = []; + if (this.props.status) { + labels = this.props.status.model.labelPool.concat([]); + } + return + } +} + +export { LabelList }; \ No newline at end of file diff --git a/source/Panel/Panel.tsx b/source/Panel/Panel.tsx index 66b5c66..747d4cd 100644 --- a/source/Panel/Panel.tsx +++ b/source/Panel/Panel.tsx @@ -1,10 +1,11 @@ import { ReactNode, Component, FunctionComponent } from "react"; import { Theme } from "@Component/Theme/Theme"; -import { Localization } from "@Component/Localization/Localization"; +import { ErrorMessage } from "@Component/ErrorMessage/ErrorMessage"; import { RenderView } from "./RenderView/RenderView"; import { ObjectList } from "./ObjectList/ObjectList"; import { ObjectCommand } from "./ObjectList/ObjectCommand"; import { RangeDetails } from "./RangeDetails/RangeDetails"; +import { LabelList } from "./LabelList/LabelList"; interface IPanelInfo { nameKey: string; @@ -21,6 +22,7 @@ type PanelId = "" | "RenderView" // 主渲染器 | "ObjectList" // 对象列表 | "RangeDetails" // 范围属性 +| "LabelList" // 标签列表 ; const PanelInfoMap = new Map(); @@ -36,6 +38,10 @@ PanelInfoMap.set("RangeDetails", { nameKey: "Panel.Title.Range.Details.View", introKay: "Panel.Info.Range.Details.View", class: RangeDetails }) +PanelInfoMap.set("LabelList", { + nameKey: "Panel.Title.Label.List.View", introKay: "Panel.Info.Label.List.View", + class: LabelList +}) function getPanelById(panelId: PanelId): ReactNode { switch (panelId) { @@ -45,9 +51,7 @@ function getPanelById(panelId: PanelId): ReactNode { const C = info.class; return } else return - + } } diff --git a/source/Panel/RangeDetails/RangeDetails.tsx b/source/Panel/RangeDetails/RangeDetails.tsx index 4fe9548..101a440 100644 --- a/source/Panel/RangeDetails/RangeDetails.tsx +++ b/source/Panel/RangeDetails/RangeDetails.tsx @@ -1,10 +1,12 @@ import { Component, ReactNode } from "react"; import { AttrInput } from "@Component/AttrInput/AttrInput"; import { useStatusWithEvent, IMixinStatusProps, Status } from "@Context/Status"; -import { AllI18nKeys } from "@Component/Localization/Localization"; +import { AllI18nKeys, Localization } from "@Component/Localization/Localization"; +import { ErrorMessage } from "@Component/ErrorMessage/ErrorMessage"; import { Range } from "@Model/Range"; import { ObjectID } from "@Model/Renderer"; import { ColorInput } from "@Component/ColorInput/ColorInput"; +import { TogglesInput } from "@Component/TogglesInput/TogglesInput"; import "./RangeDetails.scss"; @useStatusWithEvent("rangeAttrChange", "focusObjectChange") @@ -12,6 +14,8 @@ class RangeDetails extends Component { public readonly AttrI18nKey: AllI18nKeys[] = [ "Common.Attr.Key.Display.Name", + "Common.Attr.Key.Display", + "Common.Attr.Key.Update", "Common.Attr.Key.Color", "Common.Attr.Key.Position.X", "Common.Attr.Key.Position.Y", @@ -21,14 +25,6 @@ class RangeDetails extends Component { "Common.Attr.Key.Radius.Z" ] - private renderErrorFrom(error: AllI18nKeys) { - return <> - {this.AttrI18nKey.map((key, index) => { - return - })} - - } - private renderAttrInput( id: ObjectID, key: number, val: string | number | undefined, change: (val: string, status: Status) => any, @@ -55,40 +51,54 @@ class RangeDetails extends Component { } private renderFrom(range: Range) { - // console.log(range); + + let keyIndex = 0; + return <> - {this.renderAttrInput(range.id, 0, range.displayName, (val, status) => { + {this.renderAttrInput(range.id, keyIndex ++, range.displayName, (val, status) => { status.changeRangeAttrib(range.id, "displayName", val); })} + + { + if (this.props.status) { + this.props.status.changeRangeAttrib(range.id, "display", val); + } + }}/> - { + { + if (this.props.status) { + this.props.status.changeRangeAttrib(range.id, "update", val); + } + }}/> + + { if (this.props.status) { this.props.status.changeRangeAttrib(range.id, "color", color); } }}/> - {this.renderAttrInput(range.id, 2, range.position[0], (val, status) => { + {this.renderAttrInput(range.id, keyIndex ++, range.position[0], (val, status) => { range.position[0] = (val as any) / 1; status.changeRangeAttrib(range.id, "position", range.position); }, .1)} - {this.renderAttrInput(range.id, 3, range.position[1], (val, status) => { + {this.renderAttrInput(range.id, keyIndex ++, range.position[1], (val, status) => { range.position[1] = (val as any) / 1; status.changeRangeAttrib(range.id, "position", range.position); }, .1)} - {this.renderAttrInput(range.id, 4, range.position[2], (val, status) => { + {this.renderAttrInput(range.id, keyIndex ++, range.position[2], (val, status) => { range.position[2] = (val as any) / 1; status.changeRangeAttrib(range.id, "position", range.position); }, .1)} - {this.renderAttrInput(range.id, 5, range.radius[0], (val, status) => { + {this.renderAttrInput(range.id, keyIndex ++, range.radius[0], (val, status) => { range.radius[0] = (val as any) / 1; status.changeRangeAttrib(range.id, "radius", range.radius); }, .1, undefined, 0)} - {this.renderAttrInput(range.id, 6, range.radius[1], (val, status) => { + {this.renderAttrInput(range.id, keyIndex ++, range.radius[1], (val, status) => { range.radius[1] = (val as any) / 1; status.changeRangeAttrib(range.id, "radius", range.radius); }, .1, undefined, 0)} - {this.renderAttrInput(range.id, 7, range.radius[2], (val, status) => { + {this.renderAttrInput(range.id, keyIndex ++, range.radius[2], (val, status) => { range.radius[2] = (val as any) / 1; status.changeRangeAttrib(range.id, "radius", range.radius); }, .1, undefined, 0)} @@ -98,12 +108,12 @@ class RangeDetails extends Component { public render(): ReactNode { if (this.props.status) { if (this.props.status.focusObject.size <= 0) { - return this.renderErrorFrom("Panel.Info.Range.Details.Attr.Error.Unspecified"); + return ; } if (this.props.status.focusObject.size > 1) { - return this.renderErrorFrom("Common.Attr.Key.Error.Multiple"); + return ; } - let id: ObjectID = 0; + let id: ObjectID = ""; this.props.status.focusObject.forEach((cid => id = cid)); let range = this.props.status!.model.getObjectById(id); @@ -111,10 +121,10 @@ class RangeDetails extends Component { if (range instanceof Range) { return this.renderFrom(range); } else { - return this.renderErrorFrom("Panel.Info.Range.Details.Attr.Error.Not.Range"); + return ; } } - return this.renderErrorFrom("Panel.Info.Range.Details.Attr.Error.Unspecified"); + return ; } }