Compare commits
	
		
			8 Commits
		
	
	
		
			f0a04875e4
			...
			edb24b27fb
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| edb24b27fb | |||
| 27688b9471 | |||
| 54a03181f1 | |||
| c86a856a32 | |||
| 97202fe976 | |||
| 8e3330b398 | |||
| f87da8cbab | |||
| 47e3c973fb | 
| @ -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]; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * 所属模型 |      * 所属模型 | ||||||
| @ -31,10 +31,10 @@ class Label { | |||||||
|      * @param id 标签 ID |      * @param id 标签 ID | ||||||
|      * @param name 用户定义的名称 |      * @param name 用户定义的名称 | ||||||
|      */ |      */ | ||||||
|     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); | ||||||
|             })} |             })} | ||||||
|  |              | ||||||
|  |             <TogglesInput keyI18n={this.AttrI18nKey[keyIndex ++]} value={range.display} valueChange={(val) => { | ||||||
|  |                 if (this.props.status) { | ||||||
|  |                     this.props.status.changeRangeAttrib(range.id, "display", val); | ||||||
|  |                 } | ||||||
|  |             }}/> | ||||||
| 
 | 
 | ||||||
|             <ColorInput keyI18n="Common.Attr.Key.Color" value={range.color} normal valueChange={(color) => { |             <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