Add combo input & color into parameter #37

Merged
MrKBear merged 4 commits from dev-mrkbear into master 2022-04-08 22:13:30 +08:00
17 changed files with 312 additions and 270 deletions

View File

@ -24,38 +24,10 @@ class BoundaryConstraint extends Behavior<IBoundaryConstraintBehaviorParameter,
public override category: string = "$Physics"; public override category: string = "$Physics";
public override parameterOption = { public override parameterOption = {
range: { range: { type: "LR", name: "$range" },
type: "LR", strength: { type: "number", name: "$Strength", defaultValue: 1, numberMin: 0, numberStep: .1 }
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 { public effect(individual: Individual, group: Group, model: Model, t: number): void {
let rangeList: Range[] = this.parameter.range.objects; let rangeList: Range[] = this.parameter.range.objects;
@ -99,6 +71,25 @@ class BoundaryConstraint extends Behavior<IBoundaryConstraintBehaviorParameter,
fz * this.parameter.strength 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 }; export { BoundaryConstraint };

View File

@ -25,37 +25,36 @@ class Brownian extends Behavior<IBrownianBehaviorParameter, IBrownianBehaviorEve
public override category: string = "$Physics"; public override category: string = "$Physics";
public override parameterOption = { public override parameterOption = {
maxFrequency: { maxFrequency: { type: "number", name: "$Max.Frequency", defaultValue: 5, numberStep: .1, numberMin: 0 },
type: "number", minFrequency: { type: "number", name: "$Min.Frequency", defaultValue: 0, numberStep: .1, numberMin: 0 },
name: "$Max.Frequency", maxStrength: { type: "number", name: "$Max.Strength", defaultValue: 10, numberStep: .01, numberMin: 0 },
defaultValue: 5, minStrength: { type: "number", name: "$Min.Strength", defaultValue: 0, numberStep: .01, numberMin: 0 }
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 override terms: Record<string, Record<string, string>> = { 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>> = {
"$Title": { "$Title": {
"ZH_CN": "布朗运动", "ZH_CN": "布朗运动",
"EN_US": "Brownian motion" "EN_US": "Brownian motion"
@ -81,29 +80,6 @@ class Brownian extends Behavior<IBrownianBehaviorParameter, IBrownianBehaviorEve
"EN_US": "Minimum strength" "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 }; export { Brownian };

View File

@ -25,67 +25,12 @@ class Dynamics extends Behavior<IDynamicsBehaviorParameter, IDynamicsBehaviorEve
public override category: string = "$Physics"; public override category: string = "$Physics";
public override parameterOption = { public override parameterOption = {
mass: { mass: { name: "$Mass", type: "number", defaultValue: 1, numberStep: .01, numberMin: .001 },
name: "$Mass", maxAcceleration: { name: "$Max.Acceleration", type: "number", defaultValue: 5, numberStep: .1, numberMin: 0 },
type: "number", maxVelocity: { name: "$Max.Velocity", type: "number", defaultValue: 10, numberStep: .1, numberMin: 0 },
defaultValue: 1, resistance: { name: "$Resistance", type: "number", defaultValue: 0.5, numberStep: .1, numberMin: 0 }
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 { public override finalEffect(individual: Individual, group: Group, model: Model, t: number): void {
// 计算当前速度 // 计算当前速度
@ -139,6 +84,37 @@ class Dynamics extends Behavior<IDynamicsBehaviorParameter, IDynamicsBehaviorEve
individual.force[1] = 0; individual.force[1] = 0;
individual.force[2] = 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 }; export { Dynamics };

View File

@ -7,6 +7,8 @@ type ITemplateBehaviorParameter = {
testNumber: "number"; testNumber: "number";
testString: "string"; testString: "string";
testBoolean: "boolean"; testBoolean: "boolean";
testColor: "color";
testOption: "option";
testR: "R"; testR: "R";
testG: "G"; testG: "G";
testLR: "LR"; testLR: "LR";
@ -29,52 +31,24 @@ class Template extends Behavior<ITemplateBehaviorParameter, ITemplateBehaviorEve
public override category: string = "$Category"; public override category: string = "$Category";
public override parameterOption = { public override parameterOption = {
testNumber: { testNumber: { name: "$Test", type: "number", defaultValue: 1, numberMax: 10, numberMin: 0, numberStep: 1 },
name: "$Test", testString: { name: "$Test", type: "string", defaultValue: "default", maxLength: 12 },
type: "number", testColor: { name: "$Test", type: "color", defaultValue: [.5, .1, 1], colorNormal: true },
defaultValue: 1, testOption: { name: "$Test", type: "option", defaultValue: "T", allOption: [
numberMax: 10, { key: "P", name: "$Test"}, { key: "T", name: "$Title"}
numberMin: 0, ]},
numberStep: 1 testBoolean: { name: "$Test", type: "boolean", defaultValue: false, iconName: "Send" },
}, testR: { name: "$Test", type: "R" },
testString: { testG: { name: "$Test", type: "G" },
name: "$Test", testLR: { name: "$Test", type: "LR" },
type: "string", testLG: { name: "$Test", type: "LG" },
defaultValue: "default", testVec: { name: "$Test", type: "vec", defaultValue: [1, 2, 3], numberMax: 10, numberMin: 0, numberStep: 1 }
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>> = { public override terms: Record<string, Record<string, string>> = {
"$Title": { "$Title": {
"ZH_CN": "行为", "ZH_CN": "行为",
@ -87,12 +61,12 @@ class Template extends Behavior<ITemplateBehaviorParameter, ITemplateBehaviorEve
"$Test": { "$Test": {
"ZH_CN": "测试参数", "ZH_CN": "测试参数",
"EN_US": "Test Parameter" "EN_US": "Test Parameter"
},
"$Category": {
"ZH_CN": "测序模板",
"EN_US": "Test template"
} }
}; };
public effect(individual: Individual, group: Group, model: Model, t: number): void {
}
} }
export { Template }; export { Template };

View File

@ -145,10 +145,10 @@ class BehaviorPicker extends Component<IBehaviorPickerProps & IMixinSettingProps
private renderPickerList(): ReactNode { private renderPickerList(): ReactNode {
return <PickerList return <PickerList
objectList={this.getAllData()} item={this.getAllData()}
noData="Behavior.Picker.Add.Nodata" noData="Behavior.Picker.Add.Nodata"
target={this.clickLineRef} target={this.clickLineRef}
clickObjectItems={((item) => { click={((item) => {
if (item instanceof Behavior && this.props.add) { if (item instanceof Behavior && this.props.add) {
this.props.add(item); this.props.add(item);
} }

View File

@ -1,6 +1,6 @@
import { Component, createRef, ReactNode } from "react"; import { Component, createRef, ReactNode } from "react";
import { Icon } from "@fluentui/react"; import { Icon } from "@fluentui/react";
import { PickerList, IDisplayItem } from "@Input/PickerList/PickerList"; import { ComboList, IDisplayItem } from "@Input/ComboList/ComboList";
import { TextField, ITextFieldProps } from "@Input/TextField/TextField"; import { TextField, ITextFieldProps } from "@Input/TextField/TextField";
import { Localization } from "@Component/Localization/Localization"; import { Localization } from "@Component/Localization/Localization";
import "./ComboInput.scss"; import "./ComboInput.scss";
@ -26,13 +26,11 @@ class ComboInput extends Component<IComboInputProps, IComboInputState> {
private pickerTarget = createRef<HTMLDivElement>(); private pickerTarget = createRef<HTMLDivElement>();
private renderPicker() { private renderPicker() {
return <PickerList return <ComboList
target={this.pickerTarget} target={this.pickerTarget}
displayItems={(this.props.allOption ?? []).map((item) => { item={this.props.allOption ?? []}
return item.key === this.props.value?.key ? focus={this.props.value}
{...item, mark: true} : item; click={((item) => {
})}
clickDisplayItems={((item) => {
if (this.props.valueChange) { if (this.props.valueChange) {
this.props.valueChange(item); this.props.valueChange(item);
} }
@ -64,8 +62,8 @@ class ComboInput extends Component<IComboInputProps, IComboInputState> {
<div className="value-view"> <div className="value-view">
{ {
this.props.value ? this.props.value ?
<Localization i18nKey={this.props.value.nameKey}/> : <Localization i18nKey={this.props.value.i18n} options={this.props.value.i18nOption}/> :
null <Localization i18nKey="Input.Error.Combo"/>
} }
</div> </div>
<div className="list-button"> <div className="list-button">

View File

@ -0,0 +1 @@
@import "../PickerList/PickerList.scss";

View File

@ -0,0 +1,71 @@
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 }

View File

@ -48,13 +48,13 @@ class LabelPicker extends Component<ILabelPickerProps & IMixinStatusProps, ILabe
private renderPicker() { private renderPicker() {
return <PickerList return <PickerList
noData="Common.Attr.Key.Label.Picker.Nodata" noData="Common.Attr.Key.Label.Picker.Nodata"
objectList={this.getOtherLabel()} item={this.getOtherLabel()}
dismiss={() => { dismiss={() => {
this.setState({ this.setState({
isPickerVisible: false isPickerVisible: false
}); });
}} }}
clickObjectItems={(label) => { click={(label) => {
if (label instanceof Label && this.props.labelAdd) { if (label instanceof Label && this.props.labelAdd) {
this.props.labelAdd(label) this.props.labelAdd(label)
} }

View File

@ -6,7 +6,7 @@ import { Range } from "@Model/Range";
import { CtrlObject } from "@Model/CtrlObject"; import { CtrlObject } from "@Model/CtrlObject";
import { Behavior } from "@Model/Behavior"; import { Behavior } from "@Model/Behavior";
import { TextField, ITextFieldProps } from "@Input/TextField/TextField"; import { TextField, ITextFieldProps } from "@Input/TextField/TextField";
import { PickerList, IDisplayItem, getObjectDisplayInfo, IDisplayInfo } from "@Input/PickerList/PickerList"; import { PickerList, getObjectDisplayInfo, IDisplayInfo } from "@Input/PickerList/PickerList";
import { Localization } from "@Component/Localization/Localization"; import { Localization } from "@Component/Localization/Localization";
import { Icon } from "@fluentui/react"; import { Icon } from "@fluentui/react";
import "./ObjectPicker.scss"; import "./ObjectPicker.scss";
@ -79,8 +79,8 @@ class ObjectPicker extends Component<IObjectPickerProps & IMixinStatusProps, IOb
return <PickerList return <PickerList
noData="Object.Picker.List.No.Data" noData="Object.Picker.List.No.Data"
target={this.pickerTarget} target={this.pickerTarget}
objectList={this.getAllOption()} item={this.getAllOption()}
clickObjectItems={((item) => { click={((item) => {
if (item instanceof Behavior) return; if (item instanceof Behavior) return;
if (this.props.valueChange) { if (this.props.valueChange) {
this.props.valueChange(item); this.props.valueChange(item);
@ -166,4 +166,4 @@ class ObjectPicker extends Component<IObjectPickerProps & IMixinStatusProps, IOb
} }
} }
export { ObjectPicker, IDisplayItem }; export { ObjectPicker };

View File

@ -4,8 +4,10 @@ import { AttrInput } from "@Input/AttrInput/AttrInput";
import { ObjectID } from "@Model/Renderer"; import { ObjectID } from "@Model/Renderer";
import { TogglesInput } from "@Input/TogglesInput/TogglesInput"; import { TogglesInput } from "@Input/TogglesInput/TogglesInput";
import { ObjectPicker } from "@Input/ObjectPicker/ObjectPicker"; import { ObjectPicker } from "@Input/ObjectPicker/ObjectPicker";
import { AllI18nKeys } from "@Component/Localization/Localization"; import { AllI18nKeys, I18N } from "@Component/Localization/Localization";
import { Message } from "@Input/Message/Message"; import { Message } from "@Input/Message/Message";
import { ColorInput } from "@Input/ColorInput/ColorInput";
import { ComboInput, IDisplayItem } from "@Input/ComboInput/ComboInput";
import { import {
IParameter, IParameterOption, IParameterOptionItem, IParameter, IParameterOption, IParameterOptionItem,
IParameterValue, IParamValue, isObjectType, isVectorType IParameterValue, IParamValue, isObjectType, isVectorType
@ -17,7 +19,7 @@ interface IParameterProps<P extends IParameter = {}> {
value: IParameterValue<P>; value: IParameterValue<P>;
key: ObjectID; key: ObjectID;
change: <K extends keyof P>(key: K, val: IParamValue<P[K]>) => any; change: <K extends keyof P>(key: K, val: IParamValue<P[K]>) => any;
i18n: <K extends keyof P>(option: IParameterOptionItem<P[K]>, language: Language) => string; i18n?: (key: string, language: Language) => string;
title?: AllI18nKeys; title?: AllI18nKeys;
titleOption?: Record<string, string>; titleOption?: Record<string, string>;
isFirst?: boolean; isFirst?: boolean;
@ -29,16 +31,29 @@ class Parameter<P extends IParameter> extends Component<IParameterProps<P> & IMi
private renderParameter<K extends keyof P> private renderParameter<K extends keyof P>
(key: K, option: IParameterOptionItem<P[K]>, value: IParamValue<P[K]>): ReactNode { (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 indexKey = `${this.props.key}-${key}`;
const type = option.type; const type = option.type;
const i18nString = this.props.i18n(option, this.props.setting?.language ?? "EN_US"); 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;
}
if (type === "number") { if (type === "number") {
return <AttrInput return <AttrInput
key={indexKey} key={indexKey}
id={indexKey} id={indexKey}
keyI18n="Panel.Info.Behavior.Details.Parameter.Key" keyI18n={keyI18n}
keyI18nOption={{ key: i18nString }} keyI18nOption={keyI18nOption}
isNumber={true} isNumber={true}
step={option.numberStep} step={option.numberStep}
maxLength={option.maxLength} maxLength={option.maxLength}
@ -55,8 +70,8 @@ class Parameter<P extends IParameter> extends Component<IParameterProps<P> & IMi
return <AttrInput return <AttrInput
key={indexKey} key={indexKey}
id={indexKey} id={indexKey}
keyI18n="Panel.Info.Behavior.Details.Parameter.Key" keyI18n={keyI18n}
keyI18nOption={{ key: i18nString }} keyI18nOption={keyI18nOption}
maxLength={option.maxLength} maxLength={option.maxLength}
value={value as IParamValue<"string"> ?? ""} value={value as IParamValue<"string"> ?? ""}
valueChange={(val) => { valueChange={(val) => {
@ -68,9 +83,10 @@ class Parameter<P extends IParameter> extends Component<IParameterProps<P> & IMi
else if (type === "boolean") { else if (type === "boolean") {
return <TogglesInput return <TogglesInput
key={indexKey} key={indexKey}
keyI18n="Panel.Info.Behavior.Details.Parameter.Key" keyI18n={keyI18n}
keyI18nOption={{ key: i18nString }} keyI18nOption={keyI18nOption}
onIconName={option.iconName} onIconName={option.iconName}
red={option.iconRed}
value={value as IParamValue<"boolean"> ?? false} value={value as IParamValue<"boolean"> ?? false}
valueChange={(val) => { valueChange={(val) => {
this.props.change(key, val as IParamValue<P[K]>); this.props.change(key, val as IParamValue<P[K]>);
@ -85,8 +101,8 @@ class Parameter<P extends IParameter> extends Component<IParameterProps<P> & IMi
return <ObjectPicker return <ObjectPicker
key={indexKey} key={indexKey}
keyI18n="Panel.Info.Behavior.Details.Parameter.Key" keyI18n={keyI18n}
keyI18nOption={{ key: i18nString }} keyI18nOption={keyI18nOption}
type={type} type={type}
value={typedValue.picker} value={typedValue.picker}
valueChange={(obj) => { valueChange={(obj) => {
@ -100,10 +116,66 @@ class Parameter<P extends IParameter> extends Component<IParameterProps<P> & IMi
/> />
} }
else if (isVectorType(type)) { 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") {
type IObjectParamValue = IParamValue<"vec">; type IObjectParamValue = IParamValue<"vec">;
const typedValue = value as IObjectParamValue; const typedValue = value as IObjectParamValue;
const i18nVal = I18N(this.props, keyI18n, keyI18nOption);
return <Fragment key={indexKey}> return <Fragment key={indexKey}>
@ -111,7 +183,7 @@ class Parameter<P extends IParameter> extends Component<IParameterProps<P> & IMi
key={`${indexKey}-X`} key={`${indexKey}-X`}
id={indexKey} id={indexKey}
keyI18n="Panel.Info.Behavior.Details.Parameter.Key.Vec.X" keyI18n="Panel.Info.Behavior.Details.Parameter.Key.Vec.X"
keyI18nOption={{ key: i18nString }} keyI18nOption={{ key: i18nVal }}
isNumber={true} isNumber={true}
step={option.numberStep} step={option.numberStep}
maxLength={option.maxLength} maxLength={option.maxLength}
@ -128,7 +200,7 @@ class Parameter<P extends IParameter> extends Component<IParameterProps<P> & IMi
key={`${indexKey}-Y`} key={`${indexKey}-Y`}
id={indexKey} id={indexKey}
keyI18n="Panel.Info.Behavior.Details.Parameter.Key.Vec.Y" keyI18n="Panel.Info.Behavior.Details.Parameter.Key.Vec.Y"
keyI18nOption={{ key: i18nString }} keyI18nOption={{ key: i18nVal }}
isNumber={true} isNumber={true}
step={option.numberStep} step={option.numberStep}
maxLength={option.maxLength} maxLength={option.maxLength}
@ -145,7 +217,7 @@ class Parameter<P extends IParameter> extends Component<IParameterProps<P> & IMi
key={`${indexKey}-Z`} key={`${indexKey}-Z`}
id={indexKey} id={indexKey}
keyI18n="Panel.Info.Behavior.Details.Parameter.Key.Vec.Z" keyI18n="Panel.Info.Behavior.Details.Parameter.Key.Vec.Z"
keyI18nOption={{ key: i18nString }} keyI18nOption={{ key: i18nVal }}
isNumber={true} isNumber={true}
step={option.numberStep} step={option.numberStep}
maxLength={option.maxLength} maxLength={option.maxLength}

View File

@ -17,12 +17,6 @@ interface IDisplayInfo {
allLabel: boolean; allLabel: boolean;
}; };
interface IDisplayItem {
nameKey: AllI18nKeys;
key: string;
mark?: boolean;
}
function getObjectDisplayInfo(item?: IPickerListItem): IDisplayInfo { function getObjectDisplayInfo(item?: IPickerListItem): IDisplayInfo {
if (!item) { if (!item) {
@ -98,13 +92,11 @@ function getObjectDisplayInfo(item?: IPickerListItem): IDisplayInfo {
} }
interface IPickerListProps { interface IPickerListProps {
displayItems?: IDisplayItem[]; item: IPickerListItem[];
objectList?: IPickerListItem[];
target?: RefObject<any>; target?: RefObject<any>;
noData?: AllI18nKeys; noData?: AllI18nKeys;
dismiss?: () => any; dismiss?: () => any;
clickObjectItems?: (item: IPickerListItem) => any; click?: (item: IPickerListItem) => any;
clickDisplayItems?: (item: IDisplayItem) => any;
} }
class PickerList extends Component<IPickerListProps> { class PickerList extends Component<IPickerListProps> {
@ -116,8 +108,8 @@ class PickerList extends Component<IPickerListProps> {
className="picker-list-item" className="picker-list-item"
key={item.id} key={item.id}
onClick={() => { onClick={() => {
if (this.props.clickObjectItems) { if (this.props.click) {
this.props.clickObjectItems(item) this.props.click(item)
} }
}} }}
> >
@ -143,27 +135,6 @@ class PickerList extends Component<IPickerListProps> {
</div>; </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 { public render(): ReactNode {
return <Callout return <Callout
onDismiss={this.props.dismiss} onDismiss={this.props.dismiss}
@ -171,18 +142,11 @@ class PickerList extends Component<IPickerListProps> {
directionalHint={DirectionalHint.topCenter} directionalHint={DirectionalHint.topCenter}
> >
<div className="picker-list-root"> <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.objectList || this.props.displayItems) || this.props.item.map((item) => this.renderItem(item))
!( }
this.props.objectList && this.props.objectList.length > 0 || {
this.props.displayItems && this.props.displayItems.length > 0 this.props.item.length <= 0 ?
) ?
<Localization <Localization
className="picker-list-nodata" className="picker-list-nodata"
i18nKey={this.props.noData ?? "Common.No.Data"} i18nKey={this.props.noData ?? "Common.No.Data"}
@ -194,4 +158,4 @@ class PickerList extends Component<IPickerListProps> {
} }
} }
export { PickerList, IDisplayItem, IDisplayInfo, getObjectDisplayInfo } export { PickerList, IDisplayInfo, getObjectDisplayInfo }

View File

@ -25,6 +25,7 @@ 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}",
"Input.Error.Length.Less": "The length of the input content must be greater than {num}", "Input.Error.Length.Less": "The length of the input content must be greater than {num}",
"Input.Error.Select": "Select object ...", "Input.Error.Select": "Select object ...",
"Input.Error.Combo": "Select options ...",
"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.New.Label": "Label {id}",

View File

@ -25,6 +25,7 @@ const ZH_CN = {
"Input.Error.Length": "输入内容长度须小于 {number}", "Input.Error.Length": "输入内容长度须小于 {number}",
"Input.Error.Length.Less": "输入内容长度须大于 {number}", "Input.Error.Length.Less": "输入内容长度须大于 {number}",
"Input.Error.Select": "选择对象 ...", "Input.Error.Select": "选择对象 ...",
"Input.Error.Combo": "选择选项 ...",
"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.New.Label": "标签 {id}",

View File

@ -14,6 +14,7 @@ type IMapBasicParamTypeKeyToType = {
"number": number; "number": number;
"string": string; "string": string;
"boolean": boolean; "boolean": boolean;
"option": string;
} }
type IMapObjectParamTypeKeyToType = { type IMapObjectParamTypeKeyToType = {
@ -25,6 +26,7 @@ type IMapObjectParamTypeKeyToType = {
type IMapVectorParamTypeKeyToType = { type IMapVectorParamTypeKeyToType = {
"vec": number[]; "vec": number[];
"color": number[];
} }
/** /**
@ -100,6 +102,21 @@ interface IParameterOptionItem<T extends IParamType = IParamType> {
* *
*/ */
iconName?: string; iconName?: string;
/**
*
*/
iconRed?: boolean;
/**
*
*/
colorNormal?: boolean;
/**
*
*/
allOption?: Array<{key: string, name: string}>;
} }
interface IParameter { interface IParameter {

View File

@ -65,7 +65,7 @@ class BehaviorDetails extends Component<IBehaviorDetailsProps & IMixinStatusProp
key={behavior.id} key={behavior.id}
option={behavior.parameterOption} option={behavior.parameterOption}
value={behavior.parameter} value={behavior.parameter}
i18n={(option, language) => behavior.getTerms(option.name, language)} i18n={(name, language) => behavior.getTerms(name, language)}
title={"Panel.Info.Behavior.Details.Behavior.Props"} title={"Panel.Info.Behavior.Details.Behavior.Props"}
titleOption={{ titleOption={{
behavior: behavior.getTerms(behavior.behaviorName, this.props.setting?.language) behavior: behavior.getTerms(behavior.behaviorName, this.props.setting?.language)

View File

@ -22,8 +22,8 @@ mapGenModToI18nKey.set(GenMod.Point, "Common.Attr.Key.Generation.Mod.Point");
mapGenModToI18nKey.set(GenMod.Range, "Common.Attr.Key.Generation.Mod.Range"); mapGenModToI18nKey.set(GenMod.Range, "Common.Attr.Key.Generation.Mod.Range");
const allOption: IDisplayItem[] = [ const allOption: IDisplayItem[] = [
{nameKey: "Common.Attr.Key.Generation.Mod.Point", key: GenMod.Point}, {i18n: "Common.Attr.Key.Generation.Mod.Point", key: GenMod.Point},
{nameKey: "Common.Attr.Key.Generation.Mod.Range", key: GenMod.Range} {i18n: "Common.Attr.Key.Generation.Mod.Range", key: GenMod.Range}
]; ];
@useSetting @useSetting
@ -144,7 +144,7 @@ class GroupDetails extends Component<IGroupDetailsProps & IMixinStatusProps & IM
<ComboInput <ComboInput
keyI18n="Common.Attr.Key.Generation.Mod" keyI18n="Common.Attr.Key.Generation.Mod"
value={{ value={{
nameKey: mapGenModToI18nKey.get(group.genMethod) ?? "Common.No.Data", i18n: mapGenModToI18nKey.get(group.genMethod) ?? "Common.No.Data",
key: group.genMethod key: group.genMethod
}} }}
allOption={allOption} allOption={allOption}