Add behavior details panel & auto switch behavior details panels & mod behavior model add cache object #34
| @ -112,7 +112,7 @@ class BehaviorList extends Component<IBehaviorListProps & IMixinSettingProps & I | |||||||
| 		if (behavior instanceof Behavior) { | 		if (behavior instanceof Behavior) { | ||||||
| 			id = behavior.id; | 			id = behavior.id; | ||||||
| 			name = behavior.name; | 			name = behavior.name; | ||||||
| 			color = behavior.color; | 			color = `rgb(${behavior.color.join(",")})`; | ||||||
| 			needLocal = false; | 			needLocal = false; | ||||||
|             info = behavior.behaviorName; |             info = behavior.behaviorName; | ||||||
| 		} | 		} | ||||||
|  | |||||||
| @ -62,7 +62,7 @@ class BehaviorPicker extends Component<IBehaviorPickerProps & IMixinSettingProps | |||||||
| 
 | 
 | ||||||
|             return <> |             return <> | ||||||
|                 <div className="behavior-picker-line-color-view"> |                 <div className="behavior-picker-line-color-view"> | ||||||
|                     <div style={{ borderLeft: `10px solid ${behavior.color}` }}/> |                     <div style={{ borderLeft: `10px solid rgb(${behavior.color.join(",")})` }}/> | ||||||
|                 </div> |                 </div> | ||||||
|                 <div |                 <div | ||||||
|                     className="behavior-picker-line-icon-view" |                     className="behavior-picker-line-icon-view" | ||||||
|  | |||||||
| @ -123,8 +123,7 @@ class BehaviorPopupComponent extends Component< | |||||||
|                 ) + " " + (recorder.nameIndex - 1).toString(); |                 ) + " " + (recorder.nameIndex - 1).toString(); | ||||||
| 
 | 
 | ||||||
|                 // 赋予一个随机颜色
 |                 // 赋予一个随机颜色
 | ||||||
|                 let color = randomColor(true); |                 newBehavior.color = randomColor(true); | ||||||
|                 newBehavior.color = `rgb(${color[0]},${color[1]},${color[2]})`; |  | ||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
|         this.props.onDismiss ? this.props.onDismiss() : undefined; |         this.props.onDismiss ? this.props.onDismiss() : undefined; | ||||||
|  | |||||||
| @ -11,7 +11,7 @@ import { Setting } from "./Setting"; | |||||||
| import { I18N } from "@Component/Localization/Localization"; | import { I18N } from "@Component/Localization/Localization"; | ||||||
| import { superConnectWithEvent, superConnect } from "./Context"; | import { superConnectWithEvent, superConnect } from "./Context"; | ||||||
| import { PopupController } from "./Popups"; | import { PopupController } from "./Popups"; | ||||||
| import { Behavior } from "@Model/Behavior"; | import { Behavior, IBehaviorParameter, IParamValue } from "@Model/Behavior"; | ||||||
| import { Actuator } from "@Model/Actuator"; | import { Actuator } from "@Model/Actuator"; | ||||||
| 
 | 
 | ||||||
