Compare commits
	
		
			No commits in common. "0120a4972dd1138089a69ec5d093051f5f67515f" and "aa8d35e5db5404aadcc90f721dc7e9b98ca6268c" have entirely different histories.
		
	
	
		
			0120a4972d
			...
			aa8d35e5db
		
	
		
| @ -24,10 +24,38 @@ class BoundaryConstraint extends Behavior<IBoundaryConstraintBehaviorParameter, | ||||
|     public override category: string = "$Physics"; | ||||
| 
 | ||||
| 	public override parameterOption = { | ||||
| 		range: { type: "LR", name: "$range" }, | ||||
| 		strength: { type: "number", name: "$Strength", defaultValue: 1, numberMin: 0, numberStep: .1 } | ||||
| 		range: { | ||||
| 			type: "LR", | ||||
| 			name: "$range" | ||||
| 		}, | ||||
| 		strength: { | ||||
| 			type: "number", | ||||
| 			name: "$Strength", | ||||
| 			defaultValue: 1, | ||||
|             numberMin: 0, | ||||
|             numberStep: .1 | ||||
| 		} | ||||
| 	}; | ||||
| 
 | ||||
|     public override terms: Record<string, Record<string, string>> = { | ||||
|         "$Title": { | ||||
|             "ZH_CN": "边界约束", | ||||
|             "EN_US": "Boundary constraint" | ||||
|         }, | ||||
| 		"$range": { | ||||
| 			"ZH_CN": "约束范围", | ||||
| 			"EN_US": "Constraint range" | ||||
| 		}, | ||||
| 		"$Strength": { | ||||
| 			"ZH_CN": "约束强度系数", | ||||
| 			"EN_US": "Restraint strength coefficient" | ||||
| 		}, | ||||
|         "$Intro": { | ||||
|             "ZH_CN": "个体越出边界后将主动返回", | ||||
|             "EN_US": "Individuals will return actively after crossing the border" | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     public effect(individual: Individual, group: Group, model: Model, t: number): void { | ||||
|         let rangeList: Range[] = this.parameter.range.objects; | ||||
| 
 | ||||
| @ -71,25 +99,6 @@ class BoundaryConstraint extends Behavior<IBoundaryConstraintBehaviorParameter, | ||||
| 			fz * this.parameter.strength | ||||
| 		); | ||||
|     } | ||||
| 
 | ||||
| 	public override terms: Record<string, Record<string, string>> = { | ||||
|         "$Title": { | ||||
|             "ZH_CN": "边界约束", | ||||
|             "EN_US": "Boundary constraint" | ||||
|         }, | ||||
| 		"$range": { | ||||
| 			"ZH_CN": "约束范围", | ||||
| 			"EN_US": "Constraint range" | ||||
| 		}, | ||||
| 		"$Strength": { | ||||
| 			"ZH_CN": "约束强度系数", | ||||
| 			"EN_US": "Restraint strength coefficient" | ||||
| 		}, | ||||
|         "$Intro": { | ||||
|             "ZH_CN": "个体越出边界后将主动返回", | ||||
|             "EN_US": "Individuals will return actively after crossing the border" | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| export { BoundaryConstraint }; | ||||
| @ -25,36 +25,37 @@ class Brownian extends Behavior<IBrownianBehaviorParameter, IBrownianBehaviorEve | ||||
| 	public override category: string = "$Physics"; | ||||
| 
 | ||||
| 	public override parameterOption = { | ||||
| 		maxFrequency: { type: "number", name: "$Max.Frequency", defaultValue: 5, numberStep: .1, numberMin: 0 }, | ||||
| 		minFrequency: { type: "number", name: "$Min.Frequency", defaultValue: 0, numberStep: .1, numberMin: 0 }, | ||||
| 		maxStrength: { type: "number", name: "$Max.Strength", defaultValue: 10, numberStep: .01, numberMin: 0 }, | ||||
| 		minStrength: { type: "number", name: "$Min.Strength", defaultValue: 0, numberStep: .01, numberMin: 0 } | ||||
| 		maxFrequency: { | ||||
| 			type: "number", | ||||
| 			name: "$Max.Frequency", | ||||
| 			defaultValue: 5, | ||||
| 			numberStep: .1, | ||||
| 			numberMin: 0 | ||||
| 		}, | ||||
| 		minFrequency: { | ||||
| 			type: "number", | ||||
| 			name: "$Min.Frequency", | ||||
| 			defaultValue: 0, | ||||
| 			numberStep: .1, | ||||
| 			numberMin: 0 | ||||
| 		}, | ||||
| 		maxStrength: { | ||||
| 			type: "number", | ||||
| 			name: "$Max.Strength", | ||||
| 			defaultValue: 10, | ||||
| 			numberStep: .01, | ||||
| 			numberMin: 0 | ||||
| 		}, | ||||
| 		minStrength: { | ||||
| 			type: "number", | ||||
| 			name: "$Min.Strength", | ||||
| 			defaultValue: 0, | ||||
| 			numberStep: .01, | ||||
| 			numberMin: 0 | ||||
| 		} | ||||
| 	}; | ||||
| 
 | ||||
| 	public effect(individual: Individual, group: Group, model: Model, t: number): void { | ||||
| 
 | ||||
| 		const {maxFrequency, minFrequency, maxStrength, minStrength} = this.parameter; | ||||
| 
 | ||||
| 		let nextTime = individual.getData("Brownian.nextTime") ??  | ||||
| 		minFrequency +  Math.random() * (maxFrequency - minFrequency); | ||||
| 		let currentTime = individual.getData("Brownian.currentTime") ?? 0; | ||||
| 		 | ||||
| 		currentTime += t; | ||||
| 		if (currentTime > nextTime) { | ||||
| 			individual.applyForce( | ||||
| 				minStrength + (Math.random() * 2 - 1) * (maxStrength - minStrength), | ||||
| 				minStrength + (Math.random() * 2 - 1) * (maxStrength - minStrength), | ||||
| 				minStrength + (Math.random() * 2 - 1) * (maxStrength - minStrength) | ||||
| 			); | ||||
| 			nextTime = minFrequency +  Math.random() * (maxFrequency - minFrequency); | ||||
| 			currentTime = 0; | ||||
| 		} | ||||
| 
 | ||||
| 		individual.setData("Brownian.nextTime", nextTime); | ||||
| 		individual.setData("Brownian.currentTime", currentTime); | ||||
| 	} | ||||
| 
 | ||||
| 	public override terms: Record<string, Record<string, string>> = { | ||||
|     public override terms: Record<string, Record<string, string>> = { | ||||
|         "$Title": { | ||||
|             "ZH_CN": "布朗运动", | ||||
|             "EN_US": "Brownian motion" | ||||
| @ -80,6 +81,29 @@ class Brownian extends Behavior<IBrownianBehaviorParameter, IBrownianBehaviorEve | ||||
|             "EN_US": "Minimum strength" | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
| 	public effect(individual: Individual, group: Group, model: Model, t: number): void { | ||||
| 
 | ||||
| 		const {maxFrequency, minFrequency, maxStrength, minStrength} = this.parameter; | ||||
| 
 | ||||
| 		let nextTime = individual.getData("Brownian.nextTime") ??  | ||||
| 		minFrequency +  Math.random() * (maxFrequency - minFrequency); | ||||
| 		let currentTime = individual.getData("Brownian.currentTime") ?? 0; | ||||
| 		 | ||||
| 		currentTime += t; | ||||
| 		if (currentTime > nextTime) { | ||||
| 			individual.applyForce( | ||||
| 				minStrength + (Math.random() * 2 - 1) * (maxStrength - minStrength), | ||||
| 				minStrength + (Math.random() * 2 - 1) * (maxStrength - minStrength), | ||||
| 				minStrength + (Math.random() * 2 - 1) * (maxStrength - minStrength) | ||||
| 			); | ||||
| 			nextTime = minFrequency +  Math.random() * (maxFrequency - minFrequency); | ||||
| 			currentTime = 0; | ||||
| 		} | ||||
| 
 | ||||
| 		individual.setData("Brownian.nextTime", nextTime); | ||||
| 		individual.setData("Brownian.currentTime", currentTime); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| export { Brownian }; | ||||
| @ -25,12 +25,67 @@ class Dynamics extends Behavior<IDynamicsBehaviorParameter, IDynamicsBehaviorEve | ||||
| 	public override category: string = "$Physics"; | ||||
| 
 | ||||
| 	public override parameterOption = { | ||||
| 		mass: { name: "$Mass", type: "number", defaultValue: 1, numberStep: .01, numberMin: .001 }, | ||||
| 		maxAcceleration: { name: "$Max.Acceleration", type: "number", defaultValue: 5, numberStep: .1, numberMin: 0 }, | ||||
| 		maxVelocity: { name: "$Max.Velocity", type: "number", defaultValue: 10, numberStep: .1, numberMin: 0 }, | ||||
| 		resistance: { name: "$Resistance", type: "number", defaultValue: 0.5, numberStep: .1, numberMin: 0 } | ||||
| 		mass: { | ||||
| 			name: "$Mass", | ||||
| 			type: "number", | ||||
| 			defaultValue: 1, | ||||
| 			numberStep: .01, | ||||
| 			numberMin: .001 | ||||
| 		}, | ||||
| 		maxAcceleration: { | ||||
| 			name: "$Max.Acceleration", | ||||
| 			type: "number", | ||||
| 			defaultValue: 5, | ||||
| 			numberStep: .1, | ||||
| 			numberMin: 0 | ||||
| 		}, | ||||
| 		maxVelocity: { | ||||
| 			name: "$Max.Velocity", | ||||
| 			type: "number", | ||||
| 			defaultValue: 10, | ||||
| 			numberStep: .1, | ||||
| 			numberMin: 0 | ||||
| 		}, | ||||
| 		resistance: { | ||||
| 			name: "$Resistance", | ||||
| 			type: "number", | ||||
| 			defaultValue: 0.5, | ||||
| 			numberStep: .1, | ||||
| 			numberMin: 0 | ||||
| 		} | ||||
| 	}; | ||||
| 
 | ||||
|     public override terms: Record<string, Record<string, string>> = { | ||||
|         "$Title": { | ||||
|             "ZH_CN": "动力学", | ||||
|             "EN_US": "Dynamics" | ||||
|         }, | ||||
|         "$Intro": { | ||||
|             "ZH_CN": "一切可以运动物体的必要行为,执行物理法则。", | ||||
|             "EN_US": "All necessary behaviors that can move objects and implement the laws of physics." | ||||
|         }, | ||||
| 		"$Mass": { | ||||
| 			"ZH_CN": "质量 (Kg)", | ||||
|             "EN_US": "Mass (Kg)" | ||||
| 		}, | ||||
| 		"$Max.Acceleration": { | ||||
| 			"ZH_CN": "最大加速度 (m/s²)", | ||||
|             "EN_US": "Maximum acceleration (m/s²)" | ||||
| 		}, | ||||
| 		"$Max.Velocity": { | ||||
| 			"ZH_CN": "最大速度 (m/s)", | ||||
|             "EN_US": "Maximum velocity (m/s)" | ||||
| 		}, | ||||
| 		"$Resistance": { | ||||
| 			"ZH_CN": "阻力系数", | ||||
| 			"EN_US": "Resistance coefficient" | ||||
| 		}, | ||||
| 		"$Physics": { | ||||
| 			"ZH_CN": "物理", | ||||
|             "EN_US": "Physics" | ||||
| 		} | ||||
|     }; | ||||
| 
 | ||||
| 	public override finalEffect(individual: Individual, group: Group, model: Model, t: number): void { | ||||
| 
 | ||||
| 		// 计算当前速度
 | ||||
| @ -84,37 +139,6 @@ class Dynamics extends Behavior<IDynamicsBehaviorParameter, IDynamicsBehaviorEve | ||||
| 		individual.force[1] = 0; | ||||
| 		individual.force[2] = 0; | ||||
| 	}; | ||||
| 	 | ||||
|     public override terms: Record<string, Record<string, string>> = { | ||||
|         "$Title": { | ||||
|             "ZH_CN": "动力学", | ||||
|             "EN_US": "Dynamics" | ||||
|         }, | ||||
|         "$Intro": { | ||||
|             "ZH_CN": "一切可以运动物体的必要行为,执行物理法则。", | ||||
|             "EN_US": "All necessary behaviors that can move objects and implement the laws of physics." | ||||
|         }, | ||||
| 		"$Mass": { | ||||
| 			"ZH_CN": "质量 (Kg)", | ||||
|             "EN_US": "Mass (Kg)" | ||||
| 		}, | ||||
| 		"$Max.Acceleration": { | ||||
| 			"ZH_CN": "最大加速度 (m/s²)", | ||||
|             "EN_US": "Maximum acceleration (m/s²)" | ||||
| 		}, | ||||
| 		"$Max.Velocity": { | ||||
| 			"ZH_CN": "最大速度 (m/s)", | ||||
|             "EN_US": "Maximum velocity (m/s)" | ||||
| 		}, | ||||
| 		"$Resistance": { | ||||
| 			"ZH_CN": "阻力系数", | ||||
| 			"EN_US": "Resistance coefficient" | ||||
| 		}, | ||||
| 		"$Physics": { | ||||
| 			"ZH_CN": "物理", | ||||
|             "EN_US": "Physics" | ||||
| 		} | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| export { Dynamics }; | ||||
| @ -7,8 +7,6 @@ type ITemplateBehaviorParameter = { | ||||
|     testNumber: "number"; | ||||
|     testString: "string"; | ||||
|     testBoolean: "boolean"; | ||||
|     testColor: "color"; | ||||
|     testOption: "option"; | ||||
|     testR: "R"; | ||||
|     testG: "G"; | ||||
|     testLR: "LR"; | ||||
| @ -31,24 +29,52 @@ class Template extends Behavior<ITemplateBehaviorParameter, ITemplateBehaviorEve | ||||
|     public override category: string = "$Category"; | ||||
| 
 | ||||
|     public override parameterOption = { | ||||
|         testNumber: { name: "$Test", type: "number", defaultValue: 1, numberMax: 10, numberMin: 0, numberStep: 1 }, | ||||
|         testString: { name: "$Test", type: "string", defaultValue: "default", maxLength: 12 }, | ||||
|         testColor: { name: "$Test", type: "color", defaultValue: [.5, .1, 1], colorNormal: true }, | ||||
|         testOption: { name: "$Test", type: "option", defaultValue: "T", allOption: [ | ||||
|             { key: "P", name: "$Test"}, { key: "T", name: "$Title"} | ||||
|         ]}, | ||||
|         testBoolean: { name: "$Test", type: "boolean", defaultValue: false, iconName: "Send" }, | ||||
|         testR: { name: "$Test", type: "R" }, | ||||
|         testG: { name: "$Test", type: "G" }, | ||||
|         testLR: { name: "$Test", type: "LR" }, | ||||
|         testLG: { name: "$Test", type: "LG" }, | ||||
|         testVec: { name: "$Test", type: "vec", defaultValue: [1, 2, 3], numberMax: 10, numberMin: 0, numberStep: 1 } | ||||
|         testNumber: { | ||||
|             name: "$Test", | ||||
|             type: "number", | ||||
|             defaultValue: 1, | ||||
|             numberMax: 10, | ||||
|             numberMin: 0, | ||||
|             numberStep: 1 | ||||
|         }, | ||||
|         testString: { | ||||
|             name: "$Test", | ||||
|             type: "string", | ||||
|             defaultValue: "default", | ||||
|             maxLength: 12 | ||||
|         }, | ||||
|         testBoolean: { | ||||
|             name: "$Test", | ||||
|             type: "boolean", | ||||
|             defaultValue: false, | ||||
|             iconName: "Send" | ||||
|         }, | ||||
|         testR: { | ||||
|             name: "$Test", | ||||
|             type: "R" | ||||
|         }, | ||||
|         testG: { | ||||
|             name: "$Test", | ||||
|             type: "G" | ||||
|         }, | ||||
|         testLR: { | ||||
|             name: "$Test", | ||||
|             type: "LR" | ||||
|         }, | ||||
|         testLG: { | ||||
|             name: "$Test", | ||||
|             type: "LG" | ||||
|         }, | ||||
|         testVec: { | ||||
|             name: "$Test", | ||||
|             type: "vec", | ||||
|             defaultValue: [1, 2, 3], | ||||
|             numberMax: 10, | ||||
|             numberMin: 0, | ||||
|             numberStep: 1 | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     public effect(individual: Individual, group: Group, model: Model, t: number): void { | ||||
|          | ||||
|     } | ||||
| 
 | ||||
|     public override terms: Record<string, Record<string, string>> = { | ||||
|         "$Title": { | ||||
|             "ZH_CN": "行为", | ||||
| @ -61,12 +87,12 @@ class Template extends Behavior<ITemplateBehaviorParameter, ITemplateBehaviorEve | ||||
|         "$Test": { | ||||
|             "ZH_CN": "测试参数", | ||||
|             "EN_US": "Test Parameter" | ||||
|         }, | ||||
|         "$Category": { | ||||
|             "ZH_CN": "测序模板", | ||||
|             "EN_US": "Test template" | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     public effect(individual: Individual, group: Group, model: Model, t: number): void { | ||||
|          | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export { Template }; | ||||
| @ -145,10 +145,10 @@ class BehaviorPicker extends Component<IBehaviorPickerProps & IMixinSettingProps | ||||
| 
 | ||||
|     private renderPickerList(): ReactNode { | ||||
|         return <PickerList | ||||
|             item={this.getAllData()} | ||||
|             objectList={this.getAllData()} | ||||
|             noData="Behavior.Picker.Add.Nodata" | ||||
|             target={this.clickLineRef} | ||||
|             click={((item) => { | ||||
|             clickObjectItems={((item) => { | ||||
|                 if (item instanceof Behavior && this.props.add) { | ||||
|                     this.props.add(item); | ||||
|                 } | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| import { Component, createRef, ReactNode } from "react"; | ||||
| import { Icon } from "@fluentui/react"; | ||||
| import { ComboList, IDisplayItem } from "@Input/ComboList/ComboList"; | ||||
| import { PickerList, IDisplayItem } from "@Input/PickerList/PickerList"; | ||||
| import { TextField, ITextFieldProps } from "@Input/TextField/TextField"; | ||||
| import { Localization } from "@Component/Localization/Localization"; | ||||
| import "./ComboInput.scss"; | ||||
| @ -26,11 +26,13 @@ class ComboInput extends Component<IComboInputProps, IComboInputState> { | ||||
|     private pickerTarget = createRef<HTMLDivElement>(); | ||||
| 
 | ||||
|     private renderPicker() { | ||||
|         return <ComboList | ||||
|         return <PickerList | ||||
|             target={this.pickerTarget} | ||||
|             item={this.props.allOption ?? []} | ||||
|             focus={this.props.value} | ||||
|             click={((item) => { | ||||
|             displayItems={(this.props.allOption ?? []).map((item) => { | ||||
|                 return item.key === this.props.value?.key ?  | ||||
|                     {...item, mark: true} : item; | ||||
|             })} | ||||
|             clickDisplayItems={((item) => { | ||||
|                 if (this.props.valueChange) { | ||||
|                     this.props.valueChange(item); | ||||
|                 } | ||||
| @ -62,8 +64,8 @@ class ComboInput extends Component<IComboInputProps, IComboInputState> { | ||||
|                 <div className="value-view"> | ||||
|                     { | ||||
|                         this.props.value ?  | ||||
|                             <Localization i18nKey={this.props.value.i18n} options={this.props.value.i18nOption}/> : | ||||
|                             <Localization i18nKey="Input.Error.Combo"/> | ||||
|                         <Localization i18nKey={this.props.value.nameKey}/> : | ||||
|                         null | ||||
|                     } | ||||
|                 </div> | ||||
|                 <div className="list-button"> | ||||
|  | ||||
| @ -1 +0,0 @@ | ||||
| @import "../PickerList/PickerList.scss"; | ||||
| @ -1,71 +0,0 @@ | ||||
| import { AllI18nKeys, Localization } from "@Component/Localization/Localization"; | ||||
| import { Callout, DirectionalHint, Icon } from "@fluentui/react"; | ||||
| import { Component, ReactNode, RefObject } from "react"; | ||||
| import "./ComboList.scss"; | ||||
| 
 | ||||
| interface IDisplayItem { | ||||
| 	i18nOption?: Record<string, string>; | ||||
|     i18n: AllI18nKeys; | ||||
|     key: string; | ||||
| } | ||||
| 
 | ||||
| interface IComboListProps { | ||||
| 	target?: RefObject<any>; | ||||
|     item: IDisplayItem[]; | ||||
| 	focus?: IDisplayItem; | ||||
|     noData?: AllI18nKeys; | ||||
| 	dismiss?: () => any; | ||||
| 	click?: (item: IDisplayItem) => any; | ||||
| } | ||||
| 
 | ||||
| class ComboList extends Component<IComboListProps> { | ||||
| 
 | ||||
|     private renderString(item: IDisplayItem) { | ||||
| 
 | ||||
| 		const isFocus = item.key === this.props.focus?.key; | ||||
| 
 | ||||
|         return <div | ||||
| 			className="picker-list-item" | ||||
| 			key={item.key} | ||||
| 			onClick={() => { | ||||
| 				if (this.props.click) { | ||||
| 					this.props.click(item) | ||||
| 				} | ||||
| 			}} | ||||
| 		> | ||||
| 			<div className="list-item-icon"> | ||||
| 				<Icon | ||||
| 					iconName="CheckMark" | ||||
| 					style={{ | ||||
| 						display: isFocus ? "block" : "none" | ||||
| 					}} | ||||
| 				/> | ||||
| 			</div> | ||||
| 			<div className="list-item-name"> | ||||
| 				<Localization i18nKey={item.i18n} options={item.i18nOption}/> | ||||
| 			</div> | ||||
| 		</div>; | ||||
|     } | ||||
| 
 | ||||
| 	public render(): ReactNode { | ||||
| 		return <Callout | ||||
| 			onDismiss={this.props.dismiss} | ||||
| 			target={this.props.target} | ||||
| 			directionalHint={DirectionalHint.topCenter} | ||||
| 		> | ||||
| 			<div className="picker-list-root"> | ||||
|                 { this.props.item.map((item) => this.renderString(item)) } | ||||
| 				{ | ||||
|                     this.props.item.length <= 0 ? | ||||
|                         <Localization | ||||
|                             className="picker-list-nodata" | ||||
|                             i18nKey={this.props.noData ?? "Common.No.Data"} | ||||
|                         /> | ||||
|                         : null | ||||
| 				} | ||||
| 			</div> | ||||
| 		</Callout> | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| export { ComboList, IDisplayItem } | ||||
| @ -48,13 +48,13 @@ class LabelPicker extends Component<ILabelPickerProps & IMixinStatusProps, ILabe | ||||
|     private renderPicker() { | ||||
|         return <PickerList | ||||
|             noData="Common.Attr.Key.Label.Picker.Nodata" | ||||
|             item={this.getOtherLabel()} | ||||
|             objectList={this.getOtherLabel()} | ||||
|             dismiss={() => { | ||||
|                 this.setState({ | ||||
|                     isPickerVisible: false | ||||
|                 }); | ||||
|             }} | ||||
|             click={(label) => { | ||||
|             clickObjectItems={(label) => { | ||||
|                 if (label instanceof Label && this.props.labelAdd) { | ||||
|                     this.props.labelAdd(label) | ||||
|                 } | ||||
|  | ||||
| @ -6,7 +6,7 @@ import { Range } from "@Model/Range"; | ||||
| import { CtrlObject } from "@Model/CtrlObject"; | ||||
| import { Behavior } from "@Model/Behavior"; | ||||
| import { TextField, ITextFieldProps } from "@Input/TextField/TextField"; | ||||
| import { PickerList, getObjectDisplayInfo, IDisplayInfo } from "@Input/PickerList/PickerList"; | ||||
| import { PickerList, IDisplayItem, getObjectDisplayInfo, IDisplayInfo } from "@Input/PickerList/PickerList"; | ||||
| import { Localization } from "@Component/Localization/Localization"; | ||||
| import { Icon } from "@fluentui/react"; | ||||
| import "./ObjectPicker.scss"; | ||||
| @ -79,8 +79,8 @@ class ObjectPicker extends Component<IObjectPickerProps & IMixinStatusProps, IOb | ||||
|         return <PickerList | ||||
|             noData="Object.Picker.List.No.Data" | ||||
|             target={this.pickerTarget} | ||||
|             item={this.getAllOption()} | ||||
|             click={((item) => { | ||||
|             objectList={this.getAllOption()} | ||||
|             clickObjectItems={((item) => { | ||||
|                 if (item instanceof Behavior) return; | ||||
|                 if (this.props.valueChange) { | ||||
|                     this.props.valueChange(item); | ||||
| @ -166,4 +166,4 @@ class ObjectPicker extends Component<IObjectPickerProps & IMixinStatusProps, IOb | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export { ObjectPicker }; | ||||
| export { ObjectPicker, IDisplayItem }; | ||||
| @ -4,10 +4,8 @@ import { AttrInput } from "@Input/AttrInput/AttrInput"; | ||||
| import { ObjectID } from "@Model/Renderer"; | ||||
| import { TogglesInput } from "@Input/TogglesInput/TogglesInput"; | ||||
| import { ObjectPicker } from "@Input/ObjectPicker/ObjectPicker"; | ||||
| import { AllI18nKeys, I18N } from "@Component/Localization/Localization"; | ||||
| import { AllI18nKeys } from "@Component/Localization/Localization"; | ||||
| import { Message } from "@Input/Message/Message"; | ||||
| import { ColorInput } from "@Input/ColorInput/ColorInput"; | ||||
| import { ComboInput, IDisplayItem } from "@Input/ComboInput/ComboInput"; | ||||
| import { | ||||
|     IParameter, IParameterOption, IParameterOptionItem, | ||||
|     IParameterValue, IParamValue, isObjectType, isVectorType | ||||
| @ -19,7 +17,7 @@ interface IParameterProps<P extends IParameter = {}> { | ||||
|     value: IParameterValue<P>; | ||||
|     key: ObjectID; | ||||
|     change: <K extends keyof P>(key: K, val: IParamValue<P[K]>) => any; | ||||
|     i18n?: (key: string, language: Language) => string; | ||||
|     i18n: <K extends keyof P>(option: IParameterOptionItem<P[K]>, language: Language) => string; | ||||
|     title?: AllI18nKeys; | ||||
|     titleOption?: Record<string, string>; | ||||
|     isFirst?: boolean; | ||||
| @ -31,29 +29,16 @@ class Parameter<P extends IParameter> extends Component<IParameterProps<P> & IMi | ||||
|     private renderParameter<K extends keyof P> | ||||
|     (key: K, option: IParameterOptionItem<P[K]>, value: IParamValue<P[K]>): ReactNode { | ||||
| 
 | ||||
|         const language = this.props.setting?.language ?? "EN_US"; | ||||
|         const indexKey = `${this.props.key}-${key}`; | ||||
|         const type = option.type; | ||||
|         let keyI18n: string, keyI18nOption: Record<string, string> | undefined; | ||||
| 
 | ||||
|         // Custom I18N
 | ||||
|         if (this.props.i18n) { | ||||
|             keyI18n = "Panel.Info.Behavior.Details.Parameter.Key"; | ||||
|             keyI18nOption = { | ||||
|                 key: this.props.i18n(option.name, language) | ||||
|             }; | ||||
|         } | ||||
|          | ||||
|         else { | ||||
|             keyI18n = option.name; | ||||
|         } | ||||
|         const i18nString = this.props.i18n(option, this.props.setting?.language ?? "EN_US"); | ||||
| 
 | ||||
|         if (type === "number") { | ||||
|             return <AttrInput | ||||
|                 key={indexKey} | ||||
|                 id={indexKey} | ||||
|                 keyI18n={keyI18n} | ||||
|                 keyI18nOption={keyI18nOption} | ||||
|                 keyI18n="Panel.Info.Behavior.Details.Parameter.Key" | ||||
|                 keyI18nOption={{ key: i18nString }} | ||||
|                 isNumber={true} | ||||
|                 step={option.numberStep} | ||||
|                 maxLength={option.maxLength} | ||||
| @ -70,8 +55,8 @@ class Parameter<P extends IParameter> extends Component<IParameterProps<P> & IMi | ||||
|             return <AttrInput | ||||
|                 key={indexKey} | ||||
|                 id={indexKey} | ||||
|                 keyI18n={keyI18n} | ||||
|                 keyI18nOption={keyI18nOption} | ||||
|                 keyI18n="Panel.Info.Behavior.Details.Parameter.Key" | ||||
|                 keyI18nOption={{ key: i18nString }} | ||||
|                 maxLength={option.maxLength} | ||||
|                 value={value as IParamValue<"string"> ?? ""} | ||||
|                 valueChange={(val) => { | ||||
| @ -83,10 +68,9 @@ class Parameter<P extends IParameter> extends Component<IParameterProps<P> & IMi | ||||
|         else if (type === "boolean") { | ||||
|             return <TogglesInput | ||||
|                 key={indexKey} | ||||
|                 keyI18n={keyI18n} | ||||
|                 keyI18nOption={keyI18nOption} | ||||
|                 keyI18n="Panel.Info.Behavior.Details.Parameter.Key" | ||||
|                 keyI18nOption={{ key: i18nString }} | ||||
| 				onIconName={option.iconName} | ||||
|                 red={option.iconRed} | ||||
|                 value={value as IParamValue<"boolean"> ?? false} | ||||
| 				valueChange={(val) => { | ||||
| 					this.props.change(key, val as IParamValue<P[K]>); | ||||
| @ -101,8 +85,8 @@ class Parameter<P extends IParameter> extends Component<IParameterProps<P> & IMi | ||||
| 
 | ||||
|             return <ObjectPicker | ||||
|                 key={indexKey} | ||||
|                 keyI18n={keyI18n} | ||||
|                 keyI18nOption={keyI18nOption} | ||||
|                 keyI18n="Panel.Info.Behavior.Details.Parameter.Key" | ||||
|                 keyI18nOption={{ key: i18nString }} | ||||
|                 type={type} | ||||
|                 value={typedValue.picker} | ||||
|                 valueChange={(obj) => { | ||||
| @ -116,66 +100,10 @@ class Parameter<P extends IParameter> extends Component<IParameterProps<P> & IMi | ||||
|             /> | ||||
|         } | ||||
| 
 | ||||
|         else if (type === "color") { | ||||
| 
 | ||||
|             return <ColorInput | ||||
|                 key={indexKey} | ||||
|                 keyI18n={keyI18n} | ||||
|                 keyI18nOption={keyI18nOption} | ||||
|                 normal={option.colorNormal} | ||||
|                 value={value as IParamValue<"color"> ?? false} | ||||
|                 valueChange={(val) => { | ||||
| 					this.props.change(key, val as IParamValue<P[K]>); | ||||
| 				}} | ||||
|             /> | ||||
|         } | ||||
| 
 | ||||
|         else if (type === "option") { | ||||
| 
 | ||||
|             let allOption: IDisplayItem[] = []; | ||||
|             let focusKey: number = -1; | ||||
| 
 | ||||
|             if (option.allOption) { | ||||
|                 for (let i = 0; i < option.allOption.length; i++) { | ||||
| 
 | ||||
|                     if (this.props.i18n) { | ||||
|                         allOption.push({ | ||||
|                             i18nOption: { key: this.props.i18n(option.allOption[i].name, language) }, | ||||
|                             i18n: "Panel.Info.Behavior.Details.Parameter.Key", | ||||
|                             key: option.allOption[i].key | ||||
|                         }) | ||||
|                     } | ||||
|                      | ||||
|                     else { | ||||
|                         allOption.push({ | ||||
|                             i18n: option.allOption[i].name, | ||||
|                             key: option.allOption[i].key | ||||
|                         }) | ||||
|                     } | ||||
| 
 | ||||
|                     if (option.allOption[i].key === value) { | ||||
|                         focusKey = i; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             return <ComboInput | ||||
|                 key={indexKey} | ||||
|                 keyI18n={keyI18n} | ||||
|                 keyI18nOption={keyI18nOption} | ||||
|                 allOption={allOption} | ||||
|                 value={allOption[focusKey]} | ||||
|                 valueChange={(val) => { | ||||
|                     this.props.change(key, val.key as IParamValue<P[K]>); | ||||
|                 }} | ||||
|             /> | ||||
|         } | ||||
| 
 | ||||
|         else if (type === "vec") { | ||||
|         else if (isVectorType(type)) { | ||||
| 
 | ||||
|             type IObjectParamValue = IParamValue<"vec">; | ||||
|             const typedValue = value as IObjectParamValue; | ||||
|             const i18nVal = I18N(this.props, keyI18n, keyI18nOption); | ||||
|              | ||||
|             return <Fragment key={indexKey}> | ||||
|                  | ||||
| @ -183,7 +111,7 @@ class Parameter<P extends IParameter> extends Component<IParameterProps<P> & IMi | ||||
|                     key={`${indexKey}-X`} | ||||
|                     id={indexKey} | ||||
|                     keyI18n="Panel.Info.Behavior.Details.Parameter.Key.Vec.X" | ||||
|                     keyI18nOption={{ key: i18nVal }} | ||||
|                     keyI18nOption={{ key: i18nString }} | ||||
|                     isNumber={true} | ||||
|                     step={option.numberStep} | ||||
|                     maxLength={option.maxLength} | ||||
| @ -200,7 +128,7 @@ class Parameter<P extends IParameter> extends Component<IParameterProps<P> & IMi | ||||
|                     key={`${indexKey}-Y`} | ||||
|                     id={indexKey} | ||||
|                     keyI18n="Panel.Info.Behavior.Details.Parameter.Key.Vec.Y" | ||||
|                     keyI18nOption={{ key: i18nVal }} | ||||
|                     keyI18nOption={{ key: i18nString }} | ||||
|                     isNumber={true} | ||||
|                     step={option.numberStep} | ||||
|                     maxLength={option.maxLength} | ||||
| @ -217,7 +145,7 @@ class Parameter<P extends IParameter> extends Component<IParameterProps<P> & IMi | ||||
|                     key={`${indexKey}-Z`} | ||||
|                     id={indexKey} | ||||
|                     keyI18n="Panel.Info.Behavior.Details.Parameter.Key.Vec.Z" | ||||
|                     keyI18nOption={{ key: i18nVal }} | ||||
|                     keyI18nOption={{ key: i18nString }} | ||||
|                     isNumber={true} | ||||
|                     step={option.numberStep} | ||||
|                     maxLength={option.maxLength} | ||||
|  | ||||
| @ -17,6 +17,12 @@ interface IDisplayInfo { | ||||
|     allLabel: boolean; | ||||
| }; | ||||
| 
 | ||||
| interface IDisplayItem { | ||||
|     nameKey: AllI18nKeys; | ||||
|     key: string; | ||||
| 	mark?: boolean; | ||||
| } | ||||
| 
 | ||||
| function getObjectDisplayInfo(item?: IPickerListItem): IDisplayInfo { | ||||
| 
 | ||||
|     if (!item) { | ||||
| @ -92,11 +98,13 @@ function getObjectDisplayInfo(item?: IPickerListItem): IDisplayInfo { | ||||
| } | ||||
| 
 | ||||
| interface IPickerListProps { | ||||
| 	item: IPickerListItem[]; | ||||
|     displayItems?: IDisplayItem[]; | ||||
| 	objectList?: IPickerListItem[]; | ||||
| 	target?: RefObject<any>; | ||||
|     noData?: AllI18nKeys; | ||||
| 	dismiss?: () => any; | ||||
| 	click?: (item: IPickerListItem) => any; | ||||
| 	clickObjectItems?: (item: IPickerListItem) => any; | ||||
|     clickDisplayItems?: (item: IDisplayItem) => any; | ||||
| } | ||||
| 
 | ||||
| class PickerList extends Component<IPickerListProps> { | ||||
| @ -108,8 +116,8 @@ class PickerList extends Component<IPickerListProps> { | ||||
| 			className="picker-list-item" | ||||
| 			key={item.id} | ||||
| 			onClick={() => { | ||||
| 				if (this.props.click) { | ||||
| 					this.props.click(item) | ||||
| 				if (this.props.clickObjectItems) { | ||||
| 					this.props.clickObjectItems(item) | ||||
| 				} | ||||
| 			}} | ||||
| 		> | ||||
| @ -135,6 +143,27 @@ class PickerList extends Component<IPickerListProps> { | ||||
| 		</div>; | ||||
| 	} | ||||
| 
 | ||||
|     private renderString(item: IDisplayItem) { | ||||
|         return <div | ||||
| 			className="picker-list-item" | ||||
| 			key={item.key} | ||||
| 			onClick={() => { | ||||
| 				if (this.props.clickDisplayItems) { | ||||
| 					this.props.clickDisplayItems(item) | ||||
| 				} | ||||
| 			}} | ||||
| 		> | ||||
| 			<div className="list-item-icon"> | ||||
| 				<Icon iconName="CheckMark" style={{ | ||||
| 					display: item.mark ? "block" : "none" | ||||
| 				}}/> | ||||
| 			</div> | ||||
| 			<div className="list-item-name"> | ||||
| 				<Localization i18nKey={item.nameKey}/> | ||||
| 			</div> | ||||
| 		</div>; | ||||
|     } | ||||
| 
 | ||||
| 	public render(): ReactNode { | ||||
| 		return <Callout | ||||
| 			onDismiss={this.props.dismiss} | ||||
| @ -142,11 +171,18 @@ class PickerList extends Component<IPickerListProps> { | ||||
| 			directionalHint={DirectionalHint.topCenter} | ||||
| 		> | ||||
| 			<div className="picker-list-root"> | ||||
| 				{this.props.objectList ? this.props.objectList.map((item) => { | ||||
| 					return this.renderItem(item); | ||||
| 				}) : null} | ||||
|                 {this.props.displayItems ? this.props.displayItems.map((item) => { | ||||
| 					return this.renderString(item); | ||||
| 				}) : null} | ||||
| 				{ | ||||
| 					this.props.item.map((item) => this.renderItem(item)) | ||||
| 				} | ||||
| 				{ | ||||
|                     this.props.item.length <= 0 ? | ||||
|                     !(this.props.objectList || this.props.displayItems) ||  | ||||
|                     !( | ||||
|                         this.props.objectList && this.props.objectList.length > 0 ||  | ||||
|                         this.props.displayItems && this.props.displayItems.length > 0 | ||||
|                     ) ? | ||||
|                         <Localization | ||||
|                             className="picker-list-nodata" | ||||
|                             i18nKey={this.props.noData ?? "Common.No.Data"} | ||||
| @ -158,4 +194,4 @@ class PickerList extends Component<IPickerListProps> { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| export { PickerList, IDisplayInfo, getObjectDisplayInfo } | ||||
| export { PickerList, IDisplayItem, IDisplayInfo, getObjectDisplayInfo } | ||||
| @ -25,7 +25,6 @@ const EN_US = { | ||||
|     "Input.Error.Length": "The length of the input content must be less than {num}", | ||||
|     "Input.Error.Length.Less": "The length of the input content must be greater than {num}", | ||||
|     "Input.Error.Select": "Select object ...", | ||||
|     "Input.Error.Combo": "Select options ...", | ||||
|     "Object.List.New.Group": "Group object {id}", | ||||
|     "Object.List.New.Range": "Range object {id}", | ||||
|     "Object.List.New.Label": "Label {id}", | ||||
|  | ||||
| @ -25,7 +25,6 @@ const ZH_CN = { | ||||
|     "Input.Error.Length": "输入内容长度须小于 {number}", | ||||
|     "Input.Error.Length.Less": "输入内容长度须大于 {number}", | ||||
|     "Input.Error.Select": "选择对象 ...", | ||||
|     "Input.Error.Combo": "选择选项 ...", | ||||
|     "Object.List.New.Group": "群对象 {id}", | ||||
|     "Object.List.New.Range": "范围对象 {id}", | ||||
|     "Object.List.New.Label": "标签 {id}", | ||||
|  | ||||
| @ -14,7 +14,6 @@ type IMapBasicParamTypeKeyToType = { | ||||
|     "number": number; | ||||
|     "string": string; | ||||
|     "boolean": boolean; | ||||
|     "option": string; | ||||
| } | ||||
| 
 | ||||
| type IMapObjectParamTypeKeyToType = { | ||||
| @ -26,7 +25,6 @@ type IMapObjectParamTypeKeyToType = { | ||||
| 
 | ||||
| type IMapVectorParamTypeKeyToType = { | ||||
|     "vec": number[]; | ||||
|     "color": number[]; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
| @ -102,21 +100,6 @@ interface IParameterOptionItem<T extends IParamType = IParamType> { | ||||
|      * 图标名字 | ||||
|      */ | ||||
|     iconName?: string; | ||||
| 
 | ||||
|     /** | ||||
|      * 图标是否显示为红色 | ||||
|      */ | ||||
|     iconRed?: boolean; | ||||
| 
 | ||||
|     /** | ||||
|      * 颜色是否进行归一化 | ||||
|      */ | ||||
|     colorNormal?: boolean; | ||||
| 
 | ||||
|     /** | ||||
|      * 全部选项 | ||||
|      */ | ||||
|     allOption?: Array<{key: string, name: string}>; | ||||
| } | ||||
| 
 | ||||
| interface IParameter { | ||||
|  | ||||
| @ -65,7 +65,7 @@ class BehaviorDetails extends Component<IBehaviorDetailsProps & IMixinStatusProp | ||||
|                 key={behavior.id} | ||||
|                 option={behavior.parameterOption} | ||||
|                 value={behavior.parameter} | ||||
|                 i18n={(name, language) => behavior.getTerms(name, language)} | ||||
|                 i18n={(option, language) => behavior.getTerms(option.name, language)} | ||||
|                 title={"Panel.Info.Behavior.Details.Behavior.Props"} | ||||
|                 titleOption={{ | ||||
|                     behavior: behavior.getTerms(behavior.behaviorName, this.props.setting?.language) | ||||
|  | ||||
| @ -22,8 +22,8 @@ mapGenModToI18nKey.set(GenMod.Point, "Common.Attr.Key.Generation.Mod.Point"); | ||||
| mapGenModToI18nKey.set(GenMod.Range, "Common.Attr.Key.Generation.Mod.Range"); | ||||
| 
 | ||||
| const allOption: IDisplayItem[] = [ | ||||
|     {i18n: "Common.Attr.Key.Generation.Mod.Point", key: GenMod.Point}, | ||||
|     {i18n: "Common.Attr.Key.Generation.Mod.Range", key: GenMod.Range} | ||||
|     {nameKey: "Common.Attr.Key.Generation.Mod.Point", key: GenMod.Point}, | ||||
|     {nameKey: "Common.Attr.Key.Generation.Mod.Range", key: GenMod.Range} | ||||
| ]; | ||||
| 
 | ||||
| @useSetting | ||||
| @ -144,7 +144,7 @@ class GroupDetails extends Component<IGroupDetailsProps & IMixinStatusProps & IM | ||||
|             <ComboInput | ||||
|                 keyI18n="Common.Attr.Key.Generation.Mod" | ||||
|                 value={{ | ||||
|                     i18n: mapGenModToI18nKey.get(group.genMethod) ?? "Common.No.Data", | ||||
|                     nameKey: mapGenModToI18nKey.get(group.genMethod) ?? "Common.No.Data", | ||||
|                     key: group.genMethod | ||||
|                 }} | ||||
|                 allOption={allOption} | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user