From 8cc8819cd314ea3acbc1f1ab320e639d6245806f Mon Sep 17 00:00:00 2001 From: MrKBear Date: Fri, 8 Apr 2022 17:39:26 +0800 Subject: [PATCH 1/3] Add color Parameter --- source/Behavior/Template.ts | 12 ++++++++++++ source/Input/Parameter/Parameter.tsx | 18 +++++++++++++++++- source/Model/Parameter.ts | 17 +++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/source/Behavior/Template.ts b/source/Behavior/Template.ts index 916c5eb..dff6373 100644 --- a/source/Behavior/Template.ts +++ b/source/Behavior/Template.ts @@ -7,6 +7,8 @@ type ITemplateBehaviorParameter = { testNumber: "number"; testString: "string"; testBoolean: "boolean"; + testColor: "color"; + testOption: "option"; testR: "R"; testG: "G"; testLR: "LR"; @@ -43,6 +45,16 @@ class Template extends Behavior extends Component & IMi 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); @@ -100,7 +102,21 @@ class Parameter

extends Component & IMi /> } - else if (isVectorType(type)) { + else if (type === "color") { + + return ?? false} + valueChange={(val) => { + this.props.change(key, val as IParamValue); + }} + /> + } + + else if (type === "vec") { type IObjectParamValue = IParamValue<"vec">; const typedValue = value as IObjectParamValue; diff --git a/source/Model/Parameter.ts b/source/Model/Parameter.ts index 0d70ca4..8ab4192 100644 --- a/source/Model/Parameter.ts +++ b/source/Model/Parameter.ts @@ -14,6 +14,7 @@ type IMapBasicParamTypeKeyToType = { "number": number; "string": string; "boolean": boolean; + "option": string; } type IMapObjectParamTypeKeyToType = { @@ -25,6 +26,7 @@ type IMapObjectParamTypeKeyToType = { type IMapVectorParamTypeKeyToType = { "vec": number[]; + "color": number[]; } /** @@ -100,6 +102,21 @@ interface IParameterOptionItem { * 图标名字 */ iconName?: string; + + /** + * 图标是否显示为红色 + */ + iconRed?: boolean; + + /** + * 颜色是否进行归一化 + */ + colorNormal?: boolean; + + /** + * 全部选项 + */ + allOption?: string[]; } interface IParameter { -- 2.45.2 From cb2501f1f087e876f0dc75b411b32afc70e8d011 Mon Sep 17 00:00:00 2001 From: MrKBear Date: Fri, 8 Apr 2022 20:40:07 +0800 Subject: [PATCH 2/3] Detach separates the combolist from the pickerlist --- .../Input/BehaviorPicker/BehaviorPicker.tsx | 4 +- source/Input/ComboInput/ComboInput.tsx | 16 ++--- source/Input/ComboList/ComboList.scss | 1 + source/Input/ComboList/ComboList.tsx | 71 +++++++++++++++++++ source/Input/LabelPicker/LabelPicker.tsx | 4 +- source/Input/ObjectPicker/ObjectPicker.tsx | 8 +-- source/Input/PickerList/PickerList.tsx | 54 +++----------- source/Panel/GroupDetails/GroupDetails.tsx | 6 +- 8 files changed, 99 insertions(+), 65 deletions(-) create mode 100644 source/Input/ComboList/ComboList.scss create mode 100644 source/Input/ComboList/ComboList.tsx diff --git a/source/Input/BehaviorPicker/BehaviorPicker.tsx b/source/Input/BehaviorPicker/BehaviorPicker.tsx index 7276dfd..cf89104 100644 --- a/source/Input/BehaviorPicker/BehaviorPicker.tsx +++ b/source/Input/BehaviorPicker/BehaviorPicker.tsx @@ -145,10 +145,10 @@ class BehaviorPicker extends Component { + click={((item) => { if (item instanceof Behavior && this.props.add) { this.props.add(item); } diff --git a/source/Input/ComboInput/ComboInput.tsx b/source/Input/ComboInput/ComboInput.tsx index 122cd78..761a51f 100644 --- a/source/Input/ComboInput/ComboInput.tsx +++ b/source/Input/ComboInput/ComboInput.tsx @@ -1,6 +1,6 @@ import { Component, createRef, ReactNode } from "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 { Localization } from "@Component/Localization/Localization"; import "./ComboInput.scss"; @@ -26,13 +26,11 @@ class ComboInput extends Component { private pickerTarget = createRef(); private renderPicker() { - return { - return item.key === this.props.value?.key ? - {...item, mark: true} : item; - })} - clickDisplayItems={((item) => { + item={this.props.allOption ?? []} + focus={this.props.value} + click={((item) => { if (this.props.valueChange) { this.props.valueChange(item); } @@ -64,8 +62,8 @@ class ComboInput extends Component {

{ this.props.value ? - : - null + : + null }
diff --git a/source/Input/ComboList/ComboList.scss b/source/Input/ComboList/ComboList.scss new file mode 100644 index 0000000..b835123 --- /dev/null +++ b/source/Input/ComboList/ComboList.scss @@ -0,0 +1 @@ +@import "../PickerList/PickerList.scss"; \ No newline at end of file diff --git a/source/Input/ComboList/ComboList.tsx b/source/Input/ComboList/ComboList.tsx new file mode 100644 index 0000000..f58cb72 --- /dev/null +++ b/source/Input/ComboList/ComboList.tsx @@ -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; + i18n: AllI18nKeys; + key: string; +} + +interface IComboListProps { + target?: RefObject; + item: IDisplayItem[]; + focus?: IDisplayItem; + noData?: AllI18nKeys; + dismiss?: () => any; + click?: (item: IDisplayItem) => any; +} + +class ComboList extends Component { + + private renderString(item: IDisplayItem) { + + const isFocus = item.key === this.props.focus?.key; + + return
{ + if (this.props.click) { + this.props.click(item) + } + }} + > +
+ +
+
+ +
+
; + } + + public render(): ReactNode { + return +
+ { this.props.item.map((item) => this.renderString(item)) } + { + this.props.item.length <= 0 ? + + : null + } +
+
+ } +} + +export { ComboList, IDisplayItem } \ No newline at end of file diff --git a/source/Input/LabelPicker/LabelPicker.tsx b/source/Input/LabelPicker/LabelPicker.tsx index 3ae8d11..6a9c22a 100644 --- a/source/Input/LabelPicker/LabelPicker.tsx +++ b/source/Input/LabelPicker/LabelPicker.tsx @@ -48,13 +48,13 @@ class LabelPicker extends Component { this.setState({ isPickerVisible: false }); }} - clickObjectItems={(label) => { + click={(label) => { if (label instanceof Label && this.props.labelAdd) { this.props.labelAdd(label) } diff --git a/source/Input/ObjectPicker/ObjectPicker.tsx b/source/Input/ObjectPicker/ObjectPicker.tsx index 4b7c49e..0fd0ff6 100644 --- a/source/Input/ObjectPicker/ObjectPicker.tsx +++ b/source/Input/ObjectPicker/ObjectPicker.tsx @@ -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, IDisplayItem, getObjectDisplayInfo, IDisplayInfo } from "@Input/PickerList/PickerList"; +import { PickerList, 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 { + item={this.getAllOption()} + click={((item) => { if (item instanceof Behavior) return; if (this.props.valueChange) { this.props.valueChange(item); @@ -166,4 +166,4 @@ class ObjectPicker extends Component; noData?: AllI18nKeys; dismiss?: () => any; - clickObjectItems?: (item: IPickerListItem) => any; - clickDisplayItems?: (item: IDisplayItem) => any; + click?: (item: IPickerListItem) => any; } class PickerList extends Component { @@ -116,8 +108,8 @@ class PickerList extends Component { className="picker-list-item" key={item.id} onClick={() => { - if (this.props.clickObjectItems) { - this.props.clickObjectItems(item) + if (this.props.click) { + this.props.click(item) } }} > @@ -143,27 +135,6 @@ class PickerList extends Component {
; } - private renderString(item: IDisplayItem) { - return
{ - if (this.props.clickDisplayItems) { - this.props.clickDisplayItems(item) - } - }} - > -
- -
-
- -
-
; - } - public render(): ReactNode { return { directionalHint={DirectionalHint.topCenter} >
- {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.objectList && this.props.objectList.length > 0 || - this.props.displayItems && this.props.displayItems.length > 0 - ) ? + this.props.item.map((item) => this.renderItem(item)) + } + { + this.props.item.length <= 0 ? { } } -export { PickerList, IDisplayItem, IDisplayInfo, getObjectDisplayInfo } \ No newline at end of file +export { PickerList, IDisplayInfo, getObjectDisplayInfo } \ No newline at end of file diff --git a/source/Panel/GroupDetails/GroupDetails.tsx b/source/Panel/GroupDetails/GroupDetails.tsx index 35d3ed5..51d94c2 100644 --- a/source/Panel/GroupDetails/GroupDetails.tsx +++ b/source/Panel/GroupDetails/GroupDetails.tsx @@ -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[] = [ - {nameKey: "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.Point", key: GenMod.Point}, + {i18n: "Common.Attr.Key.Generation.Mod.Range", key: GenMod.Range} ]; @useSetting @@ -144,7 +144,7 @@ class GroupDetails extends Component Date: Fri, 8 Apr 2022 21:46:33 +0800 Subject: [PATCH 3/3] Add combo input into parameter --- source/Behavior/BoundaryConstraint.ts | 51 +++++----- source/Behavior/Brownian.ts | 80 ++++++---------- source/Behavior/Dynamics.ts | 94 +++++++------------ source/Behavior/Template.ts | 78 ++++----------- source/Input/ComboInput/ComboInput.tsx | 2 +- source/Input/Parameter/Parameter.tsx | 88 +++++++++++++---- source/Localization/EN-US.ts | 1 + source/Localization/ZH-CN.ts | 1 + source/Model/Parameter.ts | 2 +- .../Panel/BehaviorDetails/BehaviorDetails.tsx | 2 +- 10 files changed, 181 insertions(+), 218 deletions(-) diff --git a/source/Behavior/BoundaryConstraint.ts b/source/Behavior/BoundaryConstraint.ts index 32c7c71..befd8c5 100644 --- a/source/Behavior/BoundaryConstraint.ts +++ b/source/Behavior/BoundaryConstraint.ts @@ -24,38 +24,10 @@ class BoundaryConstraint extends Behavior> = { - "$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; @@ -99,6 +71,25 @@ class BoundaryConstraint extends Behavior> = { + "$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 }; \ No newline at end of file diff --git a/source/Behavior/Brownian.ts b/source/Behavior/Brownian.ts index c468d20..62e04aa 100644 --- a/source/Behavior/Brownian.ts +++ b/source/Behavior/Brownian.ts @@ -25,37 +25,36 @@ class Brownian extends Behavior> = { + 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> = { "$Title": { "ZH_CN": "布朗运动", "EN_US": "Brownian motion" @@ -81,29 +80,6 @@ class Brownian extends Behavior 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 }; \ No newline at end of file diff --git a/source/Behavior/Dynamics.ts b/source/Behavior/Dynamics.ts index d41ef84..34c122a 100644 --- a/source/Behavior/Dynamics.ts +++ b/source/Behavior/Dynamics.ts @@ -25,67 +25,12 @@ class Dynamics extends Behavior> = { - "$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 { // 计算当前速度 @@ -139,6 +84,37 @@ class Dynamics extends Behavior> = { + "$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 }; \ No newline at end of file diff --git a/source/Behavior/Template.ts b/source/Behavior/Template.ts index dff6373..48d75be 100644 --- a/source/Behavior/Template.ts +++ b/source/Behavior/Template.ts @@ -31,62 +31,24 @@ class Template extends Behavior> = { "$Title": { "ZH_CN": "行为", @@ -99,12 +61,12 @@ class Template extends Behavior { { this.props.value ? : - null + }
diff --git a/source/Input/Parameter/Parameter.tsx b/source/Input/Parameter/Parameter.tsx index 024195c..deb6c4b 100644 --- a/source/Input/Parameter/Parameter.tsx +++ b/source/Input/Parameter/Parameter.tsx @@ -4,9 +4,10 @@ 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 } from "@Component/Localization/Localization"; +import { AllI18nKeys, I18N } 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 @@ -18,7 +19,7 @@ interface IParameterProps

{ value: IParameterValue

; key: ObjectID; change: (key: K, val: IParamValue) => any; - i18n: (option: IParameterOptionItem, language: Language) => string; + i18n?: (key: string, language: Language) => string; title?: AllI18nKeys; titleOption?: Record; isFirst?: boolean; @@ -30,16 +31,29 @@ class Parameter

extends Component & IMi private renderParameter (key: K, option: IParameterOptionItem, value: IParamValue): ReactNode { + const language = this.props.setting?.language ?? "EN_US"; const indexKey = `${this.props.key}-${key}`; const type = option.type; - const i18nString = this.props.i18n(option, this.props.setting?.language ?? "EN_US"); + let keyI18n: string, keyI18nOption: Record | 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") { return extends Component & IMi return ?? ""} valueChange={(val) => { @@ -69,8 +83,8 @@ class Parameter

extends Component & IMi else if (type === "boolean") { return ?? false} @@ -87,8 +101,8 @@ class Parameter

extends Component & IMi return { @@ -106,8 +120,8 @@ class Parameter

extends Component & IMi return ?? false} valueChange={(val) => { @@ -116,10 +130,52 @@ class Parameter

extends Component & IMi /> } + 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 { + this.props.change(key, val.key as IParamValue); + }} + /> + } + else if (type === "vec") { type IObjectParamValue = IParamValue<"vec">; const typedValue = value as IObjectParamValue; + const i18nVal = I18N(this.props, keyI18n, keyI18nOption); return @@ -127,7 +183,7 @@ class Parameter

extends Component & IMi key={`${indexKey}-X`} id={indexKey} keyI18n="Panel.Info.Behavior.Details.Parameter.Key.Vec.X" - keyI18nOption={{ key: i18nString }} + keyI18nOption={{ key: i18nVal }} isNumber={true} step={option.numberStep} maxLength={option.maxLength} @@ -144,7 +200,7 @@ class Parameter

extends Component & IMi key={`${indexKey}-Y`} id={indexKey} keyI18n="Panel.Info.Behavior.Details.Parameter.Key.Vec.Y" - keyI18nOption={{ key: i18nString }} + keyI18nOption={{ key: i18nVal }} isNumber={true} step={option.numberStep} maxLength={option.maxLength} @@ -161,7 +217,7 @@ class Parameter

extends Component & IMi key={`${indexKey}-Z`} id={indexKey} keyI18n="Panel.Info.Behavior.Details.Parameter.Key.Vec.Z" - keyI18nOption={{ key: i18nString }} + keyI18nOption={{ key: i18nVal }} isNumber={true} step={option.numberStep} maxLength={option.maxLength} diff --git a/source/Localization/EN-US.ts b/source/Localization/EN-US.ts index b172fad..52e32be 100644 --- a/source/Localization/EN-US.ts +++ b/source/Localization/EN-US.ts @@ -25,6 +25,7 @@ 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}", diff --git a/source/Localization/ZH-CN.ts b/source/Localization/ZH-CN.ts index 8403f11..3dd7c6b 100644 --- a/source/Localization/ZH-CN.ts +++ b/source/Localization/ZH-CN.ts @@ -25,6 +25,7 @@ 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}", diff --git a/source/Model/Parameter.ts b/source/Model/Parameter.ts index 8ab4192..54bf988 100644 --- a/source/Model/Parameter.ts +++ b/source/Model/Parameter.ts @@ -116,7 +116,7 @@ interface IParameterOptionItem { /** * 全部选项 */ - allOption?: string[]; + allOption?: Array<{key: string, name: string}>; } interface IParameter { diff --git a/source/Panel/BehaviorDetails/BehaviorDetails.tsx b/source/Panel/BehaviorDetails/BehaviorDetails.tsx index 7090ee8..e3490e9 100644 --- a/source/Panel/BehaviorDetails/BehaviorDetails.tsx +++ b/source/Panel/BehaviorDetails/BehaviorDetails.tsx @@ -65,7 +65,7 @@ class BehaviorDetails extends Component behavior.getTerms(option.name, language)} + i18n={(name, language) => behavior.getTerms(name, language)} title={"Panel.Info.Behavior.Details.Behavior.Props"} titleOption={{ behavior: behavior.getTerms(behavior.behaviorName, this.props.setting?.language) -- 2.45.2