| function randomColor(unNormal: boolean = false) { | function randomColor(unNormal: boolean = false) { | ||||||
| @ -43,6 +43,7 @@ interface IStatusEvent { | |||||||
|     rangeAttrChange: void; |     rangeAttrChange: void; | ||||||
|     labelAttrChange: void; |     labelAttrChange: void; | ||||||
|     groupAttrChange: void; |     groupAttrChange: void; | ||||||
|  |     behaviorAttrChange: void; | ||||||
|     individualChange: void; |     individualChange: void; | ||||||
|     behaviorChange: void; |     behaviorChange: void; | ||||||
|     popupChange: void; |     popupChange: void; | ||||||
| @ -193,6 +194,24 @@ class Status extends Emitter<IStatusEvent> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * 修改群属性 | ||||||
|  |      */ | ||||||
|  |     public changeBehaviorAttrib<K extends IBehaviorParameter, P extends keyof K | keyof Behavior<K>> | ||||||
|  |     (id: ObjectID, key: P, val: IParamValue<K[P]>) { | ||||||
|  |         const behavior = this.model.getBehaviorById(id); | ||||||
|  |         if (behavior) { | ||||||
|  |             if (key === "color") { | ||||||
|  |                 behavior.color = val as number[]; | ||||||
|  |             } else if (key === "name") { | ||||||
|  |                 behavior.name = val as string; | ||||||
|  |             } else { | ||||||
|  |                 behavior.parameter[key] = val; | ||||||
|  |             } | ||||||
|  |             this.emit("behaviorAttrChange"); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public addGroupBehavior(id: ObjectID, val: Behavior) { |     public addGroupBehavior(id: ObjectID, val: Behavior) { | ||||||
|         const group = this.model.getObjectById(id); |         const group = this.model.getObjectById(id); | ||||||
|         if (group && group instanceof Group) { |         if (group && group instanceof Group) { | ||||||
|  | |||||||
| @ -48,6 +48,8 @@ const EN_US = { | |||||||
|     "Panel.Info.Group.Details.View": "Edit view group attributes", |     "Panel.Info.Group.Details.View": "Edit view group attributes", | ||||||
|     "Panel.Title.Behavior.List.View": "Behavior list", |     "Panel.Title.Behavior.List.View": "Behavior list", | ||||||
|     "Panel.Info.Behavior.List.View": "Edit view behavior list", |     "Panel.Info.Behavior.List.View": "Edit view behavior list", | ||||||
|  |     "Panel.Title.Behavior.Details.View": "Behavior", | ||||||
|  |     "Panel.Info.Behavior.Details.View": "Edit view Behavior attributes", | ||||||
|     "Popup.Title.Unnamed": "Popup message", |     "Popup.Title.Unnamed": "Popup message", | ||||||
|     "Popup.Title.Confirm": "Confirm message", |     "Popup.Title.Confirm": "Confirm message", | ||||||
|     "Popup.Action.Yes": "Confirm", |     "Popup.Action.Yes": "Confirm", | ||||||
| @ -109,5 +111,7 @@ const EN_US = { | |||||||
|     "Panel.Info.Group.Details.Attr.Error.Unspecified": "Unspecified group object", |     "Panel.Info.Group.Details.Attr.Error.Unspecified": "Unspecified group object", | ||||||
|     "Panel.Info.Label.Details.Error.Unspecified": "Label object not specified", |     "Panel.Info.Label.Details.Error.Unspecified": "Label object not specified", | ||||||
|     "Panel.Info.Label.List.Error.Nodata": "There are no labels in the model, click the button to create", |     "Panel.Info.Label.List.Error.Nodata": "There are no labels in the model, click the button to create", | ||||||
|  |     "Panel.Info.Behavior.Details.Error.Not.Behavior": "Please specify a behavior first to view the details", | ||||||
|  |     "Panel.Info.Behavior.Details.Behavior.Props": "{behavior} parameter", | ||||||
| } | } | ||||||
| export default EN_US; | export default EN_US; | ||||||
| @ -48,6 +48,8 @@ const ZH_CN = { | |||||||
|     "Panel.Info.Group.Details.View": "编辑查看群属性", |     "Panel.Info.Group.Details.View": "编辑查看群属性", | ||||||
|     "Panel.Title.Behavior.List.View": "行为列表", |     "Panel.Title.Behavior.List.View": "行为列表", | ||||||
|     "Panel.Info.Behavior.List.View": "编辑查看行为列表", |     "Panel.Info.Behavior.List.View": "编辑查看行为列表", | ||||||
|  |     "Panel.Title.Behavior.Details.View": "行为", | ||||||
|  |     "Panel.Info.Behavior.Details.View": "编辑查看行为属性", | ||||||
|     "Popup.Title.Unnamed": "弹窗消息", |     "Popup.Title.Unnamed": "弹窗消息", | ||||||
|     "Popup.Title.Confirm": "确认消息", |     "Popup.Title.Confirm": "确认消息", | ||||||
|     "Popup.Action.Yes": "确定", |     "Popup.Action.Yes": "确定", | ||||||
| @ -109,5 +111,7 @@ const ZH_CN = { | |||||||
|     "Panel.Info.Group.Details.Attr.Error.Unspecified": "未指定群对象", |     "Panel.Info.Group.Details.Attr.Error.Unspecified": "未指定群对象", | ||||||
|     "Panel.Info.Label.Details.Error.Unspecified": "未指定标签对象", |     "Panel.Info.Label.Details.Error.Unspecified": "未指定标签对象", | ||||||
|     "Panel.Info.Label.List.Error.Nodata": "模型中没有标签,点击按钮以创建", |     "Panel.Info.Label.List.Error.Nodata": "模型中没有标签,点击按钮以创建", | ||||||
|  |     "Panel.Info.Behavior.Details.Error.Not.Behavior": "请先指定一个行为以查看详情", | ||||||
|  |     "Panel.Info.Behavior.Details.Behavior.Props": "{behavior}参数", | ||||||
| } | } | ||||||
| export default ZH_CN; | export default ZH_CN; | ||||||
| @ -6,6 +6,11 @@ import type { Model } from "./Model"; | |||||||
| import type { Range } from "./Range"; | import type { Range } from "./Range"; | ||||||
| import type { Label } from "./Label"; | import type { Label } from "./Label"; | ||||||
| 
 | 
 | ||||||
|  | type IObjectParamCacheType<P, Q = P> = { | ||||||
|  |     picker: P; | ||||||
|  |     objects: Q; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /** | /** | ||||||
|  * 参数类型 |  * 参数类型 | ||||||
|  */ |  */ | ||||||
| @ -16,12 +21,10 @@ type IMapBasicParamTypeKeyToType = { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type IMapObjectParamTypeKeyToType = { | type IMapObjectParamTypeKeyToType = { | ||||||
|     "R"?: Range; |     "R": IObjectParamCacheType<Range | undefined>; | ||||||
|     "G"?: Group; |     "G": IObjectParamCacheType<Group | undefined>; | ||||||
|     "GR"?: Group | Range; |     "LR": IObjectParamCacheType<Label | Range | undefined, Range[]>; | ||||||
|     "LR"?: Label | Range; |     "LG": IObjectParamCacheType<Label | Group | undefined, Range[]>; | ||||||
|     "LG"?: Label | Group; |  | ||||||
|     "LGR"?: Label | Group | Range; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type IMapVectorParamTypeKeyToType = { | type IMapVectorParamTypeKeyToType = { | ||||||
| @ -40,7 +43,7 @@ type IParamValue<K extends IParamType> = AllMapType[K]; | |||||||
| /** | /** | ||||||
|  * 特殊对象类型判定 |  * 特殊对象类型判定 | ||||||
|  */ |  */ | ||||||
| const objectTypeListEnumSet = new Set<IParamType>(["R", "G", "GR", "LR", "LG", "LGR"]); | const objectTypeListEnumSet = new Set<IParamType>(["R", "G", "LR", "LG"]); | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * 对象断言表达式 |  * 对象断言表达式 | ||||||
| @ -247,6 +250,22 @@ class BehaviorRecorder< | |||||||
|                     case "vec": |                     case "vec": | ||||||
|                         defaultObj[key] = [0, 0, 0] as any; |                         defaultObj[key] = [0, 0, 0] as any; | ||||||
|                         break; |                         break; | ||||||
|  |                      | ||||||
|  |                     case "G": | ||||||
|  |                     case "R": | ||||||
|  |                         defaultObj[key] = { | ||||||
|  |                             picker: undefined, | ||||||
|  |                             objects: undefined | ||||||
|  |                         } as any; | ||||||
|  |                         break; | ||||||
|  | 
 | ||||||
|  |                     case "LR": | ||||||
|  |                     case "LG": | ||||||
|  |                         defaultObj[key] = { | ||||||
|  |                             picker: undefined, | ||||||
|  |                             objects: [] | ||||||
|  |                         } as any; | ||||||
|  |                         break; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @ -295,7 +314,7 @@ class Behavior< | |||||||
|     /** |     /** | ||||||
|      * 颜色 |      * 颜色 | ||||||
|      */ |      */ | ||||||
|     public color: string = ""; |     public color: number[] = [0, 0, 0]; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * 优先级 |      * 优先级 | ||||||
| @ -397,7 +416,7 @@ class Behavior< | |||||||
| type IRenderBehavior = BehaviorInfo | Behavior; | type IRenderBehavior = BehaviorInfo | Behavior; | ||||||
| 
 | 
 | ||||||
| export { | export { | ||||||
|     Behavior, BehaviorRecorder, IBehaviorParameterOption, IBehaviorParameterOptionItem, |     Behavior, BehaviorRecorder, IBehaviorParameterOption, IBehaviorParameterOptionItem, IParamValue, | ||||||
|     IAnyBehavior, IAnyBehaviorRecorder, BehaviorInfo, IRenderBehavior |     IAnyBehavior, IAnyBehaviorRecorder, BehaviorInfo, IRenderBehavior, IBehaviorParameter | ||||||
| }; | }; | ||||||
| export default { Behavior }; | export default { Behavior }; | ||||||
| @ -56,11 +56,11 @@ class SimulatorWeb extends Component { | |||||||
|             this.status.newLabel().name = "New Label"; |             this.status.newLabel().name = "New Label"; | ||||||
|             this.status.newLabel().name = "Test Label 01"; |             this.status.newLabel().name = "Test Label 01"; | ||||||
|             let dynamic = this.status.model.addBehavior(AllBehaviors[0]); |             let dynamic = this.status.model.addBehavior(AllBehaviors[0]); | ||||||
|             dynamic.name = "Dynamic"; dynamic.color = "rgb(250, 200, 80)"; |             dynamic.name = "Dynamic"; dynamic.color = [250, 200, 80]; | ||||||
|             let brownian = this.status.model.addBehavior(AllBehaviors[1]); |             let brownian = this.status.model.addBehavior(AllBehaviors[1]); | ||||||
|             brownian.name = "Brownian"; brownian.color = "rgb(200, 80, 250)"; |             brownian.name = "Brownian"; brownian.color = [200, 80, 250]; | ||||||
|             let boundary = this.status.model.addBehavior(AllBehaviors[2]); |             let boundary = this.status.model.addBehavior(AllBehaviors[2]); | ||||||
|             boundary.name = "Boundary"; boundary.color = "rgb(80, 200, 250)"; |             boundary.name = "Boundary"; boundary.color = [80, 200, 250]; | ||||||
|             boundary.parameter.range = this.status.model.allRangeLabel; |             boundary.parameter.range = this.status.model.allRangeLabel; | ||||||
|             group.addBehavior(dynamic); |             group.addBehavior(dynamic); | ||||||
|             group.addBehavior(brownian); |             group.addBehavior(brownian); | ||||||
| @ -75,9 +75,9 @@ class SimulatorWeb extends Component { | |||||||
|             items: [ |             items: [ | ||||||
|                 { |                 { | ||||||
|                     items: [ |                     items: [ | ||||||
|                         {panels: ["RenderView", "Label Aa Bb", "Label aaa"]}, |                         {panels: ["RenderView"]}, | ||||||
|                         { |                         { | ||||||
|                             items: [{panels: ["BehaviorList", "Label bbb"]}, {panels: ["LabelList"]}], |                             items: [{panels: ["BehaviorList"]}, {panels: ["LabelList"]}], | ||||||
|                             scale: 80, |                             scale: 80, | ||||||
|                             layout: LayoutDirection.X |                             layout: LayoutDirection.X | ||||||
|                         } |                         } | ||||||
| @ -87,9 +87,9 @@ class SimulatorWeb extends Component { | |||||||
|                 }, |                 }, | ||||||
|                 { |                 { | ||||||
|                     items: [{ |                     items: [{ | ||||||
|                         panels: ["ObjectList", "Test tab"] |                         panels: ["ObjectList"] | ||||||
|                     }, { |                     }, { | ||||||
|                         panels: ["GroupDetails", "RangeDetails", "LabelDetails"] |                         panels: ["GroupDetails", "RangeDetails", "LabelDetails", "BehaviorDetails"] | ||||||
|                     }], |                     }], | ||||||
|                     scale: 30, |                     scale: 30, | ||||||
|                     layout: LayoutDirection.Y |                     layout: LayoutDirection.Y | ||||||
|  | |||||||
							
								
								
									
										0
									
								
								source/Panel/BehaviorDetails/BehaviorDetails.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								source/Panel/BehaviorDetails/BehaviorDetails.scss
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										77
									
								
								source/Panel/BehaviorDetails/BehaviorDetails.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								source/Panel/BehaviorDetails/BehaviorDetails.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,77 @@ | |||||||
|  | import { Component, ReactNode} from "react"; | ||||||
|  | import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; | ||||||
|  | import { Behavior } from "@Model/Behavior"; | ||||||
|  | import { Message } from "@Component/Message/Message"; | ||||||
|  | import { AttrInput } from "@Component/AttrInput/AttrInput"; | ||||||
|  | import { ColorInput } from "@Component/ColorInput/ColorInput"; | ||||||
|  | import { TogglesInput } from "@Component/TogglesInput/TogglesInput"; | ||||||
|  | import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup"; | ||||||
|  | import "./BehaviorDetails.scss"; | ||||||
|  | 
 | ||||||
|  | interface IBehaviorDetailsProps {} | ||||||
|  | 
 | ||||||
|  | @useStatusWithEvent("focusBehaviorChange", "behaviorAttrChange") | ||||||
|  | class BehaviorDetails extends Component<IBehaviorDetailsProps & IMixinStatusProps> { | ||||||
|  | 
 | ||||||
|  | 	private renderFrom(behavior: Behavior): ReactNode { | ||||||
|  | 		return <> | ||||||
|  |          | ||||||
|  |             <Message i18nKey="Common.Attr.Title.Basic" isTitle first/> | ||||||
|  | 
 | ||||||
|  |             <AttrInput | ||||||
|  |                 id={behavior.id} keyI18n="Common.Attr.Key.Display.Name" value={behavior.name} | ||||||
|  |                 valueChange={(val) => { | ||||||
|  |                     this.props.status?.changeBehaviorAttrib(behavior.id, "name", val); | ||||||
|  |                 }} | ||||||
|  |             /> | ||||||
|  | 
 | ||||||
|  |             <ColorInput | ||||||
|  |                 keyI18n="Common.Attr.Key.Color" | ||||||
|  |                 value={behavior.color} | ||||||
|  |                 valueChange={(color) => { | ||||||
|  |                     this.props.status?.changeBehaviorAttrib(behavior.id, "color", color); | ||||||
|  |                 }} | ||||||
|  |             /> | ||||||
|  | 
 | ||||||
|  |             <TogglesInput | ||||||
|  | 				keyI18n="Common.Attr.Key.Delete" red | ||||||
|  | 				onIconName="delete" offIconName="delete" | ||||||
|  | 				valueChange={() => { | ||||||
|  | 					if (this.props.status) { | ||||||
|  |                         const status = this.props.status; | ||||||
|  |                         status.popup.showPopup(ConfirmPopup, { | ||||||
|  |                             infoI18n: "Popup.Delete.Behavior.Confirm", | ||||||
|  |                             titleI18N: "Popup.Action.Objects.Confirm.Title", | ||||||
|  |                             yesI18n: "Popup.Action.Objects.Confirm.Delete", | ||||||
|  |                             red: "yes", | ||||||
|  |                             yes: () => { | ||||||
|  |                                 status.model.deleteBehavior(behavior); | ||||||
|  |                                 status.setBehaviorObject(); | ||||||
|  |                             } | ||||||
|  |                         }) | ||||||
|  |                     } | ||||||
|  | 				}} | ||||||
|  | 			/> | ||||||
|  | 
 | ||||||
|  |             <Message | ||||||
|  |                 isTitle | ||||||
|  |                 i18nKey="Panel.Info.Behavior.Details.Behavior.Props" | ||||||
|  |                 options={{ | ||||||
|  |                     behavior: behavior.getTerms(behavior.behaviorName) | ||||||
|  |                 }} | ||||||
|  |             /> | ||||||
|  | 
 | ||||||
|  |         </>; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public render(): ReactNode { | ||||||
|  | 		if (this.props.status) { | ||||||
|  |             if (this.props.status.focusBehavior) { | ||||||
|  |                 return this.renderFrom(this.props.status.focusBehavior); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 		return <Message i18nKey="Panel.Info.Behavior.Details.Error.Not.Behavior"/>; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export { BehaviorDetails }; | ||||||
| @ -13,7 +13,7 @@ interface IBehaviorListProps { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @useSetting | @useSetting | ||||||
| @useStatusWithEvent("behaviorChange", "focusBehaviorChange") | @useStatusWithEvent("behaviorChange", "focusBehaviorChange", "behaviorAttrChange") | ||||||
| class BehaviorList extends Component<IBehaviorListProps & IMixinStatusProps & IMixinSettingProps> { | class BehaviorList extends Component<IBehaviorListProps & IMixinStatusProps & IMixinSettingProps> { | ||||||
|      |      | ||||||
|     private labelInnerClick: boolean = false; |     private labelInnerClick: boolean = false; | ||||||
| @ -45,9 +45,9 @@ class BehaviorList extends Component<IBehaviorListProps & IMixinStatusProps & IM | |||||||
|                     if (this.props.status) { |                     if (this.props.status) { | ||||||
|                         this.props.status.setBehaviorObject(behavior as Behavior); |                         this.props.status.setBehaviorObject(behavior as Behavior); | ||||||
|                     } |                     } | ||||||
|                     // if (this.props.setting) {
 |                     if (this.props.setting) { | ||||||
|                     //     this.props.setting.layout.focus("LabelDetails");
 |                         this.props.setting.layout.focus("BehaviorDetails"); | ||||||
|                     // }
 |                     } | ||||||
|                     this.labelInnerClick = true; |                     this.labelInnerClick = true; | ||||||
|                 }} |                 }} | ||||||
|                 onAdd={() => { |                 onAdd={() => { | ||||||
| @ -63,6 +63,7 @@ class BehaviorList extends Component<IBehaviorListProps & IMixinStatusProps & IM | |||||||
|                             red: "yes", |                             red: "yes", | ||||||
|                             yes: () => { |                             yes: () => { | ||||||
|                                 status.model.deleteBehavior(behavior); |                                 status.model.deleteBehavior(behavior); | ||||||
|  |                                 status.setBehaviorObject(); | ||||||
|                             } |                             } | ||||||
|                         }) |                         }) | ||||||
|                     } |                     } | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| import { Component, ReactNode } from "react"; | import { Component, ReactNode } from "react"; | ||||||
| import { AttrInput } from "@Component/AttrInput/AttrInput"; | import { AttrInput } from "@Component/AttrInput/AttrInput"; | ||||||
| import { useStatusWithEvent, IMixinStatusProps, Status } from "@Context/Status"; | import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; | ||||||
|  | import { useSetting, IMixinSettingProps } from "@Context/Setting"; | ||||||
| import { Message } from "@Component/Message/Message"; | import { Message } from "@Component/Message/Message"; | ||||||
| import { ObjectID } from "@Model/Renderer"; | import { ObjectID } from "@Model/Renderer"; | ||||||
| import { ColorInput } from "@Component/ColorInput/ColorInput"; | import { ColorInput } from "@Component/ColorInput/ColorInput"; | ||||||
| @ -25,11 +26,13 @@ const allOption: IDisplayItem[] = [ | |||||||
|     {nameKey: "Common.Attr.Key.Generation.Mod.Range", key: GenMod.Range} |     {nameKey: "Common.Attr.Key.Generation.Mod.Range", key: GenMod.Range} | ||||||
| ]; | ]; | ||||||
| 
 | 
 | ||||||
|  | @useSetting | ||||||
| @useStatusWithEvent( | @useStatusWithEvent( | ||||||
|     "groupAttrChange", "groupLabelChange", "focusObjectChange", |     "groupAttrChange", "groupLabelChange", "focusObjectChange", | ||||||
|     "focusBehaviorChange", "behaviorChange", "groupBehaviorChange" |     "focusBehaviorChange", "behaviorChange", "groupBehaviorChange", | ||||||
|  |     "behaviorAttrChange" | ||||||
| ) | ) | ||||||
| class GroupDetails extends Component<IGroupDetailsProps & IMixinStatusProps> { | class GroupDetails extends Component<IGroupDetailsProps & IMixinStatusProps & IMixinSettingProps> { | ||||||
| 
 | 
 | ||||||
| 	private renderFrom(group: Group) { | 	private renderFrom(group: Group) { | ||||||
| 		return <> | 		return <> | ||||||
| @ -118,10 +121,15 @@ class GroupDetails extends Component<IGroupDetailsProps & IMixinStatusProps> { | |||||||
|                 behavior={group.behaviors} |                 behavior={group.behaviors} | ||||||
|                 focusBehavior={this.props.status?.focusBehavior} |                 focusBehavior={this.props.status?.focusBehavior} | ||||||
|                 click={(behavior) => { |                 click={(behavior) => { | ||||||
|  |                     if (behavior.isDeleted()) return; | ||||||
|                     this.props.status?.setBehaviorObject(behavior); |                     this.props.status?.setBehaviorObject(behavior); | ||||||
|                 }} |                 }} | ||||||
|                 action={(behavior) => { |                 action={(behavior) => { | ||||||
|  |                     if (behavior.isDeleted()) return; | ||||||
|                     this.props.status?.setBehaviorObject(behavior); |                     this.props.status?.setBehaviorObject(behavior); | ||||||
|  |                     setTimeout(() => { | ||||||
|  |                         this.props.setting?.layout.focus("BehaviorDetails"); | ||||||
|  |                     }); | ||||||
|                 }} |                 }} | ||||||
|                 delete={(behavior) => { |                 delete={(behavior) => { | ||||||
|                     this.props.status?.deleteGroupBehavior(group.id, behavior); |                     this.props.status?.deleteGroupBehavior(group.id, behavior); | ||||||
|  | |||||||
| @ -20,16 +20,19 @@ div.object-list { | |||||||
|             opacity: 0; |             opacity: 0; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         i.checkbox-icon:hover { |  | ||||||
|             color: $lt-green; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         i.type-icon { |         i.type-icon { | ||||||
|             display: inline-block; |             display: inline-block; | ||||||
|             opacity: 1; |             opacity: 1; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     div.object-list-checkbox:hover { | ||||||
|  | 
 | ||||||
|  |         i.checkbox-icon { | ||||||
|  |             color: $lt-green !important; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     div.details-list-item:hover { |     div.details-list-item:hover { | ||||||
| 
 | 
 | ||||||
|         div.object-list-checkbox { |         div.object-list-checkbox { | ||||||
|  | |||||||
| @ -51,9 +51,6 @@ class ObjectList extends Component<IMixinStatusProps & IMixinSettingProps> { | |||||||
|                 } |                 } | ||||||
|             }} |             }} | ||||||
|             checkBox={(item) => { |             checkBox={(item) => { | ||||||
|                 if (this.props.setting) { |  | ||||||
|                     this.props.setting.layout.focus("ObjectList"); |  | ||||||
|                 } |  | ||||||
|                 if (this.props.status) { |                 if (this.props.status) { | ||||||
|                     if ( |                     if ( | ||||||
|                         this.props.status.focusObject.has(item.key.toString()) || |                         this.props.status.focusObject.has(item.key.toString()) || | ||||||
|  | |||||||
| @ -9,6 +9,7 @@ import { LabelList } from "./LabelList/LabelList"; | |||||||
| import { LabelDetails } from "./LabelDetails/LabelDetails"; | import { LabelDetails } from "./LabelDetails/LabelDetails"; | ||||||
| import { GroupDetails } from "./GroupDetails/GroupDetails"; | import { GroupDetails } from "./GroupDetails/GroupDetails"; | ||||||
| import { BehaviorList } from "./BehaviorList/BehaviorList"; | import { BehaviorList } from "./BehaviorList/BehaviorList"; | ||||||
|  | import { BehaviorDetails } from "./BehaviorDetails/BehaviorDetails"; | ||||||
| 
 | 
 | ||||||
| interface IPanelInfo { | interface IPanelInfo { | ||||||
| 	nameKey: string; | 	nameKey: string; | ||||||
| @ -29,6 +30,7 @@ type PanelId = "" | |||||||
| | "LabelDetails" // 标签属性
 | | "LabelDetails" // 标签属性
 | ||||||
| | "GroupDetails" // 群属性
 | | "GroupDetails" // 群属性
 | ||||||
| | "BehaviorList" // 行为列表
 | | "BehaviorList" // 行为列表
 | ||||||
|  | | "BehaviorDetails" // 行为属性
 | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| const PanelInfoMap = new Map<PanelId, IPanelInfo>(); | const PanelInfoMap = new Map<PanelId, IPanelInfo>(); | ||||||
| @ -60,6 +62,10 @@ PanelInfoMap.set("BehaviorList", { | |||||||
|     nameKey: "Panel.Title.Behavior.List.View", introKay: "Panel.Info.Behavior.List.View", |     nameKey: "Panel.Title.Behavior.List.View", introKay: "Panel.Info.Behavior.List.View", | ||||||
|     class: BehaviorList, hidePadding: true |     class: BehaviorList, hidePadding: true | ||||||
| }); | }); | ||||||
|  | PanelInfoMap.set("BehaviorDetails", { | ||||||
|  |     nameKey: "Panel.Title.Behavior.Details.View", introKay: "Panel.Info.Behavior.Details.View", | ||||||
|  |     class: BehaviorDetails | ||||||
|  | }); | ||||||
| 
 | 
 | ||||||
| function getPanelById(panelId: PanelId): ReactNode { | function getPanelById(panelId: PanelId): ReactNode { | ||||||
| 	switch (panelId) { | 	switch (panelId) { | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user