Compare commits
	
		
			2 Commits
		
	
	
		
			9bc8ddf061
			...
			f3ba3b6150
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| f3ba3b6150 | |||
| 71e17b2f5a | 
| @ -4,51 +4,71 @@ div.attr-input { | |||||||
| 	width: 100%; | 	width: 100%; | ||||||
| 	display: flex; | 	display: flex; | ||||||
| 	min-height: 24px; | 	min-height: 24px; | ||||||
| 	padding: 8px 0; | 	padding: 5px 0; | ||||||
| 
 | 
 | ||||||
| 	div.input-intro { | 	div.input-intro { | ||||||
| 		width: 50%; | 		width: 50%; | ||||||
| 		height: 100%; | 		height: 100%; | ||||||
| 		max-width: 180px; | 		max-width: 220px; | ||||||
| 		display: flex; | 		display: flex; | ||||||
| 		align-items: center; | 		align-items: center; | ||||||
|  |         padding-right: 5px; | ||||||
|  |         box-sizing: border-box; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	div.input-content { |     div.root-content { | ||||||
| 		width: 50%; |         width: 50%; | ||||||
| 		height: 100%; |         height: 100%; | ||||||
| 		max-width: 180px; |         max-width: 180px; | ||||||
| 		box-sizing: border-box; |  | ||||||
| 		border-radius: 3px; |  | ||||||
| 		overflow: hidden; |  | ||||||
| 		display: flex; |  | ||||||
| 		justify-content: space-between; |  | ||||||
| 		align-items: center; |  | ||||||
| 		min-height: 24px; |  | ||||||
| 
 | 
 | ||||||
| 		input { |         div.input-content { | ||||||
| 			padding: 0 5px; |             box-sizing: border-box; | ||||||
| 			width: 100%; |             border: 1px solid transparent; | ||||||
| 			height: 100%; |             border-radius: 3px; | ||||||
| 			border: none; |             overflow: hidden; | ||||||
| 			outline:none; |             display: flex; | ||||||
| 		}; |             justify-content: space-between; | ||||||
|  |             align-items: center; | ||||||
|  |             min-height: 24px; | ||||||
|  |      | ||||||
|  |             input { | ||||||
|  |                 width: 100%; | ||||||
|  |                 height: 100%; | ||||||
|  |                 border: none; | ||||||
|  |                 outline:none; | ||||||
|  |             }; | ||||||
|  |      | ||||||
|  |             input:focus { | ||||||
|  |                 border: none; | ||||||
|  |             } | ||||||
|  |      | ||||||
|  |             div.button-left, div.button-right { | ||||||
|  |                 min-height: 24px; | ||||||
|  |                 height: 100%; | ||||||
|  |                 display: flex; | ||||||
|  |                 justify-content: center; | ||||||
|  |                 align-items: center; | ||||||
|  |                 vertical-align: middle; | ||||||
|  |                 cursor: pointer; | ||||||
|  |                 user-select: none; | ||||||
|  |                 padding: 0 3px; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |      | ||||||
|  |         div.input-content.error { | ||||||
|  |             border: 1px solid $lt-red; | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
| 		input:focus { |         div.input-content.focus { | ||||||
| 			border: none; |             border: 1px solid $lt-blue; | ||||||
| 		} |         } | ||||||
| 
 | 
 | ||||||
| 		div.button-left, div.button-right { |         div.err-message { | ||||||
| 			height: 100%; |             color: $lt-red; | ||||||
| 			display: flex; |             padding-top: 5px; | ||||||
| 			justify-content: center; |             min-height: 24px; | ||||||
| 			align-items: center; |         } | ||||||
| 			vertical-align: middle; |     } | ||||||
| 			cursor: pointer; |  | ||||||
| 			user-select: none; |  | ||||||
| 			padding: 0 3px; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| div.dark.attr-input { | div.dark.attr-input { | ||||||
|  | |||||||
| @ -2,35 +2,151 @@ import { Component, ReactNode } from "react"; | |||||||
| import { FontLevel, Theme } from "@Component/Theme/Theme"; | import { FontLevel, Theme } from "@Component/Theme/Theme"; | ||||||
| import "./AttrInput.scss"; | import "./AttrInput.scss"; | ||||||
| import { Icon } from "@fluentui/react"; | import { Icon } from "@fluentui/react"; | ||||||
|  | import { Localization, AllI18nKeys } from "@Component/Localization/Localization"; | ||||||
| 
 | 
 | ||||||
| interface IAttrInputProps { | interface IAttrInputProps { | ||||||
|  |     keyI18n: AllI18nKeys; | ||||||
|  |     infoI18n?: AllI18nKeys; | ||||||
|  |     value?: number | string; | ||||||
| 	isNumber?: boolean; | 	isNumber?: boolean; | ||||||
|  |     maxLength?: number; | ||||||
|  |     max?: number; | ||||||
|  |     min?: number; | ||||||
|  |     step?: number; | ||||||
|  |     disable?: boolean; | ||||||
|  |     disableI18n?: AllI18nKeys; | ||||||
|  |     valueChange?: (value: this["isNumber"] extends true ? number : string) => any; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| class AttrInput extends Component<IAttrInputProps> { | class AttrInput extends Component<IAttrInputProps> { | ||||||
|  | 
 | ||||||
|  |     private value: string = ""; | ||||||
|  |     private error: ReactNode; | ||||||
|  | 
 | ||||||
|  |     private check(value: string): ReactNode { | ||||||
|  | 
 | ||||||
|  |         // 长度校验
 | ||||||
|  |         const maxLength = this.props.maxLength ?? 32; | ||||||
|  |         if (value.length > maxLength) { | ||||||
|  |             return <Localization i18nKey="Input.Error.Length" options={{ num: maxLength.toString() }} /> | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (this.props.isNumber) { | ||||||
|  |             const praseNumber = (value as any) / 1; | ||||||
|  | 
 | ||||||
|  |             // 数字校验
 | ||||||
|  |             if (isNaN(praseNumber)) { | ||||||
|  |                 return <Localization i18nKey="Input.Error.Not.Number" /> | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // 最大值校验
 | ||||||
|  |             if (this.props.max !== undefined && praseNumber > this.props.max) { | ||||||
|  |                 return <Localization i18nKey="Input.Error.Max" options={{ num: this.props.max.toString() }} /> | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // 最小值校验
 | ||||||
|  |             if (this.props.min !== undefined && praseNumber < this.props.min) { | ||||||
|  |                 return <Localization i18nKey="Input.Error.Min" options={{ num: this.props.min.toString() }} /> | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  |         return undefined; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private handelValueChange = () => { | ||||||
|  |         if (!this.error && this.props.valueChange) { | ||||||
|  |             this.props.valueChange(this.value); | ||||||
|  |         } | ||||||
|  |         this.forceUpdate(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private changeValue = (direction: number) => { | ||||||
|  |         if (this.error) { | ||||||
|  |             return; | ||||||
|  |         } else { | ||||||
|  |             let newVal = (this.value as any / 1) + (this.props.step ?? 1) * direction; | ||||||
|  | 
 | ||||||
|  |             // 最大值校验
 | ||||||
|  |             if (this.props.max !== undefined && newVal > this.props.max) { | ||||||
|  |                 newVal = this.props.max; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // 最小值校验
 | ||||||
|  |             if (this.props.min !== undefined && newVal < this.props.min) { | ||||||
|  |                 newVal = this.props.min; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             this.value = newVal.toString(); | ||||||
|  |             this.handelValueChange() | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private renderInput() { | ||||||
|  |         return <> | ||||||
|  |             <div className={"input-content" + (this.error ? ` error` : "")}> | ||||||
|  |                 { | ||||||
|  |                     this.props.isNumber ? <div | ||||||
|  |                         className="button-left" | ||||||
|  |                         onClick={() => this.changeValue(-1)} | ||||||
|  |                     > | ||||||
|  |                         <Icon iconName="ChevronLeft"></Icon> | ||||||
|  |                     </div> : null | ||||||
|  |                 } | ||||||
|  |                 <input | ||||||
|  |                     className="input" | ||||||
|  |                     value={this.value} | ||||||
|  |                     style={{ | ||||||
|  |                         padding: this.props.isNumber ? "0 3px" : "0 8px" | ||||||
|  |                     }} | ||||||
|  |                     onChange={(e) => { | ||||||
|  |                         this.value = e.target.value; | ||||||
|  |                         this.error = this.check(e.target.value); | ||||||
|  |                         this.handelValueChange(); | ||||||
|  |                     }} | ||||||
|  |                 ></input> | ||||||
|  |                 { | ||||||
|  |                     this.props.isNumber ? <div | ||||||
|  |                         className="button-right" | ||||||
|  |                         onClick={() => this.changeValue(1)} | ||||||
|  |                     > | ||||||
|  |                         <Icon iconName="ChevronRight"></Icon> | ||||||
|  |                     </div> : null | ||||||
|  |                 } | ||||||
|  |             </div> | ||||||
|  |             {  | ||||||
|  |                 this.error ?  | ||||||
|  |                     <div className="err-message"> | ||||||
|  |                         {this.error} | ||||||
|  |                     </div> : null | ||||||
|  |             } | ||||||
|  |         </> | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| 	public render(): ReactNode { | 	public render(): ReactNode { | ||||||
| 
 | 
 | ||||||
|  |         if (!this.error) { | ||||||
|  |             const value = this.props.value ?? (this.props.isNumber ? "0" : ""); | ||||||
|  |             this.value = value.toString(); | ||||||
|  |             this.error = this.check(value.toString()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
| 		return <Theme | 		return <Theme | ||||||
| 			className="attr-input" |             className="attr-input" | ||||||
| 			fontLevel={FontLevel.normal} |             fontLevel={FontLevel.normal} | ||||||
| 		> |         > | ||||||
| 			<div className="input-intro"> |             <div className="input-intro"> | ||||||
| 				Input |                 <Localization i18nKey={this.props.keyI18n}/> | ||||||
| 			</div> |             </div> | ||||||
| 			<div className="input-content"> |             <div className="root-content"> | ||||||
| 				{ |                 { | ||||||
| 					this.props.isNumber ? <div className="button-left"> |                     this.props.disable ?  | ||||||
| 						<Icon iconName="ChevronLeft"></Icon> |                         this.props.disableI18n ?  | ||||||
| 					</div> : null |                             <Localization i18nKey={this.props.disableI18n}/> : | ||||||
| 				} |                             <div>{this.props.value}</div> : | ||||||
| 				<input className="input"></input> |                         this.renderInput() | ||||||
| 				{ |                 } | ||||||
| 					this.props.isNumber ? <div className="button-right"> |             </div> | ||||||
| 						<Icon iconName="ChevronRight"></Icon> |         </Theme> | ||||||
| 					</div> : null |  | ||||||
| 				} |  | ||||||
| 			</div> |  | ||||||
| 		</Theme> |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -27,7 +27,7 @@ div.app-container { | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		div:hover { | 		div:hover { | ||||||
| 			background-color: blue; | 			background-color: $lt-blue; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -83,7 +83,7 @@ div.app-container { | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		div.app-tab-header-item.active { | 		div.app-tab-header-item.active { | ||||||
| 			border: .8px solid blue; | 			border: .8px solid $lt-blue; | ||||||
| 			transition: none; | 			transition: none; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| @ -141,7 +141,7 @@ div.app-container { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	div.app-panel-root.active { | 	div.app-panel-root.active { | ||||||
| 		border: .8px solid blue !important; | 		border: .8px solid $lt-blue !important; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,5 +1,8 @@ | |||||||
| @import "@fluentui/react/dist/sass/References"; | @import "@fluentui/react/dist/sass/References"; | ||||||
| 
 | 
 | ||||||
|  | $lt-blue: rgb(81, 79, 235); | ||||||
|  | $lt-red: rgb(240, 94, 94); | ||||||
|  | 
 | ||||||
| $lt-font-size-normal: 13px; | $lt-font-size-normal: 13px; | ||||||
| $lt-font-size-lvl3: $ms-font-size-16; | $lt-font-size-lvl3: $ms-font-size-16; | ||||||
| $lt-font-size-lvl2: $ms-font-size-18; | $lt-font-size-lvl2: $ms-font-size-18; | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| import { createContext, Component, FunctionComponent, useState, useEffect, ReactNode } from "react"; | import { createContext, Component, FunctionComponent, useState, useEffect, ReactNode } from "react"; | ||||||
| import { Emitter } from "@Model/Emitter"; | import { Emitter } from "@Model/Emitter"; | ||||||
| import { Model, ObjectID } from "@Model/Model"; | import { Model, ObjectID } from "@Model/Model"; | ||||||
|  | import { Range } from "@Model/Range"; | ||||||
| import { Archive } from "@Model/Archive"; | import { Archive } from "@Model/Archive"; | ||||||
| import { AbstractRenderer } from "@Model/Renderer"; | import { AbstractRenderer } from "@Model/Renderer"; | ||||||
| import { ClassicRenderer, MouseMod } from "@GLRender/ClassicRenderer"; | import { ClassicRenderer, MouseMod } from "@GLRender/ClassicRenderer"; | ||||||
| @ -22,6 +23,7 @@ interface IStatusEvent { | |||||||
|     focusObjectChange: void; |     focusObjectChange: void; | ||||||
|     objectChange: void; |     objectChange: void; | ||||||
|     labelChange: void; |     labelChange: void; | ||||||
|  |     rangeAttrChange: void; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| class Status extends Emitter<IStatusEvent> { | class Status extends Emitter<IStatusEvent> { | ||||||
| @ -83,6 +85,19 @@ class Status extends Emitter<IStatusEvent> { | |||||||
|         this.emit("focusObjectChange"); |         this.emit("focusObjectChange"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * 修改范围属性 | ||||||
|  |      */ | ||||||
|  |     public changeRangeAttrib<K extends keyof Range> | ||||||
|  |     (id: ObjectID, key: K, val: Range[K]) { | ||||||
|  |         const range = this.model.getObjectById(id); | ||||||
|  |         if (range && range instanceof Range) { | ||||||
|  |             range[key] = val; | ||||||
|  |             this.emit("rangeAttrChange"); | ||||||
|  |             this.model.draw(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * 鼠标工具状态 |      * 鼠标工具状态 | ||||||
|      */ |      */ | ||||||
|  | |||||||
| @ -19,6 +19,10 @@ const EN_US = { | |||||||
|     "Command.Bar.Add.Tag.Info": "Add label object", |     "Command.Bar.Add.Tag.Info": "Add label object", | ||||||
|     "Command.Bar.Camera.Info": "Renderer settings", |     "Command.Bar.Camera.Info": "Renderer settings", | ||||||
|     "Command.Bar.Setting.Info": "Global Settings", |     "Command.Bar.Setting.Info": "Global Settings", | ||||||
|  |     "Input.Error.Not.Number": "Please key in numbers", | ||||||
|  |     "Input.Error.Max": "Enter value must be less than {num}", | ||||||
|  |     "Input.Error.Min": "Enter value must be greater 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.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", | ||||||
| @ -30,6 +34,12 @@ const EN_US = { | |||||||
|     "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", | ||||||
| 
 |     "Common.Attr.Key.Display.Name": "Display name", | ||||||
|  |     "Common.Attr.Key.Position.X": "Position X", | ||||||
|  |     "Common.Attr.Key.Position.Y": "Position Y", | ||||||
|  |     "Common.Attr.Key.Position.Z": "Position Z", | ||||||
|  |     "Common.Attr.Key.Error.Multiple": "Cannot edit multiple values", | ||||||
|  |     "Panel.Info.Range.Details.Attr.Error.Not.Range": "The focus object is not a Range", | ||||||
|  |     "Panel.Info.Range.Details.Attr.Error.Unspecified": "Unspecified range object", | ||||||
| } | } | ||||||
| export default EN_US; | export default EN_US; | ||||||
| @ -19,6 +19,10 @@ const ZH_CN = { | |||||||
|     "Command.Bar.Add.Tag.Info": "添加标签对象", |     "Command.Bar.Add.Tag.Info": "添加标签对象", | ||||||
|     "Command.Bar.Camera.Info": "渲染器设置", |     "Command.Bar.Camera.Info": "渲染器设置", | ||||||
|     "Command.Bar.Setting.Info": "全局设置", |     "Command.Bar.Setting.Info": "全局设置", | ||||||
|  |     "Input.Error.Not.Number": "请输入数字", | ||||||
|  |     "Input.Error.Max": "输入数值须小于 {number}", | ||||||
|  |     "Input.Error.Min": "输入数值须大于 {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.No.Data": "模型中没有任何对象,点击按钮以创建", |     "Object.List.No.Data": "模型中没有任何对象,点击按钮以创建", | ||||||
| @ -30,5 +34,12 @@ 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": "编辑查看范围属性", | ||||||
|  |     "Common.Attr.Key.Display.Name": "显示名称", | ||||||
|  |     "Common.Attr.Key.Position.X": "X 坐标", | ||||||
|  |     "Common.Attr.Key.Position.Y": "Y 坐标", | ||||||
|  |     "Common.Attr.Key.Position.Z": "Z 坐标", | ||||||
|  |     "Common.Attr.Key.Error.Multiple": "无法编辑多重数值", | ||||||
|  |     "Panel.Info.Range.Details.Attr.Error.Not.Range": "焦点对象不是一个范围", | ||||||
|  |     "Panel.Info.Range.Details.Attr.Error.Unspecified": "未指定范围对象", | ||||||
| } | } | ||||||
| export default ZH_CN; | export default ZH_CN; | ||||||
| @ -39,7 +39,7 @@ class Model extends Emitter<ModelEvent> { | |||||||
| 
 | 
 | ||||||
|     public getObjectById(id: ObjectID): CtrlObject | undefined { |     public getObjectById(id: ObjectID): CtrlObject | undefined { | ||||||
|         for (let i = 0; i < this.objectPool.length; i++) { |         for (let i = 0; i < this.objectPool.length; i++) { | ||||||
|             if (this.objectPool[i].id === id) { |             if (this.objectPool[i].id.toString() === id.toString()) { | ||||||
|                 return this.objectPool[i]; |                 return this.objectPool[i]; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ class Range extends CtrlObject { | |||||||
|     /** |     /** | ||||||
|      * 坐标 |      * 坐标 | ||||||
|      */ |      */ | ||||||
|     public position: number[] = []; |     public position: number[] = [0, 0, 0]; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * 半径 |      * 半径 | ||||||
|  | |||||||
| @ -7,7 +7,7 @@ import { ObjectID } from "@Model/Renderer"; | |||||||
| import "./ObjectList.scss"; | import "./ObjectList.scss"; | ||||||
| 
 | 
 | ||||||
| @useSetting | @useSetting | ||||||
| @useStatusWithEvent("objectChange", "focusObjectChange") | @useStatusWithEvent("objectChange", "focusObjectChange", "rangeAttrChange") | ||||||
| class ObjectList extends Component<IMixinStatusProps & IMixinSettingProps> { | class ObjectList extends Component<IMixinStatusProps & IMixinSettingProps> { | ||||||
| 
 | 
 | ||||||
|     private renderList() { |     private renderList() { | ||||||
|  | |||||||
| @ -1,13 +1,81 @@ | |||||||
| 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 } from "@Context/Status"; | ||||||
|  | import { AllI18nKeys } from "@Component/Localization/Localization"; | ||||||
|  | import { Range } from "@Model/Range"; | ||||||
|  | import { ObjectID } from "@Model/Renderer"; | ||||||
| import "./RangeDetails.scss"; | import "./RangeDetails.scss"; | ||||||
| 
 | 
 | ||||||
| class RangeDetails extends Component { | @useStatusWithEvent("rangeAttrChange", "focusObjectChange") | ||||||
|  | class RangeDetails extends Component<IMixinStatusProps> { | ||||||
|  | 
 | ||||||
|  |     private renderErrorFrom(error: AllI18nKeys) { | ||||||
|  |         return <> | ||||||
|  | 			<AttrInput keyI18n="Common.Attr.Key.Display.Name" disable disableI18n={error}/> | ||||||
|  | 			<AttrInput keyI18n="Common.Attr.Key.Position.X" disable disableI18n={error}/> | ||||||
|  |             <AttrInput keyI18n="Common.Attr.Key.Position.Y" disable disableI18n={error}/> | ||||||
|  |             <AttrInput keyI18n="Common.Attr.Key.Position.Z" disable disableI18n={error}/> | ||||||
|  | 		</> | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private renderFrom(range: Range) { | ||||||
|  |         return <> | ||||||
|  | 			<AttrInput | ||||||
|  |                 keyI18n="Common.Attr.Key.Display.Name" | ||||||
|  |                 value={range.displayName} | ||||||
|  |                 valueChange={(e) => { | ||||||
|  |                     this.props.status ? this.props.status.changeRangeAttrib(range.id, "displayName", e) : null; | ||||||
|  |                 }} | ||||||
|  |             /> | ||||||
|  | 			<AttrInput | ||||||
|  |                 isNumber={true} | ||||||
|  |                 step={.1} | ||||||
|  |                 keyI18n="Common.Attr.Key.Position.X" | ||||||
|  |                 value={range.position[0]} | ||||||
|  |                 valueChange={(e) => { | ||||||
|  |                     if (this.props.status) { | ||||||
|  |                         range.position[0] = (e as any) / 1; | ||||||
|  |                         this.props.status.changeRangeAttrib(range.id, "position", range.position); | ||||||
|  |                     } | ||||||
|  |                 }} | ||||||
|  |             /> | ||||||
|  |             <AttrInput | ||||||
|  |                 keyI18n="Common.Attr.Key.Position.Y" | ||||||
|  |                 value={range.position[1]} | ||||||
|  |                 valueChange={(e) => { | ||||||
|  |                     this.props.status ? this.props.status.changeRangeAttrib(range.id, "displayName", e) : null; | ||||||
|  |                 }} | ||||||
|  |             /> | ||||||
|  |             <AttrInput | ||||||
|  |                 keyI18n="Common.Attr.Key.Position.Z" | ||||||
|  |                 value={range.position[2]} | ||||||
|  |                 valueChange={(e) => { | ||||||
|  |                     this.props.status ? this.props.status.changeRangeAttrib(range.id, "displayName", e) : null; | ||||||
|  |                 }} | ||||||
|  |             /> | ||||||
|  | 		</> | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| 	public render(): ReactNode { | 	public render(): ReactNode { | ||||||
| 		return <div> |         if (this.props.status) { | ||||||
| 			<AttrInput></AttrInput> |             if (this.props.status.focusObject.size <= 0) { | ||||||
| 			<AttrInput isNumber></AttrInput> |                 return this.renderErrorFrom("Panel.Info.Range.Details.Attr.Error.Unspecified"); | ||||||
| 		</div> |             } | ||||||
|  |             if (this.props.status.focusObject.size > 1) { | ||||||
|  |                 return this.renderErrorFrom("Common.Attr.Key.Error.Multiple"); | ||||||
|  |             } | ||||||
|  |             let id: ObjectID = 0; | ||||||
|  |             this.props.status.focusObject.forEach((cid => id = cid)); | ||||||
|  |              | ||||||
|  |             let range = this.props.status!.model.getObjectById(id); | ||||||
|  | 
 | ||||||
|  |             if (range instanceof Range) { | ||||||
|  |                 return this.renderFrom(range); | ||||||
|  |             } else { | ||||||
|  |                 return this.renderErrorFrom("Panel.Info.Range.Details.Attr.Error.Not.Range"); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 		return this.renderErrorFrom("Panel.Info.Range.Details.Attr.Error.Unspecified"); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user