Add label list component & panel & message component #17

Merged
MrKBear merged 7 commits from dev-mrkbear into master 2022-03-09 22:01:32 +08:00
22 changed files with 423 additions and 61 deletions

View File

@ -24,6 +24,13 @@ class AttrInput extends Component<IAttrInputProps> {
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<IAttrInputProps> {
const praseNumber = (value as any) / 1;
// 数字校验
if (isNaN(praseNumber) || /\.0*$/.test(value)) {
if (this.numberTester(value)) {
return <Localization i18nKey="Input.Error.Not.Number" />
}

View File

@ -37,6 +37,7 @@ div.color-input-root {
div.color-box {
width: 12px;
height: 12px;
border-radius: 3px;
}
}

View File

@ -58,7 +58,13 @@ class CommandBar extends Component<ICommandBarProps & IMixinSettingProps & IMixi
}
})}
{this.getRenderButton({ iconName: "StepSharedAdd", i18NKey: "Command.Bar.Add.Behavior.Info" })}
{this.getRenderButton({ iconName: "Tag", i18NKey: "Command.Bar.Add.Tag.Info" })}
{this.getRenderButton({
iconName: "Tag",
i18NKey: "Command.Bar.Add.Tag.Info",
click: () => {
this.props.status ? this.props.status.newLabel() : undefined;
}
})}
{this.getRenderButton({ iconName: "Camera", i18NKey: "Command.Bar.Camera.Info" })}
</div>
<div>

View File

@ -34,11 +34,11 @@ class Container extends Component<IContainerProps> {
/**
* 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<IContainerProps> {
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 ?
<div className={classList.join(" ")} onClick={() => {
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<IContainerProps> {
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<IContainerProps> {
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 <div
className={classList.join(" ")}
@ -216,7 +216,7 @@ class Container extends Component<IContainerProps> {
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}

View File

@ -0,0 +1,3 @@
div.panel-error-message {
padding-top: 5px;
}

View File

@ -0,0 +1,16 @@
import { AllI18nKeys, Localization } from "@Component/Localization/Localization";
import { FunctionComponent } from "react";
import "./ErrorMessage.scss";
interface IErrorMessageProps {
i18nKey: AllI18nKeys;
options?: Record<string, string>;
}
const ErrorMessage: FunctionComponent<IErrorMessageProps> = (props) => {
return <div className="panel-error-message">
<Localization i18nKey={props.i18nKey} options={props.options}/>
</div>
}
export { ErrorMessage };

View File

@ -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;
}
}

View File

@ -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<ILabelListProps & IMixinSettingProps, ILabelListState> {
public state: Readonly<ILabelListState> = {
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 <div className={`label ${themeClassName}`} key={label.id}>
<div className="label-color" style={{
backgroundColor: colorCss
}}/>
<div className="label-name">
{label.name}
</div>
{
this.props.canDelete ?
<div className="delete-button">
<Icon iconName="delete"></Icon>
</div> : null
}
</div>
}
public render() {
return <>
{
this.props.labels.map((label) => {
return this.renderLabel(label);
})
}
</>
}
}
export { LabelList };

View File

@ -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;
}
}

View File

@ -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<ITogglesInputProps> {
public render(): ReactNode {
return <Theme className="toggles-input">
<div className="toggles-intro">
<Localization i18nKey={this.props.keyI18n}/>
</div>
<div className="toggles-content">
<div
className="checkbox"
style={{
cursor: this.props.disable ? "not-allowed" : "pointer"
}}
onClick={(() => {
if (this.props.disable) {
return;
}
if (this.props.valueChange) {
this.props.valueChange(!this.props.value);
}
})}
>
<Icon iconName="CheckMark" style={{
display: this.props.value ? "inline-block" : "none"
}}></Icon>
</div>
</div>
</Theme>
}
}
export { TogglesInput };

View File

@ -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<IStatusEvent> {
*
*/
public objectNameIndex = 1;
public labelNameIndex = 1;
/**
*
@ -123,6 +130,17 @@ class Status extends Emitter<IStatusEvent> {
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) {

View File

@ -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",

View File

@ -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": "未指定范围对象",

View File

@ -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;
}
/**

View File

@ -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<ILayoutEvent> {
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<ILayoutEvent> {
}
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;
}

View File

@ -28,8 +28,8 @@ class Model extends Emitter<ModelEvent> {
* 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<ModelEvent> {
*/
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<ModelEvent> {
*/
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<ModelEvent> {
*/
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);

View File

@ -35,7 +35,7 @@ interface ICommonParam {
/**
*
*/
type ObjectID = Symbol | string | number;
type ObjectID = string;
/**
*

View File

@ -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
}

View File

@ -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;
}
}

View File

@ -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<ILabelListProps & IMixinStatusProps> {
public render() {
let labels: Label[] = [];
if (this.props.status) {
labels = this.props.status.model.labelPool.concat([]);
}
return <LabelListComponent labels={labels} canDelete/>
}
}
export { LabelList };

View File

@ -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<PanelId, IPanelInfo>();
@ -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 <C></C>
} else return <Theme>
<Localization i18nKey={"Panel.Info.Notfound"} options={{
id: panelId
}}/>
<ErrorMessage i18nKey={"Panel.Info.Notfound"} options={{ id: panelId }}/>
</Theme>
}
}

View File

@ -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<IMixinStatusProps> {
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<IMixinStatusProps> {
"Common.Attr.Key.Radius.Z"
]
private renderErrorFrom(error: AllI18nKeys) {
return <>
{this.AttrI18nKey.map((key, index) => {
return <AttrInput key={index} keyI18n={key} disable disableI18n={error}/>
})}
</>
}
private renderAttrInput(
id: ObjectID, key: number, val: string | number | undefined,
change: (val: string, status: Status) => any,
@ -55,40 +51,54 @@ class RangeDetails extends Component<IMixinStatusProps> {
}
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);
})}
<ColorInput keyI18n="Common.Attr.Key.Color" value={range.color} normal valueChange={(color) => {
<TogglesInput keyI18n={this.AttrI18nKey[keyIndex ++]} value={range.display} valueChange={(val) => {
if (this.props.status) {
this.props.status.changeRangeAttrib(range.id, "display", val);
}
}}/>
<TogglesInput keyI18n={this.AttrI18nKey[keyIndex ++]} value={range.update} valueChange={(val) => {
if (this.props.status) {
this.props.status.changeRangeAttrib(range.id, "update", val);
}
}}/>
<ColorInput keyI18n={this.AttrI18nKey[keyIndex ++]} value={range.color} normal valueChange={(color) => {
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<IMixinStatusProps> {
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 <ErrorMessage i18nKey="Panel.Info.Range.Details.Attr.Error.Unspecified"/>;
}
if (this.props.status.focusObject.size > 1) {
return this.renderErrorFrom("Common.Attr.Key.Error.Multiple");
return <ErrorMessage i18nKey="Common.Attr.Key.Error.Multiple"/>;
}
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<IMixinStatusProps> {
if (range instanceof Range) {
return this.renderFrom(range);
} else {
return this.renderErrorFrom("Panel.Info.Range.Details.Attr.Error.Not.Range");
return <ErrorMessage i18nKey="Panel.Info.Range.Details.Attr.Error.Not.Range"/>;
}
}
return this.renderErrorFrom("Panel.Info.Range.Details.Attr.Error.Unspecified");
return <ErrorMessage i18nKey="Panel.Info.Range.Details.Attr.Error.Unspecified"/>;
}
}