Merge pull request 'Add label list component & panel & message component' (#17) from dev-mrkbear into master
Reviewed-on: http://git.mrkbear.com/MrKBear/living-together/pulls/17
This commit is contained in:
commit
edb24b27fb
@ -24,6 +24,13 @@ class AttrInput extends Component<IAttrInputProps> {
|
|||||||
|
|
||||||
private value: string = "";
|
private value: string = "";
|
||||||
private error: ReactNode;
|
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 {
|
private check(value: string): ReactNode {
|
||||||
|
|
||||||
@ -37,7 +44,7 @@ class AttrInput extends Component<IAttrInputProps> {
|
|||||||
const praseNumber = (value as any) / 1;
|
const praseNumber = (value as any) / 1;
|
||||||
|
|
||||||
// 数字校验
|
// 数字校验
|
||||||
if (isNaN(praseNumber) || /\.0*$/.test(value)) {
|
if (this.numberTester(value)) {
|
||||||
return <Localization i18nKey="Input.Error.Not.Number" />
|
return <Localization i18nKey="Input.Error.Not.Number" />
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ div.color-input-root {
|
|||||||
div.color-box {
|
div.color-box {
|
||||||
width: 12px;
|
width: 12px;
|
||||||
height: 12px;
|
height: 12px;
|
||||||
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,13 @@ class CommandBar extends Component<ICommandBarProps & IMixinSettingProps & IMixi
|
|||||||
}
|
}
|
||||||
})}
|
})}
|
||||||
{this.getRenderButton({ iconName: "StepSharedAdd", i18NKey: "Command.Bar.Add.Behavior.Info" })}
|
{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" })}
|
{this.getRenderButton({ iconName: "Camera", i18NKey: "Command.Bar.Camera.Info" })}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
@ -34,11 +34,11 @@ class Container extends Component<IContainerProps> {
|
|||||||
/**
|
/**
|
||||||
* 渲染此 Tab 下的 ELE
|
* 渲染此 Tab 下的 ELE
|
||||||
*/
|
*/
|
||||||
private renderPanel(panles: string[], showBar: boolean, focus?: string) {
|
private renderPanel(panels: string[], showBar: boolean, focus?: string) {
|
||||||
|
|
||||||
const classList: string[] = [];
|
const classList: string[] = [];
|
||||||
const theme: Themes = this.props.theme ?? Themes.dark;
|
const theme: Themes = this.props.theme ?? Themes.dark;
|
||||||
const showPanelId = focus ?? panles[0];
|
const showPanelId = focus ?? panels[0];
|
||||||
const showPanelInfo = getPanelInfoById(showPanelId as any);
|
const showPanelInfo = getPanelInfoById(showPanelId as any);
|
||||||
|
|
||||||
classList.push(theme === Themes.light ? "light" : "dark");
|
classList.push(theme === Themes.light ? "light" : "dark");
|
||||||
@ -46,14 +46,14 @@ class Container extends Component<IContainerProps> {
|
|||||||
classList.push(`font-${FontLevel.Level3}`);
|
classList.push(`font-${FontLevel.Level3}`);
|
||||||
classList.push("app-tab-header");
|
classList.push("app-tab-header");
|
||||||
|
|
||||||
const hasActivePanel = panles.some((id) => id === this.props.focusId);
|
const hasActivePanel = panels.some((id) => id === this.props.focusId);
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
{showBar ?
|
{showBar ?
|
||||||
<div className={classList.join(" ")} onClick={() => {
|
<div className={classList.join(" ")} onClick={() => {
|
||||||
this.props.onFocusTab ? this.props.onFocusTab("") : undefined
|
this.props.onFocusTab ? this.props.onFocusTab("") : undefined
|
||||||
}}>{
|
}}>{
|
||||||
panles.map((panelId: string) => {
|
panels.map((panelId: string) => {
|
||||||
|
|
||||||
const classList: string[] = ["app-tab-header-item"];
|
const classList: string[] = ["app-tab-header-item"];
|
||||||
if (panelId === this.props.focusId) classList.push("active");
|
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 items: [IContainerProps, IContainerProps] | undefined = props.items;
|
||||||
const showBar: boolean = props.showBar ?? true;
|
const showBar: boolean = props.showBar ?? true;
|
||||||
const panles: string[] = props.panles ?? [];
|
const panels: string[] = props.panels ?? [];
|
||||||
const layout: LayoutDirection = props.layout ?? LayoutDirection.Y;
|
const layout: LayoutDirection = props.layout ?? LayoutDirection.Y;
|
||||||
const scale: number = props.scale ?? 50;
|
const scale: number = props.scale ?? 50;
|
||||||
const isRoot: boolean = !!props.isRoot;
|
const isRoot: boolean = !!props.isRoot;
|
||||||
@ -201,7 +201,7 @@ class Container extends Component<IContainerProps> {
|
|||||||
classList.push(`background-${BackgroundLevel.Level4}`);
|
classList.push(`background-${BackgroundLevel.Level4}`);
|
||||||
classList.push(`font-${FontLevel.normal}`);
|
classList.push(`font-${FontLevel.normal}`);
|
||||||
classList.push("app-container");
|
classList.push("app-container");
|
||||||
if (panles.length > 0 && !items) classList.push("end-containe");
|
if (panels.length > 0 && !items) classList.push("end-containe");
|
||||||
|
|
||||||
return <div
|
return <div
|
||||||
className={classList.join(" ")}
|
className={classList.join(" ")}
|
||||||
@ -216,7 +216,7 @@ class Container extends Component<IContainerProps> {
|
|||||||
onMouseUp={isRoot ? () => this.focusEdgeId = undefined : undefined}
|
onMouseUp={isRoot ? () => this.focusEdgeId = undefined : undefined}
|
||||||
>
|
>
|
||||||
{/* 渲染 Panel */}
|
{/* 渲染 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}
|
{items && items[0] ? this.renderContainer(items[0], scale, layout) : null}
|
||||||
|
3
source/Component/ErrorMessage/ErrorMessage.scss
Normal file
3
source/Component/ErrorMessage/ErrorMessage.scss
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
div.panel-error-message {
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
16
source/Component/ErrorMessage/ErrorMessage.tsx
Normal file
16
source/Component/ErrorMessage/ErrorMessage.tsx
Normal 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 };
|
64
source/Component/LabelList/LabelList.scss
Normal file
64
source/Component/LabelList/LabelList.scss
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
56
source/Component/LabelList/LabelList.tsx
Normal file
56
source/Component/LabelList/LabelList.tsx
Normal 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 };
|
63
source/Component/TogglesInput/TogglesInput.scss
Normal file
63
source/Component/TogglesInput/TogglesInput.scss
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
45
source/Component/TogglesInput/TogglesInput.tsx
Normal file
45
source/Component/TogglesInput/TogglesInput.tsx
Normal 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 };
|
@ -8,12 +8,18 @@ import { ClassicRenderer, MouseMod } from "@GLRender/ClassicRenderer";
|
|||||||
import { Setting } from "./Setting";
|
import { Setting } from "./Setting";
|
||||||
import { I18N } from "@Component/Localization/Localization";
|
import { I18N } from "@Component/Localization/Localization";
|
||||||
|
|
||||||
function randomColor() {
|
function randomColor(unNormal: boolean = false) {
|
||||||
return [
|
const color = [
|
||||||
Math.random() * .8 + .2,
|
Math.random() * .8 + .2,
|
||||||
Math.random() * .8 + .2,
|
Math.random() * .8 + .2,
|
||||||
Math.random() * .8 + .2, 1
|
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 {
|
interface IStatusEvent {
|
||||||
@ -34,6 +40,7 @@ class Status extends Emitter<IStatusEvent> {
|
|||||||
* 对象命名
|
* 对象命名
|
||||||
*/
|
*/
|
||||||
public objectNameIndex = 1;
|
public objectNameIndex = 1;
|
||||||
|
public labelNameIndex = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 渲染器
|
* 渲染器
|
||||||
@ -123,6 +130,17 @@ class Status extends Emitter<IStatusEvent> {
|
|||||||
return range;
|
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) {
|
public setMouseMod(mod: MouseMod) {
|
||||||
this.mouseMod = mod;
|
this.mouseMod = mod;
|
||||||
if (this.renderer instanceof ClassicRenderer) {
|
if (this.renderer instanceof ClassicRenderer) {
|
||||||
|
@ -25,15 +25,18 @@ const EN_US = {
|
|||||||
"Input.Error.Length": "The length of the input content must be less than {num}",
|
"Input.Error.Length": "The length of the input content must be less than {num}",
|
||||||
"Object.List.New.Group": "Group object {id}",
|
"Object.List.New.Group": "Group object {id}",
|
||||||
"Object.List.New.Range": "Range 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",
|
"Object.List.No.Data": "There are no objects in the model, click the button to create it",
|
||||||
"Panel.Title.Notfound": "{id}",
|
"Panel.Title.Notfound": "{id}",
|
||||||
"Panel.Info.Notfound": "This panel with id {id} can not found!",
|
"Panel.Info.Notfound": "This panel with id {id} can not found!",
|
||||||
"Panel.Title.Render.View": "Live preview",
|
"Panel.Title.Render.View": "Live preview",
|
||||||
"Panel.Info.Render.View": "Live simulation results preview",
|
"Panel.Info.Render.View": "Live simulation results preview",
|
||||||
"Panel.Title.Object.List.View": "Object list",
|
"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.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.Display.Name": "Display name",
|
||||||
"Common.Attr.Key.Position.X": "Position X",
|
"Common.Attr.Key.Position.X": "Position X",
|
||||||
"Common.Attr.Key.Position.Y": "Position Y",
|
"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.Y": "Radius Y",
|
||||||
"Common.Attr.Key.Radius.Z": "Radius Z",
|
"Common.Attr.Key.Radius.Z": "Radius Z",
|
||||||
"Common.Attr.Key.Color": "Color",
|
"Common.Attr.Key.Color": "Color",
|
||||||
|
"Common.Attr.Key.Display": "Display",
|
||||||
|
"Common.Attr.Key.Update": "Update",
|
||||||
"Common.Attr.Key.Error.Multiple": "Multiple values",
|
"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.Not.Range": "Object is not a Range",
|
||||||
"Panel.Info.Range.Details.Attr.Error.Unspecified": "Unspecified range object",
|
"Panel.Info.Range.Details.Attr.Error.Unspecified": "Unspecified range object",
|
||||||
|
@ -25,8 +25,9 @@ const ZH_CN = {
|
|||||||
"Input.Error.Length": "输入内容长度须小于 {number}",
|
"Input.Error.Length": "输入内容长度须小于 {number}",
|
||||||
"Object.List.New.Group": "组对象 {id}",
|
"Object.List.New.Group": "组对象 {id}",
|
||||||
"Object.List.New.Range": "范围对象 {id}",
|
"Object.List.New.Range": "范围对象 {id}",
|
||||||
|
"Object.List.New.Label": "标签 {id}",
|
||||||
"Object.List.No.Data": "模型中没有任何对象,点击按钮以创建",
|
"Object.List.No.Data": "模型中没有任何对象,点击按钮以创建",
|
||||||
"Panel.Title.Notfound": "找不到面板: {id}",
|
"Panel.Title.Notfound": "{id}",
|
||||||
"Panel.Info.Notfound": "这个编号为 {id} 的面板无法找到!",
|
"Panel.Info.Notfound": "这个编号为 {id} 的面板无法找到!",
|
||||||
"Panel.Title.Render.View": "实时预览",
|
"Panel.Title.Render.View": "实时预览",
|
||||||
"Panel.Info.Render.View": "实时仿真结果预览",
|
"Panel.Info.Render.View": "实时仿真结果预览",
|
||||||
@ -34,6 +35,8 @@ const ZH_CN = {
|
|||||||
"Panel.Info.Object.List.View": "编辑查看全部对象属性",
|
"Panel.Info.Object.List.View": "编辑查看全部对象属性",
|
||||||
"Panel.Title.Range.Details.View": "范围属性",
|
"Panel.Title.Range.Details.View": "范围属性",
|
||||||
"Panel.Info.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.Display.Name": "显示名称",
|
||||||
"Common.Attr.Key.Position.X": "X 坐标",
|
"Common.Attr.Key.Position.X": "X 坐标",
|
||||||
"Common.Attr.Key.Position.Y": "Y 坐标",
|
"Common.Attr.Key.Position.Y": "Y 坐标",
|
||||||
@ -42,6 +45,8 @@ const ZH_CN = {
|
|||||||
"Common.Attr.Key.Radius.Y": "Y 半径",
|
"Common.Attr.Key.Radius.Y": "Y 半径",
|
||||||
"Common.Attr.Key.Radius.Z": "Z 半径",
|
"Common.Attr.Key.Radius.Z": "Z 半径",
|
||||||
"Common.Attr.Key.Color": "颜色",
|
"Common.Attr.Key.Color": "颜色",
|
||||||
|
"Common.Attr.Key.Display": "显示",
|
||||||
|
"Common.Attr.Key.Update": "更新",
|
||||||
"Common.Attr.Key.Error.Multiple": "多重数值",
|
"Common.Attr.Key.Error.Multiple": "多重数值",
|
||||||
"Panel.Info.Range.Details.Attr.Error.Not.Range": "对象不是一个范围",
|
"Panel.Info.Range.Details.Attr.Error.Not.Range": "对象不是一个范围",
|
||||||
"Panel.Info.Range.Details.Attr.Error.Unspecified": "未指定范围对象",
|
"Panel.Info.Range.Details.Attr.Error.Unspecified": "未指定范围对象",
|
||||||
|
@ -14,12 +14,12 @@ class Label {
|
|||||||
/**
|
/**
|
||||||
* 用户定义的名称
|
* 用户定义的名称
|
||||||
*/
|
*/
|
||||||
public name?: string;
|
public name: string = "";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CSS 颜色
|
* CSS 颜色
|
||||||
*/
|
*/
|
||||||
public color?: string;
|
public color: number[] = [0, 0, 0];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 所属模型
|
* 所属模型
|
||||||
@ -34,7 +34,7 @@ class Label {
|
|||||||
public constructor(model: Model, id: ObjectID, name?: string) {
|
public constructor(model: Model, id: ObjectID, name?: string) {
|
||||||
this.model = model;
|
this.model = model;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name ?? this.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,7 +7,7 @@ enum LayoutDirection {
|
|||||||
|
|
||||||
class ILayout {
|
class ILayout {
|
||||||
items?: [ILayout, ILayout];
|
items?: [ILayout, ILayout];
|
||||||
panles?: string[];
|
panels?: string[];
|
||||||
focusPanel?: string;
|
focusPanel?: string;
|
||||||
layout?: LayoutDirection;
|
layout?: LayoutDirection;
|
||||||
scale?: number;
|
scale?: number;
|
||||||
@ -51,8 +51,8 @@ class Layout extends Emitter<ILayoutEvent> {
|
|||||||
this.id = 0;
|
this.id = 0;
|
||||||
this.map((layout) => {
|
this.map((layout) => {
|
||||||
layout.id = this.id;
|
layout.id = this.id;
|
||||||
if (!layout.focusPanel && layout.panles && layout.panles.length > 0) {
|
if (!layout.focusPanel && layout.panels && layout.panels.length > 0) {
|
||||||
layout.focusPanel = layout.panles[0]
|
layout.focusPanel = layout.panels[0]
|
||||||
}
|
}
|
||||||
this.id ++;
|
this.id ++;
|
||||||
});
|
});
|
||||||
@ -80,10 +80,10 @@ class Layout extends Emitter<ILayoutEvent> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.map((layout) => {
|
this.map((layout) => {
|
||||||
if (layout.panles && layout.panles.length > 0) {
|
if (layout.panels && layout.panels.length > 0) {
|
||||||
let index = -1;
|
let index = -1;
|
||||||
for (let i = 0; i < layout.panles.length; i++) {
|
for (let i = 0; i < layout.panels.length; i++) {
|
||||||
if (layout.panles[i] === panelId) {
|
if (layout.panels[i] === panelId) {
|
||||||
index = i;
|
index = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,8 @@ class Model extends Emitter<ModelEvent> {
|
|||||||
* 下一个需要分配的 ID
|
* 下一个需要分配的 ID
|
||||||
*/
|
*/
|
||||||
private idIndex: number = 1;
|
private idIndex: number = 1;
|
||||||
public get nextId(): number {
|
public nextId(label: string = "U"): string {
|
||||||
return this.idIndex ++;
|
return `${label}-${this.idIndex ++}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -55,7 +55,7 @@ class Model extends Emitter<ModelEvent> {
|
|||||||
*/
|
*/
|
||||||
public addLabel(name: string): Label {
|
public addLabel(name: string): Label {
|
||||||
console.log(`Model: Creat label with id ${this.idIndex}`);
|
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.labelPool.push(label);
|
||||||
this.emit("labelAdd", label);
|
this.emit("labelAdd", label);
|
||||||
this.emit("labelChange", this.labelPool);
|
this.emit("labelChange", this.labelPool);
|
||||||
@ -95,7 +95,7 @@ class Model extends Emitter<ModelEvent> {
|
|||||||
*/
|
*/
|
||||||
public addGroup(): Group {
|
public addGroup(): Group {
|
||||||
console.log(`Model: Creat group with id ${this.idIndex}`);
|
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.objectPool.push(group);
|
||||||
this.emit("groupAdd", group);
|
this.emit("groupAdd", group);
|
||||||
this.emit("objectAdd", group);
|
this.emit("objectAdd", group);
|
||||||
@ -108,7 +108,7 @@ class Model extends Emitter<ModelEvent> {
|
|||||||
*/
|
*/
|
||||||
public addRange(): Range {
|
public addRange(): Range {
|
||||||
console.log(`Model: Creat range with id ${this.idIndex}`);
|
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.objectPool.push(range);
|
||||||
this.emit("rangeAdd", range);
|
this.emit("rangeAdd", range);
|
||||||
this.emit("objectAdd", range);
|
this.emit("objectAdd", range);
|
||||||
|
@ -35,7 +35,7 @@ interface ICommonParam {
|
|||||||
/**
|
/**
|
||||||
* 对象标识符
|
* 对象标识符
|
||||||
*/
|
*/
|
||||||
type ObjectID = Symbol | string | number;
|
type ObjectID = string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 接收的数据类型
|
* 接收的数据类型
|
||||||
|
@ -51,6 +51,8 @@ class SimulatorWeb extends Component {
|
|||||||
individual.position[2] = (Math.random() - .5) * 2;
|
individual.position[2] = (Math.random() - .5) * 2;
|
||||||
})
|
})
|
||||||
this.status.model.update(0);
|
this.status.model.update(0);
|
||||||
|
this.status.newLabel().name = "New Label";
|
||||||
|
this.status.newLabel().name = "Test Label 01";
|
||||||
}
|
}
|
||||||
|
|
||||||
(window as any).s = this;
|
(window as any).s = this;
|
||||||
@ -61,9 +63,9 @@ class SimulatorWeb extends Component {
|
|||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
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,
|
scale: 80,
|
||||||
layout: LayoutDirection.X
|
layout: LayoutDirection.X
|
||||||
}
|
}
|
||||||
@ -73,9 +75,9 @@ class SimulatorWeb extends Component {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
items: [{
|
items: [{
|
||||||
panles: ["ObjectList", "Test tab"]
|
panels: ["ObjectList", "Test tab"]
|
||||||
}, {
|
}, {
|
||||||
panles: ["RangeDetails", "Label e"]
|
panels: ["RangeDetails", "Label e"]
|
||||||
}],
|
}],
|
||||||
layout: LayoutDirection.Y
|
layout: LayoutDirection.Y
|
||||||
}
|
}
|
||||||
|
33
source/Panel/LabelList/LabelList.scss
Normal file
33
source/Panel/LabelList/LabelList.scss
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
24
source/Panel/LabelList/LabelList.tsx
Normal file
24
source/Panel/LabelList/LabelList.tsx
Normal 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 };
|
@ -1,10 +1,11 @@
|
|||||||
import { ReactNode, Component, FunctionComponent } from "react";
|
import { ReactNode, Component, FunctionComponent } from "react";
|
||||||
import { Theme } from "@Component/Theme/Theme";
|
import { Theme } from "@Component/Theme/Theme";
|
||||||
import { Localization } from "@Component/Localization/Localization";
|
import { ErrorMessage } from "@Component/ErrorMessage/ErrorMessage";
|
||||||
import { RenderView } from "./RenderView/RenderView";
|
import { RenderView } from "./RenderView/RenderView";
|
||||||
import { ObjectList } from "./ObjectList/ObjectList";
|
import { ObjectList } from "./ObjectList/ObjectList";
|
||||||
import { ObjectCommand } from "./ObjectList/ObjectCommand";
|
import { ObjectCommand } from "./ObjectList/ObjectCommand";
|
||||||
import { RangeDetails } from "./RangeDetails/RangeDetails";
|
import { RangeDetails } from "./RangeDetails/RangeDetails";
|
||||||
|
import { LabelList } from "./LabelList/LabelList";
|
||||||
|
|
||||||
interface IPanelInfo {
|
interface IPanelInfo {
|
||||||
nameKey: string;
|
nameKey: string;
|
||||||
@ -21,6 +22,7 @@ type PanelId = ""
|
|||||||
| "RenderView" // 主渲染器
|
| "RenderView" // 主渲染器
|
||||||
| "ObjectList" // 对象列表
|
| "ObjectList" // 对象列表
|
||||||
| "RangeDetails" // 范围属性
|
| "RangeDetails" // 范围属性
|
||||||
|
| "LabelList" // 标签列表
|
||||||
;
|
;
|
||||||
|
|
||||||
const PanelInfoMap = new Map<PanelId, IPanelInfo>();
|
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",
|
nameKey: "Panel.Title.Range.Details.View", introKay: "Panel.Info.Range.Details.View",
|
||||||
class: RangeDetails
|
class: RangeDetails
|
||||||
})
|
})
|
||||||
|
PanelInfoMap.set("LabelList", {
|
||||||
|
nameKey: "Panel.Title.Label.List.View", introKay: "Panel.Info.Label.List.View",
|
||||||
|
class: LabelList
|
||||||
|
})
|
||||||
|
|
||||||
function getPanelById(panelId: PanelId): ReactNode {
|
function getPanelById(panelId: PanelId): ReactNode {
|
||||||
switch (panelId) {
|
switch (panelId) {
|
||||||
@ -45,9 +51,7 @@ function getPanelById(panelId: PanelId): ReactNode {
|
|||||||
const C = info.class;
|
const C = info.class;
|
||||||
return <C></C>
|
return <C></C>
|
||||||
} else return <Theme>
|
} else return <Theme>
|
||||||
<Localization i18nKey={"Panel.Info.Notfound"} options={{
|
<ErrorMessage i18nKey={"Panel.Info.Notfound"} options={{ id: panelId }}/>
|
||||||
id: panelId
|
|
||||||
}}/>
|
|
||||||
</Theme>
|
</Theme>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import { Component, ReactNode } from "react";
|
import { Component, ReactNode } from "react";
|
||||||
import { AttrInput } from "@Component/AttrInput/AttrInput";
|
import { AttrInput } from "@Component/AttrInput/AttrInput";
|
||||||
import { useStatusWithEvent, IMixinStatusProps, Status } from "@Context/Status";
|
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 { Range } from "@Model/Range";
|
||||||
import { ObjectID } from "@Model/Renderer";
|
import { ObjectID } from "@Model/Renderer";
|
||||||
import { ColorInput } from "@Component/ColorInput/ColorInput";
|
import { ColorInput } from "@Component/ColorInput/ColorInput";
|
||||||
|
import { TogglesInput } from "@Component/TogglesInput/TogglesInput";
|
||||||
import "./RangeDetails.scss";
|
import "./RangeDetails.scss";
|
||||||
|
|
||||||
@useStatusWithEvent("rangeAttrChange", "focusObjectChange")
|
@useStatusWithEvent("rangeAttrChange", "focusObjectChange")
|
||||||
@ -12,6 +14,8 @@ class RangeDetails extends Component<IMixinStatusProps> {
|
|||||||
|
|
||||||
public readonly AttrI18nKey: AllI18nKeys[] = [
|
public readonly AttrI18nKey: AllI18nKeys[] = [
|
||||||
"Common.Attr.Key.Display.Name",
|
"Common.Attr.Key.Display.Name",
|
||||||
|
"Common.Attr.Key.Display",
|
||||||
|
"Common.Attr.Key.Update",
|
||||||
"Common.Attr.Key.Color",
|
"Common.Attr.Key.Color",
|
||||||
"Common.Attr.Key.Position.X",
|
"Common.Attr.Key.Position.X",
|
||||||
"Common.Attr.Key.Position.Y",
|
"Common.Attr.Key.Position.Y",
|
||||||
@ -21,14 +25,6 @@ class RangeDetails extends Component<IMixinStatusProps> {
|
|||||||
"Common.Attr.Key.Radius.Z"
|
"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(
|
private renderAttrInput(
|
||||||
id: ObjectID, key: number, val: string | number | undefined,
|
id: ObjectID, key: number, val: string | number | undefined,
|
||||||
change: (val: string, status: Status) => any,
|
change: (val: string, status: Status) => any,
|
||||||
@ -55,40 +51,54 @@ class RangeDetails extends Component<IMixinStatusProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private renderFrom(range: Range) {
|
private renderFrom(range: Range) {
|
||||||
// console.log(range);
|
|
||||||
|
let keyIndex = 0;
|
||||||
|
|
||||||
return <>
|
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);
|
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) {
|
if (this.props.status) {
|
||||||
this.props.status.changeRangeAttrib(range.id, "color", color);
|
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;
|
range.position[0] = (val as any) / 1;
|
||||||
status.changeRangeAttrib(range.id, "position", range.position);
|
status.changeRangeAttrib(range.id, "position", range.position);
|
||||||
}, .1)}
|
}, .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;
|
range.position[1] = (val as any) / 1;
|
||||||
status.changeRangeAttrib(range.id, "position", range.position);
|
status.changeRangeAttrib(range.id, "position", range.position);
|
||||||
}, .1)}
|
}, .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;
|
range.position[2] = (val as any) / 1;
|
||||||
status.changeRangeAttrib(range.id, "position", range.position);
|
status.changeRangeAttrib(range.id, "position", range.position);
|
||||||
}, .1)}
|
}, .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;
|
range.radius[0] = (val as any) / 1;
|
||||||
status.changeRangeAttrib(range.id, "radius", range.radius);
|
status.changeRangeAttrib(range.id, "radius", range.radius);
|
||||||
}, .1, undefined, 0)}
|
}, .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;
|
range.radius[1] = (val as any) / 1;
|
||||||
status.changeRangeAttrib(range.id, "radius", range.radius);
|
status.changeRangeAttrib(range.id, "radius", range.radius);
|
||||||
}, .1, undefined, 0)}
|
}, .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;
|
range.radius[2] = (val as any) / 1;
|
||||||
status.changeRangeAttrib(range.id, "radius", range.radius);
|
status.changeRangeAttrib(range.id, "radius", range.radius);
|
||||||
}, .1, undefined, 0)}
|
}, .1, undefined, 0)}
|
||||||
@ -98,12 +108,12 @@ class RangeDetails extends Component<IMixinStatusProps> {
|
|||||||
public render(): ReactNode {
|
public render(): ReactNode {
|
||||||
if (this.props.status) {
|
if (this.props.status) {
|
||||||
if (this.props.status.focusObject.size <= 0) {
|
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) {
|
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));
|
this.props.status.focusObject.forEach((cid => id = cid));
|
||||||
|
|
||||||
let range = this.props.status!.model.getObjectById(id);
|
let range = this.props.status!.model.getObjectById(id);
|
||||||
@ -111,10 +121,10 @@ class RangeDetails extends Component<IMixinStatusProps> {
|
|||||||
if (range instanceof Range) {
|
if (range instanceof Range) {
|
||||||
return this.renderFrom(range);
|
return this.renderFrom(range);
|
||||||
} else {
|
} 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"/>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user